From 7f09859be28be7dd5a51d3448dd3d9cbe8d28c14 Mon Sep 17 00:00:00 2001 From: Vlad Gribinchuk Date: Fri, 28 Sep 2018 13:30:48 +0300 Subject: [PATCH 0001/1292] Settings for the "Minimum Support Area" and "Minimum Support Interface Area" features --- resources/definitions/fdmprinter.def.json | 58 +++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 823635a62a..cd489126bf 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -4083,6 +4083,20 @@ "limit_to_extruder": "support_infill_extruder_nr", "settable_per_mesh": false }, + "minimum_support_area": + { + "label": "Minimum Support Area", + "description": "Minimum area size for support polygons. Polygons which area is smaller than this value will not be generated.", + "unit": "mm²", + "type": "float", + "default_value": 0.0, + "minimum_value": "0", + "enabled": "support_enable", + "limit_to_extruder": "support_infill_extruder_nr", + "settable_per_mesh": true, + "fabricate_enabled": true, + "intermediate_enabled": true + }, "support_interface_enable": { "label": "Enable Support Interface", @@ -4322,6 +4336,50 @@ } } }, + "minimum_interface_area": + { + "label": "Minimum Support Interface Area", + "description": "Minimum area size for support interface polygons. Polygons which area are smaller than this value will not be generated.", + "unit": "mm²", + "type": "float", + "default_value": 1.0, + "minimum_value": "0", + "minimum_value_warning": "minimum_support_area", + "limit_to_extruder": "support_interface_extruder_nr", + "enabled": "support_interface_enable and (support_enable or support_tree_enable)", + "settable_per_mesh": true, + "children": + { + "minimum_roof_area": + { + "label": "Minimum Support Roof Area", + "description": "Minimum area size for the roofs of the support. Polygons which area are smaller than this value will not be generated.", + "unit": "mm²", + "type": "float", + "default_value": 1.0, + "value": "extruderValue(support_roof_extruder_nr, 'minimum_interface_area')", + "minimum_value": "0", + "minimum_value_warning": "minimum_support_area", + "limit_to_extruder": "support_roof_extruder_nr", + "enabled": "support_roof_enable and (support_enable or support_tree_enable)", + "settable_per_mesh": true + }, + "minimum_bottom_area": + { + "label": "Minimum Support Floor Area", + "description": "Minimum area size for the floors of the support. Polygons which area are smaller than this value will not be generated.", + "unit": "mm²", + "type": "float", + "default_value": 1.0, + "value": "extruderValue(support_bottom_extruder_nr, 'minimum_interface_area')", + "minimum_value": "0", + "minimum_value_warning": "minimum_support_area", + "limit_to_extruder": "support_bottom_extruder_nr", + "enabled": "support_bottom_enable and (support_enable or support_tree_enable)", + "settable_per_mesh": true + } + } + }, "support_fan_enable": { "label": "Fan Speed Override", From 193f11385168d1b0ca015127cfc46ac607a1d2a6 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 8 Oct 2018 10:33:01 +0200 Subject: [PATCH 0002/1292] Clean up Cura.qml: - Create a Skeleton folder where the main parts of the application will be stored. - Separate the top menus to a different file. Contributes to CURA-5784. --- cura/CuraApplication.py | 4 +- resources/qml/Cura.qml | 259 ++------------------- resources/qml/Skeleton/ApplicationMenu.qml | 234 +++++++++++++++++++ 3 files changed, 251 insertions(+), 246 deletions(-) create mode 100644 resources/qml/Skeleton/ApplicationMenu.qml diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 67bdd5805e..1990fd1b36 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -617,9 +617,7 @@ class CuraApplication(QtApplication): self._message_box_callback(button, *self._message_box_callback_arguments) self._message_box_callback = None self._message_box_callback_arguments = [] - - showPrintMonitor = pyqtSignal(bool, arguments = ["show"]) - + def setSaveDataEnabled(self, enabled: bool) -> None: self._save_data_enabled = enabled diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index b3367471ad..380e425ef5 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.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.7 @@ -11,28 +11,21 @@ import UM 1.3 as UM import Cura 1.1 as Cura import "Menus" +import "Skeleton" UM.MainWindow { id: base - //: Cura application window title - title: catalog.i18nc("@title:window","Ultimaker Cura"); - viewportRect: Qt.rect(0, 0, (base.width - sidebar.width) / base.width, 1.0) - property bool showPrintMonitor: false + // Cura application window title + title: catalog.i18nc("@title:window", "Ultimaker Cura") + viewportRect: Qt.rect(0, 0, (base.width - sidebar.width) / base.width, 1.0) backgroundColor: UM.Theme.getColor("viewport_background") - // This connection is here to support legacy printer output devices that use the showPrintMonitor signal on Application to switch to the monitor stage - // It should be phased out in newer plugin versions. - Connections + + UM.I18nCatalog { - target: CuraApplication - onShowPrintMonitor: { - if (show) { - UM.Controller.setActiveStage("MonitorStage") - } else { - UM.Controller.setActiveStage("PrepareStage") - } - } + id: catalog + name:"cura" } onWidthChanged: @@ -72,12 +65,12 @@ UM.MainWindow Item { - id: backgroundItem; - anchors.fill: parent; - UM.I18nCatalog{id: catalog; name:"cura"} + id: backgroundItem + anchors.fill: parent signal hasMesh(string name) //this signal sends the filebase name so it can be used for the JobSpecs.qml - function getMeshName(path){ + function getMeshName(path) + { //takes the path the complete path of the meshname and returns only the filebase var fileName = path.slice(path.lastIndexOf("/") + 1) var fileBase = fileName.slice(0, fileName.indexOf(".")) @@ -85,238 +78,18 @@ UM.MainWindow } //DeleteSelection on the keypress backspace event - Keys.onPressed: { + Keys.onPressed: + { if (event.key == Qt.Key_Backspace) { Cura.Actions.deleteSelection.trigger() } } - UM.ApplicationMenu + ApplicationMenu { id: menu window: base - - Menu - { - id: fileMenu - title: catalog.i18nc("@title:menu menubar:toplevel","&File"); - MenuItem - { - id: newProjectMenu - action: Cura.Actions.newProject; - } - - MenuItem - { - id: openMenu - action: Cura.Actions.open; - } - - RecentFilesMenu { } - - MenuItem - { - id: saveWorkspaceMenu - text: catalog.i18nc("@title:menu menubar:file","&Save...") - onTriggered: - { - var args = { "filter_by_machine": false, "file_type": "workspace", "preferred_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml" }; - if(UM.Preferences.getValue("cura/dialog_on_project_save")) - { - saveWorkspaceDialog.args = args; - saveWorkspaceDialog.open() - } - else - { - UM.OutputDeviceManager.requestWriteToDevice("local_file", PrintInformation.jobName, args) - } - } - } - - MenuSeparator { } - - MenuItem - { - id: saveAsMenu - text: catalog.i18nc("@title:menu menubar:file", "&Export...") - onTriggered: - { - var localDeviceId = "local_file"; - UM.OutputDeviceManager.requestWriteToDevice(localDeviceId, PrintInformation.jobName, { "filter_by_machine": false, "preferred_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml"}); - } - } - - MenuItem - { - id: exportSelectionMenu - 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_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml"}); - } - - MenuSeparator { } - - MenuItem - { - id: reloadAllMenu - action: Cura.Actions.reloadAll; - } - - MenuSeparator { } - - MenuItem { action: Cura.Actions.quit; } - } - - Menu - { - title: catalog.i18nc("@title:menu menubar:toplevel","&Edit"); - - MenuItem { action: Cura.Actions.undo; } - MenuItem { action: Cura.Actions.redo; } - MenuSeparator { } - MenuItem { action: Cura.Actions.selectAll; } - MenuItem { action: Cura.Actions.arrangeAll; } - MenuItem { action: Cura.Actions.deleteSelection; } - MenuItem { action: Cura.Actions.deleteAll; } - MenuItem { action: Cura.Actions.resetAllTranslation; } - MenuItem { action: Cura.Actions.resetAll; } - MenuSeparator { } - MenuItem { action: Cura.Actions.groupObjects;} - MenuItem { action: Cura.Actions.mergeObjects;} - MenuItem { action: Cura.Actions.unGroupObjects;} - } - - ViewMenu { title: catalog.i18nc("@title:menu", "&View") } - - Menu - { - id: settingsMenu - title: catalog.i18nc("@title:menu", "&Settings") - - PrinterMenu { title: catalog.i18nc("@title:menu menubar:settings", "&Printer") } - - Instantiator - { - model: Cura.ExtrudersModel { simpleNames: true } - Menu { - title: model.name - - NozzleMenu { title: Cura.MachineManager.activeDefinitionVariantsName; visible: Cura.MachineManager.hasVariants; extruderIndex: index } - MaterialMenu { title: catalog.i18nc("@title:menu", "&Material"); visible: Cura.MachineManager.hasMaterials; extruderIndex: index } - - MenuSeparator - { - visible: Cura.MachineManager.hasVariants || Cura.MachineManager.hasMaterials - } - - MenuItem - { - text: catalog.i18nc("@action:inmenu", "Set as Active Extruder") - onTriggered: Cura.MachineManager.setExtruderIndex(model.index) - } - - MenuItem - { - text: catalog.i18nc("@action:inmenu", "Enable Extruder") - onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, true) - visible: !Cura.MachineManager.getExtruder(model.index).isEnabled - } - - MenuItem - { - text: catalog.i18nc("@action:inmenu", "Disable Extruder") - onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, false) - visible: Cura.MachineManager.getExtruder(model.index).isEnabled - enabled: Cura.MachineManager.numberExtrudersEnabled > 1 - } - - } - onObjectAdded: settingsMenu.insertItem(index, object) - onObjectRemoved: settingsMenu.removeItem(object) - } - - // TODO Only show in dev mode. Remove check when feature ready - BuildplateMenu { title: catalog.i18nc("@title:menu", "&Build plate"); visible: CuraSDKVersion == "dev" ? Cura.MachineManager.hasVariantBuildplates : false } - ProfileMenu { title: catalog.i18nc("@title:settings", "&Profile"); } - - MenuSeparator { } - - MenuItem { action: Cura.Actions.configureSettingVisibility } - } - - Menu - { - id: extension_menu - title: catalog.i18nc("@title:menu menubar:toplevel","E&xtensions"); - - Instantiator - { - id: extensions - model: UM.ExtensionModel { } - - Menu - { - id: sub_menu - title: model.name; - visible: actions != null - enabled: actions != null - Instantiator - { - model: actions - MenuItem - { - text: model.text - onTriggered: extensions.model.subMenuTriggered(name, model.text) - } - onObjectAdded: sub_menu.insertItem(index, object) - onObjectRemoved: sub_menu.removeItem(object) - } - } - - onObjectAdded: extension_menu.insertItem(index, object) - onObjectRemoved: extension_menu.removeItem(object) - } - } - - Menu - { - id: plugin_menu - title: catalog.i18nc("@title:menu menubar:toplevel", "&Toolbox") - - MenuItem { action: Cura.Actions.browsePackages } - } - - Menu - { - id: preferencesMenu - title: catalog.i18nc("@title:menu menubar:toplevel","P&references"); - - MenuItem { action: Cura.Actions.preferences; } - } - - Menu - { - id: helpMenu - title: catalog.i18nc("@title:menu menubar:toplevel","&Help"); - - MenuItem { action: Cura.Actions.showProfileFolder; } - MenuItem { action: Cura.Actions.documentation; } - MenuItem { action: Cura.Actions.reportBug; } - MenuSeparator { } - MenuItem { action: Cura.Actions.about; } - } - } - - UM.SettingPropertyProvider - { - id: machineExtruderCount - - containerStack: Cura.MachineManager.activeMachine - key: "machine_extruder_count" - watchedProperties: [ "value" ] - storeIndex: 0 } Item diff --git a/resources/qml/Skeleton/ApplicationMenu.qml b/resources/qml/Skeleton/ApplicationMenu.qml new file mode 100644 index 0000000000..9abaa80f2a --- /dev/null +++ b/resources/qml/Skeleton/ApplicationMenu.qml @@ -0,0 +1,234 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import QtQuick.Layouts 1.1 +import QtQuick.Dialogs 1.2 + +import UM 1.3 as UM +import Cura 1.1 as Cura + +import "../Menus" + +UM.ApplicationMenu +{ + id: menu + + Menu + { + id: fileMenu + title: catalog.i18nc("@title:menu menubar:toplevel","&File") + + MenuItem + { + id: newProjectMenu + action: Cura.Actions.newProject + } + + MenuItem + { + id: openMenu + action: Cura.Actions.open + } + + RecentFilesMenu { } + + MenuItem + { + id: saveWorkspaceMenu + text: catalog.i18nc("@title:menu menubar:file","&Save...") + onTriggered: + { + var args = { "filter_by_machine": false, "file_type": "workspace", "preferred_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml" }; + if(UM.Preferences.getValue("cura/dialog_on_project_save")) + { + saveWorkspaceDialog.args = args + saveWorkspaceDialog.open() + } + else + { + UM.OutputDeviceManager.requestWriteToDevice("local_file", PrintInformation.jobName, args) + } + } + } + + MenuSeparator { } + + MenuItem + { + id: saveAsMenu + text: catalog.i18nc("@title:menu menubar:file", "&Export...") + onTriggered: + { + var localDeviceId = "local_file" + UM.OutputDeviceManager.requestWriteToDevice(localDeviceId, PrintInformation.jobName, { "filter_by_machine": false, "preferred_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml"}) + } + } + + MenuItem + { + id: exportSelectionMenu + 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_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml"}) + } + + MenuSeparator { } + + MenuItem + { + id: reloadAllMenu + action: Cura.Actions.reloadAll + } + + MenuSeparator { } + + MenuItem { action: Cura.Actions.quit } + } + + Menu + { + title: catalog.i18nc("@title:menu menubar:toplevel","&Edit") + + MenuItem { action: Cura.Actions.undo } + MenuItem { action: Cura.Actions.redo } + MenuSeparator { } + MenuItem { action: Cura.Actions.selectAll } + MenuItem { action: Cura.Actions.arrangeAll } + MenuItem { action: Cura.Actions.deleteSelection } + MenuItem { action: Cura.Actions.deleteAll } + MenuItem { action: Cura.Actions.resetAllTranslation } + MenuItem { action: Cura.Actions.resetAll } + MenuSeparator { } + MenuItem { action: Cura.Actions.groupObjects } + MenuItem { action: Cura.Actions.mergeObjects } + MenuItem { action: Cura.Actions.unGroupObjects } + } + + ViewMenu { title: catalog.i18nc("@title:menu", "&View") } + + Menu + { + id: settingsMenu + title: catalog.i18nc("@title:menu", "&Settings") + + PrinterMenu { title: catalog.i18nc("@title:menu menubar:settings", "&Printer") } + + Instantiator + { + model: Cura.ExtrudersModel { simpleNames: true } + Menu { + title: model.name + + NozzleMenu { title: Cura.MachineManager.activeDefinitionVariantsName; visible: Cura.MachineManager.hasVariants; extruderIndex: index } + MaterialMenu { title: catalog.i18nc("@title:menu", "&Material"); visible: Cura.MachineManager.hasMaterials; extruderIndex: index } + + MenuSeparator + { + visible: Cura.MachineManager.hasVariants || Cura.MachineManager.hasMaterials + } + + MenuItem + { + text: catalog.i18nc("@action:inmenu", "Set as Active Extruder") + onTriggered: Cura.MachineManager.setExtruderIndex(model.index) + } + + MenuItem + { + text: catalog.i18nc("@action:inmenu", "Enable Extruder") + onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, true) + visible: !Cura.MachineManager.getExtruder(model.index).isEnabled + } + + MenuItem + { + text: catalog.i18nc("@action:inmenu", "Disable Extruder") + onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, false) + visible: Cura.MachineManager.getExtruder(model.index).isEnabled + enabled: Cura.MachineManager.numberExtrudersEnabled > 1 + } + + } + onObjectAdded: settingsMenu.insertItem(index, object) + onObjectRemoved: settingsMenu.removeItem(object) + } + + // TODO Only show in dev mode. Remove check when feature ready + BuildplateMenu + { + title: catalog.i18nc("@title:menu", "&Build plate") + visible: CuraSDKVersion == "dev" && Cura.MachineManager.hasVariantBuildplates + } + ProfileMenu { title: catalog.i18nc("@title:settings", "&Profile") } + + MenuSeparator { } + + MenuItem { action: Cura.Actions.configureSettingVisibility } + } + + Menu + { + id: extension_menu + title: catalog.i18nc("@title:menu menubar:toplevel","E&xtensions") + + Instantiator + { + id: extensions + model: UM.ExtensionModel { } + + Menu + { + id: sub_menu + title: model.name; + visible: actions != null + enabled: actions != null + Instantiator + { + model: actions + MenuItem + { + text: model.text + onTriggered: extensions.model.subMenuTriggered(name, model.text) + } + onObjectAdded: sub_menu.insertItem(index, object) + onObjectRemoved: sub_menu.removeItem(object) + } + } + + onObjectAdded: extension_menu.insertItem(index, object) + onObjectRemoved: extension_menu.removeItem(object) + } + } + + Menu + { + id: plugin_menu + title: catalog.i18nc("@title:menu menubar:toplevel", "&Toolbox") + + MenuItem { action: Cura.Actions.browsePackages } + } + + Menu + { + id: preferencesMenu + title: catalog.i18nc("@title:menu menubar:toplevel","P&references") + + MenuItem { action: Cura.Actions.preferences } + } + + Menu + { + id: helpMenu + title: catalog.i18nc("@title:menu menubar:toplevel","&Help") + + MenuItem { action: Cura.Actions.showProfileFolder } + MenuItem { action: Cura.Actions.documentation } + MenuItem { action: Cura.Actions.reportBug } + MenuSeparator { } + MenuItem { action: Cura.Actions.about } + } +} \ No newline at end of file From 8bdd27183fcb318cf76c1c5f5aab1b0e7507e4f7 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 8 Oct 2018 10:59:46 +0200 Subject: [PATCH 0003/1292] Move TopBar to the Skeleton folder. Clean up the Cura.qml even more by moving some components to the ApplicationMenu, where they are called. Contributes to CURA-5784. --- resources/qml/Cura.qml | 35 -- .../{ => Dialogs}/WorkspaceSummaryDialog.qml | 0 resources/qml/Skeleton/ApplicationMenu.qml | 413 ++++++++++-------- resources/qml/{ => Skeleton}/Topbar.qml | 3 +- 4 files changed, 229 insertions(+), 222 deletions(-) rename resources/qml/{ => Dialogs}/WorkspaceSummaryDialog.qml (100%) rename resources/qml/{ => Skeleton}/Topbar.qml (99%) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 380e425ef5..18280ea4ae 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -183,7 +183,6 @@ UM.MainWindow bottom: parent.bottom; left: parent.left; } - } Topbar @@ -340,13 +339,6 @@ UM.MainWindow } } - WorkspaceSummaryDialog - { - id: saveWorkspaceDialog - property var args - onYes: UM.OutputDeviceManager.requestWriteToDevice("local_file", PrintInformation.jobName, args) - } - Connections { target: Cura.Actions.preferences @@ -359,33 +351,6 @@ UM.MainWindow onShowPreferencesWindow: preferences.visible = true } - MessageDialog - { - id: newProjectDialog - modality: Qt.ApplicationModal - title: catalog.i18nc("@title:window", "New project") - text: catalog.i18nc("@info:question", "Are you sure you want to start a new project? This will clear the build plate and any unsaved settings.") - standardButtons: StandardButton.Yes | StandardButton.No - icon: StandardIcon.Question - onYes: - { - CuraApplication.deleteAll(); - Cura.Actions.resetProfile.trigger(); - } - } - - Connections - { - target: Cura.Actions.newProject - onTriggered: - { - if(Printer.platformActivity || Cura.MachineManager.hasUserSettings) - { - newProjectDialog.visible = true - } - } - } - Connections { target: Cura.Actions.addProfile diff --git a/resources/qml/WorkspaceSummaryDialog.qml b/resources/qml/Dialogs/WorkspaceSummaryDialog.qml similarity index 100% rename from resources/qml/WorkspaceSummaryDialog.qml rename to resources/qml/Dialogs/WorkspaceSummaryDialog.qml diff --git a/resources/qml/Skeleton/ApplicationMenu.qml b/resources/qml/Skeleton/ApplicationMenu.qml index 9abaa80f2a..97d8f7ca7e 100644 --- a/resources/qml/Skeleton/ApplicationMenu.qml +++ b/resources/qml/Skeleton/ApplicationMenu.qml @@ -11,224 +11,267 @@ import UM 1.3 as UM import Cura 1.1 as Cura import "../Menus" +import "../Dialogs" -UM.ApplicationMenu +Item { id: menu + width: applicationMenu.width + height: applicationMenu.height + property alias window: applicationMenu.window - Menu + UM.ApplicationMenu { - id: fileMenu - title: catalog.i18nc("@title:menu menubar:toplevel","&File") + id: applicationMenu - MenuItem + Menu { - id: newProjectMenu - action: Cura.Actions.newProject - } + id: fileMenu + title: catalog.i18nc("@title:menu menubar:toplevel","&File") - MenuItem - { - id: openMenu - action: Cura.Actions.open - } - - RecentFilesMenu { } - - MenuItem - { - id: saveWorkspaceMenu - text: catalog.i18nc("@title:menu menubar:file","&Save...") - onTriggered: + MenuItem { - var args = { "filter_by_machine": false, "file_type": "workspace", "preferred_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml" }; - if(UM.Preferences.getValue("cura/dialog_on_project_save")) + id: newProjectMenu + action: Cura.Actions.newProject + } + + MenuItem + { + id: openMenu + action: Cura.Actions.open + } + + RecentFilesMenu { } + + MenuItem + { + id: saveWorkspaceMenu + text: catalog.i18nc("@title:menu menubar:file","&Save...") + onTriggered: { - saveWorkspaceDialog.args = args - saveWorkspaceDialog.open() - } - else - { - UM.OutputDeviceManager.requestWriteToDevice("local_file", PrintInformation.jobName, args) + var args = { "filter_by_machine": false, "file_type": "workspace", "preferred_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml" }; + if(UM.Preferences.getValue("cura/dialog_on_project_save")) + { + saveWorkspaceDialog.args = args + saveWorkspaceDialog.open() + } + else + { + UM.OutputDeviceManager.requestWriteToDevice("local_file", PrintInformation.jobName, args) + } } } - } - MenuSeparator { } + MenuSeparator { } - MenuItem - { - id: saveAsMenu - text: catalog.i18nc("@title:menu menubar:file", "&Export...") - onTriggered: + MenuItem { - var localDeviceId = "local_file" - UM.OutputDeviceManager.requestWriteToDevice(localDeviceId, PrintInformation.jobName, { "filter_by_machine": false, "preferred_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml"}) + id: saveAsMenu + text: catalog.i18nc("@title:menu menubar:file", "&Export...") + onTriggered: + { + var localDeviceId = "local_file" + UM.OutputDeviceManager.requestWriteToDevice(localDeviceId, PrintInformation.jobName, { "filter_by_machine": false, "preferred_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml"}) + } } - } - MenuItem - { - id: exportSelectionMenu - 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_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml"}) - } - - MenuSeparator { } - - MenuItem - { - id: reloadAllMenu - action: Cura.Actions.reloadAll - } - - MenuSeparator { } - - MenuItem { action: Cura.Actions.quit } - } - - Menu - { - title: catalog.i18nc("@title:menu menubar:toplevel","&Edit") - - MenuItem { action: Cura.Actions.undo } - MenuItem { action: Cura.Actions.redo } - MenuSeparator { } - MenuItem { action: Cura.Actions.selectAll } - MenuItem { action: Cura.Actions.arrangeAll } - MenuItem { action: Cura.Actions.deleteSelection } - MenuItem { action: Cura.Actions.deleteAll } - MenuItem { action: Cura.Actions.resetAllTranslation } - MenuItem { action: Cura.Actions.resetAll } - MenuSeparator { } - MenuItem { action: Cura.Actions.groupObjects } - MenuItem { action: Cura.Actions.mergeObjects } - MenuItem { action: Cura.Actions.unGroupObjects } - } - - ViewMenu { title: catalog.i18nc("@title:menu", "&View") } - - Menu - { - id: settingsMenu - title: catalog.i18nc("@title:menu", "&Settings") - - PrinterMenu { title: catalog.i18nc("@title:menu menubar:settings", "&Printer") } - - Instantiator - { - model: Cura.ExtrudersModel { simpleNames: true } - Menu { - title: model.name - - NozzleMenu { title: Cura.MachineManager.activeDefinitionVariantsName; visible: Cura.MachineManager.hasVariants; extruderIndex: index } - MaterialMenu { title: catalog.i18nc("@title:menu", "&Material"); visible: Cura.MachineManager.hasMaterials; extruderIndex: index } - - MenuSeparator - { - visible: Cura.MachineManager.hasVariants || Cura.MachineManager.hasMaterials - } - - MenuItem - { - text: catalog.i18nc("@action:inmenu", "Set as Active Extruder") - onTriggered: Cura.MachineManager.setExtruderIndex(model.index) - } - - MenuItem - { - text: catalog.i18nc("@action:inmenu", "Enable Extruder") - onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, true) - visible: !Cura.MachineManager.getExtruder(model.index).isEnabled - } - - MenuItem - { - text: catalog.i18nc("@action:inmenu", "Disable Extruder") - onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, false) - visible: Cura.MachineManager.getExtruder(model.index).isEnabled - enabled: Cura.MachineManager.numberExtrudersEnabled > 1 - } - - } - onObjectAdded: settingsMenu.insertItem(index, object) - onObjectRemoved: settingsMenu.removeItem(object) - } - - // TODO Only show in dev mode. Remove check when feature ready - BuildplateMenu - { - title: catalog.i18nc("@title:menu", "&Build plate") - visible: CuraSDKVersion == "dev" && Cura.MachineManager.hasVariantBuildplates - } - ProfileMenu { title: catalog.i18nc("@title:settings", "&Profile") } - - MenuSeparator { } - - MenuItem { action: Cura.Actions.configureSettingVisibility } - } - - Menu - { - id: extension_menu - title: catalog.i18nc("@title:menu menubar:toplevel","E&xtensions") - - Instantiator - { - id: extensions - model: UM.ExtensionModel { } - - Menu + MenuItem { - id: sub_menu - title: model.name; - visible: actions != null - enabled: actions != null - Instantiator - { - model: actions + id: exportSelectionMenu + 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_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml"}) + } + + MenuSeparator { } + + MenuItem + { + id: reloadAllMenu + action: Cura.Actions.reloadAll + } + + MenuSeparator { } + + MenuItem { action: Cura.Actions.quit } + } + + Menu + { + title: catalog.i18nc("@title:menu menubar:toplevel","&Edit") + + MenuItem { action: Cura.Actions.undo } + MenuItem { action: Cura.Actions.redo } + MenuSeparator { } + MenuItem { action: Cura.Actions.selectAll } + MenuItem { action: Cura.Actions.arrangeAll } + MenuItem { action: Cura.Actions.deleteSelection } + MenuItem { action: Cura.Actions.deleteAll } + MenuItem { action: Cura.Actions.resetAllTranslation } + MenuItem { action: Cura.Actions.resetAll } + MenuSeparator { } + MenuItem { action: Cura.Actions.groupObjects } + MenuItem { action: Cura.Actions.mergeObjects } + MenuItem { action: Cura.Actions.unGroupObjects } + } + + ViewMenu { title: catalog.i18nc("@title:menu", "&View") } + + Menu + { + id: settingsMenu + title: catalog.i18nc("@title:menu", "&Settings") + + PrinterMenu { title: catalog.i18nc("@title:menu menubar:settings", "&Printer") } + + Instantiator + { + model: Cura.ExtrudersModel { simpleNames: true } + Menu { + title: model.name + + NozzleMenu { title: Cura.MachineManager.activeDefinitionVariantsName; visible: Cura.MachineManager.hasVariants; extruderIndex: index } + MaterialMenu { title: catalog.i18nc("@title:menu", "&Material"); visible: Cura.MachineManager.hasMaterials; extruderIndex: index } + + MenuSeparator + { + visible: Cura.MachineManager.hasVariants || Cura.MachineManager.hasMaterials + } + MenuItem { - text: model.text - onTriggered: extensions.model.subMenuTriggered(name, model.text) + text: catalog.i18nc("@action:inmenu", "Set as Active Extruder") + onTriggered: Cura.MachineManager.setExtruderIndex(model.index) } - onObjectAdded: sub_menu.insertItem(index, object) - onObjectRemoved: sub_menu.removeItem(object) + + MenuItem + { + text: catalog.i18nc("@action:inmenu", "Enable Extruder") + onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, true) + visible: !Cura.MachineManager.getExtruder(model.index).isEnabled + } + + MenuItem + { + text: catalog.i18nc("@action:inmenu", "Disable Extruder") + onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, false) + visible: Cura.MachineManager.getExtruder(model.index).isEnabled + enabled: Cura.MachineManager.numberExtrudersEnabled > 1 + } + } + onObjectAdded: settingsMenu.insertItem(index, object) + onObjectRemoved: settingsMenu.removeItem(object) } - onObjectAdded: extension_menu.insertItem(index, object) - onObjectRemoved: extension_menu.removeItem(object) + // TODO Only show in dev mode. Remove check when feature ready + BuildplateMenu + { + title: catalog.i18nc("@title:menu", "&Build plate") + visible: CuraSDKVersion == "dev" && Cura.MachineManager.hasVariantBuildplates + } + ProfileMenu { title: catalog.i18nc("@title:settings", "&Profile") } + + MenuSeparator { } + + MenuItem { action: Cura.Actions.configureSettingVisibility } + } + + Menu + { + id: extension_menu + title: catalog.i18nc("@title:menu menubar:toplevel","E&xtensions") + + Instantiator + { + id: extensions + model: UM.ExtensionModel { } + + Menu + { + id: sub_menu + title: model.name; + visible: actions != null + enabled: actions != null + Instantiator + { + model: actions + MenuItem + { + text: model.text + onTriggered: extensions.model.subMenuTriggered(name, model.text) + } + onObjectAdded: sub_menu.insertItem(index, object) + onObjectRemoved: sub_menu.removeItem(object) + } + } + + onObjectAdded: extension_menu.insertItem(index, object) + onObjectRemoved: extension_menu.removeItem(object) + } + } + + Menu + { + id: plugin_menu + title: catalog.i18nc("@title:menu menubar:toplevel", "&Toolbox") + + MenuItem { action: Cura.Actions.browsePackages } + } + + Menu + { + id: preferencesMenu + title: catalog.i18nc("@title:menu menubar:toplevel","P&references") + + MenuItem { action: Cura.Actions.preferences } + } + + Menu + { + id: helpMenu + title: catalog.i18nc("@title:menu menubar:toplevel","&Help") + + MenuItem { action: Cura.Actions.showProfileFolder } + MenuItem { action: Cura.Actions.documentation } + MenuItem { action: Cura.Actions.reportBug } + MenuSeparator { } + MenuItem { action: Cura.Actions.about } } } - Menu + WorkspaceSummaryDialog { - id: plugin_menu - title: catalog.i18nc("@title:menu menubar:toplevel", "&Toolbox") - - MenuItem { action: Cura.Actions.browsePackages } + id: saveWorkspaceDialog + property var args + onYes: UM.OutputDeviceManager.requestWriteToDevice("local_file", PrintInformation.jobName, args) } - Menu + MessageDialog { - id: preferencesMenu - title: catalog.i18nc("@title:menu menubar:toplevel","P&references") - - MenuItem { action: Cura.Actions.preferences } + id: newProjectDialog + modality: Qt.ApplicationModal + title: catalog.i18nc("@title:window", "New project") + text: catalog.i18nc("@info:question", "Are you sure you want to start a new project? This will clear the build plate and any unsaved settings.") + standardButtons: StandardButton.Yes | StandardButton.No + icon: StandardIcon.Question + onYes: + { + CuraApplication.deleteAll(); + Cura.Actions.resetProfile.trigger(); + } } - Menu + Connections { - id: helpMenu - title: catalog.i18nc("@title:menu menubar:toplevel","&Help") - - MenuItem { action: Cura.Actions.showProfileFolder } - MenuItem { action: Cura.Actions.documentation } - MenuItem { action: Cura.Actions.reportBug } - MenuSeparator { } - MenuItem { action: Cura.Actions.about } + target: Cura.Actions.newProject + onTriggered: + { + if(Printer.platformActivity || Cura.MachineManager.hasUserSettings) + { + newProjectDialog.visible = true + } + } } } \ No newline at end of file diff --git a/resources/qml/Topbar.qml b/resources/qml/Skeleton/Topbar.qml similarity index 99% rename from resources/qml/Topbar.qml rename to resources/qml/Skeleton/Topbar.qml index 17819dbd27..d27d9865b8 100644 --- a/resources/qml/Topbar.qml +++ b/resources/qml/Skeleton/Topbar.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.2 @@ -8,7 +8,6 @@ import QtQuick.Layouts 1.1 import UM 1.4 as UM import Cura 1.0 as Cura -import "Menus" Rectangle { From 3acfdadd12c8a0f5b136cb94d011cf6ccfebc693 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 8 Oct 2018 11:31:53 +0200 Subject: [PATCH 0004/1292] Organize the components in a Column. Separate the TopHeader and place it below the application menu, using all the width. Contributes to CURA-5784. --- resources/qml/Cura.qml | 104 +++++++++--------- .../Skeleton/{Topbar.qml => TopHeader.qml} | 0 2 files changed, 53 insertions(+), 51 deletions(-) rename resources/qml/Skeleton/{Topbar.qml => TopHeader.qml} (100%) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 18280ea4ae..62ec4799c9 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -63,7 +63,7 @@ UM.MainWindow CuraApplication.purgeWindows() } - Item + Column { id: backgroundItem anchors.fill: parent @@ -92,19 +92,25 @@ UM.MainWindow window: base } + TopHeader + { + id: topHeader + anchors.left: parent.left + anchors.right: parent.right + } + Item { - id: contentItem; + id: contentItem - y: menu.height - width: parent.width; - height: parent.height - menu.height; + width: parent.width + height: parent.height - menu.height - topHeader.height Keys.forwardTo: menu DropArea { - anchors.fill: parent; + anchors.fill: parent onDropped: { if (drop.urls.length > 0) @@ -137,69 +143,61 @@ UM.MainWindow id: jobSpecs anchors { - bottom: parent.bottom; - right: sidebar.left; - bottomMargin: UM.Theme.getSize("default_margin").height; - rightMargin: UM.Theme.getSize("default_margin").width; + bottom: parent.bottom + right: sidebar.left + bottomMargin: UM.Theme.getSize("default_margin").height + rightMargin: UM.Theme.getSize("default_margin").width } } Button { - id: openFileButton; - text: catalog.i18nc("@action:button","Open File"); + id: openFileButton + text: catalog.i18nc("@action:button","Open File") iconSource: UM.Theme.getIcon("load") style: UM.Theme.styles.tool_button tooltip: "" anchors { - top: topbar.bottom; - topMargin: UM.Theme.getSize("default_margin").height; - left: parent.left; + top: parent.top + topMargin: UM.Theme.getSize("default_margin").height + left: parent.left } - action: Cura.Actions.open; + action: Cura.Actions.open } Toolbar { - id: toolbar; + id: toolbar property int mouseX: base.mouseX property int mouseY: base.mouseY anchors { - top: openFileButton.bottom; - topMargin: UM.Theme.getSize("window_margin").height; - left: parent.left; + top: openFileButton.bottom + topMargin: UM.Theme.getSize("window_margin").height + left: parent.left } } ObjectsList { - id: objectsList; - visible: UM.Preferences.getValue("cura/use_multi_build_plate"); + id: objectsList + visible: UM.Preferences.getValue("cura/use_multi_build_plate") anchors { - bottom: parent.bottom; - left: parent.left; + bottom: parent.bottom + left: parent.left } } - Topbar - { - id: topbar - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - } - Loader { id: main anchors { - top: topbar.bottom + top: parent.top bottom: parent.bottom left: parent.left right: sidebar.left @@ -220,26 +218,30 @@ UM.MainWindow { id: sidebar - property bool collapsed: false; - property var initialWidth: UM.Theme.getSize("sidebar").width; + property bool collapsed: false + property var initialWidth: UM.Theme.getSize("sidebar").width - function callExpandOrCollapse() { - if (collapsed) { - sidebar.visible = true; - sidebar.initialWidth = UM.Theme.getSize("sidebar").width; - viewportRect = Qt.rect(0, 0, (base.width - sidebar.width) / base.width, 1.0); + function callExpandOrCollapse() + { + if (collapsed) + { + sidebar.visible = true + sidebar.initialWidth = UM.Theme.getSize("sidebar").width + viewportRect = Qt.rect(0, 0, (base.width - sidebar.width) / base.width, 1.0) expandSidebarAnimation.start(); - } else { - viewportRect = Qt.rect(0, 0, 1, 1.0); - collapseSidebarAnimation.start(); } - collapsed = !collapsed; - UM.Preferences.setValue("cura/sidebar_collapsed", collapsed); + else + { + viewportRect = Qt.rect(0, 0, 1, 1.0) + collapseSidebarAnimation.start() + } + collapsed = !collapsed + UM.Preferences.setValue("cura/sidebar_collapsed", collapsed) } anchors { - top: topbar.top + top: parent.top bottom: parent.bottom } @@ -265,13 +267,13 @@ UM.MainWindow Component.onCompleted: { - var sidebar_collapsed = UM.Preferences.getValue("cura/sidebar_collapsed"); + var sidebar_collapsed = UM.Preferences.getValue("cura/sidebar_collapsed") if (sidebar_collapsed) { - sidebar.collapsed = true; + sidebar.collapsed = true viewportRect = Qt.rect(0, 0, 1, 1.0) - collapseSidebarAnimation.start(); + collapseSidebarAnimation.start() } } @@ -290,8 +292,8 @@ UM.MainWindow { horizontalCenter: parent.horizontalCenter horizontalCenterOffset: -(Math.round(UM.Theme.getSize("sidebar").width / 2)) - top: parent.verticalCenter; - bottom: parent.bottom; + top: parent.verticalCenter + bottom: parent.bottom bottomMargin: UM.Theme.getSize("default_margin").height } } diff --git a/resources/qml/Skeleton/Topbar.qml b/resources/qml/Skeleton/TopHeader.qml similarity index 100% rename from resources/qml/Skeleton/Topbar.qml rename to resources/qml/Skeleton/TopHeader.qml From 075a9a161fb77c999ad432666cd9b6d943f52cad Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 8 Oct 2018 12:57:16 +0200 Subject: [PATCH 0005/1292] Create a component for the Views selector. This component contains the list of the views and also the shortcuts for the camera position. The theme colors, sizes and the styles have been updated. Contributes to CURA-5784. --- .../resources/qml/ToolboxTabButton.qml | 6 +- resources/qml/Cura.qml | 12 + .../ConfigurationMenu/ConfigurationItem.qml | 4 +- resources/qml/Skeleton/ApplicationViews.qml | 108 +++++++++ resources/qml/Skeleton/OrientationViews.qml | 56 +++++ resources/qml/Skeleton/TopHeader.qml | 208 ++---------------- resources/themes/cura-dark/theme.json | 15 +- resources/themes/cura-light/styles.qml | 106 ++------- resources/themes/cura-light/theme.json | 24 +- 9 files changed, 235 insertions(+), 304 deletions(-) create mode 100644 resources/qml/Skeleton/ApplicationViews.qml create mode 100644 resources/qml/Skeleton/OrientationViews.qml diff --git a/plugins/Toolbox/resources/qml/ToolboxTabButton.qml b/plugins/Toolbox/resources/qml/ToolboxTabButton.qml index 22fb6d73ca..58149e419a 100644 --- a/plugins/Toolbox/resources/qml/ToolboxTabButton.qml +++ b/plugins/Toolbox/resources/qml/ToolboxTabButton.qml @@ -32,15 +32,15 @@ Button { if(control.hovered) { - return UM.Theme.getColor("topbar_button_text_hovered"); + return UM.Theme.getColor("toolbox_header_button_text_hovered"); } if(control.active) { - return UM.Theme.getColor("topbar_button_text_active"); + return UM.Theme.getColor("toolbox_header_button_text_active"); } else { - return UM.Theme.getColor("topbar_button_text_inactive"); + return UM.Theme.getColor("toolbox_header_button_text_inactive"); } } font: control.enabled ? (control.active ? UM.Theme.getFont("medium_bold") : UM.Theme.getFont("medium")) : UM.Theme.getFont("default_italic") diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 62ec4799c9..b7245b1b65 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -191,6 +191,18 @@ UM.MainWindow } } + ApplicationViews + { + id: applicationViews + + visible: UM.Controller.activeStage.stageId != "MonitorStage" + anchors + { + top: parent.top + right: sidebar.left + } + } + Loader { id: main diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 942dd81d9c..517b69428e 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -77,8 +77,8 @@ Rectangle UM.RecolorImage { id: buildplateIcon anchors.left: parent.left - width: UM.Theme.getSize("topbar_button_icon").width - height: UM.Theme.getSize("topbar_button_icon").height + width: UM.Theme.getSize("topheader_button_icon").width + height: UM.Theme.getSize("topheader_button_icon").height sourceSize.width: width sourceSize.height: height source: UM.Theme.getIcon("buildplate") diff --git a/resources/qml/Skeleton/ApplicationViews.qml b/resources/qml/Skeleton/ApplicationViews.qml new file mode 100644 index 0000000000..8e0b6efc0b --- /dev/null +++ b/resources/qml/Skeleton/ApplicationViews.qml @@ -0,0 +1,108 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 +import QtQuick.Layouts 1.1 + +import UM 1.4 as UM +import Cura 1.0 as Cura + +// This item contains the views selector, a combobox that is dinamically created from +// the list of available Views (packages that create different visualizactions of the +// scene. Aside the selector, there is a row of buttons that change the orientation of the view. +Item +{ + id: applicationViewsSelector + + height: UM.Theme.getSize("views_selector").height + + OrientationViews + { + id: orientationViews + + anchors { + verticalCenter: parent.verticalCenter + right: viewModeButton.left + rightMargin: UM.Theme.getSize("default_margin").width + } + } + + ComboBox + { + id: viewModeButton + + anchors { + verticalCenter: parent.verticalCenter + right: parent.right + rightMargin: UM.Theme.getSize("default_margin").width + } + + style: UM.Theme.styles.combobox + + model: UM.ViewModel { } + textRole: "name" + + // update the model's active index + function updateItemActiveFlags () + { + currentIndex = getActiveIndex() + for (var i = 0; i < model.rowCount(); i++) + { + model.getItem(i).active = (i == currentIndex) + } + } + + // get the index of the active model item on start + function getActiveIndex () + { + for (var i = 0; i < model.rowCount(); i++) + { + if (model.getItem(i).active) { + return i + } + } + return 0 + } + + // set the active index + function setActiveIndex (index) + { + UM.Controller.setActiveView(index) + // the connection to UM.ActiveView will trigger update so there is no reason to call it manually here + } + + onCurrentIndexChanged: + { + if (model.getItem(currentIndex).id != undefined) + { + viewModeButton.setActiveIndex(model.getItem(currentIndex).id) + } + } + currentIndex: getActiveIndex() + + // watch the active view proxy for changes made from the menu item + Connections + { + target: UM.ActiveView + onActiveViewChanged: viewModeButton.updateItemActiveFlags() + } + } + + Loader + { + id: viewPanel + + anchors.top: viewModeButton.bottom + anchors.topMargin: UM.Theme.getSize("default_margin").height + anchors.right: viewModeButton.right + + property var buttonTarget: Qt.point(viewModeButton.x + Math.round(viewModeButton.width / 2), viewModeButton.y + Math.round(viewModeButton.height / 2)) + + height: childrenRect.height + width: childrenRect.width + + source: UM.ActiveView.valid ? UM.ActiveView.activeViewPanel : "" + } +} diff --git a/resources/qml/Skeleton/OrientationViews.qml b/resources/qml/Skeleton/OrientationViews.qml new file mode 100644 index 0000000000..d1b370ed71 --- /dev/null +++ b/resources/qml/Skeleton/OrientationViews.qml @@ -0,0 +1,56 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 + +import UM 1.4 as UM + +// View orientation Item +Row +{ + id: viewOrientationControl + + spacing: 2 * screenScaleFactor + + // #1 3d view + Button + { + iconSource: UM.Theme.getIcon("view_3d") + style: UM.Theme.styles.small_tool_button + onClicked:UM.Controller.rotateView("3d", 0) + } + + // #2 Front view + Button + { + iconSource: UM.Theme.getIcon("view_front") + style: UM.Theme.styles.small_tool_button + onClicked: UM.Controller.rotateView("home", 0) + } + + // #3 Top view + Button + { + iconSource: UM.Theme.getIcon("view_top") + style: UM.Theme.styles.small_tool_button + onClicked: UM.Controller.rotateView("y", 90) + } + + // #4 Left view + Button + { + iconSource: UM.Theme.getIcon("view_left") + style: UM.Theme.styles.small_tool_button + onClicked: UM.Controller.rotateView("x", 90) + } + + // #5 Right view + Button + { + iconSource: UM.Theme.getIcon("view_right") + style: UM.Theme.styles.small_tool_button + onClicked: UM.Controller.rotateView("x", -90) + } +} diff --git a/resources/qml/Skeleton/TopHeader.qml b/resources/qml/Skeleton/TopHeader.qml index d27d9865b8..bdc9afd0cc 100644 --- a/resources/qml/Skeleton/TopHeader.qml +++ b/resources/qml/Skeleton/TopHeader.qml @@ -12,38 +12,9 @@ import Cura 1.0 as Cura Rectangle { id: base - anchors.left: parent.left - anchors.right: parent.right - height: UM.Theme.getSize("sidebar_header").height - color: UM.Controller.activeStage.stageId == "MonitorStage" ? UM.Theme.getColor("topbar_background_color_monitoring") : UM.Theme.getColor("topbar_background_color") - property bool printerConnected: Cura.MachineManager.printerConnected - property bool printerAcceptsCommands: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands - - property int rightMargin: UM.Theme.getSize("sidebar").width + UM.Theme.getSize("default_margin").width; - property int allItemsWidth: 0; - - function updateMarginsAndSizes() { - if (UM.Preferences.getValue("cura/sidebar_collapsed")) - { - rightMargin = UM.Theme.getSize("default_margin").width; - } - else - { - rightMargin = UM.Theme.getSize("sidebar").width + UM.Theme.getSize("default_margin").width; - } - allItemsWidth = ( - logo.width + UM.Theme.getSize("topbar_logo_right_margin").width + - UM.Theme.getSize("topbar_logo_right_margin").width + stagesMenuContainer.width + - UM.Theme.getSize("default_margin").width + viewModeButton.width + - rightMargin); - } - - UM.I18nCatalog - { - id: catalog - name:"cura" - } + height: UM.Theme.getSize("topheader").height + color: UM.Theme.getColor("topheader_background") Image { @@ -52,36 +23,36 @@ Rectangle anchors.leftMargin: UM.Theme.getSize("default_margin").width anchors.verticalCenter: parent.verticalCenter - source: UM.Theme.getImage("logo"); - width: UM.Theme.getSize("logo").width; - height: UM.Theme.getSize("logo").height; + source: UM.Theme.getImage("logo") + width: UM.Theme.getSize("logo").width + height: UM.Theme.getSize("logo").height - sourceSize.width: width; - sourceSize.height: height; + sourceSize.width: width + sourceSize.height: height } Row { id: stagesMenuContainer anchors.left: logo.right - anchors.leftMargin: UM.Theme.getSize("topbar_logo_right_margin").width + anchors.leftMargin: UM.Theme.getSize("topheader_logo_right_margin").width spacing: UM.Theme.getSize("default_margin").width - // The topbar is dynamically filled with all available stages + // The topheader is dynamically filled with all available stages Repeater { id: stagesMenu - model: UM.StageModel{} + model: UM.StageModel { } delegate: Button { text: model.name checkable: true checked: model.active - exclusiveGroup: topbarMenuGroup - style: (model.stage.iconSource != "") ? UM.Theme.styles.topbar_header_tab_no_overlay : UM.Theme.styles.topbar_header_tab - height: UM.Theme.getSize("sidebar_header").height + exclusiveGroup: topheaderMenuGroup + style: UM.Theme.styles.topheader_tab + height: UM.Theme.getSize("topheader").height onClicked: UM.Controller.setActiveStage(model.id) iconSource: model.stage.iconSource @@ -90,157 +61,6 @@ Rectangle } } - ExclusiveGroup { id: topbarMenuGroup } + ExclusiveGroup { id: topheaderMenuGroup } } - - // View orientation Item - Row - { - id: viewOrientationControl - height: 30 - - spacing: 2 - visible: UM.Controller.activeStage.stageId != "MonitorStage" - - anchors - { - verticalCenter: base.verticalCenter - right: viewModeButton.left - rightMargin: UM.Theme.getSize("default_margin").width - } - - // #1 3d view - Button - { - iconSource: UM.Theme.getIcon("view_3d") - style: UM.Theme.styles.small_tool_button - anchors.verticalCenter: viewOrientationControl.verticalCenter - onClicked:UM.Controller.rotateView("3d", 0) - visible: base.width - allItemsWidth - 4 * this.width > 0 - } - - // #2 Front view - Button - { - iconSource: UM.Theme.getIcon("view_front") - style: UM.Theme.styles.small_tool_button - anchors.verticalCenter: viewOrientationControl.verticalCenter - onClicked: UM.Controller.rotateView("home", 0); - visible: base.width - allItemsWidth - 3 * this.width > 0 - } - - // #3 Top view - Button - { - iconSource: UM.Theme.getIcon("view_top") - style: UM.Theme.styles.small_tool_button - anchors.verticalCenter: viewOrientationControl.verticalCenter - onClicked: UM.Controller.rotateView("y", 90) - visible: base.width - allItemsWidth - 2 * this.width > 0 - } - - // #4 Left view - Button - { - iconSource: UM.Theme.getIcon("view_left") - style: UM.Theme.styles.small_tool_button - anchors.verticalCenter: viewOrientationControl.verticalCenter - onClicked: UM.Controller.rotateView("x", 90) - visible: base.width - allItemsWidth - 1 * this.width > 0 - } - - // #5 Right view - Button - { - iconSource: UM.Theme.getIcon("view_right") - style: UM.Theme.styles.small_tool_button - anchors.verticalCenter: viewOrientationControl.verticalCenter - onClicked: UM.Controller.rotateView("x", -90) - visible: base.width - allItemsWidth > 0 - } - } - - ComboBox - { - id: viewModeButton - - anchors { - verticalCenter: parent.verticalCenter - right: parent.right - rightMargin: rightMargin - } - - style: UM.Theme.styles.combobox - visible: UM.Controller.activeStage.stageId != "MonitorStage" - - model: UM.ViewModel { } - textRole: "name" - - // update the model's active index - function updateItemActiveFlags () { - currentIndex = getActiveIndex() - for (var i = 0; i < model.rowCount(); i++) { - model.getItem(i).active = (i == currentIndex) - } - } - - // get the index of the active model item on start - function getActiveIndex () { - for (var i = 0; i < model.rowCount(); i++) { - if (model.getItem(i).active) { - return i - } - } - return 0 - } - - // set the active index - function setActiveIndex (index) { - UM.Controller.setActiveView(index) - // the connection to UM.ActiveView will trigger update so there is no reason to call it manually here - } - - onCurrentIndexChanged: - { - if (model.getItem(currentIndex).id != undefined) - viewModeButton.setActiveIndex(model.getItem(currentIndex).id) - } - currentIndex: getActiveIndex() - - // watch the active view proxy for changes made from the menu item - Connections - { - target: UM.ActiveView - onActiveViewChanged: viewModeButton.updateItemActiveFlags() - } - } - - Loader - { - id: view_panel - - anchors.top: viewModeButton.bottom - anchors.topMargin: UM.Theme.getSize("default_margin").height - anchors.right: viewModeButton.right - - property var buttonTarget: Qt.point(viewModeButton.x + Math.round(viewModeButton.width / 2), viewModeButton.y + Math.round(viewModeButton.height / 2)) - - height: childrenRect.height - width: childrenRect.width - - source: UM.ActiveView.valid ? UM.ActiveView.activeViewPanel : ""; - } - - // Expand or collapse sidebar - Connections - { - target: Cura.Actions.expandSidebar - onTriggered: updateMarginsAndSizes() - } - - Component.onCompleted: - { - updateMarginsAndSizes(); - } - } diff --git a/resources/themes/cura-dark/theme.json b/resources/themes/cura-dark/theme.json index 26e6c2ac8b..fa0da2851e 100644 --- a/resources/themes/cura-dark/theme.json +++ b/resources/themes/cura-dark/theme.json @@ -15,12 +15,11 @@ "border": [127, 127, 127, 255], "secondary": [241, 242, 242, 255], - "topbar_background_color": [0, 0, 0, 0], - "topbar_background_color_monitoring": [31, 36, 39, 255], + "topheader_background": [31, 36, 39, 255], - "topbar_button_text_active": [255, 255, 255, 255], - "topbar_button_text_inactive": [128, 128, 128, 255], - "topbar_button_text_hovered": [255, 255, 255, 255], + "topheader_button_text_active": [255, 255, 255, 255], + "topheader_button_text_inactive": [128, 128, 128, 255], + "topheader_button_text_hovered": [255, 255, 255, 255], "text": [255, 255, 255, 204], "text_detail": [255, 255, 255, 172], @@ -221,6 +220,10 @@ "quality_slider_available": [255, 255, 255, 255], "quality_slider_handle": [255, 255, 255, 255], "quality_slider_handle_hover": [127, 127, 127, 255], - "quality_slider_text": [255, 255, 255, 255] + "quality_slider_text": [255, 255, 255, 255], + + "toolbox_header_button_text_active": [255, 255, 255, 255], + "toolbox_header_button_text_inactive": [128, 128, 128, 255], + "toolbox_header_button_text_hovered": [255, 255, 255, 255] } } diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index b71ddd2d86..b54d12e07b 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -90,85 +90,11 @@ QtObject { } } - property Component topbar_header_tab_no_overlay: Component { - ButtonStyle { - background: Rectangle { - implicitHeight: Theme.getSize("topbar_button").height - implicitWidth: Theme.getSize("topbar_button").width - color: "transparent" - anchors.fill: parent - - Rectangle - { - id: underline - - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - width: parent.width - height: Theme.getSize("sidebar_header_highlight").height - color: control.checked ? UM.Theme.getColor("sidebar_header_highlight") : UM.Theme.getColor("sidebar_header_highlight_hover") - visible: control.hovered || control.checked - } - } - - label: Rectangle { - implicitHeight: Theme.getSize("topbar_button_icon").height - implicitWidth: Theme.getSize("topbar_button").width - color: "transparent" - anchors.fill: parent - - Item - { - anchors.centerIn: parent - width: Math.round(textLabel.width + icon.width + Theme.getSize("default_margin").width / 2) - Label - { - id: textLabel - text: control.text - anchors.right: icon.visible ? icon.left : parent.right - anchors.rightMargin: icon.visible ? Math.round(Theme.getSize("default_margin").width / 2) : 0 - anchors.verticalCenter: parent.verticalCenter; - font: control.checked ? UM.Theme.getFont("large") : UM.Theme.getFont("large_nonbold") - color: - { - if(control.hovered) - { - return UM.Theme.getColor("topbar_button_text_hovered"); - } - if(control.checked) - { - return UM.Theme.getColor("topbar_button_text_active"); - } - else - { - return UM.Theme.getColor("topbar_button_text_inactive"); - } - } - } - Image - { - id: icon - visible: control.iconSource != "" - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - opacity: !control.enabled ? 0.2 : 1.0 - source: control.iconSource - width: visible ? Theme.getSize("topbar_button_icon").width : 0 - height: Theme.getSize("topbar_button_icon").height - - sourceSize: Theme.getSize("topbar_button_icon") - } - } - } - } - } - - property Component topbar_header_tab: Component { + property Component topheader_tab: Component { ButtonStyle { background: Item { - implicitHeight: Theme.getSize("topbar_button").height - implicitWidth: Theme.getSize("topbar_button").width + Theme.getSize("topbar_button_icon").width + implicitHeight: Theme.getSize("topheader_button").height + implicitWidth: Theme.getSize("topheader_button").width + Theme.getSize("topheader_button_icon").width Rectangle { id: buttonFace; @@ -182,7 +108,7 @@ QtObject { anchors.horizontalCenter: parent.horizontalCenter anchors.bottom: parent.bottom - width: Theme.getSize("topbar_button").width + Theme.getSize("topbar_button_icon").width + width: Theme.getSize("topheader_button").width + Theme.getSize("topheader_button_icon").width height: Theme.getSize("sidebar_header_highlight").height color: control.checked ? UM.Theme.getColor("sidebar_header_highlight") : UM.Theme.getColor("sidebar_header_highlight_hover") visible: control.hovered || control.checked @@ -192,14 +118,14 @@ QtObject { label: Item { - implicitHeight: Theme.getSize("topbar_button_icon").height - implicitWidth: Theme.getSize("topbar_button").width + Theme.getSize("topbar_button_icon").width + implicitHeight: Theme.getSize("topheader_button_icon").height + implicitWidth: Theme.getSize("topheader_button").width + Theme.getSize("topheader_button_icon").width Item { anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter; width: childrenRect.width - height: Theme.getSize("topbar_button_icon").height + height: Theme.getSize("topheader_button_icon").height Label { id: button_label @@ -210,15 +136,15 @@ QtObject { { if(control.hovered) { - return UM.Theme.getColor("topbar_button_text_hovered"); + return UM.Theme.getColor("topheader_button_text_hovered"); } if(control.checked) { - return UM.Theme.getColor("topbar_button_text_active"); + return UM.Theme.getColor("topheader_button_text_active"); } else { - return UM.Theme.getColor("topbar_button_text_inactive"); + return UM.Theme.getColor("topheader_button_text_inactive"); } } } @@ -231,10 +157,10 @@ QtObject { color: UM.Theme.getColor("text_emphasis") opacity: !control.enabled ? 0.2 : 1.0 source: control.iconSource - width: visible ? Theme.getSize("topbar_button_icon").width : 0 - height: Theme.getSize("topbar_button_icon").height + width: visible ? Theme.getSize("topheader_button_icon").width : 0 + height: Theme.getSize("topheader_button_icon").height - sourceSize: Theme.getSize("topbar_button_icon") + sourceSize: Theme.getSize("topheader_button_icon") } UM.RecolorImage { @@ -245,10 +171,10 @@ QtObject { color: control.overlayColor opacity: !control.enabled ? 0.2 : 1.0 source: control.overlayIconSource - width: visible ? Theme.getSize("topbar_button_icon").width : 0 - height: Theme.getSize("topbar_button_icon").height + width: visible ? Theme.getSize("topheader_button_icon").width : 0 + height: Theme.getSize("topheader_button_icon").height - sourceSize: Theme.getSize("topbar_button_icon") + sourceSize: Theme.getSize("topheader_button_icon") } } } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 43d892c34c..74644c4de9 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -79,12 +79,11 @@ "border": [127, 127, 127, 255], "secondary": [245, 245, 245, 255], - "topbar_background_color": [255, 255, 255, 0], - "topbar_background_color_monitoring": [255, 255, 255, 255], + "topheader_background": [255, 255, 255, 255], - "topbar_button_text_active": [0, 0, 0, 255], - "topbar_button_text_inactive": [128, 128, 128, 255], - "topbar_button_text_hovered": [0, 0, 0, 255], + "topheader_button_text_active": [0, 0, 0, 255], + "topheader_button_text_inactive": [128, 128, 128, 255], + "topheader_button_text_hovered": [0, 0, 0, 255], "text": [0, 0, 0, 255], "text_detail": [174, 174, 174, 128], @@ -317,6 +316,10 @@ "printer_config_matched": [12, 169, 227, 255], "printer_config_mismatch": [127, 127, 127, 255], + "toolbox_header_button_text_active": [0, 0, 0, 255], + "toolbox_header_button_text_inactive": [128, 128, 128, 255], + "toolbox_header_button_text_hovered": [0, 0, 0, 255], + "favorites_header_bar": [245, 245, 245, 255], "favorites_header_hover": [245, 245, 245, 255], "favorites_header_text": [31, 36, 39, 255], @@ -332,6 +335,13 @@ "sizes": { "window_minimum_size": [70, 50], + "topheader": [0.0, 4.0], + "topheader_logo_right_margin": [3, 0], + "topheader_button": [8, 4], + "topheader_button_icon": [1.2, 1.2], + + "views_selector": [0.0, 4.0], + "default_lining": [0.08, 0.08], "default_arrow": [0.8, 0.8], "logo": [7.6, 1.6], @@ -390,10 +400,6 @@ "printer_status_icon": [1.8, 1.8], "printer_sync_icon": [1.2, 1.2], - "topbar_logo_right_margin": [3, 0], - "topbar_button": [8, 4], - "topbar_button_icon": [1.2, 1.2], - "button_tooltip": [1.0, 1.3], "button_tooltip_arrow": [0.25, 0.25], From 41add97b135482b19b23246793d52d32b992a7d0 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 8 Oct 2018 14:50:13 +0200 Subject: [PATCH 0006/1292] Add Toolbox shortcut to the TopHeader and align the stage tabs to the center. Contributes to CURA-5784. --- resources/qml/Cura.qml | 13 ----------- resources/qml/Skeleton/ApplicationMenu.qml | 27 +++++++++++++++++++--- resources/qml/Skeleton/TopHeader.qml | 26 +++++++++++++++++---- resources/themes/cura-light/theme.json | 1 - 4 files changed, 46 insertions(+), 21 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index b7245b1b65..445bfb6ec9 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -422,19 +422,6 @@ UM.MainWindow } } - UM.ExtensionModel { - id: curaExtensions - } - - // show the plugin browser dialog - Connections - { - target: Cura.Actions.browsePackages - onTriggered: { - curaExtensions.callExtensionMethod("Toolbox", "browsePackages") - } - } - Timer { id: createProfileTimer diff --git a/resources/qml/Skeleton/ApplicationMenu.qml b/resources/qml/Skeleton/ApplicationMenu.qml index 97d8f7ca7e..a8774e8ceb 100644 --- a/resources/qml/Skeleton/ApplicationMenu.qml +++ b/resources/qml/Skeleton/ApplicationMenu.qml @@ -180,7 +180,7 @@ Item Menu { - id: extension_menu + id: extensionMenu title: catalog.i18nc("@title:menu menubar:toplevel","E&xtensions") Instantiator @@ -207,8 +207,8 @@ Item } } - onObjectAdded: extension_menu.insertItem(index, object) - onObjectRemoved: extension_menu.removeItem(object) + onObjectAdded: extensionMenu.insertItem(index, object) + onObjectRemoved: extensionMenu.removeItem(object) } } @@ -241,6 +241,10 @@ Item } } + // ############################################################################################### + // Definition of other components that are linked to the menus + // ############################################################################################### + WorkspaceSummaryDialog { id: saveWorkspaceDialog @@ -263,6 +267,14 @@ Item } } + UM.ExtensionModel { + id: curaExtensions + } + + // ############################################################################################### + // Definition of all the connections + // ############################################################################################### + Connections { target: Cura.Actions.newProject @@ -274,4 +286,13 @@ Item } } } + + // show the plugin browser dialog + Connections + { + target: Cura.Actions.browsePackages + onTriggered: { + curaExtensions.callExtensionMethod("Toolbox", "browsePackages") + } + } } \ No newline at end of file diff --git a/resources/qml/Skeleton/TopHeader.qml b/resources/qml/Skeleton/TopHeader.qml index bdc9afd0cc..bf92fbb41d 100644 --- a/resources/qml/Skeleton/TopHeader.qml +++ b/resources/qml/Skeleton/TopHeader.qml @@ -33,15 +33,19 @@ Rectangle Row { - id: stagesMenuContainer - anchors.left: logo.right - anchors.leftMargin: UM.Theme.getSize("topheader_logo_right_margin").width + id: stagesListContainer + + anchors + { + horizontalCenter: parent.horizontalCenter + leftMargin: UM.Theme.getSize("default_margin").width + } spacing: UM.Theme.getSize("default_margin").width // The topheader is dynamically filled with all available stages Repeater { - id: stagesMenu + id: stagesHeader model: UM.StageModel { } @@ -63,4 +67,18 @@ Rectangle ExclusiveGroup { id: topheaderMenuGroup } } + + // Shortcut button to quick access the Toolbox + Button + { + id: toolboxShortcutButton + text: catalog.i18nc("@action:button", "Toolbox") + anchors + { + right: parent.right + leftMargin: UM.Theme.getSize("default_margin").width + } + style: UM.Theme.styles.topheader_tab + action: Cura.Actions.browsePackages + } } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 74644c4de9..f5372bbb0f 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -336,7 +336,6 @@ "window_minimum_size": [70, 50], "topheader": [0.0, 4.0], - "topheader_logo_right_margin": [3, 0], "topheader_button": [8, 4], "topheader_button_icon": [1.2, 1.2], From 2ffcf03f43e7c68a57471123a2a221be13d964d1 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 8 Oct 2018 17:35:24 +0200 Subject: [PATCH 0007/1292] Create an AvatarImage component that will show the profile image of the user. Still WIP. Create an AccountWidget (WIP) that shows the avatar image and the dropdown menu to manage accounts. Contributes to CURA-5784. --- resources/qml/Skeleton/ApplicationViews.qml | 2 + resources/qml/Skeleton/TopHeader.qml | 17 ++++- .../qml/Skeleton/components/AccountWidget.qml | 71 ++++++++++++++++++ .../qml/Skeleton/components/AvatarImage.qml | 42 +++++++++++ .../{ => components}/OrientationViews.qml | 0 .../themes/cura-light/icons/circle_mask.svg | 64 ++++++++++++++++ .../cura-light/images/avatar_default.png | Bin 0 -> 3115 bytes 7 files changed, 193 insertions(+), 3 deletions(-) create mode 100644 resources/qml/Skeleton/components/AccountWidget.qml create mode 100644 resources/qml/Skeleton/components/AvatarImage.qml rename resources/qml/Skeleton/{ => components}/OrientationViews.qml (100%) create mode 100644 resources/themes/cura-light/icons/circle_mask.svg create mode 100644 resources/themes/cura-light/images/avatar_default.png diff --git a/resources/qml/Skeleton/ApplicationViews.qml b/resources/qml/Skeleton/ApplicationViews.qml index 8e0b6efc0b..25c2ff9983 100644 --- a/resources/qml/Skeleton/ApplicationViews.qml +++ b/resources/qml/Skeleton/ApplicationViews.qml @@ -9,6 +9,8 @@ import QtQuick.Layouts 1.1 import UM 1.4 as UM import Cura 1.0 as Cura +import "components" + // This item contains the views selector, a combobox that is dinamically created from // the list of available Views (packages that create different visualizactions of the // scene. Aside the selector, there is a row of buttons that change the orientation of the view. diff --git a/resources/qml/Skeleton/TopHeader.qml b/resources/qml/Skeleton/TopHeader.qml index bf92fbb41d..c2e03aa04b 100644 --- a/resources/qml/Skeleton/TopHeader.qml +++ b/resources/qml/Skeleton/TopHeader.qml @@ -4,11 +4,12 @@ import QtQuick 2.2 import QtQuick.Controls 1.1 import QtQuick.Controls.Styles 1.1 -import QtQuick.Layouts 1.1 import UM 1.4 as UM import Cura 1.0 as Cura +import "components" + Rectangle { id: base @@ -75,10 +76,20 @@ Rectangle text: catalog.i18nc("@action:button", "Toolbox") anchors { - right: parent.right - leftMargin: UM.Theme.getSize("default_margin").width + right: accountWidget.left + rightMargin: UM.Theme.getSize("default_margin").width } style: UM.Theme.styles.topheader_tab action: Cura.Actions.browsePackages } + + AccountWidget + { + id: accountWidget + anchors + { + right: parent.right + rightMargin: UM.Theme.getSize("default_margin").width + } + } } diff --git a/resources/qml/Skeleton/components/AccountWidget.qml b/resources/qml/Skeleton/components/AccountWidget.qml new file mode 100644 index 0000000000..3d33aeaf27 --- /dev/null +++ b/resources/qml/Skeleton/components/AccountWidget.qml @@ -0,0 +1,71 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 1.1 + +import UM 1.4 as UM + +Item +{ + id: base + height: UM.Theme.getSize("topheader").height + width: UM.Theme.getSize("topheader").height + + AvatarImage + { + id: avatar + width: Math.round(0.8 * parent.width) + height: Math.round(0.8 * parent.height) + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + } + + MouseArea + { + anchors.fill: avatar + onClicked: + { + // Collapse/Expand the dropdown panel + accountManagementPanel.visible = !accountManagementPanel.visible + } + } + + UM.PointingRectangle + { + id: accountManagementPanel + + width: 250 + height: 250 + + anchors + { + top: parent.bottom + topMargin: UM.Theme.getSize("default_margin").height + right: parent.right + } + + target: Qt.point(parent.width / 2, parent.bottom) + arrowSize: UM.Theme.getSize("default_arrow").width + + visible: false + opacity: visible ? 1 : 0 + Behavior on opacity { NumberAnimation { duration: 100 } } + + color: UM.Theme.getColor("tool_panel_background") + borderColor: UM.Theme.getColor("lining") + borderWidth: UM.Theme.getSize("default_lining").width + + Loader + { + id: panel + sourceComponent: login + } + } + + Component + { + id: login + Label {text: "HOLA"} + } +} \ No newline at end of file diff --git a/resources/qml/Skeleton/components/AvatarImage.qml b/resources/qml/Skeleton/components/AvatarImage.qml new file mode 100644 index 0000000000..52e2757cbf --- /dev/null +++ b/resources/qml/Skeleton/components/AvatarImage.qml @@ -0,0 +1,42 @@ +// Copyright (c) 2018 Ultimaker B.V. +import QtQuick 2.7 +import QtQuick.Controls 2.1 +import QtGraphicalEffects 1.0 + +import UM 1.4 as UM + +Item +{ + id: avatar + + Image + { + id: profileImage + source: UM.Theme.getImage("avatar_default") + sourceSize: Qt.size(parent.width, parent.height) + width: parent.width + height: parent.height + fillMode: Image.PreserveAspectCrop + visible: false + } + + UM.RecolorImage + { + id: profileImageMask + source: UM.Theme.getIcon("circle_mask") + sourceSize: Qt.size(parent.width, parent.height) + width: parent.width + height: parent.height + color: UM.Theme.getColor("topheader_background") + visible: false + } + + OpacityMask + { + anchors.fill: profileImage + source: profileImage + maskSource: profileImageMask + cached: true + invert: false + } +} \ No newline at end of file diff --git a/resources/qml/Skeleton/OrientationViews.qml b/resources/qml/Skeleton/components/OrientationViews.qml similarity index 100% rename from resources/qml/Skeleton/OrientationViews.qml rename to resources/qml/Skeleton/components/OrientationViews.qml diff --git a/resources/themes/cura-light/icons/circle_mask.svg b/resources/themes/cura-light/icons/circle_mask.svg new file mode 100644 index 0000000000..d5bfe53a97 --- /dev/null +++ b/resources/themes/cura-light/icons/circle_mask.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/resources/themes/cura-light/images/avatar_default.png b/resources/themes/cura-light/images/avatar_default.png new file mode 100644 index 0000000000000000000000000000000000000000..0c306680f721dba0de73fb7be90fe5c548608692 GIT binary patch literal 3115 zcmbVOX*iS%8y@?FGN>;UW^hD^kmA@)wk*+Nt%xutWD5~v3CY&j$IjT-F&O*4hwKUE z94T3j?C-quPWgQQzF+4%*LPp{bv?_E`&q8%$MgEOiQZ{;0d^P+cG^H6Z4QGmp16!K zIMa#gEfyO(2~=(y-Mu-mK<{6mcg{kT38-cisu+e!2WiFqw8CCm*DTcYfleBQa=K}W z6fmrs>RSxBWCM@Vj~=ESx#R%hHPqgDdjCgy-55mZ0NwL}%npz|24!@BLFH5j!qLkL zYV#yS8iV2+LAQLsJr9VdfK8Lo(>x%t3GDqyFX*KOlmd^^jtcr{9kWn!Gnm{0woE~< z$>3wckweDO8#35B4Yf@}F=Ws_{mA|#QxCSyK;0kc*}S| z044`$nu0n`l;`O_ML=*R6<0}(sR!fg!TcT?c^vATgRr?kSQRy|hvr`fWOjm%nMY5u zfY54c?K{Yu2xN7FIbAf@93Z<3^e6zH6#!*}v=?Q-i*lfO3QC}Wr318xT51%D8eIoA zyob`;z~BmMNF~)N3uv5x^15kp4Pamy;G6}t&p;`y;Ojatq>Aca3fN^FJ;?-~mjHgn zfKM?Hc`^bCta%4zcY?WHG(tNV+W@xDLd63#$1I?77%CZ{74^~byJ^IJT2Vi(d=PTV z2HsLm8V2x9U{VX{Nd!__KrbRt{SK-gfjkO&Kz8A*gl~BKFY~dyFwK*r`ebwANjJhOPID+-Nx%tm}=cC;EG* z#j=W=110?DuK3Bl{ogFoz#k(fe^#n1(1$%vfMY>V7)@S@FQ#q&H)`@+?Kl-^bK z5*Dlcm!jhhSB~R0IFIg|H0dW=j%nAldy31hybBvnzOL2Nhpo2Lx~EFOMGUNdm2NsG zh5GY$-DN#CudgzRh^Efe_!*-p%e97Y-;K7pxgIY#RIJYs`VqZz>L!Eb3rHt5GlMlR zQ|+fCHHETsYbaK?(h^f8C9P3RP)rBLBZ4o9U@Sal3%goW8s4#y#d6j0{<)Wp7=^xA zmh6KEYa-FyaSHr6f((MUB~<}oa|_ApZ>oS?RMp?fvA6pb)@8uYR4>Sov~I;JL1qfY zZ)bDPZ0*AFPaV2)ZsLd;p^LA&^e44huViRzijg8&Riki2?u3b0&7l<`LTw4RR^mee zvpAUkg(`gwuH9@(n$uHbP5OOZokpFY)MW!5*L_4tyXKuEt)SUG5##ky9r^)JoMbpv zf|NUO5l3~A9#e+zzDE)E<@>IarxY*!Wbc!$naWc}B=jn-Bm0DFCW*d? zNA(92M74lu;TX(}eY9}=MCk`q@I1Ou1*L9jK#uQG3kY)(3=j0ma%yJ)hzU+=XVzAk zPfLYi&2@V}M_}t>BimU%5OX4ba@i&&DOR$_4@(l1gx!bt6|2s=533TC&aBK~2+svp z?rRuhaZQIx#+$F2d?Slzb(T~#rx#G}ZUq=Y1cm0ZU=VF%K$v6l#7Y`pz%`{5V^RPapBoiInb0l{pRd3o5KK;rtv`vVp?zlnlPr52w` zS>uLVnewJ0`RejxSbY>x$UTPBd>pU6;flx`=H|UPK?yA!(FYegvW@Et&~D;nND}3| ztq~?JW5b{R+MD|ZW@#Ab;~vW3b)dt#lFcipr9L7L%TVG&rFkEGnj*>R4BVS?PO-3y z4ze|P^z~c!+2)pHb%7>U2gj$89m7G4-m7$98nNIk>u_bpLH{ocJG{?_X*St}D6^H> z$%caxp)Gucn$HILak_Zsa*+(jvK>}iD_Z~S}J(c6PmtYBo}LxjmnoK3eG!M|T8dU$L@T2I>M z=d~V_7THE`bO%9R=q*yuV{1+B<$mWS1j=h=en2`(g1oyziM}Xl1?>z7eeQL>pmFTN zQ()LuP*JtGkVHQ{d_?iEmDxjHmFqm%sqRdX-PEvn@Ul9@3M4&Oafbsl;`-=Zmd+PyK-FW)M+61ViY?&|~d%7+HD z%C(8V!oP4UezbjFEk1@La&c~3W|KRD9O$sJV z<`iFDZ})Yu{v%7Z5z6O`v!)*0dh=(z|Ju7n%#wxowrLl`u(0j%4W0b*;}TVNL-BLR zZBeKxzfCU=cJy9aMG|NBD&Vl6Xm+dq5V%ULzP@Cnsrv=}fKA73t=t18I&(0E*6rHh zc)+KQX>Ca4eyi%o+biNHRBBJWm_EhKU;c=e6r1JPYdD1P|1u|6FmAiMGf3QAG10YL zOXi`gW9SEhy0*)4GE_IbwMG};&_T%#7H^&AV6@752f;Mx@s)kZLC-5TV`=lvZpi9* zIj4h!ck3zKYKg70(Y>uBL}0%HzXQZ2`q`XI{#%X-s>9lv9NRv+uKIW*$(numCzf09 z!uH;>W9=!@K5!lsuG<&wyJewqoJq`;)QVkN9zND{N)=Ix|4NmTmpixnY|ZVLc*aBo zU;6!b%cyIe$i0ClV5``j*k}kfrh!ZuL_7fxlLIYRP;~?)^X>KgE9jZXbIB;nPZ9b8 zomui?yg!g(Er5CC_boxR32;6cwb;VIt+4*!Ot@;A9#QOtvh<#U$dhwX2G-oDAKvqh z=S98$;z_d+JJJ+79UM>+` zZEH_9OHbEqx^_qRt3w3gdZzqkh!;+lN;YeWmHYh`e~|*5l$mTMb&n05Oo)P-Yx;HFQ2VR8c z;?Slc3;~iRk;A?|gGJ;GLO00@xhLA=BEx}p7m2MVX|BrkxCs3=$02g;ns!G2 Date: Tue, 9 Oct 2018 15:58:13 +0200 Subject: [PATCH 0008/1292] Add the callout panel to the account panel, with the two components that will show up when the user is logged in or when not. Contributes to CURA-5784. --- .../components => Accounts}/AccountWidget.qml | 32 ++++++---- .../components => Accounts}/AvatarImage.qml | 4 +- .../qml/Accounts/GeneralManagementWidget.qml | 23 +++++++ .../qml/Accounts/UserManagementWidget.qml | 33 ++++++++++ resources/qml/Cura.qml | 1 + resources/qml/Skeleton/ApplicationViews.qml | 2 +- resources/qml/Skeleton/TopHeader.qml | 2 +- resources/qml/components/ActionButton.qml | 61 +++++++++++++++++++ .../components/OrientationViews.qml | 0 9 files changed, 143 insertions(+), 15 deletions(-) rename resources/qml/{Skeleton/components => Accounts}/AccountWidget.qml (60%) rename resources/qml/{Skeleton/components => Accounts}/AvatarImage.qml (88%) create mode 100644 resources/qml/Accounts/GeneralManagementWidget.qml create mode 100644 resources/qml/Accounts/UserManagementWidget.qml create mode 100644 resources/qml/components/ActionButton.qml rename resources/qml/{Skeleton => }/components/OrientationViews.qml (100%) diff --git a/resources/qml/Skeleton/components/AccountWidget.qml b/resources/qml/Accounts/AccountWidget.qml similarity index 60% rename from resources/qml/Skeleton/components/AccountWidget.qml rename to resources/qml/Accounts/AccountWidget.qml index 3d33aeaf27..89f9acd8cc 100644 --- a/resources/qml/Skeleton/components/AccountWidget.qml +++ b/resources/qml/Accounts/AccountWidget.qml @@ -5,10 +5,14 @@ import QtQuick 2.2 import QtQuick.Controls 1.1 import UM 1.4 as UM +import Cura 1.1 as Cura Item { - id: base + id: accountWidget + property var profile: Cura.API.account.userProfile + property var loggedIn: Cura.API.account.isLoggedIn + property var logoutCallback: Cura.API.account.logout height: UM.Theme.getSize("topheader").height width: UM.Theme.getSize("topheader").height @@ -19,24 +23,21 @@ Item height: Math.round(0.8 * parent.height) anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter + source: loggedIn ? profile["profile_image_url"] : UM.Theme.getImage("avatar_default") } MouseArea { - anchors.fill: avatar - onClicked: - { - // Collapse/Expand the dropdown panel - accountManagementPanel.visible = !accountManagementPanel.visible - } + anchors.fill: parent + onClicked: accountManagementPanel.visible = !accountManagementPanel.visible // Collapse/Expand the dropdown panel } UM.PointingRectangle { id: accountManagementPanel - width: 250 - height: 250 + width: panel.width + height: panel.height anchors { @@ -56,16 +57,23 @@ Item borderColor: UM.Theme.getColor("lining") borderWidth: UM.Theme.getSize("default_lining").width + // Shows the user management options or general options to create account Loader { id: panel - sourceComponent: login + sourceComponent: loggedIn ? userManagementWidget : generalManagementWidget } } Component { - id: login - Label {text: "HOLA"} + id: userManagementWidget + UserManagementWidget { } + } + + Component + { + id: generalManagementWidget + GeneralManagementWidget { } } } \ No newline at end of file diff --git a/resources/qml/Skeleton/components/AvatarImage.qml b/resources/qml/Accounts/AvatarImage.qml similarity index 88% rename from resources/qml/Skeleton/components/AvatarImage.qml rename to resources/qml/Accounts/AvatarImage.qml index 52e2757cbf..18ac19a45d 100644 --- a/resources/qml/Skeleton/components/AvatarImage.qml +++ b/resources/qml/Accounts/AvatarImage.qml @@ -9,10 +9,12 @@ Item { id: avatar + property var source + Image { id: profileImage - source: UM.Theme.getImage("avatar_default") + source: avatar.source ? avatar.source : UM.Theme.getImage("avatar_default") sourceSize: Qt.size(parent.width, parent.height) width: parent.width height: parent.height diff --git a/resources/qml/Accounts/GeneralManagementWidget.qml b/resources/qml/Accounts/GeneralManagementWidget.qml new file mode 100644 index 0000000000..2bb0c89f98 --- /dev/null +++ b/resources/qml/Accounts/GeneralManagementWidget.qml @@ -0,0 +1,23 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 1.1 + +import UM 1.4 as UM +import Cura 1.1 as Cura + +import "../components" + +Column +{ + ActionButton + { + text: catalog.i18nc("@button", "Sign In") + color: "transparent" + hoverColor: "transparent" + textColor: UM.Theme.getColor("text") + textHoverColor: UM.Theme.getColor("text_link") + onClicked: Cura.API.account.login() + } +} \ No newline at end of file diff --git a/resources/qml/Accounts/UserManagementWidget.qml b/resources/qml/Accounts/UserManagementWidget.qml new file mode 100644 index 0000000000..24f4966679 --- /dev/null +++ b/resources/qml/Accounts/UserManagementWidget.qml @@ -0,0 +1,33 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 1.1 + +import UM 1.4 as UM +import Cura 1.1 as Cura + +import "../components" + +Column +{ + ActionButton + { + text: catalog.i18nc("@button", "Manage Profile") + color: "transparent" + hoverColor: "transparent" + textColor: UM.Theme.getColor("text") + textHoverColor: UM.Theme.getColor("text_link") + onClicked: Qt.openUrlExternally("https://account.ultimaker.com") + } + + ActionButton + { + text: catalog.i18nc("@button", "Sign Out") + color: "transparent" + hoverColor: "transparent" + textColor: UM.Theme.getColor("text") + textHoverColor: UM.Theme.getColor("text_link") + onClicked: Cura.API.account.logout() + } +} \ No newline at end of file diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 445bfb6ec9..16bae8aa3b 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -105,6 +105,7 @@ UM.MainWindow width: parent.width height: parent.height - menu.height - topHeader.height + z: topHeader.z - 1 Keys.forwardTo: menu diff --git a/resources/qml/Skeleton/ApplicationViews.qml b/resources/qml/Skeleton/ApplicationViews.qml index 25c2ff9983..b3d08ab627 100644 --- a/resources/qml/Skeleton/ApplicationViews.qml +++ b/resources/qml/Skeleton/ApplicationViews.qml @@ -9,7 +9,7 @@ import QtQuick.Layouts 1.1 import UM 1.4 as UM import Cura 1.0 as Cura -import "components" +import "../components" // This item contains the views selector, a combobox that is dinamically created from // the list of available Views (packages that create different visualizactions of the diff --git a/resources/qml/Skeleton/TopHeader.qml b/resources/qml/Skeleton/TopHeader.qml index c2e03aa04b..fedb00898f 100644 --- a/resources/qml/Skeleton/TopHeader.qml +++ b/resources/qml/Skeleton/TopHeader.qml @@ -8,7 +8,7 @@ import QtQuick.Controls.Styles 1.1 import UM 1.4 as UM import Cura 1.0 as Cura -import "components" +import "../Accounts" Rectangle { diff --git a/resources/qml/components/ActionButton.qml b/resources/qml/components/ActionButton.qml new file mode 100644 index 0000000000..02c279a458 --- /dev/null +++ b/resources/qml/components/ActionButton.qml @@ -0,0 +1,61 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.1 +import QtQuick.Layouts 1.3 + +import UM 1.1 as UM + +Button +{ + id: button + property alias cursorShape: mouseArea.cursorShape + property var iconSource: "" + property var color: UM.Theme.getColor("primary") + property var hoverColor: UM.Theme.getColor("primary_hover") + property var disabledColor: color + property var textColor: UM.Theme.getColor("button_text") + property var textHoverColor: UM.Theme.getColor("button_text_hover") + property var textDisabledColor: textColor + property var textFont: UM.Theme.getFont("action_button") + + contentItem: Row + { + UM.RecolorImage + { + id: buttonIcon + source: button.iconSource + width: 16 * screenScaleFactor + height: 16 * screenScaleFactor + sourceSize.width: width + sourceSize.height: height + color: button.hovered ? button.textHoverColor : button.textColor + visible: button.iconSource != "" + } + + Label + { + id: buttonText + text: button.text + color: button.enabled ? (button.hovered ? button.textHoverColor : button.textColor): button.textDisabledColor + font: button.textFont + visible: button.text != "" + renderType: Text.NativeRendering + } + } + + background: Rectangle + { + color: button.enabled ? (button.hovered ? button.hoverColor : button.color) : button.disabledColor + } + + MouseArea + { + id: mouseArea + anchors.fill: parent + onPressed: mouse.accepted = false + hoverEnabled: true + cursorShape: button.enabled ? (hovered ? Qt.PointingHandCursor : Qt.ArrowCursor) : Qt.ForbiddenCursor + } +} diff --git a/resources/qml/Skeleton/components/OrientationViews.qml b/resources/qml/components/OrientationViews.qml similarity index 100% rename from resources/qml/Skeleton/components/OrientationViews.qml rename to resources/qml/components/OrientationViews.qml From 49e96980f124381410b3e6f34cd1c9c1737178d0 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 9 Oct 2018 17:11:01 +0200 Subject: [PATCH 0009/1292] Store the dialogs in a folder called Dialogs. Contributes to CURA-5784. --- resources/qml/{Accounts => Account}/AccountWidget.qml | 0 resources/qml/{Accounts => Account}/AvatarImage.qml | 0 resources/qml/{Accounts => Account}/GeneralManagementWidget.qml | 0 resources/qml/{Accounts => Account}/UserManagementWidget.qml | 0 resources/qml/Cura.qml | 1 + resources/qml/{ => Dialogs}/AboutDialog.qml | 0 resources/qml/{ => Dialogs}/AddMachineDialog.qml | 0 resources/qml/{ => Dialogs}/AskOpenAsProjectOrModelsDialog.qml | 0 .../qml/{ => Dialogs}/DiscardOrKeepProfileChangesDialog.qml | 0 .../qml/{ => Dialogs}/OpenFilesIncludingProjectsDialog.qml | 0 resources/qml/Menus/RecentFilesMenu.qml | 2 ++ resources/qml/Skeleton/TopHeader.qml | 2 +- 12 files changed, 4 insertions(+), 1 deletion(-) rename resources/qml/{Accounts => Account}/AccountWidget.qml (100%) rename resources/qml/{Accounts => Account}/AvatarImage.qml (100%) rename resources/qml/{Accounts => Account}/GeneralManagementWidget.qml (100%) rename resources/qml/{Accounts => Account}/UserManagementWidget.qml (100%) rename resources/qml/{ => Dialogs}/AboutDialog.qml (100%) rename resources/qml/{ => Dialogs}/AddMachineDialog.qml (100%) rename resources/qml/{ => Dialogs}/AskOpenAsProjectOrModelsDialog.qml (100%) rename resources/qml/{ => Dialogs}/DiscardOrKeepProfileChangesDialog.qml (100%) rename resources/qml/{ => Dialogs}/OpenFilesIncludingProjectsDialog.qml (100%) diff --git a/resources/qml/Accounts/AccountWidget.qml b/resources/qml/Account/AccountWidget.qml similarity index 100% rename from resources/qml/Accounts/AccountWidget.qml rename to resources/qml/Account/AccountWidget.qml diff --git a/resources/qml/Accounts/AvatarImage.qml b/resources/qml/Account/AvatarImage.qml similarity index 100% rename from resources/qml/Accounts/AvatarImage.qml rename to resources/qml/Account/AvatarImage.qml diff --git a/resources/qml/Accounts/GeneralManagementWidget.qml b/resources/qml/Account/GeneralManagementWidget.qml similarity index 100% rename from resources/qml/Accounts/GeneralManagementWidget.qml rename to resources/qml/Account/GeneralManagementWidget.qml diff --git a/resources/qml/Accounts/UserManagementWidget.qml b/resources/qml/Account/UserManagementWidget.qml similarity index 100% rename from resources/qml/Accounts/UserManagementWidget.qml rename to resources/qml/Account/UserManagementWidget.qml diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 16bae8aa3b..2af085fee7 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -10,6 +10,7 @@ import QtQuick.Dialogs 1.2 import UM 1.3 as UM import Cura 1.1 as Cura +import "Dialogs" import "Menus" import "Skeleton" diff --git a/resources/qml/AboutDialog.qml b/resources/qml/Dialogs/AboutDialog.qml similarity index 100% rename from resources/qml/AboutDialog.qml rename to resources/qml/Dialogs/AboutDialog.qml diff --git a/resources/qml/AddMachineDialog.qml b/resources/qml/Dialogs/AddMachineDialog.qml similarity index 100% rename from resources/qml/AddMachineDialog.qml rename to resources/qml/Dialogs/AddMachineDialog.qml diff --git a/resources/qml/AskOpenAsProjectOrModelsDialog.qml b/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml similarity index 100% rename from resources/qml/AskOpenAsProjectOrModelsDialog.qml rename to resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml diff --git a/resources/qml/DiscardOrKeepProfileChangesDialog.qml b/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml similarity index 100% rename from resources/qml/DiscardOrKeepProfileChangesDialog.qml rename to resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml diff --git a/resources/qml/OpenFilesIncludingProjectsDialog.qml b/resources/qml/Dialogs/OpenFilesIncludingProjectsDialog.qml similarity index 100% rename from resources/qml/OpenFilesIncludingProjectsDialog.qml rename to resources/qml/Dialogs/OpenFilesIncludingProjectsDialog.qml diff --git a/resources/qml/Menus/RecentFilesMenu.qml b/resources/qml/Menus/RecentFilesMenu.qml index 12f53fb517..0f1f67b6fa 100644 --- a/resources/qml/Menus/RecentFilesMenu.qml +++ b/resources/qml/Menus/RecentFilesMenu.qml @@ -7,6 +7,8 @@ import QtQuick.Controls 1.1 import UM 1.3 as UM import Cura 1.0 as Cura +import "../Dialogs" + Menu { id: menu diff --git a/resources/qml/Skeleton/TopHeader.qml b/resources/qml/Skeleton/TopHeader.qml index fedb00898f..5013c12703 100644 --- a/resources/qml/Skeleton/TopHeader.qml +++ b/resources/qml/Skeleton/TopHeader.qml @@ -8,7 +8,7 @@ import QtQuick.Controls.Styles 1.1 import UM 1.4 as UM import Cura 1.0 as Cura -import "../Accounts" +import "../Account" Rectangle { From 0df7fa1a6cb4e2ac0284fb9300c3025a692bab0a Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 10 Oct 2018 11:04:08 +0200 Subject: [PATCH 0010/1292] Add style to the top header tabs. Contributes to CURA-5784. --- resources/qml/Skeleton/TopHeader.qml | 3 +- resources/themes/cura-light/images/logo.svg | 200 +++++++++++++++----- resources/themes/cura-light/styles.qml | 109 ++++------- resources/themes/cura-light/theme.json | 12 +- 4 files changed, 195 insertions(+), 129 deletions(-) diff --git a/resources/qml/Skeleton/TopHeader.qml b/resources/qml/Skeleton/TopHeader.qml index 5013c12703..8cb568df4d 100644 --- a/resources/qml/Skeleton/TopHeader.qml +++ b/resources/qml/Skeleton/TopHeader.qml @@ -41,7 +41,6 @@ Rectangle horizontalCenter: parent.horizontalCenter leftMargin: UM.Theme.getSize("default_margin").width } - spacing: UM.Theme.getSize("default_margin").width // The topheader is dynamically filled with all available stages Repeater @@ -52,7 +51,7 @@ Rectangle delegate: Button { - text: model.name + text: model.name.toUpperCase() checkable: true checked: model.active exclusiveGroup: topheaderMenuGroup diff --git a/resources/themes/cura-light/images/logo.svg b/resources/themes/cura-light/images/logo.svg index 5fa5895443..89692f8295 100644 --- a/resources/themes/cura-light/images/logo.svg +++ b/resources/themes/cura-light/images/logo.svg @@ -1,4 +1,6 @@ + + + id="svg8" + inkscape:version="0.92.2 (5c3e80d, 2017-08-06)" + sodipodi:docname="logo.svg"> + + + id="metadata5"> @@ -26,47 +49,124 @@ - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index b54d12e07b..ba0350fd4b 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -90,92 +90,57 @@ QtObject { } } - property Component topheader_tab: Component { - ButtonStyle { - background: Item { - implicitHeight: Theme.getSize("topheader_button").height - implicitWidth: Theme.getSize("topheader_button").width + Theme.getSize("topheader_button_icon").width + property Component topheader_tab: Component + { + ButtonStyle + { + // This property will be back-propagated when the width of the label is calculated + property var buttonWidth: 0 - Rectangle { - id: buttonFace; - anchors.fill: parent; + background: Rectangle + { + id: buttonFace + implicitHeight: control.height + implicitWidth: buttonWidth + color: control.checked ? UM.Theme.getColor("topheader_button_background_active") : UM.Theme.getColor("topheader_button_background_inactive") - color: "transparent" - Behavior on color { ColorAnimation { duration: 50; } } - - Rectangle { - id: underline; - - anchors.horizontalCenter: parent.horizontalCenter - anchors.bottom: parent.bottom - width: Theme.getSize("topheader_button").width + Theme.getSize("topheader_button_icon").width - height: Theme.getSize("sidebar_header_highlight").height - color: control.checked ? UM.Theme.getColor("sidebar_header_highlight") : UM.Theme.getColor("sidebar_header_highlight_hover") - visible: control.hovered || control.checked - } - } + Behavior on color { ColorAnimation { duration: 50 } } } label: Item { - implicitHeight: Theme.getSize("topheader_button_icon").height - implicitWidth: Theme.getSize("topheader_button").width + Theme.getSize("topheader_button_icon").width - Item + id: contents + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + height: control.height + width: buttonLabel.width + 4 * UM.Theme.getSize("default_margin").width + + Label { + id: buttonLabel + text: control.text + anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter; - width: childrenRect.width - height: Theme.getSize("topheader_button_icon").height - Label + font: UM.Theme.getFont("medium_bold") + color: { - id: button_label - text: control.text; - anchors.verticalCenter: parent.verticalCenter; - font: control.checked ? UM.Theme.getFont("large") : UM.Theme.getFont("large_nonbold") - color: + if (control.checked) { - if(control.hovered) + return UM.Theme.getColor("topheader_button_text_active") + } + else + { + if (control.hovered) { - return UM.Theme.getColor("topheader_button_text_hovered"); - } - if(control.checked) - { - return UM.Theme.getColor("topheader_button_text_active"); - } - else - { - return UM.Theme.getColor("topheader_button_text_inactive"); + return UM.Theme.getColor("topheader_button_text_hovered") } + return UM.Theme.getColor("topheader_button_text_inactive") } } - UM.RecolorImage - { - visible: control.iconSource != "" - id: icon - anchors.left: button_label.right - anchors.leftMargin: (icon.visible || overlayIcon.visible) ? Theme.getSize("default_margin").width : 0 - color: UM.Theme.getColor("text_emphasis") - opacity: !control.enabled ? 0.2 : 1.0 - source: control.iconSource - width: visible ? Theme.getSize("topheader_button_icon").width : 0 - height: Theme.getSize("topheader_button_icon").height - - sourceSize: Theme.getSize("topheader_button_icon") - } - UM.RecolorImage - { - id: overlayIcon - anchors.left: button_label.right - anchors.leftMargin: (icon.visible || overlayIcon.visible) ? Theme.getSize("default_margin").width : 0 - visible: control.overlayIconSource != "" && control.iconSource != "" - color: control.overlayColor - opacity: !control.enabled ? 0.2 : 1.0 - source: control.overlayIconSource - width: visible ? Theme.getSize("topheader_button_icon").width : 0 - height: Theme.getSize("topheader_button_icon").height - - sourceSize: Theme.getSize("topheader_button_icon") - } + } + Component.onCompleted: + { + buttonWidth = width } } } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index f5372bbb0f..e49824ae74 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -79,11 +79,13 @@ "border": [127, 127, 127, 255], "secondary": [245, 245, 245, 255], - "topheader_background": [255, 255, 255, 255], + "topheader_background": [12, 169, 227, 255], - "topheader_button_text_active": [0, 0, 0, 255], - "topheader_button_text_inactive": [128, 128, 128, 255], + "topheader_button_text_active": [12, 169, 227, 255], + "topheader_button_text_inactive": [255, 255, 255, 255], "topheader_button_text_hovered": [0, 0, 0, 255], + "topheader_button_background_active": [255, 255, 255, 255], + "topheader_button_background_inactive": [255, 255, 255, 0], "text": [0, 0, 0, 255], "text_detail": [174, 174, 174, 128], @@ -335,7 +337,7 @@ "sizes": { "window_minimum_size": [70, 50], - "topheader": [0.0, 4.0], + "topheader": [0.0, 4.5], "topheader_button": [8, 4], "topheader_button_icon": [1.2, 1.2], @@ -343,7 +345,7 @@ "default_lining": [0.08, 0.08], "default_arrow": [0.8, 0.8], - "logo": [7.6, 1.6], + "logo": [8, 2.4], "default_margin": [1.0, 1.0], "wide_margin": [2.0, 2.0], From b89c220a4d43e423432af9b4b032de077727fcbf Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 10 Oct 2018 11:17:09 +0200 Subject: [PATCH 0011/1292] Add linings between tabs in the top header. Contributes to CURA-5784. --- resources/themes/cura-light/styles.qml | 34 ++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index ba0350fd4b..b08d9e8728 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -97,14 +97,38 @@ QtObject { // This property will be back-propagated when the width of the label is calculated property var buttonWidth: 0 - background: Rectangle + background: Item { - id: buttonFace implicitHeight: control.height - implicitWidth: buttonWidth - color: control.checked ? UM.Theme.getColor("topheader_button_background_active") : UM.Theme.getColor("topheader_button_background_inactive") + implicitWidth: buttonWidth + 2 * UM.Theme.getSize("default_lining").width - Behavior on color { ColorAnimation { duration: 50 } } + Rectangle + { + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + implicitHeight: parent.height - 2 * UM.Theme.getSize("default_margin").width + implicitWidth: UM.Theme.getSize("default_lining").width + color: UM.Theme.getColor("topheader_button_background_active") + visible: !control.checked + } + Rectangle + { + id: buttonFace + implicitHeight: parent.height + implicitWidth: parent.width + color: control.checked ? UM.Theme.getColor("topheader_button_background_active") : UM.Theme.getColor("topheader_button_background_inactive") + + Behavior on color { ColorAnimation { duration: 50 } } + } + Rectangle + { + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + implicitHeight: parent.height - 2 * UM.Theme.getSize("default_margin").width + implicitWidth: UM.Theme.getSize("default_lining").width + color: UM.Theme.getColor("topheader_button_background_active") + visible: !control.checked + } } label: Item From b3fc76092d4b957ac0462910a49b2244a982654b Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 10 Oct 2018 14:01:34 +0200 Subject: [PATCH 0012/1292] Removed unused EngineLog --- resources/qml/Actions.qml | 9 ------- resources/qml/Cura.qml | 5 ---- resources/qml/EngineLog.qml | 53 ------------------------------------- 3 files changed, 67 deletions(-) delete mode 100644 resources/qml/EngineLog.qml diff --git a/resources/qml/Actions.qml b/resources/qml/Actions.qml index 7d898eed2c..1b1881ab76 100644 --- a/resources/qml/Actions.qml +++ b/resources/qml/Actions.qml @@ -58,7 +58,6 @@ Item property alias preferences: preferencesAction; - property alias showEngineLog: showEngineLogAction; property alias showProfileFolder: showProfileFolderAction; property alias documentation: documentationAction; property alias reportBug: reportBugAction; @@ -396,14 +395,6 @@ Item shortcut: StandardKey.New } - Action - { - id: showEngineLogAction; - text: catalog.i18nc("@action:inmenu menubar:help","Show Engine &Log..."); - iconName: "view-list-text"; - shortcut: StandardKey.WhatsThis; - } - Action { id: showProfileFolderAction; diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 2af085fee7..0a6e054a5f 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -655,11 +655,6 @@ UM.MainWindow } } - EngineLog - { - id: engineLog; - } - Connections { target: Cura.Actions.showProfileFolder diff --git a/resources/qml/EngineLog.qml b/resources/qml/EngineLog.qml deleted file mode 100644 index 965587b59e..0000000000 --- a/resources/qml/EngineLog.qml +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2015 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.2 -import QtQuick.Controls 1.1 -import QtQuick.Layouts 1.1 - -import UM 1.1 as UM - -UM.Dialog -{ - id: dialog; - - //: Engine Log dialog title - title: catalog.i18nc("@title:window","Engine Log"); - - modality: Qt.NonModal; - - TextArea - { - id: textArea - anchors.fill: parent; - - Timer - { - id: updateTimer; - interval: 1000; - running: false; - repeat: true; - onTriggered: textArea.text = CuraApplication.getEngineLog(); - } - UM.I18nCatalog{id: catalog; name:"cura"} - } - - rightButtons: Button - { - //: Close engine log button - text: catalog.i18nc("@action:button","Close"); - onClicked: dialog.visible = false; - } - - onVisibleChanged: - { - if(visible) - { - textArea.text = CuraApplication.getEngineLog(); - updateTimer.start(); - } else - { - updateTimer.stop(); - } - } -} From 1ed3558b9a0489a8c479e30170040ec74ec7cb2b Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 10 Oct 2018 14:21:09 +0200 Subject: [PATCH 0013/1292] Move ViewOrientationControl to lower left corner This also renames the component to better reflect what it is (the old name implied that it had something to do with orientation views, wheres it's actually a set of controls to change orientation) CURA-5772 --- resources/qml/Cura.qml | 17 ++++++++++++++++- resources/qml/Skeleton/ApplicationViews.qml | 10 ---------- ...ionViews.qml => ViewOrientationControls.qml} | 3 ++- 3 files changed, 18 insertions(+), 12 deletions(-) rename resources/qml/components/{OrientationViews.qml => ViewOrientationControls.qml} (95%) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 0a6e054a5f..50419067b4 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -13,6 +13,7 @@ import Cura 1.1 as Cura import "Dialogs" import "Menus" import "Skeleton" +import "components" UM.MainWindow { @@ -197,7 +198,7 @@ UM.MainWindow { id: applicationViews - visible: UM.Controller.activeStage.stageId != "MonitorStage" + anchors { top: parent.top @@ -311,6 +312,20 @@ UM.MainWindow bottomMargin: UM.Theme.getSize("default_margin").height } } + + + ViewOrientationControls + { + id: viewOrientationControls + + anchors + { + left: parent.left + margins: UM.Theme.getSize("default_margin").width + + bottom: parent.bottom + } + } } } diff --git a/resources/qml/Skeleton/ApplicationViews.qml b/resources/qml/Skeleton/ApplicationViews.qml index b3d08ab627..94315a73fb 100644 --- a/resources/qml/Skeleton/ApplicationViews.qml +++ b/resources/qml/Skeleton/ApplicationViews.qml @@ -20,16 +20,6 @@ Item height: UM.Theme.getSize("views_selector").height - OrientationViews - { - id: orientationViews - - anchors { - verticalCenter: parent.verticalCenter - right: viewModeButton.left - rightMargin: UM.Theme.getSize("default_margin").width - } - } ComboBox { diff --git a/resources/qml/components/OrientationViews.qml b/resources/qml/components/ViewOrientationControls.qml similarity index 95% rename from resources/qml/components/OrientationViews.qml rename to resources/qml/components/ViewOrientationControls.qml index d1b370ed71..bf56ef2997 100644 --- a/resources/qml/components/OrientationViews.qml +++ b/resources/qml/components/ViewOrientationControls.qml @@ -13,7 +13,8 @@ Row id: viewOrientationControl spacing: 2 * screenScaleFactor - + height: childrenRect.height + width: childrenRect.width // #1 3d view Button { From 5befc0b256f93a4ad5d0199eccfcd5a023aa2be9 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 10 Oct 2018 16:34:55 +0200 Subject: [PATCH 0014/1292] Restyle the dropdown of the accounts, with information about the user and available operations that can be done when the user is logged in or not. Contributes to CURA-5784. --- resources/qml/Account/AccountDetails.qml | 77 +++++++++++++++++++ resources/qml/Account/AccountWidget.qml | 23 ++---- resources/qml/Account/AvatarImage.qml | 12 +++ .../qml/Account/GeneralManagementWidget.qml | 23 ------ resources/qml/Account/GeneralOperations.qml | 35 +++++++++ .../qml/Account/UserManagementWidget.qml | 33 -------- resources/qml/Account/UserOperations.qml | 35 +++++++++ resources/qml/Skeleton/TopHeader.qml | 24 +++++- resources/qml/components/ActionButton.qml | 4 + .../cura-light/icons/circle_outline.svg | 64 +++++++++++++++ resources/themes/cura-light/styles.qml | 8 ++ resources/themes/cura-light/theme.json | 5 ++ 12 files changed, 267 insertions(+), 76 deletions(-) create mode 100644 resources/qml/Account/AccountDetails.qml delete mode 100644 resources/qml/Account/GeneralManagementWidget.qml create mode 100644 resources/qml/Account/GeneralOperations.qml delete mode 100644 resources/qml/Account/UserManagementWidget.qml create mode 100644 resources/qml/Account/UserOperations.qml create mode 100644 resources/themes/cura-light/icons/circle_outline.svg diff --git a/resources/qml/Account/AccountDetails.qml b/resources/qml/Account/AccountDetails.qml new file mode 100644 index 0000000000..ab1ccc15df --- /dev/null +++ b/resources/qml/Account/AccountDetails.qml @@ -0,0 +1,77 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.1 + +import UM 1.4 as UM +import Cura 1.1 as Cura + +import "../components" + +Column +{ + property var profile: null + property var loggedIn: false + + padding: 2 * UM.Theme.getSize("default_margin").height + spacing: 2 * UM.Theme.getSize("default_margin").height + + AvatarImage + { + id: avatar + width: 75 * screenScaleFactor + height: 75 * screenScaleFactor + anchors.horizontalCenter: parent.horizontalCenter + source: loggedIn ? profile["profile_image_url"] : UM.Theme.getImage("avatar_default") + outlineColor: loggedIn ? UM.Theme.getColor("account_widget_ouline_active") : UM.Theme.getColor("account_widget_ouline_inactive") + } + + Label + { + id: message + anchors.horizontalCenter: parent.horizontalCenter + visible: !loggedIn + text: catalog.i18nc("@label", "Please login or create an account to 
enjoy all features of Ultimaker Cura") + } + + Column + { + id: userInformation + anchors.horizontalCenter: parent.horizontalCenter + visible: loggedIn + + Label + { + anchors.horizontalCenter: parent.horizontalCenter + text: loggedIn ? profile["username"] : "" + font: UM.Theme.getFont("large") + } + + Label + { + anchors.horizontalCenter: parent.horizontalCenter + text: "email.address@hardcoded.is" + font: UM.Theme.getFont("default") + } + } + + Loader + { + id: accountEntryPoints + anchors.horizontalCenter: parent.horizontalCenter + sourceComponent: loggedIn ? userOperations : generalOperations + } + + Component + { + id: userOperations + UserOperations { } + } + + Component + { + id: generalOperations + GeneralOperations { } + } +} \ No newline at end of file diff --git a/resources/qml/Account/AccountWidget.qml b/resources/qml/Account/AccountWidget.qml index 89f9acd8cc..1d9541de2c 100644 --- a/resources/qml/Account/AccountWidget.qml +++ b/resources/qml/Account/AccountWidget.qml @@ -1,8 +1,8 @@ // Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.2 -import QtQuick.Controls 1.1 +import QtQuick 2.7 +import QtQuick.Controls 2.1 import UM 1.4 as UM import Cura 1.1 as Cura @@ -12,7 +12,6 @@ Item id: accountWidget property var profile: Cura.API.account.userProfile property var loggedIn: Cura.API.account.isLoggedIn - property var logoutCallback: Cura.API.account.logout height: UM.Theme.getSize("topheader").height width: UM.Theme.getSize("topheader").height @@ -24,6 +23,7 @@ Item anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter source: loggedIn ? profile["profile_image_url"] : UM.Theme.getImage("avatar_default") + outlineColor: loggedIn ? UM.Theme.getColor("account_widget_ouline_active") : UM.Theme.getColor("account_widget_ouline_inactive") } MouseArea @@ -58,22 +58,11 @@ Item borderWidth: UM.Theme.getSize("default_lining").width // Shows the user management options or general options to create account - Loader + AccountDetails { id: panel - sourceComponent: loggedIn ? userManagementWidget : generalManagementWidget + profile: Cura.API.account.userProfile + loggedIn: Cura.API.account.isLoggedIn } } - - Component - { - id: userManagementWidget - UserManagementWidget { } - } - - Component - { - id: generalManagementWidget - GeneralManagementWidget { } - } } \ No newline at end of file diff --git a/resources/qml/Account/AvatarImage.qml b/resources/qml/Account/AvatarImage.qml index 18ac19a45d..96c3cd2330 100644 --- a/resources/qml/Account/AvatarImage.qml +++ b/resources/qml/Account/AvatarImage.qml @@ -10,6 +10,8 @@ Item id: avatar property var source + property var fallbackSource: UM.Theme.getImage("avatar_default") + property var outlineColor: UM.Theme.getColor("account_widget_ouline_active") Image { @@ -41,4 +43,14 @@ Item cached: true invert: false } + + UM.RecolorImage + { + id: profileImageOutline + source: UM.Theme.getIcon("circle_outline") + sourceSize: Qt.size(parent.width, parent.height) + width: parent.width + height: parent.height + color: avatar.outlineColor + } } \ No newline at end of file diff --git a/resources/qml/Account/GeneralManagementWidget.qml b/resources/qml/Account/GeneralManagementWidget.qml deleted file mode 100644 index 2bb0c89f98..0000000000 --- a/resources/qml/Account/GeneralManagementWidget.qml +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.2 -import QtQuick.Controls 1.1 - -import UM 1.4 as UM -import Cura 1.1 as Cura - -import "../components" - -Column -{ - ActionButton - { - text: catalog.i18nc("@button", "Sign In") - color: "transparent" - hoverColor: "transparent" - textColor: UM.Theme.getColor("text") - textHoverColor: UM.Theme.getColor("text_link") - onClicked: Cura.API.account.login() - } -} \ No newline at end of file diff --git a/resources/qml/Account/GeneralOperations.qml b/resources/qml/Account/GeneralOperations.qml new file mode 100644 index 0000000000..d224de44bb --- /dev/null +++ b/resources/qml/Account/GeneralOperations.qml @@ -0,0 +1,35 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 1.1 + +import UM 1.4 as UM +import Cura 1.1 as Cura + +import "../components" + +Row +{ + spacing: UM.Theme.getSize("default_margin").width + + ActionButton + { + width: UM.Theme.getSize("account_button").width + height: UM.Theme.getSize("account_button").height + text: catalog.i18nc("@button", "Create account") + color: UM.Theme.getColor("secondary") + hoverColor: UM.Theme.getColor("secondary") + textColor: UM.Theme.getColor("text_link") + textHoverColor: UM.Theme.getColor("text") + onClicked: Qt.openUrlExternally("https://account.ultimaker.com") + } + + ActionButton + { + width: UM.Theme.getSize("account_button").width + height: UM.Theme.getSize("account_button").height + text: catalog.i18nc("@button", "Login") + onClicked: Cura.API.account.login() + } +} \ No newline at end of file diff --git a/resources/qml/Account/UserManagementWidget.qml b/resources/qml/Account/UserManagementWidget.qml deleted file mode 100644 index 24f4966679..0000000000 --- a/resources/qml/Account/UserManagementWidget.qml +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.2 -import QtQuick.Controls 1.1 - -import UM 1.4 as UM -import Cura 1.1 as Cura - -import "../components" - -Column -{ - ActionButton - { - text: catalog.i18nc("@button", "Manage Profile") - color: "transparent" - hoverColor: "transparent" - textColor: UM.Theme.getColor("text") - textHoverColor: UM.Theme.getColor("text_link") - onClicked: Qt.openUrlExternally("https://account.ultimaker.com") - } - - ActionButton - { - text: catalog.i18nc("@button", "Sign Out") - color: "transparent" - hoverColor: "transparent" - textColor: UM.Theme.getColor("text") - textHoverColor: UM.Theme.getColor("text_link") - onClicked: Cura.API.account.logout() - } -} \ No newline at end of file diff --git a/resources/qml/Account/UserOperations.qml b/resources/qml/Account/UserOperations.qml new file mode 100644 index 0000000000..1704254ed3 --- /dev/null +++ b/resources/qml/Account/UserOperations.qml @@ -0,0 +1,35 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 1.1 + +import UM 1.4 as UM +import Cura 1.1 as Cura + +import "../components" + +Row +{ + spacing: UM.Theme.getSize("default_margin").width + + ActionButton + { + width: UM.Theme.getSize("account_button").width + height: UM.Theme.getSize("account_button").height + text: catalog.i18nc("@button", "Manage account") + color: UM.Theme.getColor("secondary") + hoverColor: UM.Theme.getColor("secondary") + textColor: UM.Theme.getColor("text_link") + textHoverColor: UM.Theme.getColor("text") + onClicked: Qt.openUrlExternally("https://account.ultimaker.com") + } + + ActionButton + { + width: UM.Theme.getSize("account_button").width + height: UM.Theme.getSize("account_button").height + text: catalog.i18nc("@button", "Logout") + onClicked: Cura.API.account.logout() + } +} \ No newline at end of file diff --git a/resources/qml/Skeleton/TopHeader.qml b/resources/qml/Skeleton/TopHeader.qml index 8cb568df4d..c24fe86af0 100644 --- a/resources/qml/Skeleton/TopHeader.qml +++ b/resources/qml/Skeleton/TopHeader.qml @@ -1,13 +1,14 @@ // Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.2 +import QtQuick 2.7 import QtQuick.Controls 1.1 import QtQuick.Controls.Styles 1.1 import UM 1.4 as UM import Cura 1.0 as Cura +import "../components" import "../Account" Rectangle @@ -72,13 +73,30 @@ Rectangle Button { id: toolboxShortcutButton - text: catalog.i18nc("@action:button", "Toolbox") anchors { right: accountWidget.left rightMargin: UM.Theme.getSize("default_margin").width + verticalCenter: parent.verticalCenter + } + style: ButtonStyle + { + background: Rectangle + { + color: control.hovered ? UM.Theme.getColor("secondary") : UM.Theme.getColor("topheader_button_background_active") + radius: 2 * screenScaleFactor + } + + label: Label + { + text: catalog.i18nc("@action:button", "Toolbox") + color: UM.Theme.getColor("topheader_button_text_active") + font: UM.Theme.getFont("action_button") + renderType: Text.NativeRendering + anchors.verticalCenter: control.verticalCenter + } + } - style: UM.Theme.styles.topheader_tab action: Cura.Actions.browsePackages } diff --git a/resources/qml/components/ActionButton.qml b/resources/qml/components/ActionButton.qml index 02c279a458..b49e3f1dcb 100644 --- a/resources/qml/components/ActionButton.qml +++ b/resources/qml/components/ActionButton.qml @@ -19,6 +19,7 @@ Button property var textHoverColor: UM.Theme.getColor("button_text_hover") property var textDisabledColor: textColor property var textFont: UM.Theme.getFont("action_button") + property var cornerRadius: 2 * screenScaleFactor contentItem: Row { @@ -32,6 +33,7 @@ Button sourceSize.height: height color: button.hovered ? button.textHoverColor : button.textColor visible: button.iconSource != "" + anchors.verticalCenter: parent.verticalCenter } Label @@ -42,12 +44,14 @@ Button font: button.textFont visible: button.text != "" renderType: Text.NativeRendering + anchors.verticalCenter: parent.verticalCenter } } background: Rectangle { color: button.enabled ? (button.hovered ? button.hoverColor : button.color) : button.disabledColor + radius: cornerRadius } MouseArea diff --git a/resources/themes/cura-light/icons/circle_outline.svg b/resources/themes/cura-light/icons/circle_outline.svg new file mode 100644 index 0000000000..4d0b0e4eb0 --- /dev/null +++ b/resources/themes/cura-light/icons/circle_outline.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index b08d9e8728..939399efc8 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -90,6 +90,14 @@ QtObject { } } + property Component action_button: Component + { + ButtonStyle + { + + } + } + property Component topheader_tab: Component { ButtonStyle diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index e49824ae74..285d2724a0 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -87,6 +87,9 @@ "topheader_button_background_active": [255, 255, 255, 255], "topheader_button_background_inactive": [255, 255, 255, 0], + "account_widget_ouline_active": [9, 140, 188, 255], + "account_widget_ouline_inactive": [175, 175, 175, 255], + "text": [0, 0, 0, 255], "text_detail": [174, 174, 174, 128], "text_link": [12, 169, 227, 255], @@ -341,6 +344,8 @@ "topheader_button": [8, 4], "topheader_button_icon": [1.2, 1.2], + "account_button": [12, 3], + "views_selector": [0.0, 4.0], "default_lining": [0.08, 0.08], From 85436c1469142301ea02cc647df70e42a9eaba7c Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 11 Oct 2018 10:29:59 +0200 Subject: [PATCH 0015/1292] Move machine selector to own component & new location This also simplifies & cleans up the actually used QML CURA-5772 --- resources/qml/Cura.qml | 8 ++++ resources/qml/PrepareSidebar.qml | 39 ++------------- .../MachineAndConfigurationSelector.qml | 48 +++++++++++++++++++ 3 files changed, 60 insertions(+), 35 deletions(-) create mode 100644 resources/qml/components/MachineAndConfigurationSelector.qml diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 50419067b4..f040469916 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -169,6 +169,14 @@ UM.MainWindow action: Cura.Actions.open } + MachineAndConfigurationSelector + { + anchors.left: openFileButton.right + //anchors.right: sidebar.left + anchors.leftMargin: UM.Theme.getSize("default_margin").height + anchors.top: openFileButton.top + } + Toolbar { id: toolbar diff --git a/resources/qml/PrepareSidebar.qml b/resources/qml/PrepareSidebar.qml index fe0fb033f7..a44f3fad7d 100644 --- a/resources/qml/PrepareSidebar.qml +++ b/resources/qml/PrepareSidebar.qml @@ -9,6 +9,8 @@ import UM 1.2 as UM import Cura 1.0 as Cura import "Menus" import "Menus/ConfigurationMenu" +import "components" + Rectangle { @@ -19,7 +21,6 @@ Rectangle property bool hideView: Cura.MachineManager.activeMachineName == "" // Is there an output device for this printer? - property bool isNetworkPrinter: Cura.MachineManager.activeMachineNetworkKey != "" property bool printerConnected: Cura.MachineManager.printerConnected property bool printerAcceptsCommands: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands property var connectedPrinter: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null @@ -85,41 +86,11 @@ Rectangle } } - MachineSelection - { - id: machineSelection - width: base.width - configSelection.width - separator.width - height: UM.Theme.getSize("sidebar_header").height - anchors.top: base.top - anchors.left: parent.left - } - - Rectangle - { - id: separator - visible: configSelection.visible - width: visible ? Math.round(UM.Theme.getSize("sidebar_lining_thin").height / 2) : 0 - height: UM.Theme.getSize("sidebar_header").height - color: UM.Theme.getColor("sidebar_lining_thin") - anchors.left: machineSelection.right - } - - ConfigurationSelection - { - id: configSelection - visible: isNetworkPrinter && printerConnected - width: visible ? Math.round(base.width * 0.15) : 0 - height: UM.Theme.getSize("sidebar_header").height - anchors.top: base.top - anchors.right: parent.right - panelWidth: base.width - } - SidebarHeader { id: header width: parent.width visible: !hideSettings && (machineExtruderCount.properties.value > 1 || Cura.MachineManager.hasMaterials || Cura.MachineManager.hasVariants) - anchors.top: machineSelection.bottom + anchors.top: parent.top onShowTooltip: base.showTooltip(item, location, text) onHideTooltip: base.hideTooltip() @@ -160,10 +131,9 @@ Rectangle } // Settings mode selection toggle - Rectangle + Item { id: settingsModeSelection - color: "transparent" width: Math.round(parent.width * 0.55) height: UM.Theme.getSize("sidebar_header_mode_toggle").height @@ -328,7 +298,6 @@ Rectangle anchors.bottomMargin: UM.Theme.getSize("sidebar_margin").height height: timeDetails.height + costSpec.height width: base.width - (saveButton.buttonRowWidth + UM.Theme.getSize("sidebar_margin").width) - clip: true Label { diff --git a/resources/qml/components/MachineAndConfigurationSelector.qml b/resources/qml/components/MachineAndConfigurationSelector.qml new file mode 100644 index 0000000000..5b919c42d8 --- /dev/null +++ b/resources/qml/components/MachineAndConfigurationSelector.qml @@ -0,0 +1,48 @@ +// Copyright (c) 2017 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 + +import UM 1.2 as UM +import Cura 1.0 as Cura +import "../Menus" +import "../Menus/ConfigurationMenu" +import ".." + +Rectangle +{ + color: UM.Theme.getColor("sidebar_lining_thin") + + implicitHeight: UM.Theme.getSize("sidebar_header").height + implicitWidth: UM.Theme.getSize("sidebar").width + + property bool isNetworkPrinter: Cura.MachineManager.activeMachineNetworkKey != "" + property bool printerConnected: Cura.MachineManager.printerConnected + + MachineSelection + { + id: machineSelection + anchors + { + left: parent.left + right: configSelection.left + rightMargin: UM.Theme.getSize("sidebar_lining_thin").height / 2 + top: parent.top + bottom: parent.bottom + } + } + + ConfigurationSelection + { + id: configSelection + visible: isNetworkPrinter && printerConnected + width: visible ? Math.round(parent.width * 0.15) : 0 + panelWidth: parent.width + anchors + { + right: parent.right + top: parent.top + bottom: parent.bottom + } + } +} \ No newline at end of file From cc6d5617eefe9431012bbf98496743c4c11723c4 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 11 Oct 2018 10:41:29 +0200 Subject: [PATCH 0016/1292] Update documentation & typing CURA-5772 --- cura/Stages/CuraStage.py | 19 ++++++++++++++----- resources/qml/PrepareSidebar.qml | 6 ++++-- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/cura/Stages/CuraStage.py b/cura/Stages/CuraStage.py index b2f6d61799..774a5a6e76 100644 --- a/cura/Stages/CuraStage.py +++ b/cura/Stages/CuraStage.py @@ -5,19 +5,28 @@ from PyQt5.QtCore import pyqtProperty, QUrl from UM.Stage import Stage +# Since Cura has a few pre-defined "space claims" for the locations of certain components, we've provided some structure +# to indicate this. +# * The StageMenuComponent is the horizontal area below the stage bar. This should be used to show stage specific +# buttons and elements. This component will be drawn over the bar & main component. +# * The MainComponent is the component that will be drawn starting from the bottom of the stageBar and fills the rest +# of the screen. class CuraStage(Stage): - - def __init__(self, parent = None): + def __init__(self, parent = None) -> None: super().__init__(parent) @pyqtProperty(str, constant = True) - def stageId(self): + def stageId(self) -> str: return self.getPluginId() @pyqtProperty(QUrl, constant = True) - def mainComponent(self): + def mainComponent(self) -> QUrl: return self.getDisplayComponent("main") @pyqtProperty(QUrl, constant = True) - def sidebarComponent(self): + def sidebarComponent(self) -> QUrl: return self.getDisplayComponent("sidebar") + + @pyqtProperty(QUrl, constant=True) + def stageMenuComponent(self) -> QUrl: + return self.getDisplayComponent("menu") \ No newline at end of file diff --git a/resources/qml/PrepareSidebar.qml b/resources/qml/PrepareSidebar.qml index a44f3fad7d..7c99e6e145 100644 --- a/resources/qml/PrepareSidebar.qml +++ b/resources/qml/PrepareSidebar.qml @@ -86,7 +86,8 @@ Rectangle } } - SidebarHeader { + SidebarHeader + { id: header width: parent.width visible: !hideSettings && (machineExtruderCount.properties.value > 1 || Cura.MachineManager.hasMaterials || Cura.MachineManager.hasVariants) @@ -96,7 +97,8 @@ Rectangle onHideTooltip: base.hideTooltip() } - Rectangle { + Rectangle + { id: headerSeparator width: parent.width visible: settingsModeSelection.visible && header.visible From f18d490ca1037296b4c507481058f1372cbe2ca3 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 11 Oct 2018 13:08:57 +0200 Subject: [PATCH 0017/1292] Move extruderIcon to it's own location This also simplifies the qml that actually handles the display CURA-5772 --- resources/qml/ExtruderIcon.qml | 56 ++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 resources/qml/ExtruderIcon.qml diff --git a/resources/qml/ExtruderIcon.qml b/resources/qml/ExtruderIcon.qml new file mode 100644 index 0000000000..2c2edcb492 --- /dev/null +++ b/resources/qml/ExtruderIcon.qml @@ -0,0 +1,56 @@ +import QtQuick 2.7 +import QtQuick.Controls 1.1 +import UM 1.2 as UM + +Item +{ + + id: extruderIconItem + + implicitWidth: UM.Theme.getSize("button").width + implicitHeight: implicitWidth + + property bool checked: true + property alias material_color: materialColorCircle.color + property alias text_color: extruderNumberText.color + + UM.RecolorImage + { + id: mainCircle + anchors.fill: parent + + sourceSize.width: parent.width + sourceSize.height: parent.width + source: UM.Theme.getIcon("extruder_button") + color: extruderNumberText.color + } + + Label + { + id: extruderNumberText + anchors.centerIn: parent + text: index + 1; + font: UM.Theme.getFont("default_bold") + } + + // Material colour circle + // Only draw the filling colour of the material inside the SVG border. + Rectangle + { + id: materialColorCircle + + anchors + { + right: parent.right + } + + width: Math.round(parent.width * 0.35) + height: Math.round(parent.height * 0.35) + radius: Math.round(width / 2) + + border.width: 1 + border.color: UM.Theme.getColor("extruder_button_material_border") + + opacity: !extruderIconItem.checked ? 0.6 : 1.0 + } +} \ No newline at end of file From a861b88de11ed317f32523e233eb0a3a0252aca9 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 11 Oct 2018 15:03:37 +0200 Subject: [PATCH 0018/1292] Move most of the sidebarHeader items to materialAndVariantSelector CURA-5772 --- resources/qml/MaterialAndVariantSelector.qml | 349 +++++++++++++++++++ 1 file changed, 349 insertions(+) create mode 100644 resources/qml/MaterialAndVariantSelector.qml diff --git a/resources/qml/MaterialAndVariantSelector.qml b/resources/qml/MaterialAndVariantSelector.qml new file mode 100644 index 0000000000..3d2ef2e98f --- /dev/null +++ b/resources/qml/MaterialAndVariantSelector.qml @@ -0,0 +1,349 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +import "Menus" // TODO: This needs to be fixed in the qmldir! + +Rectangle +{ + implicitWidth: parent.width + implicitHeight: parent.height + + id: base + + color: "purple" + // Height has an extra 2x margin for the top & bottom margin. + height: childrenRect.height + 2 * UM.Theme.getSize("default_margin").width + + Cura.ExtrudersModel { id: extrudersModel; } + + ListView + { + // Horizontal list that shows the extruders + id: extrudersList + visible: extrudersModel.items.length > 1 + property var index: 0 + + height: UM.Theme.getSize("sidebar_header_mode_tabs").height + boundsBehavior: Flickable.StopAtBounds + + anchors + { + left: parent.left + right: parent.right + top: parent.top + margins: UM.Theme.getSize("sidebar_margin").width + } + + ExclusiveGroup { id: extruderMenuGroup; } + + orientation: ListView.Horizontal + + model: extrudersModel + + Connections + { + target: Cura.MachineManager + onGlobalContainerChanged: forceActiveFocus() // Changing focus applies the currently-being-typed values so it can change the displayed setting values. + } + + delegate: Button + { + height: parent.height + width: Math.round(ListView.view.width / extrudersModel.rowCount()) + + text: model.name + tooltip: model.name + exclusiveGroup: extruderMenuGroup + checked: Cura.ExtruderManager.activeExtruderIndex == index + + property bool extruder_enabled: true + + MouseArea // TODO; This really should be fixed. It makes absolutely no sense to have a button AND a mouse area. + { + anchors.fill: parent + acceptedButtons: Qt.LeftButton | Qt.RightButton + onClicked: { + switch (mouse.button) { + case Qt.LeftButton: + extruder_enabled = Cura.MachineManager.getExtruder(model.index).isEnabled + if (extruder_enabled) + { + forceActiveFocus(); // Changing focus applies the currently-being-typed values so it can change the displayed setting values. + Cura.ExtruderManager.setActiveExtruderIndex(index); + } + break; + case Qt.RightButton: + extruder_enabled = Cura.MachineManager.getExtruder(model.index).isEnabled + extruderMenu.popup(); + break; + } + + } + } + + Menu + { + id: extruderMenu + + MenuItem + { + text: catalog.i18nc("@action:inmenu", "Enable Extruder") + onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, true) + visible: !extruder_enabled // using an intermediate variable prevents an empty popup that occured now and then + } + + MenuItem + { + text: catalog.i18nc("@action:inmenu", "Disable Extruder") + onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, false) + visible: extruder_enabled + enabled: Cura.MachineManager.numberExtrudersEnabled > 1 + } + } + + style: ButtonStyle + { + background: Rectangle + { + anchors.fill: parent + border.width: control.checked ? UM.Theme.getSize("default_lining").width * 2 : UM.Theme.getSize("default_lining").width + border.color: { + if (Cura.MachineManager.getExtruder(index).isEnabled) + { + if(control.checked || control.pressed) + { + return UM.Theme.getColor("action_button_active_border"); + } else if (control.hovered) + { + return UM.Theme.getColor("action_button_hovered_border") + } + return UM.Theme.getColor("action_button_border") + } + return UM.Theme.getColor("action_button_disabled_border") + } + color: { + if (Cura.MachineManager.getExtruder(index).isEnabled) + { + if(control.checked || control.pressed) + { + return UM.Theme.getColor("action_button_active"); + } else if (control.hovered) + { + return UM.Theme.getColor("action_button_hovered") + } + return UM.Theme.getColor("action_button") + } + return UM.Theme.getColor("action_button_disabled") + } + Behavior on color { ColorAnimation { duration: 50; } } + + Item + { + id: extruderButtonFace + anchors.centerIn: parent + width: childrenRect.width + + Label + { + // Static text that holds the "Extruder" label + id: extruderStaticText + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + + color: { + if (Cura.MachineManager.getExtruder(index).isEnabled) + { + if(control.checked || control.pressed) + { + return UM.Theme.getColor("action_button_active_text"); + } else if (control.hovered) + { + return UM.Theme.getColor("action_button_hovered_text") + } + return UM.Theme.getColor("action_button_text") + } + return UM.Theme.getColor("action_button_disabled_text") + } + + font: UM.Theme.getFont("large_nonbold") + text: catalog.i18nc("@label", "Extruder") + visible: width < (control.width - extruderIconItem.width - UM.Theme.getSize("default_margin").width) + elide: Text.ElideRight + } + + ExtruderIcon + { + // Round icon with the extruder number and material color indicator. + anchors.verticalCenter: parent.verticalCenter + anchors.left: extruderStaticText.right + width: control.height - Math.round(UM.Theme.getSize("default_margin").width / 2) + height: width + + checked: control.checked + material_color: model.color + text_color: extruderStaticText.color + } + } + } + + label: Item {} + } + } + } + + Item + { + id: materialRow + height: UM.Theme.getSize("sidebar_setup").height + visible: Cura.MachineManager.hasMaterials + + anchors + { + left: parent.left + right: parent.right + top: extrudersList.bottom + margins: UM.Theme.getSize("sidebar_margin").width + } + + Label + { + id: materialLabel + text: catalog.i18nc("@label", "Material"); + width: Math.round(parent.width * 0.45 - UM.Theme.getSize("default_margin").width) + height: parent.height + verticalAlignment: Text.AlignVCenter + font: UM.Theme.getFont("default"); + color: UM.Theme.getColor("text"); + } + + ToolButton + { + id: materialSelection + + property var activeExtruder: Cura.MachineManager.activeStack + property var hasActiveExtruder: activeExtruder != null + property var currentRootMaterialName: hasActiveExtruder ? activeExtruder.material.name : "" + + text: currentRootMaterialName + tooltip: currentRootMaterialName + visible: Cura.MachineManager.hasMaterials + + enabled: !extrudersList.visible || Cura.ExtruderManager.activeExtruderIndex > -1 + + height: UM.Theme.getSize("setting_control").height + width: Math.round(parent.width * 0.7) + UM.Theme.getSize("sidebar_margin").width + anchors.right: parent.right + style: UM.Theme.styles.sidebar_header_button + activeFocusOnPress: true; + menu: MaterialMenu + { + extruderIndex: Cura.ExtruderManager.activeExtruderIndex + } + + property var valueError: hasActiveExtruder ? Cura.ContainerManager.getContainerMetaDataEntry(activeExtruder.material.id, "compatible", "") != "True" : true + property var valueWarning: ! Cura.MachineManager.isActiveQualitySupported + } + } + + Item + { + id: variantRow + height: UM.Theme.getSize("sidebar_setup").height + visible: Cura.MachineManager.hasVariants + + anchors + { + left: parent.left + right: parent.right + top: materialRow.bottom + margins: UM.Theme.getSize("sidebar_margin").width + } + + Label + { + id: variantLabel + text: Cura.MachineManager.activeDefinitionVariantsName; + width: Math.round(parent.width * 0.45 - UM.Theme.getSize("default_margin").width) + height: parent.height + verticalAlignment: Text.AlignVCenter + font: UM.Theme.getFont("default"); + color: UM.Theme.getColor("text"); + } + + ToolButton + { + id: variantSelection + text: Cura.MachineManager.activeVariantName + tooltip: Cura.MachineManager.activeVariantName; + visible: Cura.MachineManager.hasVariants + + height: UM.Theme.getSize("setting_control").height + width: Math.round(parent.width * 0.7 + UM.Theme.getSize("sidebar_margin").width) + anchors.right: parent.right + style: UM.Theme.styles.sidebar_header_button + activeFocusOnPress: true; + + menu: NozzleMenu { extruderIndex: Cura.ExtruderManager.activeExtruderIndex } + } + } + + Item + { + id: materialCompatibilityLink + height: UM.Theme.getSize("sidebar_setup").height + + anchors.right: parent.right + anchors.top: variantRow.bottom + anchors.margins: UM.Theme.getSize("sidebar_margin").width + UM.RecolorImage + { + id: warningImage + + anchors.right: materialInfoLabel.left + anchors.rightMargin: UM.Theme.getSize("default_margin").width + + source: UM.Theme.getIcon("warning") + width: UM.Theme.getSize("section_icon").width + height: UM.Theme.getSize("section_icon").height + + sourceSize.width: width + sourceSize.height: height + + color: UM.Theme.getColor("material_compatibility_warning") + + visible: !Cura.MachineManager.isCurrentSetupSupported + } + + Label + { + id: materialInfoLabel + wrapMode: Text.WordWrap + text: "" + catalog.i18nc("@label", "Check compatibility") + "" + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + linkColor: UM.Theme.getColor("text_link") + + verticalAlignment: Text.AlignTop + + anchors.right: parent.right + + MouseArea + { + anchors.fill: parent + + onClicked: { + // open the material URL with web browser + Qt.openUrlExternally("https://ultimaker.com/incoming-links/cura/material-compatibilty"); + } + } + } + } + +} \ No newline at end of file From 9ab0fdfb68e12576977e226103c88f428f4cbce3 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 11 Oct 2018 15:03:37 +0200 Subject: [PATCH 0019/1292] Move most of the sidebarHeader items to materialAndVariantSelector CURA-5772 --- resources/qml/MaterialAndVariantSelector.qml | 349 +++++++++++++++++++ 1 file changed, 349 insertions(+) create mode 100644 resources/qml/MaterialAndVariantSelector.qml diff --git a/resources/qml/MaterialAndVariantSelector.qml b/resources/qml/MaterialAndVariantSelector.qml new file mode 100644 index 0000000000..8acaba9ec7 --- /dev/null +++ b/resources/qml/MaterialAndVariantSelector.qml @@ -0,0 +1,349 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +import "Menus" // TODO: This needs to be fixed in the qmldir! + +Rectangle +{ + implicitWidth: parent.width + implicitHeight: parent.height + + id: base + color: UM.Theme.getColor("sidebar") + + // Height has an extra 2x margin for the top & bottom margin. + height: childrenRect.height + 2 * UM.Theme.getSize("default_margin").width + + Cura.ExtrudersModel { id: extrudersModel; } + + ListView + { + // Horizontal list that shows the extruders + id: extrudersList + visible: extrudersModel.items.length > 1 + property var index: 0 + + height: UM.Theme.getSize("sidebar_header_mode_tabs").height + boundsBehavior: Flickable.StopAtBounds + + anchors + { + left: parent.left + right: parent.right + top: parent.top + margins: UM.Theme.getSize("sidebar_margin").width + } + + ExclusiveGroup { id: extruderMenuGroup; } + + orientation: ListView.Horizontal + + model: extrudersModel + + Connections + { + target: Cura.MachineManager + onGlobalContainerChanged: forceActiveFocus() // Changing focus applies the currently-being-typed values so it can change the displayed setting values. + } + + delegate: Button + { + height: parent.height + width: Math.round(ListView.view.width / extrudersModel.rowCount()) + + text: model.name + tooltip: model.name + exclusiveGroup: extruderMenuGroup + checked: Cura.ExtruderManager.activeExtruderIndex == index + + property bool extruder_enabled: true + + MouseArea // TODO; This really should be fixed. It makes absolutely no sense to have a button AND a mouse area. + { + anchors.fill: parent + acceptedButtons: Qt.LeftButton | Qt.RightButton + onClicked: { + switch (mouse.button) { + case Qt.LeftButton: + extruder_enabled = Cura.MachineManager.getExtruder(model.index).isEnabled + if (extruder_enabled) + { + forceActiveFocus(); // Changing focus applies the currently-being-typed values so it can change the displayed setting values. + Cura.ExtruderManager.setActiveExtruderIndex(index); + } + break; + case Qt.RightButton: + extruder_enabled = Cura.MachineManager.getExtruder(model.index).isEnabled + extruderMenu.popup(); + break; + } + + } + } + + Menu + { + id: extruderMenu + + MenuItem + { + text: catalog.i18nc("@action:inmenu", "Enable Extruder") + onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, true) + visible: !extruder_enabled // using an intermediate variable prevents an empty popup that occured now and then + } + + MenuItem + { + text: catalog.i18nc("@action:inmenu", "Disable Extruder") + onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, false) + visible: extruder_enabled + enabled: Cura.MachineManager.numberExtrudersEnabled > 1 + } + } + + style: ButtonStyle + { + background: Rectangle + { + anchors.fill: parent + border.width: control.checked ? UM.Theme.getSize("default_lining").width * 2 : UM.Theme.getSize("default_lining").width + border.color: { + if (Cura.MachineManager.getExtruder(index).isEnabled) + { + if(control.checked || control.pressed) + { + return UM.Theme.getColor("action_button_active_border"); + } else if (control.hovered) + { + return UM.Theme.getColor("action_button_hovered_border") + } + return UM.Theme.getColor("action_button_border") + } + return UM.Theme.getColor("action_button_disabled_border") + } + color: { + if (Cura.MachineManager.getExtruder(index).isEnabled) + { + if(control.checked || control.pressed) + { + return UM.Theme.getColor("action_button_active"); + } else if (control.hovered) + { + return UM.Theme.getColor("action_button_hovered") + } + return UM.Theme.getColor("action_button") + } + return UM.Theme.getColor("action_button_disabled") + } + Behavior on color { ColorAnimation { duration: 50; } } + + Item + { + id: extruderButtonFace + anchors.centerIn: parent + width: childrenRect.width + + Label + { + // Static text that holds the "Extruder" label + id: extruderStaticText + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + + color: { + if (Cura.MachineManager.getExtruder(index).isEnabled) + { + if(control.checked || control.pressed) + { + return UM.Theme.getColor("action_button_active_text"); + } else if (control.hovered) + { + return UM.Theme.getColor("action_button_hovered_text") + } + return UM.Theme.getColor("action_button_text") + } + return UM.Theme.getColor("action_button_disabled_text") + } + + font: UM.Theme.getFont("large_nonbold") + text: catalog.i18nc("@label", "Extruder") + visible: width < (control.width - extruderIconItem.width - UM.Theme.getSize("default_margin").width) + elide: Text.ElideRight + } + + ExtruderIcon + { + // Round icon with the extruder number and material color indicator. + anchors.verticalCenter: parent.verticalCenter + anchors.left: extruderStaticText.right + width: control.height - Math.round(UM.Theme.getSize("default_margin").width / 2) + height: width + + checked: control.checked + material_color: model.color + text_color: extruderStaticText.color + } + } + } + + label: Item {} + } + } + } + + Item + { + id: materialRow + height: UM.Theme.getSize("sidebar_setup").height + visible: Cura.MachineManager.hasMaterials + + anchors + { + left: parent.left + right: parent.right + top: extrudersList.bottom + margins: UM.Theme.getSize("sidebar_margin").width + } + + Label + { + id: materialLabel + text: catalog.i18nc("@label", "Material"); + width: Math.round(parent.width * 0.45 - UM.Theme.getSize("default_margin").width) + height: parent.height + verticalAlignment: Text.AlignVCenter + font: UM.Theme.getFont("default"); + color: UM.Theme.getColor("text"); + } + + ToolButton + { + id: materialSelection + + property var activeExtruder: Cura.MachineManager.activeStack + property var hasActiveExtruder: activeExtruder != null + property var currentRootMaterialName: hasActiveExtruder ? activeExtruder.material.name : "" + + text: currentRootMaterialName + tooltip: currentRootMaterialName + visible: Cura.MachineManager.hasMaterials + + enabled: !extrudersList.visible || Cura.ExtruderManager.activeExtruderIndex > -1 + + height: UM.Theme.getSize("setting_control").height + width: Math.round(parent.width * 0.7) + UM.Theme.getSize("sidebar_margin").width + anchors.right: parent.right + style: UM.Theme.styles.sidebar_header_button + activeFocusOnPress: true; + menu: MaterialMenu + { + extruderIndex: Cura.ExtruderManager.activeExtruderIndex + } + + property var valueError: hasActiveExtruder ? Cura.ContainerManager.getContainerMetaDataEntry(activeExtruder.material.id, "compatible", "") != "True" : true + property var valueWarning: ! Cura.MachineManager.isActiveQualitySupported + } + } + + Item + { + id: variantRow + height: UM.Theme.getSize("sidebar_setup").height + visible: Cura.MachineManager.hasVariants + + anchors + { + left: parent.left + right: parent.right + top: materialRow.bottom + margins: UM.Theme.getSize("sidebar_margin").width + } + + Label + { + id: variantLabel + text: Cura.MachineManager.activeDefinitionVariantsName; + width: Math.round(parent.width * 0.45 - UM.Theme.getSize("default_margin").width) + height: parent.height + verticalAlignment: Text.AlignVCenter + font: UM.Theme.getFont("default"); + color: UM.Theme.getColor("text"); + } + + ToolButton + { + id: variantSelection + text: Cura.MachineManager.activeVariantName + tooltip: Cura.MachineManager.activeVariantName; + visible: Cura.MachineManager.hasVariants + + height: UM.Theme.getSize("setting_control").height + width: Math.round(parent.width * 0.7 + UM.Theme.getSize("sidebar_margin").width) + anchors.right: parent.right + style: UM.Theme.styles.sidebar_header_button + activeFocusOnPress: true; + + menu: NozzleMenu { extruderIndex: Cura.ExtruderManager.activeExtruderIndex } + } + } + + Item + { + id: materialCompatibilityLink + height: UM.Theme.getSize("sidebar_setup").height + + anchors.right: parent.right + anchors.top: variantRow.bottom + anchors.margins: UM.Theme.getSize("sidebar_margin").width + UM.RecolorImage + { + id: warningImage + + anchors.right: materialInfoLabel.left + anchors.rightMargin: UM.Theme.getSize("default_margin").width + + source: UM.Theme.getIcon("warning") + width: UM.Theme.getSize("section_icon").width + height: UM.Theme.getSize("section_icon").height + + sourceSize.width: width + sourceSize.height: height + + color: UM.Theme.getColor("material_compatibility_warning") + + visible: !Cura.MachineManager.isCurrentSetupSupported + } + + Label + { + id: materialInfoLabel + wrapMode: Text.WordWrap + text: "" + catalog.i18nc("@label", "Check compatibility") + "" + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + linkColor: UM.Theme.getColor("text_link") + + verticalAlignment: Text.AlignTop + + anchors.right: parent.right + + MouseArea + { + anchors.fill: parent + + onClicked: { + // open the material URL with web browser + Qt.openUrlExternally("https://ultimaker.com/incoming-links/cura/material-compatibilty"); + } + } + } + } + +} \ No newline at end of file From bb7582159910728976e4e020d0b61de2b0b08ce2 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 11 Oct 2018 13:44:10 +0200 Subject: [PATCH 0020/1292] Fix some code style Contributes to issue CURA-5784. --- resources/qml/Cura.qml | 22 ++++++++++++--------- resources/qml/Skeleton/ApplicationMenu.qml | 12 +++++------ resources/qml/Skeleton/ApplicationViews.qml | 16 ++++++++------- 3 files changed, 28 insertions(+), 22 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index f040469916..8369c2a743 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -27,21 +27,25 @@ UM.MainWindow UM.I18nCatalog { id: catalog - name:"cura" + name: "cura" } onWidthChanged: { // If slidebar is collapsed then it should be invisible // otherwise after the main_window resize the sidebar will be fully re-drawn - if (sidebar.collapsed){ - if (sidebar.visible == true){ + if (sidebar.collapsed) + { + if (sidebar.visible == true) + { sidebar.visible = false sidebar.initialWidth = 0 } } - else{ - if (sidebar.visible == false){ + else + { + if (sidebar.visible == false) + { sidebar.visible = true sidebar.initialWidth = UM.Theme.getSize("sidebar").width } @@ -156,7 +160,7 @@ UM.MainWindow Button { id: openFileButton - text: catalog.i18nc("@action:button","Open File") + text: catalog.i18nc("@action:button", "Open File") iconSource: UM.Theme.getIcon("load") style: UM.Theme.styles.tool_button tooltip: "" @@ -352,10 +356,10 @@ UM.MainWindow { //; Remove & re-add the general page as we want to use our own instead of uranium standard. removePage(0); - insertPage(0, catalog.i18nc("@title:tab","General"), Qt.resolvedUrl("Preferences/GeneralPage.qml")); + insertPage(0, catalog.i18nc("@title:tab", "General"), Qt.resolvedUrl("Preferences/GeneralPage.qml")); removePage(1); - insertPage(1, catalog.i18nc("@title:tab","Settings"), Qt.resolvedUrl("Preferences/SettingVisibilityPage.qml")); + insertPage(1, catalog.i18nc("@title:tab", "Settings"), Qt.resolvedUrl("Preferences/SettingVisibilityPage.qml")); insertPage(2, catalog.i18nc("@title:tab", "Printers"), Qt.resolvedUrl("Preferences/MachinesPage.qml")); @@ -528,7 +532,7 @@ UM.MainWindow id: openDialog; //: File open dialog title - title: catalog.i18nc("@title:window","Open file(s)") + title: catalog.i18nc("@title:window", "Open file(s)") modality: UM.Application.platform == "linux" ? Qt.NonModal : Qt.WindowModal; selectMultiple: true nameFilters: UM.MeshFileHandler.supportedReadFileTypes; diff --git a/resources/qml/Skeleton/ApplicationMenu.qml b/resources/qml/Skeleton/ApplicationMenu.qml index a8774e8ceb..00859e2a45 100644 --- a/resources/qml/Skeleton/ApplicationMenu.qml +++ b/resources/qml/Skeleton/ApplicationMenu.qml @@ -27,7 +27,7 @@ Item Menu { id: fileMenu - title: catalog.i18nc("@title:menu menubar:toplevel","&File") + title: catalog.i18nc("@title:menu menubar:toplevel", "&File") MenuItem { @@ -46,7 +46,7 @@ Item MenuItem { id: saveWorkspaceMenu - text: catalog.i18nc("@title:menu menubar:file","&Save...") + text: catalog.i18nc("@title:menu menubar:file", "&Save...") onTriggered: { var args = { "filter_by_machine": false, "file_type": "workspace", "preferred_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml" }; @@ -99,7 +99,7 @@ Item Menu { - title: catalog.i18nc("@title:menu menubar:toplevel","&Edit") + title: catalog.i18nc("@title:menu menubar:toplevel", "&Edit") MenuItem { action: Cura.Actions.undo } MenuItem { action: Cura.Actions.redo } @@ -181,7 +181,7 @@ Item Menu { id: extensionMenu - title: catalog.i18nc("@title:menu menubar:toplevel","E&xtensions") + title: catalog.i18nc("@title:menu menubar:toplevel", "E&xtensions") Instantiator { @@ -223,7 +223,7 @@ Item Menu { id: preferencesMenu - title: catalog.i18nc("@title:menu menubar:toplevel","P&references") + title: catalog.i18nc("@title:menu menubar:toplevel", "P&references") MenuItem { action: Cura.Actions.preferences } } @@ -231,7 +231,7 @@ Item Menu { id: helpMenu - title: catalog.i18nc("@title:menu menubar:toplevel","&Help") + title: catalog.i18nc("@title:menu menubar:toplevel", "&Help") MenuItem { action: Cura.Actions.showProfileFolder } MenuItem { action: Cura.Actions.documentation } diff --git a/resources/qml/Skeleton/ApplicationViews.qml b/resources/qml/Skeleton/ApplicationViews.qml index 94315a73fb..eb8ab16fae 100644 --- a/resources/qml/Skeleton/ApplicationViews.qml +++ b/resources/qml/Skeleton/ApplicationViews.qml @@ -11,9 +11,9 @@ import Cura 1.0 as Cura import "../components" -// This item contains the views selector, a combobox that is dinamically created from -// the list of available Views (packages that create different visualizactions of the -// scene. Aside the selector, there is a row of buttons that change the orientation of the view. +// This item contains the views selector, a combobox that is dynamically created from +// the list of available Views (packages that create different visualizations of the +// scene). Aside from the selector, there is a row of buttons that change the orientation of the view. Item { id: applicationViewsSelector @@ -25,7 +25,8 @@ Item { id: viewModeButton - anchors { + anchors + { verticalCenter: parent.verticalCenter right: parent.right rightMargin: UM.Theme.getSize("default_margin").width @@ -51,15 +52,16 @@ Item { for (var i = 0; i < model.rowCount(); i++) { - if (model.getItem(i).active) { - return i + if (model.getItem(i).active) + { + return i; } } return 0 } // set the active index - function setActiveIndex (index) + function setActiveIndex(index) { UM.Controller.setActiveView(index) // the connection to UM.ActiveView will trigger update so there is no reason to call it manually here From 10de312647a1e38db0ae6c24b0d06b3e807f7f37 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 12 Oct 2018 13:28:08 +0200 Subject: [PATCH 0021/1292] Added QMLDIR so we can specify cura specific QML components for plugins This ensures that we can be way more explicit with what QML components we see as re-usable CURA-5772 --- resources/qml/qmldir | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 resources/qml/qmldir diff --git a/resources/qml/qmldir b/resources/qml/qmldir new file mode 100644 index 0000000000..5083b5e80a --- /dev/null +++ b/resources/qml/qmldir @@ -0,0 +1,5 @@ +module Cura + +MachineAndConfigurationSelector 1.0 components/MachineAndConfigurationSelector.qml +MaterialAndVariantSelector 1.0 MaterialAndVariantSelector.qml +ProfileAndSettingComponent 1.0 ProfileAndSettingComponent.qml \ No newline at end of file From 7d5472b09fe0a0fc524b36ab9c9d85e54c68d241 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 12 Oct 2018 13:29:57 +0200 Subject: [PATCH 0022/1292] Moved the prepareMenu into the prepare stage plugin CURA-5772 --- plugins/PrepareStage/PrepareMenu.qml | 42 ++++++++++++++++++++++++++++ plugins/PrepareStage/PrepareStage.py | 6 +++- 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 plugins/PrepareStage/PrepareMenu.qml diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml new file mode 100644 index 0000000000..eb09326524 --- /dev/null +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -0,0 +1,42 @@ +import QtQuick 2.7 + +import QtQuick.Controls 1.4 + +import UM 1.3 as UM +import Cura 1.1 as Cura + + +Row +{ + spacing: UM.Theme.getSize("default_margin").width + + UM.I18nCatalog + { + id: catalog + name:"cura" + } + + Button + { + id: openFileButton; + text: catalog.i18nc("@action:button", "Open File"); + iconSource: UM.Theme.getIcon("load") + style: UM.Theme.styles.tool_button + tooltip: "" + action: Cura.Actions.open; + } + + Cura.MachineAndConfigurationSelector + { + } + + Cura.MaterialAndVariantSelector + { + width: UM.Theme.getSize("sidebar").width + } + + Cura.ProfileAndSettingComponent + { + width: UM.Theme.getSize("sidebar").width + } +} \ No newline at end of file diff --git a/plugins/PrepareStage/PrepareStage.py b/plugins/PrepareStage/PrepareStage.py index c3c9f0a1f8..b22f3385b8 100644 --- a/plugins/PrepareStage/PrepareStage.py +++ b/plugins/PrepareStage/PrepareStage.py @@ -2,13 +2,14 @@ # Cura is released under the terms of the LGPLv3 or higher. import os.path from UM.Application import Application +from UM.PluginRegistry import PluginRegistry from UM.Resources import Resources from cura.Stages.CuraStage import CuraStage + ## Stage for preparing model (slicing). class PrepareStage(CuraStage): - def __init__(self, parent = None): super().__init__(parent) Application.getInstance().engineCreatedSignal.connect(self._engineCreated) @@ -16,4 +17,7 @@ class PrepareStage(CuraStage): def _engineCreated(self): sidebar_component_path = os.path.join(Resources.getPath(Application.getInstance().ResourceTypes.QmlFiles), "PrepareSidebar.qml") + + menu_component_path = os.path.join(PluginRegistry.getInstance().getPluginPath("PrepareStage"), "PrepareMenu.qml") + self.addDisplayComponent("menu", menu_component_path) self.addDisplayComponent("sidebar", sidebar_component_path) From 11a08d0e472612b7c5377273cf2435c1a17cb3c4 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 12 Oct 2018 13:32:23 +0200 Subject: [PATCH 0023/1292] Move whole bunch of QML components to their new locations The tooltips are still not working correctly, it might be that it needs rework CURA-5772 --- resources/qml/Cura.qml | 149 +++++--- resources/qml/ExtruderIcon.qml | 1 - resources/qml/MaterialAndVariantSelector.qml | 2 +- ...bar.qml => ProfileAndSettingComponent.qml} | 330 ++++++------------ resources/qml/ProgressAndSaveWidget.qml | 237 +++++++++++++ resources/qml/SaveButton.qml | 165 +++++---- resources/qml/Settings/SettingView.qml | 9 +- resources/qml/SidebarHeader.qml | 3 +- resources/qml/Skeleton/TopHeader.qml | 3 +- 9 files changed, 536 insertions(+), 363 deletions(-) rename resources/qml/{PrepareSidebar.qml => ProfileAndSettingComponent.qml} (66%) create mode 100644 resources/qml/ProgressAndSaveWidget.qml diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 8369c2a743..f89f8d63dd 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -21,36 +21,45 @@ UM.MainWindow // Cura application window title title: catalog.i18nc("@title:window", "Ultimaker Cura") - viewportRect: Qt.rect(0, 0, (base.width - sidebar.width) / base.width, 1.0) + //viewportRect: Qt.rect(0, 0, (base.width - sidebar.width) / base.width, 1.0) + viewportRect: Qt.rect(0, 0, 1.0, 1.0) backgroundColor: UM.Theme.getColor("viewport_background") UM.I18nCatalog { id: catalog - name: "cura" + name:"cura" } - onWidthChanged: + function showTooltip(item, position, text) + { + tooltip.text = text; + position = item.mapToItem(backgroundItem, position.x - UM.Theme.getSize("default_arrow").width, position.y); + tooltip.show(position); + } + + function hideTooltip() + { + tooltip.hide(); + } + + /*onWidthChanged: { // If slidebar is collapsed then it should be invisible // otherwise after the main_window resize the sidebar will be fully re-drawn - if (sidebar.collapsed) - { - if (sidebar.visible == true) - { + if (sidebar.collapsed){ + if (sidebar.visible == true){ sidebar.visible = false sidebar.initialWidth = 0 } } - else - { - if (sidebar.visible == false) - { + else{ + if (sidebar.visible == false){ sidebar.visible = true sidebar.initialWidth = UM.Theme.getSize("sidebar").width } } - } + }*/ Component.onCompleted: { @@ -69,11 +78,16 @@ UM.MainWindow CuraApplication.purgeWindows() } - Column + Item { id: backgroundItem anchors.fill: parent + SidebarTooltip + { + id: tooltip + } + signal hasMesh(string name) //this signal sends the filebase name so it can be used for the JobSpecs.qml function getMeshName(path) { @@ -94,26 +108,34 @@ UM.MainWindow ApplicationMenu { - id: menu + id: applicationMenu window: base } TopHeader { id: topHeader - anchors.left: parent.left - anchors.right: parent.right + anchors + { + left: parent.left + right: parent.right + top: applicationMenu.bottom + } } Item { id: contentItem - width: parent.width - height: parent.height - menu.height - topHeader.height - z: topHeader.z - 1 + anchors + { + top: topHeader.bottom + bottom: parent.bottom + left: parent.left + right: parent.right + } - Keys.forwardTo: menu + Keys.forwardTo: applicationMenu DropArea { @@ -145,41 +167,39 @@ UM.MainWindow } } + Loader + { + // The stage menu is, as the name implies, a menu that is defined by the active stage. + // Note that this menu does not need to be set at all! It's perfectly acceptable to have a stage + // without this menu! + id: stageMenu + + anchors + { + left: parent.left + right: parent.right + top: parent.top + margins: UM.Theme.getSize("default_margin").height + } + + height: 50 + + source: UM.Controller.activeStage.stageMenuComponent + } + JobSpecs { id: jobSpecs anchors { bottom: parent.bottom - right: sidebar.left + //right: sidebar.left bottomMargin: UM.Theme.getSize("default_margin").height rightMargin: UM.Theme.getSize("default_margin").width } } - Button - { - id: openFileButton - text: catalog.i18nc("@action:button", "Open File") - iconSource: UM.Theme.getIcon("load") - style: UM.Theme.styles.tool_button - tooltip: "" - anchors - { - top: parent.top - topMargin: UM.Theme.getSize("default_margin").height - left: parent.left - } - action: Cura.Actions.open - } - MachineAndConfigurationSelector - { - anchors.left: openFileButton.right - //anchors.right: sidebar.left - anchors.leftMargin: UM.Theme.getSize("default_margin").height - anchors.top: openFileButton.top - } Toolbar { @@ -189,7 +209,7 @@ UM.MainWindow property int mouseY: base.mouseY anchors { - top: openFileButton.bottom + top: stageMenu.bottom topMargin: UM.Theme.getSize("window_margin").height left: parent.left } @@ -206,7 +226,7 @@ UM.MainWindow } } - ApplicationViews + /*ApplicationViews { id: applicationViews @@ -216,7 +236,7 @@ UM.MainWindow top: parent.top right: sidebar.left } - } + }*/ Loader { @@ -227,7 +247,7 @@ UM.MainWindow top: parent.top bottom: parent.bottom left: parent.left - right: sidebar.left + right: parent.right } MouseArea @@ -241,7 +261,7 @@ UM.MainWindow source: UM.Controller.activeStage.mainComponent } - Loader + /*Loader { id: sidebar @@ -311,7 +331,7 @@ UM.MainWindow acceptedButtons: Qt.AllButtons onWheel: wheel.accepted = true } - } + }*/ UM.MessageStack { @@ -338,15 +358,33 @@ UM.MainWindow bottom: parent.bottom } } + + + ProgressAndSaveWidget + { + anchors.right: parent.right + anchors.bottom: parent.bottom + width: UM.Theme.getSize("sidebar").width + anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width + anchors.bottomMargin: UM.Theme.getSize("sidebar_margin").height + onShowTooltip: + { + base.showTooltip(item, location, text) + } + onHideTooltip: + { + base.hideTooltip() + } + } } } // Expand or collapse sidebar - Connections + /*Connections { target: Cura.Actions.expandSidebar onTriggered: sidebar.callExpandOrCollapse() - } + }*/ UM.PreferencesDialog { @@ -356,10 +394,10 @@ UM.MainWindow { //; Remove & re-add the general page as we want to use our own instead of uranium standard. removePage(0); - insertPage(0, catalog.i18nc("@title:tab", "General"), Qt.resolvedUrl("Preferences/GeneralPage.qml")); + insertPage(0, catalog.i18nc("@title:tab","General"), Qt.resolvedUrl("Preferences/GeneralPage.qml")); removePage(1); - insertPage(1, catalog.i18nc("@title:tab", "Settings"), Qt.resolvedUrl("Preferences/SettingVisibilityPage.qml")); + insertPage(1, catalog.i18nc("@title:tab","Settings"), Qt.resolvedUrl("Preferences/SettingVisibilityPage.qml")); insertPage(2, catalog.i18nc("@title:tab", "Printers"), Qt.resolvedUrl("Preferences/MachinesPage.qml")); @@ -532,7 +570,7 @@ UM.MainWindow id: openDialog; //: File open dialog title - title: catalog.i18nc("@title:window", "Open file(s)") + title: catalog.i18nc("@title:window","Open file(s)") modality: UM.Application.platform == "linux" ? Qt.NonModal : Qt.WindowModal; selectMultiple: true nameFilters: UM.MeshFileHandler.supportedReadFileTypes; @@ -638,7 +676,8 @@ UM.MainWindow modality: Qt.ApplicationModal } - MessageDialog { + MessageDialog + { id: infoMultipleFilesWithGcodeDialog title: catalog.i18nc("@title:window", "Open File(s)") icon: StandardIcon.Information diff --git a/resources/qml/ExtruderIcon.qml b/resources/qml/ExtruderIcon.qml index 2c2edcb492..580ff5dce9 100644 --- a/resources/qml/ExtruderIcon.qml +++ b/resources/qml/ExtruderIcon.qml @@ -4,7 +4,6 @@ import UM 1.2 as UM Item { - id: extruderIconItem implicitWidth: UM.Theme.getSize("button").width diff --git a/resources/qml/MaterialAndVariantSelector.qml b/resources/qml/MaterialAndVariantSelector.qml index 325ffa85a5..fff3ef1100 100644 --- a/resources/qml/MaterialAndVariantSelector.qml +++ b/resources/qml/MaterialAndVariantSelector.qml @@ -17,7 +17,7 @@ Rectangle id: base color: UM.Theme.getColor("sidebar") - + // Height has an extra 2x margin for the top & bottom margin. height: childrenRect.height + 2 * UM.Theme.getSize("default_margin").width diff --git a/resources/qml/PrepareSidebar.qml b/resources/qml/ProfileAndSettingComponent.qml similarity index 66% rename from resources/qml/PrepareSidebar.qml rename to resources/qml/ProfileAndSettingComponent.qml index 7c99e6e145..33c2f37fb1 100644 --- a/resources/qml/PrepareSidebar.qml +++ b/resources/qml/ProfileAndSettingComponent.qml @@ -16,14 +16,10 @@ Rectangle { id: base + height: childrenRect.height + property int currentModeIndex: -1 property bool hideSettings: PrintInformation.preSliced - property bool hideView: Cura.MachineManager.activeMachineName == "" - - // Is there an output device for this printer? - property bool printerConnected: Cura.MachineManager.printerConnected - property bool printerAcceptsCommands: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands - property var connectedPrinter: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null property variant printDuration: PrintInformation.currentPrintTime property variant printMaterialLengths: PrintInformation.materialLengths @@ -34,7 +30,8 @@ Rectangle color: UM.Theme.getColor("sidebar") UM.I18nCatalog { id: catalog; name:"cura"} - Timer { + Timer + { id: tooltipDelayTimer interval: 500 repeat: false @@ -59,7 +56,8 @@ Rectangle tooltip.hide(); } - function strPadLeft(string, pad, length) { + function strPadLeft(string, pad, length) + { return (new Array(length + 1).join(pad) + string).slice(-length); } @@ -86,35 +84,9 @@ Rectangle } } - SidebarHeader - { - id: header - width: parent.width - visible: !hideSettings && (machineExtruderCount.properties.value > 1 || Cura.MachineManager.hasMaterials || Cura.MachineManager.hasVariants) - anchors.top: parent.top - - onShowTooltip: base.showTooltip(item, location, text) - onHideTooltip: base.hideTooltip() - } - - Rectangle - { - id: headerSeparator - width: parent.width - visible: settingsModeSelection.visible && header.visible - height: visible ? UM.Theme.getSize("sidebar_lining").height : 0 - color: UM.Theme.getColor("sidebar_lining") - anchors.top: header.bottom - anchors.topMargin: visible ? UM.Theme.getSize("sidebar_margin").height : 0 - } - onCurrentModeIndexChanged: { UM.Preferences.setValue("cura/active_mode", currentModeIndex); - if(modesListModel.count > base.currentModeIndex) - { - sidebarContents.replace(modesListModel.get(base.currentModeIndex).item, { "replace": true }) - } } Label @@ -122,176 +94,129 @@ Rectangle id: settingsModeLabel text: !hideSettings ? catalog.i18nc("@label:listbox", "Print Setup") : catalog.i18nc("@label:listbox", "Print Setup disabled\nG-code files cannot be modified") renderType: Text.NativeRendering - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width - anchors.top: hideSettings ? machineSelection.bottom : headerSeparator.bottom - anchors.topMargin: UM.Theme.getSize("sidebar_margin").height + + anchors + { + left: parent.left + top: parent.top + margins: UM.Theme.getSize("sidebar_margin").width + } + width: Math.round(parent.width * 0.45) + height: contentHeight font: UM.Theme.getFont("large") color: UM.Theme.getColor("text") - visible: !hideView } - // Settings mode selection toggle - Item - { - id: settingsModeSelection + ListView + { + // Settings mode selection toggle + id: settingsModeSelection + model: modesListModel width: Math.round(parent.width * 0.55) height: UM.Theme.getSize("sidebar_header_mode_toggle").height anchors.right: parent.right anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width - anchors.topMargin: UM.Theme.getSize("sidebar_margin").height - anchors.top: - { - if (settingsModeLabel.contentWidth >= parent.width - width - UM.Theme.getSize("sidebar_margin").width * 2) - { - return settingsModeLabel.bottom; - } - else - { - return headerSeparator.bottom; - } - } - visible: !hideSettings && !hideView - - Component - { - id: wizardDelegate - - Button - { - id: control - - height: settingsModeSelection.height - width: Math.round(parent.width / 2) - - anchors.left: parent.left - anchors.leftMargin: model.index * Math.round(settingsModeSelection.width / 2) - anchors.verticalCenter: parent.verticalCenter - - ButtonGroup.group: modeMenuGroup - - checkable: true - checked: base.currentModeIndex == index - onClicked: base.currentModeIndex = index - - onHoveredChanged: - { - if (hovered) - { - tooltipDelayTimer.item = settingsModeSelection - tooltipDelayTimer.text = model.tooltipText - tooltipDelayTimer.start() - } - else - { - tooltipDelayTimer.stop() - base.hideTooltip() - } - } - - background: Rectangle - { - border.width: control.checked ? UM.Theme.getSize("default_lining").width * 2 : UM.Theme.getSize("default_lining").width - border.color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active_border") : control.hovered ? UM.Theme.getColor("action_button_hovered_border"): UM.Theme.getColor("action_button_border") - - // for some reason, QtQuick decided to use the color of the background property as text color for the contentItem, so here it is - color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active") : control.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") - } - - contentItem: Label - { - text: model.text - font: UM.Theme.getFont("default") - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - renderType: Text.NativeRendering - elide: Text.ElideRight - color: - { - if(control.pressed) - { - return UM.Theme.getColor("action_button_active_text"); - } - else if(control.hovered) - { - return UM.Theme.getColor("action_button_hovered_text"); - } - return UM.Theme.getColor("action_button_text"); - } - } - } - } + anchors.top: settingsModeLabel.top ButtonGroup { id: modeMenuGroup } - ListView + delegate: Button { - id: modesList - model: modesListModel - delegate: wizardDelegate - anchors.top: parent.top + id: control + + height: settingsModeSelection.height + width: Math.round(parent.width / 2) + anchors.left: parent.left - width: parent.width - } - } + anchors.leftMargin: model.index * Math.round(settingsModeSelection.width / 2) + anchors.verticalCenter: parent.verticalCenter - StackView - { - id: sidebarContents + ButtonGroup.group: modeMenuGroup - anchors.bottom: footerSeparator.top - anchors.top: settingsModeSelection.bottom - anchors.topMargin: UM.Theme.getSize("sidebar_margin").height - anchors.left: base.left - anchors.right: base.right - visible: !hideSettings + checkable: true + checked: base.currentModeIndex == index + onClicked: base.currentModeIndex = index - replaceEnter: Transition { - PropertyAnimation { - property: "opacity" - from: 0 - to:1 - duration: 100 + onHoveredChanged: + { + if (hovered) + { + tooltipDelayTimer.item = settingsModeSelection + tooltipDelayTimer.text = model.tooltipText + tooltipDelayTimer.start() + } + else + { + tooltipDelayTimer.stop() + base.hideTooltip() + } + } + + background: Rectangle + { + border.width: control.checked ? UM.Theme.getSize("default_lining").width * 2 : UM.Theme.getSize("default_lining").width + border.color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active_border") : control.hovered ? UM.Theme.getColor("action_button_hovered_border"): UM.Theme.getColor("action_button_border") + + // for some reason, QtQuick decided to use the color of the background property as text color for the contentItem, so here it is + color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active") : control.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") + } + + contentItem: Label + { + text: model.text + font: UM.Theme.getFont("default") + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + renderType: Text.NativeRendering + elide: Text.ElideRight + color: + { + if(control.pressed) + { + return UM.Theme.getColor("action_button_active_text"); + } + else if(control.hovered) + { + return UM.Theme.getColor("action_button_hovered_text"); + } + return UM.Theme.getColor("action_button_text"); + } } } - - replaceExit: Transition { - PropertyAnimation { - property: "opacity" - from: 1 - to:0 - duration: 100 - } - } - } - - Loader - { - anchors.bottom: footerSeparator.top - anchors.top: headerSeparator.bottom - anchors.left: base.left - anchors.right: base.right - source: "SidebarContents.qml" - } - - Rectangle - { - id: footerSeparator - width: parent.width - height: UM.Theme.getSize("sidebar_lining").height - color: UM.Theme.getColor("sidebar_lining") - anchors.bottom: printSpecs.top - anchors.bottomMargin: Math.round(UM.Theme.getSize("sidebar_margin").height * 2 + UM.Theme.getSize("progressbar").height + UM.Theme.getFont("default_bold").pixelSize) } Item + { + id: sidebarContents + anchors.top: settingsModeSelection.bottom + anchors.topMargin: UM.Theme.getSize("sidebar_margin").height + anchors.left: parent.left + anchors.right: parent.right + height: 500 + + // We load both of them at once (instead of using a loader) because the advanced sidebar can take + // quite some time to load. So in this case we sacrifice memory for speed. + SidebarAdvanced + { + anchors.fill: parent + visible: currentModeIndex == 1 + } + + SidebarSimple + { + anchors.fill: parent + visible: currentModeIndex != 1 + } + } + + /*Item { id: printSpecs anchors.left: parent.left @@ -499,22 +424,23 @@ Rectangle } } } - } + }*/ // SaveButton is actually the bottom footer panel. - SaveButton + /*SaveButton { id: saveButton implicitWidth: base.width anchors.top: footerSeparator.bottom anchors.topMargin: UM.Theme.getSize("sidebar_margin").height anchors.bottom: parent.bottom - } + }*/ + /* SidebarTooltip { id: tooltip - } + }*/ // Setting mode: Recommended or Custom ListModel @@ -522,35 +448,15 @@ Rectangle id: modesListModel } - SidebarSimple - { - id: sidebarSimple - visible: false - - onShowTooltip: base.showTooltip(item, location, text) - onHideTooltip: base.hideTooltip() - } - - SidebarAdvanced - { - id: sidebarAdvanced - visible: false - - onShowTooltip: base.showTooltip(item, location, text) - onHideTooltip: base.hideTooltip() - } - Component.onCompleted: { modesListModel.append({ text: catalog.i18nc("@title:tab", "Recommended"), - tooltipText: catalog.i18nc("@tooltip", "Recommended Print Setup

Print with the recommended settings for the selected printer, material and quality."), - item: sidebarSimple + tooltipText: catalog.i18nc("@tooltip", "Recommended Print Setup

Print with the recommended settings for the selected printer, material and quality.") }) modesListModel.append({ text: catalog.i18nc("@title:tab", "Custom"), - tooltipText: catalog.i18nc("@tooltip", "Custom Print Setup

Print with finegrained control over every last bit of the slicing process."), - item: sidebarAdvanced + tooltipText: catalog.i18nc("@tooltip", "Custom Print Setup

Print with finegrained control over every last bit of the slicing process.") }) var index = Math.round(UM.Preferences.getValue("cura/active_mode")) @@ -564,24 +470,4 @@ Rectangle currentModeIndex = 0; } } - - UM.SettingPropertyProvider - { - id: machineExtruderCount - - containerStack: Cura.MachineManager.activeMachine - key: "machine_extruder_count" - watchedProperties: [ "value" ] - storeIndex: 0 - } - - UM.SettingPropertyProvider - { - id: machineHeatedBed - - containerStack: Cura.MachineManager.activeMachine - key: "machine_heated_bed" - watchedProperties: [ "value" ] - storeIndex: 0 - } } diff --git a/resources/qml/ProgressAndSaveWidget.qml b/resources/qml/ProgressAndSaveWidget.qml new file mode 100644 index 0000000000..88819af759 --- /dev/null +++ b/resources/qml/ProgressAndSaveWidget.qml @@ -0,0 +1,237 @@ +// Copyright (c) 2017 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.0 +import QtQuick.Layouts 1.3 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +Rectangle +{ + id: base + + // We need a whole lot of print duration information. + property variant printDuration: PrintInformation.currentPrintTime + + // This widget doesn't show tooltips by itself. Instead it emits signals so others can do something with it. + signal showTooltip(Item item, point location, string text) + signal hideTooltip() + + // Also add an extra margin, as we ant some breathing room around the edges. + height: childrenRect.height + UM.Theme.getSize("sidebar_margin").height + Label + { + id: timeDetails + anchors.left: parent.left + anchors.bottom: costSpec.top + anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width + + font: UM.Theme.getFont("large") + color: UM.Theme.getColor("text_subtext") + text: (!base.printDuration || !base.printDuration.valid) ? catalog.i18nc("@label Hours and minutes", "00h 00min") : base.printDuration.getDisplayString(UM.DurationFormat.Short) + renderType: Text.NativeRendering + + MouseArea + { + id: timeDetailsMouseArea + anchors.fill: parent + hoverEnabled: true + + onEntered: + { + if(base.printDuration.valid && !base.printDuration.isTotalDurationZero) + { + // All the time information for the different features is achieved + var print_time = PrintInformation.getFeaturePrintTimes(); + var total_seconds = parseInt(base.printDuration.getDisplayString(UM.DurationFormat.Seconds)) + + // A message is created and displayed when the user hover the time label + var tooltip_html = "%1
".arg(catalog.i18nc("@tooltip", "Time specification")); + for(var feature in print_time) + { + if(!print_time[feature].isTotalDurationZero) + { + tooltip_html += "" + + "".arg(print_time[feature].getDisplayString(UM.DurationFormat.ISO8601).slice(0,-3)) + + "".arg(Math.round(100 * parseInt(print_time[feature].getDisplayString(UM.DurationFormat.Seconds)) / total_seconds)) + + ""; + } + } + tooltip_html += "
" + feature + ":  %1  %1%
"; + //print("trying to show tooltip", base, Qt.point(-UM.Theme.getSize("sidebar_margin").width, 0), tooltip_html) + base.showTooltip(parent, Qt.point(0, 0), tooltip_html); + } + } + onExited: + { + base.hideTooltip(); + } + } + } + + Label + { + function formatRow(items) + { + var row_html = ""; + for(var item = 0; item < items.length; item++) + { + if (item == 0) + { + row_html += "%1".arg(items[item]); + } + else + { + row_html += "  %1".arg(items[item]); + } + } + row_html += ""; + return row_html; + } + + function getSpecsData() + { + var lengths = []; + var total_length = 0; + var weights = []; + var total_weight = 0; + var costs = []; + var total_cost = 0; + var some_costs_known = false; + var names = []; + if(base.printMaterialLengths) + { + for(var index = 0; index < base.printMaterialLengths.length; index++) + { + if(base.printMaterialLengths[index] > 0) + { + names.push(base.printMaterialNames[index]); + lengths.push(base.printMaterialLengths[index].toFixed(2)); + weights.push(String(Math.round(base.printMaterialWeights[index]))); + var cost = base.printMaterialCosts[index] == undefined ? 0 : base.printMaterialCosts[index].toFixed(2); + costs.push(cost); + if(cost > 0) + { + some_costs_known = true; + } + + total_length += base.printMaterialLengths[index]; + total_weight += base.printMaterialWeights[index]; + total_cost += base.printMaterialCosts[index]; + } + } + } + if(lengths.length == 0) + { + lengths = ["0.00"]; + weights = ["0"]; + costs = ["0.00"]; + } + + var tooltip_html = "%1
".arg(catalog.i18nc("@label", "Cost specification")); + for(var index = 0; index < lengths.length; index++) + { + tooltip_html += formatRow([ + "%1:".arg(names[index]), + catalog.i18nc("@label m for meter", "%1m").arg(lengths[index]), + catalog.i18nc("@label g for grams", "%1g").arg(weights[index]), + "%1 %2".arg(UM.Preferences.getValue("cura/currency")).arg(costs[index]), + ]); + } + if(lengths.length > 1) + { + tooltip_html += formatRow([ + catalog.i18nc("@label", "Total:"), + catalog.i18nc("@label m for meter", "%1m").arg(total_length.toFixed(2)), + catalog.i18nc("@label g for grams", "%1g").arg(Math.round(total_weight)), + "%1 %2".arg(UM.Preferences.getValue("cura/currency")).arg(total_cost.toFixed(2)), + ]); + } + tooltip_html += "
"; + tooltipText = tooltip_html; + + return tooltipText + } + + id: costSpec + + anchors.left: parent.left + anchors.bottom: parent.bottom + anchors.bottomMargin: UM.Theme.getSize("sidebar_margin").height + anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width + + font: UM.Theme.getFont("very_small") + renderType: Text.NativeRendering + color: UM.Theme.getColor("text_subtext") + elide: Text.ElideMiddle + width: parent.width + property string tooltipText + text: + { + var lengths = []; + var weights = []; + var costs = []; + var someCostsKnown = false; + if(base.printMaterialLengths) { + for(var index = 0; index < base.printMaterialLengths.length; index++) + { + if(base.printMaterialLengths[index] > 0) + { + lengths.push(base.printMaterialLengths[index].toFixed(2)); + weights.push(String(Math.round(base.printMaterialWeights[index]))); + var cost = base.printMaterialCosts[index] == undefined ? 0 : base.printMaterialCosts[index].toFixed(2); + costs.push(cost); + if(cost > 0) + { + someCostsKnown = true; + } + } + } + } + if(lengths.length == 0) + { + lengths = ["0.00"]; + weights = ["0"]; + costs = ["0.00"]; + } + var result = lengths.join(" + ") + "m / ~ " + weights.join(" + ") + "g"; + if(someCostsKnown) + { + result += " / ~ " + costs.join(" + ") + " " + UM.Preferences.getValue("cura/currency"); + } + return result; + } + + MouseArea + { + id: costSpecMouseArea + anchors.fill: parent + hoverEnabled: true + + onEntered: + { + + if(base.printDuration.valid && !base.printDuration.isTotalDurationZero) + { + var show_data = costSpec.getSpecsData() + + base.showTooltip(parent, Qt.point(-UM.Theme.getSize("sidebar_margin").width, 0), show_data); + } + } + onExited: + { + base.hideTooltip(); + } + } + } + + SaveButton + { + id: saveButton + width: parent.width + height: 100 + anchors.bottom: parent.bottom + } +} \ No newline at end of file diff --git a/resources/qml/SaveButton.qml b/resources/qml/SaveButton.qml index 2a0a523026..8c561b0d00 100644 --- a/resources/qml/SaveButton.qml +++ b/resources/qml/SaveButton.qml @@ -9,7 +9,9 @@ import QtQuick.Layouts 1.1 import UM 1.1 as UM import Cura 1.0 as Cura -Item { +// This widget does so much more than "just" being a save button, so it should be refactored at some point in time. +Item +{ id: base; UM.I18nCatalog { id: catalog; name:"cura"} @@ -27,10 +29,6 @@ Item { return catalog.i18nc("@label:PrintjobStatus", "Please load a 3D model"); } - if (base.backendState == "undefined") { - return "" - } - switch(base.backendState) { case 1: @@ -48,19 +46,23 @@ Item { } } - function sliceOrStopSlicing() { + function sliceOrStopSlicing() + { try { - if ([1, 5].indexOf(base.backendState) != -1) { + if ([1, 5].indexOf(base.backendState) != -1) + { CuraApplication.backend.forceSlice(); } else { CuraApplication.backend.stopSlicing(); } - } catch (e) { + } catch (e) + { console.log('Could not start or stop slicing', e) } } - Label { + Label + { id: statusLabel width: parent.width - 2 * UM.Theme.getSize("sidebar_margin").width anchors.top: parent.top @@ -72,7 +74,8 @@ Item { text: statusText; } - Rectangle { + Rectangle + { id: progressBar width: parent.width - 2 * UM.Theme.getSize("sidebar_margin").width height: UM.Theme.getSize("progressbar").height @@ -83,32 +86,37 @@ Item { radius: UM.Theme.getSize("progressbar_radius").width color: UM.Theme.getColor("progressbar_background") - Rectangle { + Rectangle + { width: Math.max(parent.width * base.progress) height: parent.height color: UM.Theme.getColor("progressbar_control") radius: UM.Theme.getSize("progressbar_radius").width - visible: (base.backendState != "undefined" && base.backendState == 2) ? true : false + visible: base.backendState == 2 } } // Shortcut for "save as/print/..." - Action { + Action + { shortcut: "Ctrl+P" onTriggered: { // only work when the button is enabled - if (saveToButton.enabled) { + if (saveToButton.enabled) + { saveToButton.clicked(); } // prepare button - if (prepareButton.enabled) { + if (prepareButton.enabled) + { sliceOrStopSlicing(); } } } - Item { + Item + { id: saveRow width: { // using childrenRect.width directly causes a binding loop, because setting the width affects the childrenRect @@ -129,7 +137,8 @@ Item { anchors.right: parent.right clip: true - Row { + Row + { id: additionalComponentsRow anchors.top: parent.top anchors.right: saveToButton.visible ? saveToButton.left : (prepareButton.visible ? prepareButton.left : parent.right) @@ -138,24 +147,30 @@ Item { spacing: UM.Theme.getSize("default_margin").width } - Component.onCompleted: { + Component.onCompleted: + { saveRow.addAdditionalComponents("saveButton") } - Connections { + Connections + { target: CuraApplication onAdditionalComponentsChanged: saveRow.addAdditionalComponents("saveButton") } - function addAdditionalComponents (areaId) { - if(areaId == "saveButton") { - for (var component in CuraApplication.additionalComponents["saveButton"]) { + function addAdditionalComponents (areaId) + { + if(areaId == "saveButton") + { + for (var component in CuraApplication.additionalComponents["saveButton"]) + { CuraApplication.additionalComponents["saveButton"][component].parent = additionalComponentsRow } } } - Connections { + Connections + { target: UM.Preferences onPreferenceChanged: { @@ -166,13 +181,14 @@ Item { } // Prepare button, only shows if auto_slice is off - Button { + Button + { id: prepareButton tooltip: [1, 5].indexOf(base.backendState) != -1 ? catalog.i18nc("@info:tooltip","Slice current printjob") : catalog.i18nc("@info:tooltip","Cancel slicing process") // 1 = not started, 2 = Processing - enabled: base.backendState != "undefined" && ([1, 2].indexOf(base.backendState) != -1) && base.activity - visible: base.backendState != "undefined" && !autoSlice && ([1, 2, 4].indexOf(base.backendState) != -1) && base.activity + enabled: ([1, 2].indexOf(base.backendState) != -1) && base.activity + visible: !autoSlice && ([1, 2, 4].indexOf(base.backendState) != -1) && base.activity property bool autoSlice height: UM.Theme.getSize("save_button_save_to_button").height @@ -236,11 +252,12 @@ Item { text: control.text; } } - label: Item { } + label: Item {} } } - Button { + Button + { id: saveToButton tooltip: UM.OutputDeviceManager.activeDeviceDescription; @@ -262,7 +279,8 @@ Item { { "filter_by_machine": true, "preferred_mimetypes": Cura.MachineManager.activeMachine.preferred_output_file_formats }); } - style: ButtonStyle { + style: ButtonStyle + { background: Rectangle { border.width: UM.Theme.getSize("default_lining").width @@ -296,17 +314,7 @@ Item { Label { id: actualLabel anchors.centerIn: parent - color: - { - if(!control.enabled) - return UM.Theme.getColor("action_button_disabled_text"); - else if(control.pressed) - return UM.Theme.getColor("print_button_ready_text"); - else if(control.hovered) - return UM.Theme.getColor("print_button_ready_text"); - else - return UM.Theme.getColor("print_button_ready_text"); - } + color:control.enabled ? UM.Theme.getColor("print_button_ready_text") : UM.Theme.getColor("action_button_disabled_text") font: UM.Theme.getFont("action_button") text: control.text; } @@ -324,36 +332,49 @@ Item { anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width width: UM.Theme.getSize("save_button_save_to_button").height height: UM.Theme.getSize("save_button_save_to_button").height + // 3 = Done, 5 = Disabled - enabled: base.backendState != "undefined" && (base.backendState == 3 || base.backendState == 5) && base.activity == true - visible: base.backendState != "undefined" && (devicesModel.deviceCount > 1) && (base.backendState == 3 || base.backendState == 5) && base.activity == true + enabled: (base.backendState == 3 || base.backendState == 5) && base.activity == true + visible: (devicesModel.deviceCount > 1) && (base.backendState == 3 || base.backendState == 5) && base.activity == true - style: ButtonStyle { - background: Rectangle { + style: ButtonStyle + { + background: Rectangle + { id: deviceSelectionIcon border.width: UM.Theme.getSize("default_lining").width border.color: { if(!control.enabled) - return UM.Theme.getColor("action_button_disabled_border"); - else if(control.pressed) - return UM.Theme.getColor("print_button_ready_pressed_border"); - else if(control.hovered) - return UM.Theme.getColor("print_button_ready_hovered_border"); - else - return UM.Theme.getColor("print_button_ready_border"); + { + return UM.Theme.getColor("action_button_disabled_border") + } else if(control.pressed) + { + return UM.Theme.getColor("print_button_ready_pressed_border") + } else if(control.hovered) + { + return UM.Theme.getColor("print_button_ready_hovered_border") + } else + { + return UM.Theme.getColor("print_button_ready_border") + } } color: { if(!control.enabled) - return UM.Theme.getColor("action_button_disabled"); - else if(control.pressed) - return UM.Theme.getColor("print_button_ready_pressed"); - else if(control.hovered) - return UM.Theme.getColor("print_button_ready_hovered"); - else - return UM.Theme.getColor("print_button_ready"); + { + return UM.Theme.getColor("action_button_disabled") + } else if(control.pressed) + { + return UM.Theme.getColor("print_button_ready_pressed") + } else if(control.hovered) + { + return UM.Theme.getColor("print_button_ready_hovered") + } else + { + return UM.Theme.getColor("print_button_ready") + } } Behavior on color { ColorAnimation { duration: 50; } } anchors.left: parent.left @@ -361,40 +382,34 @@ Item { width: parent.height height: parent.height - UM.RecolorImage { + UM.RecolorImage + { anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height sourceSize.width: width sourceSize.height: height - color: - { - if(!control.enabled) - return UM.Theme.getColor("action_button_disabled_text"); - else if(control.pressed) - return UM.Theme.getColor("print_button_ready_text"); - else if(control.hovered) - return UM.Theme.getColor("print_button_ready_text"); - else - return UM.Theme.getColor("print_button_ready_text"); - } + color: control.enabled ? UM.Theme.getColor("print_button_ready_text") : UM.Theme.getColor("action_button_disabled_text") source: UM.Theme.getIcon("arrow_bottom"); } } - label: Label{ } } - menu: Menu { + menu: Menu + { id: devicesMenu; - Instantiator { + Instantiator + { model: devicesModel; - MenuItem { + MenuItem + { text: model.description checkable: true; checked: model.id == UM.OutputDeviceManager.activeDevice; exclusiveGroup: devicesMenuGroup; - onTriggered: { + onTriggered: + { UM.OutputDeviceManager.setActiveDevice(model.id); } } diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index da50b430ac..5a6811926e 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -25,7 +25,6 @@ Item { id: globalProfileRow height: UM.Theme.getSize("sidebar_setup").height - visible: !sidebar.hideSettings anchors { @@ -54,7 +53,6 @@ Item id: globalProfileSelection text: generateActiveQualityText() - enabled: !header.currentExtruderVisible || header.currentExtruderIndex > -1 width: Math.round(parent.width * 0.55) height: UM.Theme.getSize("setting_control").height anchors.left: globalProfileLabel.right @@ -177,9 +175,7 @@ Item right: settingVisibilityMenu.left rightMargin: Math.floor(UM.Theme.getSize("default_margin").width / 2) } - height: visible ? UM.Theme.getSize("setting_control").height : 0 - Behavior on height { NumberAnimation { duration: 100 } } - + height: UM.Theme.getSize("setting_control").height Timer { id: settingsSearchTimer @@ -292,8 +288,7 @@ Item anchors.bottom: parent.bottom; anchors.right: parent.right; anchors.left: parent.left; - anchors.topMargin: filterContainer.visible ? UM.Theme.getSize("sidebar_margin").height : 0 - Behavior on anchors.topMargin { NumberAnimation { duration: 100 } } + anchors.topMargin: UM.Theme.getSize("sidebar_margin").height style: UM.Theme.styles.scrollview; flickableItem.flickableDirection: Flickable.VerticalFlick; diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index df4f493ea5..15ca60e6e3 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -90,7 +90,8 @@ Column } } - Rectangle { + Rectangle + { id: headerSeparator width: parent.width visible: printerTypeSelectionRow.visible diff --git a/resources/qml/Skeleton/TopHeader.qml b/resources/qml/Skeleton/TopHeader.qml index c24fe86af0..f08a0aaca3 100644 --- a/resources/qml/Skeleton/TopHeader.qml +++ b/resources/qml/Skeleton/TopHeader.qml @@ -15,7 +15,8 @@ Rectangle { id: base - height: UM.Theme.getSize("topheader").height + implicitHeight: UM.Theme.getSize("topheader").height + implicitWidth: UM.Theme.getSize("topheader").width color: UM.Theme.getColor("topheader_background") Image From 2fce1e433a4c732462310c24c63970752e6fcd43 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 15 Oct 2018 09:49:08 +0200 Subject: [PATCH 0024/1292] Fix the tooltips for time estimations CURA-5772 --- resources/qml/ProgressAndSaveWidget.qml | 3 +-- resources/qml/SidebarTooltip.qml | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/resources/qml/ProgressAndSaveWidget.qml b/resources/qml/ProgressAndSaveWidget.qml index 88819af759..2fa5cf6149 100644 --- a/resources/qml/ProgressAndSaveWidget.qml +++ b/resources/qml/ProgressAndSaveWidget.qml @@ -60,8 +60,7 @@ Rectangle } } tooltip_html += ""; - //print("trying to show tooltip", base, Qt.point(-UM.Theme.getSize("sidebar_margin").width, 0), tooltip_html) - base.showTooltip(parent, Qt.point(0, 0), tooltip_html); + base.showTooltip(parent, Qt.point(-UM.Theme.getSize("sidebar_margin").width, 0), tooltip_html); } } onExited: diff --git a/resources/qml/SidebarTooltip.qml b/resources/qml/SidebarTooltip.qml index 29199481f6..4fa4ef9dd7 100644 --- a/resources/qml/SidebarTooltip.qml +++ b/resources/qml/SidebarTooltip.qml @@ -36,7 +36,7 @@ UM.PointingRectangle { } } base.opacity = 1; - target = Qt.point(40 , position.y + Math.round(UM.Theme.getSize("tooltip_arrow_margins").height / 2)) + target = Qt.point(position.x + 1, position.y + Math.round(UM.Theme.getSize("tooltip_arrow_margins").height / 2)) } function hide() { From fc1faf79f5dec5dc9271e5ee7fe89079161dae5a Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 15 Oct 2018 09:52:48 +0200 Subject: [PATCH 0025/1292] Cleanup unused code CURA-5772 --- resources/qml/Cura.qml | 118 +---------------------------------------- 1 file changed, 2 insertions(+), 116 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index f89f8d63dd..8955cb9598 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -21,7 +21,6 @@ UM.MainWindow // Cura application window title title: catalog.i18nc("@title:window", "Ultimaker Cura") - //viewportRect: Qt.rect(0, 0, (base.width - sidebar.width) / base.width, 1.0) viewportRect: Qt.rect(0, 0, 1.0, 1.0) backgroundColor: UM.Theme.getColor("viewport_background") @@ -43,24 +42,6 @@ UM.MainWindow tooltip.hide(); } - /*onWidthChanged: - { - // If slidebar is collapsed then it should be invisible - // otherwise after the main_window resize the sidebar will be fully re-drawn - if (sidebar.collapsed){ - if (sidebar.visible == true){ - sidebar.visible = false - sidebar.initialWidth = 0 - } - } - else{ - if (sidebar.visible == false){ - sidebar.visible = true - sidebar.initialWidth = UM.Theme.getSize("sidebar").width - } - } - }*/ - Component.onCompleted: { CuraApplication.setMinimumWindowSize(UM.Theme.getSize("window_minimum_size")) @@ -193,14 +174,11 @@ UM.MainWindow anchors { bottom: parent.bottom - //right: sidebar.left bottomMargin: UM.Theme.getSize("default_margin").height rightMargin: UM.Theme.getSize("default_margin").width } } - - Toolbar { id: toolbar @@ -226,18 +204,6 @@ UM.MainWindow } } - /*ApplicationViews - { - id: applicationViews - - - anchors - { - top: parent.top - right: sidebar.left - } - }*/ - Loader { id: main @@ -261,78 +227,6 @@ UM.MainWindow source: UM.Controller.activeStage.mainComponent } - /*Loader - { - id: sidebar - - property bool collapsed: false - property var initialWidth: UM.Theme.getSize("sidebar").width - - function callExpandOrCollapse() - { - if (collapsed) - { - sidebar.visible = true - sidebar.initialWidth = UM.Theme.getSize("sidebar").width - viewportRect = Qt.rect(0, 0, (base.width - sidebar.width) / base.width, 1.0) - expandSidebarAnimation.start(); - } - else - { - viewportRect = Qt.rect(0, 0, 1, 1.0) - collapseSidebarAnimation.start() - } - collapsed = !collapsed - UM.Preferences.setValue("cura/sidebar_collapsed", collapsed) - } - - anchors - { - top: parent.top - bottom: parent.bottom - } - - width: initialWidth - x: base.width - sidebar.width - source: UM.Controller.activeStage.sidebarComponent - - NumberAnimation { - id: collapseSidebarAnimation - target: sidebar - properties: "x" - to: base.width - duration: 100 - } - - NumberAnimation { - id: expandSidebarAnimation - target: sidebar - properties: "x" - to: base.width - sidebar.width - duration: 100 - } - - Component.onCompleted: - { - var sidebar_collapsed = UM.Preferences.getValue("cura/sidebar_collapsed") - - if (sidebar_collapsed) - { - sidebar.collapsed = true - viewportRect = Qt.rect(0, 0, 1, 1.0) - collapseSidebarAnimation.start() - } - } - - MouseArea - { - visible: UM.Controller.activeStage.sidebarComponent != "" - anchors.fill: parent - acceptedButtons: Qt.AllButtons - onWheel: wheel.accepted = true - } - }*/ - UM.MessageStack { anchors @@ -345,7 +239,6 @@ UM.MainWindow } } - ViewOrientationControls { id: viewOrientationControls @@ -359,7 +252,6 @@ UM.MainWindow } } - ProgressAndSaveWidget { anchors.right: parent.right @@ -379,13 +271,6 @@ UM.MainWindow } } - // Expand or collapse sidebar - /*Connections - { - target: Cura.Actions.expandSidebar - onTriggered: sidebar.callExpandOrCollapse() - }*/ - UM.PreferencesDialog { id: preferences @@ -509,7 +394,8 @@ UM.MainWindow } } - ContextMenu { + ContextMenu + { id: contextMenu } From 8cac5e1de214b34ad39328fe93b29a9bfe270afe Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 15 Oct 2018 10:26:27 +0200 Subject: [PATCH 0026/1292] Removed the components qml dir We can consider putting components into their own folder, but we first should have a clear definition of what they are / should be. CURA-5772 --- resources/qml/Account/AccountDetails.qml | 2 -- resources/qml/Account/GeneralOperations.qml | 6 ++---- resources/qml/Account/UserOperations.qml | 6 ++---- resources/qml/{components => }/ActionButton.qml | 0 resources/qml/Cura.qml | 1 - .../{components => }/MachineAndConfigurationSelector.qml | 5 ++--- resources/qml/ProfileAndSettingComponent.qml | 2 -- resources/qml/Skeleton/ApplicationViews.qml | 1 - resources/qml/Skeleton/TopHeader.qml | 1 - resources/qml/{components => }/ViewOrientationControls.qml | 0 resources/qml/qmldir | 5 +++-- 11 files changed, 9 insertions(+), 20 deletions(-) rename resources/qml/{components => }/ActionButton.qml (100%) rename resources/qml/{components => }/MachineAndConfigurationSelector.qml (94%) rename resources/qml/{components => }/ViewOrientationControls.qml (100%) diff --git a/resources/qml/Account/AccountDetails.qml b/resources/qml/Account/AccountDetails.qml index ab1ccc15df..4d6b0a314b 100644 --- a/resources/qml/Account/AccountDetails.qml +++ b/resources/qml/Account/AccountDetails.qml @@ -7,8 +7,6 @@ import QtQuick.Controls 2.1 import UM 1.4 as UM import Cura 1.1 as Cura -import "../components" - Column { property var profile: null diff --git a/resources/qml/Account/GeneralOperations.qml b/resources/qml/Account/GeneralOperations.qml index d224de44bb..1f3cd51f26 100644 --- a/resources/qml/Account/GeneralOperations.qml +++ b/resources/qml/Account/GeneralOperations.qml @@ -7,13 +7,11 @@ import QtQuick.Controls 1.1 import UM 1.4 as UM import Cura 1.1 as Cura -import "../components" - Row { spacing: UM.Theme.getSize("default_margin").width - ActionButton + Cura.ActionButton { width: UM.Theme.getSize("account_button").width height: UM.Theme.getSize("account_button").height @@ -25,7 +23,7 @@ Row onClicked: Qt.openUrlExternally("https://account.ultimaker.com") } - ActionButton + Cura.ActionButton { width: UM.Theme.getSize("account_button").width height: UM.Theme.getSize("account_button").height diff --git a/resources/qml/Account/UserOperations.qml b/resources/qml/Account/UserOperations.qml index 1704254ed3..ffcf518b6e 100644 --- a/resources/qml/Account/UserOperations.qml +++ b/resources/qml/Account/UserOperations.qml @@ -7,13 +7,11 @@ import QtQuick.Controls 1.1 import UM 1.4 as UM import Cura 1.1 as Cura -import "../components" - Row { spacing: UM.Theme.getSize("default_margin").width - ActionButton + Cura.ActionButton { width: UM.Theme.getSize("account_button").width height: UM.Theme.getSize("account_button").height @@ -25,7 +23,7 @@ Row onClicked: Qt.openUrlExternally("https://account.ultimaker.com") } - ActionButton + Cura.ActionButton { width: UM.Theme.getSize("account_button").width height: UM.Theme.getSize("account_button").height diff --git a/resources/qml/components/ActionButton.qml b/resources/qml/ActionButton.qml similarity index 100% rename from resources/qml/components/ActionButton.qml rename to resources/qml/ActionButton.qml diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 8955cb9598..304f78e633 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -13,7 +13,6 @@ import Cura 1.1 as Cura import "Dialogs" import "Menus" import "Skeleton" -import "components" UM.MainWindow { diff --git a/resources/qml/components/MachineAndConfigurationSelector.qml b/resources/qml/MachineAndConfigurationSelector.qml similarity index 94% rename from resources/qml/components/MachineAndConfigurationSelector.qml rename to resources/qml/MachineAndConfigurationSelector.qml index 5b919c42d8..15b9ca6dd6 100644 --- a/resources/qml/components/MachineAndConfigurationSelector.qml +++ b/resources/qml/MachineAndConfigurationSelector.qml @@ -5,9 +5,8 @@ import QtQuick 2.7 import UM 1.2 as UM import Cura 1.0 as Cura -import "../Menus" -import "../Menus/ConfigurationMenu" -import ".." +import "Menus" +import "Menus/ConfigurationMenu" Rectangle { diff --git a/resources/qml/ProfileAndSettingComponent.qml b/resources/qml/ProfileAndSettingComponent.qml index 33c2f37fb1..dbded90576 100644 --- a/resources/qml/ProfileAndSettingComponent.qml +++ b/resources/qml/ProfileAndSettingComponent.qml @@ -9,8 +9,6 @@ import UM 1.2 as UM import Cura 1.0 as Cura import "Menus" import "Menus/ConfigurationMenu" -import "components" - Rectangle { diff --git a/resources/qml/Skeleton/ApplicationViews.qml b/resources/qml/Skeleton/ApplicationViews.qml index eb8ab16fae..d91837a2db 100644 --- a/resources/qml/Skeleton/ApplicationViews.qml +++ b/resources/qml/Skeleton/ApplicationViews.qml @@ -9,7 +9,6 @@ import QtQuick.Layouts 1.1 import UM 1.4 as UM import Cura 1.0 as Cura -import "../components" // This item contains the views selector, a combobox that is dynamically created from // the list of available Views (packages that create different visualizations of the diff --git a/resources/qml/Skeleton/TopHeader.qml b/resources/qml/Skeleton/TopHeader.qml index f08a0aaca3..7344d01436 100644 --- a/resources/qml/Skeleton/TopHeader.qml +++ b/resources/qml/Skeleton/TopHeader.qml @@ -8,7 +8,6 @@ import QtQuick.Controls.Styles 1.1 import UM 1.4 as UM import Cura 1.0 as Cura -import "../components" import "../Account" Rectangle diff --git a/resources/qml/components/ViewOrientationControls.qml b/resources/qml/ViewOrientationControls.qml similarity index 100% rename from resources/qml/components/ViewOrientationControls.qml rename to resources/qml/ViewOrientationControls.qml diff --git a/resources/qml/qmldir b/resources/qml/qmldir index 5083b5e80a..b9306b14bc 100644 --- a/resources/qml/qmldir +++ b/resources/qml/qmldir @@ -1,5 +1,6 @@ module Cura -MachineAndConfigurationSelector 1.0 components/MachineAndConfigurationSelector.qml +MachineAndConfigurationSelector 1.0 MachineAndConfigurationSelector.qml MaterialAndVariantSelector 1.0 MaterialAndVariantSelector.qml -ProfileAndSettingComponent 1.0 ProfileAndSettingComponent.qml \ No newline at end of file +ProfileAndSettingComponent 1.0 ProfileAndSettingComponent.qml +ActionButton 1.0 ActionButton.qml \ No newline at end of file From d2baef97c4e2d014884e22537330e4ecc4b34cf5 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 15 Oct 2018 11:07:03 +0200 Subject: [PATCH 0027/1292] Fix tooltips for settings CURA-5772 --- plugins/PrepareStage/PrepareMenu.qml | 12 +- resources/qml/Cura.qml | 8 +- resources/qml/ProfileAndSettingComponent.qml | 246 +------------------ 3 files changed, 24 insertions(+), 242 deletions(-) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index eb09326524..353c4df51a 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -10,6 +10,10 @@ Row { spacing: UM.Theme.getSize("default_margin").width + // This widget doesn't show tooltips by itself. Instead it emits signals so others can do something with it. + signal showTooltip(Item item, point location, string text) + signal hideTooltip() + UM.I18nCatalog { id: catalog @@ -18,12 +22,12 @@ Row Button { - id: openFileButton; - text: catalog.i18nc("@action:button", "Open File"); + id: openFileButton + text: catalog.i18nc("@action:button", "Open File") iconSource: UM.Theme.getIcon("load") style: UM.Theme.styles.tool_button tooltip: "" - action: Cura.Actions.open; + action: Cura.Actions.open } Cura.MachineAndConfigurationSelector @@ -38,5 +42,7 @@ Row Cura.ProfileAndSettingComponent { width: UM.Theme.getSize("sidebar").width + onShowTooltip: parent.showTooltip(item, location, text) + onHideTooltip: parent.hideTooltip() } } \ No newline at end of file diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 304f78e633..97cdc94d64 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -163,10 +163,16 @@ UM.MainWindow } height: 50 - source: UM.Controller.activeStage.stageMenuComponent } + Connections + { + target: stageMenu.item + onShowTooltip: base.showTooltip(item, location, text) + onHideTooltop: base.hideTooltip() + } + JobSpecs { id: jobSpecs diff --git a/resources/qml/ProfileAndSettingComponent.qml b/resources/qml/ProfileAndSettingComponent.qml index dbded90576..b367c1130f 100644 --- a/resources/qml/ProfileAndSettingComponent.qml +++ b/resources/qml/ProfileAndSettingComponent.qml @@ -28,6 +28,10 @@ Rectangle color: UM.Theme.getColor("sidebar") UM.I18nCatalog { id: catalog; name:"cura"} + // This widget doesn't show tooltips by itself. Instead it emits signals so others can do something with it. + signal showTooltip(Item item, point location, string text) + signal hideTooltip() + Timer { id: tooltipDelayTimer @@ -42,18 +46,6 @@ Rectangle } } - function showTooltip(item, position, text) - { - tooltip.text = text; - position = item.mapToItem(base, position.x - UM.Theme.getSize("default_arrow").width, position.y); - tooltip.show(position); - } - - function hideTooltip() - { - tooltip.hide(); - } - function strPadLeft(string, pad, length) { return (new Array(length + 1).join(pad) + string).slice(-length); @@ -205,241 +197,19 @@ Rectangle { anchors.fill: parent visible: currentModeIndex == 1 + onShowTooltip: base.showTooltip(item, location, text) + onHideTooltip: base.hideTooltip() } SidebarSimple { anchors.fill: parent visible: currentModeIndex != 1 + onShowTooltip: base.showTooltip(item, location, text) + onHideTooltip: base.hideTooltip() } } - /*Item - { - id: printSpecs - anchors.left: parent.left - anchors.bottom: parent.bottom - anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width - anchors.bottomMargin: UM.Theme.getSize("sidebar_margin").height - height: timeDetails.height + costSpec.height - width: base.width - (saveButton.buttonRowWidth + UM.Theme.getSize("sidebar_margin").width) - - Label - { - id: timeDetails - anchors.left: parent.left - anchors.bottom: costSpec.top - font: UM.Theme.getFont("large") - color: UM.Theme.getColor("text_subtext") - text: (!base.printDuration || !base.printDuration.valid) ? catalog.i18nc("@label Hours and minutes", "00h 00min") : base.printDuration.getDisplayString(UM.DurationFormat.Short) - renderType: Text.NativeRendering - - MouseArea - { - id: timeDetailsMouseArea - anchors.fill: parent - hoverEnabled: true - - onEntered: - { - if(base.printDuration.valid && !base.printDuration.isTotalDurationZero) - { - // All the time information for the different features is achieved - var print_time = PrintInformation.getFeaturePrintTimes(); - var total_seconds = parseInt(base.printDuration.getDisplayString(UM.DurationFormat.Seconds)) - - // A message is created and displayed when the user hover the time label - var tooltip_html = "%1
".arg(catalog.i18nc("@tooltip", "Time specification")); - for(var feature in print_time) - { - if(!print_time[feature].isTotalDurationZero) - { - tooltip_html += "" + - "".arg(print_time[feature].getDisplayString(UM.DurationFormat.ISO8601).slice(0,-3)) + - "".arg(Math.round(100 * parseInt(print_time[feature].getDisplayString(UM.DurationFormat.Seconds)) / total_seconds)) + - ""; - } - } - tooltip_html += "
" + feature + ":  %1  %1%
"; - - base.showTooltip(parent, Qt.point(-UM.Theme.getSize("sidebar_margin").width, 0), tooltip_html); - } - } - onExited: - { - base.hideTooltip(); - } - } - } - - Label - { - function formatRow(items) - { - var row_html = ""; - for(var item = 0; item < items.length; item++) - { - if (item == 0) - { - row_html += "%1".arg(items[item]); - } - else - { - row_html += "  %1".arg(items[item]); - } - } - row_html += ""; - return row_html; - } - - function getSpecsData() - { - var lengths = []; - var total_length = 0; - var weights = []; - var total_weight = 0; - var costs = []; - var total_cost = 0; - var some_costs_known = false; - var names = []; - if(base.printMaterialLengths) - { - for(var index = 0; index < base.printMaterialLengths.length; index++) - { - if(base.printMaterialLengths[index] > 0) - { - names.push(base.printMaterialNames[index]); - lengths.push(base.printMaterialLengths[index].toFixed(2)); - weights.push(String(Math.round(base.printMaterialWeights[index]))); - var cost = base.printMaterialCosts[index] == undefined ? 0 : base.printMaterialCosts[index].toFixed(2); - costs.push(cost); - if(cost > 0) - { - some_costs_known = true; - } - - total_length += base.printMaterialLengths[index]; - total_weight += base.printMaterialWeights[index]; - total_cost += base.printMaterialCosts[index]; - } - } - } - if(lengths.length == 0) - { - lengths = ["0.00"]; - weights = ["0"]; - costs = ["0.00"]; - } - - var tooltip_html = "%1
".arg(catalog.i18nc("@label", "Cost specification")); - for(var index = 0; index < lengths.length; index++) - { - tooltip_html += formatRow([ - "%1:".arg(names[index]), - catalog.i18nc("@label m for meter", "%1m").arg(lengths[index]), - catalog.i18nc("@label g for grams", "%1g").arg(weights[index]), - "%1 %2".arg(UM.Preferences.getValue("cura/currency")).arg(costs[index]), - ]); - } - if(lengths.length > 1) - { - tooltip_html += formatRow([ - catalog.i18nc("@label", "Total:"), - catalog.i18nc("@label m for meter", "%1m").arg(total_length.toFixed(2)), - catalog.i18nc("@label g for grams", "%1g").arg(Math.round(total_weight)), - "%1 %2".arg(UM.Preferences.getValue("cura/currency")).arg(total_cost.toFixed(2)), - ]); - } - tooltip_html += "
"; - tooltipText = tooltip_html; - - return tooltipText - } - - id: costSpec - anchors.left: parent.left - anchors.bottom: parent.bottom - font: UM.Theme.getFont("very_small") - renderType: Text.NativeRendering - color: UM.Theme.getColor("text_subtext") - elide: Text.ElideMiddle - width: parent.width - property string tooltipText - text: - { - var lengths = []; - var weights = []; - var costs = []; - var someCostsKnown = false; - if(base.printMaterialLengths) { - for(var index = 0; index < base.printMaterialLengths.length; index++) - { - if(base.printMaterialLengths[index] > 0) - { - lengths.push(base.printMaterialLengths[index].toFixed(2)); - weights.push(String(Math.round(base.printMaterialWeights[index]))); - var cost = base.printMaterialCosts[index] == undefined ? 0 : base.printMaterialCosts[index].toFixed(2); - costs.push(cost); - if(cost > 0) - { - someCostsKnown = true; - } - } - } - } - if(lengths.length == 0) - { - lengths = ["0.00"]; - weights = ["0"]; - costs = ["0.00"]; - } - var result = lengths.join(" + ") + "m / ~ " + weights.join(" + ") + "g"; - if(someCostsKnown) - { - result += " / ~ " + costs.join(" + ") + " " + UM.Preferences.getValue("cura/currency"); - } - return result; - } - MouseArea - { - id: costSpecMouseArea - anchors.fill: parent - hoverEnabled: true - - onEntered: - { - - if(base.printDuration.valid && !base.printDuration.isTotalDurationZero) - { - var show_data = costSpec.getSpecsData() - - base.showTooltip(parent, Qt.point(-UM.Theme.getSize("sidebar_margin").width, 0), show_data); - } - } - onExited: - { - base.hideTooltip(); - } - } - } - }*/ - - // SaveButton is actually the bottom footer panel. - /*SaveButton - { - id: saveButton - implicitWidth: base.width - anchors.top: footerSeparator.bottom - anchors.topMargin: UM.Theme.getSize("sidebar_margin").height - anchors.bottom: parent.bottom - }*/ - - /* - SidebarTooltip - { - id: tooltip - }*/ - // Setting mode: Recommended or Custom ListModel { From 0a1dad92ea50beeab3bdf7fc487e4d48e1169142 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 15 Oct 2018 13:41:44 +0200 Subject: [PATCH 0028/1292] Change AvatarImage so it uses aliases instead of properties I've changed this because it makes for much cleaner QML CURA-5772 --- resources/qml/Account/AvatarImage.qml | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/resources/qml/Account/AvatarImage.qml b/resources/qml/Account/AvatarImage.qml index 96c3cd2330..0e0d182018 100644 --- a/resources/qml/Account/AvatarImage.qml +++ b/resources/qml/Account/AvatarImage.qml @@ -7,19 +7,19 @@ import UM 1.4 as UM Item { + // This item shows the provided image while applying a round mask to it. + // It also shows a round border around it. The color is defined by the outlineColor property. + id: avatar - property var source - property var fallbackSource: UM.Theme.getImage("avatar_default") - property var outlineColor: UM.Theme.getColor("account_widget_ouline_active") + property alias source: profileImage.source + property alias outlineColor: profileImageOutline.color Image { id: profileImage - source: avatar.source ? avatar.source : UM.Theme.getImage("avatar_default") - sourceSize: Qt.size(parent.width, parent.height) - width: parent.width - height: parent.height + source: UM.Theme.getImage("avatar_default") + anchors.fill: parent fillMode: Image.PreserveAspectCrop visible: false } @@ -29,8 +29,7 @@ Item id: profileImageMask source: UM.Theme.getIcon("circle_mask") sourceSize: Qt.size(parent.width, parent.height) - width: parent.width - height: parent.height + anchors.fill: parent color: UM.Theme.getColor("topheader_background") visible: false } @@ -49,8 +48,7 @@ Item id: profileImageOutline source: UM.Theme.getIcon("circle_outline") sourceSize: Qt.size(parent.width, parent.height) - width: parent.width - height: parent.height - color: avatar.outlineColor + anchors.fill: parent + color: UM.Theme.getColor("account_widget_ouline_active") } } \ No newline at end of file From 62c99804381a0d8647791b888cf163499a22a5ca Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 15 Oct 2018 14:07:01 +0200 Subject: [PATCH 0029/1292] Move SidebarTooltip so that it's no longer ocluded by other objects CURA-5772 --- resources/qml/Cura.qml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 97cdc94d64..bf71bd8d94 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -63,11 +63,6 @@ UM.MainWindow id: backgroundItem anchors.fill: parent - SidebarTooltip - { - id: tooltip - } - signal hasMesh(string name) //this signal sends the filebase name so it can be used for the JobSpecs.qml function getMeshName(path) { @@ -274,6 +269,11 @@ UM.MainWindow } } } + + SidebarTooltip + { + id: tooltip + } } UM.PreferencesDialog From f6ae19003ba77a5da9d8a8a90016422f0b9ef297 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 15 Oct 2018 14:07:30 +0200 Subject: [PATCH 0030/1292] The AccountDetails Panel is now an actual popup This ensures that it's always visible (previously it was ocluded by the StageMenu) CURA-5772 --- resources/qml/Account/AccountWidget.qml | 65 ++++++++++++------------- 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/resources/qml/Account/AccountWidget.qml b/resources/qml/Account/AccountWidget.qml index 1d9541de2c..1b4e6de1b2 100644 --- a/resources/qml/Account/AccountWidget.qml +++ b/resources/qml/Account/AccountWidget.qml @@ -7,62 +7,59 @@ import QtQuick.Controls 2.1 import UM 1.4 as UM import Cura 1.1 as Cura -Item +Button { id: accountWidget property var profile: Cura.API.account.userProfile property var loggedIn: Cura.API.account.isLoggedIn - height: UM.Theme.getSize("topheader").height - width: UM.Theme.getSize("topheader").height + + implicitHeight: UM.Theme.getSize("topheader").height + implicitWidth: UM.Theme.getSize("topheader").height + AvatarImage { id: avatar + + width: Math.round(0.8 * parent.width) height: Math.round(0.8 * parent.height) anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter + source: loggedIn ? profile["profile_image_url"] : UM.Theme.getImage("avatar_default") outlineColor: loggedIn ? UM.Theme.getColor("account_widget_ouline_active") : UM.Theme.getColor("account_widget_ouline_inactive") } - MouseArea + background: Item {} + + onClicked: popup.open() + + Popup { - anchors.fill: parent - onClicked: accountManagementPanel.visible = !accountManagementPanel.visible // Collapse/Expand the dropdown panel - } + id: popup - UM.PointingRectangle - { - id: accountManagementPanel + y: parent.height + UM.Theme.getSize("default_arrow").height + x: (parent.width - width) - width: panel.width - height: panel.height - - anchors - { - top: parent.bottom - topMargin: UM.Theme.getSize("default_margin").height - right: parent.right - } - - target: Qt.point(parent.width / 2, parent.bottom) - arrowSize: UM.Theme.getSize("default_arrow").width - - visible: false - opacity: visible ? 1 : 0 - Behavior on opacity { NumberAnimation { duration: 100 } } - - color: UM.Theme.getColor("tool_panel_background") - borderColor: UM.Theme.getColor("lining") - borderWidth: UM.Theme.getSize("default_lining").width - - // Shows the user management options or general options to create account - AccountDetails + contentItem: AccountDetails { id: panel profile: Cura.API.account.userProfile loggedIn: Cura.API.account.isLoggedIn } + + background: UM.PointingRectangle + { + opacity: visible ? 1 : 0 + Behavior on opacity { NumberAnimation { duration: 100 } } + color: UM.Theme.getColor("tool_panel_background") + borderColor: UM.Theme.getColor("lining") + borderWidth: UM.Theme.getSize("default_lining").width + + target: Qt.point(width - (accountWidget.width / 2), -10) + + arrowSize: UM.Theme.getSize("default_arrow").width + } } -} \ No newline at end of file +} From 4e432a5f06c5726f4c83e8127636470867274631 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 15 Oct 2018 14:21:03 +0200 Subject: [PATCH 0031/1292] Remove SidebarHeader It has been replaced by others, so we don't need it anymore CURA-5772 --- resources/qml/SidebarHeader.qml | 618 -------------------------------- 1 file changed, 618 deletions(-) delete mode 100644 resources/qml/SidebarHeader.qml diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml deleted file mode 100644 index 15ca60e6e3..0000000000 --- a/resources/qml/SidebarHeader.qml +++ /dev/null @@ -1,618 +0,0 @@ -// Copyright (c) 2017 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.7 -import QtQuick.Controls 1.1 -import QtQuick.Controls.Styles 1.1 - -import UM 1.2 as UM -import Cura 1.0 as Cura - -import "Menus" - -Column -{ - id: base; - - property int currentExtruderIndex: Cura.ExtruderManager.activeExtruderIndex; - property bool currentExtruderVisible: extrudersList.visible; - property bool printerConnected: Cura.MachineManager.printerConnected - property bool hasManyPrinterTypes: - { - if (printerConnected) - { - if (Cura.MachineManager.printerOutputDevices[0].connectedPrintersTypeCount != null) - { - return Cura.MachineManager.printerOutputDevices[0].connectedPrintersTypeCount.length > 1; - } - } - return false; - } - property bool buildplateCompatibilityError: !Cura.MachineManager.variantBuildplateCompatible && !Cura.MachineManager.variantBuildplateUsable - property bool buildplateCompatibilityWarning: Cura.MachineManager.variantBuildplateUsable - - spacing: Math.round(UM.Theme.getSize("sidebar_margin").width * 0.9) - - signal showTooltip(Item item, point location, string text) - signal hideTooltip() - - Item - { - id: initialSeparator - anchors - { - left: parent.left - right: parent.right - } - visible: printerTypeSelectionRow.visible || buildplateRow.visible || extruderSelectionRow.visible - height: UM.Theme.getSize("default_lining").height - width: height - } - - // Printer Type Row - Item - { - id: printerTypeSelectionRow - height: UM.Theme.getSize("sidebar_setup").height - visible: printerConnected && hasManyPrinterTypes && !sidebar.hideSettings - - anchors - { - left: parent.left - leftMargin: UM.Theme.getSize("sidebar_margin").width - right: parent.right - rightMargin: UM.Theme.getSize("sidebar_margin").width - } - - Label - { - id: configurationLabel - text: catalog.i18nc("@label", "Printer type"); - width: Math.round(parent.width * 0.4 - UM.Theme.getSize("default_margin").width) - height: parent.height - verticalAlignment: Text.AlignVCenter - font: UM.Theme.getFont("default"); - color: UM.Theme.getColor("text"); - } - - ToolButton - { - id: printerTypeSelection - text: Cura.MachineManager.activeMachineDefinitionName - tooltip: Cura.MachineManager.activeMachineDefinitionName - height: UM.Theme.getSize("setting_control").height - width: Math.round(parent.width * 0.7) + UM.Theme.getSize("sidebar_margin").width - anchors.right: parent.right - style: UM.Theme.styles.sidebar_header_button - activeFocusOnPress: true; - - menu: PrinterTypeMenu { } - } - } - - Rectangle - { - id: headerSeparator - width: parent.width - visible: printerTypeSelectionRow.visible - height: visible ? UM.Theme.getSize("sidebar_lining").height : 0 - color: UM.Theme.getColor("sidebar_lining") - } - - // Extruder Row - Item - { - id: extruderSelectionRow - width: parent.width - height: Math.round(UM.Theme.getSize("sidebar_tabs").height * 2 / 3) - visible: machineExtruderCount.properties.value > 1 - - anchors - { - left: parent.left - leftMargin: Math.round(UM.Theme.getSize("sidebar_margin").width * 0.7) - right: parent.right - rightMargin: Math.round(UM.Theme.getSize("sidebar_margin").width * 0.7) - topMargin: UM.Theme.getSize("sidebar_margin").height - } - - ListView - { - id: extrudersList - property var index: 0 - - height: UM.Theme.getSize("sidebar_header_mode_tabs").height - width: Math.round(parent.width) - boundsBehavior: Flickable.StopAtBounds - - anchors - { - left: parent.left - leftMargin: Math.round(UM.Theme.getSize("default_margin").width / 2) - right: parent.right - rightMargin: Math.round(UM.Theme.getSize("default_margin").width / 2) - verticalCenter: parent.verticalCenter - } - - ExclusiveGroup { id: extruderMenuGroup; } - - orientation: ListView.Horizontal - - model: Cura.ExtrudersModel { id: extrudersModel; } - - Connections - { - target: Cura.MachineManager - onGlobalContainerChanged: forceActiveFocus() // Changing focus applies the currently-being-typed values so it can change the displayed setting values. - } - - delegate: Button - { - height: ListView.view.height - width: Math.round(ListView.view.width / extrudersModel.rowCount()) - - text: model.name - tooltip: model.name - exclusiveGroup: extruderMenuGroup - checked: base.currentExtruderIndex == index - - property bool extruder_enabled: true - - MouseArea - { - anchors.fill: parent - acceptedButtons: Qt.LeftButton | Qt.RightButton - onClicked: { - switch (mouse.button) { - case Qt.LeftButton: - extruder_enabled = Cura.MachineManager.getExtruder(model.index).isEnabled - if (extruder_enabled) - { - forceActiveFocus(); // Changing focus applies the currently-being-typed values so it can change the displayed setting values. - Cura.ExtruderManager.setActiveExtruderIndex(index); - } - break; - case Qt.RightButton: - extruder_enabled = Cura.MachineManager.getExtruder(model.index).isEnabled - extruderMenu.popup(); - break; - } - - } - } - - Menu - { - id: extruderMenu - - MenuItem { - text: catalog.i18nc("@action:inmenu", "Enable Extruder") - onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, true) - visible: !extruder_enabled // using an intermediate variable prevents an empty popup that occured now and then - } - - MenuItem { - text: catalog.i18nc("@action:inmenu", "Disable Extruder") - onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, false) - visible: extruder_enabled - enabled: Cura.MachineManager.numberExtrudersEnabled > 1 - } - } - - style: ButtonStyle - { - background: Item - { - function buttonBackgroundColor(index) - { - var extruder = Cura.MachineManager.getExtruder(index) - if (extruder.isEnabled) { - return (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active") : - control.hovered ? UM.Theme.getColor("action_button_hovered") : - UM.Theme.getColor("action_button") - } else { - return UM.Theme.getColor("action_button_disabled") - } - } - - function buttonBorderColor(index) - { - var extruder = Cura.MachineManager.getExtruder(index) - if (extruder.isEnabled) { - return (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active_border") : - control.hovered ? UM.Theme.getColor("action_button_hovered_border") : - UM.Theme.getColor("action_button_border") - } else { - return UM.Theme.getColor("action_button_disabled_border") - } - } - - function buttonColor(index) { - var extruder = Cura.MachineManager.getExtruder(index); - if (extruder.isEnabled) - { - return ( - control.checked || control.pressed) ? UM.Theme.getColor("action_button_active_text") : - control.hovered ? UM.Theme.getColor("action_button_hovered_text") : - UM.Theme.getColor("action_button_text"); - } else { - return UM.Theme.getColor("action_button_disabled_text"); - } - } - - Rectangle - { - anchors.fill: parent - border.width: control.checked ? UM.Theme.getSize("default_lining").width * 2 : UM.Theme.getSize("default_lining").width - border.color: buttonBorderColor(index) - color: buttonBackgroundColor(index) - Behavior on color { ColorAnimation { duration: 50; } } - } - - Item - { - id: extruderButtonFace - anchors.centerIn: parent - - width: { - var extruderTextWidth = extruderStaticText.visible ? extruderStaticText.width : 0; - var iconWidth = extruderIconItem.width; - return Math.round(extruderTextWidth + iconWidth + UM.Theme.getSize("default_margin").width / 2); - } - - // Static text "Extruder" - Label - { - id: extruderStaticText - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - - color: buttonColor(index) - - font: UM.Theme.getFont("large_nonbold") - text: catalog.i18nc("@label", "Extruder") - visible: width < (control.width - extruderIconItem.width - UM.Theme.getSize("default_margin").width) - elide: Text.ElideRight - } - - // Everything for the extruder icon - Item - { - id: extruderIconItem - anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - - property var sizeToUse: - { - var minimumWidth = control.width < UM.Theme.getSize("button").width ? control.width : UM.Theme.getSize("button").width; - var minimumHeight = control.height < UM.Theme.getSize("button").height ? control.height : UM.Theme.getSize("button").height; - var minimumSize = minimumWidth < minimumHeight ? minimumWidth : minimumHeight; - minimumSize -= Math.round(UM.Theme.getSize("default_margin").width / 2); - return minimumSize; - } - - width: sizeToUse - height: sizeToUse - - UM.RecolorImage { - id: mainCircle - anchors.fill: parent - - sourceSize.width: parent.width - sourceSize.height: parent.width - source: UM.Theme.getIcon("extruder_button") - - color: extruderNumberText.color - } - - Label - { - id: extruderNumberText - anchors.centerIn: parent - text: index + 1; - color: buttonColor(index) - font: UM.Theme.getFont("default_bold") - } - - // Material colour circle - // Only draw the filling colour of the material inside the SVG border. - Rectangle - { - id: materialColorCircle - - anchors - { - right: parent.right - top: parent.top - rightMargin: Math.round(parent.sizeToUse * 0.01) - topMargin: Math.round(parent.sizeToUse * 0.05) - } - - color: model.color - - width: Math.round(parent.width * 0.35) - height: Math.round(parent.height * 0.35) - radius: Math.round(width / 2) - - border.width: 1 - border.color: UM.Theme.getColor("extruder_button_material_border") - - opacity: !control.checked ? 0.6 : 1.0 - } - } - } - } - label: Item {} - } - } - } - } - - Item - { - id: variantRowSpacer - height: Math.round(UM.Theme.getSize("sidebar_margin").height / 4) - width: height - visible: !extruderSelectionRow.visible && !initialSeparator.visible - } - - // Material Row - Item - { - id: materialRow - height: UM.Theme.getSize("sidebar_setup").height - visible: Cura.MachineManager.hasMaterials && !sidebar.hideSettings - - anchors - { - left: parent.left - leftMargin: UM.Theme.getSize("sidebar_margin").width - right: parent.right - rightMargin: UM.Theme.getSize("sidebar_margin").width - } - - Label - { - id: materialLabel - text: catalog.i18nc("@label", "Material"); - width: Math.round(parent.width * 0.45 - UM.Theme.getSize("default_margin").width) - height: parent.height - verticalAlignment: Text.AlignVCenter - font: UM.Theme.getFont("default"); - color: UM.Theme.getColor("text"); - } - - ToolButton - { - id: materialSelection - - property var activeExtruder: Cura.MachineManager.activeStack - property var hasActiveExtruder: activeExtruder != null - property var currentRootMaterialName: hasActiveExtruder ? activeExtruder.material.name : "" - - text: currentRootMaterialName - tooltip: currentRootMaterialName - visible: Cura.MachineManager.hasMaterials - enabled: !extrudersList.visible || base.currentExtruderIndex > -1 - height: UM.Theme.getSize("setting_control").height - width: Math.round(parent.width * 0.7) + UM.Theme.getSize("sidebar_margin").width - anchors.right: parent.right - style: UM.Theme.styles.sidebar_header_button - activeFocusOnPress: true; - menu: MaterialMenu - { - extruderIndex: base.currentExtruderIndex - } - - property var valueError: !isMaterialSupported() - property var valueWarning: ! Cura.MachineManager.isActiveQualitySupported - - function isMaterialSupported () - { - if (!hasActiveExtruder) - { - return false; - } - return Cura.ContainerManager.getContainerMetaDataEntry(activeExtruder.material.id, "compatible", "") == "True" - } - } - } - - //Variant row - Item - { - id: variantRow - height: UM.Theme.getSize("sidebar_setup").height - visible: Cura.MachineManager.hasVariants && !sidebar.hideSettings - - anchors - { - left: parent.left - leftMargin: UM.Theme.getSize("sidebar_margin").width - right: parent.right - rightMargin: UM.Theme.getSize("sidebar_margin").width - } - - Label - { - id: variantLabel - text: Cura.MachineManager.activeDefinitionVariantsName; - width: Math.round(parent.width * 0.45 - UM.Theme.getSize("default_margin").width) - height: parent.height - verticalAlignment: Text.AlignVCenter - font: UM.Theme.getFont("default"); - color: UM.Theme.getColor("text"); - } - - ToolButton - { - id: variantSelection - text: Cura.MachineManager.activeVariantName - tooltip: Cura.MachineManager.activeVariantName; - visible: Cura.MachineManager.hasVariants - - height: UM.Theme.getSize("setting_control").height - width: Math.round(parent.width * 0.7 + UM.Theme.getSize("sidebar_margin").width) - anchors.right: parent.right - style: UM.Theme.styles.sidebar_header_button - activeFocusOnPress: true; - - menu: NozzleMenu { extruderIndex: base.currentExtruderIndex } - } - } - - Rectangle - { - id: buildplateSeparator - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width - width: parent.width - 2 * UM.Theme.getSize("sidebar_margin").width - visible: buildplateRow.visible - height: visible ? UM.Theme.getSize("sidebar_lining_thin").height : 0 - color: UM.Theme.getColor("sidebar_lining") - } - - //Buildplate row - Item - { - id: buildplateRow - height: UM.Theme.getSize("sidebar_setup").height - // TODO Only show in dev mode. Remove check when feature ready - visible: CuraSDKVersion == "dev" ? Cura.MachineManager.hasVariantBuildplates && !sidebar.hideSettings : false - - anchors - { - left: parent.left - leftMargin: UM.Theme.getSize("sidebar_margin").width - right: parent.right - rightMargin: UM.Theme.getSize("sidebar_margin").width - } - - Label - { - id: bulidplateLabel - text: catalog.i18nc("@label", "Build plate"); - width: Math.floor(parent.width * 0.45 - UM.Theme.getSize("default_margin").width) - height: parent.height - verticalAlignment: Text.AlignVCenter - font: UM.Theme.getFont("default"); - color: UM.Theme.getColor("text"); - } - - ToolButton - { - id: buildplateSelection - text: Cura.MachineManager.activeVariantBuildplateName - tooltip: Cura.MachineManager.activeVariantBuildplateName - visible: Cura.MachineManager.hasVariantBuildplates - - height: UM.Theme.getSize("setting_control").height - width: Math.floor(parent.width * 0.7 + UM.Theme.getSize("sidebar_margin").width) - anchors.right: parent.right - style: UM.Theme.styles.sidebar_header_button - activeFocusOnPress: true; - - menu: BuildplateMenu {} - - property var valueError: !Cura.MachineManager.variantBuildplateCompatible && !Cura.MachineManager.variantBuildplateUsable - property var valueWarning: Cura.MachineManager.variantBuildplateUsable - } - } - - // Material info row - Item - { - id: materialInfoRow - height: Math.round(UM.Theme.getSize("sidebar_setup").height / 2) - visible: (Cura.MachineManager.hasVariants || Cura.MachineManager.hasMaterials || Cura.MachineManager.hasVariantBuildplates) && !sidebar.hideSettings - - anchors - { - left: parent.left - leftMargin: UM.Theme.getSize("sidebar_margin").width - right: parent.right - rightMargin: UM.Theme.getSize("sidebar_margin").width - } - - // TODO This was added to replace the buildplate selector. Remove this component when the feature is ready - Label - { - id: materialCompatibilityLabel - y: -Math.round(UM.Theme.getSize("sidebar_margin").height / 3) - anchors.left: parent.left - width: parent.width - materialCompatibilityLink.width - text: catalog.i18nc("@label", "Use glue with this material combination") - font: UM.Theme.getFont("very_small") - color: UM.Theme.getColor("text") - visible: CuraSDKVersion == "dev" ? false : buildplateCompatibilityError || buildplateCompatibilityWarning - wrapMode: Text.WordWrap - opacity: 0.5 - } - - Item - { - id: materialCompatibilityLink - height: UM.Theme.getSize("sidebar_setup").height - anchors.right: parent.right - width: childrenRect.width + UM.Theme.getSize("default_margin").width - - UM.RecolorImage { - id: warningImage - anchors.right: materialInfoLabel.left - anchors.rightMargin: UM.Theme.getSize("default_margin").width - anchors.verticalCenter: parent.Bottom - source: UM.Theme.getIcon("warning") - width: UM.Theme.getSize("section_icon").width - height: UM.Theme.getSize("section_icon").height - sourceSize.width: width - sourceSize.height: height - color: UM.Theme.getColor("material_compatibility_warning") - visible: !Cura.MachineManager.isCurrentSetupSupported || buildplateCompatibilityError || buildplateCompatibilityWarning - } - - Label { - id: materialInfoLabel - wrapMode: Text.WordWrap - text: "" + catalog.i18nc("@label", "Check compatibility") + "" - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - linkColor: UM.Theme.getColor("text_link") - verticalAlignment: Text.AlignTop - anchors.top: parent.top - anchors.right: parent.right - anchors.bottom: parent.bottom - - MouseArea { - anchors.fill: parent - hoverEnabled: true - onClicked: { - // open the material URL with web browser - var url = "https://ultimaker.com/incoming-links/cura/material-compatibilty" - Qt.openUrlExternally(url); - } - onEntered: { - var content = catalog.i18nc("@tooltip", "Click to check the material compatibility on Ultimaker.com."); - base.showTooltip( - materialInfoRow, - Qt.point(-UM.Theme.getSize("sidebar_margin").width, 0), - catalog.i18nc("@tooltip", content) - ); - } - onExited: base.hideTooltip(); - } - } - } - } - - UM.SettingPropertyProvider - { - id: machineExtruderCount - - containerStack: Cura.MachineManager.activeMachine - key: "machine_extruder_count" - watchedProperties: [ "value" ] - storeIndex: 0 - } - - UM.I18nCatalog { id: catalog; name:"cura" } -} From 1e3a9ff57cabc85ef2cea5c0346d620e57f48493 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 15 Oct 2018 14:23:42 +0200 Subject: [PATCH 0032/1292] Removed the expandSidebar action Since we don't even have a sidebar anymore, there is no point in expanding it. --- resources/qml/Actions.qml | 9 --------- resources/qml/Menus/ViewMenu.qml | 6 ++---- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/resources/qml/Actions.qml b/resources/qml/Actions.qml index 1b1881ab76..30295f6e9b 100644 --- a/resources/qml/Actions.qml +++ b/resources/qml/Actions.qml @@ -23,8 +23,6 @@ Item property alias viewLeftSideCamera: viewLeftSideCameraAction; property alias viewRightSideCamera: viewRightSideCameraAction; - property alias expandSidebar: expandSidebarAction; - property alias deleteSelection: deleteSelectionAction; property alias centerSelection: centerSelectionAction; property alias multiplySelection: multiplySelectionAction; @@ -415,11 +413,4 @@ Item text: catalog.i18nc("@action:menu", "Browse packages...") iconName: "plugins_browse" } - - Action - { - id: expandSidebarAction; - text: catalog.i18nc("@action:inmenu menubar:view","Expand/Collapse Sidebar"); - shortcut: "Ctrl+E"; - } } diff --git a/resources/qml/Menus/ViewMenu.qml b/resources/qml/Menus/ViewMenu.qml index 9a2e603673..593bd63bcc 100644 --- a/resources/qml/Menus/ViewMenu.qml +++ b/resources/qml/Menus/ViewMenu.qml @@ -44,7 +44,8 @@ Menu MenuItem { action: Cura.Actions.viewRightSideCamera; } } - MenuSeparator { + MenuSeparator + { visible: UM.Preferences.getValue("cura/use_multi_build_plate") } @@ -72,8 +73,5 @@ Menu MenuSeparator {} - MenuItem { action: Cura.Actions.expandSidebar; } - - MenuSeparator {} MenuItem { action: Cura.Actions.toggleFullScreen; } } From a473a46a35c360605226c0cf71f7efed51ced0fc Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 15 Oct 2018 15:07:46 +0200 Subject: [PATCH 0033/1292] Add a bit more documentation to explain what the elements do CURA-5772 --- resources/qml/Cura.qml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index bf71bd8d94..df5995de39 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -114,6 +114,7 @@ UM.MainWindow DropArea { + // The drop area is here to handle files being dropped onto Cura. anchors.fill: parent onDropped: { @@ -181,6 +182,8 @@ UM.MainWindow Toolbar { + // The toolbar is the left bar that is populated by all the tools (which are dynamicly populated by + // plugins) id: toolbar property int mouseX: base.mouseX @@ -206,6 +209,7 @@ UM.MainWindow Loader { + // A stage can control this area. If nothing is set, it will therefor show the 3D view. id: main anchors From a7edd893d796df3c9537ca58c4794f1aaac7b43e Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 15 Oct 2018 15:08:58 +0200 Subject: [PATCH 0034/1292] Change the order in which ViewOrientationControls and ProgressAndSaveWidget are drawn. This will ensure that if a stage sets a mainComponent that it won't have any other items drawn over it. CURA-5772 --- resources/qml/Cura.qml | 60 +++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index df5995de39..39443f9b0b 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -207,6 +207,36 @@ UM.MainWindow } } + ViewOrientationControls + { + id: viewOrientationControls + + anchors + { + left: parent.left + margins: UM.Theme.getSize("default_margin").width + + bottom: parent.bottom + } + } + + ProgressAndSaveWidget + { + anchors.right: parent.right + anchors.bottom: parent.bottom + width: UM.Theme.getSize("sidebar").width + anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width + anchors.bottomMargin: UM.Theme.getSize("sidebar_margin").height + onShowTooltip: + { + base.showTooltip(item, location, text) + } + onHideTooltip: + { + base.hideTooltip() + } + } + Loader { // A stage can control this area. If nothing is set, it will therefor show the 3D view. @@ -242,36 +272,6 @@ UM.MainWindow bottomMargin: UM.Theme.getSize("default_margin").height } } - - ViewOrientationControls - { - id: viewOrientationControls - - anchors - { - left: parent.left - margins: UM.Theme.getSize("default_margin").width - - bottom: parent.bottom - } - } - - ProgressAndSaveWidget - { - anchors.right: parent.right - anchors.bottom: parent.bottom - width: UM.Theme.getSize("sidebar").width - anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width - anchors.bottomMargin: UM.Theme.getSize("sidebar_margin").height - onShowTooltip: - { - base.showTooltip(item, location, text) - } - onHideTooltip: - { - base.hideTooltip() - } - } } SidebarTooltip From 1c70a62df67918acb63ff233daa650c506f2ec7c Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 15 Oct 2018 15:10:50 +0200 Subject: [PATCH 0035/1292] Fix typo Derp. CURA-5772 --- resources/qml/Cura.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 39443f9b0b..517affe1b1 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -166,7 +166,7 @@ UM.MainWindow { target: stageMenu.item onShowTooltip: base.showTooltip(item, location, text) - onHideTooltop: base.hideTooltip() + onHideTooltip: base.hideTooltip() } JobSpecs From cd5a0a84a80ae0de2ed518cc18e3e19a67c88f79 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 15 Oct 2018 15:14:05 +0200 Subject: [PATCH 0036/1292] Horizontally align the prepare menu bar CURA-5772 --- plugins/PrepareStage/PrepareMenu.qml | 51 +++++++++++++++------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index 353c4df51a..ea247bf258 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -6,10 +6,9 @@ import UM 1.3 as UM import Cura 1.1 as Cura -Row +Item { - spacing: UM.Theme.getSize("default_margin").width - + id: prepareMenu // This widget doesn't show tooltips by itself. Instead it emits signals so others can do something with it. signal showTooltip(Item item, point location, string text) signal hideTooltip() @@ -20,29 +19,35 @@ Row name:"cura" } - Button + Row { - id: openFileButton - text: catalog.i18nc("@action:button", "Open File") - iconSource: UM.Theme.getIcon("load") - style: UM.Theme.styles.tool_button - tooltip: "" - action: Cura.Actions.open - } + spacing: UM.Theme.getSize("default_margin").width + anchors.horizontalCenter: parent.horizontalCenter - Cura.MachineAndConfigurationSelector - { - } + Button + { + id: openFileButton + text: catalog.i18nc("@action:button", "Open File") + iconSource: UM.Theme.getIcon("load") + style: UM.Theme.styles.tool_button + tooltip: "" + action: Cura.Actions.open + } - Cura.MaterialAndVariantSelector - { - width: UM.Theme.getSize("sidebar").width - } + Cura.MachineAndConfigurationSelector + { + } - Cura.ProfileAndSettingComponent - { - width: UM.Theme.getSize("sidebar").width - onShowTooltip: parent.showTooltip(item, location, text) - onHideTooltip: parent.hideTooltip() + Cura.MaterialAndVariantSelector + { + width: UM.Theme.getSize("sidebar").width + } + + Cura.ProfileAndSettingComponent + { + width: UM.Theme.getSize("sidebar").width + onShowTooltip: prepareMenu.showTooltip(item, location, text) + onHideTooltip: prepareMenu.hideTooltip() + } } } \ No newline at end of file From 2455961ac7c63dba6fa5970506fd0b3e79310c91 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 15 Oct 2018 15:16:28 +0200 Subject: [PATCH 0037/1292] Vertically allign the toolbar CURA-5772 --- 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 517affe1b1..bb94435c69 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -189,9 +189,9 @@ UM.MainWindow property int mouseX: base.mouseX property int mouseY: base.mouseY - anchors { - top: stageMenu.bottom - topMargin: UM.Theme.getSize("window_margin").height + anchors + { + verticalCenter: parent.verticalCenter left: parent.left } } From 553e29b9b801d8c6679382f2fe29b4a17a4da72d Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 15 Oct 2018 15:32:50 +0200 Subject: [PATCH 0038/1292] Fix QML warnings CURA-5772 --- resources/qml/Cura.qml | 6 +++--- resources/qml/MaterialAndVariantSelector.qml | 5 ++++- resources/qml/ProgressAndSaveWidget.qml | 2 +- resources/qml/Skeleton/TopHeader.qml | 1 - 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index bb94435c69..a3746a557b 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -159,7 +159,7 @@ UM.MainWindow } height: 50 - source: UM.Controller.activeStage.stageMenuComponent + source: UM.Controller.activeStage != null ? UM.Controller.activeStage.stageMenuComponent : "" } Connections @@ -252,13 +252,13 @@ UM.MainWindow MouseArea { - visible: UM.Controller.activeStage.mainComponent != "" + visible: parent.source != "" anchors.fill: parent acceptedButtons: Qt.AllButtons onWheel: wheel.accepted = true } - source: UM.Controller.activeStage.mainComponent + source: UM.Controller.activeStage != null ? UM.Controller.activeStage.mainComponent : "" } UM.MessageStack diff --git a/resources/qml/MaterialAndVariantSelector.qml b/resources/qml/MaterialAndVariantSelector.qml index fff3ef1100..31a898f8ae 100644 --- a/resources/qml/MaterialAndVariantSelector.qml +++ b/resources/qml/MaterialAndVariantSelector.qml @@ -174,15 +174,18 @@ Rectangle font: UM.Theme.getFont("large_nonbold") text: catalog.i18nc("@label", "Extruder") - visible: width < (control.width - extruderIconItem.width - UM.Theme.getSize("default_margin").width) + visible: width < (control.width - extruderIcon.width - UM.Theme.getSize("default_margin").width) elide: Text.ElideRight } ExtruderIcon { // Round icon with the extruder number and material color indicator. + id: extruderIcon + anchors.verticalCenter: parent.verticalCenter anchors.left: extruderStaticText.right + anchors.leftMargin: UM.Theme.getSize("default_margin").width width: control.height - Math.round(UM.Theme.getSize("default_margin").width / 2) height: width diff --git a/resources/qml/ProgressAndSaveWidget.qml b/resources/qml/ProgressAndSaveWidget.qml index 2fa5cf6149..1e82681164 100644 --- a/resources/qml/ProgressAndSaveWidget.qml +++ b/resources/qml/ProgressAndSaveWidget.qml @@ -20,7 +20,7 @@ Rectangle signal hideTooltip() // Also add an extra margin, as we ant some breathing room around the edges. - height: childrenRect.height + UM.Theme.getSize("sidebar_margin").height + height: saveButton.height + UM.Theme.getSize("sidebar_margin").height Label { id: timeDetails diff --git a/resources/qml/Skeleton/TopHeader.qml b/resources/qml/Skeleton/TopHeader.qml index 7344d01436..867a6bafbb 100644 --- a/resources/qml/Skeleton/TopHeader.qml +++ b/resources/qml/Skeleton/TopHeader.qml @@ -93,7 +93,6 @@ Rectangle color: UM.Theme.getColor("topheader_button_text_active") font: UM.Theme.getFont("action_button") renderType: Text.NativeRendering - anchors.verticalCenter: control.verticalCenter } } From 304a9e11f3978dd4f2a30c649598583e0ddee5ee Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 17 Oct 2018 09:50:24 +0200 Subject: [PATCH 0039/1292] Moved view selection back into Cura QML It didn't make a whole lot of sense for it to be a seperate component, since it's probably going to change in the future CURA-5772 --- resources/qml/Cura.qml | 77 +++++++++++++++ resources/qml/Skeleton/ApplicationViews.qml | 101 -------------------- 2 files changed, 77 insertions(+), 101 deletions(-) delete mode 100644 resources/qml/Skeleton/ApplicationViews.qml diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index a3746a557b..a999e7deac 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -220,6 +220,83 @@ UM.MainWindow } } + ComboBox + { + // This item contains the views selector, a combobox that is dynamically created from + // the list of available Views (packages that create different visualizations of the + // scene). + id: viewModeButton + + anchors.left: viewOrientationControls.right + anchors.bottom: viewOrientationControls.bottom + + style: UM.Theme.styles.combobox + + model: UM.ViewModel { } + textRole: "name" + + // update the model's active index + function updateItemActiveFlags () + { + currentIndex = getActiveIndex() + for (var i = 0; i < model.rowCount(); i++) + { + model.getItem(i).active = (i == currentIndex) + } + } + + // get the index of the active model item on start + function getActiveIndex () + { + for (var i = 0; i < model.rowCount(); i++) + { + if (model.getItem(i).active) + { + return i; + } + } + return 0 + } + + // set the active index + function setActiveIndex(index) + { + UM.Controller.setActiveView(index) + // the connection to UM.ActiveView will trigger update so there is no reason to call it manually here + } + + onCurrentIndexChanged: + { + if (model.getItem(currentIndex).id != undefined) + { + viewModeButton.setActiveIndex(model.getItem(currentIndex).id) + } + } + currentIndex: getActiveIndex() + + // watch the active view proxy for changes made from the menu item + Connections + { + target: UM.ActiveView + onActiveViewChanged: viewModeButton.updateItemActiveFlags() + } + } + Loader + { + id: viewPanel + + anchors.bottom: viewModeButton.top + anchors.topMargin: UM.Theme.getSize("default_margin").height + anchors.right: viewModeButton.right + + property var buttonTarget: Qt.point(viewModeButton.x + Math.round(viewModeButton.width / 2), viewModeButton.y + Math.round(viewModeButton.height / 2)) + + height: childrenRect.height + width: childrenRect.width + + source: UM.ActiveView.valid ? UM.ActiveView.activeViewPanel : "" + } + ProgressAndSaveWidget { anchors.right: parent.right diff --git a/resources/qml/Skeleton/ApplicationViews.qml b/resources/qml/Skeleton/ApplicationViews.qml deleted file mode 100644 index d91837a2db..0000000000 --- a/resources/qml/Skeleton/ApplicationViews.qml +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.2 -import QtQuick.Controls 1.1 -import QtQuick.Controls.Styles 1.1 -import QtQuick.Layouts 1.1 - -import UM 1.4 as UM -import Cura 1.0 as Cura - - -// This item contains the views selector, a combobox that is dynamically created from -// the list of available Views (packages that create different visualizations of the -// scene). Aside from the selector, there is a row of buttons that change the orientation of the view. -Item -{ - id: applicationViewsSelector - - height: UM.Theme.getSize("views_selector").height - - - ComboBox - { - id: viewModeButton - - anchors - { - verticalCenter: parent.verticalCenter - right: parent.right - rightMargin: UM.Theme.getSize("default_margin").width - } - - style: UM.Theme.styles.combobox - - model: UM.ViewModel { } - textRole: "name" - - // update the model's active index - function updateItemActiveFlags () - { - currentIndex = getActiveIndex() - for (var i = 0; i < model.rowCount(); i++) - { - model.getItem(i).active = (i == currentIndex) - } - } - - // get the index of the active model item on start - function getActiveIndex () - { - for (var i = 0; i < model.rowCount(); i++) - { - if (model.getItem(i).active) - { - return i; - } - } - return 0 - } - - // set the active index - function setActiveIndex(index) - { - UM.Controller.setActiveView(index) - // the connection to UM.ActiveView will trigger update so there is no reason to call it manually here - } - - onCurrentIndexChanged: - { - if (model.getItem(currentIndex).id != undefined) - { - viewModeButton.setActiveIndex(model.getItem(currentIndex).id) - } - } - currentIndex: getActiveIndex() - - // watch the active view proxy for changes made from the menu item - Connections - { - target: UM.ActiveView - onActiveViewChanged: viewModeButton.updateItemActiveFlags() - } - } - - Loader - { - id: viewPanel - - anchors.top: viewModeButton.bottom - anchors.topMargin: UM.Theme.getSize("default_margin").height - anchors.right: viewModeButton.right - - property var buttonTarget: Qt.point(viewModeButton.x + Math.round(viewModeButton.width / 2), viewModeButton.y + Math.round(viewModeButton.height / 2)) - - height: childrenRect.height - width: childrenRect.width - - source: UM.ActiveView.valid ? UM.ActiveView.activeViewPanel : "" - } -} From 7fb72a1a58ad0d7522f53dbd00f57e44f829590c Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 17 Oct 2018 16:13:43 +0200 Subject: [PATCH 0040/1292] Change Skeleton folder name to MainWindow. This folder is intended to store the files that construct the main window. All the parts. The rest of the components are stored in more specific folders. Contributes to CURA-5784. --- resources/qml/Cura.qml | 2 +- resources/qml/{Skeleton => MainWindow}/ApplicationMenu.qml | 0 resources/qml/{Skeleton => MainWindow}/TopHeader.qml | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename resources/qml/{Skeleton => MainWindow}/ApplicationMenu.qml (100%) rename resources/qml/{Skeleton => MainWindow}/TopHeader.qml (100%) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index a999e7deac..a58e7ef6fc 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -12,7 +12,7 @@ import Cura 1.1 as Cura import "Dialogs" import "Menus" -import "Skeleton" +import "MainWindow" UM.MainWindow { diff --git a/resources/qml/Skeleton/ApplicationMenu.qml b/resources/qml/MainWindow/ApplicationMenu.qml similarity index 100% rename from resources/qml/Skeleton/ApplicationMenu.qml rename to resources/qml/MainWindow/ApplicationMenu.qml diff --git a/resources/qml/Skeleton/TopHeader.qml b/resources/qml/MainWindow/TopHeader.qml similarity index 100% rename from resources/qml/Skeleton/TopHeader.qml rename to resources/qml/MainWindow/TopHeader.qml From 54554bff8920ee3e9ab85df0302a4d9e0d030722 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 18 Oct 2018 09:51:04 +0200 Subject: [PATCH 0041/1292] Adjust colors to work with dark theme. Contributes to CURA-5784. --- resources/qml/Account/AccountDetails.qml | 3 + .../cura-dark/icons/tab_status_unknown.svg | 13 ---- resources/themes/cura-dark/images/logo.svg | 72 ------------------- resources/themes/cura-dark/theme.json | 2 +- 4 files changed, 4 insertions(+), 86 deletions(-) delete mode 100644 resources/themes/cura-dark/icons/tab_status_unknown.svg delete mode 100644 resources/themes/cura-dark/images/logo.svg diff --git a/resources/qml/Account/AccountDetails.qml b/resources/qml/Account/AccountDetails.qml index 4d6b0a314b..0ce82570a5 100644 --- a/resources/qml/Account/AccountDetails.qml +++ b/resources/qml/Account/AccountDetails.qml @@ -31,6 +31,7 @@ Column anchors.horizontalCenter: parent.horizontalCenter visible: !loggedIn text: catalog.i18nc("@label", "Please login or create an account to 
enjoy all features of Ultimaker Cura") + color: UM.Theme.getColor("text") } Column @@ -44,6 +45,7 @@ Column anchors.horizontalCenter: parent.horizontalCenter text: loggedIn ? profile["username"] : "" font: UM.Theme.getFont("large") + color: UM.Theme.getColor("text") } Label @@ -51,6 +53,7 @@ Column anchors.horizontalCenter: parent.horizontalCenter text: "email.address@hardcoded.is" font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") } } diff --git a/resources/themes/cura-dark/icons/tab_status_unknown.svg b/resources/themes/cura-dark/icons/tab_status_unknown.svg deleted file mode 100644 index d20218bc00..0000000000 --- a/resources/themes/cura-dark/icons/tab_status_unknown.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - Unknown - Created with Sketch. - - - - - - - - \ No newline at end of file diff --git a/resources/themes/cura-dark/images/logo.svg b/resources/themes/cura-dark/images/logo.svg deleted file mode 100644 index 92ffe4ca0c..0000000000 --- a/resources/themes/cura-dark/images/logo.svg +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - diff --git a/resources/themes/cura-dark/theme.json b/resources/themes/cura-dark/theme.json index fa0da2851e..99737ff8bf 100644 --- a/resources/themes/cura-dark/theme.json +++ b/resources/themes/cura-dark/theme.json @@ -17,7 +17,7 @@ "topheader_background": [31, 36, 39, 255], - "topheader_button_text_active": [255, 255, 255, 255], + "topheader_button_text_active": [31, 36, 39, 255], "topheader_button_text_inactive": [128, 128, 128, 255], "topheader_button_text_hovered": [255, 255, 255, 255], From 11693aad36a86ca56843f9bcf5bbbd787f8685b7 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 18 Oct 2018 09:51:42 +0200 Subject: [PATCH 0042/1292] Change the behaviour of the Popup, that now closes when clicking the widget if it is open. Contributes to CURA-5784. --- resources/qml/Account/AccountWidget.qml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/resources/qml/Account/AccountWidget.qml b/resources/qml/Account/AccountWidget.qml index 1b4e6de1b2..d1e285e1da 100644 --- a/resources/qml/Account/AccountWidget.qml +++ b/resources/qml/Account/AccountWidget.qml @@ -33,7 +33,7 @@ Button background: Item {} - onClicked: popup.open() + onClicked: popup.opened ? popup.close() : popup.open() Popup { @@ -42,6 +42,8 @@ Button y: parent.height + UM.Theme.getSize("default_arrow").height x: (parent.width - width) + closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent + contentItem: AccountDetails { id: panel From a4c609d514a7687b318613d862894c67dce83b1d Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 18 Oct 2018 14:28:00 +0200 Subject: [PATCH 0043/1292] Remove email label from the account widget. It's not needed and it's not currently public data that is published with the user token. Contributes to CURA-5784. --- cura/OAuth2/Models.py | 2 ++ resources/qml/Account/AccountDetails.qml | 28 +++--------------------- 2 files changed, 5 insertions(+), 25 deletions(-) diff --git a/cura/OAuth2/Models.py b/cura/OAuth2/Models.py index 83fc22554f..0515e789e6 100644 --- a/cura/OAuth2/Models.py +++ b/cura/OAuth2/Models.py @@ -1,4 +1,6 @@ # Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + from typing import Optional diff --git a/resources/qml/Account/AccountDetails.qml b/resources/qml/Account/AccountDetails.qml index 0ce82570a5..27860cfae5 100644 --- a/resources/qml/Account/AccountDetails.qml +++ b/resources/qml/Account/AccountDetails.qml @@ -27,36 +27,14 @@ Column Label { - id: message + id: information anchors.horizontalCenter: parent.horizontalCenter visible: !loggedIn - text: catalog.i18nc("@label", "Please login or create an account to 
enjoy all features of Ultimaker Cura") + text: loggedIn ? profile["username"] : catalog.i18nc("@label", "Please login or create an account to 
enjoy all features of Ultimaker Cura") + font: loggedIn ? UM.Theme.getFont("large") : UM.Theme.getFont("default") color: UM.Theme.getColor("text") } - Column - { - id: userInformation - anchors.horizontalCenter: parent.horizontalCenter - visible: loggedIn - - Label - { - anchors.horizontalCenter: parent.horizontalCenter - text: loggedIn ? profile["username"] : "" - font: UM.Theme.getFont("large") - color: UM.Theme.getColor("text") - } - - Label - { - anchors.horizontalCenter: parent.horizontalCenter - text: "email.address@hardcoded.is" - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - } - } - Loader { id: accountEntryPoints From 1bcd134f85c2f70df31f8e61706cec8636ed3790 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 18 Oct 2018 14:30:11 +0200 Subject: [PATCH 0044/1292] Fix code style Most stuff here was recently changed. Some of it was where I found a pattern in something that was likely copy-pasted from somewhere else, so I did a global search and replace on that. Contributes to issue CURA-5784. --- .../FirmwareUpdaterMachineAction.qml | 2 +- plugins/ImageReader/ConfigUI.qml | 2 +- plugins/ModelChecker/ModelChecker.qml | 2 +- .../PostProcessingPlugin.qml | 2 +- plugins/PrepareStage/PrepareMenu.qml | 2 +- plugins/Toolbox/resources/qml/Toolbox.qml | 2 +- .../resources/qml/DiscoverUM3Action.qml | 2 +- .../resources/qml/UM3InfoComponents.qml | 2 +- .../UMOCheckupMachineAction.qml | 2 +- plugins/UserAgreement/UserAgreement.qml | 2 +- resources/qml/Account/AccountWidget.qml | 2 +- resources/qml/Actions.qml | 4 +- resources/qml/Cura.qml | 6 +- resources/qml/Dialogs/AboutDialog.qml | 52 +-- resources/qml/JobSpecs.qml | 4 +- resources/qml/MainWindow/ApplicationMenu.qml | 9 +- resources/qml/MaterialAndVariantSelector.qml | 25 +- resources/qml/MonitorButton.qml | 2 +- resources/qml/MonitorSidebar.qml | 6 +- resources/qml/Preferences/GeneralPage.qml | 4 +- resources/qml/ProfileAndSettingComponent.qml | 8 +- resources/qml/ProgressAndSaveWidget.qml | 5 +- resources/qml/SaveButton.qml | 100 +++- resources/themes/cura-light/styles.qml | 429 +++++++++++------- 24 files changed, 433 insertions(+), 243 deletions(-) diff --git a/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.qml b/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.qml index 9a56dbb20a..b5b6c15f50 100644 --- a/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.qml +++ b/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.qml @@ -22,7 +22,7 @@ Cura.MachineAction { id: firmwareUpdaterMachineAction anchors.fill: parent; - UM.I18nCatalog { id: catalog; name:"cura"} + UM.I18nCatalog { id: catalog; name: "cura"} spacing: UM.Theme.getSize("default_margin").height Label diff --git a/plugins/ImageReader/ConfigUI.qml b/plugins/ImageReader/ConfigUI.qml index 12c6aa8dde..b9ff2e4453 100644 --- a/plugins/ImageReader/ConfigUI.qml +++ b/plugins/ImageReader/ConfigUI.qml @@ -20,7 +20,7 @@ UM.Dialog GridLayout { - UM.I18nCatalog{id: catalog; name:"cura"} + UM.I18nCatalog{id: catalog; name: "cura"} anchors.fill: parent; Layout.fillWidth: true columnSpacing: 16 * screenScaleFactor diff --git a/plugins/ModelChecker/ModelChecker.qml b/plugins/ModelChecker/ModelChecker.qml index 98db233bf8..5e41591d6b 100644 --- a/plugins/ModelChecker/ModelChecker.qml +++ b/plugins/ModelChecker/ModelChecker.qml @@ -16,7 +16,7 @@ Button { id: modelCheckerButton - UM.I18nCatalog{id: catalog; name:"cura"} + UM.I18nCatalog{id: catalog; name: "cura"} visible: manager.hasWarnings tooltip: catalog.i18nc("@info:tooltip", "Some things could be problematic in this print. Click to see tips for adjustment.") diff --git a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml index d492e06462..10cc4cc082 100644 --- a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml +++ b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml @@ -31,7 +31,7 @@ UM.Dialog Item { - UM.I18nCatalog{id: catalog; name:"cura"} + UM.I18nCatalog{id: catalog; name: "cura"} id: base property int columnWidth: Math.round((base.width / 2) - UM.Theme.getSize("default_margin").width) property int textMargin: Math.round(UM.Theme.getSize("default_margin").width / 2) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index ea247bf258..208e7d18df 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -16,7 +16,7 @@ Item UM.I18nCatalog { id: catalog - name:"cura" + name: "cura" } Row diff --git a/plugins/Toolbox/resources/qml/Toolbox.qml b/plugins/Toolbox/resources/qml/Toolbox.qml index 4fb8192d81..29b026058c 100644 --- a/plugins/Toolbox/resources/qml/Toolbox.qml +++ b/plugins/Toolbox/resources/qml/Toolbox.qml @@ -24,7 +24,7 @@ Window UM.I18nCatalog { id: catalog - name:"cura" + name: "cura" } Item { diff --git a/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml b/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml index b5b80a3010..773c38a454 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml @@ -54,7 +54,7 @@ Cura.MachineAction spacing: UM.Theme.getSize("default_margin").height SystemPalette { id: palette } - UM.I18nCatalog { id: catalog; name:"cura" } + UM.I18nCatalog { id: catalog; name: "cura" } Label { id: pageTitle diff --git a/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml b/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml index a19d1be60d..d84c58daef 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml @@ -121,5 +121,5 @@ Item } } - UM.I18nCatalog{id: catalog; name:"cura"} + UM.I18nCatalog{id: catalog; name: "cura"} } diff --git a/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml b/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml index 4a1d42e248..2a01cfaa40 100644 --- a/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml +++ b/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml @@ -19,7 +19,7 @@ Cura.MachineAction property bool heatupBedStarted: false property bool printerConnected: Cura.MachineManager.printerConnected - UM.I18nCatalog { id: catalog; name:"cura"} + UM.I18nCatalog { id: catalog; name: "cura"} Label { id: pageTitle diff --git a/plugins/UserAgreement/UserAgreement.qml b/plugins/UserAgreement/UserAgreement.qml index 4ee03f4ad5..2e5893fc41 100644 --- a/plugins/UserAgreement/UserAgreement.qml +++ b/plugins/UserAgreement/UserAgreement.qml @@ -36,7 +36,7 @@ UM.Dialog width: parent.width anchors.bottomMargin: UM.Theme.getSize("default_margin").height - UM.I18nCatalog { id: catalog; name:"cura" } + UM.I18nCatalog { id: catalog; name: "cura" } Button { diff --git a/resources/qml/Account/AccountWidget.qml b/resources/qml/Account/AccountWidget.qml index d1e285e1da..a6a79a7d29 100644 --- a/resources/qml/Account/AccountWidget.qml +++ b/resources/qml/Account/AccountWidget.qml @@ -40,7 +40,7 @@ Button id: popup y: parent.height + UM.Theme.getSize("default_arrow").height - x: (parent.width - width) + x: parent.width - width closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent diff --git a/resources/qml/Actions.qml b/resources/qml/Actions.qml index 30295f6e9b..a2b58063b4 100644 --- a/resources/qml/Actions.qml +++ b/resources/qml/Actions.qml @@ -1,4 +1,4 @@ -// Copyright (c) 2015 Ultimaker B.V. +// Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. pragma Singleton @@ -67,7 +67,7 @@ Item property alias browsePackages: browsePackagesAction - UM.I18nCatalog{id: catalog; name:"cura"} + UM.I18nCatalog{id: catalog; name: "cura"} Action { diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index a58e7ef6fc..2654eb3c20 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -26,7 +26,7 @@ UM.MainWindow UM.I18nCatalog { id: catalog - name:"cura" + name: "cura" } function showTooltip(item, position, text) @@ -236,7 +236,7 @@ UM.MainWindow textRole: "name" // update the model's active index - function updateItemActiveFlags () + function updateItemActiveFlags() { currentIndex = getActiveIndex() for (var i = 0; i < model.rowCount(); i++) @@ -316,7 +316,7 @@ UM.MainWindow Loader { - // A stage can control this area. If nothing is set, it will therefor show the 3D view. + // A stage can control this area. If nothing is set, it will therefore show the 3D view. id: main anchors diff --git a/resources/qml/Dialogs/AboutDialog.qml b/resources/qml/Dialogs/AboutDialog.qml index 9a7e53260b..25c9bbf74b 100644 --- a/resources/qml/Dialogs/AboutDialog.qml +++ b/resources/qml/Dialogs/AboutDialog.qml @@ -1,4 +1,4 @@ -// Copyright (c) 2015 Ultimaker B.V. +// Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 @@ -45,7 +45,7 @@ UM.Dialog anchors.topMargin: ((base.minimumWidth - width) / 2) | 0 anchors.horizontalCenter: parent.horizontalCenter - UM.I18nCatalog{id: catalog; name:"cura"} + UM.I18nCatalog{id: catalog; name: "cura"} } Label @@ -129,32 +129,32 @@ UM.Dialog } Component.onCompleted: { - projectsModel.append({ name:"Cura", description: catalog.i18nc("@label", "Graphical user interface"), license: "LGPLv3", url: "https://github.com/Ultimaker/Cura" }); - projectsModel.append({ name:"Uranium", description: catalog.i18nc("@label", "Application framework"), license: "LGPLv3", url: "https://github.com/Ultimaker/Uranium" }); - projectsModel.append({ name:"CuraEngine", description: catalog.i18nc("@label", "G-code generator"), license: "AGPLv3", url: "https://github.com/Ultimaker/CuraEngine" }); - projectsModel.append({ name:"libArcus", description: catalog.i18nc("@label", "Interprocess communication library"), license: "LGPLv3", url: "https://github.com/Ultimaker/libArcus" }); + projectsModel.append({ name: "Cura", description: catalog.i18nc("@label", "Graphical user interface"), license: "LGPLv3", url: "https://github.com/Ultimaker/Cura" }); + projectsModel.append({ name: "Uranium", description: catalog.i18nc("@label", "Application framework"), license: "LGPLv3", url: "https://github.com/Ultimaker/Uranium" }); + projectsModel.append({ name: "CuraEngine", description: catalog.i18nc("@label", "G-code generator"), license: "AGPLv3", url: "https://github.com/Ultimaker/CuraEngine" }); + projectsModel.append({ name: "libArcus", description: catalog.i18nc("@label", "Interprocess communication library"), license: "LGPLv3", url: "https://github.com/Ultimaker/libArcus" }); - projectsModel.append({ name:"Python", description: catalog.i18nc("@label", "Programming language"), license: "Python", url: "http://python.org/" }); - projectsModel.append({ name:"Qt5", description: catalog.i18nc("@label", "GUI framework"), license: "LGPLv3", url: "https://www.qt.io/" }); - projectsModel.append({ name:"PyQt", description: catalog.i18nc("@label", "GUI framework bindings"), license: "GPL", url: "https://riverbankcomputing.com/software/pyqt" }); - projectsModel.append({ name:"SIP", description: catalog.i18nc("@label", "C/C++ Binding library"), license: "GPL", url: "https://riverbankcomputing.com/software/sip" }); - projectsModel.append({ name:"Protobuf", description: catalog.i18nc("@label", "Data interchange format"), license: "BSD", url: "https://developers.google.com/protocol-buffers" }); - projectsModel.append({ name:"SciPy", description: catalog.i18nc("@label", "Support library for scientific computing"), license: "BSD-new", url: "https://www.scipy.org/" }); - projectsModel.append({ name:"NumPy", description: catalog.i18nc("@label", "Support library for faster math"), license: "BSD", url: "http://www.numpy.org/" }); - projectsModel.append({ name:"NumPy-STL", description: catalog.i18nc("@label", "Support library for handling STL files"), license: "BSD", url: "https://github.com/WoLpH/numpy-stl" }); - projectsModel.append({ name:"Shapely", description: catalog.i18nc("@label", "Support library for handling planar objects"), license: "BSD", url: "https://github.com/Toblerity/Shapely" }); - projectsModel.append({ name:"Trimesh", description: catalog.i18nc("@label", "Support library for handling triangular meshes"), license: "MIT", url: "https://trimsh.org" }); - projectsModel.append({ name:"NetworkX", description: catalog.i18nc("@label", "Support library for analysis of complex networks"), license: "3-clause BSD", url: "https://networkx.github.io/" }); - projectsModel.append({ name:"libSavitar", description: catalog.i18nc("@label", "Support library for handling 3MF files"), license: "LGPLv3", url: "https://github.com/ultimaker/libsavitar" }); - projectsModel.append({ name:"libCharon", description: catalog.i18nc("@label", "Support library for file metadata and streaming"), license: "LGPLv3", url: "https://github.com/ultimaker/libcharon" }); - projectsModel.append({ name:"PySerial", description: catalog.i18nc("@label", "Serial communication library"), license: "Python", url: "http://pyserial.sourceforge.net/" }); - projectsModel.append({ name:"python-zeroconf", description: catalog.i18nc("@label", "ZeroConf discovery library"), license: "LGPL", url: "https://github.com/jstasiak/python-zeroconf" }); - projectsModel.append({ name:"Clipper", description: catalog.i18nc("@label", "Polygon clipping library"), license: "Boost", url: "http://www.angusj.com/delphi/clipper.php" }); - projectsModel.append({ name:"Requests", description: catalog.i18nc("@Label", "Python HTTP library"), license: "GPL", url: "http://docs.python-requests.org" }); + projectsModel.append({ name: "Python", description: catalog.i18nc("@label", "Programming language"), license: "Python", url: "http://python.org/" }); + projectsModel.append({ name: "Qt5", description: catalog.i18nc("@label", "GUI framework"), license: "LGPLv3", url: "https://www.qt.io/" }); + projectsModel.append({ name: "PyQt", description: catalog.i18nc("@label", "GUI framework bindings"), license: "GPL", url: "https://riverbankcomputing.com/software/pyqt" }); + projectsModel.append({ name: "SIP", description: catalog.i18nc("@label", "C/C++ Binding library"), license: "GPL", url: "https://riverbankcomputing.com/software/sip" }); + projectsModel.append({ name: "Protobuf", description: catalog.i18nc("@label", "Data interchange format"), license: "BSD", url: "https://developers.google.com/protocol-buffers" }); + projectsModel.append({ name: "SciPy", description: catalog.i18nc("@label", "Support library for scientific computing"), license: "BSD-new", url: "https://www.scipy.org/" }); + projectsModel.append({ name: "NumPy", description: catalog.i18nc("@label", "Support library for faster math"), license: "BSD", url: "http://www.numpy.org/" }); + projectsModel.append({ name: "NumPy-STL", description: catalog.i18nc("@label", "Support library for handling STL files"), license: "BSD", url: "https://github.com/WoLpH/numpy-stl" }); + projectsModel.append({ name: "Shapely", description: catalog.i18nc("@label", "Support library for handling planar objects"), license: "BSD", url: "https://github.com/Toblerity/Shapely" }); + projectsModel.append({ name: "Trimesh", description: catalog.i18nc("@label", "Support library for handling triangular meshes"), license: "MIT", url: "https://trimsh.org" }); + projectsModel.append({ name: "NetworkX", description: catalog.i18nc("@label", "Support library for analysis of complex networks"), license: "3-clause BSD", url: "https://networkx.github.io/" }); + projectsModel.append({ name: "libSavitar", description: catalog.i18nc("@label", "Support library for handling 3MF files"), license: "LGPLv3", url: "https://github.com/ultimaker/libsavitar" }); + projectsModel.append({ name: "libCharon", description: catalog.i18nc("@label", "Support library for file metadata and streaming"), license: "LGPLv3", url: "https://github.com/ultimaker/libcharon" }); + projectsModel.append({ name: "PySerial", description: catalog.i18nc("@label", "Serial communication library"), license: "Python", url: "http://pyserial.sourceforge.net/" }); + projectsModel.append({ name: "python-zeroconf", description: catalog.i18nc("@label", "ZeroConf discovery library"), license: "LGPL", url: "https://github.com/jstasiak/python-zeroconf" }); + projectsModel.append({ name: "Clipper", description: catalog.i18nc("@label", "Polygon clipping library"), license: "Boost", url: "http://www.angusj.com/delphi/clipper.php" }); + projectsModel.append({ name: "Requests", description: catalog.i18nc("@Label", "Python HTTP library"), license: "GPL", url: "http://docs.python-requests.org" }); - projectsModel.append({ name:"Noto Sans", description: catalog.i18nc("@label", "Font"), license: "Apache 2.0", url: "https://www.google.com/get/noto/" }); - projectsModel.append({ name:"Font-Awesome-SVG-PNG", description: catalog.i18nc("@label", "SVG icons"), license: "SIL OFL 1.1", url: "https://github.com/encharm/Font-Awesome-SVG-PNG" }); - projectsModel.append({ name:"AppImageKit", description: catalog.i18nc("@label", "Linux cross-distribution application deployment"), license: "MIT", url: "https://github.com/AppImage/AppImageKit" }); + projectsModel.append({ name: "Noto Sans", description: catalog.i18nc("@label", "Font"), license: "Apache 2.0", url: "https://www.google.com/get/noto/" }); + projectsModel.append({ name: "Font-Awesome-SVG-PNG", description: catalog.i18nc("@label", "SVG icons"), license: "SIL OFL 1.1", url: "https://github.com/encharm/Font-Awesome-SVG-PNG" }); + projectsModel.append({ name: "AppImageKit", description: catalog.i18nc("@label", "Linux cross-distribution application deployment"), license: "MIT", url: "https://github.com/AppImage/AppImageKit" }); } } } diff --git a/resources/qml/JobSpecs.qml b/resources/qml/JobSpecs.qml index 1a5b604886..45111992c1 100644 --- a/resources/qml/JobSpecs.qml +++ b/resources/qml/JobSpecs.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.2 @@ -15,7 +15,7 @@ Item { property bool activity: CuraApplication.platformActivity property string fileBaseName: PrintInformation.baseName - UM.I18nCatalog { id: catalog; name:"cura"} + UM.I18nCatalog { id: catalog; name: "cura"} height: childrenRect.height diff --git a/resources/qml/MainWindow/ApplicationMenu.qml b/resources/qml/MainWindow/ApplicationMenu.qml index 00859e2a45..e538e966fc 100644 --- a/resources/qml/MainWindow/ApplicationMenu.qml +++ b/resources/qml/MainWindow/ApplicationMenu.qml @@ -128,7 +128,8 @@ Item Instantiator { model: Cura.ExtrudersModel { simpleNames: true } - Menu { + Menu + { title: model.name NozzleMenu { title: Cura.MachineManager.activeDefinitionVariantsName; visible: Cura.MachineManager.hasVariants; extruderIndex: index } @@ -267,7 +268,8 @@ Item } } - UM.ExtensionModel { + UM.ExtensionModel + { id: curaExtensions } @@ -291,7 +293,8 @@ Item Connections { target: Cura.Actions.browsePackages - onTriggered: { + onTriggered: + { curaExtensions.callExtensionMethod("Toolbox", "browsePackages") } } diff --git a/resources/qml/MaterialAndVariantSelector.qml b/resources/qml/MaterialAndVariantSelector.qml index 31a898f8ae..7dfc3737c0 100644 --- a/resources/qml/MaterialAndVariantSelector.qml +++ b/resources/qml/MaterialAndVariantSelector.qml @@ -21,7 +21,7 @@ Rectangle // Height has an extra 2x margin for the top & bottom margin. height: childrenRect.height + 2 * UM.Theme.getSize("default_margin").width - Cura.ExtrudersModel { id: extrudersModel; } + Cura.ExtrudersModel { id: extrudersModel } ListView { @@ -41,7 +41,7 @@ Rectangle margins: UM.Theme.getSize("sidebar_margin").width } - ExclusiveGroup { id: extruderMenuGroup; } + ExclusiveGroup { id: extruderMenuGroup } orientation: ListView.Horizontal @@ -69,8 +69,10 @@ Rectangle { anchors.fill: parent acceptedButtons: Qt.LeftButton | Qt.RightButton - onClicked: { - switch (mouse.button) { + onClicked: + { + switch (mouse.button) + { case Qt.LeftButton: extruder_enabled = Cura.MachineManager.getExtruder(model.index).isEnabled if (extruder_enabled) @@ -114,7 +116,8 @@ Rectangle { anchors.fill: parent border.width: control.checked ? UM.Theme.getSize("default_lining").width * 2 : UM.Theme.getSize("default_lining").width - border.color: { + border.color: + { if (Cura.MachineManager.getExtruder(index).isEnabled) { if(control.checked || control.pressed) @@ -128,13 +131,15 @@ Rectangle } return UM.Theme.getColor("action_button_disabled_border") } - color: { + color: + { if (Cura.MachineManager.getExtruder(index).isEnabled) { if(control.checked || control.pressed) { return UM.Theme.getColor("action_button_active"); - } else if (control.hovered) + } + else if (control.hovered) { return UM.Theme.getColor("action_button_hovered") } @@ -157,13 +162,15 @@ Rectangle anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left - color: { + color: + { if (Cura.MachineManager.getExtruder(index).isEnabled) { if(control.checked || control.pressed) { return UM.Theme.getColor("action_button_active_text"); - } else if (control.hovered) + } + else if (control.hovered) { return UM.Theme.getColor("action_button_hovered_text") } diff --git a/resources/qml/MonitorButton.qml b/resources/qml/MonitorButton.qml index aa40de11e4..efee50a2b3 100644 --- a/resources/qml/MonitorButton.qml +++ b/resources/qml/MonitorButton.qml @@ -13,7 +13,7 @@ import Cura 1.0 as Cura Item { id: base; - UM.I18nCatalog { id: catalog; name:"cura"} + UM.I18nCatalog { id: catalog; name: "cura"} height: childrenRect.height + UM.Theme.getSize("sidebar_margin").height diff --git a/resources/qml/MonitorSidebar.qml b/resources/qml/MonitorSidebar.qml index 80bd5c1a2e..179fcafb53 100644 --- a/resources/qml/MonitorSidebar.qml +++ b/resources/qml/MonitorSidebar.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.7 @@ -31,7 +31,7 @@ Rectangle property variant printMaterialNames: PrintInformation.materialNames color: UM.Theme.getColor("sidebar") - UM.I18nCatalog { id: catalog; name:"cura"} + UM.I18nCatalog { id: catalog; name: "cura"} Timer { id: tooltipDelayTimer @@ -70,7 +70,7 @@ Rectangle time -= minutes * 60 var seconds = Math.floor(time); - var finalTime = strPadLeft(hours, "0", 2) + ':' + strPadLeft(minutes,'0',2)+ ':' + strPadLeft(seconds,'0',2); + var finalTime = strPadLeft(hours, "0", 2) + ":" + strPadLeft(minutes, "0", 2) + ":" + strPadLeft(seconds, "0", 2); return finalTime; } diff --git a/resources/qml/Preferences/GeneralPage.qml b/resources/qml/Preferences/GeneralPage.qml index 64c1246929..0e8dd1b426 100644 --- a/resources/qml/Preferences/GeneralPage.qml +++ b/resources/qml/Preferences/GeneralPage.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.1 @@ -134,7 +134,7 @@ UM.PreferencesPage UM.PluginsModel { id: plugins } //: Language selection label - UM.I18nCatalog{id: catalog; name:"cura"} + UM.I18nCatalog{id: catalog; name: "cura"} Label { diff --git a/resources/qml/ProfileAndSettingComponent.qml b/resources/qml/ProfileAndSettingComponent.qml index b367c1130f..e5a29dffad 100644 --- a/resources/qml/ProfileAndSettingComponent.qml +++ b/resources/qml/ProfileAndSettingComponent.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.7 @@ -26,7 +26,7 @@ Rectangle property variant printMaterialNames: PrintInformation.materialNames color: UM.Theme.getColor("sidebar") - UM.I18nCatalog { id: catalog; name:"cura"} + UM.I18nCatalog { id: catalog; name: "cura"} // This widget doesn't show tooltips by itself. Instead it emits signals so others can do something with it. signal showTooltip(Item item, point location, string text) @@ -59,7 +59,7 @@ Rectangle time -= minutes * 60 var seconds = Math.floor(time); - var finalTime = strPadLeft(hours, "0", 2) + ':' + strPadLeft(minutes,'0',2)+ ':' + strPadLeft(seconds,'0',2); + var finalTime = strPadLeft(hours, "0", 2) + ":" + strPadLeft(minutes, "0", 2) + ":" + strPadLeft(seconds, "0", 2); return finalTime; } @@ -152,7 +152,7 @@ Rectangle background: Rectangle { border.width: control.checked ? UM.Theme.getSize("default_lining").width * 2 : UM.Theme.getSize("default_lining").width - border.color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active_border") : control.hovered ? UM.Theme.getColor("action_button_hovered_border"): UM.Theme.getColor("action_button_border") + border.color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active_border") : control.hovered ? UM.Theme.getColor("action_button_hovered_border") : UM.Theme.getColor("action_button_border") // for some reason, QtQuick decided to use the color of the background property as text color for the contentItem, so here it is color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active") : control.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") diff --git a/resources/qml/ProgressAndSaveWidget.qml b/resources/qml/ProgressAndSaveWidget.qml index 1e82681164..6e8eb59482 100644 --- a/resources/qml/ProgressAndSaveWidget.qml +++ b/resources/qml/ProgressAndSaveWidget.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.7 @@ -173,7 +173,8 @@ Rectangle var weights = []; var costs = []; var someCostsKnown = false; - if(base.printMaterialLengths) { + if(base.printMaterialLengths) + { for(var index = 0; index < base.printMaterialLengths.length; index++) { if(base.printMaterialLengths[index] > 0) diff --git a/resources/qml/SaveButton.qml b/resources/qml/SaveButton.qml index 8c561b0d00..5e41dd3007 100644 --- a/resources/qml/SaveButton.qml +++ b/resources/qml/SaveButton.qml @@ -13,7 +13,7 @@ import Cura 1.0 as Cura Item { id: base; - UM.I18nCatalog { id: catalog; name:"cura"} + UM.I18nCatalog { id: catalog; name: "cura"} property real progress: UM.Backend.progress property int backendState: UM.Backend.state @@ -36,7 +36,7 @@ Item case 2: return catalog.i18nc("@label:PrintjobStatus", "Slicing..."); case 3: - return catalog.i18nc("@label:PrintjobStatus %1 is target operation","Ready to %1").arg(UM.OutputDeviceManager.activeDeviceShortDescription); + return catalog.i18nc("@label:PrintjobStatus %1 is target operation", "Ready to %1").arg(UM.OutputDeviceManager.activeDeviceShortDescription); case 4: return catalog.i18nc("@label:PrintjobStatus", "Unable to Slice"); case 5: @@ -48,16 +48,20 @@ Item function sliceOrStopSlicing() { - try { + try + { if ([1, 5].indexOf(base.backendState) != -1) { CuraApplication.backend.forceSlice(); - } else { + } + else + { CuraApplication.backend.stopSlicing(); } - } catch (e) + } + catch (e) { - console.log('Could not start or stop slicing', e) + console.log("Could not start or stop slicing.", e) } } @@ -203,50 +207,76 @@ Item sliceOrStopSlicing(); } - style: ButtonStyle { + style: ButtonStyle + { background: Rectangle { border.width: UM.Theme.getSize("default_lining").width border.color: { if(!control.enabled) + { return UM.Theme.getColor("action_button_disabled_border"); + } else if(control.pressed) + { return UM.Theme.getColor("action_button_active_border"); + } else if(control.hovered) + { return UM.Theme.getColor("action_button_hovered_border"); + } else + { return UM.Theme.getColor("action_button_border"); + } } color: { if(!control.enabled) + { return UM.Theme.getColor("action_button_disabled"); + } else if(control.pressed) + { return UM.Theme.getColor("action_button_active"); + } else if(control.hovered) + { return UM.Theme.getColor("action_button_hovered"); + } else + { return UM.Theme.getColor("action_button"); + } } Behavior on color { ColorAnimation { duration: 50; } } implicitWidth: actualLabel.contentWidth + (UM.Theme.getSize("sidebar_margin").width * 2) - Label { + Label + { id: actualLabel anchors.centerIn: parent color: { if(!control.enabled) + { return UM.Theme.getColor("action_button_disabled_text"); + } else if(control.pressed) + { return UM.Theme.getColor("action_button_active_text"); + } else if(control.hovered) + { return UM.Theme.getColor("action_button_hovered_text"); + } else + { return UM.Theme.getColor("action_button_text"); + } } font: UM.Theme.getFont("action_button") text: control.text; @@ -287,43 +317,61 @@ Item border.color: { if(!control.enabled) + { return UM.Theme.getColor("action_button_disabled_border"); + } else if(control.pressed) + { return UM.Theme.getColor("print_button_ready_pressed_border"); + } else if(control.hovered) + { return UM.Theme.getColor("print_button_ready_hovered_border"); + } else + { return UM.Theme.getColor("print_button_ready_border"); + } } color: { if(!control.enabled) + { return UM.Theme.getColor("action_button_disabled"); + } else if(control.pressed) + { return UM.Theme.getColor("print_button_ready_pressed"); + } else if(control.hovered) + { return UM.Theme.getColor("print_button_ready_hovered"); + } else + { return UM.Theme.getColor("print_button_ready"); + } } Behavior on color { ColorAnimation { duration: 50; } } implicitWidth: actualLabel.contentWidth + (UM.Theme.getSize("sidebar_margin").width * 2) - Label { + Label + { id: actualLabel anchors.centerIn: parent - color:control.enabled ? UM.Theme.getColor("print_button_ready_text") : UM.Theme.getColor("action_button_disabled_text") + color: control.enabled ? UM.Theme.getColor("print_button_ready_text") : UM.Theme.getColor("action_button_disabled_text") font: UM.Theme.getFont("action_button") - text: control.text; + text: control.text } } label: Item { } } } - Button { + Button + { id: deviceSelectionMenu tooltip: catalog.i18nc("@info:tooltip","Select the active output device"); anchors.top: parent.top @@ -349,13 +397,16 @@ Item if(!control.enabled) { return UM.Theme.getColor("action_button_disabled_border") - } else if(control.pressed) + } + else if(control.pressed) { return UM.Theme.getColor("print_button_ready_pressed_border") - } else if(control.hovered) + } + else if(control.hovered) { return UM.Theme.getColor("print_button_ready_hovered_border") - } else + } + else { return UM.Theme.getColor("print_button_ready_border") } @@ -365,13 +416,16 @@ Item if(!control.enabled) { return UM.Theme.getColor("action_button_disabled") - } else if(control.pressed) + } + else if(control.pressed) { return UM.Theme.getColor("print_button_ready_pressed") - } else if(control.hovered) + } + else if(control.hovered) { return UM.Theme.getColor("print_button_ready_hovered") - } else + } + else { return UM.Theme.getColor("print_button_ready") } @@ -391,7 +445,7 @@ Item sourceSize.width: width sourceSize.height: height color: control.enabled ? UM.Theme.getColor("print_button_ready_text") : UM.Theme.getColor("action_button_disabled_text") - source: UM.Theme.getIcon("arrow_bottom"); + source: UM.Theme.getIcon("arrow_bottom") } } } @@ -406,8 +460,8 @@ Item { text: model.description checkable: true; - checked: model.id == UM.OutputDeviceManager.activeDevice; - exclusiveGroup: devicesMenuGroup; + checked: model.id == UM.OutputDeviceManager.activeDevice + exclusiveGroup: devicesMenuGroup onTriggered: { UM.OutputDeviceManager.setActiveDevice(model.id); @@ -416,9 +470,9 @@ Item onObjectAdded: devicesMenu.insertItem(index, object) onObjectRemoved: devicesMenu.removeItem(object) } - ExclusiveGroup { id: devicesMenuGroup; } + ExclusiveGroup { id: devicesMenuGroup } } } - UM.OutputDevicesModel { id: devicesModel; } + UM.OutputDevicesModel { id: devicesModel } } } diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index 939399efc8..58e6d2cf4d 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.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.1 @@ -7,10 +7,14 @@ import QtQuick.Controls.Styles 1.1 import UM 1.1 as UM -QtObject { - property Component sidebar_header_button: Component { - ButtonStyle { - background: Rectangle { +QtObject +{ + property Component sidebar_header_button: Component + { + ButtonStyle + { + background: Rectangle + { color: { if(control.enabled) @@ -61,7 +65,8 @@ QtObject { return Theme.getColor("setting_control_disabled_border"); } } - UM.RecolorImage { + UM.RecolorImage + { id: downArrow anchors.verticalCenter: parent.verticalCenter anchors.right: parent.right @@ -73,7 +78,8 @@ QtObject { color: control.enabled ? Theme.getColor("setting_category_text") : Theme.getColor("setting_category_disabled_text") source: Theme.getIcon("arrow_bottom") } - Label { + Label + { id: sidebarComboBoxLabel color: control.enabled ? Theme.getColor("setting_control_text") : Theme.getColor("setting_control_disabled_text") text: control.text; @@ -158,33 +164,37 @@ QtObject { { if (control.checked) { - return UM.Theme.getColor("topheader_button_text_active") + return UM.Theme.getColor("topheader_button_text_active"); } else { if (control.hovered) { - return UM.Theme.getColor("topheader_button_text_hovered") + return UM.Theme.getColor("topheader_button_text_hovered"); } - return UM.Theme.getColor("topheader_button_text_inactive") + return UM.Theme.getColor("topheader_button_text_inactive"); } } } Component.onCompleted: { - buttonWidth = width + buttonWidth = width; } } } } - property Component tool_button: Component { - ButtonStyle { - background: Item { + property Component tool_button: Component + { + ButtonStyle + { + background: Item + { implicitWidth: Theme.getSize("button").width; implicitHeight: Theme.getSize("button").height; - UM.PointingRectangle { + UM.PointingRectangle + { id: button_tooltip anchors.left: parent.right @@ -203,7 +213,8 @@ QtObject { Behavior on width { NumberAnimation { duration: 100; } } Behavior on opacity { NumberAnimation { duration: 100; } } - Label { + Label + { id: button_tip anchors.horizontalCenter: parent.horizontalCenter @@ -215,7 +226,8 @@ QtObject { } } - Rectangle { + Rectangle + { id: buttonFace; anchors.fill: parent; @@ -249,7 +261,8 @@ QtObject { border.width: (control.hasOwnProperty("needBorder") && control.needBorder) ? 2 * screenScaleFactor : 0 border.color: Theme.getColor("tool_button_border") - UM.RecolorImage { + UM.RecolorImage + { id: tool_button_arrow anchors.right: parent.right; anchors.rightMargin: Theme.getSize("button").width - Math.round(Theme.getSize("button_icon").width / 4) @@ -284,8 +297,10 @@ QtObject { } } - label: Item { - UM.RecolorImage { + label: Item + { + UM.RecolorImage + { anchors.centerIn: parent; opacity: !control.enabled ? 0.2 : 1.0 source: control.iconSource; @@ -317,13 +332,17 @@ QtObject { } } - property Component small_tool_button: Component { - ButtonStyle { - background: Item { + property Component small_tool_button: Component + { + ButtonStyle + { + background: Item + { implicitWidth: Theme.getSize("small_button").width; implicitHeight: Theme.getSize("small_button").height; - Rectangle { + Rectangle + { id: smallButtonFace; anchors.fill: parent; @@ -357,7 +376,8 @@ QtObject { border.width: (control.hasOwnProperty("needBorder") && control.needBorder) ? 2 * screenScaleFactor : 0 border.color: Theme.getColor("tool_button_border") - UM.RecolorImage { + UM.RecolorImage + { id: smallToolButtonArrow width: 5 @@ -389,13 +409,15 @@ QtObject { } } - label: Item { - UM.RecolorImage { - anchors.centerIn: parent; + label: Item + { + UM.RecolorImage + { + anchors.centerIn: parent opacity: !control.enabled ? 0.2 : 1.0 source: control.iconSource; - width: Theme.getSize("small_button_icon").width; - height: Theme.getSize("small_button_icon").height; + width: Theme.getSize("small_button_icon").width + height: Theme.getSize("small_button_icon").height color: { if(control.checkable && control.checked && control.hovered) @@ -422,14 +444,18 @@ QtObject { } } - property Component progressbar: Component{ - ProgressBarStyle { - background: Rectangle { + property Component progressbar: Component + { + ProgressBarStyle + { + background: Rectangle + { implicitWidth: Theme.getSize("message").width - (Theme.getSize("default_margin").width * 2) implicitHeight: Theme.getSize("progressbar").height color: control.hasOwnProperty("backgroundColor") ? control.backgroundColor : Theme.getColor("progressbar_background") } - progress: Rectangle { + progress: Rectangle + { color: { if(control.indeterminate) @@ -446,14 +472,16 @@ QtObject { } } radius: Theme.getSize("progressbar_radius").width - Rectangle{ + Rectangle + { radius: Theme.getSize("progressbar_radius").width color: control.hasOwnProperty("controlColor") ? control.controlColor : Theme.getColor("progressbar_control") width: Theme.getSize("progressbar_control").width height: Theme.getSize("progressbar_control").height visible: control.indeterminate - SequentialAnimation on x { + SequentialAnimation on x + { id: xAnim property int animEndPoint: Theme.getSize("message").width - Math.round((Theme.getSize("default_margin").width * 2.5)) - Theme.getSize("progressbar_control").width running: control.indeterminate && control.visible @@ -466,59 +494,88 @@ QtObject { } } - property Component sidebar_category: Component { - ButtonStyle { - background: Rectangle { - anchors.fill: parent; + property Component sidebar_category: Component + { + ButtonStyle + { + background: Rectangle + { + anchors.fill: parent anchors.left: parent.left anchors.leftMargin: Theme.getSize("sidebar_margin").width anchors.right: parent.right anchors.rightMargin: Theme.getSize("sidebar_margin").width - implicitHeight: Theme.getSize("section").height; - color: { - if(control.color) { + implicitHeight: Theme.getSize("section").height + color: + { + if(control.color) + { return control.color; - } else if(!control.enabled) { + } + else if(!control.enabled) + { return Theme.getColor("setting_category_disabled"); - } else if(control.hovered && control.checkable && control.checked) { + } + else if(control.hovered && control.checkable && control.checked) + { return Theme.getColor("setting_category_active_hover"); - } else if(control.pressed || (control.checkable && control.checked)) { + } + else if(control.pressed || (control.checkable && control.checked)) + { return Theme.getColor("setting_category_active"); - } else if(control.hovered) { + } + else if(control.hovered) + { return Theme.getColor("setting_category_hover"); - } else { + } + else + { return Theme.getColor("setting_category"); } } Behavior on color { ColorAnimation { duration: 50; } } - Rectangle { + Rectangle + { height: Theme.getSize("default_lining").height width: parent.width anchors.bottom: parent.bottom - color: { - if(!control.enabled) { + color: + { + if(!control.enabled) + { return Theme.getColor("setting_category_disabled_border"); - } else if((control.hovered || control.activeFocus) && control.checkable && control.checked) { + } + else if((control.hovered || control.activeFocus) && control.checkable && control.checked) + { return Theme.getColor("setting_category_active_hover_border"); - } else if(control.pressed || (control.checkable && control.checked)) { + } + else if(control.pressed || (control.checkable && control.checked)) + { return Theme.getColor("setting_category_active_border"); - } else if(control.hovered || control.activeFocus) { + } + else if(control.hovered || control.activeFocus) + { return Theme.getColor("setting_category_hover_border"); - } else { + } + else + { return Theme.getColor("setting_category_border"); } } } } - label: Item { - anchors.fill: parent; + label: Item + { + anchors.fill: parent anchors.left: parent.left - Item{ - id: icon; + Item + { + id: icon anchors.left: parent.left height: parent.height width: Theme.getSize("section_icon_column").width - UM.RecolorImage { + UM.RecolorImage + { anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left anchors.leftMargin: Theme.getSize("sidebar_margin").width @@ -553,15 +610,17 @@ QtObject { } } - Label { - anchors { - left: icon.right; - leftMargin: Theme.getSize("default_margin").width; - right: parent.right; - verticalCenter: parent.verticalCenter; + Label + { + anchors + { + left: icon.right + leftMargin: Theme.getSize("default_margin").width + right: parent.right + verticalCenter: parent.verticalCenter } - text: control.text; - font: Theme.getFont("setting_category"); + text: control.text + font: Theme.getFont("setting_category") color: { if(!control.enabled) @@ -585,10 +644,11 @@ QtObject { return Theme.getColor("setting_category_text"); } } - fontSizeMode: Text.HorizontalFit; + fontSizeMode: Text.HorizontalFit minimumPointSize: 8 } - UM.RecolorImage { + UM.RecolorImage + { id: category_arrow anchors.verticalCenter: parent.verticalCenter anchors.right: parent.right @@ -626,20 +686,24 @@ QtObject { } } - property Component scrollview: Component { - ScrollViewStyle { + property Component scrollview: Component + { + ScrollViewStyle + { decrementControl: Item { } incrementControl: Item { } transientScrollBars: false - scrollBarBackground: Rectangle { + scrollBarBackground: Rectangle + { implicitWidth: Theme.getSize("scrollbar").width radius: Math.round(implicitWidth / 2) color: Theme.getColor("scrollbar_background"); } - handle: Rectangle { + handle: Rectangle + { id: scrollViewHandle implicitWidth: Theme.getSize("scrollbar").width; radius: Math.round(implicitWidth / 2) @@ -650,10 +714,13 @@ QtObject { } } - property Component combobox: Component { - ComboBoxStyle { + property Component combobox: Component + { + ComboBoxStyle + { - background: Rectangle { + background: Rectangle + { implicitHeight: Theme.getSize("setting_control").height; implicitWidth: Theme.getSize("setting_control").width; @@ -664,28 +731,31 @@ QtObject { border.color: control.hovered ? Theme.getColor("setting_control_border_highlight") : Theme.getColor("setting_control_border"); } - label: Item { + label: Item + { - Label { - anchors.left: parent.left; + Label + { + anchors.left: parent.left anchors.leftMargin: Theme.getSize("default_lining").width - anchors.right: downArrow.left; - anchors.rightMargin: Theme.getSize("default_lining").width; - anchors.verticalCenter: parent.verticalCenter; + anchors.right: downArrow.left + anchors.rightMargin: Theme.getSize("default_lining").width + anchors.verticalCenter: parent.verticalCenter - text: control.currentText; + text: control.currentText font: Theme.getFont("default"); - color: !enabled ? Theme.getColor("setting_control_disabled_text") : Theme.getColor("setting_control_text"); + color: !enabled ? Theme.getColor("setting_control_disabled_text") : Theme.getColor("setting_control_text") - elide: Text.ElideRight; - verticalAlignment: Text.AlignVCenter; + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter } - UM.RecolorImage { + UM.RecolorImage + { id: downArrow - anchors.right: parent.right; - anchors.rightMargin: Theme.getSize("default_lining").width * 2; - anchors.verticalCenter: parent.verticalCenter; + anchors.right: parent.right + anchors.rightMargin: Theme.getSize("default_lining").width * 2 + anchors.verticalCenter: parent.verticalCenter source: Theme.getIcon("arrow_bottom") width: Theme.getSize("standard_arrow").width @@ -700,19 +770,24 @@ QtObject { } // Combobox with items with colored rectangles - property Component combobox_color: Component { + property Component combobox_color: Component + { - ComboBoxStyle { + ComboBoxStyle + { - background: Rectangle { + background: Rectangle + { color: !enabled ? UM.Theme.getColor("setting_control_disabled") : control._hovered ? UM.Theme.getColor("setting_control_highlight") : UM.Theme.getColor("setting_control") border.width: UM.Theme.getSize("default_lining").width border.color: !enabled ? UM.Theme.getColor("setting_control_disabled_border") : control._hovered ? UM.Theme.getColor("setting_control_border_highlight") : UM.Theme.getColor("setting_control_border") } - label: Item { + label: Item + { - Label { + Label + { anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("default_lining").width anchors.right: swatch.left @@ -727,7 +802,8 @@ QtObject { verticalAlignment: Text.AlignVCenter } - Rectangle { + Rectangle + { id: swatch height: Math.round(UM.Theme.getSize("setting_control").height / 2) width: height @@ -740,7 +816,8 @@ QtObject { color: (control.color_override !== "") ? control.color_override : control.color } - UM.RecolorImage { + UM.RecolorImage + { id: downArrow anchors.right: parent.right anchors.rightMargin: UM.Theme.getSize("default_lining").width * 2 @@ -758,22 +835,26 @@ QtObject { } } - property Component checkbox: Component { - CheckBoxStyle { + property Component checkbox: Component + { + CheckBoxStyle + { background: Item { } - indicator: Rectangle { - implicitWidth: Theme.getSize("checkbox").width; - implicitHeight: Theme.getSize("checkbox").height; + indicator: Rectangle + { + implicitWidth: Theme.getSize("checkbox").width + implicitHeight: Theme.getSize("checkbox").height - color: (control.hovered || control._hovered) ? Theme.getColor("checkbox_hover") : Theme.getColor("checkbox"); + color: (control.hovered || control._hovered) ? Theme.getColor("checkbox_hover") : Theme.getColor("checkbox") Behavior on color { ColorAnimation { duration: 50; } } radius: control.exclusiveGroup ? Math.round(Theme.getSize("checkbox").width / 2) : 0 - border.width: Theme.getSize("default_lining").width; - border.color: (control.hovered || control._hovered) ? Theme.getColor("checkbox_border_hover") : Theme.getColor("checkbox_border"); + border.width: Theme.getSize("default_lining").width + border.color: (control.hovered || control._hovered) ? Theme.getColor("checkbox_border_hover") : Theme.getColor("checkbox_border") - UM.RecolorImage { + UM.RecolorImage + { anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter width: Math.round(parent.width / 2.5) @@ -786,7 +867,8 @@ QtObject { Behavior on opacity { NumberAnimation { duration: 100; } } } } - label: Label { + label: Label + { text: control.text color: Theme.getColor("checkbox_text") font: Theme.getFont("default") @@ -795,12 +877,15 @@ QtObject { } } - property Component partially_checkbox: Component { - CheckBoxStyle { + property Component partially_checkbox: Component + { + CheckBoxStyle + { background: Item { } - indicator: Rectangle { - implicitWidth: Theme.getSize("checkbox").width; - implicitHeight: Theme.getSize("checkbox").height; + indicator: Rectangle + { + implicitWidth: Theme.getSize("checkbox").width + implicitHeight: Theme.getSize("checkbox").height color: (control.hovered || control._hovered) ? Theme.getColor("checkbox_hover") : Theme.getColor("checkbox"); Behavior on color { ColorAnimation { duration: 50; } } @@ -810,7 +895,8 @@ QtObject { border.width: Theme.getSize("default_lining").width; border.color: (control.hovered || control._hovered) ? Theme.getColor("checkbox_border_hover") : Theme.getColor("checkbox_border"); - UM.RecolorImage { + UM.RecolorImage + { anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter width: Math.round(parent.width / 2.5) @@ -818,50 +904,60 @@ QtObject { sourceSize.width: width sourceSize.height: width color: Theme.getColor("checkbox_mark") - source: { - if (control.checkbox_state == 2){ - return Theme.getIcon("solid") + source: + { + if (control.checkbox_state == 2) + { + return Theme.getIcon("solid"); } - else{ - return control.exclusiveGroup ? Theme.getIcon("dot") : Theme.getIcon("check") + else + { + return control.exclusiveGroup ? Theme.getIcon("dot") : Theme.getIcon("check"); } } opacity: control.checked Behavior on opacity { NumberAnimation { duration: 100; } } } } - label: Label { - text: control.text; - color: Theme.getColor("checkbox_text"); - font: Theme.getFont("default"); + label: Label + { + text: control.text + color: Theme.getColor("checkbox_text") + font: Theme.getFont("default") } } } - property Component slider: Component { - SliderStyle { - groove: Rectangle { - implicitWidth: control.width; - implicitHeight: Theme.getSize("slider_groove").height; + property Component slider: Component + { + SliderStyle + { + groove: Rectangle + { + implicitWidth: control.width + implicitHeight: Theme.getSize("slider_groove").height - color: Theme.getColor("slider_groove"); - border.width: Theme.getSize("default_lining").width; - border.color: Theme.getColor("slider_groove_border"); + color: Theme.getColor("slider_groove") + border.width: Theme.getSize("default_lining").width + border.color: Theme.getColor("slider_groove_border") - radius: Math.round(width / 2); + radius: Math.round(width / 2) - Rectangle { - anchors { - left: parent.left; - top: parent.top; - bottom: parent.bottom; + Rectangle + { + anchors + { + left: parent.left + top: parent.top + bottom: parent.bottom } color: Theme.getColor("slider_groove_fill"); width: Math.round((control.value / (control.maximumValue - control.minimumValue)) * parent.width); radius: Math.round(width / 2); } } - handle: Rectangle { + handle: Rectangle + { width: Theme.getSize("slider_handle").width; height: Theme.getSize("slider_handle").height; color: control.hovered ? Theme.getColor("slider_handle_hover") : Theme.getColor("slider_handle"); @@ -873,11 +969,13 @@ QtObject { } } - property Component text_field: Component { - TextFieldStyle { - textColor: Theme.getColor("setting_control_text"); + property Component text_field: Component + { + TextFieldStyle + { + textColor: Theme.getColor("setting_control_text") placeholderTextColor: Theme.getColor("setting_control_text") - font: Theme.getFont("default"); + font: Theme.getFont("default") background: Rectangle { @@ -889,7 +987,8 @@ QtObject { color: Theme.getColor("setting_validation_ok"); - Label { + Label + { anchors.right: parent.right; anchors.rightMargin: Theme.getSize("setting_unit_margin").width; anchors.verticalCenter: parent.verticalCenter; @@ -902,7 +1001,8 @@ QtObject { } } - property Component sidebar_action_button: Component { + property Component sidebar_action_button: Component + { ButtonStyle { background: Rectangle @@ -911,26 +1011,42 @@ QtObject { border.color: { if(!control.enabled) + { return UM.Theme.getColor("action_button_disabled_border"); + } else if(control.pressed) + { return UM.Theme.getColor("action_button_active_border"); + } else if(control.hovered) + { return UM.Theme.getColor("action_button_hovered_border"); + } else + { return UM.Theme.getColor("action_button_border"); + } } color: { if(!control.enabled) + { return UM.Theme.getColor("action_button_disabled"); + } else if(control.pressed) + { return UM.Theme.getColor("action_button_active"); + } else if(control.hovered) + { return UM.Theme.getColor("action_button_hovered"); + } else + { return UM.Theme.getColor("action_button"); + } } - Behavior on color { ColorAnimation { duration: 50; } } + Behavior on color { ColorAnimation { duration: 50 } } implicitWidth: actualLabel.contentWidth + (UM.Theme.getSize("sidebar_margin").width * 2) @@ -941,13 +1057,21 @@ QtObject { color: { if(!control.enabled) + { return UM.Theme.getColor("action_button_disabled_text"); + } else if(control.pressed) + { return UM.Theme.getColor("action_button_active_text"); + } else if(control.hovered) + { return UM.Theme.getColor("action_button_hovered_text"); + } else + { return UM.Theme.getColor("action_button_text"); + } } font: UM.Theme.getFont("action_button") text: control.text @@ -957,7 +1081,8 @@ QtObject { } } - property Component toolbox_action_button: Component { + property Component toolbox_action_button: Component + { ButtonStyle { background: Rectangle @@ -968,17 +1093,17 @@ QtObject { { if (control.installed) { - return UM.Theme.getColor("action_button_disabled") + return UM.Theme.getColor("action_button_disabled"); } else { if (control.hovered) { - return UM.Theme.getColor("primary_hover") + return UM.Theme.getColor("primary_hover"); } else { - return UM.Theme.getColor("primary") + return UM.Theme.getColor("primary"); } } @@ -991,17 +1116,17 @@ QtObject { { if (control.installed) { - return UM.Theme.getColor("action_button_disabled_text") + return UM.Theme.getColor("action_button_disabled_text"); } else { if (control.hovered) { - return UM.Theme.getColor("button_text_hover") + return UM.Theme.getColor("button_text_hover"); } else { - return UM.Theme.getColor("button_text") + return UM.Theme.getColor("button_text"); } } } From 237c360a88897a34ea7abf365c584b9ee04180a9 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 18 Oct 2018 15:18:00 +0200 Subject: [PATCH 0045/1292] The size of the avatar image is now themed. Some other small fixes in the AccountDetails componenent were done. Contributes to CURA-5784. --- resources/qml/Account/AccountDetails.qml | 8 ++++---- resources/qml/Account/AvatarImage.qml | 2 ++ resources/themes/cura-light/styles.qml | 2 +- resources/themes/cura-light/theme.json | 2 ++ 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/resources/qml/Account/AccountDetails.qml b/resources/qml/Account/AccountDetails.qml index 27860cfae5..10ee5016cd 100644 --- a/resources/qml/Account/AccountDetails.qml +++ b/resources/qml/Account/AccountDetails.qml @@ -18,8 +18,8 @@ Column AvatarImage { id: avatar - width: 75 * screenScaleFactor - height: 75 * screenScaleFactor + width: UM.Theme.getSize("avatar_image").width + height: UM.Theme.getSize("avatar_image").height anchors.horizontalCenter: parent.horizontalCenter source: loggedIn ? profile["profile_image_url"] : UM.Theme.getImage("avatar_default") outlineColor: loggedIn ? UM.Theme.getColor("account_widget_ouline_active") : UM.Theme.getColor("account_widget_ouline_inactive") @@ -29,8 +29,8 @@ Column { id: information anchors.horizontalCenter: parent.horizontalCenter - visible: !loggedIn - text: loggedIn ? profile["username"] : catalog.i18nc("@label", "Please login or create an account to 
enjoy all features of Ultimaker Cura") + horizontalAlignment: Text.AlignHCenter + text: loggedIn ? profile["username"] : catalog.i18nc("@label", "Please log in or create an account to\nenjoy all features of Ultimaker Cura.") font: loggedIn ? UM.Theme.getFont("large") : UM.Theme.getFont("default") color: UM.Theme.getColor("text") } diff --git a/resources/qml/Account/AvatarImage.qml b/resources/qml/Account/AvatarImage.qml index 0e0d182018..333bce29d7 100644 --- a/resources/qml/Account/AvatarImage.qml +++ b/resources/qml/Account/AvatarImage.qml @@ -1,4 +1,6 @@ // Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + import QtQuick 2.7 import QtQuick.Controls 2.1 import QtGraphicalEffects 1.0 diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index 939399efc8..1164b84332 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.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.1 diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 285d2724a0..43a0b628b5 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -488,6 +488,8 @@ "toolbox_action_button": [8.0, 2.5], "toolbox_loader": [2.0, 2.0], + "avatar_image": [6.8, 6.8], + "drop_shadow_radius": [1.0, 1.0] } } From 119638efa1fa71492648b0305df87bdea23bad12 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 18 Oct 2018 15:35:21 +0200 Subject: [PATCH 0046/1292] Adjust outline color for the avatar image. Following the colors in the designs. Contributes to CURA-5784. --- resources/themes/cura-light/theme.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 43a0b628b5..16cb17756d 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -88,7 +88,7 @@ "topheader_button_background_inactive": [255, 255, 255, 0], "account_widget_ouline_active": [9, 140, 188, 255], - "account_widget_ouline_inactive": [175, 175, 175, 255], + "account_widget_ouline_inactive": [229, 229, 229, 255], "text": [0, 0, 0, 255], "text_detail": [174, 174, 174, 128], From 0a07f48375bb47976d32194ece31c0d5c7038dbe Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 18 Oct 2018 15:38:24 +0200 Subject: [PATCH 0047/1292] Fix typo in a theme's key. Contributes to CURA-5784. --- resources/qml/Account/AccountDetails.qml | 2 +- resources/qml/Account/AccountWidget.qml | 2 +- resources/themes/cura-light/theme.json | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/qml/Account/AccountDetails.qml b/resources/qml/Account/AccountDetails.qml index 10ee5016cd..18f11622fd 100644 --- a/resources/qml/Account/AccountDetails.qml +++ b/resources/qml/Account/AccountDetails.qml @@ -22,7 +22,7 @@ Column height: UM.Theme.getSize("avatar_image").height anchors.horizontalCenter: parent.horizontalCenter source: loggedIn ? profile["profile_image_url"] : UM.Theme.getImage("avatar_default") - outlineColor: loggedIn ? UM.Theme.getColor("account_widget_ouline_active") : UM.Theme.getColor("account_widget_ouline_inactive") + outlineColor: loggedIn ? UM.Theme.getColor("account_widget_outline_active") : UM.Theme.getColor("account_widget_outline_inactive") } Label diff --git a/resources/qml/Account/AccountWidget.qml b/resources/qml/Account/AccountWidget.qml index a6a79a7d29..6374aaad69 100644 --- a/resources/qml/Account/AccountWidget.qml +++ b/resources/qml/Account/AccountWidget.qml @@ -28,7 +28,7 @@ Button anchors.horizontalCenter: parent.horizontalCenter source: loggedIn ? profile["profile_image_url"] : UM.Theme.getImage("avatar_default") - outlineColor: loggedIn ? UM.Theme.getColor("account_widget_ouline_active") : UM.Theme.getColor("account_widget_ouline_inactive") + outlineColor: loggedIn ? UM.Theme.getColor("account_widget_outline_active") : UM.Theme.getColor("account_widget_outline_inactive") } background: Item {} diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 16cb17756d..07eab72afb 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -87,8 +87,8 @@ "topheader_button_background_active": [255, 255, 255, 255], "topheader_button_background_inactive": [255, 255, 255, 0], - "account_widget_ouline_active": [9, 140, 188, 255], - "account_widget_ouline_inactive": [229, 229, 229, 255], + "account_widget_outline_active": [9, 140, 188, 255], + "account_widget_outline_inactive": [229, 229, 229, 255], "text": [0, 0, 0, 255], "text_detail": [174, 174, 174, 128], From fdfa81b2b8cf69d78897961f6985bf6ed8b941e0 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 18 Oct 2018 16:06:21 +0200 Subject: [PATCH 0048/1292] Make some items' size dependent on parent's. Also make the ActionButton more themable. Contributes to CURA-5784. --- resources/qml/Account/AccountDetails.qml | 1 + resources/qml/Account/AccountWidget.qml | 1 - resources/qml/ActionButton.qml | 21 +++++++++++---------- resources/themes/cura-light/theme.json | 2 ++ 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/resources/qml/Account/AccountDetails.qml b/resources/qml/Account/AccountDetails.qml index 18f11622fd..cc065fc0dd 100644 --- a/resources/qml/Account/AccountDetails.qml +++ b/resources/qml/Account/AccountDetails.qml @@ -30,6 +30,7 @@ Column id: information anchors.horizontalCenter: parent.horizontalCenter horizontalAlignment: Text.AlignHCenter + renderType: Text.NativeRendering text: loggedIn ? profile["username"] : catalog.i18nc("@label", "Please log in or create an account to\nenjoy all features of Ultimaker Cura.") font: loggedIn ? UM.Theme.getFont("large") : UM.Theme.getFont("default") color: UM.Theme.getColor("text") diff --git a/resources/qml/Account/AccountWidget.qml b/resources/qml/Account/AccountWidget.qml index 6374aaad69..70ee6c86da 100644 --- a/resources/qml/Account/AccountWidget.qml +++ b/resources/qml/Account/AccountWidget.qml @@ -21,7 +21,6 @@ Button { id: avatar - width: Math.round(0.8 * parent.width) height: Math.round(0.8 * parent.height) anchors.verticalCenter: parent.verticalCenter diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index b49e3f1dcb..44299d3734 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -11,28 +11,28 @@ Button { id: button property alias cursorShape: mouseArea.cursorShape - property var iconSource: "" + property alias iconSource: buttonIcon.source + property alias textFont: buttonText.font + property alias cornerRadius: backgroundRect.radius property var color: UM.Theme.getColor("primary") property var hoverColor: UM.Theme.getColor("primary_hover") property var disabledColor: color property var textColor: UM.Theme.getColor("button_text") property var textHoverColor: UM.Theme.getColor("button_text_hover") property var textDisabledColor: textColor - property var textFont: UM.Theme.getFont("action_button") - property var cornerRadius: 2 * screenScaleFactor contentItem: Row { UM.RecolorImage { id: buttonIcon - source: button.iconSource - width: 16 * screenScaleFactor - height: 16 * screenScaleFactor + source: "" + height: Math.round(0.6 * parent.height) + width: height sourceSize.width: width sourceSize.height: height color: button.hovered ? button.textHoverColor : button.textColor - visible: button.iconSource != "" + visible: source != "" anchors.verticalCenter: parent.verticalCenter } @@ -41,8 +41,8 @@ Button id: buttonText text: button.text color: button.enabled ? (button.hovered ? button.textHoverColor : button.textColor): button.textDisabledColor - font: button.textFont - visible: button.text != "" + font: UM.Theme.getFont("action_button") + visible: text != "" renderType: Text.NativeRendering anchors.verticalCenter: parent.verticalCenter } @@ -50,8 +50,9 @@ Button background: Rectangle { + id: backgroundRect color: button.enabled ? (button.hovered ? button.hoverColor : button.color) : button.disabledColor - radius: cornerRadius + radius: UM.Theme.getSize("action_button_radius").width } MouseArea diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 07eab72afb..3325312e8b 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -490,6 +490,8 @@ "avatar_image": [6.8, 6.8], + "action_button_radius": [0.25, 0.25], + "drop_shadow_radius": [1.0, 1.0] } } From 1cc7e0e586604ddf16b2931e1bcffbadb53c7f80 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 18 Oct 2018 16:33:13 +0200 Subject: [PATCH 0049/1292] Set the height of the stage menu in the theme instead of hardcoded. I also adjusted a bit the design to fulfill the requirments from UX/UI team. Contributes to CURA-5772. --- cura/Stages/CuraStage.py | 5 +++-- plugins/PrepareStage/PrepareMenu.qml | 8 +++++++- resources/qml/Cura.qml | 17 ++++++++++++++--- resources/themes/cura-light/theme.json | 2 ++ 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/cura/Stages/CuraStage.py b/cura/Stages/CuraStage.py index 774a5a6e76..e8537fb6b9 100644 --- a/cura/Stages/CuraStage.py +++ b/cura/Stages/CuraStage.py @@ -1,5 +1,6 @@ -# Copyright (c) 2017 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. + from PyQt5.QtCore import pyqtProperty, QUrl from UM.Stage import Stage @@ -27,6 +28,6 @@ class CuraStage(Stage): def sidebarComponent(self) -> QUrl: return self.getDisplayComponent("sidebar") - @pyqtProperty(QUrl, constant=True) + @pyqtProperty(QUrl, constant = True) def stageMenuComponent(self) -> QUrl: return self.getDisplayComponent("menu") \ No newline at end of file diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index 208e7d18df..10ff0b2310 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -21,7 +21,6 @@ Item Row { - spacing: UM.Theme.getSize("default_margin").width anchors.horizontalCenter: parent.horizontalCenter Button @@ -34,6 +33,13 @@ Item action: Cura.Actions.open } + Item + { + id: spacing + width: UM.Theme.getSize("default_margin").width + height: parent.height + } + Cura.MachineAndConfigurationSelector { } diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 2654eb3c20..d9113ca448 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -20,7 +20,6 @@ UM.MainWindow // Cura application window title title: catalog.i18nc("@title:window", "Ultimaker Cura") - viewportRect: Qt.rect(0, 0, 1.0, 1.0) backgroundColor: UM.Theme.getColor("viewport_background") UM.I18nCatalog @@ -143,6 +142,19 @@ UM.MainWindow } } + Rectangle + { + anchors + { + left: parent.left + right: parent.right + top: parent.top + } + visible: stageMenu.source != "" + height: Math.round(UM.Theme.getSize("stage_menu").height / 2) + color: UM.Theme.getColor("topheader_background") + } + Loader { // The stage menu is, as the name implies, a menu that is defined by the active stage. @@ -155,10 +167,9 @@ UM.MainWindow left: parent.left right: parent.right top: parent.top - margins: UM.Theme.getSize("default_margin").height } - height: 50 + height: UM.Theme.getSize("stage_menu").height source: UM.Controller.activeStage != null ? UM.Controller.activeStage.stageMenuComponent : "" } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 3325312e8b..d26c872b00 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -344,6 +344,8 @@ "topheader_button": [8, 4], "topheader_button_icon": [1.2, 1.2], + "stage_menu": [0.0, 4.5], + "account_button": [12, 3], "views_selector": [0.0, 4.0], From 8df3eb33d45fd89bc4e7b0789ba03cfdc1020c4f Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 18 Oct 2018 16:51:32 +0200 Subject: [PATCH 0050/1292] Minor changes: remove empty lines, small changes in the anchors, ... Contributes to CURA-5772. --- resources/qml/Account/AccountDetails.qml | 2 +- resources/qml/Account/AccountWidget.qml | 1 - resources/qml/Cura.qml | 9 +-------- 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/resources/qml/Account/AccountDetails.qml b/resources/qml/Account/AccountDetails.qml index cc065fc0dd..9cd9b91949 100644 --- a/resources/qml/Account/AccountDetails.qml +++ b/resources/qml/Account/AccountDetails.qml @@ -38,7 +38,7 @@ Column Loader { - id: accountEntryPoints + id: accountOperations anchors.horizontalCenter: parent.horizontalCenter sourceComponent: loggedIn ? userOperations : generalOperations } diff --git a/resources/qml/Account/AccountWidget.qml b/resources/qml/Account/AccountWidget.qml index 70ee6c86da..d6d4728e7e 100644 --- a/resources/qml/Account/AccountWidget.qml +++ b/resources/qml/Account/AccountWidget.qml @@ -16,7 +16,6 @@ Button implicitHeight: UM.Theme.getSize("topheader").height implicitWidth: UM.Theme.getSize("topheader").height - AvatarImage { id: avatar diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index d9113ca448..52ff99ad9b 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -187,7 +187,6 @@ UM.MainWindow { bottom: parent.bottom bottomMargin: UM.Theme.getSize("default_margin").height - rightMargin: UM.Theme.getSize("default_margin").width } } @@ -330,13 +329,7 @@ UM.MainWindow // A stage can control this area. If nothing is set, it will therefore show the 3D view. id: main - anchors - { - top: parent.top - bottom: parent.bottom - left: parent.left - right: parent.right - } + anchors.fill: parent MouseArea { From 93b04190f803b16e8409ac94f843f2605a347ed8 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 18 Oct 2018 17:13:15 +0200 Subject: [PATCH 0051/1292] Change name of some components to make them more indicative of what they do. Contributes to CURA-5772. --- plugins/PrepareStage/PrepareMenu.qml | 23 +++++++-- ...or.qml => CustomConfigurationSelector.qml} | 0 .../qml/MachineAndConfigurationSelector.qml | 47 ------------------- ...chineSelection.qml => MachineSelector.qml} | 0 ...ion.qml => QuickConfigurationSelector.qml} | 0 ...ngComponent.qml => PrintSetupSelector.qml} | 0 resources/qml/qmldir | 7 +-- 7 files changed, 23 insertions(+), 54 deletions(-) rename resources/qml/{MaterialAndVariantSelector.qml => CustomConfigurationSelector.qml} (100%) delete mode 100644 resources/qml/MachineAndConfigurationSelector.qml rename resources/qml/{MachineSelection.qml => MachineSelector.qml} (100%) rename resources/qml/Menus/ConfigurationMenu/{ConfigurationSelection.qml => QuickConfigurationSelector.qml} (100%) rename resources/qml/{ProfileAndSettingComponent.qml => PrintSetupSelector.qml} (100%) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index 10ff0b2310..8d0f03ec2f 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -13,6 +13,9 @@ Item signal showTooltip(Item item, point location, string text) signal hideTooltip() + property bool isNetworkPrinter: Cura.MachineManager.activeMachineNetworkKey != "" + property bool printerConnected: Cura.MachineManager.printerConnected + UM.I18nCatalog { id: catalog @@ -37,19 +40,31 @@ Item { id: spacing width: UM.Theme.getSize("default_margin").width - height: parent.height + height: prepareMenu.height } - Cura.MachineAndConfigurationSelector + Cura.MachineSelector { + id: machineSelection + width: UM.Theme.getSize("sidebar").width + height: prepareMenu.height } - Cura.MaterialAndVariantSelector + Cura.QuickConfigurationSelector + { + id: configSelection + visible: isNetworkPrinter && printerConnected + width: visible ? Math.round(machineSelection.width * 0.15) : 0 + panelWidth: machineSelection.width + height: prepareMenu.height + } + + Cura.CustomConfigurationSelector { width: UM.Theme.getSize("sidebar").width } - Cura.ProfileAndSettingComponent + Cura.PrintSetupSelector { width: UM.Theme.getSize("sidebar").width onShowTooltip: prepareMenu.showTooltip(item, location, text) diff --git a/resources/qml/MaterialAndVariantSelector.qml b/resources/qml/CustomConfigurationSelector.qml similarity index 100% rename from resources/qml/MaterialAndVariantSelector.qml rename to resources/qml/CustomConfigurationSelector.qml diff --git a/resources/qml/MachineAndConfigurationSelector.qml b/resources/qml/MachineAndConfigurationSelector.qml deleted file mode 100644 index 15b9ca6dd6..0000000000 --- a/resources/qml/MachineAndConfigurationSelector.qml +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) 2017 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.7 - -import UM 1.2 as UM -import Cura 1.0 as Cura -import "Menus" -import "Menus/ConfigurationMenu" - -Rectangle -{ - color: UM.Theme.getColor("sidebar_lining_thin") - - implicitHeight: UM.Theme.getSize("sidebar_header").height - implicitWidth: UM.Theme.getSize("sidebar").width - - property bool isNetworkPrinter: Cura.MachineManager.activeMachineNetworkKey != "" - property bool printerConnected: Cura.MachineManager.printerConnected - - MachineSelection - { - id: machineSelection - anchors - { - left: parent.left - right: configSelection.left - rightMargin: UM.Theme.getSize("sidebar_lining_thin").height / 2 - top: parent.top - bottom: parent.bottom - } - } - - ConfigurationSelection - { - id: configSelection - visible: isNetworkPrinter && printerConnected - width: visible ? Math.round(parent.width * 0.15) : 0 - panelWidth: parent.width - anchors - { - right: parent.right - top: parent.top - bottom: parent.bottom - } - } -} \ No newline at end of file diff --git a/resources/qml/MachineSelection.qml b/resources/qml/MachineSelector.qml similarity index 100% rename from resources/qml/MachineSelection.qml rename to resources/qml/MachineSelector.qml diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationSelection.qml b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml similarity index 100% rename from resources/qml/Menus/ConfigurationMenu/ConfigurationSelection.qml rename to resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml diff --git a/resources/qml/ProfileAndSettingComponent.qml b/resources/qml/PrintSetupSelector.qml similarity index 100% rename from resources/qml/ProfileAndSettingComponent.qml rename to resources/qml/PrintSetupSelector.qml diff --git a/resources/qml/qmldir b/resources/qml/qmldir index b9306b14bc..10e103d9ef 100644 --- a/resources/qml/qmldir +++ b/resources/qml/qmldir @@ -1,6 +1,7 @@ module Cura -MachineAndConfigurationSelector 1.0 MachineAndConfigurationSelector.qml -MaterialAndVariantSelector 1.0 MaterialAndVariantSelector.qml -ProfileAndSettingComponent 1.0 ProfileAndSettingComponent.qml +MachineSelector 1.0 MachineSelector.qml +QuickConfigurationSelector 1.0 QuickConfigurationSelector.qml +CustomConfigurationSelector 1.0 CustomConfigurationSelector.qml +PrintSetupSelector 1.0 PrintSetupSelector.qml ActionButton 1.0 ActionButton.qml \ No newline at end of file From 84adfa14ee73ef09831197c464ca847b5543f1de Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 18 Oct 2018 17:26:10 +0200 Subject: [PATCH 0052/1292] Add license to the top of a file Contributes to CURA-5772. --- resources/qml/ExtruderIcon.qml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/resources/qml/ExtruderIcon.qml b/resources/qml/ExtruderIcon.qml index 580ff5dce9..e4161e0058 100644 --- a/resources/qml/ExtruderIcon.qml +++ b/resources/qml/ExtruderIcon.qml @@ -1,3 +1,6 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + import QtQuick 2.7 import QtQuick.Controls 1.1 import UM 1.2 as UM @@ -47,7 +50,7 @@ Item height: Math.round(parent.height * 0.35) radius: Math.round(width / 2) - border.width: 1 + border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("extruder_button_material_border") opacity: !extruderIconItem.checked ? 0.6 : 1.0 From bf6817ce7a68c2e7f0b347ca98062e913a7a35e4 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 18 Oct 2018 17:38:23 +0200 Subject: [PATCH 0053/1292] Reduce the size of the ApplicationMenu.qml file by moving some components out to different files. Contributes to CURA-5772. --- resources/qml/MainWindow/ApplicationMenu.qml | 136 +------------------ resources/qml/Menus/FileMenu.qml | 81 +++++++++++ resources/qml/Menus/SettingsMenu.qml | 69 ++++++++++ 3 files changed, 153 insertions(+), 133 deletions(-) create mode 100644 resources/qml/Menus/FileMenu.qml create mode 100644 resources/qml/Menus/SettingsMenu.qml diff --git a/resources/qml/MainWindow/ApplicationMenu.qml b/resources/qml/MainWindow/ApplicationMenu.qml index e538e966fc..d3bc115419 100644 --- a/resources/qml/MainWindow/ApplicationMenu.qml +++ b/resources/qml/MainWindow/ApplicationMenu.qml @@ -24,78 +24,7 @@ Item { id: applicationMenu - Menu - { - id: fileMenu - title: catalog.i18nc("@title:menu menubar:toplevel", "&File") - - MenuItem - { - id: newProjectMenu - action: Cura.Actions.newProject - } - - MenuItem - { - id: openMenu - action: Cura.Actions.open - } - - RecentFilesMenu { } - - MenuItem - { - id: saveWorkspaceMenu - text: catalog.i18nc("@title:menu menubar:file", "&Save...") - onTriggered: - { - var args = { "filter_by_machine": false, "file_type": "workspace", "preferred_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml" }; - if(UM.Preferences.getValue("cura/dialog_on_project_save")) - { - saveWorkspaceDialog.args = args - saveWorkspaceDialog.open() - } - else - { - UM.OutputDeviceManager.requestWriteToDevice("local_file", PrintInformation.jobName, args) - } - } - } - - MenuSeparator { } - - MenuItem - { - id: saveAsMenu - text: catalog.i18nc("@title:menu menubar:file", "&Export...") - onTriggered: - { - var localDeviceId = "local_file" - UM.OutputDeviceManager.requestWriteToDevice(localDeviceId, PrintInformation.jobName, { "filter_by_machine": false, "preferred_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml"}) - } - } - - MenuItem - { - id: exportSelectionMenu - 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_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml"}) - } - - MenuSeparator { } - - MenuItem - { - id: reloadAllMenu - action: Cura.Actions.reloadAll - } - - MenuSeparator { } - - MenuItem { action: Cura.Actions.quit } - } + FileMenu { title: catalog.i18nc("@title:menu menubar:toplevel", "&File") } Menu { @@ -116,68 +45,9 @@ Item MenuItem { action: Cura.Actions.unGroupObjects } } - ViewMenu { title: catalog.i18nc("@title:menu", "&View") } + ViewMenu { title: catalog.i18nc("@title:menu menubar:toplevel", "&View") } - Menu - { - id: settingsMenu - title: catalog.i18nc("@title:menu", "&Settings") - - PrinterMenu { title: catalog.i18nc("@title:menu menubar:settings", "&Printer") } - - Instantiator - { - model: Cura.ExtrudersModel { simpleNames: true } - Menu - { - title: model.name - - NozzleMenu { title: Cura.MachineManager.activeDefinitionVariantsName; visible: Cura.MachineManager.hasVariants; extruderIndex: index } - MaterialMenu { title: catalog.i18nc("@title:menu", "&Material"); visible: Cura.MachineManager.hasMaterials; extruderIndex: index } - - MenuSeparator - { - visible: Cura.MachineManager.hasVariants || Cura.MachineManager.hasMaterials - } - - MenuItem - { - text: catalog.i18nc("@action:inmenu", "Set as Active Extruder") - onTriggered: Cura.MachineManager.setExtruderIndex(model.index) - } - - MenuItem - { - text: catalog.i18nc("@action:inmenu", "Enable Extruder") - onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, true) - visible: !Cura.MachineManager.getExtruder(model.index).isEnabled - } - - MenuItem - { - text: catalog.i18nc("@action:inmenu", "Disable Extruder") - onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, false) - visible: Cura.MachineManager.getExtruder(model.index).isEnabled - enabled: Cura.MachineManager.numberExtrudersEnabled > 1 - } - - } - onObjectAdded: settingsMenu.insertItem(index, object) - onObjectRemoved: settingsMenu.removeItem(object) - } - - // TODO Only show in dev mode. Remove check when feature ready - BuildplateMenu - { - title: catalog.i18nc("@title:menu", "&Build plate") - visible: CuraSDKVersion == "dev" && Cura.MachineManager.hasVariantBuildplates - } - ProfileMenu { title: catalog.i18nc("@title:settings", "&Profile") } - - MenuSeparator { } - - MenuItem { action: Cura.Actions.configureSettingVisibility } - } + SettingsMenu { title: catalog.i18nc("@title:menu menubar:toplevel", "&Settings") } Menu { diff --git a/resources/qml/Menus/FileMenu.qml b/resources/qml/Menus/FileMenu.qml new file mode 100644 index 0000000000..955ac89693 --- /dev/null +++ b/resources/qml/Menus/FileMenu.qml @@ -0,0 +1,81 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 1.1 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +Menu +{ + id: base + title: catalog.i18nc("@title:menu menubar:toplevel", "&File") + + MenuItem + { + id: newProjectMenu + action: Cura.Actions.newProject + } + + MenuItem + { + id: openMenu + action: Cura.Actions.open + } + + RecentFilesMenu { } + + MenuItem + { + id: saveWorkspaceMenu + text: catalog.i18nc("@title:menu menubar:file", "&Save...") + onTriggered: + { + var args = { "filter_by_machine": false, "file_type": "workspace", "preferred_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml" }; + if(UM.Preferences.getValue("cura/dialog_on_project_save")) + { + saveWorkspaceDialog.args = args + saveWorkspaceDialog.open() + } + else + { + UM.OutputDeviceManager.requestWriteToDevice("local_file", PrintInformation.jobName, args) + } + } + } + + MenuSeparator { } + + MenuItem + { + id: saveAsMenu + text: catalog.i18nc("@title:menu menubar:file", "&Export...") + onTriggered: + { + var localDeviceId = "local_file" + UM.OutputDeviceManager.requestWriteToDevice(localDeviceId, PrintInformation.jobName, { "filter_by_machine": false, "preferred_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml"}) + } + } + + MenuItem + { + id: exportSelectionMenu + 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_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml"}) + } + + MenuSeparator { } + + MenuItem + { + id: reloadAllMenu + action: Cura.Actions.reloadAll + } + + MenuSeparator { } + + MenuItem { action: Cura.Actions.quit } +} \ No newline at end of file diff --git a/resources/qml/Menus/SettingsMenu.qml b/resources/qml/Menus/SettingsMenu.qml new file mode 100644 index 0000000000..79f8c5b7bf --- /dev/null +++ b/resources/qml/Menus/SettingsMenu.qml @@ -0,0 +1,69 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 1.1 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +Menu +{ + id: base + title: catalog.i18nc("@title:menu menubar:toplevel", "&Settings") + + PrinterMenu { title: catalog.i18nc("@title:menu menubar:settings", "&Printer") } + + Instantiator + { + model: Cura.ExtrudersModel { simpleNames: true } + Menu + { + title: model.name + + NozzleMenu { title: Cura.MachineManager.activeDefinitionVariantsName; visible: Cura.MachineManager.hasVariants; extruderIndex: index } + MaterialMenu { title: catalog.i18nc("@title:menu", "&Material"); visible: Cura.MachineManager.hasMaterials; extruderIndex: index } + + MenuSeparator + { + visible: Cura.MachineManager.hasVariants || Cura.MachineManager.hasMaterials + } + + MenuItem + { + text: catalog.i18nc("@action:inmenu", "Set as Active Extruder") + onTriggered: Cura.MachineManager.setExtruderIndex(model.index) + } + + MenuItem + { + text: catalog.i18nc("@action:inmenu", "Enable Extruder") + onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, true) + visible: !Cura.MachineManager.getExtruder(model.index).isEnabled + } + + MenuItem + { + text: catalog.i18nc("@action:inmenu", "Disable Extruder") + onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, false) + visible: Cura.MachineManager.getExtruder(model.index).isEnabled + enabled: Cura.MachineManager.numberExtrudersEnabled > 1 + } + + } + onObjectAdded: base.insertItem(index, object) + onObjectRemoved: base.removeItem(object) + } + + // TODO Only show in dev mode. Remove check when feature ready + BuildplateMenu + { + title: catalog.i18nc("@title:menu", "&Build plate") + visible: CuraSDKVersion == "dev" && Cura.MachineManager.hasVariantBuildplates + } + ProfileMenu { title: catalog.i18nc("@title:settings", "&Profile") } + + MenuSeparator { } + + MenuItem { action: Cura.Actions.configureSettingVisibility } +} \ No newline at end of file From 176c7bfc22ea4972ce194c07301b9e75ca28331f Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 18 Oct 2018 17:48:03 +0200 Subject: [PATCH 0054/1292] Small fixes in the CustomConfigurationSelector file Contributes to CURA-5772. --- resources/qml/CustomConfigurationSelector.qml | 26 +++++++++---------- resources/qml/qmldir | 4 ++- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/resources/qml/CustomConfigurationSelector.qml b/resources/qml/CustomConfigurationSelector.qml index 7dfc3737c0..9a3f91e6a3 100644 --- a/resources/qml/CustomConfigurationSelector.qml +++ b/resources/qml/CustomConfigurationSelector.qml @@ -8,8 +8,6 @@ import QtQuick.Controls.Styles 1.1 import UM 1.2 as UM import Cura 1.0 as Cura -import "Menus" // TODO: This needs to be fixed in the qmldir! - Rectangle { implicitWidth: parent.width @@ -77,16 +75,15 @@ Rectangle extruder_enabled = Cura.MachineManager.getExtruder(model.index).isEnabled if (extruder_enabled) { - forceActiveFocus(); // Changing focus applies the currently-being-typed values so it can change the displayed setting values. - Cura.ExtruderManager.setActiveExtruderIndex(index); + forceActiveFocus() // Changing focus applies the currently-being-typed values so it can change the displayed setting values. + Cura.ExtruderManager.setActiveExtruderIndex(index) } - break; + break case Qt.RightButton: extruder_enabled = Cura.MachineManager.getExtruder(model.index).isEnabled - extruderMenu.popup(); - break; + extruderMenu.popup() + break } - } } @@ -122,8 +119,9 @@ Rectangle { if(control.checked || control.pressed) { - return UM.Theme.getColor("action_button_active_border"); - } else if (control.hovered) + return UM.Theme.getColor("action_button_active_border") + } + else if (control.hovered) { return UM.Theme.getColor("action_button_hovered_border") } @@ -252,7 +250,7 @@ Rectangle anchors.right: parent.right style: UM.Theme.styles.sidebar_header_button activeFocusOnPress: true; - menu: MaterialMenu + menu: Cura.MaterialMenu { extruderIndex: Cura.ExtruderManager.activeExtruderIndex } @@ -300,7 +298,7 @@ Rectangle style: UM.Theme.styles.sidebar_header_button activeFocusOnPress: true; - menu: NozzleMenu { extruderIndex: Cura.ExtruderManager.activeExtruderIndex } + menu: Cura.NozzleMenu { extruderIndex: Cura.ExtruderManager.activeExtruderIndex } } } @@ -348,12 +346,12 @@ Rectangle { anchors.fill: parent - onClicked: { + onClicked: + { // open the material URL with web browser Qt.openUrlExternally("https://ultimaker.com/incoming-links/cura/material-compatibilty"); } } } } - } diff --git a/resources/qml/qmldir b/resources/qml/qmldir index 10e103d9ef..2681da00e1 100644 --- a/resources/qml/qmldir +++ b/resources/qml/qmldir @@ -4,4 +4,6 @@ MachineSelector 1.0 MachineSelector.qml QuickConfigurationSelector 1.0 QuickConfigurationSelector.qml CustomConfigurationSelector 1.0 CustomConfigurationSelector.qml PrintSetupSelector 1.0 PrintSetupSelector.qml -ActionButton 1.0 ActionButton.qml \ No newline at end of file +ActionButton 1.0 ActionButton.qml +MaterialMenu 1.0 MaterialMenu.qml +NozzleMenu 1.0 NozzleMenu.qml \ No newline at end of file From 66147f4172f1162a5a5a604742186f91e3025c4a Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 18 Oct 2018 17:49:56 +0200 Subject: [PATCH 0055/1292] Remove unused style button. Contributes to CURA-5772. --- resources/themes/cura-light/styles.qml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index 58e6d2cf4d..074ceb4200 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -96,14 +96,6 @@ QtObject } } - property Component action_button: Component - { - ButtonStyle - { - - } - } - property Component topheader_tab: Component { ButtonStyle From 405e4c5bbd73eb60b8b27822e3e30890ecdb97aa Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 18 Oct 2018 17:52:42 +0200 Subject: [PATCH 0056/1292] Correct year, we live now in 2018 (keep it in mind) Contributes to CURA-5772. --- resources/qml/MachineSelector.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/MachineSelector.qml b/resources/qml/MachineSelector.qml index 7a8a6b476b..49fbf16e19 100644 --- a/resources/qml/MachineSelector.qml +++ b/resources/qml/MachineSelector.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.2 From 6f12197cead700d53666f0f9007b895f830e0fd5 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 19 Oct 2018 13:41:32 +0200 Subject: [PATCH 0057/1292] Don't use an image to create a mask but a circle. Contributes to CURA-5772. --- resources/qml/Account/AvatarImage.qml | 12 ++-- .../themes/cura-light/icons/circle_mask.svg | 64 ----------------- .../cura-light/icons/circle_outline.svg | 68 ++----------------- 3 files changed, 8 insertions(+), 136 deletions(-) delete mode 100644 resources/themes/cura-light/icons/circle_mask.svg diff --git a/resources/qml/Account/AvatarImage.qml b/resources/qml/Account/AvatarImage.qml index 333bce29d7..21adbcb7c3 100644 --- a/resources/qml/Account/AvatarImage.qml +++ b/resources/qml/Account/AvatarImage.qml @@ -26,31 +26,27 @@ Item visible: false } - UM.RecolorImage + Rectangle { id: profileImageMask - source: UM.Theme.getIcon("circle_mask") - sourceSize: Qt.size(parent.width, parent.height) anchors.fill: parent - color: UM.Theme.getColor("topheader_background") - visible: false + radius: width } OpacityMask { - anchors.fill: profileImage + anchors.fill: parent source: profileImage maskSource: profileImageMask cached: true - invert: false } UM.RecolorImage { id: profileImageOutline + anchors.fill: parent source: UM.Theme.getIcon("circle_outline") sourceSize: Qt.size(parent.width, parent.height) - anchors.fill: parent color: UM.Theme.getColor("account_widget_ouline_active") } } \ No newline at end of file diff --git a/resources/themes/cura-light/icons/circle_mask.svg b/resources/themes/cura-light/icons/circle_mask.svg deleted file mode 100644 index d5bfe53a97..0000000000 --- a/resources/themes/cura-light/icons/circle_mask.svg +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - diff --git a/resources/themes/cura-light/icons/circle_outline.svg b/resources/themes/cura-light/icons/circle_outline.svg index 4d0b0e4eb0..3a8fb197f3 100644 --- a/resources/themes/cura-light/icons/circle_outline.svg +++ b/resources/themes/cura-light/icons/circle_outline.svg @@ -1,64 +1,4 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - + + + + \ No newline at end of file From 15b35da612e773bb78827ae7bd5940c33cd85717 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 19 Oct 2018 16:40:21 +0200 Subject: [PATCH 0058/1292] Change the TopHeader name to MainWindowHeader, since there is nothing more on the top than the header. Contributes to CURA-5784. --- resources/qml/Account/AccountWidget.qml | 4 ++-- resources/qml/Account/GeneralOperations.qml | 4 ++-- resources/qml/Account/UserOperations.qml | 4 ++-- resources/qml/Cura.qml | 8 +++---- .../{TopHeader.qml => MainWindowHeader.qml} | 22 +++++++++---------- .../ConfigurationMenu/ConfigurationItem.qml | 4 ++-- resources/themes/cura-dark/theme.json | 9 ++++---- resources/themes/cura-light/styles.qml | 14 ++++++------ resources/themes/cura-light/theme.json | 19 ++++++++-------- 9 files changed, 43 insertions(+), 45 deletions(-) rename resources/qml/MainWindow/{TopHeader.qml => MainWindowHeader.qml} (76%) diff --git a/resources/qml/Account/AccountWidget.qml b/resources/qml/Account/AccountWidget.qml index d6d4728e7e..fc99273119 100644 --- a/resources/qml/Account/AccountWidget.qml +++ b/resources/qml/Account/AccountWidget.qml @@ -13,8 +13,8 @@ Button property var profile: Cura.API.account.userProfile property var loggedIn: Cura.API.account.isLoggedIn - implicitHeight: UM.Theme.getSize("topheader").height - implicitWidth: UM.Theme.getSize("topheader").height + implicitHeight: UM.Theme.getSize("main_window_header").height + implicitWidth: UM.Theme.getSize("main_window_header").height AvatarImage { diff --git a/resources/qml/Account/GeneralOperations.qml b/resources/qml/Account/GeneralOperations.qml index 1f3cd51f26..6bc94dd830 100644 --- a/resources/qml/Account/GeneralOperations.qml +++ b/resources/qml/Account/GeneralOperations.qml @@ -18,8 +18,8 @@ Row text: catalog.i18nc("@button", "Create account") color: UM.Theme.getColor("secondary") hoverColor: UM.Theme.getColor("secondary") - textColor: UM.Theme.getColor("text_link") - textHoverColor: UM.Theme.getColor("text") + textColor: UM.Theme.getColor("main_window_header_button_text_active") + textHoverColor: UM.Theme.getColor("main_window_header_button_text_active") onClicked: Qt.openUrlExternally("https://account.ultimaker.com") } diff --git a/resources/qml/Account/UserOperations.qml b/resources/qml/Account/UserOperations.qml index ffcf518b6e..a12bfbf6d7 100644 --- a/resources/qml/Account/UserOperations.qml +++ b/resources/qml/Account/UserOperations.qml @@ -18,8 +18,8 @@ Row text: catalog.i18nc("@button", "Manage account") color: UM.Theme.getColor("secondary") hoverColor: UM.Theme.getColor("secondary") - textColor: UM.Theme.getColor("text_link") - textHoverColor: UM.Theme.getColor("text") + textColor: UM.Theme.getColor("main_window_header_button_text_active") + textHoverColor: UM.Theme.getColor("main_window_header_button_text_active") onClicked: Qt.openUrlExternally("https://account.ultimaker.com") } diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 52ff99ad9b..474f93afa4 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -86,9 +86,9 @@ UM.MainWindow window: base } - TopHeader + MainWindowHeader { - id: topHeader + id: mainWindowHeader anchors { left: parent.left @@ -103,7 +103,7 @@ UM.MainWindow anchors { - top: topHeader.bottom + top: mainWindowHeader.bottom bottom: parent.bottom left: parent.left right: parent.right @@ -152,7 +152,7 @@ UM.MainWindow } visible: stageMenu.source != "" height: Math.round(UM.Theme.getSize("stage_menu").height / 2) - color: UM.Theme.getColor("topheader_background") + color: UM.Theme.getColor("main_window_header_background") } Loader diff --git a/resources/qml/MainWindow/TopHeader.qml b/resources/qml/MainWindow/MainWindowHeader.qml similarity index 76% rename from resources/qml/MainWindow/TopHeader.qml rename to resources/qml/MainWindow/MainWindowHeader.qml index 867a6bafbb..b90968c606 100644 --- a/resources/qml/MainWindow/TopHeader.qml +++ b/resources/qml/MainWindow/MainWindowHeader.qml @@ -2,7 +2,7 @@ // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 -import QtQuick.Controls 1.1 +import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.1 import UM 1.4 as UM @@ -14,9 +14,9 @@ Rectangle { id: base - implicitHeight: UM.Theme.getSize("topheader").height - implicitWidth: UM.Theme.getSize("topheader").width - color: UM.Theme.getColor("topheader_background") + implicitHeight: UM.Theme.getSize("main_window_header").height + implicitWidth: UM.Theme.getSize("main_window_header").width + color: UM.Theme.getColor("main_window_header_background") Image { @@ -43,7 +43,7 @@ Rectangle leftMargin: UM.Theme.getSize("default_margin").width } - // The topheader is dynamically filled with all available stages + // The main window header is dynamically filled with all available stages Repeater { id: stagesHeader @@ -55,9 +55,9 @@ Rectangle text: model.name.toUpperCase() checkable: true checked: model.active - exclusiveGroup: topheaderMenuGroup - style: UM.Theme.styles.topheader_tab - height: UM.Theme.getSize("topheader").height + exclusiveGroup: mainWindowHeaderMenuGroup + style: UM.Theme.styles.main_window_header_tab + height: UM.Theme.getSize("main_window_header").height onClicked: UM.Controller.setActiveStage(model.id) iconSource: model.stage.iconSource @@ -66,7 +66,7 @@ Rectangle } } - ExclusiveGroup { id: topheaderMenuGroup } + ExclusiveGroup { id: mainWindowHeaderMenuGroup } } // Shortcut button to quick access the Toolbox @@ -83,14 +83,14 @@ Rectangle { background: Rectangle { - color: control.hovered ? UM.Theme.getColor("secondary") : UM.Theme.getColor("topheader_button_background_active") + color: control.hovered ? UM.Theme.getColor("secondary") : UM.Theme.getColor("main_window_header_button_background_active") radius: 2 * screenScaleFactor } label: Label { text: catalog.i18nc("@action:button", "Toolbox") - color: UM.Theme.getColor("topheader_button_text_active") + color: UM.Theme.getColor("main_window_header_button_text_active") font: UM.Theme.getFont("action_button") renderType: Text.NativeRendering } diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 517b69428e..37d851a35d 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -77,8 +77,8 @@ Rectangle UM.RecolorImage { id: buildplateIcon anchors.left: parent.left - width: UM.Theme.getSize("topheader_button_icon").width - height: UM.Theme.getSize("topheader_button_icon").height + width: UM.Theme.getSize("main_window_header_button_icon").width + height: UM.Theme.getSize("main_window_header_button_icon").height sourceSize.width: width sourceSize.height: height source: UM.Theme.getIcon("buildplate") diff --git a/resources/themes/cura-dark/theme.json b/resources/themes/cura-dark/theme.json index 99737ff8bf..897d09ccf2 100644 --- a/resources/themes/cura-dark/theme.json +++ b/resources/themes/cura-dark/theme.json @@ -15,11 +15,10 @@ "border": [127, 127, 127, 255], "secondary": [241, 242, 242, 255], - "topheader_background": [31, 36, 39, 255], - - "topheader_button_text_active": [31, 36, 39, 255], - "topheader_button_text_inactive": [128, 128, 128, 255], - "topheader_button_text_hovered": [255, 255, 255, 255], + "main_window_header_background": [31, 36, 39, 255], + "main_window_header_button_text_active": [31, 36, 39, 255], + "main_window_header_button_text_inactive": [128, 128, 128, 255], + "main_window_header_button_text_hovered": [255, 255, 255, 255], "text": [255, 255, 255, 204], "text_detail": [255, 255, 255, 172], diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index 074ceb4200..e6e5bd7fda 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -96,7 +96,7 @@ QtObject } } - property Component topheader_tab: Component + property Component main_window_header_tab: Component { ButtonStyle { @@ -114,7 +114,7 @@ QtObject anchors.verticalCenter: parent.verticalCenter implicitHeight: parent.height - 2 * UM.Theme.getSize("default_margin").width implicitWidth: UM.Theme.getSize("default_lining").width - color: UM.Theme.getColor("topheader_button_background_active") + color: UM.Theme.getColor("main_window_header_button_background_active") visible: !control.checked } Rectangle @@ -122,7 +122,7 @@ QtObject id: buttonFace implicitHeight: parent.height implicitWidth: parent.width - color: control.checked ? UM.Theme.getColor("topheader_button_background_active") : UM.Theme.getColor("topheader_button_background_inactive") + color: control.checked ? UM.Theme.getColor("main_window_header_button_background_active") : UM.Theme.getColor("main_window_header_button_background_inactive") Behavior on color { ColorAnimation { duration: 50 } } } @@ -132,7 +132,7 @@ QtObject anchors.verticalCenter: parent.verticalCenter implicitHeight: parent.height - 2 * UM.Theme.getSize("default_margin").width implicitWidth: UM.Theme.getSize("default_lining").width - color: UM.Theme.getColor("topheader_button_background_active") + color: UM.Theme.getColor("main_window_header_button_background_active") visible: !control.checked } } @@ -156,15 +156,15 @@ QtObject { if (control.checked) { - return UM.Theme.getColor("topheader_button_text_active"); + return UM.Theme.getColor("main_window_header_button_text_active"); } else { if (control.hovered) { - return UM.Theme.getColor("topheader_button_text_hovered"); + return UM.Theme.getColor("main_window_header_button_text_hovered"); } - return UM.Theme.getColor("topheader_button_text_inactive"); + return UM.Theme.getColor("main_window_header_button_text_inactive"); } } } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index d26c872b00..d72493ec89 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -79,13 +79,12 @@ "border": [127, 127, 127, 255], "secondary": [245, 245, 245, 255], - "topheader_background": [12, 169, 227, 255], - - "topheader_button_text_active": [12, 169, 227, 255], - "topheader_button_text_inactive": [255, 255, 255, 255], - "topheader_button_text_hovered": [0, 0, 0, 255], - "topheader_button_background_active": [255, 255, 255, 255], - "topheader_button_background_inactive": [255, 255, 255, 0], + "main_window_header_background": [12, 169, 227, 255], + "main_window_header_button_text_active": [12, 169, 227, 255], + "main_window_header_button_text_inactive": [255, 255, 255, 255], + "main_window_header_button_text_hovered": [0, 0, 0, 255], + "main_window_header_button_background_active": [255, 255, 255, 255], + "main_window_header_button_background_inactive": [255, 255, 255, 0], "account_widget_outline_active": [9, 140, 188, 255], "account_widget_outline_inactive": [229, 229, 229, 255], @@ -340,9 +339,9 @@ "sizes": { "window_minimum_size": [70, 50], - "topheader": [0.0, 4.5], - "topheader_button": [8, 4], - "topheader_button_icon": [1.2, 1.2], + "main_window_header": [0.0, 4.5], + "main_window_header_button": [8, 4], + "main_window_header_button_icon": [1.2, 1.2], "stage_menu": [0.0, 4.5], From 17b77c58eff28e52f9d070cbc5a80c3dd5fcc4ec Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 19 Oct 2018 17:03:48 +0200 Subject: [PATCH 0059/1292] Make the spacing between the orientation controls be dependent on the theme. --- resources/qml/ViewOrientationControls.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/qml/ViewOrientationControls.qml b/resources/qml/ViewOrientationControls.qml index bf56ef2997..acf75b1b48 100644 --- a/resources/qml/ViewOrientationControls.qml +++ b/resources/qml/ViewOrientationControls.qml @@ -12,9 +12,10 @@ Row { id: viewOrientationControl - spacing: 2 * screenScaleFactor + spacing: UM.Theme.getSize("narrow_margin").width height: childrenRect.height width: childrenRect.width + // #1 3d view Button { From 17732b116935eabf8e61accec56b44f324ea73db Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 19 Oct 2018 17:03:48 +0200 Subject: [PATCH 0060/1292] Make the spacing between the orientation controls be dependent on the theme. Contributes to CURA-5772. --- resources/qml/ViewOrientationControls.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/qml/ViewOrientationControls.qml b/resources/qml/ViewOrientationControls.qml index bf56ef2997..acf75b1b48 100644 --- a/resources/qml/ViewOrientationControls.qml +++ b/resources/qml/ViewOrientationControls.qml @@ -12,9 +12,10 @@ Row { id: viewOrientationControl - spacing: 2 * screenScaleFactor + spacing: UM.Theme.getSize("narrow_margin").width height: childrenRect.height width: childrenRect.width + // #1 3d view Button { From 69fc1e5bfb85b7fc71c1b50b24a03b8ceae54981 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 22 Oct 2018 10:30:06 +0200 Subject: [PATCH 0061/1292] Reuse ActionButton component to create the toolbox shortcut. Contributes to CURA-5784. --- resources/qml/MainWindow/MainWindowHeader.qml | 27 +++++-------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/resources/qml/MainWindow/MainWindowHeader.qml b/resources/qml/MainWindow/MainWindowHeader.qml index b90968c606..3de4dc7865 100644 --- a/resources/qml/MainWindow/MainWindowHeader.qml +++ b/resources/qml/MainWindow/MainWindowHeader.qml @@ -70,33 +70,20 @@ Rectangle } // Shortcut button to quick access the Toolbox - Button + Cura.ActionButton { - id: toolboxShortcutButton anchors { right: accountWidget.left rightMargin: UM.Theme.getSize("default_margin").width verticalCenter: parent.verticalCenter } - style: ButtonStyle - { - background: Rectangle - { - color: control.hovered ? UM.Theme.getColor("secondary") : UM.Theme.getColor("main_window_header_button_background_active") - radius: 2 * screenScaleFactor - } - - label: Label - { - text: catalog.i18nc("@action:button", "Toolbox") - color: UM.Theme.getColor("main_window_header_button_text_active") - font: UM.Theme.getFont("action_button") - renderType: Text.NativeRendering - } - - } - action: Cura.Actions.browsePackages + text: catalog.i18nc("@action:button", "Toolbox") + color: UM.Theme.getColor("main_window_header_button_background_active") + hoverColor: UM.Theme.getColor("secondary") + textColor: UM.Theme.getColor("main_window_header_button_text_active") + textHoverColor: UM.Theme.getColor("main_window_header_button_text_active") + onClicked: Cura.Actions.browsePackages.trigger() } AccountWidget From dbb62f2490c76e482320bbbfe419b91498eee147 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 22 Oct 2018 11:31:19 +0200 Subject: [PATCH 0062/1292] Add default icons for the avatar. Contributes to CURA-5784. --- resources/qml/Account/AccountDetails.qml | 2 +- resources/qml/Account/AccountWidget.qml | 2 +- resources/qml/Account/AvatarImage.qml | 2 +- .../cura-light/images/avatar_default.png | Bin 3115 -> 0 bytes .../cura-light/images/avatar_default.svg | 76 ++++++++++++++++++ .../cura-light/images/avatar_no_user.svg | 76 ++++++++++++++++++ 6 files changed, 155 insertions(+), 3 deletions(-) delete mode 100644 resources/themes/cura-light/images/avatar_default.png create mode 100644 resources/themes/cura-light/images/avatar_default.svg create mode 100644 resources/themes/cura-light/images/avatar_no_user.svg diff --git a/resources/qml/Account/AccountDetails.qml b/resources/qml/Account/AccountDetails.qml index 9cd9b91949..a88fb77956 100644 --- a/resources/qml/Account/AccountDetails.qml +++ b/resources/qml/Account/AccountDetails.qml @@ -21,7 +21,7 @@ Column width: UM.Theme.getSize("avatar_image").width height: UM.Theme.getSize("avatar_image").height anchors.horizontalCenter: parent.horizontalCenter - source: loggedIn ? profile["profile_image_url"] : UM.Theme.getImage("avatar_default") + source: loggedIn ? profile["profile_image_url"] : UM.Theme.getImage("avatar_no_user") outlineColor: loggedIn ? UM.Theme.getColor("account_widget_outline_active") : UM.Theme.getColor("account_widget_outline_inactive") } diff --git a/resources/qml/Account/AccountWidget.qml b/resources/qml/Account/AccountWidget.qml index fc99273119..f54cf366e0 100644 --- a/resources/qml/Account/AccountWidget.qml +++ b/resources/qml/Account/AccountWidget.qml @@ -25,7 +25,7 @@ Button anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter - source: loggedIn ? profile["profile_image_url"] : UM.Theme.getImage("avatar_default") + source: loggedIn ? profile["profile_image_url"] : UM.Theme.getImage("avatar_no_user") outlineColor: loggedIn ? UM.Theme.getColor("account_widget_outline_active") : UM.Theme.getColor("account_widget_outline_inactive") } diff --git a/resources/qml/Account/AvatarImage.qml b/resources/qml/Account/AvatarImage.qml index 21adbcb7c3..c730ef428f 100644 --- a/resources/qml/Account/AvatarImage.qml +++ b/resources/qml/Account/AvatarImage.qml @@ -20,8 +20,8 @@ Item Image { id: profileImage - source: UM.Theme.getImage("avatar_default") anchors.fill: parent + source: UM.Theme.getImage("avatar_default") fillMode: Image.PreserveAspectCrop visible: false } diff --git a/resources/themes/cura-light/images/avatar_default.png b/resources/themes/cura-light/images/avatar_default.png deleted file mode 100644 index 0c306680f721dba0de73fb7be90fe5c548608692..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3115 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 + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/resources/themes/cura-light/images/avatar_no_user.svg b/resources/themes/cura-light/images/avatar_no_user.svg new file mode 100644 index 0000000000..bef9cb52db --- /dev/null +++ b/resources/themes/cura-light/images/avatar_no_user.svg @@ -0,0 +1,76 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + From bf1c23243e3c46a465121b8248483c272be61830 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 24 Oct 2018 09:55:51 +0200 Subject: [PATCH 0063/1292] Modify the styles to match the requirements. Contributes to CURA-5784. --- resources/qml/ActionButton.qml | 7 +++ resources/qml/MainWindow/MainWindowHeader.qml | 18 +++++-- resources/themes/cura-dark/theme.json | 2 - resources/themes/cura-light/images/logo.svg | 12 ++--- resources/themes/cura-light/styles.qml | 47 +++++++++---------- resources/themes/cura-light/theme.json | 18 +++++-- 6 files changed, 61 insertions(+), 43 deletions(-) diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index 44299d3734..a8ad94474e 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -20,6 +20,9 @@ Button property var textColor: UM.Theme.getColor("button_text") property var textHoverColor: UM.Theme.getColor("button_text_hover") property var textDisabledColor: textColor + property var outlineColor: color + property var outlineHoverColor: hoverColor + property var outlineDisabledColor: outlineColor contentItem: Row { @@ -34,6 +37,7 @@ Button color: button.hovered ? button.textHoverColor : button.textColor visible: source != "" anchors.verticalCenter: parent.verticalCenter + Behavior on color { ColorAnimation { duration: 50 } } } Label @@ -53,6 +57,9 @@ Button id: backgroundRect color: button.enabled ? (button.hovered ? button.hoverColor : button.color) : button.disabledColor radius: UM.Theme.getSize("action_button_radius").width + border.width: UM.Theme.getSize("default_lining").width + border.color: button.enabled ? (button.hovered ? button.outlineHoverColor : button.outlineColor) : button.outlineDisabledColor + Behavior on color { ColorAnimation { duration: 50 } } } MouseArea diff --git a/resources/qml/MainWindow/MainWindowHeader.qml b/resources/qml/MainWindow/MainWindowHeader.qml index 3de4dc7865..92d9d8ee26 100644 --- a/resources/qml/MainWindow/MainWindowHeader.qml +++ b/resources/qml/MainWindow/MainWindowHeader.qml @@ -36,10 +36,12 @@ Rectangle Row { id: stagesListContainer + spacing: Math.round(UM.Theme.getSize("default_margin").width / 2) anchors { horizontalCenter: parent.horizontalCenter + verticalCenter: parent.verticalCenter leftMargin: UM.Theme.getSize("default_margin").width } @@ -55,9 +57,10 @@ Rectangle text: model.name.toUpperCase() checkable: true checked: model.active + anchors.verticalCenter: parent.verticalCenter exclusiveGroup: mainWindowHeaderMenuGroup style: UM.Theme.styles.main_window_header_tab - height: UM.Theme.getSize("main_window_header").height + height: Math.round(0.56 * UM.Theme.getSize("main_window_header").height) onClicked: UM.Controller.setActiveStage(model.id) iconSource: model.stage.iconSource @@ -78,11 +81,16 @@ Rectangle rightMargin: UM.Theme.getSize("default_margin").width verticalCenter: parent.verticalCenter } + leftPadding: UM.Theme.getSize("default_margin").width + rightPadding: UM.Theme.getSize("default_margin").width text: catalog.i18nc("@action:button", "Toolbox") - color: UM.Theme.getColor("main_window_header_button_background_active") - hoverColor: UM.Theme.getColor("secondary") - textColor: UM.Theme.getColor("main_window_header_button_text_active") - textHoverColor: UM.Theme.getColor("main_window_header_button_text_active") + height: Math.round(0.5 * UM.Theme.getSize("main_window_header").height) + color: UM.Theme.getColor("main_window_header_secondary_button_background_active") + hoverColor: UM.Theme.getColor("main_window_header_secondary_button_background_hovered") + outlineColor: UM.Theme.getColor("main_window_header_secondary_button_outline_active") + outlineHoverColor: UM.Theme.getColor("main_window_header_secondary_button_outline_hovered") + textColor: UM.Theme.getColor("main_window_header_secondary_button_text_active") + textHoverColor: UM.Theme.getColor("main_window_header_secondary_button_text_hovered") onClicked: Cura.Actions.browsePackages.trigger() } diff --git a/resources/themes/cura-dark/theme.json b/resources/themes/cura-dark/theme.json index 897d09ccf2..1625750a19 100644 --- a/resources/themes/cura-dark/theme.json +++ b/resources/themes/cura-dark/theme.json @@ -15,8 +15,6 @@ "border": [127, 127, 127, 255], "secondary": [241, 242, 242, 255], - "main_window_header_background": [31, 36, 39, 255], - "main_window_header_button_text_active": [31, 36, 39, 255], "main_window_header_button_text_inactive": [128, 128, 128, 255], "main_window_header_button_text_hovered": [255, 255, 255, 255], diff --git a/resources/themes/cura-light/images/logo.svg b/resources/themes/cura-light/images/logo.svg index 89692f8295..55842ef530 100644 --- a/resources/themes/cura-light/images/logo.svg +++ b/resources/themes/cura-light/images/logo.svg @@ -25,11 +25,11 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="0.35" - inkscape:cx="-64.285714" - inkscape:cy="560" + inkscape:zoom="1.979899" + inkscape:cx="97.165681" + inkscape:cy="69.313647" inkscape:document-units="mm" - inkscape:current-layer="layer1" + inkscape:current-layer="g4570" showgrid="false" inkscape:window-width="1920" inkscape:window-height="1137" @@ -45,7 +45,7 @@ image/svg+xml - + @@ -61,7 +61,7 @@ id="polygon4506" points="741.8,410.8 781.7,410.8 801.9,390.6 801.9,350.7 762,350.7 741.8,370.9 " class="st0" - style="fill:#333333" /> + style="fill:#3282ff;fill-opacity:1" /> Date: Wed, 24 Oct 2018 11:28:52 +0200 Subject: [PATCH 0064/1292] Add pointing hand cursor shape when hovering the AccountWidget. Contributes to CURA-5784. --- resources/qml/Account/AccountWidget.qml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/resources/qml/Account/AccountWidget.qml b/resources/qml/Account/AccountWidget.qml index f54cf366e0..eb58d66773 100644 --- a/resources/qml/Account/AccountWidget.qml +++ b/resources/qml/Account/AccountWidget.qml @@ -29,6 +29,15 @@ Button outlineColor: loggedIn ? UM.Theme.getColor("account_widget_outline_active") : UM.Theme.getColor("account_widget_outline_inactive") } + MouseArea + { + id: mouseArea + anchors.fill: parent + onPressed: mouse.accepted = false + hoverEnabled: true + cursorShape: accountWidget.enabled ? (hovered ? Qt.PointingHandCursor : Qt.ArrowCursor) : Qt.ForbiddenCursor + } + background: Item {} onClicked: popup.opened ? popup.close() : popup.open() From 0f5dda72c4eaa8b8824efa68587d1c7452cfeb93 Mon Sep 17 00:00:00 2001 From: Gordon LaPlante Date: Wed, 24 Oct 2018 10:26:01 -0400 Subject: [PATCH 0065/1292] gMax 1.5+ Cura 3.5.1 Config gMax 1.5+ Cura 3.5.1 Config updates --- resources/definitions/gmax15plus.def.json | 15 ++++++++++----- resources/definitions/gmax15plus_dual.def.json | 10 ++++++---- .../extruders/gmax15plus_dual_extruder_0.def.json | 2 +- .../extruders/gmax15plus_dual_extruder_1.def.json | 2 +- ...cfg => gmax15plus_global_dual_normal.inst.cfg} | 3 ++- ....cfg => gmax15plus_global_dual_thick.inst.cfg} | 3 ++- ...t.cfg => gmax15plus_global_dual_thin.inst.cfg} | 3 ++- ...=> gmax15plus_global_dual_very_thick.inst.cfg} | 3 ++- ...inst.cfg => gmax15plus_global_normal.inst.cfg} | 3 +++ ....inst.cfg => gmax15plus_global_thick.inst.cfg} | 3 ++- ...n.inst.cfg => gmax15plus_global_thin.inst.cfg} | 3 ++- ....cfg => gmax15plus_global_very_thick.inst.cfg} | 3 ++- resources/variants/gmax15plus_04_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_05_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_06_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_08_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_10_jhead.inst.cfg | 2 +- ...25_e3d.inst.cfg => gmax15plus_12_e3d.inst.cfg} | 4 ++-- .../variants/gmax15plus_dual_025_e3d.inst.cfg | 13 ------------- .../variants/gmax15plus_dual_04_e3d.inst.cfg | 2 +- .../variants/gmax15plus_dual_10_jhead.inst.cfg | 2 +- 21 files changed, 44 insertions(+), 40 deletions(-) rename resources/quality/gmax15plus/{gmax15plus_pla_dual_normal.inst.cfg => gmax15plus_global_dual_normal.inst.cfg} (96%) rename resources/quality/gmax15plus/{gmax15plus_pla_dual_thick.inst.cfg => gmax15plus_global_dual_thick.inst.cfg} (96%) rename resources/quality/gmax15plus/{gmax15plus_pla_dual_thin.inst.cfg => gmax15plus_global_dual_thin.inst.cfg} (96%) rename resources/quality/gmax15plus/{gmax15plus_pla_dual_very_thick.inst.cfg => gmax15plus_global_dual_very_thick.inst.cfg} (96%) rename resources/quality/gmax15plus/{gmax15plus_pla_normal.inst.cfg => gmax15plus_global_normal.inst.cfg} (98%) rename resources/quality/gmax15plus/{gmax15plus_pla_thick.inst.cfg => gmax15plus_global_thick.inst.cfg} (95%) rename resources/quality/gmax15plus/{gmax15plus_pla_thin.inst.cfg => gmax15plus_global_thin.inst.cfg} (95%) rename resources/quality/gmax15plus/{gmax15plus_pla_very_thick.inst.cfg => gmax15plus_global_very_thick.inst.cfg} (95%) rename resources/variants/{gmax15plus_025_e3d.inst.cfg => gmax15plus_12_e3d.inst.cfg} (71%) delete mode 100644 resources/variants/gmax15plus_dual_025_e3d.inst.cfg diff --git a/resources/definitions/gmax15plus.def.json b/resources/definitions/gmax15plus.def.json index 16695714f4..3196076420 100644 --- a/resources/definitions/gmax15plus.def.json +++ b/resources/definitions/gmax15plus.def.json @@ -10,13 +10,16 @@ "category": "Other", "file_formats": "text/x-gcode", "platform": "gmax_1-5_xt-plus_s3d_full model_150707.stl", - "has_machine_quality": true, + "has_machine_quality": true, "has_variants": true, - "variants_name": "Hotend", - "preferred_variant_name": "0.5mm E3D (Default)", - "machine_extruder_trains": { + "variants_name": "Hotend", + "preferred_variant_name": "*0.5mm E3D (Default)*", + "preferred_quality_type": "gmax15plus_global_normal", + "machine_extruder_trains": { "0": "gmax15plus_extruder_0" } + + }, "overrides": { @@ -27,6 +30,8 @@ "machine_depth": { "default_value": 406 }, "machine_height": { "default_value": 533 }, "machine_center_is_zero": { "default_value": false }, + "material_diameter": { "default_value": 1.75 }, + "machine_nozzle_size": { "default_value": 0.5 }, "layer_height": { "default_value": 0.2 }, "layer_height_0": { "default_value": 0.3 }, "retraction_amount": { "default_value": 1 }, @@ -43,7 +48,7 @@ "machine_max_jerk_z": { "default_value": 0.4 }, "machine_max_jerk_e": { "default_value": 5.0 }, "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" }, - "machine_start_gcode": { "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 ;Home X/Y/Z\nG29 ; Bed level\nM104 S{material_print_temperature} ; Preheat\nM109 S{material_print_temperature} ; Preheat\nG91 ;relative positioning\nG90 ;absolute positioning\nG1 Z25.0 F9000 ;raise nozzle 25mm\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." }, + "machine_start_gcode": { "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 ;Home X/Y/Z\nM104 S{material_print_temperature} ; Preheat\nM109 S{material_print_temperature} ; Preheat\nG91 ;relative positioning\nG90 ;absolute positioning\nG1 Z25.0 F9000 ;raise nozzle 25mm\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." }, "machine_end_gcode": { "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" }, "material_print_temperature": { "default_value": 202 }, "wall_thickness": { "default_value": 1 }, diff --git a/resources/definitions/gmax15plus_dual.def.json b/resources/definitions/gmax15plus_dual.def.json index 5972061933..634ce2b3b8 100644 --- a/resources/definitions/gmax15plus_dual.def.json +++ b/resources/definitions/gmax15plus_dual.def.json @@ -11,13 +11,13 @@ "file_formats": "text/x-gcode", "platform": "gmax_1-5_xt-plus_s3d_full model_150707.stl", "has_variants": true, - "has_machine_quality": true, "variants_name": "Hotend", - "preferred_variant_name": "0.5mm E3D (Default)", + "preferred_variant_name": "*0.5mm E3D (Default)*", + "preferred_quality_type": "gmax15plus_global_dual_normal", "machine_extruder_trains": { "0": "gmax15plus_dual_extruder_0", "1": "gmax15plus_dual_extruder_1" - } + } }, "overrides": { @@ -28,6 +28,8 @@ "machine_depth": { "default_value": 406 }, "machine_height": { "default_value": 533 }, "machine_center_is_zero": { "default_value": false }, + "material_diameter": { "default_value": 1.75 }, + "machine_nozzle_size": { "default_value": 0.5 }, "layer_height": { "default_value": 0.2 }, "layer_height_0": { "default_value": 0.3 }, "retraction_amount": { "default_value": 1 }, @@ -44,7 +46,7 @@ "machine_max_jerk_z": { "default_value": 0.4 }, "machine_max_jerk_e": { "default_value": 5.0 }, "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" }, - "machine_start_gcode": { "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 ;Home X/Y/Z\nG29 ; Bed level\nM104 S{material_print_temperature} T0 ; Preheat Left Extruder\nM104 S{material_print_temperature} T1 ; Preheat Right Extruder\nM109 S{material_print_temperature} T0 ; Preheat Left Extruder\nM109 S{material_print_temperature} T1 ; Preheat Right Extruder\nG91 ;relative positioning\nG90 ;absolute positioning\nM218 T1 X34.3 Y0; Set 2nd extruder offset. This can be changed later if needed\nG1 Z25.0 F9000 ;raise nozzle 25mm\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." }, + "machine_start_gcode": { "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 ;Home X/Y/Z\nM104 S{material_print_temperature} T0 ; Preheat Left Extruder\nM104 S{material_print_temperature} T1 ; Preheat Right Extruder\nM109 S{material_print_temperature} T0 ; Preheat Left Extruder\nM109 S{material_print_temperature} T1 ; Preheat Right Extruder\nG91 ;relative positioning\nG90 ;absolute positioning\nM218 T1 X34.3 Y0; Set 2nd extruder offset. This can be changed later if needed\nG1 Z25.0 F9000 ;raise nozzle 25mm\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." }, "machine_end_gcode": { "default_value": "M104 S0 T0;Left extruder off\nM104 S0 T1; Right extruder off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" }, "material_print_temperature": { "default_value": 202 }, "wall_thickness": { "default_value": 1 }, diff --git a/resources/extruders/gmax15plus_dual_extruder_0.def.json b/resources/extruders/gmax15plus_dual_extruder_0.def.json index b490f4a40e..524fa72f9f 100644 --- a/resources/extruders/gmax15plus_dual_extruder_0.def.json +++ b/resources/extruders/gmax15plus_dual_extruder_0.def.json @@ -16,7 +16,7 @@ "machine_nozzle_offset_x": { "default_value": 0.0 }, "machine_nozzle_offset_y": { "default_value": 0.0 }, "machine_nozzle_size": { "default_value": 0.5 }, - "material_diameter": { "default_value": 1.75 }, + "material_diameter": { "default_value": 1.75 }, "machine_extruder_start_pos_abs": { "default_value": true }, "machine_extruder_start_pos_x": { "value": 40 }, diff --git a/resources/extruders/gmax15plus_dual_extruder_1.def.json b/resources/extruders/gmax15plus_dual_extruder_1.def.json index ad3c628d6f..1b9f7bda5f 100644 --- a/resources/extruders/gmax15plus_dual_extruder_1.def.json +++ b/resources/extruders/gmax15plus_dual_extruder_1.def.json @@ -16,7 +16,7 @@ "machine_nozzle_offset_x": { "default_value": 0.0 }, "machine_nozzle_offset_y": { "default_value": 0.0 }, "machine_nozzle_size": { "default_value": 0.5 }, - "material_diameter": { "default_value": 1.75 }, + "material_diameter": { "default_value": 1.75 }, "machine_extruder_start_pos_abs": { "default_value": true }, "machine_extruder_start_pos_x": { "value": 40 }, diff --git a/resources/quality/gmax15plus/gmax15plus_pla_dual_normal.inst.cfg b/resources/quality/gmax15plus/gmax15plus_global_dual_normal.inst.cfg similarity index 96% rename from resources/quality/gmax15plus/gmax15plus_pla_dual_normal.inst.cfg rename to resources/quality/gmax15plus/gmax15plus_global_dual_normal.inst.cfg index 7fd2ab2296..5dea12d308 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_dual_normal.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_global_dual_normal.inst.cfg @@ -8,6 +8,7 @@ setting_version = 5 type = quality quality_type = normal weight = -1 +global_quality = True [values] layer_height = 0.2 @@ -64,7 +65,7 @@ ooze_shield_enabled = True prime_tower_enable = False prime_tower_position_x = 350 prime_tower_position_y = 350 -prime_tower_min_volume = 18 +prime_tower_wall_thickness = 2 switch_extruder_retraction_amount = 6 switch_extruder_retraction_speeds = 60 diff --git a/resources/quality/gmax15plus/gmax15plus_pla_dual_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_global_dual_thick.inst.cfg similarity index 96% rename from resources/quality/gmax15plus/gmax15plus_pla_dual_thick.inst.cfg rename to resources/quality/gmax15plus/gmax15plus_global_dual_thick.inst.cfg index 30a99ef243..de374e3a9f 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_dual_thick.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_global_dual_thick.inst.cfg @@ -8,6 +8,7 @@ setting_version = 5 type = quality quality_type = course weight = -2 +global_quality = True [values] layer_height = 0.28 @@ -64,7 +65,7 @@ ooze_shield_enabled = True prime_tower_enable = False prime_tower_position_x = 350 prime_tower_position_y = 350 -prime_tower_min_volume = 18 +prime_tower_wall_thickness = 2 switch_extruder_retraction_amount = 6 switch_extruder_retraction_speeds = 60 diff --git a/resources/quality/gmax15plus/gmax15plus_pla_dual_thin.inst.cfg b/resources/quality/gmax15plus/gmax15plus_global_dual_thin.inst.cfg similarity index 96% rename from resources/quality/gmax15plus/gmax15plus_pla_dual_thin.inst.cfg rename to resources/quality/gmax15plus/gmax15plus_global_dual_thin.inst.cfg index decafac241..f36ed38c00 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_dual_thin.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_global_dual_thin.inst.cfg @@ -8,6 +8,7 @@ setting_version = 5 type = quality quality_type = high weight = 0 +global_quality = True [values] layer_height = 0.16 @@ -64,7 +65,7 @@ ooze_shield_enabled = True prime_tower_enable = False prime_tower_position_x = 350 prime_tower_position_y = 350 -prime_tower_min_volume = 18 +prime_tower_wall_thickness = 2 switch_extruder_retraction_amount = 6 switch_extruder_retraction_speeds = 60 diff --git a/resources/quality/gmax15plus/gmax15plus_pla_dual_very_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_global_dual_very_thick.inst.cfg similarity index 96% rename from resources/quality/gmax15plus/gmax15plus_pla_dual_very_thick.inst.cfg rename to resources/quality/gmax15plus/gmax15plus_global_dual_very_thick.inst.cfg index a74bdfdd78..2ce55450dd 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_dual_very_thick.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_global_dual_very_thick.inst.cfg @@ -8,6 +8,7 @@ setting_version = 5 type = quality quality_type = extra_course weight = -3 +global_quality = True [values] layer_height = 0.32 @@ -63,7 +64,7 @@ ooze_shield_enabled = True prime_tower_enable = False prime_tower_position_x = 350 prime_tower_position_y = 350 -prime_tower_min_volume = 18 +prime_tower_wall_thickness = 2 switch_extruder_retraction_amount = 6 switch_extruder_retraction_speeds = 60 diff --git a/resources/quality/gmax15plus/gmax15plus_pla_normal.inst.cfg b/resources/quality/gmax15plus/gmax15plus_global_normal.inst.cfg similarity index 98% rename from resources/quality/gmax15plus/gmax15plus_pla_normal.inst.cfg rename to resources/quality/gmax15plus/gmax15plus_global_normal.inst.cfg index ddf5a4c491..1f7203a03b 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_normal.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_global_normal.inst.cfg @@ -8,6 +8,7 @@ setting_version = 5 type = quality quality_type = normal weight = -1 +global_quality = True [values] layer_height = 0.2 @@ -57,3 +58,5 @@ top_thickness = 1 bottom_layers = 2 wall_line_count = 2 z_seam_corner = z_seam_corner_none + + diff --git a/resources/quality/gmax15plus/gmax15plus_pla_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_global_thick.inst.cfg similarity index 95% rename from resources/quality/gmax15plus/gmax15plus_pla_thick.inst.cfg rename to resources/quality/gmax15plus/gmax15plus_global_thick.inst.cfg index e6cb2b5854..8b01d1a166 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_thick.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_global_thick.inst.cfg @@ -8,6 +8,7 @@ setting_version = 5 type = quality quality_type = course weight = -2 +global_quality = True [values] layer_height = 0.28 @@ -56,4 +57,4 @@ top_layers = 3 top_thickness = 1 bottom_layers = 2 wall_line_count = 2 -z_seam_corner = z_seam_corner_none +z_seam_corner = z_seam_corner_none \ No newline at end of file diff --git a/resources/quality/gmax15plus/gmax15plus_pla_thin.inst.cfg b/resources/quality/gmax15plus/gmax15plus_global_thin.inst.cfg similarity index 95% rename from resources/quality/gmax15plus/gmax15plus_pla_thin.inst.cfg rename to resources/quality/gmax15plus/gmax15plus_global_thin.inst.cfg index d119539d32..a06fd24ea7 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_thin.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_global_thin.inst.cfg @@ -8,6 +8,7 @@ setting_version = 5 type = quality quality_type = high weight = 0 +global_quality = True [values] layer_height = 0.16 @@ -56,4 +57,4 @@ top_layers = 5 top_thickness = 1 bottom_layers = 3 wall_line_count = 2 -z_seam_corner = z_seam_corner_none +z_seam_corner = z_seam_corner_none \ No newline at end of file diff --git a/resources/quality/gmax15plus/gmax15plus_pla_very_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_global_very_thick.inst.cfg similarity index 95% rename from resources/quality/gmax15plus/gmax15plus_pla_very_thick.inst.cfg rename to resources/quality/gmax15plus/gmax15plus_global_very_thick.inst.cfg index 884029a4ae..36f78673c2 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_very_thick.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_global_very_thick.inst.cfg @@ -8,6 +8,7 @@ setting_version = 5 type = quality quality_type = extra_course weight = -3 +global_quality = True [values] layer_height = 0.32 @@ -55,4 +56,4 @@ top_layers = 3 top_thickness = 1 bottom_layers = 2 wall_line_count = 2 -z_seam_corner = z_seam_corner_none +z_seam_corner = z_seam_corner_none \ No newline at end of file diff --git a/resources/variants/gmax15plus_04_e3d.inst.cfg b/resources/variants/gmax15plus_04_e3d.inst.cfg index a2f779f426..48fe7ada16 100644 --- a/resources/variants/gmax15plus_04_e3d.inst.cfg +++ b/resources/variants/gmax15plus_04_e3d.inst.cfg @@ -10,4 +10,4 @@ type = variant hardware_type = nozzle [values] -machine_nozzle_size = 0.4 +machine_nozzle_size = 0.4 \ No newline at end of file diff --git a/resources/variants/gmax15plus_05_e3d.inst.cfg b/resources/variants/gmax15plus_05_e3d.inst.cfg index 68ee111aa1..0bb9517da8 100644 --- a/resources/variants/gmax15plus_05_e3d.inst.cfg +++ b/resources/variants/gmax15plus_05_e3d.inst.cfg @@ -10,4 +10,4 @@ type = variant hardware_type = nozzle [values] -machine_nozzle_size = 0.5 +machine_nozzle_size = 0.5 \ No newline at end of file diff --git a/resources/variants/gmax15plus_06_e3d.inst.cfg b/resources/variants/gmax15plus_06_e3d.inst.cfg index 987e882a09..3a372b20c9 100644 --- a/resources/variants/gmax15plus_06_e3d.inst.cfg +++ b/resources/variants/gmax15plus_06_e3d.inst.cfg @@ -10,4 +10,4 @@ type = variant hardware_type = nozzle [values] -machine_nozzle_size = 0.6 +machine_nozzle_size = 0.6 \ No newline at end of file diff --git a/resources/variants/gmax15plus_08_e3d.inst.cfg b/resources/variants/gmax15plus_08_e3d.inst.cfg index bf59b47da0..39eeef748e 100644 --- a/resources/variants/gmax15plus_08_e3d.inst.cfg +++ b/resources/variants/gmax15plus_08_e3d.inst.cfg @@ -10,4 +10,4 @@ type = variant hardware_type = nozzle [values] -machine_nozzle_size = 0.8 +machine_nozzle_size = 0.8 \ No newline at end of file diff --git a/resources/variants/gmax15plus_10_jhead.inst.cfg b/resources/variants/gmax15plus_10_jhead.inst.cfg index 47355f344c..37d2546d2a 100644 --- a/resources/variants/gmax15plus_10_jhead.inst.cfg +++ b/resources/variants/gmax15plus_10_jhead.inst.cfg @@ -10,4 +10,4 @@ type = variant hardware_type = nozzle [values] -machine_nozzle_size = 0.5 +machine_nozzle_size = 0.5 \ No newline at end of file diff --git a/resources/variants/gmax15plus_025_e3d.inst.cfg b/resources/variants/gmax15plus_12_e3d.inst.cfg similarity index 71% rename from resources/variants/gmax15plus_025_e3d.inst.cfg rename to resources/variants/gmax15plus_12_e3d.inst.cfg index 8a6b37067d..57052dd0f8 100644 --- a/resources/variants/gmax15plus_025_e3d.inst.cfg +++ b/resources/variants/gmax15plus_12_e3d.inst.cfg @@ -1,5 +1,5 @@ [general] -name = 0.25mm E3D (Difficult) +name = 1.2mm E3D Volcano version = 4 definition = gmax15plus @@ -10,4 +10,4 @@ type = variant hardware_type = nozzle [values] -machine_nozzle_size = 0.25 +machine_nozzle_size = 1.2 \ No newline at end of file diff --git a/resources/variants/gmax15plus_dual_025_e3d.inst.cfg b/resources/variants/gmax15plus_dual_025_e3d.inst.cfg deleted file mode 100644 index 750a5381b3..0000000000 --- a/resources/variants/gmax15plus_dual_025_e3d.inst.cfg +++ /dev/null @@ -1,13 +0,0 @@ -[general] -name = 0.25mm E3D (Difficult) -version = 4 -definition = gmax15plus_dual - -[metadata] -author = gcreate -setting_version = 5 -type = variant -hardware_type = nozzle - -[values] -machine_nozzle_size = 0.25 diff --git a/resources/variants/gmax15plus_dual_04_e3d.inst.cfg b/resources/variants/gmax15plus_dual_04_e3d.inst.cfg index 4b5a71c53b..809227a62c 100644 --- a/resources/variants/gmax15plus_dual_04_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_04_e3d.inst.cfg @@ -10,4 +10,4 @@ type = variant hardware_type = nozzle [values] -machine_nozzle_size = 0.4 +machine_nozzle_size = 0.4 \ No newline at end of file diff --git a/resources/variants/gmax15plus_dual_10_jhead.inst.cfg b/resources/variants/gmax15plus_dual_10_jhead.inst.cfg index cf615bb874..ee0c8fa948 100644 --- a/resources/variants/gmax15plus_dual_10_jhead.inst.cfg +++ b/resources/variants/gmax15plus_dual_10_jhead.inst.cfg @@ -10,4 +10,4 @@ type = variant hardware_type = nozzle [values] -machine_nozzle_size = 0.5 +machine_nozzle_size = 1.0 From e64698209c22b65bb556a042f935db73fcb2df0f Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 25 Oct 2018 17:41:35 +0200 Subject: [PATCH 0066/1292] Adjust the minimum size to be something around 1280x1024. Also adjust some colors color for the dark theme. Contributes to CURA-5772. --- plugins/PrepareStage/PrepareMenu.qml | 6 +++--- .../{ProgressAndSaveWidget.qml => ActionPanelWidget.qml} | 6 ++++-- resources/qml/Cura.qml | 3 ++- resources/qml/qmldir | 3 ++- resources/themes/cura-light/theme.json | 2 +- 5 files changed, 12 insertions(+), 8 deletions(-) rename resources/qml/{ProgressAndSaveWidget.qml => ActionPanelWidget.qml} (98%) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index 8d0f03ec2f..f08de9d317 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -46,7 +46,7 @@ Item Cura.MachineSelector { id: machineSelection - width: UM.Theme.getSize("sidebar").width + width: Math.round(0.8 * UM.Theme.getSize("sidebar").width) - configSelection.width height: prepareMenu.height } @@ -54,8 +54,8 @@ Item { id: configSelection visible: isNetworkPrinter && printerConnected - width: visible ? Math.round(machineSelection.width * 0.15) : 0 - panelWidth: machineSelection.width + width: visible ? Math.round(UM.Theme.getSize("sidebar").width * 0.15) : 0 + panelWidth: Math.round(0.8 * UM.Theme.getSize("sidebar").width) height: prepareMenu.height } diff --git a/resources/qml/ProgressAndSaveWidget.qml b/resources/qml/ActionPanelWidget.qml similarity index 98% rename from resources/qml/ProgressAndSaveWidget.qml rename to resources/qml/ActionPanelWidget.qml index 6e8eb59482..02ac154178 100644 --- a/resources/qml/ProgressAndSaveWidget.qml +++ b/resources/qml/ActionPanelWidget.qml @@ -19,7 +19,9 @@ Rectangle signal showTooltip(Item item, point location, string text) signal hideTooltip() - // Also add an extra margin, as we ant some breathing room around the edges. + color: UM.Theme.getColor("sidebar") + + // Also add an extra margin, as we want some breathing room around the edges. height: saveButton.height + UM.Theme.getSize("sidebar_margin").height Label { @@ -231,7 +233,7 @@ Rectangle { id: saveButton width: parent.width - height: 100 + height: 100 * screenScaleFactor anchors.bottom: parent.bottom } } \ No newline at end of file diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 474f93afa4..c5abb0f107 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -291,6 +291,7 @@ UM.MainWindow onActiveViewChanged: viewModeButton.updateItemActiveFlags() } } + Loader { id: viewPanel @@ -307,7 +308,7 @@ UM.MainWindow source: UM.ActiveView.valid ? UM.ActiveView.activeViewPanel : "" } - ProgressAndSaveWidget + Cura.ActionPanelWidget { anchors.right: parent.right anchors.bottom: parent.bottom diff --git a/resources/qml/qmldir b/resources/qml/qmldir index 2681da00e1..0e5e316409 100644 --- a/resources/qml/qmldir +++ b/resources/qml/qmldir @@ -6,4 +6,5 @@ CustomConfigurationSelector 1.0 CustomConfigurationSelector.qml PrintSetupSelector 1.0 PrintSetupSelector.qml ActionButton 1.0 ActionButton.qml MaterialMenu 1.0 MaterialMenu.qml -NozzleMenu 1.0 NozzleMenu.qml \ No newline at end of file +NozzleMenu 1.0 NozzleMenu.qml +ActionPanelWidget 1.0 ActionPanelWidget.qml \ No newline at end of file diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 68ea9b88f8..1820ead338 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -345,7 +345,7 @@ }, "sizes": { - "window_minimum_size": [70, 50], + "window_minimum_size": [106, 85], "main_window_header": [0.0, 4.5], "main_window_header_button": [8, 4], From 7eedbb6b07ca9a14c76aed521f9b304f7e0c283e Mon Sep 17 00:00:00 2001 From: Gordon LaPlante Date: Thu, 25 Oct 2018 13:48:35 -0400 Subject: [PATCH 0067/1292] Updates Per Cura Comments gMax 1.5+ Config, updates per comments --- resources/definitions/gmax15plus.def.json | 20 ++++++++--------- .../definitions/gmax15plus_dual.def.json | 22 +++++++++---------- .../gmax15plus_dual_extruder_0.def.json | 8 +++---- .../gmax15plus_dual_extruder_1.def.json | 8 +++---- .../gmax15plus_global_dual_normal.inst.cfg | 1 - .../gmax15plus_global_dual_thick.inst.cfg | 1 - .../gmax15plus_global_dual_thin.inst.cfg | 1 - ...gmax15plus_global_dual_very_thick.inst.cfg | 1 - .../variants/gmax15plus_025_e3d.inst.cfg | 13 +++++++++++ .../variants/gmax15plus_dual_025_e3d.inst.cfg | 13 +++++++++++ 10 files changed, 55 insertions(+), 33 deletions(-) create mode 100644 resources/variants/gmax15plus_025_e3d.inst.cfg create mode 100644 resources/variants/gmax15plus_dual_025_e3d.inst.cfg diff --git a/resources/definitions/gmax15plus.def.json b/resources/definitions/gmax15plus.def.json index 3196076420..069b8be999 100644 --- a/resources/definitions/gmax15plus.def.json +++ b/resources/definitions/gmax15plus.def.json @@ -10,20 +10,20 @@ "category": "Other", "file_formats": "text/x-gcode", "platform": "gmax_1-5_xt-plus_s3d_full model_150707.stl", - "has_machine_quality": true, + "has_machine_quality": true, "has_variants": true, - "variants_name": "Hotend", - "preferred_variant_name": "*0.5mm E3D (Default)*", - "preferred_quality_type": "gmax15plus_global_normal", - "machine_extruder_trains": { + "variants_name": "Hotend", + "preferred_variant_name": "0.5mm E3D (Default)", + "preferred_quality_type": "gmax15plus_global_normal", + "machine_extruder_trains": { "0": "gmax15plus_extruder_0" } - + }, "overrides": { - "machine_extruder_count": { "default_value": 1 }, + "machine_extruder_count": { "default_value": 1 }, "machine_name": { "default_value": "gMax 1.5 Plus" }, "machine_heated_bed": { "default_value": false }, "machine_width": { "default_value": 406 }, @@ -48,10 +48,10 @@ "machine_max_jerk_z": { "default_value": 0.4 }, "machine_max_jerk_e": { "default_value": 5.0 }, "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" }, - "machine_start_gcode": { "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 ;Home X/Y/Z\nM104 S{material_print_temperature} ; Preheat\nM109 S{material_print_temperature} ; Preheat\nG91 ;relative positioning\nG90 ;absolute positioning\nG1 Z25.0 F9000 ;raise nozzle 25mm\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." }, + "machine_start_gcode": { "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 ;Home X/Y/Z\nM104 S{material_print_temperature} ; Preheat\nM109 S{material_print_temperature} ; Preheat\nG91 ;relative positioning\nG90 ;absolute positioning\nG1 Z25.0 F9000 ;raise nozzle 25mm\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." }, "machine_end_gcode": { "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" }, - "material_print_temperature": { "default_value": 202 }, - "wall_thickness": { "default_value": 1 }, + "material_print_temperature": { "default_value": 202 }, + "wall_thickness": { "default_value": 1 }, "top_bottom_thickness": { "default_value": 1 }, "bottom_thickness": { "default_value": 1 } } diff --git a/resources/definitions/gmax15plus_dual.def.json b/resources/definitions/gmax15plus_dual.def.json index 634ce2b3b8..0264ef5977 100644 --- a/resources/definitions/gmax15plus_dual.def.json +++ b/resources/definitions/gmax15plus_dual.def.json @@ -10,19 +10,19 @@ "category": "Other", "file_formats": "text/x-gcode", "platform": "gmax_1-5_xt-plus_s3d_full model_150707.stl", - "has_variants": true, - "variants_name": "Hotend", - "preferred_variant_name": "*0.5mm E3D (Default)*", - "preferred_quality_type": "gmax15plus_global_dual_normal", - "machine_extruder_trains": { - "0": "gmax15plus_dual_extruder_0", - "1": "gmax15plus_dual_extruder_1" - } + "has_variants": true, + "variants_name": "Hotend", + "preferred_variant_name": "0.5mm E3D (Default)", + "preferred_quality_type": "gmax15plus_global_dual_normal", + "machine_extruder_trains": { + "0": "gmax15plus_dual_extruder_0", + "1": "gmax15plus_dual_extruder_1" + } }, "overrides": { "machine_name": { "default_value": "gMax 1.5 Plus Dual Extruder" }, - "machine_extruder_count": { "default_value": 2 }, + "machine_extruder_count": { "default_value": 2 }, "machine_heated_bed": { "default_value": false }, "machine_width": { "default_value": 406 }, "machine_depth": { "default_value": 406 }, @@ -48,8 +48,8 @@ "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" }, "machine_start_gcode": { "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 ;Home X/Y/Z\nM104 S{material_print_temperature} T0 ; Preheat Left Extruder\nM104 S{material_print_temperature} T1 ; Preheat Right Extruder\nM109 S{material_print_temperature} T0 ; Preheat Left Extruder\nM109 S{material_print_temperature} T1 ; Preheat Right Extruder\nG91 ;relative positioning\nG90 ;absolute positioning\nM218 T1 X34.3 Y0; Set 2nd extruder offset. This can be changed later if needed\nG1 Z25.0 F9000 ;raise nozzle 25mm\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." }, "machine_end_gcode": { "default_value": "M104 S0 T0;Left extruder off\nM104 S0 T1; Right extruder off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" }, - "material_print_temperature": { "default_value": 202 }, - "wall_thickness": { "default_value": 1 }, + "material_print_temperature": { "default_value": 202 }, + "wall_thickness": { "default_value": 1 }, "top_bottom_thickness": { "default_value": 1 }, "bottom_thickness": { "default_value": 1 } } diff --git a/resources/extruders/gmax15plus_dual_extruder_0.def.json b/resources/extruders/gmax15plus_dual_extruder_0.def.json index 524fa72f9f..d3146a0576 100644 --- a/resources/extruders/gmax15plus_dual_extruder_0.def.json +++ b/resources/extruders/gmax15plus_dual_extruder_0.def.json @@ -15,10 +15,10 @@ }, "machine_nozzle_offset_x": { "default_value": 0.0 }, "machine_nozzle_offset_y": { "default_value": 0.0 }, - "machine_nozzle_size": { "default_value": 0.5 }, - "material_diameter": { "default_value": 1.75 }, - - "machine_extruder_start_pos_abs": { "default_value": true }, + "machine_nozzle_size": { "default_value": 0.5 }, + "material_diameter": { "default_value": 1.75 }, + + "machine_extruder_start_pos_abs": { "default_value": true }, "machine_extruder_start_pos_x": { "value": 40 }, "machine_extruder_start_pos_y": { "value": 210 }, "machine_extruder_end_pos_abs": { "default_value": true }, diff --git a/resources/extruders/gmax15plus_dual_extruder_1.def.json b/resources/extruders/gmax15plus_dual_extruder_1.def.json index 1b9f7bda5f..7b7354d794 100644 --- a/resources/extruders/gmax15plus_dual_extruder_1.def.json +++ b/resources/extruders/gmax15plus_dual_extruder_1.def.json @@ -15,10 +15,10 @@ }, "machine_nozzle_offset_x": { "default_value": 0.0 }, "machine_nozzle_offset_y": { "default_value": 0.0 }, - "machine_nozzle_size": { "default_value": 0.5 }, - "material_diameter": { "default_value": 1.75 }, - - "machine_extruder_start_pos_abs": { "default_value": true }, + "machine_nozzle_size": { "default_value": 0.5 }, + "material_diameter": { "default_value": 1.75 }, + + "machine_extruder_start_pos_abs": { "default_value": true }, "machine_extruder_start_pos_x": { "value": 40 }, "machine_extruder_start_pos_y": { "value": 210 }, "machine_extruder_end_pos_abs": { "default_value": true }, diff --git a/resources/quality/gmax15plus/gmax15plus_global_dual_normal.inst.cfg b/resources/quality/gmax15plus/gmax15plus_global_dual_normal.inst.cfg index 5dea12d308..743311bb54 100644 --- a/resources/quality/gmax15plus/gmax15plus_global_dual_normal.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_global_dual_normal.inst.cfg @@ -65,7 +65,6 @@ ooze_shield_enabled = True prime_tower_enable = False prime_tower_position_x = 350 prime_tower_position_y = 350 -prime_tower_wall_thickness = 2 switch_extruder_retraction_amount = 6 switch_extruder_retraction_speeds = 60 diff --git a/resources/quality/gmax15plus/gmax15plus_global_dual_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_global_dual_thick.inst.cfg index de374e3a9f..94a15bfa2b 100644 --- a/resources/quality/gmax15plus/gmax15plus_global_dual_thick.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_global_dual_thick.inst.cfg @@ -65,7 +65,6 @@ ooze_shield_enabled = True prime_tower_enable = False prime_tower_position_x = 350 prime_tower_position_y = 350 -prime_tower_wall_thickness = 2 switch_extruder_retraction_amount = 6 switch_extruder_retraction_speeds = 60 diff --git a/resources/quality/gmax15plus/gmax15plus_global_dual_thin.inst.cfg b/resources/quality/gmax15plus/gmax15plus_global_dual_thin.inst.cfg index f36ed38c00..534f646205 100644 --- a/resources/quality/gmax15plus/gmax15plus_global_dual_thin.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_global_dual_thin.inst.cfg @@ -65,7 +65,6 @@ ooze_shield_enabled = True prime_tower_enable = False prime_tower_position_x = 350 prime_tower_position_y = 350 -prime_tower_wall_thickness = 2 switch_extruder_retraction_amount = 6 switch_extruder_retraction_speeds = 60 diff --git a/resources/quality/gmax15plus/gmax15plus_global_dual_very_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_global_dual_very_thick.inst.cfg index 2ce55450dd..a35e951c32 100644 --- a/resources/quality/gmax15plus/gmax15plus_global_dual_very_thick.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_global_dual_very_thick.inst.cfg @@ -64,7 +64,6 @@ ooze_shield_enabled = True prime_tower_enable = False prime_tower_position_x = 350 prime_tower_position_y = 350 -prime_tower_wall_thickness = 2 switch_extruder_retraction_amount = 6 switch_extruder_retraction_speeds = 60 diff --git a/resources/variants/gmax15plus_025_e3d.inst.cfg b/resources/variants/gmax15plus_025_e3d.inst.cfg new file mode 100644 index 0000000000..f106b13be1 --- /dev/null +++ b/resources/variants/gmax15plus_025_e3d.inst.cfg @@ -0,0 +1,13 @@ +[general] +name = 0.25mm E3D (Difficult) +version = 2 +definition = gmax15plus + +[metadata] +author = gcreate +setting_version = 5 +type = variant +hardware_type = nozzle + +[values] +machine_nozzle_size = 0.25 diff --git a/resources/variants/gmax15plus_dual_025_e3d.inst.cfg b/resources/variants/gmax15plus_dual_025_e3d.inst.cfg new file mode 100644 index 0000000000..d5f6457902 --- /dev/null +++ b/resources/variants/gmax15plus_dual_025_e3d.inst.cfg @@ -0,0 +1,13 @@ +[general] +name = 0.25mm E3D (Difficult) +version = 2 +definition = gmax15plus_dual + +[metadata] +author = gcreate +setting_version = 5 +type = variant +hardware_type = nozzle + +[values] +machine_nozzle_size = 0.25 From a8531a335dda730bc07b71620f1123d73b1c939e Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 26 Oct 2018 09:52:02 +0200 Subject: [PATCH 0068/1292] Fix the alignments for the sliders in the simulation view. Contributes to CURA-5772. --- plugins/SimulationView/LayerSlider.qml | 6 ++--- plugins/SimulationView/SimulationView.qml | 29 ++++++++++++++--------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/plugins/SimulationView/LayerSlider.qml b/plugins/SimulationView/LayerSlider.qml index 1552506969..c30ea621c4 100644 --- a/plugins/SimulationView/LayerSlider.qml +++ b/plugins/SimulationView/LayerSlider.qml @@ -167,7 +167,7 @@ Item id: rangleHandleLabel height: sliderRoot.handleSize + UM.Theme.getSize("default_margin").height - x: parent.x - width - UM.Theme.getSize("default_margin").width + x: parent.x + parent.width + UM.Theme.getSize("default_margin").width anchors.verticalCenter: parent.verticalCenter target: Qt.point(sliderRoot.width, y + height / 2) visible: sliderRoot.activeHandle == parent @@ -275,7 +275,7 @@ Item id: upperHandleLabel height: sliderRoot.handleSize + UM.Theme.getSize("default_margin").height - x: parent.x - width - UM.Theme.getSize("default_margin").width + x: parent.x + parent.width + UM.Theme.getSize("default_margin").width anchors.verticalCenter: parent.verticalCenter target: Qt.point(sliderRoot.width, y + height / 2) visible: sliderRoot.activeHandle == parent @@ -385,7 +385,7 @@ Item id: lowerHandleLabel height: sliderRoot.handleSize + UM.Theme.getSize("default_margin").height - x: parent.x - width - UM.Theme.getSize("default_margin").width + x: parent.x + parent.width + UM.Theme.getSize("default_margin").width anchors.verticalCenter: parent.verticalCenter target: Qt.point(sliderRoot.width, y + height / 2) visible: sliderRoot.activeHandle == parent diff --git a/plugins/SimulationView/SimulationView.qml b/plugins/SimulationView/SimulationView.qml index be124157fb..7a83a07ac1 100644 --- a/plugins/SimulationView/SimulationView.qml +++ b/plugins/SimulationView/SimulationView.qml @@ -588,13 +588,14 @@ Item id: slidersBox width: parent.width + height: parent.height visible: UM.SimulationView.layerActivity && CuraApplication.platformActivity anchors { - top: parent.bottom - topMargin: UM.Theme.getSize("slider_layerview_margin").height - left: parent.left + top: parent.top + leftMargin: UM.Theme.getSize("slider_layerview_margin").height + left: parent.right } PathSlider @@ -602,9 +603,13 @@ Item id: pathSlider height: UM.Theme.getSize("slider_handle").width - anchors.left: playButton.right - anchors.leftMargin: UM.Theme.getSize("default_margin").width - anchors.right: parent.right + anchors + { + verticalCenter: playButton.verticalCenter + left: playButton.right + leftMargin: UM.Theme.getSize("default_margin").width + right: parent.right + } visible: !UM.SimulationView.compatibilityMode // custom properties @@ -650,10 +655,11 @@ Item anchors { - top: !UM.SimulationView.compatibilityMode ? pathSlider.bottom : parent.top - topMargin: !UM.SimulationView.compatibilityMode ? UM.Theme.getSize("default_margin").height : 0 - right: parent.right - rightMargin: UM.Theme.getSize("slider_layerview_margin").width + bottom: !UM.SimulationView.compatibilityMode ? pathSlider.top : parent.bottom + top: parent.top + bottomMargin: !UM.SimulationView.compatibilityMode ? UM.Theme.getSize("default_margin").height : 0 + left: parent.left + leftMargin: Math.round(UM.Theme.getSize("slider_layerview_margin").width / 2) } // custom properties @@ -704,7 +710,8 @@ Item visible: !UM.SimulationView.compatibilityMode anchors { - verticalCenter: pathSlider.verticalCenter + left: parent.left + bottom: parent.bottom } property var status: 0 // indicates if it's stopped (0) or playing (1) From 54518bdc82221950ed63d1e7bde2e4dbf26b47cf Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 26 Oct 2018 11:14:39 +0200 Subject: [PATCH 0069/1292] Change the minimum window size to be 1280x800. Contributes to CURA-5784. --- resources/themes/cura-light/theme.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 1820ead338..6a83c2c566 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -345,7 +345,7 @@ }, "sizes": { - "window_minimum_size": [106, 85], + "window_minimum_size": [106, 66], "main_window_header": [0.0, 4.5], "main_window_header_button": [8, 4], From a277bd9f3b8ee3383be53e805e47058b49a7d3f9 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 26 Oct 2018 11:29:05 +0200 Subject: [PATCH 0070/1292] Don't use the hand cursor in the action buttons by default. Contributes to CURA-5784. --- resources/qml/Account/AccountWidget.qml | 21 +++++---------------- resources/qml/ActionButton.qml | 1 - 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/resources/qml/Account/AccountWidget.qml b/resources/qml/Account/AccountWidget.qml index eb58d66773..46092e4153 100644 --- a/resources/qml/Account/AccountWidget.qml +++ b/resources/qml/Account/AccountWidget.qml @@ -16,30 +16,19 @@ Button implicitHeight: UM.Theme.getSize("main_window_header").height implicitWidth: UM.Theme.getSize("main_window_header").height - AvatarImage + background: AvatarImage { id: avatar - width: Math.round(0.8 * parent.width) - height: Math.round(0.8 * parent.height) - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.horizontalCenter + width: Math.round(0.8 * accountWidget.width) + height: Math.round(0.8 * accountWidget.height) + anchors.verticalCenter: accountWidget.verticalCenter + anchors.horizontalCenter: accountWidget.horizontalCenter source: loggedIn ? profile["profile_image_url"] : UM.Theme.getImage("avatar_no_user") outlineColor: loggedIn ? UM.Theme.getColor("account_widget_outline_active") : UM.Theme.getColor("account_widget_outline_inactive") } - MouseArea - { - id: mouseArea - anchors.fill: parent - onPressed: mouse.accepted = false - hoverEnabled: true - cursorShape: accountWidget.enabled ? (hovered ? Qt.PointingHandCursor : Qt.ArrowCursor) : Qt.ForbiddenCursor - } - - background: Item {} - onClicked: popup.opened ? popup.close() : popup.open() Popup diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index a8ad94474e..a1c03af143 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -68,6 +68,5 @@ Button anchors.fill: parent onPressed: mouse.accepted = false hoverEnabled: true - cursorShape: button.enabled ? (hovered ? Qt.PointingHandCursor : Qt.ArrowCursor) : Qt.ForbiddenCursor } } From 2cbaece3e1472639c29a5b2d7f193b62eabcadf9 Mon Sep 17 00:00:00 2001 From: pinchies <> Date: Fri, 26 Oct 2018 22:21:01 +1100 Subject: [PATCH 0071/1292] Add JGAurora Z-603S Add a preset for the JGAurora Z-603S to model list --- .../definitions/jgaurora_z_603s.def.json | 96 +++++++++++++++++++ .../jgaurora_z_603s_extruder_0.def.json | 16 ++++ 2 files changed, 112 insertions(+) create mode 100644 resources/definitions/jgaurora_z_603s.def.json create mode 100644 resources/extruders/jgaurora_z_603s_extruder_0.def.json diff --git a/resources/definitions/jgaurora_z_603s.def.json b/resources/definitions/jgaurora_z_603s.def.json new file mode 100644 index 0000000000..af7fa823db --- /dev/null +++ b/resources/definitions/jgaurora_z_603s.def.json @@ -0,0 +1,96 @@ +{ + "name": "JGAurora Z-603S", + "version": 2, + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "author": "Samuel Pinches", + "manufacturer": "JGAurora", + "file_formats": "text/x-gcode", + "preferred_quality_type": "fine", + "machine_extruder_trains": + { + "0": "jgaurora_z_603s_extruder_0" + } + }, + "overrides": { + "machine_name": { + "default_value": "JGAurora Z-603S" + }, + "machine_start_gcode": { + "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F6000 ;move Z to position 15.0 mm as fast as possible\nG92 E0 ;zero the extruded length\nG1 X0.0 Y0.0 F1000.0 ;go to edge of print area\nG1 X60.0 E9.0 F1000.0 ;intro line\nG1 X100.0 E21.5 F1000.0 ;intro line\nG92 E0 ;zero the extruded length again\n; -- end of START GCODE --" + }, + "machine_end_gcode": { + "default_value": "; -- END GCODE --\nM104 S0 ;turn off nozzle heater\nM140 S0 ;turn off bed heater\nG91 ;set to relative positioning\nG1 E-10 F300 ;retract the filament slightly\nG90 ;set to absolute positioning\nG28 X0 ;move to the X-axis origin (Home)\nG0 Y280 F600 ;bring the bed to the front for easy print removal\nM84 ;turn off stepper motors\n; -- end of END GCODE --" + }, + "machine_width": { + "default_value": 280 + }, + "machine_height": { + "default_value": 175 + }, + "machine_depth": { + "default_value": 180 + }, + "machine_heated_bed": { + "default_value": true + }, + "machine_center_is_zero": { + "default_value": false + }, + "gantry_height": { + "default_value": 10 + }, + "machine_gcode_flavor": { + "default_value": "RepRap (Marlin/Sprinter)" + }, + "material_diameter": { + "default_value": 1.75 + }, + "material_print_temperature": { + "default_value": 210 + }, + "material_bed_temperature": { + "default_value": 55 + }, + "layer_height": { + "default_value": 0.15 + }, + "layer_height_0": { + "default_value": 0.2 + }, + "wall_thickness": { + "default_value": 1.2 + }, + "speed_print": { + "default_value": 60 + }, + "speed_infill": { + "default_value": 60 + }, + "speed_wall": { + "default_value": 30 + }, + "speed_topbottom": { + "default_value": 45 + }, + "speed_travel": { + "default_value": 125 + }, + "speed_layer_0": { + "default_value": 20 + }, + "support_enable": { + "default_value": true + }, + "retraction_enable": { + "default_value": true + }, + "retraction_amount": { + "default_value": 5 + }, + "retraction_speed": { + "default_value": 50 + } + } +} \ No newline at end of file diff --git a/resources/extruders/jgaurora_z_603s_extruder_0.def.json b/resources/extruders/jgaurora_z_603s_extruder_0.def.json new file mode 100644 index 0000000000..987425b28a --- /dev/null +++ b/resources/extruders/jgaurora_z_603s_extruder_0.def.json @@ -0,0 +1,16 @@ +{ + "id": "jgaurora_z_603s_extruder_0", + "version": 2, + "name": "Extruder 1", + "inherits": "fdmextruder", + "metadata": { + "machine": "jgaurora_z_603s", + "position": "0" + }, + + "overrides": { + "extruder_nr": { "default_value": 0 }, + "machine_nozzle_size": { "default_value": 0.4 }, + "material_diameter": { "default_value": 1.75 } + } +} From bc5f92b69b096234512fa8e9ad0f3a0d63c7dd71 Mon Sep 17 00:00:00 2001 From: pinchies <> Date: Fri, 26 Oct 2018 22:24:04 +1100 Subject: [PATCH 0072/1292] Add JGAurora A1 Add a preset for the JGAurora A1 to model list --- resources/definitions/jgaurora_a1.def.json | 96 +++++++++++++++++++ .../extruders/jgaurora_a1_extruder_0.def.json | 16 ++++ 2 files changed, 112 insertions(+) create mode 100644 resources/definitions/jgaurora_a1.def.json create mode 100644 resources/extruders/jgaurora_a1_extruder_0.def.json diff --git a/resources/definitions/jgaurora_a1.def.json b/resources/definitions/jgaurora_a1.def.json new file mode 100644 index 0000000000..004fd8741d --- /dev/null +++ b/resources/definitions/jgaurora_a1.def.json @@ -0,0 +1,96 @@ +{ + "name": "JGAurora A1", + "version": 2, + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "author": "Samuel Pinches", + "manufacturer": "JGAurora", + "file_formats": "text/x-gcode", + "preferred_quality_type": "fine", + "machine_extruder_trains": + { + "0": "jgaurora_a1_extruder_0" + } + }, + "overrides": { + "machine_name": { + "default_value": "JGAurora A1" + }, + "machine_start_gcode": { + "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F6000 ;move Z to position 15.0 mm as fast as possible\nG92 E0 ;zero the extruded length\nG1 X0.0 Y0.0 F1000.0 ;go to edge of print area\nG1 X60.0 E9.0 F1000.0 ;intro line\nG1 X100.0 E21.5 F1000.0 ;intro line\nG92 E0 ;zero the extruded length again\n; -- end of START GCODE --" + }, + "machine_end_gcode": { + "default_value": "; -- END GCODE --\nM104 S0 ;turn off nozzle heater\nM140 S0 ;turn off bed heater\nG91 ;set to relative positioning\nG1 E-10 F300 ;retract the filament slightly\nG90 ;set to absolute positioning\nG28 X0 ;move to the X-axis origin (Home)\nG0 Y280 F600 ;bring the bed to the front for easy print removal\nM84 ;turn off stepper motors\n; -- end of END GCODE --" + }, + "machine_width": { + "default_value": 300 + }, + "machine_height": { + "default_value": 300 + }, + "machine_depth": { + "default_value": 300 + }, + "machine_heated_bed": { + "default_value": true + }, + "machine_center_is_zero": { + "default_value": false + }, + "gantry_height": { + "default_value": 10 + }, + "machine_gcode_flavor": { + "default_value": "RepRap (Marlin/Sprinter)" + }, + "material_diameter": { + "default_value": 1.75 + }, + "material_print_temperature": { + "default_value": 215 + }, + "material_bed_temperature": { + "default_value": 67 + }, + "layer_height": { + "default_value": 0.15 + }, + "layer_height_0": { + "default_value": 0.12 + }, + "wall_thickness": { + "default_value": 1.2 + }, + "speed_print": { + "default_value": 40 + }, + "speed_infill": { + "default_value": 40 + }, + "speed_wall": { + "default_value": 35 + }, + "speed_topbottom": { + "default_value": 35 + }, + "speed_travel": { + "default_value": 120 + }, + "speed_layer_0": { + "default_value": 12 + }, + "support_enable": { + "default_value": true + }, + "retraction_enable": { + "default_value": true + }, + "retraction_amount": { + "default_value": 6 + }, + "retraction_speed": { + "default_value": 40 + } + } +} \ No newline at end of file diff --git a/resources/extruders/jgaurora_a1_extruder_0.def.json b/resources/extruders/jgaurora_a1_extruder_0.def.json new file mode 100644 index 0000000000..71742b734a --- /dev/null +++ b/resources/extruders/jgaurora_a1_extruder_0.def.json @@ -0,0 +1,16 @@ +{ + "id": "jgaurora_a1_extruder_0", + "version": 2, + "name": "Extruder 1", + "inherits": "fdmextruder", + "metadata": { + "machine": "jgaurora_a1", + "position": "0" + }, + + "overrides": { + "extruder_nr": { "default_value": 0 }, + "machine_nozzle_size": { "default_value": 0.4 }, + "material_diameter": { "default_value": 1.75 } + } +} From 5d4aa569a9d6505736944b2f5ccfdb2548d29ba7 Mon Sep 17 00:00:00 2001 From: pinchies <> Date: Fri, 26 Oct 2018 22:34:15 +1100 Subject: [PATCH 0073/1292] Revert "Add JGAurora A1" This reverts commit bc5f92b69b096234512fa8e9ad0f3a0d63c7dd71. --- resources/definitions/jgaurora_a1.def.json | 96 ------------------- .../extruders/jgaurora_a1_extruder_0.def.json | 16 ---- 2 files changed, 112 deletions(-) delete mode 100644 resources/definitions/jgaurora_a1.def.json delete mode 100644 resources/extruders/jgaurora_a1_extruder_0.def.json diff --git a/resources/definitions/jgaurora_a1.def.json b/resources/definitions/jgaurora_a1.def.json deleted file mode 100644 index 004fd8741d..0000000000 --- a/resources/definitions/jgaurora_a1.def.json +++ /dev/null @@ -1,96 +0,0 @@ -{ - "name": "JGAurora A1", - "version": 2, - "inherits": "fdmprinter", - "metadata": { - "visible": true, - "author": "Samuel Pinches", - "manufacturer": "JGAurora", - "file_formats": "text/x-gcode", - "preferred_quality_type": "fine", - "machine_extruder_trains": - { - "0": "jgaurora_a1_extruder_0" - } - }, - "overrides": { - "machine_name": { - "default_value": "JGAurora A1" - }, - "machine_start_gcode": { - "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F6000 ;move Z to position 15.0 mm as fast as possible\nG92 E0 ;zero the extruded length\nG1 X0.0 Y0.0 F1000.0 ;go to edge of print area\nG1 X60.0 E9.0 F1000.0 ;intro line\nG1 X100.0 E21.5 F1000.0 ;intro line\nG92 E0 ;zero the extruded length again\n; -- end of START GCODE --" - }, - "machine_end_gcode": { - "default_value": "; -- END GCODE --\nM104 S0 ;turn off nozzle heater\nM140 S0 ;turn off bed heater\nG91 ;set to relative positioning\nG1 E-10 F300 ;retract the filament slightly\nG90 ;set to absolute positioning\nG28 X0 ;move to the X-axis origin (Home)\nG0 Y280 F600 ;bring the bed to the front for easy print removal\nM84 ;turn off stepper motors\n; -- end of END GCODE --" - }, - "machine_width": { - "default_value": 300 - }, - "machine_height": { - "default_value": 300 - }, - "machine_depth": { - "default_value": 300 - }, - "machine_heated_bed": { - "default_value": true - }, - "machine_center_is_zero": { - "default_value": false - }, - "gantry_height": { - "default_value": 10 - }, - "machine_gcode_flavor": { - "default_value": "RepRap (Marlin/Sprinter)" - }, - "material_diameter": { - "default_value": 1.75 - }, - "material_print_temperature": { - "default_value": 215 - }, - "material_bed_temperature": { - "default_value": 67 - }, - "layer_height": { - "default_value": 0.15 - }, - "layer_height_0": { - "default_value": 0.12 - }, - "wall_thickness": { - "default_value": 1.2 - }, - "speed_print": { - "default_value": 40 - }, - "speed_infill": { - "default_value": 40 - }, - "speed_wall": { - "default_value": 35 - }, - "speed_topbottom": { - "default_value": 35 - }, - "speed_travel": { - "default_value": 120 - }, - "speed_layer_0": { - "default_value": 12 - }, - "support_enable": { - "default_value": true - }, - "retraction_enable": { - "default_value": true - }, - "retraction_amount": { - "default_value": 6 - }, - "retraction_speed": { - "default_value": 40 - } - } -} \ No newline at end of file diff --git a/resources/extruders/jgaurora_a1_extruder_0.def.json b/resources/extruders/jgaurora_a1_extruder_0.def.json deleted file mode 100644 index 71742b734a..0000000000 --- a/resources/extruders/jgaurora_a1_extruder_0.def.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "id": "jgaurora_a1_extruder_0", - "version": 2, - "name": "Extruder 1", - "inherits": "fdmextruder", - "metadata": { - "machine": "jgaurora_a1", - "position": "0" - }, - - "overrides": { - "extruder_nr": { "default_value": 0 }, - "machine_nozzle_size": { "default_value": 0.4 }, - "material_diameter": { "default_value": 1.75 } - } -} From 1f97aa3df6f4330be335dc9529eede879636687e Mon Sep 17 00:00:00 2001 From: pinchies Date: Fri, 26 Oct 2018 23:37:31 +1100 Subject: [PATCH 0074/1292] Add files via upload --- .../extruders/jgaurora_a5_extruder_0.def.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 resources/extruders/jgaurora_a5_extruder_0.def.json diff --git a/resources/extruders/jgaurora_a5_extruder_0.def.json b/resources/extruders/jgaurora_a5_extruder_0.def.json new file mode 100644 index 0000000000..fbc6ba77e6 --- /dev/null +++ b/resources/extruders/jgaurora_a5_extruder_0.def.json @@ -0,0 +1,16 @@ +{ + "id": "jgaurora_a5_extruder_0", + "version": 2, + "name": "Extruder 1", + "inherits": "fdmextruder", + "metadata": { + "machine": "jgaurora_a5", + "position": "0" + }, + + "overrides": { + "extruder_nr": { "default_value": 0 }, + "machine_nozzle_size": { "default_value": 0.4 }, + "material_diameter": { "default_value": 1.75 } + } +} From f0277f5ef381a958e2559ffb7fbbcf33818cfb37 Mon Sep 17 00:00:00 2001 From: pinchies Date: Fri, 26 Oct 2018 23:38:30 +1100 Subject: [PATCH 0075/1292] Add files via upload --- resources/definitions/jgaurora_a5.def.json | 98 ++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 resources/definitions/jgaurora_a5.def.json diff --git a/resources/definitions/jgaurora_a5.def.json b/resources/definitions/jgaurora_a5.def.json new file mode 100644 index 0000000000..6143ef1523 --- /dev/null +++ b/resources/definitions/jgaurora_a5.def.json @@ -0,0 +1,98 @@ +{ + "name": "JGAurora A5", + "version": 2, + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "author": "Samuel Pinches", + "manufacturer": "JGAurora", + "file_formats": "text/x-gcode", + "platform": "jgaurora_a5.stl", + "platform_offset": [-242, -101, 273], + "preferred_quality_type": "fine", + "machine_extruder_trains": + { + "0": "jgaurora_a5_extruder_0" + } + }, + "overrides": { + "machine_name": { + "default_value": "JGAurora A5" + }, + "machine_start_gcode": { + "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F6000 ;move Z to position 15.0 mm as fast as possible\nG92 E0 ;zero the extruded length\nG1 X0.0 Y0.0 F1000.0 ;go to edge of print area\nG1 X60.0 E9.0 F1000.0 ;intro line\nG1 X100.0 E21.5 F1000.0 ;intro line\nG92 E0 ;zero the extruded length again\n; -- end of START GCODE --" + }, + "machine_end_gcode": { + "default_value": "; -- END GCODE --\nM104 S0 ;turn off nozzle heater\nM140 S0 ;turn off bed heater\nG91 ;set to relative positioning\nG1 E-10 F300 ;retract the filament slightly\nG90 ;set to absolute positioning\nG28 X0 ;move to the X-axis origin (Home)\nG0 Y280 F600 ;bring the bed to the front for easy print removal\nM84 ;turn off stepper motors\n; -- end of END GCODE --" + }, + "machine_width": { + "default_value": 300 + }, + "machine_height": { + "default_value": 320 + }, + "machine_depth": { + "default_value": 300 + }, + "machine_heated_bed": { + "default_value": true + }, + "machine_center_is_zero": { + "default_value": false + }, + "gantry_height": { + "default_value": 10 + }, + "machine_gcode_flavor": { + "default_value": "RepRap (Marlin/Sprinter)" + }, + "material_diameter": { + "default_value": 1.75 + }, + "material_print_temperature": { + "default_value": 215 + }, + "material_bed_temperature": { + "default_value": 67 + }, + "layer_height": { + "default_value": 0.15 + }, + "layer_height_0": { + "default_value": 0.12 + }, + "wall_thickness": { + "default_value": 1.2 + }, + "speed_print": { + "default_value": 40 + }, + "speed_infill": { + "default_value": 40 + }, + "speed_wall": { + "default_value": 35 + }, + "speed_topbottom": { + "default_value": 35 + }, + "speed_travel": { + "default_value": 120 + }, + "speed_layer_0": { + "default_value": 12 + }, + "support_enable": { + "default_value": true + }, + "retraction_enable": { + "default_value": true + }, + "retraction_amount": { + "default_value": 8 + }, + "retraction_speed": { + "default_value": 45 + } + } +} \ No newline at end of file From 494bedbe0d1f446c137d7705d5d66bec926760ee Mon Sep 17 00:00:00 2001 From: pinchies Date: Fri, 26 Oct 2018 23:40:27 +1100 Subject: [PATCH 0076/1292] Add files via upload --- resources/meshes/jgaurora_a5.stl | Bin 0 -> 1000084 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 resources/meshes/jgaurora_a5.stl diff --git a/resources/meshes/jgaurora_a5.stl b/resources/meshes/jgaurora_a5.stl new file mode 100644 index 0000000000000000000000000000000000000000..c525b036492db15e0c2c206859e54bbf20ba5301 GIT binary patch literal 1000084 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�nAJsXQuBI;Oc_GdhnxoxS7dXRN+0{t99L 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 Spr#su3KHsGOTXJo$o~KVh0fLh literal 0 HcmV?d00001 From c8269ee4c081f312c8611222fedca71952ea7ad9 Mon Sep 17 00:00:00 2001 From: pinchies Date: Fri, 26 Oct 2018 23:42:27 +1100 Subject: [PATCH 0077/1292] Add files via upload --- .../extruders/jgaurora_a1_extruder_0.def.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 resources/extruders/jgaurora_a1_extruder_0.def.json diff --git a/resources/extruders/jgaurora_a1_extruder_0.def.json b/resources/extruders/jgaurora_a1_extruder_0.def.json new file mode 100644 index 0000000000..71742b734a --- /dev/null +++ b/resources/extruders/jgaurora_a1_extruder_0.def.json @@ -0,0 +1,16 @@ +{ + "id": "jgaurora_a1_extruder_0", + "version": 2, + "name": "Extruder 1", + "inherits": "fdmextruder", + "metadata": { + "machine": "jgaurora_a1", + "position": "0" + }, + + "overrides": { + "extruder_nr": { "default_value": 0 }, + "machine_nozzle_size": { "default_value": 0.4 }, + "material_diameter": { "default_value": 1.75 } + } +} From adee0fa260b861c06f174a99ea0aba1b54b26a8b Mon Sep 17 00:00:00 2001 From: pinchies Date: Fri, 26 Oct 2018 23:42:49 +1100 Subject: [PATCH 0078/1292] Add files via upload --- resources/definitions/jgaurora_a1.def.json | 96 ++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 resources/definitions/jgaurora_a1.def.json diff --git a/resources/definitions/jgaurora_a1.def.json b/resources/definitions/jgaurora_a1.def.json new file mode 100644 index 0000000000..004fd8741d --- /dev/null +++ b/resources/definitions/jgaurora_a1.def.json @@ -0,0 +1,96 @@ +{ + "name": "JGAurora A1", + "version": 2, + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "author": "Samuel Pinches", + "manufacturer": "JGAurora", + "file_formats": "text/x-gcode", + "preferred_quality_type": "fine", + "machine_extruder_trains": + { + "0": "jgaurora_a1_extruder_0" + } + }, + "overrides": { + "machine_name": { + "default_value": "JGAurora A1" + }, + "machine_start_gcode": { + "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F6000 ;move Z to position 15.0 mm as fast as possible\nG92 E0 ;zero the extruded length\nG1 X0.0 Y0.0 F1000.0 ;go to edge of print area\nG1 X60.0 E9.0 F1000.0 ;intro line\nG1 X100.0 E21.5 F1000.0 ;intro line\nG92 E0 ;zero the extruded length again\n; -- end of START GCODE --" + }, + "machine_end_gcode": { + "default_value": "; -- END GCODE --\nM104 S0 ;turn off nozzle heater\nM140 S0 ;turn off bed heater\nG91 ;set to relative positioning\nG1 E-10 F300 ;retract the filament slightly\nG90 ;set to absolute positioning\nG28 X0 ;move to the X-axis origin (Home)\nG0 Y280 F600 ;bring the bed to the front for easy print removal\nM84 ;turn off stepper motors\n; -- end of END GCODE --" + }, + "machine_width": { + "default_value": 300 + }, + "machine_height": { + "default_value": 300 + }, + "machine_depth": { + "default_value": 300 + }, + "machine_heated_bed": { + "default_value": true + }, + "machine_center_is_zero": { + "default_value": false + }, + "gantry_height": { + "default_value": 10 + }, + "machine_gcode_flavor": { + "default_value": "RepRap (Marlin/Sprinter)" + }, + "material_diameter": { + "default_value": 1.75 + }, + "material_print_temperature": { + "default_value": 215 + }, + "material_bed_temperature": { + "default_value": 67 + }, + "layer_height": { + "default_value": 0.15 + }, + "layer_height_0": { + "default_value": 0.12 + }, + "wall_thickness": { + "default_value": 1.2 + }, + "speed_print": { + "default_value": 40 + }, + "speed_infill": { + "default_value": 40 + }, + "speed_wall": { + "default_value": 35 + }, + "speed_topbottom": { + "default_value": 35 + }, + "speed_travel": { + "default_value": 120 + }, + "speed_layer_0": { + "default_value": 12 + }, + "support_enable": { + "default_value": true + }, + "retraction_enable": { + "default_value": true + }, + "retraction_amount": { + "default_value": 6 + }, + "retraction_speed": { + "default_value": 40 + } + } +} \ No newline at end of file From 79ef3635a56ad76ac77816f98d1216b999c33d62 Mon Sep 17 00:00:00 2001 From: pinchies Date: Fri, 26 Oct 2018 23:45:32 +1100 Subject: [PATCH 0079/1292] Add files via upload --- resources/extruders/alfawise_u20.def.json | 96 +++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 resources/extruders/alfawise_u20.def.json diff --git a/resources/extruders/alfawise_u20.def.json b/resources/extruders/alfawise_u20.def.json new file mode 100644 index 0000000000..f6dccce3ee --- /dev/null +++ b/resources/extruders/alfawise_u20.def.json @@ -0,0 +1,96 @@ +{ + "name": "Alfawise U20", + "version": 2, + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "author": "Samuel Pinches", + "manufacturer": "Alfawise", + "file_formats": "text/x-gcode", + "preferred_quality_type": "fine", + "machine_extruder_trains": + { + "0": "alfawise_u20_extruder_0" + } + }, + "overrides": { + "machine_name": { + "default_value": "Alfawise U20" + }, + "machine_start_gcode": { + "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F6000 ;move Z to position 15.0 mm as fast as possible\nG92 E0 ;zero the extruded length\nG1 X0.0 Y0.0 F1000.0 ;go to edge of print area\nG1 X60.0 E9.0 F1000.0 ;intro line\nG1 X100.0 E21.5 F1000.0 ;intro line\nG92 E0 ;zero the extruded length again\n; -- end of START GCODE --" + }, + "machine_end_gcode": { + "default_value": "; -- END GCODE --\nM104 S0 ;turn off nozzle heater\nM140 S0 ;turn off bed heater\nG91 ;set to relative positioning\nG1 E-10 F300 ;retract the filament slightly\nG90 ;set to absolute positioning\nG28 X0 ;move to the X-axis origin (Home)\nG0 Y280 F600 ;bring the bed to the front for easy print removal\nM84 ;turn off stepper motors\n; -- end of END GCODE --" + }, + "machine_width": { + "default_value": 300 + }, + "machine_height": { + "default_value": 400 + }, + "machine_depth": { + "default_value": 300 + }, + "machine_heated_bed": { + "default_value": true + }, + "machine_center_is_zero": { + "default_value": false + }, + "gantry_height": { + "default_value": 10 + }, + "machine_gcode_flavor": { + "default_value": "RepRap (Marlin/Sprinter)" + }, + "material_diameter": { + "default_value": 1.75 + }, + "material_print_temperature": { + "default_value": 210 + }, + "material_bed_temperature": { + "default_value": 50 + }, + "layer_height": { + "default_value": 0.15 + }, + "layer_height_0": { + "default_value": 0.2 + }, + "wall_thickness": { + "default_value": 1.2 + }, + "speed_print": { + "default_value": 40 + }, + "speed_infill": { + "default_value": 40 + }, + "speed_wall": { + "default_value": 35 + }, + "speed_topbottom": { + "default_value": 35 + }, + "speed_travel": { + "default_value": 120 + }, + "speed_layer_0": { + "default_value": 20 + }, + "support_enable": { + "default_value": true + }, + "retraction_enable": { + "default_value": true + }, + "retraction_amount": { + "default_value": 5 + }, + "retraction_speed": { + "default_value": 45 + } + } +} \ No newline at end of file From 03532969c6c17883750f3bafb76e0e82f319cfbd Mon Sep 17 00:00:00 2001 From: pinchies Date: Fri, 26 Oct 2018 23:46:39 +1100 Subject: [PATCH 0080/1292] Add files via upload --- resources/definitions/alfawise_u20.def.json | 96 +++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 resources/definitions/alfawise_u20.def.json diff --git a/resources/definitions/alfawise_u20.def.json b/resources/definitions/alfawise_u20.def.json new file mode 100644 index 0000000000..f6dccce3ee --- /dev/null +++ b/resources/definitions/alfawise_u20.def.json @@ -0,0 +1,96 @@ +{ + "name": "Alfawise U20", + "version": 2, + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "author": "Samuel Pinches", + "manufacturer": "Alfawise", + "file_formats": "text/x-gcode", + "preferred_quality_type": "fine", + "machine_extruder_trains": + { + "0": "alfawise_u20_extruder_0" + } + }, + "overrides": { + "machine_name": { + "default_value": "Alfawise U20" + }, + "machine_start_gcode": { + "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F6000 ;move Z to position 15.0 mm as fast as possible\nG92 E0 ;zero the extruded length\nG1 X0.0 Y0.0 F1000.0 ;go to edge of print area\nG1 X60.0 E9.0 F1000.0 ;intro line\nG1 X100.0 E21.5 F1000.0 ;intro line\nG92 E0 ;zero the extruded length again\n; -- end of START GCODE --" + }, + "machine_end_gcode": { + "default_value": "; -- END GCODE --\nM104 S0 ;turn off nozzle heater\nM140 S0 ;turn off bed heater\nG91 ;set to relative positioning\nG1 E-10 F300 ;retract the filament slightly\nG90 ;set to absolute positioning\nG28 X0 ;move to the X-axis origin (Home)\nG0 Y280 F600 ;bring the bed to the front for easy print removal\nM84 ;turn off stepper motors\n; -- end of END GCODE --" + }, + "machine_width": { + "default_value": 300 + }, + "machine_height": { + "default_value": 400 + }, + "machine_depth": { + "default_value": 300 + }, + "machine_heated_bed": { + "default_value": true + }, + "machine_center_is_zero": { + "default_value": false + }, + "gantry_height": { + "default_value": 10 + }, + "machine_gcode_flavor": { + "default_value": "RepRap (Marlin/Sprinter)" + }, + "material_diameter": { + "default_value": 1.75 + }, + "material_print_temperature": { + "default_value": 210 + }, + "material_bed_temperature": { + "default_value": 50 + }, + "layer_height": { + "default_value": 0.15 + }, + "layer_height_0": { + "default_value": 0.2 + }, + "wall_thickness": { + "default_value": 1.2 + }, + "speed_print": { + "default_value": 40 + }, + "speed_infill": { + "default_value": 40 + }, + "speed_wall": { + "default_value": 35 + }, + "speed_topbottom": { + "default_value": 35 + }, + "speed_travel": { + "default_value": 120 + }, + "speed_layer_0": { + "default_value": 20 + }, + "support_enable": { + "default_value": true + }, + "retraction_enable": { + "default_value": true + }, + "retraction_amount": { + "default_value": 5 + }, + "retraction_speed": { + "default_value": 45 + } + } +} \ No newline at end of file From 135ad6d7054a84591a635ee4c4c21945dfac44be Mon Sep 17 00:00:00 2001 From: pinchies Date: Fri, 26 Oct 2018 23:53:59 +1100 Subject: [PATCH 0081/1292] Add files via upload --- .../cocoon_create_modelmaker_extruder_0.def.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 resources/extruders/cocoon_create_modelmaker_extruder_0.def.json diff --git a/resources/extruders/cocoon_create_modelmaker_extruder_0.def.json b/resources/extruders/cocoon_create_modelmaker_extruder_0.def.json new file mode 100644 index 0000000000..26d847483d --- /dev/null +++ b/resources/extruders/cocoon_create_modelmaker_extruder_0.def.json @@ -0,0 +1,16 @@ +{ + "id": "cocoon_create_modelmaker_extruder_0", + "version": 2, + "name": "Extruder 1", + "inherits": "fdmextruder", + "metadata": { + "machine": "cocoon_create_modelmaker", + "position": "0" + }, + + "overrides": { + "extruder_nr": { "default_value": 0 }, + "machine_nozzle_size": { "default_value": 0.4 }, + "material_diameter": { "default_value": 1.75 } + } +} From 49ac4233839e80423767ce13883cd3f9ba7a0cc5 Mon Sep 17 00:00:00 2001 From: pinchies Date: Fri, 26 Oct 2018 23:54:29 +1100 Subject: [PATCH 0082/1292] Add files via upload --- .../cocoon_create_modelmaker.def.json | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 resources/definitions/cocoon_create_modelmaker.def.json diff --git a/resources/definitions/cocoon_create_modelmaker.def.json b/resources/definitions/cocoon_create_modelmaker.def.json new file mode 100644 index 0000000000..f752a08fc7 --- /dev/null +++ b/resources/definitions/cocoon_create_modelmaker.def.json @@ -0,0 +1,96 @@ +{ + "name": "Cocoon Create ModelMaker", + "version": 2, + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "author": "Samuel Pinches", + "manufacturer": "Cocoon Create", + "file_formats": "text/x-gcode", + "preferred_quality_type": "fine", + "machine_extruder_trains": + { + "0": "cocoon_create_modelmaker_extruder_0" + } + }, + "overrides": { + "machine_name": { + "default_value": "Cocoon Create ModelMaker" + }, + "machine_start_gcode": { + "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F6000 ;move Z to position 15.0 mm as fast as possible\nG92 E0 ;zero the extruded length\nG1 X0.0 Y0.0 F1000.0 ;go to edge of print area\nG1 X60.0 E9.0 F1000.0 ;intro line\nG1 X100.0 E21.5 F1000.0 ;intro line\nG92 E0 ;zero the extruded length again\n; -- end of START GCODE --" + }, + "machine_end_gcode": { + "default_value": "; -- END GCODE --\nM104 S0 ;turn off nozzle heater\nG91 ;set to relative positioning\nG1 E-10 F300 ;retract the filament slightly\nG90 ;set to absolute positioning\nG28 X0 Y0 ;move to the XY-axis origin (Home)\nM84 ;turn off stepper motors\n; -- end of END GCODE --" + }, + "machine_width": { + "default_value": 120 + }, + "machine_height": { + "default_value": 100 + }, + "machine_depth": { + "default_value": 135 + }, + "machine_heated_bed": { + "default_value": false + }, + "machine_center_is_zero": { + "default_value": false + }, + "gantry_height": { + "default_value": 10 + }, + "machine_gcode_flavor": { + "default_value": "RepRap (Marlin/Sprinter)" + }, + "material_diameter": { + "default_value": 1.75 + }, + "material_print_temperature": { + "default_value": 220 + }, + "layer_height": { + "default_value": 0.15 + }, + "layer_height_0": { + "default_value": 0.2 + }, + "wall_thickness": { + "default_value": 1.2 + }, + "top_bottom_thickness": { + "default_value": 0.6 + }, + "speed_print": { + "default_value": 40 + }, + "speed_infill": { + "default_value": 40 + }, + "speed_wall": { + "default_value": 35 + }, + "speed_topbottom": { + "default_value": 35 + }, + "speed_travel": { + "default_value": 70 + }, + "speed_layer_0": { + "default_value": 20 + }, + "support_enable": { + "default_value": true + }, + "retraction_enable": { + "default_value": true + }, + "retraction_amount": { + "default_value": 7 + }, + "retraction_speed": { + "default_value": 40 + } + } +} \ No newline at end of file From 3eb71021e24b7af44626e5b4ffe1a91915f88072 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 26 Oct 2018 15:53:20 +0200 Subject: [PATCH 0083/1292] Change the way the string for the tooltip is formatted. Contributes to CURA-5772. --- resources/qml/PrintSetupSelector.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector.qml index e5a29dffad..e4cb852d89 100644 --- a/resources/qml/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector.qml @@ -220,11 +220,11 @@ Rectangle { modesListModel.append({ text: catalog.i18nc("@title:tab", "Recommended"), - tooltipText: catalog.i18nc("@tooltip", "Recommended Print Setup

Print with the recommended settings for the selected printer, material and quality.") + tooltipText: "%1

%2".arg(catalog.i18nc("@tooltip:title", "Recommended Print Setup")).arg(catalog.i18nc("@tooltip", "Print with the recommended settings for the selected printer, material and quality.")) }) modesListModel.append({ text: catalog.i18nc("@title:tab", "Custom"), - tooltipText: catalog.i18nc("@tooltip", "Custom Print Setup

Print with finegrained control over every last bit of the slicing process.") + tooltipText: "%1

%2".arg(catalog.i18nc("@tooltip:title", "Custom Print Setup")).arg(catalog.i18nc("@tooltip", "Print with finegrained control over every last bit of the slicing process.")) }) var index = Math.round(UM.Preferences.getValue("cura/active_mode")) From 5a5adb71cd159c2e7b7204aa40b42472db4d9995 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 26 Oct 2018 16:16:33 +0200 Subject: [PATCH 0084/1292] Make the height of the Print setup selector themable. Contributes to CURA-5772. --- plugins/PrepareStage/PrepareMenu.qml | 4 ++-- resources/qml/PrintSetupSelector.qml | 2 +- resources/themes/cura-light/theme.json | 3 +++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index f08de9d317..27d068e909 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -61,12 +61,12 @@ Item Cura.CustomConfigurationSelector { - width: UM.Theme.getSize("sidebar").width + width: UM.Theme.getSize("configuration_selector_widget").width } Cura.PrintSetupSelector { - width: UM.Theme.getSize("sidebar").width + width: UM.Theme.getSize("print_setup_widget").width onShowTooltip: prepareMenu.showTooltip(item, location, text) onHideTooltip: prepareMenu.hideTooltip() } diff --git a/resources/qml/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector.qml index e4cb852d89..d9b2337c96 100644 --- a/resources/qml/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector.qml @@ -189,7 +189,7 @@ Rectangle anchors.topMargin: UM.Theme.getSize("sidebar_margin").height anchors.left: parent.left anchors.right: parent.right - height: 500 + height: UM.Theme.getSize("print_setup_widget").height // We load both of them at once (instead of using a loader) because the advanced sidebar can take // quite some time to load. So in this case we sacrifice memory for speed. diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 6a83c2c566..38d4f5372f 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -355,6 +355,9 @@ "account_button": [12, 3], + "print_setup_widget": [35.0, 42.0], + "configuration_selector_widget": [35.0, 0.0], + "views_selector": [0.0, 4.0], "default_lining": [0.08, 0.08], From c8bdf7321c4a888025001064f11c852097404264 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 26 Oct 2018 16:31:03 +0200 Subject: [PATCH 0085/1292] Move the visible check within the component. Contributes to CURA-5772. --- plugins/PrepareStage/PrepareMenu.qml | 4 ---- .../Menus/ConfigurationMenu/QuickConfigurationSelector.qml | 3 +++ 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index 27d068e909..c7f8a3b0f1 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -13,9 +13,6 @@ Item signal showTooltip(Item item, point location, string text) signal hideTooltip() - property bool isNetworkPrinter: Cura.MachineManager.activeMachineNetworkKey != "" - property bool printerConnected: Cura.MachineManager.printerConnected - UM.I18nCatalog { id: catalog @@ -53,7 +50,6 @@ Item Cura.QuickConfigurationSelector { id: configSelection - visible: isNetworkPrinter && printerConnected width: visible ? Math.round(UM.Theme.getSize("sidebar").width * 0.15) : 0 panelWidth: Math.round(0.8 * UM.Theme.getSize("sidebar").width) height: prepareMenu.height diff --git a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml index d7ee2c68ee..740c12d340 100644 --- a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml +++ b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml @@ -14,6 +14,9 @@ Item property var connectedDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null property var panelWidth: control.width + // Make this component only visible when it's a network printer and it is connected + visible: Cura.MachineManager.activeMachineNetworkKey != "" && Cura.MachineManager.printerConnected + function switchPopupState() { popup.visible ? popup.close() : popup.open() From 90e8a05aab63d5d16a2431571f6e9b6791ccd192 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 26 Oct 2018 17:51:28 +0200 Subject: [PATCH 0086/1292] Remove all the entries in the theme that make reference to the sidebar, because there is no sidebar anymore. Several different margins and linings were created depending on the side, not depending on where it belongs. Contributes to CURA-5784. --- .../PostProcessingPlugin.qml | 2 +- plugins/PrepareStage/PrepareMenu.qml | 6 +- plugins/Toolbox/resources/qml/Toolbox.qml | 2 +- .../qml/ToolboxCompatibilityChart.qml | 2 +- .../resources/qml/ToolboxTabButton.qml | 4 +- resources/qml/ActionPanelWidget.qml | 14 ++-- resources/qml/Cura.qml | 7 +- resources/qml/CustomConfigurationSelector.qml | 22 +++--- resources/qml/MachineSelector.qml | 12 +-- .../ConfigurationMenu/ConfigurationItem.qml | 4 +- .../Menus/ConfigurationMenu/SyncButton.qml | 6 +- resources/qml/MonitorButton.qml | 16 ++-- resources/qml/MonitorSidebar.qml | 18 ++--- resources/qml/PrintMonitor.qml | 12 +-- resources/qml/PrintSetupSelector.qml | 10 +-- resources/qml/PrinterOutput/ExtruderBox.qml | 2 +- resources/qml/PrinterOutput/HeatedBedBox.qml | 4 +- resources/qml/SaveButton.qml | 24 +++--- resources/qml/Settings/SettingCategory.qml | 4 +- resources/qml/Settings/SettingItem.qml | 6 +- resources/qml/Settings/SettingView.qml | 26 +++---- resources/qml/SidebarSimple.qml | 78 +++++++++---------- resources/themes/cura-dark/theme.json | 17 ++-- resources/themes/cura-light/styles.qml | 8 +- resources/themes/cura-light/theme.json | 51 ++++++------ 25 files changed, 174 insertions(+), 183 deletions(-) diff --git a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml index 10cc4cc082..bd4d361d35 100644 --- a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml +++ b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml @@ -260,7 +260,7 @@ UM.Dialog Rectangle { - color: UM.Theme.getColor("sidebar") + color: UM.Theme.getColor("main_background") anchors.left: activeScripts.right anchors.leftMargin: UM.Theme.getSize("default_margin").width anchors.right: parent.right diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index c7f8a3b0f1..cdcc1384a2 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -43,15 +43,15 @@ Item Cura.MachineSelector { id: machineSelection - width: Math.round(0.8 * UM.Theme.getSize("sidebar").width) - configSelection.width + width: UM.Theme.getSize("machine_selector_widget").width - configSelection.width height: prepareMenu.height } Cura.QuickConfigurationSelector { id: configSelection - width: visible ? Math.round(UM.Theme.getSize("sidebar").width * 0.15) : 0 - panelWidth: Math.round(0.8 * UM.Theme.getSize("sidebar").width) + width: visible ? UM.Theme.getSize("machine_selector_widget").width * 0.2 : 0 + panelWidth: UM.Theme.getSize("machine_selector_widget").width height: prepareMenu.height } diff --git a/plugins/Toolbox/resources/qml/Toolbox.qml b/plugins/Toolbox/resources/qml/Toolbox.qml index 29b026058c..a5fd2be370 100644 --- a/plugins/Toolbox/resources/qml/Toolbox.qml +++ b/plugins/Toolbox/resources/qml/Toolbox.qml @@ -20,7 +20,7 @@ Window maximumWidth: minimumWidth minimumHeight: height maximumHeight: minimumHeight - color: UM.Theme.getColor("sidebar") + color: UM.Theme.getColor("main_background") UM.I18nCatalog { id: catalog diff --git a/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml b/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml index 58fea079e9..4d27489d7a 100644 --- a/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml +++ b/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml @@ -54,7 +54,7 @@ Item model: packageData.supported_configs headerDelegate: Rectangle { - color: UM.Theme.getColor("sidebar") + color: UM.Theme.getColor("main_background") height: UM.Theme.getSize("toolbox_chart_row").height Label { diff --git a/plugins/Toolbox/resources/qml/ToolboxTabButton.qml b/plugins/Toolbox/resources/qml/ToolboxTabButton.qml index 58149e419a..b671d779f8 100644 --- a/plugins/Toolbox/resources/qml/ToolboxTabButton.qml +++ b/plugins/Toolbox/resources/qml/ToolboxTabButton.qml @@ -19,10 +19,10 @@ Button Rectangle { visible: control.active - color: UM.Theme.getColor("sidebar_header_highlight_hover") + color: UM.Theme.getColor("toolbox_header_highlight_hover") anchors.bottom: parent.bottom width: parent.width - height: UM.Theme.getSize("sidebar_header_highlight").height + height: UM.Theme.getSize("toolbox_header_highlight").height } } label: Label diff --git a/resources/qml/ActionPanelWidget.qml b/resources/qml/ActionPanelWidget.qml index 02ac154178..b5dc7f83c9 100644 --- a/resources/qml/ActionPanelWidget.qml +++ b/resources/qml/ActionPanelWidget.qml @@ -19,16 +19,16 @@ Rectangle signal showTooltip(Item item, point location, string text) signal hideTooltip() - color: UM.Theme.getColor("sidebar") + color: UM.Theme.getColor("main_background") // Also add an extra margin, as we want some breathing room around the edges. - height: saveButton.height + UM.Theme.getSize("sidebar_margin").height + height: saveButton.height + UM.Theme.getSize("thick_margin").height Label { id: timeDetails anchors.left: parent.left anchors.bottom: costSpec.top - anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width + anchors.leftMargin: UM.Theme.getSize("thick_margin").width font: UM.Theme.getFont("large") color: UM.Theme.getColor("text_subtext") @@ -62,7 +62,7 @@ Rectangle } } tooltip_html += ""; - base.showTooltip(parent, Qt.point(-UM.Theme.getSize("sidebar_margin").width, 0), tooltip_html); + base.showTooltip(parent, Qt.point(-UM.Theme.getSize("thick_margin").width, 0), tooltip_html); } } onExited: @@ -160,8 +160,8 @@ Rectangle anchors.left: parent.left anchors.bottom: parent.bottom - anchors.bottomMargin: UM.Theme.getSize("sidebar_margin").height - anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width + anchors.bottomMargin: UM.Theme.getSize("thick_margin").height + anchors.leftMargin: UM.Theme.getSize("thick_margin").width font: UM.Theme.getFont("very_small") renderType: Text.NativeRendering @@ -219,7 +219,7 @@ Rectangle { var show_data = costSpec.getSpecsData() - base.showTooltip(parent, Qt.point(-UM.Theme.getSize("sidebar_margin").width, 0), show_data); + base.showTooltip(parent, Qt.point(-UM.Theme.getSize("thick_margin").width, 0), show_data); } } onExited: diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index c5abb0f107..3e2515cb3e 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -312,9 +312,9 @@ UM.MainWindow { anchors.right: parent.right anchors.bottom: parent.bottom - width: UM.Theme.getSize("sidebar").width - anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width - anchors.bottomMargin: UM.Theme.getSize("sidebar_margin").height + width: UM.Theme.getSize("action_panel_widget").width + anchors.rightMargin: UM.Theme.getSize("thick_margin").width + anchors.bottomMargin: UM.Theme.getSize("thick_margin").height onShowTooltip: { base.showTooltip(item, location, text) @@ -348,7 +348,6 @@ UM.MainWindow anchors { horizontalCenter: parent.horizontalCenter - horizontalCenterOffset: -(Math.round(UM.Theme.getSize("sidebar").width / 2)) top: parent.verticalCenter bottom: parent.bottom bottomMargin: UM.Theme.getSize("default_margin").height diff --git a/resources/qml/CustomConfigurationSelector.qml b/resources/qml/CustomConfigurationSelector.qml index 9a3f91e6a3..17b652e8d8 100644 --- a/resources/qml/CustomConfigurationSelector.qml +++ b/resources/qml/CustomConfigurationSelector.qml @@ -14,7 +14,7 @@ Rectangle implicitHeight: parent.height id: base - color: UM.Theme.getColor("sidebar") + color: UM.Theme.getColor("main_background") // Height has an extra 2x margin for the top & bottom margin. height: childrenRect.height + 2 * UM.Theme.getSize("default_margin").width @@ -28,7 +28,7 @@ Rectangle visible: extrudersModel.items.length > 1 property var index: 0 - height: UM.Theme.getSize("sidebar_header_mode_tabs").height + height: UM.Theme.getSize("configuration_selector_mode_tabs").height boundsBehavior: Flickable.StopAtBounds anchors @@ -36,7 +36,7 @@ Rectangle left: parent.left right: parent.right top: parent.top - margins: UM.Theme.getSize("sidebar_margin").width + margins: UM.Theme.getSize("thick_margin").width } ExclusiveGroup { id: extruderMenuGroup } @@ -209,7 +209,7 @@ Rectangle Item { id: materialRow - height: UM.Theme.getSize("sidebar_setup").height + height: UM.Theme.getSize("print_setup_item").height visible: Cura.MachineManager.hasMaterials anchors @@ -217,7 +217,7 @@ Rectangle left: parent.left right: parent.right top: extrudersList.bottom - margins: UM.Theme.getSize("sidebar_margin").width + margins: UM.Theme.getSize("thick_margin").width } Label @@ -246,7 +246,7 @@ Rectangle enabled: !extrudersList.visible || Cura.ExtruderManager.activeExtruderIndex > -1 height: UM.Theme.getSize("setting_control").height - width: Math.round(parent.width * 0.7) + UM.Theme.getSize("sidebar_margin").width + width: Math.round(parent.width * 0.7) + UM.Theme.getSize("thick_margin").width anchors.right: parent.right style: UM.Theme.styles.sidebar_header_button activeFocusOnPress: true; @@ -263,7 +263,7 @@ Rectangle Item { id: variantRow - height: UM.Theme.getSize("sidebar_setup").height + height: UM.Theme.getSize("print_setup_item").height visible: Cura.MachineManager.hasVariants anchors @@ -271,7 +271,7 @@ Rectangle left: parent.left right: parent.right top: materialRow.bottom - margins: UM.Theme.getSize("sidebar_margin").width + margins: UM.Theme.getSize("thick_margin").width } Label @@ -293,7 +293,7 @@ Rectangle visible: Cura.MachineManager.hasVariants height: UM.Theme.getSize("setting_control").height - width: Math.round(parent.width * 0.7 + UM.Theme.getSize("sidebar_margin").width) + width: Math.round(parent.width * 0.7 + UM.Theme.getSize("thick_margin").width) anchors.right: parent.right style: UM.Theme.styles.sidebar_header_button activeFocusOnPress: true; @@ -305,11 +305,11 @@ Rectangle Item { id: materialCompatibilityLink - height: UM.Theme.getSize("sidebar_setup").height + height: UM.Theme.getSize("print_setup_item").height anchors.right: parent.right anchors.top: variantRow.bottom - anchors.margins: UM.Theme.getSize("sidebar_margin").width + anchors.margins: UM.Theme.getSize("thick_margin").width UM.RecolorImage { id: warningImage diff --git a/resources/qml/MachineSelector.qml b/resources/qml/MachineSelector.qml index 49fbf16e19..d82211af3a 100644 --- a/resources/qml/MachineSelector.qml +++ b/resources/qml/MachineSelector.qml @@ -27,13 +27,13 @@ ToolButton color: { if (control.pressed) { - return UM.Theme.getColor("sidebar_header_active"); + return UM.Theme.getColor("machine_selector_active"); } else if (control.hovered) { - return UM.Theme.getColor("sidebar_header_hover"); + return UM.Theme.getColor("machine_selector_hover"); } else { - return UM.Theme.getColor("sidebar_header_bar"); + return UM.Theme.getColor("machine_selector_bar"); } } Behavior on color { ColorAnimation { duration: 50; } } @@ -61,18 +61,18 @@ ToolButton { verticalCenter: parent.verticalCenter left: parent.left - leftMargin: UM.Theme.getSize("sidebar_margin").width + leftMargin: UM.Theme.getSize("thick_margin").width } } Label { id: sidebarComboBoxLabel - color: UM.Theme.getColor("sidebar_header_text_active") + color: UM.Theme.getColor("machine_selector_text_active") text: control.text; elide: Text.ElideRight; anchors.left: printerStatusIcon.visible ? printerStatusIcon.right : parent.left; - anchors.leftMargin: printerStatusIcon.visible ? UM.Theme.getSize("sidebar_lining").width : UM.Theme.getSize("sidebar_margin").width + anchors.leftMargin: printerStatusIcon.visible ? UM.Theme.getSize("narrow_margin").width : UM.Theme.getSize("thick_margin").width anchors.right: downArrow.left; anchors.rightMargin: control.rightMargin; anchors.verticalCenter: parent.verticalCenter; diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 37d851a35d..7427b5ddff 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -63,7 +63,7 @@ Rectangle visible: buildplateInformation.visible width: parent.width - 2 * parent.padding - height: visible ? Math.round(UM.Theme.getSize("sidebar_lining_thin").height / 2) : 0 + height: visible ? Math.round(UM.Theme.getSize("thick_lining").height / 2) : 0 color: textColor } @@ -110,7 +110,7 @@ Rectangle parent.border.color = UM.Theme.getColor("configuration_item_border_hover") if (configurationItem.selected == false) { - configurationItem.color = UM.Theme.getColor("sidebar_lining") + configurationItem.color = UM.Theme.getColor("wide_lining") } } onExited: diff --git a/resources/qml/Menus/ConfigurationMenu/SyncButton.qml b/resources/qml/Menus/ConfigurationMenu/SyncButton.qml index 3099d684c1..558ae1e477 100644 --- a/resources/qml/Menus/ConfigurationMenu/SyncButton.qml +++ b/resources/qml/Menus/ConfigurationMenu/SyncButton.qml @@ -42,15 +42,15 @@ Button { if(control.pressed) { - return UM.Theme.getColor("sidebar_header_active"); + return UM.Theme.getColor("machine_selector_active"); } else if(control.hovered) { - return UM.Theme.getColor("sidebar_header_hover"); + return UM.Theme.getColor("machine_selector_hover"); } else { - return UM.Theme.getColor("sidebar_header_bar"); + return UM.Theme.getColor("machine_selector_bar"); } } Behavior on color { ColorAnimation { duration: 50; } } diff --git a/resources/qml/MonitorButton.qml b/resources/qml/MonitorButton.qml index efee50a2b3..eef76bcb09 100644 --- a/resources/qml/MonitorButton.qml +++ b/resources/qml/MonitorButton.qml @@ -15,7 +15,7 @@ Item id: base; UM.I18nCatalog { id: catalog; name: "cura"} - height: childrenRect.height + UM.Theme.getSize("sidebar_margin").height + height: childrenRect.height + UM.Theme.getSize("thick_margin").height property bool printerConnected: Cura.MachineManager.printerConnected property bool printerAcceptsCommands: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands @@ -162,10 +162,10 @@ Item Label { id: statusLabel - width: parent.width - 2 * UM.Theme.getSize("sidebar_margin").width + width: parent.width - 2 * UM.Theme.getSize("thick_margin").width anchors.top: parent.top anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width + anchors.leftMargin: UM.Theme.getSize("thick_margin").width color: base.statusColor font: UM.Theme.getFont("large") @@ -224,12 +224,12 @@ Item property string backgroundColor: UM.Theme.getColor("progressbar_background"); property string controlColor: base.statusColor; - width: parent.width - 2 * UM.Theme.getSize("sidebar_margin").width; + width: parent.width - 2 * UM.Theme.getSize("thick_margin").width; height: UM.Theme.getSize("progressbar").height; anchors.top: statusLabel.bottom; - anchors.topMargin: Math.round(UM.Theme.getSize("sidebar_margin").height / 4); + anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height / 4); anchors.left: parent.left; - anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width; + anchors.leftMargin: UM.Theme.getSize("thick_margin").width; } Row @@ -237,9 +237,9 @@ Item id: buttonsRow height: abortButton.height anchors.top: progressBar.bottom - anchors.topMargin: UM.Theme.getSize("sidebar_margin").height + anchors.topMargin: UM.Theme.getSize("thick_margin").height anchors.right: parent.right - anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width + anchors.rightMargin: UM.Theme.getSize("thick_margin").width spacing: UM.Theme.getSize("default_margin").width Row diff --git a/resources/qml/MonitorSidebar.qml b/resources/qml/MonitorSidebar.qml index 179fcafb53..2282034739 100644 --- a/resources/qml/MonitorSidebar.qml +++ b/resources/qml/MonitorSidebar.qml @@ -30,7 +30,7 @@ Rectangle property variant printMaterialCosts: PrintInformation.materialCosts property variant printMaterialNames: PrintInformation.materialNames - color: UM.Theme.getColor("sidebar") + color: UM.Theme.getColor("main_background") UM.I18nCatalog { id: catalog; name: "cura"} Timer { @@ -89,7 +89,7 @@ Rectangle { id: machineSelection width: base.width - configSelection.width - separator.width - height: UM.Theme.getSize("sidebar_header").height + height: UM.Theme.getSize("stage_menu").height anchors.top: base.top anchors.left: parent.left } @@ -98,9 +98,9 @@ Rectangle { id: separator visible: configSelection.visible - width: visible ? Math.round(UM.Theme.getSize("sidebar_lining_thin").height / 2) : 0 - height: UM.Theme.getSize("sidebar_header").height - color: UM.Theme.getColor("sidebar_lining_thin") + width: visible ? Math.round(UM.Theme.getSize("thick_lining").height / 2) : 0 + height: UM.Theme.getSize("stage_menu").height + color: UM.Theme.getColor("thick_lining") anchors.left: machineSelection.right } @@ -109,7 +109,7 @@ Rectangle id: configSelection visible: isNetworkPrinter && printerConnected width: visible ? Math.round(base.width * 0.15) : 0 - height: UM.Theme.getSize("sidebar_header").height + height: UM.Theme.getSize("stage_menu").height anchors.top: base.top anchors.right: parent.right panelWidth: base.width @@ -158,10 +158,10 @@ Rectangle { id: footerSeparator width: parent.width - height: UM.Theme.getSize("sidebar_lining").height - color: UM.Theme.getColor("sidebar_lining") + height: UM.Theme.getSize("wide_lining").height + color: UM.Theme.getColor("wide_lining") anchors.bottom: monitorButton.top - anchors.bottomMargin: UM.Theme.getSize("sidebar_margin").height + anchors.bottomMargin: UM.Theme.getSize("thick_margin").height } // MonitorButton is actually the bottom footer panel. diff --git a/resources/qml/PrintMonitor.qml b/resources/qml/PrintMonitor.qml index 12e95d1e89..723279847a 100644 --- a/resources/qml/PrintMonitor.qml +++ b/resources/qml/PrintMonitor.qml @@ -31,14 +31,14 @@ Column Rectangle { - color: UM.Theme.getColor("sidebar_lining") + color: UM.Theme.getColor("wide_lining") width: parent.width height: childrenRect.height Flow { id: extrudersGrid - spacing: UM.Theme.getSize("sidebar_lining_thin").width + spacing: UM.Theme.getSize("thick_lining").width width: parent.width Repeater @@ -48,8 +48,8 @@ Column ExtruderBox { - color: UM.Theme.getColor("sidebar") - width: index == machineExtruderCount.properties.value - 1 && index % 2 == 0 ? extrudersGrid.width : Math.round(extrudersGrid.width / 2 - UM.Theme.getSize("sidebar_lining_thin").width / 2) + color: UM.Theme.getColor("main_background") + width: index == machineExtruderCount.properties.value - 1 && index % 2 == 0 ? extrudersGrid.width : Math.round(extrudersGrid.width / 2 - UM.Theme.getSize("thick_lining").width / 2) extruderModel: modelData } } @@ -58,9 +58,9 @@ Column Rectangle { - color: UM.Theme.getColor("sidebar_lining") + color: UM.Theme.getColor("wide_lining") width: parent.width - height: UM.Theme.getSize("sidebar_lining_thin").width + height: UM.Theme.getSize("thick_lining").width } HeatedBedBox diff --git a/resources/qml/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector.qml index d9b2337c96..987e3ecce9 100644 --- a/resources/qml/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector.qml @@ -25,7 +25,7 @@ Rectangle property variant printMaterialCosts: PrintInformation.materialCosts property variant printMaterialNames: PrintInformation.materialNames - color: UM.Theme.getColor("sidebar") + color: UM.Theme.getColor("main_background") UM.I18nCatalog { id: catalog; name: "cura"} // This widget doesn't show tooltips by itself. Instead it emits signals so others can do something with it. @@ -89,7 +89,7 @@ Rectangle { left: parent.left top: parent.top - margins: UM.Theme.getSize("sidebar_margin").width + margins: UM.Theme.getSize("thick_margin").width } width: Math.round(parent.width * 0.45) @@ -105,10 +105,10 @@ Rectangle id: settingsModeSelection model: modesListModel width: Math.round(parent.width * 0.55) - height: UM.Theme.getSize("sidebar_header_mode_toggle").height + height: UM.Theme.getSize("print_setup_mode_toggle").height anchors.right: parent.right - anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width + anchors.rightMargin: UM.Theme.getSize("thick_margin").width anchors.top: settingsModeLabel.top @@ -186,7 +186,7 @@ Rectangle { id: sidebarContents anchors.top: settingsModeSelection.bottom - anchors.topMargin: UM.Theme.getSize("sidebar_margin").height + anchors.topMargin: UM.Theme.getSize("thick_margin").height anchors.left: parent.left anchors.right: parent.right height: UM.Theme.getSize("print_setup_widget").height diff --git a/resources/qml/PrinterOutput/ExtruderBox.qml b/resources/qml/PrinterOutput/ExtruderBox.qml index f0abd4cd6c..510a44f9da 100644 --- a/resources/qml/PrinterOutput/ExtruderBox.qml +++ b/resources/qml/PrinterOutput/ExtruderBox.qml @@ -13,7 +13,7 @@ Item property var extruderModel property var position: index implicitWidth: parent.width - implicitHeight: UM.Theme.getSize("sidebar_extruder_box").height + implicitHeight: UM.Theme.getSize("print_setup_extruder_box").height UM.SettingPropertyProvider { diff --git a/resources/qml/PrinterOutput/HeatedBedBox.qml b/resources/qml/PrinterOutput/HeatedBedBox.qml index 9de66ad0be..962ffa9b01 100644 --- a/resources/qml/PrinterOutput/HeatedBedBox.qml +++ b/resources/qml/PrinterOutput/HeatedBedBox.qml @@ -12,12 +12,12 @@ import Cura 1.0 as Cura Item { implicitWidth: parent.width - height: visible ? UM.Theme.getSize("sidebar_extruder_box").height : 0 + height: visible ? UM.Theme.getSize("print_setup_extruder_box").height : 0 property var printerModel Rectangle { - color: UM.Theme.getColor("sidebar") + color: UM.Theme.getColor("main_background") anchors.fill: parent Label //Build plate label. diff --git a/resources/qml/SaveButton.qml b/resources/qml/SaveButton.qml index 5e41dd3007..c2d310e30c 100644 --- a/resources/qml/SaveButton.qml +++ b/resources/qml/SaveButton.qml @@ -68,10 +68,10 @@ Item Label { id: statusLabel - width: parent.width - 2 * UM.Theme.getSize("sidebar_margin").width + width: parent.width - 2 * UM.Theme.getSize("thick_margin").width anchors.top: parent.top anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width + anchors.leftMargin: UM.Theme.getSize("thick_margin").width color: UM.Theme.getColor("text") font: UM.Theme.getFont("default_bold") @@ -81,12 +81,12 @@ Item Rectangle { id: progressBar - width: parent.width - 2 * UM.Theme.getSize("sidebar_margin").width + width: parent.width - 2 * UM.Theme.getSize("thick_margin").width height: UM.Theme.getSize("progressbar").height anchors.top: statusLabel.bottom - anchors.topMargin: Math.round(UM.Theme.getSize("sidebar_margin").height / 4) + anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height / 4) anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width + anchors.leftMargin: UM.Theme.getSize("thick_margin").width radius: UM.Theme.getSize("progressbar_radius").width color: UM.Theme.getColor("progressbar_background") @@ -133,11 +133,11 @@ Item children_width += child.width + child.anchors.rightMargin; } } - return Math.min(children_width, base.width - UM.Theme.getSize("sidebar_margin").width); + return Math.min(children_width, base.width - UM.Theme.getSize("thick_margin").width); } height: saveToButton.height anchors.bottom: parent.bottom - anchors.bottomMargin: UM.Theme.getSize("sidebar_margin").height + anchors.bottomMargin: UM.Theme.getSize("thick_margin").height anchors.right: parent.right clip: true @@ -198,7 +198,7 @@ Item anchors.top: parent.top anchors.right: parent.right - anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width + anchors.rightMargin: UM.Theme.getSize("thick_margin").width // 1 = not started, 4 = error, 5 = disabled text: [1, 4, 5].indexOf(base.backendState) != -1 ? catalog.i18nc("@label:Printjob", "Prepare") : catalog.i18nc("@label:Printjob", "Cancel") @@ -253,7 +253,7 @@ Item Behavior on color { ColorAnimation { duration: 50; } } - implicitWidth: actualLabel.contentWidth + (UM.Theme.getSize("sidebar_margin").width * 2) + implicitWidth: actualLabel.contentWidth + (UM.Theme.getSize("thick_margin").width * 2) Label { @@ -299,7 +299,7 @@ Item anchors.top: parent.top anchors.right: deviceSelectionMenu.visible ? deviceSelectionMenu.left : parent.right - anchors.rightMargin: deviceSelectionMenu.visible ? -3 * UM.Theme.getSize("default_lining").width : UM.Theme.getSize("sidebar_margin").width + anchors.rightMargin: deviceSelectionMenu.visible ? -3 * UM.Theme.getSize("default_lining").width : UM.Theme.getSize("thick_margin").width text: UM.OutputDeviceManager.activeDeviceShortDescription onClicked: @@ -355,7 +355,7 @@ Item Behavior on color { ColorAnimation { duration: 50; } } - implicitWidth: actualLabel.contentWidth + (UM.Theme.getSize("sidebar_margin").width * 2) + implicitWidth: actualLabel.contentWidth + (UM.Theme.getSize("thick_margin").width * 2) Label { @@ -377,7 +377,7 @@ Item anchors.top: parent.top anchors.right: parent.right - anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width + anchors.rightMargin: UM.Theme.getSize("thick_margin").width width: UM.Theme.getSize("save_button_save_to_button").height height: UM.Theme.getSize("save_button_save_to_button").height diff --git a/resources/qml/Settings/SettingCategory.qml b/resources/qml/Settings/SettingCategory.qml index e3202323eb..7995619af0 100644 --- a/resources/qml/Settings/SettingCategory.qml +++ b/resources/qml/Settings/SettingCategory.qml @@ -12,8 +12,8 @@ Button id: base anchors.left: parent.left anchors.right: parent.right - anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width - anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width + anchors.leftMargin: UM.Theme.getSize("thick_margin").width + anchors.rightMargin: UM.Theme.getSize("thick_margin").width background: Rectangle { id: backgroundRectangle diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index 785562cff5..cad6a28bd6 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -128,11 +128,11 @@ Item { id: settingControls height: Math.round(parent.height / 2) - spacing: Math.round(UM.Theme.getSize("sidebar_margin").height / 2) + spacing: Math.round(UM.Theme.getSize("thick_margin").height / 2) anchors { right: controlContainer.left - rightMargin: Math.round(UM.Theme.getSize("sidebar_margin").width / 2) + rightMargin: Math.round(UM.Theme.getSize("thick_margin").width / 2) verticalCenter: parent.verticalCenter } @@ -290,7 +290,7 @@ Item { enabled: propertyProvider.isValueUsed anchors.right: parent.right; - anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width + anchors.rightMargin: UM.Theme.getSize("thick_margin").width anchors.verticalCenter: parent.verticalCenter; width: UM.Theme.getSize("setting_control").width; height: UM.Theme.getSize("setting_control").height diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 5a6811926e..cd9701aab6 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -24,15 +24,15 @@ Item Item { id: globalProfileRow - height: UM.Theme.getSize("sidebar_setup").height + height: UM.Theme.getSize("print_setup_item").height anchors { top: parent.top left: parent.left - leftMargin: Math.round(UM.Theme.getSize("sidebar_margin").width) + leftMargin: Math.round(UM.Theme.getSize("thick_margin").width) right: parent.right - rightMargin: Math.round(UM.Theme.getSize("sidebar_margin").width) + rightMargin: Math.round(UM.Theme.getSize("thick_margin").width) } Label @@ -40,7 +40,7 @@ Item id: globalProfileLabel text: catalog.i18nc("@label","Profile:") textFormat: Text.PlainText - width: Math.round(parent.width * 0.45 - UM.Theme.getSize("sidebar_margin").width - 2) + width: Math.round(parent.width * 0.45 - UM.Theme.getSize("thick_margin").width - 2) font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") verticalAlignment: Text.AlignVCenter @@ -87,7 +87,7 @@ Item anchors.verticalCenter: parent.verticalCenter anchors.right: parent.right - anchors.rightMargin: Math.round(UM.Theme.getSize("setting_preferences_button_margin").width - UM.Theme.getSize("sidebar_margin").width) + anchors.rightMargin: Math.round(UM.Theme.getSize("setting_preferences_button_margin").width - UM.Theme.getSize("thick_margin").width) color: hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button"); iconSource: UM.Theme.getIcon("star"); @@ -100,7 +100,7 @@ Item onEntered: { var content = catalog.i18nc("@tooltip","Some setting/override values are different from the values stored in the profile.\n\nClick to open the profile manager.") - base.showTooltip(globalProfileRow, Qt.point(-UM.Theme.getSize("sidebar_margin").width, 0), content) + base.showTooltip(globalProfileRow, Qt.point(-UM.Theme.getSize("thick_margin").width, 0), content) } onExited: base.hideTooltip() } @@ -116,9 +116,9 @@ Item anchors { top: globalProfileRow.bottom - topMargin: UM.Theme.getSize("sidebar_margin").height + topMargin: UM.Theme.getSize("thick_margin").height right: parent.right - rightMargin: UM.Theme.getSize("sidebar_margin").width + rightMargin: UM.Theme.getSize("thick_margin").width } style: ButtonStyle { @@ -169,9 +169,9 @@ Item anchors { top: globalProfileRow.bottom - topMargin: UM.Theme.getSize("sidebar_margin").height + topMargin: UM.Theme.getSize("thick_margin").height left: parent.left - leftMargin: UM.Theme.getSize("sidebar_margin").width + leftMargin: UM.Theme.getSize("thick_margin").width right: settingVisibilityMenu.left rightMargin: Math.floor(UM.Theme.getSize("default_margin").width / 2) } @@ -191,7 +191,7 @@ Item height: parent.height anchors.left: parent.left anchors.right: clearFilterButton.left - anchors.rightMargin: Math.round(UM.Theme.getSize("sidebar_margin").width) + anchors.rightMargin: Math.round(UM.Theme.getSize("thick_margin").width) placeholderText: catalog.i18nc("@label:textbox", "Search...") @@ -288,7 +288,7 @@ Item anchors.bottom: parent.bottom; anchors.right: parent.right; anchors.left: parent.left; - anchors.topMargin: UM.Theme.getSize("sidebar_margin").height + anchors.topMargin: UM.Theme.getSize("thick_margin").height style: UM.Theme.styles.scrollview; flickableItem.flickableDirection: Flickable.VerticalFlick; @@ -325,7 +325,7 @@ Item { id: delegate - width: Math.round(UM.Theme.getSize("sidebar").width); + width: Math.round(UM.Theme.getSize("print_setup_widget").width); height: provider.properties.enabled == "True" ? UM.Theme.getSize("section").height : - contents.spacing Behavior on height { NumberAnimation { duration: 100 } } opacity: provider.properties.enabled == "True" ? 1 : 0 diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index ec673f2823..b5c94c3f82 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -35,7 +35,7 @@ Item { width: childrenRect.width height: childrenRect.height - color: UM.Theme.getColor("sidebar") + color: UM.Theme.getColor("main_background") // // Quality profile @@ -44,10 +44,10 @@ Item { id: qualityRow - height: UM.Theme.getSize("sidebar_margin").height - anchors.topMargin: UM.Theme.getSize("sidebar_margin").height + height: UM.Theme.getSize("thick_margin").height + anchors.topMargin: UM.Theme.getSize("thick_margin").height anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width + anchors.leftMargin: UM.Theme.getSize("thick_margin").width anchors.right: parent.right Timer @@ -207,7 +207,7 @@ Item { anchors.verticalCenter: parent.verticalCenter anchors.top: parent.top - anchors.topMargin: Math.round(UM.Theme.getSize("sidebar_margin").height / 2) + anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height / 2) color: (Cura.MachineManager.activeMachine != null && Cura.QualityProfilesDropDownMenuModel.getItem(index).available) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") text: { @@ -262,10 +262,10 @@ Item { id: speedSlider width: Math.round(base.width * 0.55) - height: UM.Theme.getSize("sidebar_margin").height + height: UM.Theme.getSize("thick_margin").height anchors.right: parent.right anchors.top: parent.top - anchors.topMargin: UM.Theme.getSize("sidebar_margin").height + anchors.topMargin: UM.Theme.getSize("thick_margin").height // This Item is used only for tooltip, for slider area which is unavailable Item @@ -275,7 +275,7 @@ Item if (showTooltip) { var content = catalog.i18nc("@tooltip", "This quality profile is not available for you current material and nozzle configuration. Please change these to enable this quality profile") - base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("sidebar_margin").width, customisedSettings.height), content) + base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), content) } else { @@ -380,7 +380,7 @@ Item Slider { id: qualitySlider - height: UM.Theme.getSize("sidebar_margin").height + height: UM.Theme.getSize("thick_margin").height anchors.bottom: speedSlider.bottom enabled: qualityModel.totalTicks > 0 && !Cura.SimpleModeSettingsManager.isProfileCustomized visible: qualityModel.availableTotalTicks > 0 @@ -448,7 +448,7 @@ Item onEntered: { var content = catalog.i18nc("@tooltip","A custom profile is currently active. To enable the quality slider, choose a default quality profile in Custom tab") - base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("sidebar_margin").width, customisedSettings.height), content) + base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), content) } onExited: { @@ -467,7 +467,7 @@ Item text: catalog.i18nc("@label", "Print Speed") font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") - width: Math.round(UM.Theme.getSize("sidebar").width * 0.35) + width: Math.round(UM.Theme.getSize("print_setup_widget").width * 0.35) elide: Text.ElideRight } @@ -503,7 +503,7 @@ Item anchors.verticalCenter: speedSlider.verticalCenter anchors.right: speedSlider.left - anchors.rightMargin: Math.round(UM.Theme.getSize("sidebar_margin").width / 2) + anchors.rightMargin: Math.round(UM.Theme.getSize("thick_margin").width / 2) color: hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button"); iconSource: UM.Theme.getIcon("reset"); @@ -516,7 +516,7 @@ Item onEntered: { var content = catalog.i18nc("@tooltip","You have modified some profile settings. If you want to change these go to custom mode.") - base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("sidebar_margin").width, customisedSettings.height), content) + base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), content) } onExited: base.hideTooltip() } @@ -530,10 +530,10 @@ Item id: infillCellLeft anchors.top: qualityRow.bottom - anchors.topMargin: UM.Theme.getSize("sidebar_margin").height * 2 + anchors.topMargin: UM.Theme.getSize("thick_margin").height * 2 anchors.left: parent.left - width: Math.round(UM.Theme.getSize("sidebar").width * .45) - UM.Theme.getSize("sidebar_margin").width + width: Math.round(UM.Theme.getSize("print_setup_widget").width * .45) - UM.Theme.getSize("thick_margin").width Label { @@ -543,9 +543,9 @@ Item color: UM.Theme.getColor("text") anchors.top: parent.top - anchors.topMargin: Math.round(UM.Theme.getSize("sidebar_margin").height * 1.7) + anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height * 1.7) anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width + anchors.leftMargin: UM.Theme.getSize("thick_margin").width } } @@ -553,12 +553,12 @@ Item { id: infillCellRight - height: infillSlider.height + UM.Theme.getSize("sidebar_margin").height + enableGradualInfillCheckBox.visible * (enableGradualInfillCheckBox.height + UM.Theme.getSize("sidebar_margin").height) - width: Math.round(UM.Theme.getSize("sidebar").width * .55) + height: infillSlider.height + UM.Theme.getSize("thick_margin").height + enableGradualInfillCheckBox.visible * (enableGradualInfillCheckBox.height + UM.Theme.getSize("thick_margin").height) + width: Math.round(UM.Theme.getSize("print_setup_widget").width * .55) anchors.left: infillCellLeft.right anchors.top: infillCellLeft.top - anchors.topMargin: UM.Theme.getSize("sidebar_margin").height + anchors.topMargin: UM.Theme.getSize("thick_margin").height Label { id: selectedInfillRateText @@ -588,10 +588,10 @@ Item anchors.top: selectedInfillRateText.bottom anchors.left: parent.left anchors.right: infillIcon.left - anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width + anchors.rightMargin: UM.Theme.getSize("thick_margin").width - height: UM.Theme.getSize("sidebar_margin").height - width: parseInt(infillCellRight.width - UM.Theme.getSize("sidebar_margin").width - style.handleWidth) + height: UM.Theme.getSize("thick_margin").height + width: parseInt(infillCellRight.width - UM.Theme.getSize("thick_margin").width - style.handleWidth) minimumValue: 0 maximumValue: 100 @@ -679,12 +679,12 @@ Item { id: infillIcon - width: Math.round((parent.width / 5) - (UM.Theme.getSize("sidebar_margin").width)) + width: Math.round((parent.width / 5) - (UM.Theme.getSize("thick_margin").width)) height: width anchors.right: parent.right anchors.top: parent.top - anchors.topMargin: Math.round(UM.Theme.getSize("sidebar_margin").height / 2) + anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height / 2) // we loop over all density icons and only show the one that has the current density and steps Repeater @@ -737,7 +737,7 @@ Item property alias _hovered: enableGradualInfillMouseArea.containsMouse anchors.top: infillSlider.bottom - anchors.topMargin: Math.round(UM.Theme.getSize("sidebar_margin").height / 2) // closer to slider since it belongs to the same category + anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height / 2) // closer to slider since it belongs to the same category anchors.left: infillCellRight.left style: UM.Theme.styles.checkbox @@ -786,7 +786,7 @@ Item id: gradualInfillLabel height: parent.height anchors.left: enableGradualInfillCheckBox.right - anchors.leftMargin: Math.round(UM.Theme.getSize("sidebar_margin").width / 2) + anchors.leftMargin: Math.round(UM.Theme.getSize("thick_margin").width / 2) verticalAlignment: Text.AlignVCenter; text: catalog.i18nc("@label", "Enable gradual") font: UM.Theme.getFont("default") @@ -848,11 +848,11 @@ Item visible: enableSupportCheckBox.visible anchors.top: infillCellRight.bottom - anchors.topMargin: Math.round(UM.Theme.getSize("sidebar_margin").height * 1.5) + anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height * 1.5) anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width + anchors.leftMargin: UM.Theme.getSize("thick_margin").width anchors.right: infillCellLeft.right - anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width + anchors.rightMargin: UM.Theme.getSize("thick_margin").width anchors.verticalCenter: enableSupportCheckBox.verticalCenter text: catalog.i18nc("@label", "Generate Support"); @@ -916,11 +916,11 @@ Item textRole: "text" // this solves that the combobox isn't populated in the first time Cura is started anchors.top: enableSupportCheckBox.top - //anchors.topMargin: ((supportEnabled.properties.value === "True") && (machineExtruderCount.properties.value > 1)) ? UM.Theme.getSize("sidebar_margin").height : 0 + //anchors.topMargin: ((supportEnabled.properties.value === "True") && (machineExtruderCount.properties.value > 1)) ? UM.Theme.getSize("thick_margin").height : 0 anchors.left: enableSupportCheckBox.right - anchors.leftMargin: Math.round(UM.Theme.getSize("sidebar_margin").width / 2) + anchors.leftMargin: Math.round(UM.Theme.getSize("thick_margin").width / 2) - width: Math.round(UM.Theme.getSize("sidebar").width * .55) - Math.round(UM.Theme.getSize("sidebar_margin").width / 2) - enableSupportCheckBox.width + width: Math.round(UM.Theme.getSize("print_setup_widget").width * .55) - Math.round(UM.Theme.getSize("thick_margin").width / 2) - enableSupportCheckBox.width height: ((supportEnabled.properties.value == "True") && (machineExtruderCount.properties.value > 1)) ? UM.Theme.getSize("setting_control").height : 0 Behavior on height { NumberAnimation { duration: 100 } } @@ -991,9 +991,9 @@ Item anchors { left: parent.left - leftMargin: UM.Theme.getSize("sidebar_margin").width + leftMargin: UM.Theme.getSize("thick_margin").width right: infillCellLeft.right - rightMargin: UM.Theme.getSize("sidebar_margin").width + rightMargin: UM.Theme.getSize("thick_margin").width verticalCenter: adhesionCheckBox.verticalCenter } } @@ -1004,7 +1004,7 @@ Item property alias _hovered: adhesionMouseArea.containsMouse anchors.top: enableSupportCheckBox.bottom - anchors.topMargin: UM.Theme.getSize("sidebar_margin").height + anchors.topMargin: UM.Theme.getSize("thick_margin").height anchors.left: infillCellRight.left //: Setting enable printing build-plate adhesion helper checkbox @@ -1065,7 +1065,7 @@ Item { id: tipsCell anchors.top: adhesionCheckBox.visible ? adhesionCheckBox.bottom : (enableSupportCheckBox.visible ? supportExtruderCombobox.bottom : infillCellRight.bottom) - anchors.topMargin: Math.round(UM.Theme.getSize("sidebar_margin").height * 2) + anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height * 2) anchors.left: parent.left width: parent.width height: tipsText.contentHeight * tipsText.lineCount @@ -1074,9 +1074,9 @@ Item { id: tipsText anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width + anchors.leftMargin: UM.Theme.getSize("thick_margin").width anchors.right: parent.right - anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width + anchors.rightMargin: UM.Theme.getSize("thick_margin").width anchors.top: parent.top wrapMode: Text.WordWrap text: catalog.i18nc("@label", "Need help improving your prints?
Read the
Ultimaker Troubleshooting Guides").arg("https://ultimaker.com/en/troubleshooting") diff --git a/resources/themes/cura-dark/theme.json b/resources/themes/cura-dark/theme.json index 1625750a19..571e1acbe4 100644 --- a/resources/themes/cura-dark/theme.json +++ b/resources/themes/cura-dark/theme.json @@ -5,7 +5,9 @@ }, "colors": { - "sidebar": [39, 44, 48, 255], + "main_background": [39, 44, 48, 255], + "wide_lining": [31, 36, 39, 255], + "thick_lining": [255, 255, 255, 30], "lining": [64, 69, 72, 255], "viewport_overlay": [0, 6, 9, 222], @@ -18,6 +20,9 @@ "main_window_header_button_text_inactive": [128, 128, 128, 255], "main_window_header_button_text_hovered": [255, 255, 255, 255], + "machine_selector_bar": [39, 44, 48, 255], + "machine_selector_active": [39, 44, 48, 255], + "text": [255, 255, 255, 204], "text_detail": [255, 255, 255, 172], "text_link": [255, 255, 255, 127], @@ -30,16 +35,6 @@ "text_scene_hover": [255, 255, 255, 204], "error": [212, 31, 53, 255], - "sidebar_header_bar": [39, 44, 48, 255], - "sidebar_header_active": [39, 44, 48, 255], - "sidebar_header_hover": [68, 72, 75, 255], - "sidebar_header_highlight": [68, 192, 255, 255], - "sidebar_header_highlight_hover": [68, 192, 255, 255], - "sidebar_header_text_active": [255, 255, 255, 255], - "sidebar_header_text_hover": [255, 255, 255, 255], - "sidebar_header_text_inactive": [255, 255, 255, 127], - "sidebar_lining": [31, 36, 39, 255], - "sidebar_lining_thin": [255, 255, 255, 30], "button": [39, 44, 48, 255], "button_hover": [39, 44, 48, 255], diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index 1bbb13ff26..43e8d29b57 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -491,9 +491,9 @@ QtObject { anchors.fill: parent anchors.left: parent.left - anchors.leftMargin: Theme.getSize("sidebar_margin").width + anchors.leftMargin: Theme.getSize("thick_margin").width anchors.right: parent.right - anchors.rightMargin: Theme.getSize("sidebar_margin").width + anchors.rightMargin: Theme.getSize("thick_margin").width implicitHeight: Theme.getSize("section").height color: { @@ -567,7 +567,7 @@ QtObject { anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left - anchors.leftMargin: Theme.getSize("sidebar_margin").width + anchors.leftMargin: Theme.getSize("thick_margin").width color: { if(!control.enabled) @@ -1037,7 +1037,7 @@ QtObject } Behavior on color { ColorAnimation { duration: 50 } } - implicitWidth: actualLabel.contentWidth + (UM.Theme.getSize("sidebar_margin").width * 2) + implicitWidth: actualLabel.contentWidth + (UM.Theme.getSize("thick_margin").width * 2) Label { diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 38d4f5372f..4b1252abf4 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -69,7 +69,9 @@ "colors": { - "sidebar": [255, 255, 255, 255], + "main_background": [255, 255, 255, 255], + "wide_lining": [245, 245, 245, 255], + "thick_lining": [127, 127, 127, 255], "lining": [192, 193, 194, 255], "viewport_overlay": [0, 0, 0, 192], @@ -97,6 +99,11 @@ "account_widget_outline_active": [70, 66, 126, 255], "account_widget_outline_inactive": [229, 229, 229, 255], + "machine_selector_bar": [31, 36, 39, 255], + "machine_selector_active": [68, 72, 75, 255], + "machine_selector_hover": [68, 72, 75, 255], + "machine_selector_text_active": [255, 255, 255, 255], + "text": [0, 0, 0, 255], "text_detail": [174, 174, 174, 128], "text_link": [12, 169, 227, 255], @@ -110,16 +117,6 @@ "text_scene_hover": [70, 84, 113, 255], "error": [255, 140, 0, 255], - "sidebar_header_bar": [31, 36, 39, 255], - "sidebar_header_active": [68, 72, 75, 255], - "sidebar_header_hover": [68, 72, 75, 255], - "sidebar_header_highlight": [68, 192, 255, 255], - "sidebar_header_highlight_hover": [68, 192, 255, 255], - "sidebar_header_text_inactive": [255, 255, 255, 255], - "sidebar_header_text_active": [255, 255, 255, 255], - "sidebar_header_text_hover": [255, 255, 255, 255], - "sidebar_lining": [245, 245, 245, 255], - "sidebar_lining_thin": [127, 127, 127, 255], "button": [31, 36, 39, 255], "button_hover": [68, 72, 75, 255], @@ -356,35 +353,34 @@ "account_button": [12, 3], "print_setup_widget": [35.0, 42.0], - "configuration_selector_widget": [35.0, 0.0], + "print_setup_mode_toggle": [0.0, 2.0], + "print_setup_item": [0.0, 2.0], + "print_setup_extruder_box": [0.0, 6.0], + + "configuration_selector_widget": [35.0, 4.5], + "configuration_selector_mode_tabs": [0.0, 3.0], + + "action_panel_widget": [35.0, 0.0], + "machine_selector_widget": [28.0, 4.5], "views_selector": [0.0, 4.0], + "wide_lining": [0.5, 0.5], + "thick_lining": [0.2, 0.2], "default_lining": [0.08, 0.08], + "default_arrow": [0.8, 0.8], "logo": [8, 2.4], - "default_margin": [1.0, 1.0], "wide_margin": [2.0, 2.0], + "thick_margin": [1.71, 1.43], + "default_margin": [1.0, 1.0], + "thin_margin": [0.71, 0.71], "narrow_margin": [0.5, 0.5], - "window_margin": [1.0, 1.0], "extruder_button_material_margin": [0.70, 0.9], "extruder_button_material": [0.75, 0.75], - "sidebar": [35.0, 10.0], - "sidebar_margin": [1.71, 1.43], - "sidebar_margin_thin": [0.71, 0.71], - "sidebar_header": [0.0, 4.0], - "sidebar_header_highlight": [0.25, 0.25], - "sidebar_header_mode_toggle": [0.0, 2.0], - "sidebar_header_mode_tabs": [0.0, 3.0], - "sidebar_lining": [0.5, 0.5], - "sidebar_lining_thin": [0.2, 0.2], - "sidebar_setup": [0.0, 2.0], - "sidebar_tabs": [0.0, 3.5], - "sidebar_inputfields": [0.0, 2.0], - "sidebar_extruder_box": [0.0, 6.0], "simple_mode_infill_caption": [0.0, 5.0], "simple_mode_infill_height": [0.0, 8.0], @@ -495,6 +491,7 @@ "toolbox_property_label": [1.0, 2.0], "toolbox_heading_label": [1.0, 4.0], "toolbox_header": [1.0, 4.0], + "toolbox_header_highlight": [0.25, 0.25], "toolbox_progress_bar": [8.0, 0.5], "toolbox_chart_row": [1.0, 2.0], "toolbox_action_button": [8.0, 2.5], From 5a759fa9f493bb034170b0cec566653b22b51793 Mon Sep 17 00:00:00 2001 From: pinchies Date: Sat, 27 Oct 2018 03:47:29 +1100 Subject: [PATCH 0087/1292] fix start routing --- resources/definitions/jgaurora_a5.def.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/definitions/jgaurora_a5.def.json b/resources/definitions/jgaurora_a5.def.json index 6143ef1523..0a8b93f7cf 100644 --- a/resources/definitions/jgaurora_a5.def.json +++ b/resources/definitions/jgaurora_a5.def.json @@ -20,7 +20,7 @@ "default_value": "JGAurora A5" }, "machine_start_gcode": { - "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F6000 ;move Z to position 15.0 mm as fast as possible\nG92 E0 ;zero the extruded length\nG1 X0.0 Y0.0 F1000.0 ;go to edge of print area\nG1 X60.0 E9.0 F1000.0 ;intro line\nG1 X100.0 E21.5 F1000.0 ;intro line\nG92 E0 ;zero the extruded length again\n; -- end of START GCODE --" + "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 ;home all axis\nM420 S1 ;turn on mesh bed levelling if enabled in firmware\nG92 E0 ;zero the extruded length\nG1 Z1 F1000 ;move up slightly\nG1 X60.0 Z0 E9.0 F1000.0;intro line\nG1 X100.0 E21.5 F1000.0 ;continue line\nG92 E0 ;zero the extruded length again\n; -- end of START GCODE --" }, "machine_end_gcode": { "default_value": "; -- END GCODE --\nM104 S0 ;turn off nozzle heater\nM140 S0 ;turn off bed heater\nG91 ;set to relative positioning\nG1 E-10 F300 ;retract the filament slightly\nG90 ;set to absolute positioning\nG28 X0 ;move to the X-axis origin (Home)\nG0 Y280 F600 ;bring the bed to the front for easy print removal\nM84 ;turn off stepper motors\n; -- end of END GCODE --" @@ -95,4 +95,4 @@ "default_value": 45 } } -} \ No newline at end of file +} From 6fa382a527137024d84a4cdf169cfc8a7dce67bb Mon Sep 17 00:00:00 2001 From: pinchies Date: Sat, 27 Oct 2018 03:48:24 +1100 Subject: [PATCH 0088/1292] Update jgaurora_a1.def.json --- resources/definitions/jgaurora_a1.def.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/definitions/jgaurora_a1.def.json b/resources/definitions/jgaurora_a1.def.json index 004fd8741d..4fd2eb4994 100644 --- a/resources/definitions/jgaurora_a1.def.json +++ b/resources/definitions/jgaurora_a1.def.json @@ -18,7 +18,7 @@ "default_value": "JGAurora A1" }, "machine_start_gcode": { - "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F6000 ;move Z to position 15.0 mm as fast as possible\nG92 E0 ;zero the extruded length\nG1 X0.0 Y0.0 F1000.0 ;go to edge of print area\nG1 X60.0 E9.0 F1000.0 ;intro line\nG1 X100.0 E21.5 F1000.0 ;intro line\nG92 E0 ;zero the extruded length again\n; -- end of START GCODE --" + "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 ;home all axis\nM420 S1 ;turn on mesh bed levelling if enabled in firmware\nG92 E0 ;zero the extruded length\nG1 Z1 F1000 ;move up slightly\nG1 X60.0 Z0 E9.0 F1000.0;intro line\nG1 X100.0 E21.5 F1000.0 ;continue line\nG92 E0 ;zero the extruded length again\n; -- end of START GCODE --" }, "machine_end_gcode": { "default_value": "; -- END GCODE --\nM104 S0 ;turn off nozzle heater\nM140 S0 ;turn off bed heater\nG91 ;set to relative positioning\nG1 E-10 F300 ;retract the filament slightly\nG90 ;set to absolute positioning\nG28 X0 ;move to the X-axis origin (Home)\nG0 Y280 F600 ;bring the bed to the front for easy print removal\nM84 ;turn off stepper motors\n; -- end of END GCODE --" @@ -93,4 +93,4 @@ "default_value": 40 } } -} \ No newline at end of file +} From 0487288edfaf3c10ae69112ab393e54eef4d01df Mon Sep 17 00:00:00 2001 From: pinchies Date: Sat, 27 Oct 2018 03:49:34 +1100 Subject: [PATCH 0089/1292] Update alfawise_u20.def.json --- resources/definitions/alfawise_u20.def.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/definitions/alfawise_u20.def.json b/resources/definitions/alfawise_u20.def.json index f6dccce3ee..abc206c4d2 100644 --- a/resources/definitions/alfawise_u20.def.json +++ b/resources/definitions/alfawise_u20.def.json @@ -18,7 +18,7 @@ "default_value": "Alfawise U20" }, "machine_start_gcode": { - "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F6000 ;move Z to position 15.0 mm as fast as possible\nG92 E0 ;zero the extruded length\nG1 X0.0 Y0.0 F1000.0 ;go to edge of print area\nG1 X60.0 E9.0 F1000.0 ;intro line\nG1 X100.0 E21.5 F1000.0 ;intro line\nG92 E0 ;zero the extruded length again\n; -- end of START GCODE --" + "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 ;home all axis\nG92 E0 ;zero the extruded length\nG1 Z1 F1000 ;move up slightly\nG1 X60.0 Z0 E9.0 F1000.0;intro line\nG1 X100.0 E21.5 F1000.0 ;continue line\nG92 E0 ;zero the extruded length again\n; -- end of START GCODE --" }, "machine_end_gcode": { "default_value": "; -- END GCODE --\nM104 S0 ;turn off nozzle heater\nM140 S0 ;turn off bed heater\nG91 ;set to relative positioning\nG1 E-10 F300 ;retract the filament slightly\nG90 ;set to absolute positioning\nG28 X0 ;move to the X-axis origin (Home)\nG0 Y280 F600 ;bring the bed to the front for easy print removal\nM84 ;turn off stepper motors\n; -- end of END GCODE --" @@ -93,4 +93,4 @@ "default_value": 45 } } -} \ No newline at end of file +} From 46c6ef71abfcdb6d617c724e3f72af77a5e48176 Mon Sep 17 00:00:00 2001 From: pinchies Date: Sat, 27 Oct 2018 03:50:15 +1100 Subject: [PATCH 0090/1292] Update jgaurora_z_603s.def.json --- resources/definitions/jgaurora_z_603s.def.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/definitions/jgaurora_z_603s.def.json b/resources/definitions/jgaurora_z_603s.def.json index af7fa823db..59e0ff129c 100644 --- a/resources/definitions/jgaurora_z_603s.def.json +++ b/resources/definitions/jgaurora_z_603s.def.json @@ -18,7 +18,7 @@ "default_value": "JGAurora Z-603S" }, "machine_start_gcode": { - "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F6000 ;move Z to position 15.0 mm as fast as possible\nG92 E0 ;zero the extruded length\nG1 X0.0 Y0.0 F1000.0 ;go to edge of print area\nG1 X60.0 E9.0 F1000.0 ;intro line\nG1 X100.0 E21.5 F1000.0 ;intro line\nG92 E0 ;zero the extruded length again\n; -- end of START GCODE --" + "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 ;home all axis\nM420 S1 ;turn on mesh bed levelling if enabled in firmware\nG92 E0 ;zero the extruded length\nG1 Z1 F1000 ;move up slightly\nG1 X60.0 Z0 E9.0 F1000.0;intro line\nG1 X100.0 E21.5 F1000.0 ;continue line\nG92 E0 ;zero the extruded length again\n; -- end of START GCODE --" }, "machine_end_gcode": { "default_value": "; -- END GCODE --\nM104 S0 ;turn off nozzle heater\nM140 S0 ;turn off bed heater\nG91 ;set to relative positioning\nG1 E-10 F300 ;retract the filament slightly\nG90 ;set to absolute positioning\nG28 X0 ;move to the X-axis origin (Home)\nG0 Y280 F600 ;bring the bed to the front for easy print removal\nM84 ;turn off stepper motors\n; -- end of END GCODE --" @@ -93,4 +93,4 @@ "default_value": 50 } } -} \ No newline at end of file +} From cdb5ab193051b4fb16752aeb57fe386c9a3d4e59 Mon Sep 17 00:00:00 2001 From: pinchies Date: Sat, 27 Oct 2018 03:51:05 +1100 Subject: [PATCH 0091/1292] Update cocoon_create_modelmaker.def.json --- resources/definitions/cocoon_create_modelmaker.def.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/definitions/cocoon_create_modelmaker.def.json b/resources/definitions/cocoon_create_modelmaker.def.json index f752a08fc7..7f19fb0239 100644 --- a/resources/definitions/cocoon_create_modelmaker.def.json +++ b/resources/definitions/cocoon_create_modelmaker.def.json @@ -18,7 +18,7 @@ "default_value": "Cocoon Create ModelMaker" }, "machine_start_gcode": { - "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F6000 ;move Z to position 15.0 mm as fast as possible\nG92 E0 ;zero the extruded length\nG1 X0.0 Y0.0 F1000.0 ;go to edge of print area\nG1 X60.0 E9.0 F1000.0 ;intro line\nG1 X100.0 E21.5 F1000.0 ;intro line\nG92 E0 ;zero the extruded length again\n; -- end of START GCODE --" + "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 ;home all axis\nG92 E0 ;zero the extruded length\nG1 Z1 F1000 ;move up slightly\nG1 X60.0 Z0 E9.0 F1000.0;intro line\nG1 X100.0 E21.5 F1000.0 ;continue line\nG92 E0 ;zero the extruded length again\n; -- end of START GCODE --" }, "machine_end_gcode": { "default_value": "; -- END GCODE --\nM104 S0 ;turn off nozzle heater\nG91 ;set to relative positioning\nG1 E-10 F300 ;retract the filament slightly\nG90 ;set to absolute positioning\nG28 X0 Y0 ;move to the XY-axis origin (Home)\nM84 ;turn off stepper motors\n; -- end of END GCODE --" @@ -93,4 +93,4 @@ "default_value": 40 } } -} \ No newline at end of file +} From 3248a05819fccd54f71f6765ff5846b15c22b181 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 29 Oct 2018 11:28:08 +0100 Subject: [PATCH 0092/1292] Add PreviewStagePlugin stubs Since we are going to move all the views into a seperate stage, we need to add another stage to do that. CURA-5829 --- cura/CuraApplication.py | 1 + plugins/MonitorStage/__init__.py | 4 +++- plugins/PreviewStage/PreviewStage.py | 13 +++++++++++++ plugins/PreviewStage/__init__.py | 22 ++++++++++++++++++++++ plugins/PreviewStage/plugin.json | 8 ++++++++ 5 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 plugins/PreviewStage/PreviewStage.py create mode 100644 plugins/PreviewStage/__init__.py create mode 100644 plugins/PreviewStage/plugin.json diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 5824d21b1c..8f9816e968 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -433,6 +433,7 @@ class CuraApplication(QtApplication): "XmlMaterialProfile", "Toolbox", "PrepareStage", + "PreviewStage", "MonitorStage", "LocalFileOutputDevice", "LocalContainerProvider", diff --git a/plugins/MonitorStage/__init__.py b/plugins/MonitorStage/__init__.py index bdaf53a36c..0468e6319b 100644 --- a/plugins/MonitorStage/__init__.py +++ b/plugins/MonitorStage/__init__.py @@ -7,14 +7,16 @@ from . import MonitorStage from UM.i18n import i18nCatalog i18n_catalog = i18nCatalog("cura") + def getMetaData(): return { "stage": { "name": i18n_catalog.i18nc("@item:inmenu", "Monitor"), - "weight": 1 + "weight": 2 } } + def register(app): return { "stage": MonitorStage.MonitorStage() diff --git a/plugins/PreviewStage/PreviewStage.py b/plugins/PreviewStage/PreviewStage.py new file mode 100644 index 0000000000..a51bf766b6 --- /dev/null +++ b/plugins/PreviewStage/PreviewStage.py @@ -0,0 +1,13 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +from UM.Application import Application +from cura.Stages.CuraStage import CuraStage + + +class PreviewStage(CuraStage): + def __init__(self, parent = None) -> None: + super().__init__(parent) + Application.getInstance().engineCreatedSignal.connect(self._engineCreated) + + def _engineCreated(self): + return \ No newline at end of file diff --git a/plugins/PreviewStage/__init__.py b/plugins/PreviewStage/__init__.py new file mode 100644 index 0000000000..e03992fc00 --- /dev/null +++ b/plugins/PreviewStage/__init__.py @@ -0,0 +1,22 @@ +# Copyright (c) 2017 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from . import PreviewStage + +from UM.i18n import i18nCatalog +i18n_catalog = i18nCatalog("cura") + + +def getMetaData(): + return { + "stage": { + "name": i18n_catalog.i18nc("@item:inmenu", "Preview"), + "weight": 1 + } + } + + +def register(app): + return { + "stage": PreviewStage.PreviewStage() + } diff --git a/plugins/PreviewStage/plugin.json b/plugins/PreviewStage/plugin.json new file mode 100644 index 0000000000..9349da2b0e --- /dev/null +++ b/plugins/PreviewStage/plugin.json @@ -0,0 +1,8 @@ +{ + "name": "Preview Stage", + "author": "Ultimaker B.V.", + "version": "1.0.0", + "description": "Provides a preview stage in Cura.", + "api": 5, + "i18n-catalog": "cura" +} \ No newline at end of file From 9cc7a7ca23df6427f5e921ca1594dfd8c3ed176a Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 29 Oct 2018 13:27:47 +0100 Subject: [PATCH 0093/1292] Moved view selection to previewStage CURA-5829 --- plugins/PreviewStage/PreviewMenu.qml | 77 ++++++++++++++++++++ plugins/PreviewStage/PreviewStage.py | 26 ++++++- plugins/PreviewStage/__init__.py | 2 +- resources/qml/Cura.qml | 62 ---------------- resources/qml/MainWindow/ApplicationMenu.qml | 2 - 5 files changed, 100 insertions(+), 69 deletions(-) create mode 100644 plugins/PreviewStage/PreviewMenu.qml diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml new file mode 100644 index 0000000000..c364c4c3d7 --- /dev/null +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -0,0 +1,77 @@ +import QtQuick 2.7 + +import QtQuick.Controls 1.4 + +import UM 1.3 as UM +import Cura 1.1 as Cura + +Item +{ + id: previewMenu + // This widget doesn't show tooltips by itself. Instead it emits signals so others can do something with it. + signal showTooltip(Item item, point location, string text) + signal hideTooltip() + + UM.I18nCatalog + { + id: catalog + name: "cura" + } + + Row + { + anchors.horizontalCenter: parent.horizontalCenter + ComboBox + { + // This item contains the views selector, a combobox that is dynamically created from + // the list of available Views (packages that create different visualizations of the + // scene). + id: viewModeButton + + style: UM.Theme.styles.combobox + + model: UM.ViewModel { } + textRole: "name" + + // update the model's active index + function updateItemActiveFlags() + { + currentIndex = getActiveIndex() + for (var i = 0; i < model.rowCount(); i++) + { + model.getItem(i).active = (i == currentIndex) + } + } + + // get the index of the active model item on start + function getActiveIndex() + { + for (var i = 0; i < model.rowCount(); i++) + { + print(model.getItem(i).active) + if (model.getItem(i).active) + { + return i; + } + } + return 0 + } + + onCurrentIndexChanged: + { + if (model.getItem(currentIndex).id != undefined) + { + UM.Controller.setActiveView(model.getItem(currentIndex).id) + } + } + currentIndex: getActiveIndex() + } + + Cura.PrintSetupSelector + { + width: UM.Theme.getSize("print_setup_widget").width + onShowTooltip: previewMenu.showTooltip(item, location, text) + onHideTooltip: previewMenu.hideTooltip() + } + } +} \ No newline at end of file diff --git a/plugins/PreviewStage/PreviewStage.py b/plugins/PreviewStage/PreviewStage.py index a51bf766b6..4c449e55f2 100644 --- a/plugins/PreviewStage/PreviewStage.py +++ b/plugins/PreviewStage/PreviewStage.py @@ -1,13 +1,31 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +import os.path + from UM.Application import Application from cura.Stages.CuraStage import CuraStage +from typing import TYPE_CHECKING, Optional + +if TYPE_CHECKING: + from UM.View import View class PreviewStage(CuraStage): - def __init__(self, parent = None) -> None: + def __init__(self, application: Application, parent = None) -> None: super().__init__(parent) - Application.getInstance().engineCreatedSignal.connect(self._engineCreated) + self._application = application + self._application.engineCreatedSignal.connect(self._engineCreated) + self._previously_active_view = None # type: Optional[View] - def _engineCreated(self): - return \ No newline at end of file + def onStageSelected(self) -> None: + self._previously_active_view = self._application.getController().getActiveView() + + def onStageDeselected(self) -> None: + if self._previously_active_view is not None: + self._application.getController().setActiveView(self._previously_active_view.getPluginId()) + self._previously_active_view = None + + def _engineCreated(self) -> None: + menu_component_path = os.path.join(self._application.getPluginRegistry().getPluginPath(self.getPluginId()), + "PreviewMenu.qml") + self.addDisplayComponent("menu", menu_component_path) diff --git a/plugins/PreviewStage/__init__.py b/plugins/PreviewStage/__init__.py index e03992fc00..d58826934e 100644 --- a/plugins/PreviewStage/__init__.py +++ b/plugins/PreviewStage/__init__.py @@ -18,5 +18,5 @@ def getMetaData(): def register(app): return { - "stage": PreviewStage.PreviewStage() + "stage": PreviewStage.PreviewStage(app) } diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 3e2515cb3e..c3d2c98ecc 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -230,68 +230,6 @@ UM.MainWindow } } - ComboBox - { - // This item contains the views selector, a combobox that is dynamically created from - // the list of available Views (packages that create different visualizations of the - // scene). - id: viewModeButton - - anchors.left: viewOrientationControls.right - anchors.bottom: viewOrientationControls.bottom - - style: UM.Theme.styles.combobox - - model: UM.ViewModel { } - textRole: "name" - - // update the model's active index - function updateItemActiveFlags() - { - currentIndex = getActiveIndex() - for (var i = 0; i < model.rowCount(); i++) - { - model.getItem(i).active = (i == currentIndex) - } - } - - // get the index of the active model item on start - function getActiveIndex () - { - for (var i = 0; i < model.rowCount(); i++) - { - if (model.getItem(i).active) - { - return i; - } - } - return 0 - } - - // set the active index - function setActiveIndex(index) - { - UM.Controller.setActiveView(index) - // the connection to UM.ActiveView will trigger update so there is no reason to call it manually here - } - - onCurrentIndexChanged: - { - if (model.getItem(currentIndex).id != undefined) - { - viewModeButton.setActiveIndex(model.getItem(currentIndex).id) - } - } - currentIndex: getActiveIndex() - - // watch the active view proxy for changes made from the menu item - Connections - { - target: UM.ActiveView - onActiveViewChanged: viewModeButton.updateItemActiveFlags() - } - } - Loader { id: viewPanel diff --git a/resources/qml/MainWindow/ApplicationMenu.qml b/resources/qml/MainWindow/ApplicationMenu.qml index d3bc115419..884609deee 100644 --- a/resources/qml/MainWindow/ApplicationMenu.qml +++ b/resources/qml/MainWindow/ApplicationMenu.qml @@ -45,8 +45,6 @@ Item MenuItem { action: Cura.Actions.unGroupObjects } } - ViewMenu { title: catalog.i18nc("@title:menu menubar:toplevel", "&View") } - SettingsMenu { title: catalog.i18nc("@title:menu menubar:toplevel", "&Settings") } Menu From ebe533bdc831c9872d3d0c352e73134656de253e Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 29 Oct 2018 13:39:00 +0100 Subject: [PATCH 0094/1292] Move active view panel to previewStage CURA-5829 --- plugins/PreviewStage/PreviewMenu.qml | 15 +++++++++++++++ resources/qml/Cura.qml | 16 ---------------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index c364c4c3d7..0ab1c0be83 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -21,6 +21,8 @@ Item Row { anchors.horizontalCenter: parent.horizontalCenter + spacing: UM.Theme.getSize("default_margin").width + ComboBox { // This item contains the views selector, a combobox that is dynamically created from @@ -67,6 +69,19 @@ Item currentIndex: getActiveIndex() } + Loader + { + // TODO: Make this panel collapsable and ensure it has a standardised background. + id: viewPanel + + property var buttonTarget: Qt.point(viewModeButton.x + Math.round(viewModeButton.width / 2), viewModeButton.y + Math.round(viewModeButton.height / 2)) + + height: childrenRect.height + width: childrenRect.width + + source: UM.ActiveView.valid ? UM.ActiveView.activeViewPanel : "" + } + Cura.PrintSetupSelector { width: UM.Theme.getSize("print_setup_widget").width diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index c3d2c98ecc..9f53b75dd1 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -230,22 +230,6 @@ UM.MainWindow } } - Loader - { - id: viewPanel - - anchors.bottom: viewModeButton.top - anchors.topMargin: UM.Theme.getSize("default_margin").height - anchors.right: viewModeButton.right - - property var buttonTarget: Qt.point(viewModeButton.x + Math.round(viewModeButton.width / 2), viewModeButton.y + Math.round(viewModeButton.height / 2)) - - height: childrenRect.height - width: childrenRect.width - - source: UM.ActiveView.valid ? UM.ActiveView.activeViewPanel : "" - } - Cura.ActionPanelWidget { anchors.right: parent.right From fc6ad4f6233833a2b59d4086306a21e1de3427f4 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 29 Oct 2018 13:41:46 +0100 Subject: [PATCH 0095/1292] Put back the view menu, since it did more than just show the views CURA-5829 --- resources/qml/MainWindow/ApplicationMenu.qml | 2 ++ resources/qml/Menus/ViewMenu.qml | 19 ------------------- 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/resources/qml/MainWindow/ApplicationMenu.qml b/resources/qml/MainWindow/ApplicationMenu.qml index 884609deee..d3bc115419 100644 --- a/resources/qml/MainWindow/ApplicationMenu.qml +++ b/resources/qml/MainWindow/ApplicationMenu.qml @@ -45,6 +45,8 @@ Item MenuItem { action: Cura.Actions.unGroupObjects } } + ViewMenu { title: catalog.i18nc("@title:menu menubar:toplevel", "&View") } + SettingsMenu { title: catalog.i18nc("@title:menu menubar:toplevel", "&Settings") } Menu diff --git a/resources/qml/Menus/ViewMenu.qml b/resources/qml/Menus/ViewMenu.qml index 593bd63bcc..33e8764cd8 100644 --- a/resources/qml/Menus/ViewMenu.qml +++ b/resources/qml/Menus/ViewMenu.qml @@ -15,25 +15,6 @@ Menu property var multiBuildPlateModel: CuraApplication.getMultiBuildPlateModel() - // main views - Instantiator - { - model: UM.ViewModel{} - MenuItem - { - text: model.name - checkable: true - checked: model.active - exclusiveGroup: group - onTriggered: UM.Controller.setActiveView(model.id) - } - onObjectAdded: base.insertItem(index, object) - onObjectRemoved: base.removeItem(object) - } - ExclusiveGroup { id: group } - - MenuSeparator {} - Menu { title: catalog.i18nc("@action:inmenu menubar:view","&Camera position"); From cfa962311bb45476fcc9e65dd24933bb9f2aa397 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 29 Oct 2018 13:54:20 +0100 Subject: [PATCH 0096/1292] Fixed typing CURA-5829 --- plugins/PreviewStage/PreviewStage.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/plugins/PreviewStage/PreviewStage.py b/plugins/PreviewStage/PreviewStage.py index 4c449e55f2..e41d4a592f 100644 --- a/plugins/PreviewStage/PreviewStage.py +++ b/plugins/PreviewStage/PreviewStage.py @@ -2,16 +2,17 @@ # Cura is released under the terms of the LGPLv3 or higher. import os.path -from UM.Application import Application +from UM.Qt.QtApplication import QtApplication from cura.Stages.CuraStage import CuraStage from typing import TYPE_CHECKING, Optional if TYPE_CHECKING: - from UM.View import View + from UM.View.View import View + class PreviewStage(CuraStage): - def __init__(self, application: Application, parent = None) -> None: + def __init__(self, application: QtApplication, parent = None) -> None: super().__init__(parent) self._application = application self._application.engineCreatedSignal.connect(self._engineCreated) @@ -26,6 +27,7 @@ class PreviewStage(CuraStage): self._previously_active_view = None def _engineCreated(self) -> None: - menu_component_path = os.path.join(self._application.getPluginRegistry().getPluginPath(self.getPluginId()), - "PreviewMenu.qml") - self.addDisplayComponent("menu", menu_component_path) + plugin_path = self._application.getPluginRegistry().getPluginPath(self.getPluginId()) + if plugin_path is not None: + menu_component_path = os.path.join(plugin_path, "PreviewMenu.qml") + self.addDisplayComponent("menu", menu_component_path) From d8dd9bf3631bcfd5cd77d11cb41688127dd31e60 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 29 Oct 2018 14:54:42 +0100 Subject: [PATCH 0097/1292] Set SolidView to invisible. Since we don't have a selector in the prepare stage anymore, solidview must be invisible CURA-5829 --- plugins/PreviewStage/PreviewMenu.qml | 1 - plugins/SolidView/__init__.py | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index 0ab1c0be83..ae875fb0a2 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -50,7 +50,6 @@ Item { for (var i = 0; i < model.rowCount(); i++) { - print(model.getItem(i).active) if (model.getItem(i).active) { return i; diff --git a/plugins/SolidView/__init__.py b/plugins/SolidView/__init__.py index db2e48f489..34148fcf05 100644 --- a/plugins/SolidView/__init__.py +++ b/plugins/SolidView/__init__.py @@ -10,7 +10,8 @@ def getMetaData(): return { "view": { "name": i18n_catalog.i18nc("@item:inmenu", "Solid view"), - "weight": 0 + "weight": 0, + "visible": False } } From bf59097320d7f5eaf4bd072cde2d8a841d27c550 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 29 Oct 2018 15:18:34 +0100 Subject: [PATCH 0098/1292] Split the action button panel in two different components that are loaded in different moments. The SliceProcessWidget is loaded once there is something to slice and it also shows the process of slicing. The OutputProcessWidget will show the print information and the actions to do to output the results, such as Print over network, Save to file, ... Contributes to CURA-5786. --- resources/qml/ActionPanelWidget.qml | 239 +++---------------------- resources/qml/Cura.qml | 17 +- resources/qml/OutputProcessWidget.qml | 72 ++++++++ resources/qml/SliceProcessWidget.qml | 62 +++++++ resources/themes/cura-light/theme.json | 4 + 5 files changed, 172 insertions(+), 222 deletions(-) create mode 100644 resources/qml/OutputProcessWidget.qml create mode 100644 resources/qml/SliceProcessWidget.qml diff --git a/resources/qml/ActionPanelWidget.qml b/resources/qml/ActionPanelWidget.qml index b5dc7f83c9..d1fe999731 100644 --- a/resources/qml/ActionPanelWidget.qml +++ b/resources/qml/ActionPanelWidget.qml @@ -2,7 +2,7 @@ // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 import QtQuick.Layouts 1.3 import UM 1.2 as UM @@ -10,230 +10,43 @@ import Cura 1.0 as Cura Rectangle { - id: base + id: actionPanelWidget - // We need a whole lot of print duration information. - property variant printDuration: PrintInformation.currentPrintTime - - // This widget doesn't show tooltips by itself. Instead it emits signals so others can do something with it. - signal showTooltip(Item item, point location, string text) - signal hideTooltip() + width: childrenRect.width + 2 * UM.Theme.getSize("thick_margin").width + height: childrenRect.height + 2 * UM.Theme.getSize("thick_margin").height color: UM.Theme.getColor("main_background") + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("lining") + radius: UM.Theme.getSize("default_radius").width + visible: CuraApplication.platformActivity - // Also add an extra margin, as we want some breathing room around the edges. - height: saveButton.height + UM.Theme.getSize("thick_margin").height - Label + property bool backendStatusDone: UM.Backend.state == 3 + + Loader { - id: timeDetails - anchors.left: parent.left - anchors.bottom: costSpec.top - anchors.leftMargin: UM.Theme.getSize("thick_margin").width - - font: UM.Theme.getFont("large") - color: UM.Theme.getColor("text_subtext") - text: (!base.printDuration || !base.printDuration.valid) ? catalog.i18nc("@label Hours and minutes", "00h 00min") : base.printDuration.getDisplayString(UM.DurationFormat.Short) - renderType: Text.NativeRendering - - MouseArea + id: loader + anchors { - id: timeDetailsMouseArea - anchors.fill: parent - hoverEnabled: true - - onEntered: - { - if(base.printDuration.valid && !base.printDuration.isTotalDurationZero) - { - // All the time information for the different features is achieved - var print_time = PrintInformation.getFeaturePrintTimes(); - var total_seconds = parseInt(base.printDuration.getDisplayString(UM.DurationFormat.Seconds)) - - // A message is created and displayed when the user hover the time label - var tooltip_html = "%1
".arg(catalog.i18nc("@tooltip", "Time specification")); - for(var feature in print_time) - { - if(!print_time[feature].isTotalDurationZero) - { - tooltip_html += "" + - "".arg(print_time[feature].getDisplayString(UM.DurationFormat.ISO8601).slice(0,-3)) + - "".arg(Math.round(100 * parseInt(print_time[feature].getDisplayString(UM.DurationFormat.Seconds)) / total_seconds)) + - ""; - } - } - tooltip_html += "
" + feature + ":  %1  %1%
"; - base.showTooltip(parent, Qt.point(-UM.Theme.getSize("thick_margin").width, 0), tooltip_html); - } - } - onExited: - { - base.hideTooltip(); - } + top: parent.top + topMargin: UM.Theme.getSize("thick_margin").height + left: parent.left + leftMargin: UM.Theme.getSize("thick_margin").width } + sourceComponent: backendStatusDone ? outputProcessWidget : sliceProcessWidget } - Label + Behavior on height { NumberAnimation { duration: 100 } } + + Component { - function formatRow(items) - { - var row_html = ""; - for(var item = 0; item < items.length; item++) - { - if (item == 0) - { - row_html += "%1".arg(items[item]); - } - else - { - row_html += "  %1".arg(items[item]); - } - } - row_html += ""; - return row_html; - } - - function getSpecsData() - { - var lengths = []; - var total_length = 0; - var weights = []; - var total_weight = 0; - var costs = []; - var total_cost = 0; - var some_costs_known = false; - var names = []; - if(base.printMaterialLengths) - { - for(var index = 0; index < base.printMaterialLengths.length; index++) - { - if(base.printMaterialLengths[index] > 0) - { - names.push(base.printMaterialNames[index]); - lengths.push(base.printMaterialLengths[index].toFixed(2)); - weights.push(String(Math.round(base.printMaterialWeights[index]))); - var cost = base.printMaterialCosts[index] == undefined ? 0 : base.printMaterialCosts[index].toFixed(2); - costs.push(cost); - if(cost > 0) - { - some_costs_known = true; - } - - total_length += base.printMaterialLengths[index]; - total_weight += base.printMaterialWeights[index]; - total_cost += base.printMaterialCosts[index]; - } - } - } - if(lengths.length == 0) - { - lengths = ["0.00"]; - weights = ["0"]; - costs = ["0.00"]; - } - - var tooltip_html = "%1
".arg(catalog.i18nc("@label", "Cost specification")); - for(var index = 0; index < lengths.length; index++) - { - tooltip_html += formatRow([ - "%1:".arg(names[index]), - catalog.i18nc("@label m for meter", "%1m").arg(lengths[index]), - catalog.i18nc("@label g for grams", "%1g").arg(weights[index]), - "%1 %2".arg(UM.Preferences.getValue("cura/currency")).arg(costs[index]), - ]); - } - if(lengths.length > 1) - { - tooltip_html += formatRow([ - catalog.i18nc("@label", "Total:"), - catalog.i18nc("@label m for meter", "%1m").arg(total_length.toFixed(2)), - catalog.i18nc("@label g for grams", "%1g").arg(Math.round(total_weight)), - "%1 %2".arg(UM.Preferences.getValue("cura/currency")).arg(total_cost.toFixed(2)), - ]); - } - tooltip_html += "
"; - tooltipText = tooltip_html; - - return tooltipText - } - - id: costSpec - - anchors.left: parent.left - anchors.bottom: parent.bottom - anchors.bottomMargin: UM.Theme.getSize("thick_margin").height - anchors.leftMargin: UM.Theme.getSize("thick_margin").width - - font: UM.Theme.getFont("very_small") - renderType: Text.NativeRendering - color: UM.Theme.getColor("text_subtext") - elide: Text.ElideMiddle - width: parent.width - property string tooltipText - text: - { - var lengths = []; - var weights = []; - var costs = []; - var someCostsKnown = false; - if(base.printMaterialLengths) - { - for(var index = 0; index < base.printMaterialLengths.length; index++) - { - if(base.printMaterialLengths[index] > 0) - { - lengths.push(base.printMaterialLengths[index].toFixed(2)); - weights.push(String(Math.round(base.printMaterialWeights[index]))); - var cost = base.printMaterialCosts[index] == undefined ? 0 : base.printMaterialCosts[index].toFixed(2); - costs.push(cost); - if(cost > 0) - { - someCostsKnown = true; - } - } - } - } - if(lengths.length == 0) - { - lengths = ["0.00"]; - weights = ["0"]; - costs = ["0.00"]; - } - var result = lengths.join(" + ") + "m / ~ " + weights.join(" + ") + "g"; - if(someCostsKnown) - { - result += " / ~ " + costs.join(" + ") + " " + UM.Preferences.getValue("cura/currency"); - } - return result; - } - - MouseArea - { - id: costSpecMouseArea - anchors.fill: parent - hoverEnabled: true - - onEntered: - { - - if(base.printDuration.valid && !base.printDuration.isTotalDurationZero) - { - var show_data = costSpec.getSpecsData() - - base.showTooltip(parent, Qt.point(-UM.Theme.getSize("thick_margin").width, 0), show_data); - } - } - onExited: - { - base.hideTooltip(); - } - } + id: sliceProcessWidget + SliceProcessWidget { } } - SaveButton + Component { - id: saveButton - width: parent.width - height: 100 * screenScaleFactor - anchors.bottom: parent.bottom + id: outputProcessWidget + OutputProcessWidget { } } } \ No newline at end of file diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 3e2515cb3e..1f4d71e460 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -312,17 +312,16 @@ UM.MainWindow { anchors.right: parent.right anchors.bottom: parent.bottom - width: UM.Theme.getSize("action_panel_widget").width anchors.rightMargin: UM.Theme.getSize("thick_margin").width anchors.bottomMargin: UM.Theme.getSize("thick_margin").height - onShowTooltip: - { - base.showTooltip(item, location, text) - } - onHideTooltip: - { - base.hideTooltip() - } +// onShowTooltip: +// { +// base.showTooltip(item, location, text) +// } +// onHideTooltip: +// { +// base.hideTooltip() +// } } Loader diff --git a/resources/qml/OutputProcessWidget.qml b/resources/qml/OutputProcessWidget.qml new file mode 100644 index 0000000000..612e4f286f --- /dev/null +++ b/resources/qml/OutputProcessWidget.qml @@ -0,0 +1,72 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.1 +import QtQuick.Layouts 1.3 + +import UM 1.1 as UM + +Button +{ + id: button + property alias cursorShape: mouseArea.cursorShape + property alias iconSource: buttonIcon.source + property alias textFont: buttonText.font + property alias cornerRadius: backgroundRect.radius + property var color: UM.Theme.getColor("primary") + property var hoverColor: UM.Theme.getColor("primary_hover") + property var disabledColor: color + property var textColor: UM.Theme.getColor("button_text") + property var textHoverColor: UM.Theme.getColor("button_text_hover") + property var textDisabledColor: textColor + property var outlineColor: color + property var outlineHoverColor: hoverColor + property var outlineDisabledColor: outlineColor + + contentItem: Row + { + UM.RecolorImage + { + id: buttonIcon + source: "" + height: Math.round(0.6 * parent.height) + width: height + sourceSize.width: width + sourceSize.height: height + color: button.hovered ? button.textHoverColor : button.textColor + visible: source != "" + anchors.verticalCenter: parent.verticalCenter + Behavior on color { ColorAnimation { duration: 50 } } + } + + Label + { + id: buttonText + text: "Preview" + color: button.enabled ? (button.hovered ? button.textHoverColor : button.textColor): button.textDisabledColor + font: UM.Theme.getFont("action_button") + visible: text != "" + renderType: Text.NativeRendering + anchors.verticalCenter: parent.verticalCenter + } + } + + background: Rectangle + { + id: backgroundRect + color: button.enabled ? (button.hovered ? button.hoverColor : button.color) : button.disabledColor + radius: UM.Theme.getSize("action_button_radius").width + border.width: UM.Theme.getSize("default_lining").width + border.color: button.enabled ? (button.hovered ? button.outlineHoverColor : button.outlineColor) : button.outlineDisabledColor + Behavior on color { ColorAnimation { duration: 50 } } + } + + MouseArea + { + id: mouseArea + anchors.fill: parent + onPressed: mouse.accepted = false + hoverEnabled: true + } +} diff --git a/resources/qml/SliceProcessWidget.qml b/resources/qml/SliceProcessWidget.qml new file mode 100644 index 0000000000..67005cb133 --- /dev/null +++ b/resources/qml/SliceProcessWidget.qml @@ -0,0 +1,62 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.1 +import QtQuick.Layouts 1.3 + +import UM 1.1 as UM +import Cura 1.0 as Cura + +Column +{ + id: widget + + spacing: UM.Theme.getSize("default_margin").height + + UM.I18nCatalog + { + id: catalog + name: "cura" + } + + property real progress: UM.Backend.progress + property int backendState: UM.Backend.state + + Rectangle + { + id: progressBar + width: parent.width + height: UM.Theme.getSize("progressbar").height + visible: widget.backendState == 2 + radius: UM.Theme.getSize("progressbar_radius").width + color: UM.Theme.getColor("progressbar_background") + + Rectangle + { + width: Math.max(parent.width * base.progress) + height: parent.height + radius: UM.Theme.getSize("progressbar_radius").width + color: UM.Theme.getColor("progressbar_control") + } + } + + Cura.ActionButton + { + id: prepareButton + width: UM.Theme.getSize("action_panel_button").width + height: UM.Theme.getSize("action_panel_button").height + text: widget.backendState == 1 ? catalog.i18nc("@button", "Prepare") : catalog.i18nc("@button", "Cancel") + onClicked: + { + if ([1, 5].indexOf(widget.backendState) != -1) + { + CuraApplication.backend.forceSlice() + } + else + { + CuraApplication.backend.stopSlicing() + } + } + } +} diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 29e3774e1f..e840a08a75 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -378,10 +378,14 @@ "configuration_selector_mode_tabs": [0.0, 3.0], "action_panel_widget": [35.0, 0.0], + "action_panel_button": [15.0, 3.0], + "machine_selector_widget": [28.0, 4.5], "views_selector": [0.0, 4.0], + "default_radius": [0.25, 0.25], + "wide_lining": [0.5, 0.5], "thick_lining": [0.2, 0.2], "default_lining": [0.08, 0.08], From e486bf8b440dd3a392779821e4720f53537f66c3 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 29 Oct 2018 15:55:16 +0100 Subject: [PATCH 0099/1292] Change the primary color to a slightly different kind of blue. Contributes to CURA-5786. --- resources/themes/cura-light/theme.json | 48 +++++++++++++------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index e840a08a75..cbd5b29e87 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -75,7 +75,7 @@ "lining": [192, 193, 194, 255], "viewport_overlay": [0, 0, 0, 192], - "primary": [12, 169, 227, 255], + "primary": [50, 130, 255, 255], "primary_hover": [48, 182, 231, 255], "primary_text": [255, 255, 255, 255], "border": [127, 127, 127, 255], @@ -106,10 +106,10 @@ "text": [0, 0, 0, 255], "text_detail": [174, 174, 174, 128], - "text_link": [12, 169, 227, 255], + "text_link": [50, 130, 255, 255], "text_inactive": [174, 174, 174, 255], "text_hover": [70, 84, 113, 255], - "text_pressed": [12, 169, 227, 255], + "text_pressed": [50, 130, 255, 255], "text_subtext": [0, 0, 0, 255], "text_medium": [128, 128, 128, 255], "text_emphasis": [255, 255, 255, 255], @@ -152,16 +152,16 @@ "action_button_border": [127, 127, 127, 255], "action_button_hovered": [255, 255, 255, 255], "action_button_hovered_text": [31, 36, 39, 255], - "action_button_hovered_border": [12, 169, 227, 255], + "action_button_hovered_border": [50, 130, 255, 255], "action_button_active": [255, 255, 255, 255], "action_button_active_text": [0, 0, 0, 255], - "action_button_active_border": [12, 169, 227, 255], + "action_button_active_border": [50, 130, 255, 255], "action_button_disabled": [245, 245, 245, 255], "action_button_disabled_text": [127, 127, 127, 255], "action_button_disabled_border": [245, 245, 245, 255], - "print_button_ready": [12, 169, 227, 255], - "print_button_ready_border": [12, 169, 227, 255], + "print_button_ready": [50, 130, 255, 255], + "print_button_ready_border": [50, 130, 255, 255], "print_button_ready_text": [255, 255, 255, 255], "print_button_ready_hovered": [30, 186, 245, 243], "print_button_ready_hovered_border": [30, 186, 245, 243], @@ -193,7 +193,7 @@ "setting_control_selected": [31, 36, 39, 255], "setting_control_highlight": [255, 255, 255, 255], "setting_control_border": [127, 127, 127, 255], - "setting_control_border_highlight": [12, 169, 227, 255], + "setting_control_border_highlight": [50, 130, 255, 255], "setting_control_text": [27, 27, 27, 255], "setting_control_depth_line": [127, 127, 127, 255], "setting_control_button": [127, 127, 127, 255], @@ -231,18 +231,18 @@ "checkbox": [255, 255, 255, 255], "checkbox_hover": [255, 255, 255, 255], "checkbox_border": [64, 69, 72, 255], - "checkbox_border_hover": [12, 169, 227, 255], + "checkbox_border_hover": [50, 130, 255, 255], "checkbox_mark": [119, 122, 124, 255], "checkbox_text": [27, 27, 27, 255], "mode_switch": [255, 255, 255, 255], "mode_switch_hover": [255, 255, 255, 255], "mode_switch_border": [127, 127, 127, 255], - "mode_switch_border_hover": [12, 169, 227, 255], + "mode_switch_border_hover": [50, 130, 255, 255], "mode_switch_handle": [31, 36, 39, 255], "mode_switch_text": [31, 36, 39, 255], "mode_switch_text_hover": [31, 36, 39, 255], - "mode_switch_text_checked": [12, 169, 227, 255], + "mode_switch_text_checked": [50, 130, 255, 255], "tooltip": [68, 192, 255, 255], "tooltip_text": [255, 255, 255, 255], @@ -253,9 +253,9 @@ "message_shadow": [0, 0, 0, 120], "message_border": [127, 127, 127, 255], "message_text": [0, 0, 0, 255], - "message_button": [12, 169, 227, 255], - "message_button_hover": [12, 169, 227, 255], - "message_button_active": [12, 169, 227, 255], + "message_button": [50, 130, 255, 255], + "message_button_hover": [50, 130, 255, 255], + "message_button_active": [50, 130, 255, 255], "message_button_text": [255, 255, 255, 255], "message_button_text_hover": [255, 255, 255, 255], "message_button_text_active": [255, 255, 255, 255], @@ -266,7 +266,7 @@ "status_offline": [0, 0, 0, 255], "status_ready": [0, 205, 0, 255], - "status_busy": [12, 169, 227, 255], + "status_busy": [50, 130, 255, 255], "status_paused": [255, 140, 0, 255], "status_stopped": [236, 82, 80, 255], "status_unknown": [127, 127, 127, 255], @@ -278,7 +278,7 @@ "all_axis": [255, 255, 255, 255], "viewport_background": [245, 245, 245, 255], - "volume_outline": [12, 169, 227, 255], + "volume_outline": [50, 130, 255, 255], "buildplate": [244, 244, 244, 255], "buildplate_grid": [129, 131, 134, 255], "buildplate_grid_minor": [230, 230, 231, 255], @@ -291,7 +291,7 @@ "model_overhang": [255, 0, 0, 255], "model_unslicable": [122, 122, 122, 255], "model_unslicable_alt": [172, 172, 127, 255], - "model_selection_outline": [12, 169, 227, 255], + "model_selection_outline": [50, 130, 255, 255], "model_non_printing": [122, 122, 122, 255], "xray": [26, 26, 62, 255], @@ -317,12 +317,12 @@ "configuration_item_text_active": [0, 0, 0, 255], "configuration_item_border": [127, 127, 127, 255], "configuration_item_border_active": [12, 169, 227, 32], - "configuration_item_border_hover": [12, 169, 227, 255], + "configuration_item_border_hover": [50, 130, 255, 255], - "tab_status_connected": [12, 169, 227, 255], + "tab_status_connected": [50, 130, 255, 255], "tab_status_disconnected": [200, 200, 200, 255], - "printer_config_matched": [12, 169, 227, 255], + "printer_config_matched": [50, 130, 255, 255], "printer_config_mismatch": [127, 127, 127, 255], "toolbox_header_button_text_active": [0, 0, 0, 255], @@ -346,12 +346,12 @@ "monitor_pill_background": [245, 245, 245, 255], "monitor_placeholder_image": [230, 230, 230, 255], "monitor_printer_icon_inactive": [154, 154, 154, 255], - "monitor_printer_icon": [12, 169, 227, 255], + "monitor_printer_icon": [50, 130, 255, 255], "monitor_progress_background_text": [0,0,0,255], "monitor_progress_background": [245, 245, 245, 255], "monitor_progress_fill_inactive": [154, 154, 154, 255], "monitor_progress_fill_text": [255,255,255,255], - "monitor_progress_fill": [12, 169, 227, 255], + "monitor_progress_fill": [50, 130, 255, 255], "monitor_shadow": [0, 0, 0, 63], "monitor_skeleton_fill": [245, 245, 245, 255], "monitor_skeleton_fill_dark": [216, 216, 216, 255], @@ -440,8 +440,8 @@ "tool_button_border": [1.0, 0], - "progressbar": [26.0, 0.4], - "progressbar_radius": [0, 0], + "progressbar": [26.0, 0.75], + "progressbar_radius": [0.15, 0.15], "progressbar_control": [8.0, 0.4], "scrollbar": [0.75, 0.5], From 0a3803d6651c66cb81fb9d2b82187fe79736aac3 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 29 Oct 2018 16:21:16 +0100 Subject: [PATCH 0100/1292] Add CuraView, which does something similar to CuraStage So instead of relying on strange activeViewProxy, it's up to the CuraView to provide a set of components. These can subsequently be used by the active stage again. CURA-5829 --- cura/CuraView.py | 24 ++++++++++++++++++++++++ plugins/PreviewStage/PreviewMenu.qml | 2 +- plugins/SimulationView/SimulationView.py | 15 +++++++++++---- plugins/SimulationView/__init__.py | 3 +++ 4 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 cura/CuraView.py diff --git a/cura/CuraView.py b/cura/CuraView.py new file mode 100644 index 0000000000..978c651b43 --- /dev/null +++ b/cura/CuraView.py @@ -0,0 +1,24 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from PyQt5.QtCore import pyqtProperty, QUrl + +from UM.View.View import View + + +# Since Cura has a few pre-defined "space claims" for the locations of certain components, we've provided some structure +# to indicate this. +# MainComponent works in the same way the MainComponent of a stage. +# the stageMenuComponent returns an item that should be used somehwere in the stage menu. It's up to the active stage +# to actually do something with this. +class CuraView(View): + def __init__(self, parent = None) -> None: + super().__init__(parent) + + @pyqtProperty(QUrl, constant = True) + def mainComponent(self) -> QUrl: + return self.getDisplayComponent("main") + + @pyqtProperty(QUrl, constant = True) + def stageMenuComponent(self) -> QUrl: + return self.getDisplayComponent("menu") \ No newline at end of file diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index ae875fb0a2..5ed0e697a9 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -78,7 +78,7 @@ Item height: childrenRect.height width: childrenRect.width - source: UM.ActiveView.valid ? UM.ActiveView.activeViewPanel : "" + source: UM.Controller.activeView != null && UM.Controller.activeView.stageMenuComponent != null ? UM.Controller.activeView.stageMenuComponent : "" } Cura.PrintSetupSelector diff --git a/plugins/SimulationView/SimulationView.py b/plugins/SimulationView/SimulationView.py index 0ae8b4d9e4..0ef08b22d7 100644 --- a/plugins/SimulationView/SimulationView.py +++ b/plugins/SimulationView/SimulationView.py @@ -26,8 +26,8 @@ from UM.View.GL.OpenGL import OpenGL from UM.View.GL.OpenGLContext import OpenGLContext from UM.View.GL.ShaderProgram import ShaderProgram -from UM.View.View import View from UM.i18n import i18nCatalog +from cura.CuraView import CuraView from cura.Scene.ConvexHullNode import ConvexHullNode from cura.CuraApplication import CuraApplication @@ -48,15 +48,15 @@ catalog = i18nCatalog("cura") ## View used to display g-code paths. -class SimulationView(View): +class SimulationView(CuraView): # Must match SimulationView.qml LAYER_VIEW_TYPE_MATERIAL_TYPE = 0 LAYER_VIEW_TYPE_LINE_TYPE = 1 LAYER_VIEW_TYPE_FEEDRATE = 2 LAYER_VIEW_TYPE_THICKNESS = 3 - def __init__(self) -> None: - super().__init__() + def __init__(self, parent = None) -> None: + super().__init__(parent) self._max_layers = 0 self._current_layer_num = 0 @@ -113,6 +113,13 @@ class SimulationView(View): self._wireprint_warning_message = Message(catalog.i18nc("@info:status", "Cura does not accurately display layers when Wire Printing is enabled"), title = catalog.i18nc("@info:title", "Simulation View")) + Application.getInstance().engineCreatedSignal.connect(self._onEngineCreated) + + def _onEngineCreated(self) -> None: + menu_component_path = os.path.join(PluginRegistry.getInstance().getPluginPath("SimulationView"), + "SimulationView.qml") + self.addDisplayComponent("menu", menu_component_path) + def _evaluateCompatibilityMode(self) -> bool: return OpenGLContext.isLegacyOpenGL() or bool(Application.getInstance().getPreferences().getValue("view/force_layer_view_compatibility_mode")) diff --git a/plugins/SimulationView/__init__.py b/plugins/SimulationView/__init__.py index 360fdc1de9..3f89ee490f 100644 --- a/plugins/SimulationView/__init__.py +++ b/plugins/SimulationView/__init__.py @@ -8,6 +8,7 @@ from . import SimulationViewProxy, SimulationView catalog = i18nCatalog("cura") + def getMetaData(): return { "view": { @@ -17,9 +18,11 @@ def getMetaData(): } } + def createSimulationViewProxy(engine, script_engine): return SimulationViewProxy.SimulationViewProxy() + def register(app): simulation_view = SimulationView.SimulationView() qmlRegisterSingletonType(SimulationViewProxy.SimulationViewProxy, "UM", 1, 0, "SimulationView", simulation_view.getProxy) From aa75b64b5bf121c2908ebdf550e89969945e8fb0 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 30 Oct 2018 09:48:56 +0100 Subject: [PATCH 0101/1292] Use the lining color to the default ouline color for the account widget. Contributes to CURA-5784. --- resources/qml/Account/AccountDetails.qml | 2 +- resources/qml/Account/AccountWidget.qml | 2 +- resources/themes/cura-light/theme.json | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/resources/qml/Account/AccountDetails.qml b/resources/qml/Account/AccountDetails.qml index a88fb77956..c723ca20fb 100644 --- a/resources/qml/Account/AccountDetails.qml +++ b/resources/qml/Account/AccountDetails.qml @@ -22,7 +22,7 @@ Column height: UM.Theme.getSize("avatar_image").height anchors.horizontalCenter: parent.horizontalCenter source: loggedIn ? profile["profile_image_url"] : UM.Theme.getImage("avatar_no_user") - outlineColor: loggedIn ? UM.Theme.getColor("account_widget_outline_active") : UM.Theme.getColor("account_widget_outline_inactive") + outlineColor: loggedIn ? UM.Theme.getColor("account_widget_outline_active") : UM.Theme.getColor("lining") } Label diff --git a/resources/qml/Account/AccountWidget.qml b/resources/qml/Account/AccountWidget.qml index 46092e4153..cdae457ac8 100644 --- a/resources/qml/Account/AccountWidget.qml +++ b/resources/qml/Account/AccountWidget.qml @@ -26,7 +26,7 @@ Button anchors.horizontalCenter: accountWidget.horizontalCenter source: loggedIn ? profile["profile_image_url"] : UM.Theme.getImage("avatar_no_user") - outlineColor: loggedIn ? UM.Theme.getColor("account_widget_outline_active") : UM.Theme.getColor("account_widget_outline_inactive") + outlineColor: loggedIn ? UM.Theme.getColor("account_widget_outline_active") : UM.Theme.getColor("lining") } onClicked: popup.opened ? popup.close() : popup.open() diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 29e3774e1f..40c776ecf1 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -97,7 +97,6 @@ "main_window_header_secondary_button_outline_hovered": [255, 255, 255, 255], "account_widget_outline_active": [70, 66, 126, 255], - "account_widget_outline_inactive": [229, 229, 229, 255], "machine_selector_bar": [31, 36, 39, 255], "machine_selector_active": [68, 72, 75, 255], From b6ea0e638578daa32fcf383335b112e8efcce7e8 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 30 Oct 2018 10:38:53 +0100 Subject: [PATCH 0102/1292] Make the height of the stage buttons themable. Now the height has to be 28px as indicated by the UXers. Contributes to CURA-5784. --- resources/qml/MainWindow/MainWindowHeader.qml | 2 +- resources/themes/cura-light/theme.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/MainWindow/MainWindowHeader.qml b/resources/qml/MainWindow/MainWindowHeader.qml index 92d9d8ee26..3f088e782f 100644 --- a/resources/qml/MainWindow/MainWindowHeader.qml +++ b/resources/qml/MainWindow/MainWindowHeader.qml @@ -60,7 +60,7 @@ Rectangle anchors.verticalCenter: parent.verticalCenter exclusiveGroup: mainWindowHeaderMenuGroup style: UM.Theme.styles.main_window_header_tab - height: Math.round(0.56 * UM.Theme.getSize("main_window_header").height) + height: UM.Theme.getSize("main_window_header_button").height onClicked: UM.Controller.setActiveStage(model.id) iconSource: model.stage.iconSource diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 40c776ecf1..e8de7c98ac 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -361,7 +361,7 @@ "window_minimum_size": [106, 66], "main_window_header": [0.0, 4.5], - "main_window_header_button": [8, 4], + "main_window_header_button": [8, 2.35], "main_window_header_button_icon": [1.2, 1.2], "stage_menu": [0.0, 4.5], From 79ed15aee19a757a3c09cd8ad0c634b57d34a527 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 30 Oct 2018 11:52:08 +0100 Subject: [PATCH 0103/1292] Add the label and the icon indicating when Cura is unable to slice. Contributes to CURA-5786. --- resources/qml/ActionPanelWidget.qml | 1 + resources/qml/SliceProcessWidget.qml | 87 +++++++++++++++++++++++--- resources/themes/cura-light/theme.json | 3 +- 3 files changed, 80 insertions(+), 11 deletions(-) diff --git a/resources/qml/ActionPanelWidget.qml b/resources/qml/ActionPanelWidget.qml index d1fe999731..b4a9b4e4ec 100644 --- a/resources/qml/ActionPanelWidget.qml +++ b/resources/qml/ActionPanelWidget.qml @@ -37,6 +37,7 @@ Rectangle } Behavior on height { NumberAnimation { duration: 100 } } + Behavior on width { NumberAnimation { duration: 100 } } Component { diff --git a/resources/qml/SliceProcessWidget.qml b/resources/qml/SliceProcessWidget.qml index 67005cb133..561e38c372 100644 --- a/resources/qml/SliceProcessWidget.qml +++ b/resources/qml/SliceProcessWidget.qml @@ -12,7 +12,9 @@ Column { id: widget - spacing: UM.Theme.getSize("default_margin").height + width: UM.Theme.getSize("action_panel_button").width + + spacing: UM.Theme.getSize("thin_margin").height UM.I18nCatalog { @@ -23,30 +25,84 @@ Column property real progress: UM.Backend.progress property int backendState: UM.Backend.state - Rectangle + Item + { + id: message + width: parent.width + height: childrenRect.height + visible: widget.backendState == 4 + + UM.RecolorImage + { + id: warningImage + + anchors.left: parent.left + + source: UM.Theme.getIcon("warning") + width: UM.Theme.getSize("section_icon").width + height: UM.Theme.getSize("section_icon").height + + sourceSize.width: width + sourceSize.height: height + + color: UM.Theme.getColor("warning") + } + + Label + { + id: unableToSliceLabel + anchors.left: warningImage.right + anchors.leftMargin: UM.Theme.getSize("thin_margin").width + text: catalog.i18nc("@label:PrintjobStatus", "Unable to Slice") + color: UM.Theme.getColor("warning") + font: UM.Theme.getFont("very_small") + } + } + + // Progress bar, only visible when the backend is in the process of slice the printjob + ProgressBar { id: progressBar width: parent.width height: UM.Theme.getSize("progressbar").height + value: progress visible: widget.backendState == 2 - radius: UM.Theme.getSize("progressbar_radius").width - color: UM.Theme.getColor("progressbar_background") - Rectangle + background: Rectangle { - width: Math.max(parent.width * base.progress) - height: parent.height + anchors.fill: parent radius: UM.Theme.getSize("progressbar_radius").width - color: UM.Theme.getColor("progressbar_control") + color: UM.Theme.getColor("progressbar_background") + } + + contentItem: Item + { + anchors.fill: parent + Rectangle + { + width: progressBar.visualPosition * parent.width + height: parent.height + radius: UM.Theme.getSize("progressbar_radius").width + color: UM.Theme.getColor("progressbar_control") + } } } Cura.ActionButton { id: prepareButton - width: UM.Theme.getSize("action_panel_button").width + width: parent.width height: UM.Theme.getSize("action_panel_button").height - text: widget.backendState == 1 ? catalog.i18nc("@button", "Prepare") : catalog.i18nc("@button", "Cancel") + text: autoSlice ? catalog.i18nc("@button", "Auto slicing...") : (widget.backendState == 1 ? catalog.i18nc("@button", "Slice") : catalog.i18nc("@button", "Cancel")) + enabled: !autoSlice + + // Get the current value from the preferences + property bool autoSlice: UM.Preferences.getValue("general/auto_slice") + + disabledColor: "transparent" + textDisabledColor: UM.Theme.getColor("primary") + outlineDisabledColor: "transparent" + onClicked: { if ([1, 5].indexOf(widget.backendState) != -1) @@ -59,4 +115,15 @@ Column } } } + + // React when the user changes the preference of having the auto slice enabled + Connections + { + target: UM.Preferences + onPreferenceChanged: + { + var autoSlice = UM.Preferences.getValue("general/auto_slice") + prepareButton.autoSlice = autoSlice + } + } } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index d695ba12cf..1473a75eec 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -116,6 +116,7 @@ "text_scene_hover": [70, 84, 113, 255], "error": [255, 140, 0, 255], + "warning": [255, 190, 35, 255], "button": [31, 36, 39, 255], "button_hover": [68, 72, 75, 255], @@ -210,7 +211,7 @@ "material_compatibility_warning": [0, 0, 0, 255], "progressbar_background": [245, 245, 245, 255], - "progressbar_control": [31, 36, 39, 255], + "progressbar_control": [50, 130, 255, 255], "slider_groove": [245, 245, 245, 255], "slider_groove_border": [127, 127, 127, 255], From 45af4eec907a0113145cc15f14b11fa1b5185a51 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 30 Oct 2018 12:08:17 +0100 Subject: [PATCH 0104/1292] Add Shortcut action Ctrl+P to slice or stop slicing. Contributes to CURA-5786. --- resources/qml/SliceProcessWidget.qml | 58 +++++++++++++++++++++------- 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/resources/qml/SliceProcessWidget.qml b/resources/qml/SliceProcessWidget.qml index 561e38c372..c9ff7178fd 100644 --- a/resources/qml/SliceProcessWidget.qml +++ b/resources/qml/SliceProcessWidget.qml @@ -4,6 +4,7 @@ import QtQuick 2.7 import QtQuick.Controls 2.1 import QtQuick.Layouts 1.3 +import QtQuick.Controls 1.4 as Controls1 import UM 1.1 as UM import Cura 1.0 as Cura @@ -25,12 +26,24 @@ Column property real progress: UM.Backend.progress property int backendState: UM.Backend.state + function sliceOrStopSlicing() + { + if ([1, 5].indexOf(widget.backendState) != -1) // == BackendState.NotStarted or BackendState.Disabled + { + CuraApplication.backend.forceSlice() + } + else + { + CuraApplication.backend.stopSlicing() + } + } + Item { id: message width: parent.width height: childrenRect.height - visible: widget.backendState == 4 + visible: widget.backendState == 4 // == BackendState.Error UM.RecolorImage { @@ -66,7 +79,7 @@ Column width: parent.width height: UM.Theme.getSize("progressbar").height value: progress - visible: widget.backendState == 2 + visible: widget.backendState == 2 // == BackendState.Processing background: Rectangle { @@ -93,7 +106,21 @@ Column id: prepareButton width: parent.width height: UM.Theme.getSize("action_panel_button").height - text: autoSlice ? catalog.i18nc("@button", "Auto slicing...") : (widget.backendState == 1 ? catalog.i18nc("@button", "Slice") : catalog.i18nc("@button", "Cancel")) + text: + { + if (autoSlice) + { + return catalog.i18nc("@button", "Auto slicing...") + } + else if ([1, 5].indexOf(widget.backendState) != -1) // == BackendState.NotStarted or BackendState.Disabled + { + return catalog.i18nc("@button", "Slice") + } + else + { + return catalog.i18nc("@button", "Cancel") + } + } enabled: !autoSlice // Get the current value from the preferences @@ -103,17 +130,7 @@ Column textDisabledColor: UM.Theme.getColor("primary") outlineDisabledColor: "transparent" - onClicked: - { - if ([1, 5].indexOf(widget.backendState) != -1) - { - CuraApplication.backend.forceSlice() - } - else - { - CuraApplication.backend.stopSlicing() - } - } + onClicked: sliceOrStopSlicing() } // React when the user changes the preference of having the auto slice enabled @@ -126,4 +143,17 @@ Column prepareButton.autoSlice = autoSlice } } + + // Shortcut for "slice/stop" + Controls1.Action + { + shortcut: "Ctrl+P" + onTriggered: + { + if (prepareButton.enabled) + { + sliceOrStopSlicing() + } + } + } } From 00d75cd4d600866933147e9a0ae75e790ebf95e6 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 30 Oct 2018 12:28:51 +0100 Subject: [PATCH 0105/1292] Tweak the colors of the disabled state. Contributes to CURA-5786. --- resources/qml/SliceProcessWidget.qml | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/resources/qml/SliceProcessWidget.qml b/resources/qml/SliceProcessWidget.qml index c9ff7178fd..98f708a9b0 100644 --- a/resources/qml/SliceProcessWidget.qml +++ b/resources/qml/SliceProcessWidget.qml @@ -108,27 +108,24 @@ Column height: UM.Theme.getSize("action_panel_button").height text: { + if ([1, 4, 5].indexOf(widget.backendState) != -1) // == BackendState.NotStarted or BackendState.Error or BackendState.Disabled + { + return catalog.i18nc("@button", "Slice") + } if (autoSlice) { return catalog.i18nc("@button", "Auto slicing...") } - else if ([1, 5].indexOf(widget.backendState) != -1) // == BackendState.NotStarted or BackendState.Disabled - { - return catalog.i18nc("@button", "Slice") - } - else - { - return catalog.i18nc("@button", "Cancel") - } + return catalog.i18nc("@button", "Cancel") } - enabled: !autoSlice + enabled: !autoSlice && ([1, 2].indexOf(widget.backendState) != -1) // Get the current value from the preferences property bool autoSlice: UM.Preferences.getValue("general/auto_slice") - disabledColor: "transparent" - textDisabledColor: UM.Theme.getColor("primary") - outlineDisabledColor: "transparent" + disabledColor: ([1, 2].indexOf(widget.backendState) == -1) ? UM.Theme.getColor("action_button_disabled") : "transparent" + textDisabledColor: ([1, 2].indexOf(widget.backendState) == -1) ? UM.Theme.getColor("action_button_disabled_text") : UM.Theme.getColor("primary") + outlineDisabledColor: ([1, 2].indexOf(widget.backendState) == -1) ? UM.Theme.getColor("action_button_disabled_border") : "transparent" onClicked: sliceOrStopSlicing() } From 027bf204cd1ff6dba53b9e386e183d2251718020 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 30 Oct 2018 15:12:03 +0100 Subject: [PATCH 0106/1292] Use the BackendState enumeration in QML to not use integers but use the enumeration literals. Contributes to CURA-5786. --- resources/qml/SliceProcessWidget.qml | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/resources/qml/SliceProcessWidget.qml b/resources/qml/SliceProcessWidget.qml index 98f708a9b0..b9c0dc39f9 100644 --- a/resources/qml/SliceProcessWidget.qml +++ b/resources/qml/SliceProcessWidget.qml @@ -28,7 +28,7 @@ Column function sliceOrStopSlicing() { - if ([1, 5].indexOf(widget.backendState) != -1) // == BackendState.NotStarted or BackendState.Disabled + if ([UM.Backend.NotStarted, UM.Backend.Disabled].indexOf(widget.backendState) != -1) { CuraApplication.backend.forceSlice() } @@ -43,7 +43,7 @@ Column id: message width: parent.width height: childrenRect.height - visible: widget.backendState == 4 // == BackendState.Error + visible: widget.backendState == UM.Backend.Error UM.RecolorImage { @@ -79,7 +79,7 @@ Column width: parent.width height: UM.Theme.getSize("progressbar").height value: progress - visible: widget.backendState == 2 // == BackendState.Processing + visible: widget.backendState == UM.Backend.Processing background: Rectangle { @@ -108,7 +108,7 @@ Column height: UM.Theme.getSize("action_panel_button").height text: { - if ([1, 4, 5].indexOf(widget.backendState) != -1) // == BackendState.NotStarted or BackendState.Error or BackendState.Disabled + if ([UM.Backend.NotStarted, UM.Backend.Error, UM.Backend.Disabled].indexOf(widget.backendState) != -1) { return catalog.i18nc("@button", "Slice") } @@ -118,14 +118,16 @@ Column } return catalog.i18nc("@button", "Cancel") } - enabled: !autoSlice && ([1, 2].indexOf(widget.backendState) != -1) + enabled: !autoSlice && !disabledSlice // Get the current value from the preferences property bool autoSlice: UM.Preferences.getValue("general/auto_slice") + // Disable the slice process when + property bool disabledSlice: [UM.Backend.Done, UM.Backend.Error, UM.Backend.Disabled].indexOf(widget.backendState) != -1 - disabledColor: ([1, 2].indexOf(widget.backendState) == -1) ? UM.Theme.getColor("action_button_disabled") : "transparent" - textDisabledColor: ([1, 2].indexOf(widget.backendState) == -1) ? UM.Theme.getColor("action_button_disabled_text") : UM.Theme.getColor("primary") - outlineDisabledColor: ([1, 2].indexOf(widget.backendState) == -1) ? UM.Theme.getColor("action_button_disabled_border") : "transparent" + disabledColor: disabledSlice ? UM.Theme.getColor("action_button_disabled") : "transparent" + textDisabledColor: disabledSlice ? UM.Theme.getColor("action_button_disabled_text") : UM.Theme.getColor("primary") + outlineDisabledColor: disabledSlice ? UM.Theme.getColor("action_button_disabled_border") : "transparent" onClicked: sliceOrStopSlicing() } From eabd7c6b5eac0fa4fd63b2f8bb9177dd115b0767 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 30 Oct 2018 17:07:07 +0100 Subject: [PATCH 0107/1292] Start mocking up the panel the user gets after slicing. Also the IconLabel component was created with the aim to be reused in several places. Contributes to CURA-5786. --- resources/qml/ActionPanelWidget.qml | 2 +- resources/qml/IconLabel.qml | 48 +++++++ resources/qml/OutputProcessWidget.qml | 139 ++++++++++++-------- resources/qml/SliceProcessWidget.qml | 32 +---- resources/qml/qmldir | 3 +- resources/themes/cura-light/icons/clock.svg | 53 ++++++++ resources/themes/cura-light/icons/info.svg | 48 +++++++ resources/themes/cura-light/icons/spool.svg | 7 + 8 files changed, 251 insertions(+), 81 deletions(-) create mode 100644 resources/qml/IconLabel.qml create mode 100644 resources/themes/cura-light/icons/clock.svg create mode 100644 resources/themes/cura-light/icons/info.svg create mode 100644 resources/themes/cura-light/icons/spool.svg diff --git a/resources/qml/ActionPanelWidget.qml b/resources/qml/ActionPanelWidget.qml index b4a9b4e4ec..6c76c31f1b 100644 --- a/resources/qml/ActionPanelWidget.qml +++ b/resources/qml/ActionPanelWidget.qml @@ -21,7 +21,7 @@ Rectangle radius: UM.Theme.getSize("default_radius").width visible: CuraApplication.platformActivity - property bool backendStatusDone: UM.Backend.state == 3 + property bool backendStatusDone: UM.Backend.state == UM.Backend.Done Loader { diff --git a/resources/qml/IconLabel.qml b/resources/qml/IconLabel.qml new file mode 100644 index 0000000000..2e765e2dbc --- /dev/null +++ b/resources/qml/IconLabel.qml @@ -0,0 +1,48 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.1 +import QtQuick.Layouts 1.3 + +import UM 1.1 as UM + +// This item will show a label with a squared icon in the left +Item +{ + id: container + + property alias text: label.text + property alias source: icon.source + property alias color: label.color + property alias font: label.font + + height: childrenRect.height + + UM.RecolorImage + { + id: icon + + anchors.left: parent.left + + source: UM.Theme.getIcon("dot") + width: UM.Theme.getSize("section_icon").width + height: UM.Theme.getSize("section_icon").height + + sourceSize.width: width + sourceSize.height: height + + color: label.color + } + + Label + { + id: label + anchors.left: icon.right + anchors.leftMargin: UM.Theme.getSize("thin_margin").width + text: "Empty label" + color: UM.Theme.getColor("text") + font: UM.Theme.getFont("very_small") + renderType: Text.NativeRendering + } +} \ No newline at end of file diff --git a/resources/qml/OutputProcessWidget.qml b/resources/qml/OutputProcessWidget.qml index 612e4f286f..244fba57ef 100644 --- a/resources/qml/OutputProcessWidget.qml +++ b/resources/qml/OutputProcessWidget.qml @@ -4,69 +4,104 @@ import QtQuick 2.7 import QtQuick.Controls 2.1 import QtQuick.Layouts 1.3 +import QtQuick.Controls 1.4 as Controls1 import UM 1.1 as UM +import Cura 1.0 as Cura -Button +Column { - id: button - property alias cursorShape: mouseArea.cursorShape - property alias iconSource: buttonIcon.source - property alias textFont: buttonText.font - property alias cornerRadius: backgroundRect.radius - property var color: UM.Theme.getColor("primary") - property var hoverColor: UM.Theme.getColor("primary_hover") - property var disabledColor: color - property var textColor: UM.Theme.getColor("button_text") - property var textHoverColor: UM.Theme.getColor("button_text_hover") - property var textDisabledColor: textColor - property var outlineColor: color - property var outlineHoverColor: hoverColor - property var outlineDisabledColor: outlineColor + id: widget - contentItem: Row + spacing: UM.Theme.getSize("thin_margin").height + + UM.I18nCatalog { + id: catalog + name: "cura" + } + + Item + { + id: information + width: parent.width + height: childrenRect.height + + Column + { + id: timeAndCostsInformation + + anchors + { + left: parent.left + right: moreInformationIcon.left + rightMargin: UM.Theme.getSize("thin_margin").height + } + + Cura.IconLabel + { + id: estimatedTime + width: parent.width + + text: "Time" + source: UM.Theme.getIcon("clock") + font: UM.Theme.getFont("small") + } + + Cura.IconLabel + { + id: estimatedCosts + width: parent.width + + text: "Material costs" + source: UM.Theme.getIcon("spool") + font: UM.Theme.getFont("very_small") + } + } + UM.RecolorImage { - id: buttonIcon - source: "" - height: Math.round(0.6 * parent.height) - width: height + id: moreInformationIcon + + anchors + { + right: parent.right + verticalCenter: timeAndCostsInformation.verticalCenter + } + + source: UM.Theme.getIcon("info") + width: UM.Theme.getSize("section_icon").width + height: UM.Theme.getSize("section_icon").height + sourceSize.width: width sourceSize.height: height - color: button.hovered ? button.textHoverColor : button.textColor - visible: source != "" - anchors.verticalCenter: parent.verticalCenter - Behavior on color { ColorAnimation { duration: 50 } } - } - Label + color: UM.Theme.getColor("text_medium") + } + } + + Row + { + id: buttonRow + spacing: UM.Theme.getSize("default_margin").width + + Cura.ActionButton { - id: buttonText - text: "Preview" - color: button.enabled ? (button.hovered ? button.textHoverColor : button.textColor): button.textDisabledColor - font: UM.Theme.getFont("action_button") - visible: text != "" - renderType: Text.NativeRendering - anchors.verticalCenter: parent.verticalCenter + height: UM.Theme.getSize("action_panel_button").height + text: catalog.i18nc("@button", "Preview") + color: UM.Theme.getColor("secondary") + hoverColor: UM.Theme.getColor("secondary") + textColor: UM.Theme.getColor("primary") + textHoverColor: UM.Theme.getColor("text") + onClicked: console.log("Clicking preview") + } + + Cura.ActionButton + { + width: UM.Theme.getSize("account_button").width + height: UM.Theme.getSize("action_panel_button").height + text: catalog.i18nc("@button", "Save to file") + onClicked: console.log("Clicking action button") } } - - background: Rectangle - { - id: backgroundRect - color: button.enabled ? (button.hovered ? button.hoverColor : button.color) : button.disabledColor - radius: UM.Theme.getSize("action_button_radius").width - border.width: UM.Theme.getSize("default_lining").width - border.color: button.enabled ? (button.hovered ? button.outlineHoverColor : button.outlineColor) : button.outlineDisabledColor - Behavior on color { ColorAnimation { duration: 50 } } - } - - MouseArea - { - id: mouseArea - anchors.fill: parent - onPressed: mouse.accepted = false - hoverEnabled: true - } -} +} \ No newline at end of file diff --git a/resources/qml/SliceProcessWidget.qml b/resources/qml/SliceProcessWidget.qml index b9c0dc39f9..38a529b04e 100644 --- a/resources/qml/SliceProcessWidget.qml +++ b/resources/qml/SliceProcessWidget.qml @@ -38,38 +38,16 @@ Column } } - Item + Cura.IconLabel { id: message width: parent.width - height: childrenRect.height visible: widget.backendState == UM.Backend.Error - UM.RecolorImage - { - id: warningImage - - anchors.left: parent.left - - source: UM.Theme.getIcon("warning") - width: UM.Theme.getSize("section_icon").width - height: UM.Theme.getSize("section_icon").height - - sourceSize.width: width - sourceSize.height: height - - color: UM.Theme.getColor("warning") - } - - Label - { - id: unableToSliceLabel - anchors.left: warningImage.right - anchors.leftMargin: UM.Theme.getSize("thin_margin").width - text: catalog.i18nc("@label:PrintjobStatus", "Unable to Slice") - color: UM.Theme.getColor("warning") - font: UM.Theme.getFont("very_small") - } + text: catalog.i18nc("@label:PrintjobStatus", "Unable to Slice") + source: UM.Theme.getIcon("warning") + color: UM.Theme.getColor("warning") + font: UM.Theme.getFont("very_small") } // Progress bar, only visible when the backend is in the process of slice the printjob diff --git a/resources/qml/qmldir b/resources/qml/qmldir index 0e5e316409..22e3ff1303 100644 --- a/resources/qml/qmldir +++ b/resources/qml/qmldir @@ -7,4 +7,5 @@ PrintSetupSelector 1.0 PrintSetupSelector.qml ActionButton 1.0 ActionButton.qml MaterialMenu 1.0 MaterialMenu.qml NozzleMenu 1.0 NozzleMenu.qml -ActionPanelWidget 1.0 ActionPanelWidget.qml \ No newline at end of file +ActionPanelWidget 1.0 ActionPanelWidget.qml +IconLabel 1.0 IconLabel.qml \ No newline at end of file diff --git a/resources/themes/cura-light/icons/clock.svg b/resources/themes/cura-light/icons/clock.svg new file mode 100644 index 0000000000..0b6cb78881 --- /dev/null +++ b/resources/themes/cura-light/icons/clock.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/themes/cura-light/icons/info.svg b/resources/themes/cura-light/icons/info.svg new file mode 100644 index 0000000000..97e4fc4f35 --- /dev/null +++ b/resources/themes/cura-light/icons/info.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/themes/cura-light/icons/spool.svg b/resources/themes/cura-light/icons/spool.svg new file mode 100644 index 0000000000..0d8ae42d9d --- /dev/null +++ b/resources/themes/cura-light/icons/spool.svg @@ -0,0 +1,7 @@ + + + + + + + From f7730302187667e74a883e061f237440a0b90521 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 31 Oct 2018 09:37:21 +0100 Subject: [PATCH 0108/1292] Add main stage to previewStage so that SimulationView can use it CURA-5829 --- plugins/PreviewStage/PreviewMain.qml | 19 ++ plugins/PreviewStage/PreviewStage.py | 2 + plugins/SimulationView/SimulationView.py | 7 +- .../SimulationViewMainComponent.qml | 212 +++++++++++++++++ ...ew.qml => SimulationViewMenuComponent.qml} | 224 ------------------ plugins/SimulationView/__init__.py | 1 - resources/qml/Cura.qml | 57 +++-- 7 files changed, 272 insertions(+), 250 deletions(-) create mode 100644 plugins/PreviewStage/PreviewMain.qml create mode 100644 plugins/SimulationView/SimulationViewMainComponent.qml rename plugins/SimulationView/{SimulationView.qml => SimulationViewMenuComponent.qml} (75%) diff --git a/plugins/PreviewStage/PreviewMain.qml b/plugins/PreviewStage/PreviewMain.qml new file mode 100644 index 0000000000..df7e09225f --- /dev/null +++ b/plugins/PreviewStage/PreviewMain.qml @@ -0,0 +1,19 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.4 +import QtQuick.Controls 1.2 +import QtQuick.Layouts 1.1 +import QtQuick.Controls.Styles 1.1 + +import UM 1.0 as UM +import Cura 1.0 as Cura + + +Loader +{ + id: previewMain + + source: UM.Controller.activeView != null && UM.Controller.activeView.mainComponent != null ? UM.Controller.activeView.mainComponent : "" + onSourceChanged: print("THE SOURCE IS", source) +} \ No newline at end of file diff --git a/plugins/PreviewStage/PreviewStage.py b/plugins/PreviewStage/PreviewStage.py index e41d4a592f..1aed95162a 100644 --- a/plugins/PreviewStage/PreviewStage.py +++ b/plugins/PreviewStage/PreviewStage.py @@ -30,4 +30,6 @@ class PreviewStage(CuraStage): plugin_path = self._application.getPluginRegistry().getPluginPath(self.getPluginId()) if plugin_path is not None: menu_component_path = os.path.join(plugin_path, "PreviewMenu.qml") + main_component_path = os.path.join(plugin_path, "PreviewMain.qml") self.addDisplayComponent("menu", menu_component_path) + self.addDisplayComponent("main", main_component_path) diff --git a/plugins/SimulationView/SimulationView.py b/plugins/SimulationView/SimulationView.py index 0ef08b22d7..f1bff5f3f7 100644 --- a/plugins/SimulationView/SimulationView.py +++ b/plugins/SimulationView/SimulationView.py @@ -117,7 +117,12 @@ class SimulationView(CuraView): def _onEngineCreated(self) -> None: menu_component_path = os.path.join(PluginRegistry.getInstance().getPluginPath("SimulationView"), - "SimulationView.qml") + "SimulationViewMenuComponent.qml") + + main_component_path = os.path.join(PluginRegistry.getInstance().getPluginPath("SimulationView"), + "SimulationViewMainComponent.qml") + + self.addDisplayComponent("main", main_component_path) self.addDisplayComponent("menu", menu_component_path) def _evaluateCompatibilityMode(self) -> bool: diff --git a/plugins/SimulationView/SimulationViewMainComponent.qml b/plugins/SimulationView/SimulationViewMainComponent.qml new file mode 100644 index 0000000000..a4ec411124 --- /dev/null +++ b/plugins/SimulationView/SimulationViewMainComponent.qml @@ -0,0 +1,212 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.4 +import QtQuick.Controls 1.2 +import QtQuick.Layouts 1.1 +import QtQuick.Controls.Styles 1.1 + +import UM 1.0 as UM +import Cura 1.0 as Cura + +Item +{ + property bool is_simulation_playing: false + visible: UM.SimulationView.layerActivity && CuraApplication.platformActivity + + PathSlider + { + id: pathSlider + height: UM.Theme.getSize("slider_handle").width + width: 250 + + anchors.bottom: parent.bottom + anchors.bottomMargin: UM.Theme.getSize("default_margin").height + + anchors.horizontalCenter: parent.horizontalCenter + + visible: !UM.SimulationView.compatibilityMode + + // Custom properties + handleValue: UM.SimulationView.currentPath + maximumValue: UM.SimulationView.numPaths + handleSize: UM.Theme.getSize("slider_handle").width + trackThickness: UM.Theme.getSize("slider_groove").width + trackColor: UM.Theme.getColor("slider_groove") + trackBorderColor: UM.Theme.getColor("slider_groove_border") + handleColor: UM.Theme.getColor("slider_handle") + handleActiveColor: UM.Theme.getColor("slider_handle_active") + rangeColor: UM.Theme.getColor("slider_groove_fill") + + // Update values when layer data changes. + Connections + { + target: UM.SimulationView + onMaxPathsChanged: pathSlider.setHandleValue(UM.SimulationView.currentPath) + onCurrentPathChanged: + { + // Only pause the simulation when the layer was changed manually, not when the simulation is running + if (pathSlider.manuallyChanged) + { + playButton.pauseSimulation() + } + pathSlider.setHandleValue(UM.SimulationView.currentPath) + } + } + + // Ensure that the slider handlers show the correct value after switching views. + Component.onCompleted: + { + pathSlider.setHandleValue(UM.SimulationView.currentPath) + } + + } + + Button + { + id: playButton + iconSource: !is_simulation_playing ? "./resources/simulation_resume.svg": "./resources/simulation_pause.svg" + style: UM.Theme.styles.small_tool_button + visible: !UM.SimulationView.compatibilityMode + anchors + { + right: pathSlider.left + verticalCenter: pathSlider.verticalCenter + } + + onClicked: + { + if(is_simulation_playing) + { + pauseSimulation() + } else + { + resumeSimulation() + } + } + + function pauseSimulation() + { + UM.SimulationView.setSimulationRunning(false) + simulationTimer.stop() + is_simulation_playing = false + layerSlider.manuallyChanged = true + pathSlider.manuallyChanged = true + } + + function resumeSimulation() + { + UM.SimulationView.setSimulationRunning(true) + simulationTimer.start() + layerSlider.manuallyChanged = false + pathSlider.manuallyChanged = false + } + } + + Timer + { + id: simulationTimer + interval: 100 + running: false + repeat: true + onTriggered: + { + var currentPath = UM.SimulationView.currentPath + var numPaths = UM.SimulationView.numPaths + var currentLayer = UM.SimulationView.currentLayer + var numLayers = UM.SimulationView.numLayers + + // When the user plays the simulation, if the path slider is at the end of this layer, we start + // the simulation at the beginning of the current layer. + if (!is_simulation_playing) + { + if (currentPath >= numPaths) + { + UM.SimulationView.setCurrentPath(0) + } + else + { + UM.SimulationView.setCurrentPath(currentPath + 1) + } + } + // If the simulation is already playing and we reach the end of a layer, then it automatically + // starts at the beginning of the next layer. + else + { + if (currentPath >= numPaths) + { + // At the end of the model, the simulation stops + if (currentLayer >= numLayers) + { + playButton.pauseSimulation() + } + else + { + UM.SimulationView.setCurrentLayer(currentLayer+1) + UM.SimulationView.setCurrentPath(0) + } + } + else + { + UM.SimulationView.setCurrentPath(currentPath+1) + } + } + // The status must be set here instead of in the resumeSimulation function otherwise it won't work + // correctly, because part of the logic is in this trigger function. + is_simulation_playing = true + } + } + + LayerSlider + { + id: layerSlider + + width: UM.Theme.getSize("slider_handle").width + height: UM.Theme.getSize("layerview_menu_size").height + + anchors + { + right: parent.right + verticalCenter: parent.verticalCenter + rightMargin: UM.Theme.getSize("default_margin").width + } + + // Custom properties + upperValue: UM.SimulationView.currentLayer + lowerValue: UM.SimulationView.minimumLayer + maximumValue: UM.SimulationView.numLayers + handleSize: UM.Theme.getSize("slider_handle").width + trackThickness: UM.Theme.getSize("slider_groove").width + trackColor: UM.Theme.getColor("slider_groove") + trackBorderColor: UM.Theme.getColor("slider_groove_border") + upperHandleColor: UM.Theme.getColor("slider_handle") + lowerHandleColor: UM.Theme.getColor("slider_handle") + rangeHandleColor: UM.Theme.getColor("slider_groove_fill") + handleActiveColor: UM.Theme.getColor("slider_handle_active") + handleLabelWidth: UM.Theme.getSize("slider_layerview_background").width + + // Update values when layer data changes + Connections + { + target: UM.SimulationView + onMaxLayersChanged: layerSlider.setUpperValue(UM.SimulationView.currentLayer) + onMinimumLayerChanged: layerSlider.setLowerValue(UM.SimulationView.minimumLayer) + onCurrentLayerChanged: + { + // Only pause the simulation when the layer was changed manually, not when the simulation is running + if (layerSlider.manuallyChanged) + { + playButton.pauseSimulation() + } + layerSlider.setUpperValue(UM.SimulationView.currentLayer) + } + } + + // Make sure the slider handlers show the correct value after switching views + Component.onCompleted: + { + layerSlider.setLowerValue(UM.SimulationView.minimumLayer) + layerSlider.setUpperValue(UM.SimulationView.currentLayer) + } + } +} \ No newline at end of file diff --git a/plugins/SimulationView/SimulationView.qml b/plugins/SimulationView/SimulationViewMenuComponent.qml similarity index 75% rename from plugins/SimulationView/SimulationView.qml rename to plugins/SimulationView/SimulationViewMenuComponent.qml index 7a83a07ac1..91ef7a2794 100644 --- a/plugins/SimulationView/SimulationView.qml +++ b/plugins/SimulationView/SimulationViewMenuComponent.qml @@ -583,230 +583,6 @@ Item } } - Item - { - id: slidersBox - - width: parent.width - height: parent.height - visible: UM.SimulationView.layerActivity && CuraApplication.platformActivity - - anchors - { - top: parent.top - leftMargin: UM.Theme.getSize("slider_layerview_margin").height - left: parent.right - } - - PathSlider - { - id: pathSlider - - height: UM.Theme.getSize("slider_handle").width - anchors - { - verticalCenter: playButton.verticalCenter - left: playButton.right - leftMargin: UM.Theme.getSize("default_margin").width - right: parent.right - } - visible: !UM.SimulationView.compatibilityMode - - // custom properties - handleValue: UM.SimulationView.currentPath - maximumValue: UM.SimulationView.numPaths - handleSize: UM.Theme.getSize("slider_handle").width - trackThickness: UM.Theme.getSize("slider_groove").width - trackColor: UM.Theme.getColor("slider_groove") - trackBorderColor: UM.Theme.getColor("slider_groove_border") - handleColor: UM.Theme.getColor("slider_handle") - handleActiveColor: UM.Theme.getColor("slider_handle_active") - rangeColor: UM.Theme.getColor("slider_groove_fill") - - // update values when layer data changes - Connections - { - target: UM.SimulationView - onMaxPathsChanged: pathSlider.setHandleValue(UM.SimulationView.currentPath) - onCurrentPathChanged: - { - // Only pause the simulation when the layer was changed manually, not when the simulation is running - if (pathSlider.manuallyChanged) - { - playButton.pauseSimulation() - } - pathSlider.setHandleValue(UM.SimulationView.currentPath) - } - } - - // make sure the slider handlers show the correct value after switching views - Component.onCompleted: - { - pathSlider.setHandleValue(UM.SimulationView.currentPath) - } - } - - LayerSlider - { - id: layerSlider - - width: UM.Theme.getSize("slider_handle").width - height: UM.Theme.getSize("layerview_menu_size").height - - anchors - { - bottom: !UM.SimulationView.compatibilityMode ? pathSlider.top : parent.bottom - top: parent.top - bottomMargin: !UM.SimulationView.compatibilityMode ? UM.Theme.getSize("default_margin").height : 0 - left: parent.left - leftMargin: Math.round(UM.Theme.getSize("slider_layerview_margin").width / 2) - } - - // custom properties - upperValue: UM.SimulationView.currentLayer - lowerValue: UM.SimulationView.minimumLayer - maximumValue: UM.SimulationView.numLayers - handleSize: UM.Theme.getSize("slider_handle").width - trackThickness: UM.Theme.getSize("slider_groove").width - trackColor: UM.Theme.getColor("slider_groove") - trackBorderColor: UM.Theme.getColor("slider_groove_border") - upperHandleColor: UM.Theme.getColor("slider_handle") - lowerHandleColor: UM.Theme.getColor("slider_handle") - rangeHandleColor: UM.Theme.getColor("slider_groove_fill") - handleActiveColor: UM.Theme.getColor("slider_handle_active") - handleLabelWidth: UM.Theme.getSize("slider_layerview_background").width - - // update values when layer data changes - Connections - { - target: UM.SimulationView - onMaxLayersChanged: layerSlider.setUpperValue(UM.SimulationView.currentLayer) - onMinimumLayerChanged: layerSlider.setLowerValue(UM.SimulationView.minimumLayer) - onCurrentLayerChanged: - { - // Only pause the simulation when the layer was changed manually, not when the simulation is running - if (layerSlider.manuallyChanged) - { - playButton.pauseSimulation() - } - layerSlider.setUpperValue(UM.SimulationView.currentLayer) - } - } - - // make sure the slider handlers show the correct value after switching views - Component.onCompleted: - { - layerSlider.setLowerValue(UM.SimulationView.minimumLayer) - layerSlider.setUpperValue(UM.SimulationView.currentLayer) - } - } - - // Play simulation button - Button - { - id: playButton - iconSource: "./resources/simulation_resume.svg" - style: UM.Theme.styles.small_tool_button - visible: !UM.SimulationView.compatibilityMode - anchors - { - left: parent.left - bottom: parent.bottom - } - - property var status: 0 // indicates if it's stopped (0) or playing (1) - - onClicked: - { - switch(status) - { - case 0: - { - resumeSimulation() - break - } - case 1: - { - pauseSimulation() - break - } - } - } - - function pauseSimulation() - { - UM.SimulationView.setSimulationRunning(false) - iconSource = "./resources/simulation_resume.svg" - simulationTimer.stop() - status = 0 - layerSlider.manuallyChanged = true - pathSlider.manuallyChanged = true - } - - function resumeSimulation() - { - UM.SimulationView.setSimulationRunning(true) - iconSource = "./resources/simulation_pause.svg" - simulationTimer.start() - layerSlider.manuallyChanged = false - pathSlider.manuallyChanged = false - } - } - - Timer - { - id: simulationTimer - interval: 100 - running: false - repeat: true - onTriggered: - { - var currentPath = UM.SimulationView.currentPath - var numPaths = UM.SimulationView.numPaths - var currentLayer = UM.SimulationView.currentLayer - var numLayers = UM.SimulationView.numLayers - // When the user plays the simulation, if the path slider is at the end of this layer, we start - // the simulation at the beginning of the current layer. - if (playButton.status == 0) - { - if (currentPath >= numPaths) - { - UM.SimulationView.setCurrentPath(0) - } - else - { - UM.SimulationView.setCurrentPath(currentPath+1) - } - } - // If the simulation is already playing and we reach the end of a layer, then it automatically - // starts at the beginning of the next layer. - else - { - if (currentPath >= numPaths) - { - // At the end of the model, the simulation stops - if (currentLayer >= numLayers) - { - playButton.pauseSimulation() - } - else - { - UM.SimulationView.setCurrentLayer(currentLayer+1) - UM.SimulationView.setCurrentPath(0) - } - } - else - { - UM.SimulationView.setCurrentPath(currentPath+1) - } - } - // The status must be set here instead of in the resumeSimulation function otherwise it won't work - // correctly, because part of the logic is in this trigger function. - playButton.status = 1 - } - } - } - FontMetrics { id: fontMetrics diff --git a/plugins/SimulationView/__init__.py b/plugins/SimulationView/__init__.py index 3f89ee490f..b12e582441 100644 --- a/plugins/SimulationView/__init__.py +++ b/plugins/SimulationView/__init__.py @@ -13,7 +13,6 @@ def getMetaData(): return { "view": { "name": catalog.i18nc("@item:inlistbox", "Layer view"), - "view_panel": "SimulationView.qml", "weight": 2 } } diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 9f53b75dd1..e49683cb8e 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -155,24 +155,6 @@ UM.MainWindow color: UM.Theme.getColor("main_window_header_background") } - Loader - { - // The stage menu is, as the name implies, a menu that is defined by the active stage. - // Note that this menu does not need to be set at all! It's perfectly acceptable to have a stage - // without this menu! - id: stageMenu - - anchors - { - left: parent.left - right: parent.right - top: parent.top - } - - height: UM.Theme.getSize("stage_menu").height - source: UM.Controller.activeStage != null ? UM.Controller.activeStage.stageMenuComponent : "" - } - Connections { target: stageMenu.item @@ -230,6 +212,22 @@ UM.MainWindow } } + Loader + { + id: viewPanel + + anchors.bottom: viewModeButton.top + anchors.topMargin: UM.Theme.getSize("default_margin").height + anchors.right: viewModeButton.right + + property var buttonTarget: Qt.point(viewModeButton.x + Math.round(viewModeButton.width / 2), viewModeButton.y + Math.round(viewModeButton.height / 2)) + + height: childrenRect.height + width: childrenRect.width + + source: UM.ActiveView.valid ? UM.ActiveView.activeViewPanel : "" + } + Cura.ActionPanelWidget { anchors.right: parent.right @@ -254,15 +252,26 @@ UM.MainWindow anchors.fill: parent - MouseArea + source: UM.Controller.activeStage != null ? UM.Controller.activeStage.mainComponent : "" + } + + + Loader + { + // The stage menu is, as the name implies, a menu that is defined by the active stage. + // Note that this menu does not need to be set at all! It's perfectly acceptable to have a stage + // without this menu! + id: stageMenu + + anchors { - visible: parent.source != "" - anchors.fill: parent - acceptedButtons: Qt.AllButtons - onWheel: wheel.accepted = true + left: parent.left + right: parent.right + top: parent.top } - source: UM.Controller.activeStage != null ? UM.Controller.activeStage.mainComponent : "" + height: UM.Theme.getSize("stage_menu").height + source: UM.Controller.activeStage != null ? UM.Controller.activeStage.stageMenuComponent : "" } UM.MessageStack From 3fc399a6443ffa0caf7fef0288c14b7b59c50cfe Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 31 Oct 2018 09:46:41 +0100 Subject: [PATCH 0109/1292] Moved default values into components CURA-5829 --- plugins/SimulationView/LayerSlider.qml | 22 +++++++++---------- plugins/SimulationView/PathSlider.qml | 14 ++++++------ .../SimulationViewMainComponent.qml | 16 -------------- .../SimulationViewMenuComponent.qml | 17 +++++++------- 4 files changed, 26 insertions(+), 43 deletions(-) diff --git a/plugins/SimulationView/LayerSlider.qml b/plugins/SimulationView/LayerSlider.qml index c30ea621c4..7a7aaa0649 100644 --- a/plugins/SimulationView/LayerSlider.qml +++ b/plugins/SimulationView/LayerSlider.qml @@ -13,22 +13,22 @@ Item { id: sliderRoot - // handle properties - property real handleSize: 10 + // Handle properties + property real handleSize: UM.Theme.getSize("slider_handle").width property real handleRadius: handleSize / 2 property real minimumRangeHandleSize: handleSize / 2 - property color upperHandleColor: "black" - property color lowerHandleColor: "black" - property color rangeHandleColor: "black" - property color handleActiveColor: "white" - property real handleLabelWidth: width + property color upperHandleColor: UM.Theme.getColor("slider_handle") + property color lowerHandleColor: UM.Theme.getColor("slider_handle") + property color rangeHandleColor: UM.Theme.getColor("slider_groove_fill") + property color handleActiveColor: UM.Theme.getColor("slider_handle_active") + property real handleLabelWidth: UM.Theme.getSize("slider_layerview_background").width property var activeHandle: upperHandle - // track properties - property real trackThickness: 4 // width of the slider track + // Track properties + property real trackThickness: UM.Theme.getSize("slider_groove").width // width of the slider track property real trackRadius: trackThickness / 2 - property color trackColor: "white" - property real trackBorderWidth: 1 // width of the slider track border + property color trackColor: UM.Theme.getColor("slider_groove") + property real trackBorderWidth: UM.Theme.getColor("slider_groove_border") property color trackBorderColor: "black" // value properties diff --git a/plugins/SimulationView/PathSlider.qml b/plugins/SimulationView/PathSlider.qml index f3c28fb5f7..701e54e398 100644 --- a/plugins/SimulationView/PathSlider.qml +++ b/plugins/SimulationView/PathSlider.qml @@ -14,19 +14,19 @@ Item id: sliderRoot // handle properties - property real handleSize: 10 + property real handleSize: UM.Theme.getSize("slider_handle").width property real handleRadius: handleSize / 2 - property color handleColor: "black" - property color handleActiveColor: "white" - property color rangeColor: "black" + property color handleColor: UM.Theme.getColor("slider_handle") + property color handleActiveColor: UM.Theme.getColor("slider_handle_active") + property color rangeColor: UM.Theme.getColor("slider_groove_fill") property real handleLabelWidth: width // track properties - property real trackThickness: 4 // width of the slider track + property real trackThickness: UM.Theme.getSize("slider_groove").width property real trackRadius: trackThickness / 2 - property color trackColor: "white" + property color trackColor: UM.Theme.getColor("slider_groove") property real trackBorderWidth: 1 // width of the slider track border - property color trackBorderColor: "black" + property color trackBorderColor: UM.Theme.getColor("slider_groove_border") // value properties property real maximumValue: 100 diff --git a/plugins/SimulationView/SimulationViewMainComponent.qml b/plugins/SimulationView/SimulationViewMainComponent.qml index a4ec411124..2484ec25ba 100644 --- a/plugins/SimulationView/SimulationViewMainComponent.qml +++ b/plugins/SimulationView/SimulationViewMainComponent.qml @@ -30,13 +30,6 @@ Item // Custom properties handleValue: UM.SimulationView.currentPath maximumValue: UM.SimulationView.numPaths - handleSize: UM.Theme.getSize("slider_handle").width - trackThickness: UM.Theme.getSize("slider_groove").width - trackColor: UM.Theme.getColor("slider_groove") - trackBorderColor: UM.Theme.getColor("slider_groove_border") - handleColor: UM.Theme.getColor("slider_handle") - handleActiveColor: UM.Theme.getColor("slider_handle_active") - rangeColor: UM.Theme.getColor("slider_groove_fill") // Update values when layer data changes. Connections @@ -175,15 +168,6 @@ Item upperValue: UM.SimulationView.currentLayer lowerValue: UM.SimulationView.minimumLayer maximumValue: UM.SimulationView.numLayers - handleSize: UM.Theme.getSize("slider_handle").width - trackThickness: UM.Theme.getSize("slider_groove").width - trackColor: UM.Theme.getColor("slider_groove") - trackBorderColor: UM.Theme.getColor("slider_groove_border") - upperHandleColor: UM.Theme.getColor("slider_handle") - lowerHandleColor: UM.Theme.getColor("slider_handle") - rangeHandleColor: UM.Theme.getColor("slider_groove_fill") - handleActiveColor: UM.Theme.getColor("slider_handle_active") - handleLabelWidth: UM.Theme.getSize("slider_layerview_background").width // Update values when layer data changes Connections diff --git a/plugins/SimulationView/SimulationViewMenuComponent.qml b/plugins/SimulationView/SimulationViewMenuComponent.qml index 91ef7a2794..a9c7305c17 100644 --- a/plugins/SimulationView/SimulationViewMenuComponent.qml +++ b/plugins/SimulationView/SimulationViewMenuComponent.qml @@ -216,15 +216,14 @@ Item onPreferenceChanged: { layerTypeCombobox.currentIndex = UM.SimulationView.compatibilityMode ? 1 : UM.Preferences.getValue("layerview/layer_view_type"); - layerTypeCombobox.updateLegends(layerTypeCombobox.currentIndex); - playButton.pauseSimulation(); - viewSettings.extruder_opacities = UM.Preferences.getValue("layerview/extruder_opacities").split("|"); - viewSettings.show_travel_moves = UM.Preferences.getValue("layerview/show_travel_moves"); - viewSettings.show_helpers = UM.Preferences.getValue("layerview/show_helpers"); - viewSettings.show_skin = UM.Preferences.getValue("layerview/show_skin"); - viewSettings.show_infill = UM.Preferences.getValue("layerview/show_infill"); - viewSettings.only_show_top_layers = UM.Preferences.getValue("view/only_show_top_layers"); - viewSettings.top_layer_count = UM.Preferences.getValue("view/top_layer_count"); + layerTypeCombobox.updateLegends(layerTypeCombobox.currentIndex) + viewSettings.extruder_opacities = UM.Preferences.getValue("layerview/extruder_opacities").split("|") + viewSettings.show_travel_moves = UM.Preferences.getValue("layerview/show_travel_moves") + viewSettings.show_helpers = UM.Preferences.getValue("layerview/show_helpers") + viewSettings.show_skin = UM.Preferences.getValue("layerview/show_skin") + viewSettings.show_infill = UM.Preferences.getValue("layerview/show_infill") + viewSettings.only_show_top_layers = UM.Preferences.getValue("view/only_show_top_layers") + viewSettings.top_layer_count = UM.Preferences.getValue("view/top_layer_count") } } From 15f586ffae119c9f2e948ce8718095156f6275e9 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 31 Oct 2018 10:30:11 +0100 Subject: [PATCH 0110/1292] Fix the location of the simulation slider label CURA-5829 --- plugins/SimulationView/LayerSlider.qml | 16 ++++++++-------- .../SimulationViewMainComponent.qml | 4 ++-- plugins/SimulationView/__init__.py | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/plugins/SimulationView/LayerSlider.qml b/plugins/SimulationView/LayerSlider.qml index 7a7aaa0649..7916cd62b3 100644 --- a/plugins/SimulationView/LayerSlider.qml +++ b/plugins/SimulationView/LayerSlider.qml @@ -28,8 +28,8 @@ Item property real trackThickness: UM.Theme.getSize("slider_groove").width // width of the slider track property real trackRadius: trackThickness / 2 property color trackColor: UM.Theme.getColor("slider_groove") - property real trackBorderWidth: UM.Theme.getColor("slider_groove_border") - property color trackBorderColor: "black" + property real trackBorderWidth: 1 + property color trackBorderColor: UM.Theme.getColor("slider_groove_border") // value properties property real maximumValue: 100 @@ -80,7 +80,7 @@ Item return Math.min(Math.max(value, sliderRoot.minimumValue), sliderRoot.maximumValue) } - // slider track + // Slider track Rectangle { id: track @@ -106,7 +106,7 @@ Item anchors.horizontalCenter: sliderRoot.horizontalCenter visible: sliderRoot.layersVisible - // set the new value when dragging + // Set the new value when dragging function onHandleDragged() { sliderRoot.manuallyChanged = true @@ -169,7 +169,7 @@ Item height: sliderRoot.handleSize + UM.Theme.getSize("default_margin").height x: parent.x + parent.width + UM.Theme.getSize("default_margin").width anchors.verticalCenter: parent.verticalCenter - target: Qt.point(sliderRoot.width, y + height / 2) + target: Qt.point(sliderRoot.width + width, y + height / 2) visible: sliderRoot.activeHandle == parent // custom properties @@ -275,7 +275,7 @@ Item id: upperHandleLabel height: sliderRoot.handleSize + UM.Theme.getSize("default_margin").height - x: parent.x + parent.width + UM.Theme.getSize("default_margin").width + x: parent.x - parent.width - width anchors.verticalCenter: parent.verticalCenter target: Qt.point(sliderRoot.width, y + height / 2) visible: sliderRoot.activeHandle == parent @@ -385,9 +385,9 @@ Item id: lowerHandleLabel height: sliderRoot.handleSize + UM.Theme.getSize("default_margin").height - x: parent.x + parent.width + UM.Theme.getSize("default_margin").width + x: parent.x - parent.width - width anchors.verticalCenter: parent.verticalCenter - target: Qt.point(sliderRoot.width, y + height / 2) + target: Qt.point(sliderRoot.width + width, y + height / 2) visible: sliderRoot.activeHandle == parent // custom properties diff --git a/plugins/SimulationView/SimulationViewMainComponent.qml b/plugins/SimulationView/SimulationViewMainComponent.qml index 2484ec25ba..5c45da6b45 100644 --- a/plugins/SimulationView/SimulationViewMainComponent.qml +++ b/plugins/SimulationView/SimulationViewMainComponent.qml @@ -135,13 +135,13 @@ Item } else { - UM.SimulationView.setCurrentLayer(currentLayer+1) + UM.SimulationView.setCurrentLayer(currentLayer + 1) UM.SimulationView.setCurrentPath(0) } } else { - UM.SimulationView.setCurrentPath(currentPath+1) + UM.SimulationView.setCurrentPath(currentPath + 1) } } // The status must be set here instead of in the resumeSimulation function otherwise it won't work diff --git a/plugins/SimulationView/__init__.py b/plugins/SimulationView/__init__.py index b12e582441..1efb7fd650 100644 --- a/plugins/SimulationView/__init__.py +++ b/plugins/SimulationView/__init__.py @@ -13,7 +13,7 @@ def getMetaData(): return { "view": { "name": catalog.i18nc("@item:inlistbox", "Layer view"), - "weight": 2 + "weight": 0 } } From 1e9aff44f635b37efc0365cce15b6f25bb980c80 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 31 Oct 2018 10:55:05 +0100 Subject: [PATCH 0111/1292] Fix QML warnings & errors CURA-5829 --- plugins/PreviewStage/PreviewMain.qml | 1 - .../SimulationViewMenuComponent.qml | 58 ++++++++----------- 2 files changed, 23 insertions(+), 36 deletions(-) diff --git a/plugins/PreviewStage/PreviewMain.qml b/plugins/PreviewStage/PreviewMain.qml index df7e09225f..04241783e9 100644 --- a/plugins/PreviewStage/PreviewMain.qml +++ b/plugins/PreviewStage/PreviewMain.qml @@ -15,5 +15,4 @@ Loader id: previewMain source: UM.Controller.activeView != null && UM.Controller.activeView.mainComponent != null ? UM.Controller.activeView.mainComponent : "" - onSourceChanged: print("THE SOURCE IS", source) } \ No newline at end of file diff --git a/plugins/SimulationView/SimulationViewMenuComponent.qml b/plugins/SimulationView/SimulationViewMenuComponent.qml index a9c7305c17..5a146910e7 100644 --- a/plugins/SimulationView/SimulationViewMenuComponent.qml +++ b/plugins/SimulationView/SimulationViewMenuComponent.qml @@ -70,7 +70,8 @@ Item border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") - Button { + Button + { id: collapseButton anchors.top: parent.top anchors.topMargin: Math.round(UM.Theme.getSize("default_margin").height + (UM.Theme.getSize("layerview_row").height - UM.Theme.getSize("default_margin").height) / 2) @@ -97,7 +98,7 @@ Item } } - ColumnLayout + Column { id: viewSettings @@ -126,11 +127,10 @@ Item Label { id: layerViewTypesLabel - anchors.left: parent.left text: catalog.i18nc("@label","Color scheme") font: UM.Theme.getFont("default"); visible: !UM.SimulationView.compatibilityMode - Layout.fillWidth: true + width: parent.width color: UM.Theme.getColor("setting_control_text") } @@ -162,13 +162,10 @@ Item ComboBox { id: layerTypeCombobox - anchors.left: parent.left - Layout.fillWidth: true - Layout.preferredWidth: UM.Theme.getSize("layerview_row").width + width: parent.width model: layerViewTypes visible: !UM.SimulationView.compatibilityMode style: UM.Theme.styles.combobox - anchors.right: parent.right onActivated: { @@ -194,14 +191,12 @@ Item Label { id: compatibilityModeLabel - anchors.left: parent.left text: catalog.i18nc("@label","Compatibility Mode") font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") visible: UM.SimulationView.compatibilityMode - Layout.fillWidth: true - Layout.preferredHeight: UM.Theme.getSize("layerview_row").height - Layout.preferredWidth: UM.Theme.getSize("layerview_row").width + height: UM.Theme.getSize("layerview_row").height + width: parent.width } Item @@ -253,9 +248,9 @@ Item border.color: UM.Theme.getColor("lining") visible: !viewSettings.show_legend & !viewSettings.show_gradient } - Layout.fillWidth: true - Layout.preferredHeight: UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("default_lining").height - Layout.preferredWidth: UM.Theme.getSize("layerview_row").width + height: UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("default_lining").height + width: parent.width + style: UM.Theme.styles.checkbox Label { @@ -264,9 +259,9 @@ Item color: UM.Theme.getColor("setting_control_text") font: UM.Theme.getFont("default") anchors.verticalCenter: parent.verticalCenter - anchors.left: extrudersModelCheckBox.left; - anchors.right: extrudersModelCheckBox.right; - anchors.leftMargin: UM.Theme.getSize("checkbox").width + Math.round(UM.Theme.getSize("default_margin").width/2) + anchors.left: extrudersModelCheckBox.left + anchors.right: extrudersModelCheckBox.right + anchors.leftMargin: UM.Theme.getSize("checkbox").width + Math.round(UM.Theme.getSize("default_margin").width / 2) anchors.rightMargin: UM.Theme.getSize("default_margin").width * 2 } } @@ -325,9 +320,8 @@ Item border.color: UM.Theme.getColor("lining") visible: viewSettings.show_legend } - Layout.fillWidth: true - Layout.preferredHeight: UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("default_lining").height - Layout.preferredWidth: UM.Theme.getSize("layerview_row").width + height: UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("default_lining").height + width: parent.width style: UM.Theme.styles.checkbox Label { @@ -336,9 +330,9 @@ Item elide: Text.ElideRight color: UM.Theme.getColor("setting_control_text") anchors.verticalCenter: parent.verticalCenter - anchors.left: legendModelCheckBox.left; - anchors.right: legendModelCheckBox.right; - anchors.leftMargin: UM.Theme.getSize("checkbox").width + Math.round(UM.Theme.getSize("default_margin").width/2) + anchors.left: legendModelCheckBox.left + anchors.right: legendModelCheckBox.right + anchors.leftMargin: UM.Theme.getSize("checkbox").width + Math.round(UM.Theme.getSize("default_margin").width / 2) anchors.rightMargin: UM.Theme.getSize("default_margin").width * 2 } } @@ -349,7 +343,7 @@ Item checked: viewSettings.only_show_top_layers onClicked: { - UM.Preferences.setValue("view/only_show_top_layers", checked ? 1.0 : 0.0); + 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 @@ -360,7 +354,7 @@ Item checked: viewSettings.top_layer_count == 5 onClicked: { - UM.Preferences.setValue("view/top_layer_count", checked ? 5 : 1); + UM.Preferences.setValue("view/top_layer_count", checked ? 5 : 1) } text: catalog.i18nc("@label", "Show 5 Detailed Layers On Top") visible: UM.SimulationView.compatibilityMode @@ -401,9 +395,8 @@ Item border.color: UM.Theme.getColor("lining") visible: viewSettings.show_legend } - Layout.fillWidth: true - Layout.preferredHeight: UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("default_lining").height - Layout.preferredWidth: UM.Theme.getSize("layerview_row").width + height: UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("default_lining").height + width: parent.width color: UM.Theme.getColor("setting_control_text") font: UM.Theme.getFont("default") } @@ -416,11 +409,6 @@ Item visible: viewSettings.show_gradient width: parent.width height: UM.Theme.getSize("layerview_row").height - anchors - { - topMargin: UM.Theme.getSize("slider_layerview_margin").height - horizontalCenter: parent.horizontalCenter - } Label { @@ -503,7 +491,7 @@ Item // Gradient colors for feedrate Rectangle - { // In QML 5.9 can be changed by LinearGradient + { // 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 From 61442545cb99dc7379ea204f0496b1464c58da27 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 31 Oct 2018 13:56:55 +0100 Subject: [PATCH 0112/1292] Fix codestyle CURA-5829 --- plugins/SimulationView/SimulationView.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/plugins/SimulationView/SimulationView.py b/plugins/SimulationView/SimulationView.py index f1bff5f3f7..6a0ffc1666 100644 --- a/plugins/SimulationView/SimulationView.py +++ b/plugins/SimulationView/SimulationView.py @@ -16,6 +16,7 @@ from UM.Mesh.MeshBuilder import MeshBuilder from UM.Message import Message from UM.Platform import Platform from UM.PluginRegistry import PluginRegistry +from UM.Qt.QtApplication import QtApplication from UM.Resources import Resources from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator @@ -113,17 +114,15 @@ class SimulationView(CuraView): self._wireprint_warning_message = Message(catalog.i18nc("@info:status", "Cura does not accurately display layers when Wire Printing is enabled"), title = catalog.i18nc("@info:title", "Simulation View")) - Application.getInstance().engineCreatedSignal.connect(self._onEngineCreated) + QtApplication.getInstance().engineCreatedSignal.connect(self._onEngineCreated) def _onEngineCreated(self) -> None: - menu_component_path = os.path.join(PluginRegistry.getInstance().getPluginPath("SimulationView"), - "SimulationViewMenuComponent.qml") - - main_component_path = os.path.join(PluginRegistry.getInstance().getPluginPath("SimulationView"), - "SimulationViewMainComponent.qml") - - self.addDisplayComponent("main", main_component_path) - self.addDisplayComponent("menu", menu_component_path) + plugin_path = PluginRegistry.getInstance().getPluginPath(self.getPluginId()) + if plugin_path: + self.addDisplayComponent("main", os.path.join(plugin_path, "SimulationViewMainComponent.qml")) + self.addDisplayComponent("menu", os.path.join(plugin_path, "SimulationViewMenuComponent.qml")) + else: + Logger.log("e", "Unable to find the path for %s", self.getPluginId()) def _evaluateCompatibilityMode(self) -> bool: return OpenGLContext.isLegacyOpenGL() or bool(Application.getInstance().getPreferences().getValue("view/force_layer_view_compatibility_mode")) From ec0d9f09b7a800f073422c102f679d7a24d44a48 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 31 Oct 2018 17:03:09 +0100 Subject: [PATCH 0113/1292] Create a component for selecting the output device before output the file. Contributes to CURA-5786. --- resources/qml/ActionButton.qml | 9 ++ resources/qml/ActionPanelWidget.qml | 4 +- resources/qml/OutputDevicesActionButton.qml | 98 +++++++++++++++++++++ resources/qml/OutputProcessWidget.qml | 6 +- resources/qml/SliceProcessWidget.qml | 6 +- resources/qml/qmldir | 3 +- 6 files changed, 116 insertions(+), 10 deletions(-) create mode 100644 resources/qml/OutputDevicesActionButton.qml diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index a1c03af143..05e75ac8c5 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -14,6 +14,7 @@ Button property alias iconSource: buttonIcon.source property alias textFont: buttonText.font property alias cornerRadius: backgroundRect.radius + property alias tooltip: tooltip.text property var color: UM.Theme.getColor("primary") property var hoverColor: UM.Theme.getColor("primary_hover") property var disabledColor: color @@ -62,6 +63,14 @@ Button Behavior on color { ColorAnimation { duration: 50 } } } + ToolTip + { + id: tooltip + text: "" + delay: 500 + visible: text != "" && button.hovered + } + MouseArea { id: mouseArea diff --git a/resources/qml/ActionPanelWidget.qml b/resources/qml/ActionPanelWidget.qml index 6c76c31f1b..417883af6f 100644 --- a/resources/qml/ActionPanelWidget.qml +++ b/resources/qml/ActionPanelWidget.qml @@ -21,7 +21,7 @@ Rectangle radius: UM.Theme.getSize("default_radius").width visible: CuraApplication.platformActivity - property bool backendStatusDone: UM.Backend.state == UM.Backend.Done + property bool outputAvailable: UM.Backend.state == UM.Backend.Done || UM.Backend.state == UM.Backend.Disabled Loader { @@ -33,7 +33,7 @@ Rectangle left: parent.left leftMargin: UM.Theme.getSize("thick_margin").width } - sourceComponent: backendStatusDone ? outputProcessWidget : sliceProcessWidget + sourceComponent: outputAvailable ? outputProcessWidget : sliceProcessWidget } Behavior on height { NumberAnimation { duration: 100 } } diff --git a/resources/qml/OutputDevicesActionButton.qml b/resources/qml/OutputDevicesActionButton.qml new file mode 100644 index 0000000000..b0cca0eba0 --- /dev/null +++ b/resources/qml/OutputDevicesActionButton.qml @@ -0,0 +1,98 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.1 +import QtQuick.Layouts 1.3 + +import UM 1.1 as UM +import Cura 1.0 as Cura + +Item +{ + id: widget + + Cura.ActionButton + { + id: saveToButton + height: parent.height + + anchors + { + top: parent.top + left: parent.left + right: deviceSelectionMenu.visible ? deviceSelectionMenu.left : parent.right + } + + tooltip: UM.OutputDeviceManager.activeDeviceDescription + + text: UM.OutputDeviceManager.activeDeviceShortDescription + + onClicked: + { + forceActiveFocus(); + UM.OutputDeviceManager.requestWriteToDevice(UM.OutputDeviceManager.activeDevice, PrintInformation.jobName, + { "filter_by_machine": true, "preferred_mimetypes": Cura.MachineManager.activeMachine.preferred_output_file_formats }); + } + } + + Cura.ActionButton + { + id: deviceSelectionMenu + height: parent.height + + anchors + { + top: parent.top + right: parent.right + } + + tooltip: catalog.i18nc("@info:tooltip", "Select the active output device") + iconSource: popup.opened ? UM.Theme.getIcon("arrow_top") : UM.Theme.getIcon("arrow_bottom") + visible: (devicesModel.deviceCount > 1) + + onClicked: popup.opened ? popup.close() : popup.open() + + Popup + { + id: popup + + y: -height + x: parent.width - width + + closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent + + contentItem: Column + { + Repeater + { + model: devicesModel + + delegate: Cura.ActionButton + { + text: model.description + color: "transparent" + hoverColor: "red" + + onClicked: + { + UM.OutputDeviceManager.setActiveDevice(model.id) + popup.close() + } + } + } + } + + background: Rectangle + { + opacity: visible ? 1 : 0 + Behavior on opacity { NumberAnimation { duration: 100 } } + color: UM.Theme.getColor("primary") + border.color: UM.Theme.getColor("lining") + border.width: UM.Theme.getSize("default_lining").width + } + } + } + + UM.OutputDevicesModel { id: devicesModel } +} \ No newline at end of file diff --git a/resources/qml/OutputProcessWidget.qml b/resources/qml/OutputProcessWidget.qml index 244fba57ef..d3f306fed5 100644 --- a/resources/qml/OutputProcessWidget.qml +++ b/resources/qml/OutputProcessWidget.qml @@ -96,12 +96,10 @@ Column onClicked: console.log("Clicking preview") } - Cura.ActionButton + Cura.OutputDevicesActionButton { - width: UM.Theme.getSize("account_button").width + width: UM.Theme.getSize("action_panel_button").width height: UM.Theme.getSize("action_panel_button").height - text: catalog.i18nc("@button", "Save to file") - onClicked: console.log("Clicking action button") } } } \ No newline at end of file diff --git a/resources/qml/SliceProcessWidget.qml b/resources/qml/SliceProcessWidget.qml index 38a529b04e..3ea6e09975 100644 --- a/resources/qml/SliceProcessWidget.qml +++ b/resources/qml/SliceProcessWidget.qml @@ -28,7 +28,7 @@ Column function sliceOrStopSlicing() { - if ([UM.Backend.NotStarted, UM.Backend.Disabled].indexOf(widget.backendState) != -1) + if (widget.backendState == UM.Backend.NotStarted) { CuraApplication.backend.forceSlice() } @@ -86,7 +86,7 @@ Column height: UM.Theme.getSize("action_panel_button").height text: { - if ([UM.Backend.NotStarted, UM.Backend.Error, UM.Backend.Disabled].indexOf(widget.backendState) != -1) + if ([UM.Backend.NotStarted, UM.Backend.Error].indexOf(widget.backendState) != -1) { return catalog.i18nc("@button", "Slice") } @@ -101,7 +101,7 @@ Column // Get the current value from the preferences property bool autoSlice: UM.Preferences.getValue("general/auto_slice") // Disable the slice process when - property bool disabledSlice: [UM.Backend.Done, UM.Backend.Error, UM.Backend.Disabled].indexOf(widget.backendState) != -1 + property bool disabledSlice: [UM.Backend.Done, UM.Backend.Error].indexOf(widget.backendState) != -1 disabledColor: disabledSlice ? UM.Theme.getColor("action_button_disabled") : "transparent" textDisabledColor: disabledSlice ? UM.Theme.getColor("action_button_disabled_text") : UM.Theme.getColor("primary") diff --git a/resources/qml/qmldir b/resources/qml/qmldir index 22e3ff1303..d5e4106d33 100644 --- a/resources/qml/qmldir +++ b/resources/qml/qmldir @@ -8,4 +8,5 @@ ActionButton 1.0 ActionButton.qml MaterialMenu 1.0 MaterialMenu.qml NozzleMenu 1.0 NozzleMenu.qml ActionPanelWidget 1.0 ActionPanelWidget.qml -IconLabel 1.0 IconLabel.qml \ No newline at end of file +IconLabel 1.0 IconLabel.qml +OutputDevicesActionButton 1.0 OutputDevicesActionButton.qml \ No newline at end of file From 3a7ae58563613088006fe0cb386d20e4dad76bd2 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 31 Oct 2018 17:23:38 +0100 Subject: [PATCH 0114/1292] Small changes in the buttons to fit with the designs. Contributes to CURA-5786. --- resources/qml/OutputDevicesActionButton.qml | 9 +++++++-- resources/themes/cura-light/theme.json | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/resources/qml/OutputDevicesActionButton.qml b/resources/qml/OutputDevicesActionButton.qml index b0cca0eba0..11be11a2b0 100644 --- a/resources/qml/OutputDevicesActionButton.qml +++ b/resources/qml/OutputDevicesActionButton.qml @@ -49,6 +49,7 @@ Item tooltip: catalog.i18nc("@info:tooltip", "Select the active output device") iconSource: popup.opened ? UM.Theme.getIcon("arrow_top") : UM.Theme.getIcon("arrow_bottom") + color: UM.Theme.getColor("action_panel_secondary") visible: (devicesModel.deviceCount > 1) onClicked: popup.opened ? popup.close() : popup.open() @@ -56,6 +57,7 @@ Item Popup { id: popup + padding: 0 y: -height x: parent.width - width @@ -72,7 +74,9 @@ Item { text: model.description color: "transparent" - hoverColor: "red" + outlineColor: "transparent" + cornerRadius: 0 + hoverColor: UM.Theme.getColor("primary") onClicked: { @@ -87,7 +91,8 @@ Item { opacity: visible ? 1 : 0 Behavior on opacity { NumberAnimation { duration: 100 } } - color: UM.Theme.getColor("primary") + radius: UM.Theme.getSize("default_radius") + color: UM.Theme.getColor("action_panel_secondary") border.color: UM.Theme.getColor("lining") border.width: UM.Theme.getSize("default_lining").width } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 1473a75eec..658fa00596 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -103,6 +103,8 @@ "machine_selector_hover": [68, 72, 75, 255], "machine_selector_text_active": [255, 255, 255, 255], + "action_panel_secondary": [27, 95, 202, 255], + "text": [0, 0, 0, 255], "text_detail": [174, 174, 174, 128], "text_link": [50, 130, 255, 255], From dcad95aab9cfb2ec215dc3cb22467fffff2918b7 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 1 Nov 2018 12:44:14 +0100 Subject: [PATCH 0115/1292] Rename Toolbox button to Marketplace. Contributes to CURA-5784. --- resources/qml/MainWindow/MainWindowHeader.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/MainWindow/MainWindowHeader.qml b/resources/qml/MainWindow/MainWindowHeader.qml index 3f088e782f..59ec542e6b 100644 --- a/resources/qml/MainWindow/MainWindowHeader.qml +++ b/resources/qml/MainWindow/MainWindowHeader.qml @@ -83,7 +83,7 @@ Rectangle } leftPadding: UM.Theme.getSize("default_margin").width rightPadding: UM.Theme.getSize("default_margin").width - text: catalog.i18nc("@action:button", "Toolbox") + text: catalog.i18nc("@action:button", "Marketplace") height: Math.round(0.5 * UM.Theme.getSize("main_window_header").height) color: UM.Theme.getColor("main_window_header_secondary_button_background_active") hoverColor: UM.Theme.getColor("main_window_header_secondary_button_background_hovered") From b03695dec66ef5bb10a07222fb11d96e92eb1155 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 2 Nov 2018 09:33:27 +0100 Subject: [PATCH 0116/1292] Add print time information and material costs to the action panel. Contributes to CURA-5786. --- resources/qml/OutputProcessWidget.qml | 33 +++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/resources/qml/OutputProcessWidget.qml b/resources/qml/OutputProcessWidget.qml index d3f306fed5..435cc6da79 100644 --- a/resources/qml/OutputProcessWidget.qml +++ b/resources/qml/OutputProcessWidget.qml @@ -30,6 +30,7 @@ Column Column { id: timeAndCostsInformation + spacing: UM.Theme.getSize("thin_margin").height anchors { @@ -43,7 +44,9 @@ Column id: estimatedTime width: parent.width - text: "Time" + property var printDuration: PrintInformation.currentPrintTime + + text: printDuration.getDisplayString(UM.DurationFormat.Long) source: UM.Theme.getIcon("clock") font: UM.Theme.getFont("small") } @@ -53,7 +56,33 @@ Column id: estimatedCosts width: parent.width - text: "Material costs" + property var printMaterialLengths: PrintInformation.materialLengths + property var printMaterialWeights: PrintInformation.materialWeights + + function getText() + { + var lengths = [] + var weights = [] + if(printMaterialLengths) + { + for(var index = 0; index < printMaterialLengths.length; index++) + { + if(printMaterialLengths[index] > 0) + { + lengths.push(printMaterialLengths[index].toFixed(2)) + weights.push(String(Math.round(printMaterialWeights[index]))) + } + } + } + if(lengths.length == 0) + { + lengths = ["0.00"] + weights = ["0"] + } + return weights.join(" + ") + "g · " + lengths.join(" + ") + "m" + } + + text: getText() source: UM.Theme.getIcon("spool") font: UM.Theme.getFont("very_small") } From 310539cb6dc84e0245a86d3e0b10aa79d413d536 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 2 Nov 2018 09:58:35 +0100 Subject: [PATCH 0117/1292] In the main action panel, only show the total amount of material weight and length (addition of all extruders). The information panel will show each cost separately. Contributes to CURA-5786. --- .../{ => ActionPanel}/ActionPanelWidget.qml | 0 .../OutputDevicesActionButton.qml | 0 .../{ => ActionPanel}/OutputProcessWidget.qml | 21 ++++++++----------- .../{ => ActionPanel}/SliceProcessWidget.qml | 0 4 files changed, 9 insertions(+), 12 deletions(-) rename resources/qml/{ => ActionPanel}/ActionPanelWidget.qml (100%) rename resources/qml/{ => ActionPanel}/OutputDevicesActionButton.qml (100%) rename resources/qml/{ => ActionPanel}/OutputProcessWidget.qml (84%) rename resources/qml/{ => ActionPanel}/SliceProcessWidget.qml (100%) diff --git a/resources/qml/ActionPanelWidget.qml b/resources/qml/ActionPanel/ActionPanelWidget.qml similarity index 100% rename from resources/qml/ActionPanelWidget.qml rename to resources/qml/ActionPanel/ActionPanelWidget.qml diff --git a/resources/qml/OutputDevicesActionButton.qml b/resources/qml/ActionPanel/OutputDevicesActionButton.qml similarity index 100% rename from resources/qml/OutputDevicesActionButton.qml rename to resources/qml/ActionPanel/OutputDevicesActionButton.qml diff --git a/resources/qml/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml similarity index 84% rename from resources/qml/OutputProcessWidget.qml rename to resources/qml/ActionPanel/OutputProcessWidget.qml index 435cc6da79..bef40fdfca 100644 --- a/resources/qml/OutputProcessWidget.qml +++ b/resources/qml/ActionPanel/OutputProcessWidget.qml @@ -61,25 +61,20 @@ Column function getText() { - var lengths = [] - var weights = [] - if(printMaterialLengths) + var totalLengths = 0 + var totalWeights = 0 + if (printMaterialLengths) { for(var index = 0; index < printMaterialLengths.length; index++) { if(printMaterialLengths[index] > 0) { - lengths.push(printMaterialLengths[index].toFixed(2)) - weights.push(String(Math.round(printMaterialWeights[index]))) + totalLengths += printMaterialLengths[index] + totalWeights += Math.round(printMaterialWeights[index]) } } } - if(lengths.length == 0) - { - lengths = ["0.00"] - weights = ["0"] - } - return weights.join(" + ") + "g · " + lengths.join(" + ") + "m" + return totalWeights + "g · " + totalLengths.toFixed(2) + "m" } text: getText() @@ -116,13 +111,15 @@ Column Cura.ActionButton { + leftPadding: UM.Theme.getSize("default_margin").width + rightPadding: UM.Theme.getSize("default_margin").width height: UM.Theme.getSize("action_panel_button").height text: catalog.i18nc("@button", "Preview") color: UM.Theme.getColor("secondary") hoverColor: UM.Theme.getColor("secondary") textColor: UM.Theme.getColor("primary") textHoverColor: UM.Theme.getColor("text") - onClicked: console.log("Clicking preview") + onClicked: UM.Controller.setActiveStage("MonitorStage") } Cura.OutputDevicesActionButton diff --git a/resources/qml/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml similarity index 100% rename from resources/qml/SliceProcessWidget.qml rename to resources/qml/ActionPanel/SliceProcessWidget.qml From c862e72514230a7ed5eee59ca3257c5c58deb968 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 2 Nov 2018 11:10:23 +0100 Subject: [PATCH 0118/1292] Add the print panel information as a popup that shows when the "i" icon is clicked. Contributes to CURA-5786. --- .../ActionPanel/OutputDevicesActionButton.qml | 2 +- .../qml/ActionPanel/OutputProcessWidget.qml | 16 +---- .../ActionPanel/PrintInformationWidget.qml | 62 +++++++++++++++++++ 3 files changed, 66 insertions(+), 14 deletions(-) create mode 100644 resources/qml/ActionPanel/PrintInformationWidget.qml diff --git a/resources/qml/ActionPanel/OutputDevicesActionButton.qml b/resources/qml/ActionPanel/OutputDevicesActionButton.qml index 11be11a2b0..32d5f8a73b 100644 --- a/resources/qml/ActionPanel/OutputDevicesActionButton.qml +++ b/resources/qml/ActionPanel/OutputDevicesActionButton.qml @@ -91,7 +91,7 @@ Item { opacity: visible ? 1 : 0 Behavior on opacity { NumberAnimation { duration: 100 } } - radius: UM.Theme.getSize("default_radius") + radius: UM.Theme.getSize("default_radius").width color: UM.Theme.getColor("action_panel_secondary") border.color: UM.Theme.getColor("lining") border.width: UM.Theme.getSize("default_lining").width diff --git a/resources/qml/ActionPanel/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml index bef40fdfca..a2f9f13576 100644 --- a/resources/qml/ActionPanel/OutputProcessWidget.qml +++ b/resources/qml/ActionPanel/OutputProcessWidget.qml @@ -4,7 +4,6 @@ import QtQuick 2.7 import QtQuick.Controls 2.1 import QtQuick.Layouts 1.3 -import QtQuick.Controls 1.4 as Controls1 import UM 1.1 as UM import Cura 1.0 as Cura @@ -35,7 +34,7 @@ Column anchors { left: parent.left - right: moreInformationIcon.left + right: printInformationPanel.left rightMargin: UM.Theme.getSize("thin_margin").height } @@ -83,24 +82,15 @@ Column } } - UM.RecolorImage + PrintInformationWidget { - id: moreInformationIcon + id: printInformationPanel anchors { right: parent.right verticalCenter: timeAndCostsInformation.verticalCenter } - - source: UM.Theme.getIcon("info") - width: UM.Theme.getSize("section_icon").width - height: UM.Theme.getSize("section_icon").height - - sourceSize.width: width - sourceSize.height: height - - color: UM.Theme.getColor("text_medium") } } diff --git a/resources/qml/ActionPanel/PrintInformationWidget.qml b/resources/qml/ActionPanel/PrintInformationWidget.qml new file mode 100644 index 0000000000..f8f91869aa --- /dev/null +++ b/resources/qml/ActionPanel/PrintInformationWidget.qml @@ -0,0 +1,62 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.1 + +import UM 1.1 as UM +import Cura 1.0 as Cura + +Button +{ + id: widget + + implicitHeight: UM.Theme.getSize("section_icon").height + implicitWidth: UM.Theme.getSize("section_icon").width + + background: UM.RecolorImage + { + id: moreInformationIcon + + source: UM.Theme.getIcon("info") + width: UM.Theme.getSize("section_icon").width + height: UM.Theme.getSize("section_icon").height + + sourceSize.width: width + sourceSize.height: height + + color: widget.hovered ? UM.Theme.getColor("primary") : UM.Theme.getColor("text_medium") + } + + onClicked: popup.opened ? popup.close() : popup.open() + + Popup + { + id: popup + + y: -(height + UM.Theme.getSize("default_arrow").height + UM.Theme.getSize("thin_margin").height) + x: parent.width - width + UM.Theme.getSize("thin_margin").width + + closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent + + contentItem: Label + { + id: panel + text: "Lorem ipsum dolor sit amet,\nconsectetur adipiscing elit, \nsed do eiusmod tempor incididunt \nut labore et dolore magna aliqua. \nUt enim ad minim veniam, ..." + } + + background: UM.PointingRectangle + { + opacity: visible ? 1 : 0 + Behavior on opacity { NumberAnimation { duration: 100 } } + color: UM.Theme.getColor("tool_panel_background") + borderColor: UM.Theme.getColor("lining") + borderWidth: UM.Theme.getSize("default_lining").width + + target: Qt.point(width - (widget.width / 2) - UM.Theme.getSize("thin_margin").width, + height + UM.Theme.getSize("default_arrow").height - UM.Theme.getSize("thin_margin").height) + + arrowSize: UM.Theme.getSize("default_arrow").width + } + } +} \ No newline at end of file From ef7ac3b089cc51712c850c3d1688ecd25cdc55d7 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 2 Nov 2018 13:29:55 +0100 Subject: [PATCH 0119/1292] Create the new component that gathers all the printjob information (times and material usage) in a popup that is shown when the "i" icon is pressed. Contributes to CURA-5786. --- .../ActionPanel/PrintInformationWidget.qml | 6 +- .../qml/ActionPanel/PrintJobInformation.qml | 166 ++++++++++++++++++ resources/themes/cura-light/theme.json | 2 +- 3 files changed, 170 insertions(+), 4 deletions(-) create mode 100644 resources/qml/ActionPanel/PrintJobInformation.qml diff --git a/resources/qml/ActionPanel/PrintInformationWidget.qml b/resources/qml/ActionPanel/PrintInformationWidget.qml index f8f91869aa..620c3a408c 100644 --- a/resources/qml/ActionPanel/PrintInformationWidget.qml +++ b/resources/qml/ActionPanel/PrintInformationWidget.qml @@ -39,10 +39,10 @@ Button closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent - contentItem: Label + contentItem: PrintJobInformation { - id: panel - text: "Lorem ipsum dolor sit amet,\nconsectetur adipiscing elit, \nsed do eiusmod tempor incididunt \nut labore et dolore magna aliqua. \nUt enim ad minim veniam, ..." + id: printJobInformation + width: UM.Theme.getSize("action_panel_information_widget").width } background: UM.PointingRectangle diff --git a/resources/qml/ActionPanel/PrintJobInformation.qml b/resources/qml/ActionPanel/PrintJobInformation.qml new file mode 100644 index 0000000000..0eaa0ca46f --- /dev/null +++ b/resources/qml/ActionPanel/PrintJobInformation.qml @@ -0,0 +1,166 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.1 + +import UM 1.1 as UM +import Cura 1.0 as Cura + +Column +{ + id: base + spacing: UM.Theme.getSize("default_margin").width + + UM.I18nCatalog + { + id: catalog + name: "cura" + } + + Column + { + id: timeSpecification + spacing: UM.Theme.getSize("thin_margin").width + width: parent.width + topPadding: UM.Theme.getSize("default_margin").height + leftPadding: UM.Theme.getSize("default_margin").width + rightPadding: UM.Theme.getSize("default_margin").width + + Label + { + text: catalog.i18nc("@label", "Time specification").toUpperCase() + color: UM.Theme.getColor("primary") + font: UM.Theme.getFont("small") + renderType: Text.NativeRendering + } + + Label + { + property var printDuration: PrintInformation.currentPrintTime + + function getTimeSpecifications() + { + // All the time information for the different features is achieved + var printTime = PrintInformation.getFeaturePrintTimes() + var totalSeconds = parseInt(printDuration.getDisplayString(UM.DurationFormat.Seconds)) + + // A message is created and displayed when the user hover the time label + var text = "" + for(var feature in printTime) + { + if(!printTime[feature].isTotalDurationZero) + { + text += "" + + "".arg(printTime[feature].getDisplayString(UM.DurationFormat.ISO8601).slice(0,-3)) + + "".arg(Math.round(100 * parseInt(printTime[feature].getDisplayString(UM.DurationFormat.Seconds)) / totalSeconds)) + + "" + } + } + text += "
" + feature + ":  %1  %1%
" + print(text) + return text + } + + text: getTimeSpecifications() + width: parent.width - 2 * UM.Theme.getSize("default_margin").width + color: UM.Theme.getColor("text") + font: UM.Theme.getFont("very_small") + renderType: Text.NativeRendering + textFormat: Text.RichText + } + } + + Column + { + id: materialSpecification + spacing: UM.Theme.getSize("thin_margin").width + width: parent.width + bottomPadding: UM.Theme.getSize("default_margin").height + leftPadding: UM.Theme.getSize("default_margin").width + rightPadding: UM.Theme.getSize("default_margin").width + + Label + { + text: catalog.i18nc("@label", "Material specification").toUpperCase() + color: UM.Theme.getColor("primary") + font: UM.Theme.getFont("small") + renderType: Text.NativeRendering + } + + Label + { + property var printMaterialLengths: PrintInformation.materialLengths + property var printMaterialWeights: PrintInformation.materialWeights + property var printMaterialCosts: PrintInformation.materialCosts + property var printMaterialNames: PrintInformation.materialNames + + function formatRow(items) + { + var rowHTML = "" + for(var item = 0; item < items.length; item++) + { + if (item == 0) + { + rowHTML += "%1".arg(items[item]) + } + else + { + rowHTML += "  %1".arg(items[item]) + } + } + rowHTML += "" + return rowHTML + } + + function getMaterialSpecifications() + { + var lengths = [] + var weights = [] + var costs = [] + var names = [] + if(printMaterialLengths) + { + for(var index = 0; index < printMaterialLengths.length; index++) + { + if(printMaterialLengths[index] > 0) + { + names.push(printMaterialNames[index]) + lengths.push(printMaterialLengths[index].toFixed(2)) + weights.push(String(Math.round(printMaterialWeights[index]))) + var cost = printMaterialCosts[index] == undefined ? 0 : printMaterialCosts[index].toFixed(2) + costs.push(cost) + } + } + } + if(lengths.length == 0) + { + lengths = ["0.00"] + weights = ["0"] + costs = ["0.00"] + } + + var text = "" + for(var index = 0; index < lengths.length; index++) + { + text += formatRow([ + "%1:".arg(names[index]), + catalog.i18nc("@label m for meter", "%1m").arg(lengths[index]), + catalog.i18nc("@label g for grams", "%1g").arg(weights[index]), + "%1 %2".arg(UM.Preferences.getValue("cura/currency")).arg(costs[index]), + ]) + } + text += "
" + + return text + } + + text: getMaterialSpecifications() + width: parent.width - 2 * UM.Theme.getSize("default_margin").width + color: UM.Theme.getColor("text") + font: UM.Theme.getFont("very_small") + renderType: Text.NativeRendering + textFormat: Text.RichText + } + } +} \ No newline at end of file diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 658fa00596..f354b521ee 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -379,7 +379,7 @@ "configuration_selector_widget": [35.0, 4.5], "configuration_selector_mode_tabs": [0.0, 3.0], - "action_panel_widget": [35.0, 0.0], + "action_panel_information_widget": [20.0, 0.0], "action_panel_button": [15.0, 3.0], "machine_selector_widget": [28.0, 4.5], From 300d109cfe45cd64665536e0113ade0e12ff0260 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 2 Nov 2018 13:37:57 +0100 Subject: [PATCH 0120/1292] Set the Z of the machine selector so the tooltip doesn't get hidden CURA-5772 --- plugins/PrepareStage/PrepareMenu.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index cdcc1384a2..e8514a9ef9 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -45,6 +45,7 @@ Item id: machineSelection width: UM.Theme.getSize("machine_selector_widget").width - configSelection.width height: prepareMenu.height + z: openFileButton.z - 1 } Cura.QuickConfigurationSelector From 34b76596f19931cd7498c837e105d95f6db1d445 Mon Sep 17 00:00:00 2001 From: Shelby Merrick Date: Fri, 2 Nov 2018 09:39:12 -0400 Subject: [PATCH 0121/1292] Updated to reference speed_travel macro --- resources/definitions/wanhao_d4s.def.json | 4 ++-- resources/definitions/wanhao_d6.def.json | 4 ++-- resources/definitions/wanhao_d6_plus.def.json | 4 ++-- resources/definitions/wanhao_duplicator5S.def.json | 4 ++-- resources/definitions/wanhao_duplicator5Smini.def.json | 4 ++-- resources/definitions/wanhao_i3.def.json | 4 ++-- resources/definitions/wanhao_i3mini.def.json | 4 ++-- resources/definitions/wanhao_i3plus.def.json | 4 ++-- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/resources/definitions/wanhao_d4s.def.json b/resources/definitions/wanhao_d4s.def.json index 8788353e92..c1807923c6 100644 --- a/resources/definitions/wanhao_d4s.def.json +++ b/resources/definitions/wanhao_d4s.def.json @@ -39,10 +39,10 @@ "default_value": "RepRap (Marlin/Sprinter)" }, "machine_start_gcode": { - "default_value": "G21 ;metric values\n G90 ;absolute positioning\n M82 ;set extruder to absolute mode\n M107 ;start with the fan off\n G28 X0 Y0 ;move X/Y to min endstops\n G28 Z0 ;move Z to min endstops\n G1 Z15.0 F{travel_speed} ;move the platform down 15mm\n G92 E0 ;zero the extruded length\n G1 F200 E6 ;extrude 6 mm of feed stock\n G92 E0 ;zero the extruded length again\n G1 F{travel_speed} \n ;Put printing message on LCD screen\n M117 Printing..." + "default_value": "G21 ;metric values\n G90 ;absolute positioning\n M82 ;set extruder to absolute mode\n M107 ;start with the fan off\n G28 X0 Y0 ;move X/Y to min endstops\n G28 Z0 ;move Z to min endstops\n G1 Z15.0 F{speed_travel} ;move the platform down 15mm\n G92 E0 ;zero the extruded length\n G1 F200 E6 ;extrude 6 mm of feed stock\n G92 E0 ;zero the extruded length again\n G1 F{speed_travel} \n ;Put printing message on LCD screen\n M117 Printing..." }, "machine_end_gcode": { - "default_value": "M104 S0 ;extruder heater off \n G91 ;relative positioning\n G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\n G1 Z+0.5 E-5 X-20 Y-20 F{travel_speed} ;move Z up a bit and retract filament even more\n G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\n M84 ;steppers off\n G90 ;absolute positioning" + "default_value": "M104 S0 ;extruder heater off \n G91 ;relative positioning\n G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\n G1 Z+0.5 E-5 X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\n G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\n M84 ;steppers off\n G90 ;absolute positioning" } } } diff --git a/resources/definitions/wanhao_d6.def.json b/resources/definitions/wanhao_d6.def.json index 7ca3031124..c8a690d02c 100644 --- a/resources/definitions/wanhao_d6.def.json +++ b/resources/definitions/wanhao_d6.def.json @@ -42,10 +42,10 @@ "default_value": "RepRap (Marlin/Sprinter)" }, "machine_start_gcode": { - "default_value": "G21 ;metric values\n G90 ;absolute positioning\n M82 ;set extruder to absolute mode\n M107 ;start with the fan off\n G28 X0 Y0 ;move X/Y to min endstops\n G28 Z0 ;move Z to min endstops\n G1 Z15.0 F{travel_speed} ;move the platform down 15mm\n G92 E0 ;zero the extruded length\n G1 F200 E6 ;extrude 6 mm of feed stock\n G92 E0 ;zero the extruded length again\n G1 F{travel_speed} \n ;Put printing message on LCD screen\n M117 Printing..." + "default_value": "G21 ;metric values\n G90 ;absolute positioning\n M82 ;set extruder to absolute mode\n M107 ;start with the fan off\n G28 X0 Y0 ;move X/Y to min endstops\n G28 Z0 ;move Z to min endstops\n G1 Z15.0 F{speed_travel} ;move the platform down 15mm\n G92 E0 ;zero the extruded length\n G1 F200 E6 ;extrude 6 mm of feed stock\n G92 E0 ;zero the extruded length again\n G1 F{speed_travel} \n ;Put printing message on LCD screen\n M117 Printing..." }, "machine_end_gcode": { - "default_value": "M104 S0 ;extruder heater off \n G91 ;relative positioning\n G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\n G1 Z+0.5 E-5 X-20 Y-20 F{travel_speed} ;move Z up a bit and retract filament even more\n G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\n M84 ;steppers off\n G90 ;absolute positioning" + "default_value": "M104 S0 ;extruder heater off \n G91 ;relative positioning\n G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\n G1 Z+0.5 E-5 X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\n G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\n M84 ;steppers off\n G90 ;absolute positioning" } } } diff --git a/resources/definitions/wanhao_d6_plus.def.json b/resources/definitions/wanhao_d6_plus.def.json index f17b58db85..b3b5ed9b0a 100644 --- a/resources/definitions/wanhao_d6_plus.def.json +++ b/resources/definitions/wanhao_d6_plus.def.json @@ -39,10 +39,10 @@ "default_value": "RepRap (Marlin/Sprinter)" }, "machine_start_gcode": { - "default_value": "G21 ;metric values\n G90 ;absolute positioning\n M82 ;set extruder to absolute mode\n M107 ;start with the fan off\n G28 X0 Y0 ;move X/Y to min endstops\n G28 Z0 ;move Z to min endstops\n G1 Z15.0 F{travel_speed} ;move the platform down 15mm\n G92 E0 ;zero the extruded length\n G1 F200 E6 ;extrude 6 mm of feed stock\n G92 E0 ;zero the extruded length again\n G1 F{travel_speed} \n ;Put printing message on LCD screen\n M117 Printing..." + "default_value": "G21 ;metric values\n G90 ;absolute positioning\n M82 ;set extruder to absolute mode\n M107 ;start with the fan off\n G28 X0 Y0 ;move X/Y to min endstops\n G28 Z0 ;move Z to min endstops\n G1 Z15.0 F{speed_travel} ;move the platform down 15mm\n G92 E0 ;zero the extruded length\n G1 F200 E6 ;extrude 6 mm of feed stock\n G92 E0 ;zero the extruded length again\n G1 F{speed_travel} \n ;Put printing message on LCD screen\n M117 Printing..." }, "machine_end_gcode": { - "default_value": "M104 S0 ;extruder heater off \n G91 ;relative positioning\n G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\n G1 Z+0.5 E-5 X-20 Y-20 F{travel_speed} ;move Z up a bit and retract filament even more\n G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\n M84 ;steppers off\n G90 ;absolute positioning" + "default_value": "M104 S0 ;extruder heater off \n G91 ;relative positioning\n G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\n G1 Z+0.5 E-5 X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\n G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\n M84 ;steppers off\n G90 ;absolute positioning" } } } diff --git a/resources/definitions/wanhao_duplicator5S.def.json b/resources/definitions/wanhao_duplicator5S.def.json index 1d29b90249..b27a13fda8 100644 --- a/resources/definitions/wanhao_duplicator5S.def.json +++ b/resources/definitions/wanhao_duplicator5S.def.json @@ -42,10 +42,10 @@ "default_value": "RepRap (Marlin/Sprinter)" }, "machine_start_gcode": { - "default_value": "G21 ;metric values\n G90 ;absolute positioning\n M82 ;set extruder to absolute mode\n M107 ;start with the fan off\n G28 X0 Y0 ;move X/Y to min endstops\n G28 Z0 ;move Z to min endstops\n G1 Z15.0 F{travel_speed} ;move the platform down 15mm\n G92 E0 ;zero the extruded length\n G1 F200 E6 ;extrude 6 mm of feed stock\n G92 E0 ;zero the extruded length again\n G1 F{travel_speed} \n ;Put printing message on LCD screen\n M117 Printing..." + "default_value": "G21 ;metric values\n G90 ;absolute positioning\n M82 ;set extruder to absolute mode\n M107 ;start with the fan off\n G28 X0 Y0 ;move X/Y to min endstops\n G28 Z0 ;move Z to min endstops\n G1 Z15.0 F{speed_travel} ;move the platform down 15mm\n G92 E0 ;zero the extruded length\n G1 F200 E6 ;extrude 6 mm of feed stock\n G92 E0 ;zero the extruded length again\n G1 F{speed_travel} \n ;Put printing message on LCD screen\n M117 Printing..." }, "machine_end_gcode": { - "default_value": "M104 S0 ;extruder heater off \n G91 ;relative positioning\n G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\n G1 Z+0.5 E-5 X-20 Y-20 F{travel_speed} ;move Z up a bit and retract filament even more\n G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\n M84 ;steppers off\n G90 ;absolute positioning" + "default_value": "M104 S0 ;extruder heater off \n G91 ;relative positioning\n G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\n G1 Z+0.5 E-5 X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\n G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\n M84 ;steppers off\n G90 ;absolute positioning" } } } diff --git a/resources/definitions/wanhao_duplicator5Smini.def.json b/resources/definitions/wanhao_duplicator5Smini.def.json index e7f9359cf1..e3ef0b92fe 100644 --- a/resources/definitions/wanhao_duplicator5Smini.def.json +++ b/resources/definitions/wanhao_duplicator5Smini.def.json @@ -39,10 +39,10 @@ "default_value": "RepRap (Marlin/Sprinter)" }, "machine_start_gcode": { - "default_value": "G21 ;metric values\n G90 ;absolute positioning\n M82 ;set extruder to absolute mode\n M107 ;start with the fan off\n G28 X0 Y0 ;move X/Y to min endstops\n G28 Z0 ;move Z to min endstops\n G1 Z15.0 F{travel_speed} ;move the platform down 15mm\n G92 E0 ;zero the extruded length\n G1 F200 E6 ;extrude 6 mm of feed stock\n G92 E0 ;zero the extruded length again\n G1 F{travel_speed} \n ;Put printing message on LCD screen\n M117 Printing..." + "default_value": "G21 ;metric values\n G90 ;absolute positioning\n M82 ;set extruder to absolute mode\n M107 ;start with the fan off\n G28 X0 Y0 ;move X/Y to min endstops\n G28 Z0 ;move Z to min endstops\n G1 Z15.0 F{speed_travel} ;move the platform down 15mm\n G92 E0 ;zero the extruded length\n G1 F200 E6 ;extrude 6 mm of feed stock\n G92 E0 ;zero the extruded length again\n G1 F{speed_travel} \n ;Put printing message on LCD screen\n M117 Printing..." }, "machine_end_gcode": { - "default_value": "M104 S0 ;extruder heater off \n G91 ;relative positioning\n G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\n G1 Z+0.5 E-5 X-20 Y-20 F{travel_speed} ;move Z up a bit and retract filament even more\n G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\n M84 ;steppers off\n G90 ;absolute positioning" + "default_value": "M104 S0 ;extruder heater off \n G91 ;relative positioning\n G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\n G1 Z+0.5 E-5 X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\n G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\n M84 ;steppers off\n G90 ;absolute positioning" } } } diff --git a/resources/definitions/wanhao_i3.def.json b/resources/definitions/wanhao_i3.def.json index 15121f8b8b..42b19c8748 100644 --- a/resources/definitions/wanhao_i3.def.json +++ b/resources/definitions/wanhao_i3.def.json @@ -39,10 +39,10 @@ "default_value": "RepRap (Marlin/Sprinter)" }, "machine_start_gcode": { - "default_value": "G21 ;metric values\n G90 ;absolute positioning\n M82 ;set extruder to absolute mode\n M107 ;start with the fan off\n G28 X0 Y0 ;move X/Y to min endstops\n G28 Z0 ;move Z to min endstops\n G1 Z15.0 F{travel_speed} ;move the platform down 15mm\n G92 E0 ;zero the extruded length\n G1 F200 E6 ;extrude 6 mm of feed stock\n G92 E0 ;zero the extruded length again\n G1 F{travel_speed} \n ;Put printing message on LCD screen\n M117 Printing..." + "default_value": "G21 ;metric values\n G90 ;absolute positioning\n M82 ;set extruder to absolute mode\n M107 ;start with the fan off\n G28 X0 Y0 ;move X/Y to min endstops\n G28 Z0 ;move Z to min endstops\n G1 Z15.0 F{speed_travel} ;move the platform down 15mm\n G92 E0 ;zero the extruded length\n G1 F200 E6 ;extrude 6 mm of feed stock\n G92 E0 ;zero the extruded length again\n G1 F{speed_travel} \n ;Put printing message on LCD screen\n M117 Printing..." }, "machine_end_gcode": { - "default_value": "M104 S0 ;extruder heater off \n G91 ;relative positioning\n G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\n G1 Z+0.5 E-5 X-20 Y-20 F{travel_speed} ;move Z up a bit and retract filament even more\n G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\n M84 ;steppers off\n G90 ;absolute positioning" + "default_value": "M104 S0 ;extruder heater off \n G91 ;relative positioning\n G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\n G1 Z+0.5 E-5 X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\n G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\n M84 ;steppers off\n G90 ;absolute positioning" } } } diff --git a/resources/definitions/wanhao_i3mini.def.json b/resources/definitions/wanhao_i3mini.def.json index 057fca81a6..0c70391c27 100644 --- a/resources/definitions/wanhao_i3mini.def.json +++ b/resources/definitions/wanhao_i3mini.def.json @@ -39,10 +39,10 @@ "default_value": "RepRap (Marlin/Sprinter)" }, "machine_start_gcode": { - "default_value": "G21 ;metric values\n G90 ;absolute positioning\n M82 ;set extruder to absolute mode\n M107 ;start with the fan off\n G28 X0 Y0 ;move X/Y to min endstops\n G28 Z0 ;move Z to min endstops\n G1 Z15.0 F{travel_speed} ;move the platform down 15mm\n G92 E0 ;zero the extruded length\n G1 F200 E6 ;extrude 6 mm of feed stock\n G92 E0 ;zero the extruded length again\n G1 F{travel_speed} \n ;Put printing message on LCD screen\n M117 Printing..." + "default_value": "G21 ;metric values\n G90 ;absolute positioning\n M82 ;set extruder to absolute mode\n M107 ;start with the fan off\n G28 X0 Y0 ;move X/Y to min endstops\n G28 Z0 ;move Z to min endstops\n G1 Z15.0 F{speed_travel} ;move the platform down 15mm\n G92 E0 ;zero the extruded length\n G1 F200 E6 ;extrude 6 mm of feed stock\n G92 E0 ;zero the extruded length again\n G1 F{speed_travel} \n ;Put printing message on LCD screen\n M117 Printing..." }, "machine_end_gcode": { - "default_value": "M104 S0 ;extruder heater off \n G91 ;relative positioning\n G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\n G1 Z+0.5 E-5 X-20 Y-20 F{travel_speed} ;move Z up a bit and retract filament even more\n G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\n M84 ;steppers off\n G90 ;absolute positioning" + "default_value": "M104 S0 ;extruder heater off \n G91 ;relative positioning\n G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\n G1 Z+0.5 E-5 X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\n G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\n M84 ;steppers off\n G90 ;absolute positioning" } } } diff --git a/resources/definitions/wanhao_i3plus.def.json b/resources/definitions/wanhao_i3plus.def.json index 2b705c6ff5..e454a40ae1 100644 --- a/resources/definitions/wanhao_i3plus.def.json +++ b/resources/definitions/wanhao_i3plus.def.json @@ -39,10 +39,10 @@ "default_value": "RepRap (Marlin/Sprinter)" }, "machine_start_gcode": { - "default_value": "G21 ;metric values\n G90 ;absolute positioning\n M82 ;set extruder to absolute mode\n M107 ;start with the fan off\n G28 X0 Y0 ;move X/Y to min endstops\n G28 Z0 ;move Z to min endstops\n G1 Z15.0 F{travel_speed} ;move the platform down 15mm\n G92 E0 ;zero the extruded length\n G1 F200 E6 ;extrude 6 mm of feed stock\n G92 E0 ;zero the extruded length again\n G1 F{travel_speed} \n ;Put printing message on LCD screen\n M117 Printing..." + "default_value": "G21 ;metric values\n G90 ;absolute positioning\n M82 ;set extruder to absolute mode\n M107 ;start with the fan off\n G28 X0 Y0 ;move X/Y to min endstops\n G28 Z0 ;move Z to min endstops\n G1 Z15.0 F{speed_travel} ;move the platform down 15mm\n G92 E0 ;zero the extruded length\n G1 F200 E6 ;extrude 6 mm of feed stock\n G92 E0 ;zero the extruded length again\n G1 F{speed_travel} \n ;Put printing message on LCD screen\n M117 Printing..." }, "machine_end_gcode": { - "default_value": "M104 S0 ;extruder heater off \n G91 ;relative positioning\n G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\n G1 Z+0.5 E-5 X-20 Y-20 F{travel_speed} ;move Z up a bit and retract filament even more\n G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\n M84 ;steppers off\n G90 ;absolute positioning" + "default_value": "M104 S0 ;extruder heater off \n G91 ;relative positioning\n G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\n G1 Z+0.5 E-5 X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\n G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\n M84 ;steppers off\n G90 ;absolute positioning" } } } From 20b3b6da79aca7c42f935e3e9b6259918c72e63a Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 2 Nov 2018 15:11:49 +0100 Subject: [PATCH 0122/1292] Document PreviewStage.py Some stuff I had to ask the original implementer to explain to me. So I wrote that down so that the next guy doesn't have to do that. Contributes to issue CURA-5829. --- plugins/PreviewStage/PreviewMenu.qml | 3 +++ plugins/PreviewStage/PreviewStage.py | 16 ++++++++++++++++ plugins/PreviewStage/__init__.py | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index 5ed0e697a9..66f7d527d9 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -1,3 +1,6 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + import QtQuick 2.7 import QtQuick.Controls 1.4 diff --git a/plugins/PreviewStage/PreviewStage.py b/plugins/PreviewStage/PreviewStage.py index 1aed95162a..1c487c8340 100644 --- a/plugins/PreviewStage/PreviewStage.py +++ b/plugins/PreviewStage/PreviewStage.py @@ -1,5 +1,6 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. + import os.path from UM.Qt.QtApplication import QtApplication @@ -11,6 +12,11 @@ if TYPE_CHECKING: from UM.View.View import View +## Displays a preview of what you're about to print. +# +# The Python component of this stage just loads PreviewMain.qml for display +# when the stage is selected, and makes sure that it reverts to the previous +# view when the previous stage is activated. class PreviewStage(CuraStage): def __init__(self, application: QtApplication, parent = None) -> None: super().__init__(parent) @@ -18,14 +24,24 @@ class PreviewStage(CuraStage): self._application.engineCreatedSignal.connect(self._engineCreated) self._previously_active_view = None # type: Optional[View] + ## When selecting the stage, remember which was the previous view so that + # we can revert to that view when we go out of the stage later. def onStageSelected(self) -> None: self._previously_active_view = self._application.getController().getActiveView() + ## Called when going to a different stage (away from the Preview Stage). + # + # When going to a different stage, the view should be reverted to what it + # was before. Normally, that just reverts it to solid view. def onStageDeselected(self) -> None: if self._previously_active_view is not None: self._application.getController().setActiveView(self._previously_active_view.getPluginId()) self._previously_active_view = None + ## Delayed load of the QML files. + # + # We need to make sure that the QML engine is running before we can load + # these. def _engineCreated(self) -> None: plugin_path = self._application.getPluginRegistry().getPluginPath(self.getPluginId()) if plugin_path is not None: diff --git a/plugins/PreviewStage/__init__.py b/plugins/PreviewStage/__init__.py index d58826934e..424f573e4a 100644 --- a/plugins/PreviewStage/__init__.py +++ b/plugins/PreviewStage/__init__.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. from . import PreviewStage From dba31c3af435202ef93363859017927d4a043bd2 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 2 Nov 2018 16:20:04 +0100 Subject: [PATCH 0123/1292] Add documentation. Contributes to CURA-5786. --- resources/qml/ActionPanel/ActionPanelWidget.qml | 4 ++++ resources/qml/ActionPanel/OutputProcessWidget.qml | 5 +++++ resources/qml/ActionPanel/SliceProcessWidget.qml | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/resources/qml/ActionPanel/ActionPanelWidget.qml b/resources/qml/ActionPanel/ActionPanelWidget.qml index 417883af6f..1fc288af6a 100644 --- a/resources/qml/ActionPanel/ActionPanelWidget.qml +++ b/resources/qml/ActionPanel/ActionPanelWidget.qml @@ -8,6 +8,10 @@ import QtQuick.Layouts 1.3 import UM 1.2 as UM import Cura 1.0 as Cura + +// This element hold all the elements needed for the user to trigger the slicing process, and later +// to get information about the printing times, material consumption and the output process (such as +// saving to a file, printing over network, ... Rectangle { id: actionPanelWidget diff --git a/resources/qml/ActionPanel/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml index a2f9f13576..5d5e5bb66c 100644 --- a/resources/qml/ActionPanel/OutputProcessWidget.qml +++ b/resources/qml/ActionPanel/OutputProcessWidget.qml @@ -8,6 +8,11 @@ import QtQuick.Layouts 1.3 import UM 1.1 as UM import Cura 1.0 as Cura + +// This element contains all the elements the user needs to visualize the data +// that is gather after the slicing process, such as printint time, material usage, ... +// There are also two buttons: one to previsualize the output layers, and the other to +// select what to do with it (such as print over network, save to file, ...) Column { id: widget diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index 3ea6e09975..e70ec45e43 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -9,6 +9,10 @@ import QtQuick.Controls 1.4 as Controls1 import UM 1.1 as UM import Cura 1.0 as Cura + +// This element contains all the elements the user needs to create a printjob from the +// model(s) that is(are) on the buildplate. Mainly the button to start/stop the slicing +// process and a progress bar to see the progress of the process. Column { id: widget From 059e681de59f073870d6858daac7b0cd85528be1 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 2 Nov 2018 16:44:50 +0100 Subject: [PATCH 0124/1292] Remove unused code. Contributes to CURA-5786. --- resources/qml/ActionPanel/OutputDevicesActionButton.qml | 1 - resources/qml/ActionPanel/PrintJobInformation.qml | 1 - resources/qml/Cura.qml | 8 -------- 3 files changed, 10 deletions(-) diff --git a/resources/qml/ActionPanel/OutputDevicesActionButton.qml b/resources/qml/ActionPanel/OutputDevicesActionButton.qml index 32d5f8a73b..87faa0a2bf 100644 --- a/resources/qml/ActionPanel/OutputDevicesActionButton.qml +++ b/resources/qml/ActionPanel/OutputDevicesActionButton.qml @@ -74,7 +74,6 @@ Item { text: model.description color: "transparent" - outlineColor: "transparent" cornerRadius: 0 hoverColor: UM.Theme.getColor("primary") diff --git a/resources/qml/ActionPanel/PrintJobInformation.qml b/resources/qml/ActionPanel/PrintJobInformation.qml index 0eaa0ca46f..df90e81aaf 100644 --- a/resources/qml/ActionPanel/PrintJobInformation.qml +++ b/resources/qml/ActionPanel/PrintJobInformation.qml @@ -58,7 +58,6 @@ Column } } text += "" - print(text) return text } diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 1f4d71e460..f7b4186515 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -314,14 +314,6 @@ UM.MainWindow anchors.bottom: parent.bottom anchors.rightMargin: UM.Theme.getSize("thick_margin").width anchors.bottomMargin: UM.Theme.getSize("thick_margin").height -// onShowTooltip: -// { -// base.showTooltip(item, location, text) -// } -// onHideTooltip: -// { -// base.hideTooltip() -// } } Loader From 2dfd354b25e3187f403cc1cffc028d61eb7bae2e Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 2 Nov 2018 16:49:31 +0100 Subject: [PATCH 0125/1292] Remove function and property that are only used once. Contributes to CURA-5786. --- resources/qml/ActionPanel/OutputProcessWidget.qml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/resources/qml/ActionPanel/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml index 5d5e5bb66c..db9a23cdf3 100644 --- a/resources/qml/ActionPanel/OutputProcessWidget.qml +++ b/resources/qml/ActionPanel/OutputProcessWidget.qml @@ -48,9 +48,7 @@ Column id: estimatedTime width: parent.width - property var printDuration: PrintInformation.currentPrintTime - - text: printDuration.getDisplayString(UM.DurationFormat.Long) + text: PrintInformation.currentPrintTime.getDisplayString(UM.DurationFormat.Long) source: UM.Theme.getIcon("clock") font: UM.Theme.getFont("small") } @@ -63,7 +61,7 @@ Column property var printMaterialLengths: PrintInformation.materialLengths property var printMaterialWeights: PrintInformation.materialWeights - function getText() + text: { var totalLengths = 0 var totalWeights = 0 @@ -80,8 +78,6 @@ Column } return totalWeights + "g · " + totalLengths.toFixed(2) + "m" } - - text: getText() source: UM.Theme.getIcon("spool") font: UM.Theme.getFont("very_small") } From 6f2e8d726dac8488f6547f39556844afbd3cf4db Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 2 Nov 2018 16:52:17 +0100 Subject: [PATCH 0126/1292] Remove functions that are only used once. Contributes to CURA-5786. --- resources/qml/ActionPanel/PrintJobInformation.qml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/resources/qml/ActionPanel/PrintJobInformation.qml b/resources/qml/ActionPanel/PrintJobInformation.qml index df90e81aaf..e53a92a994 100644 --- a/resources/qml/ActionPanel/PrintJobInformation.qml +++ b/resources/qml/ActionPanel/PrintJobInformation.qml @@ -39,7 +39,7 @@ Column { property var printDuration: PrintInformation.currentPrintTime - function getTimeSpecifications() + text: { // All the time information for the different features is achieved var printTime = PrintInformation.getFeaturePrintTimes() @@ -60,8 +60,6 @@ Column text += "" return text } - - text: getTimeSpecifications() width: parent.width - 2 * UM.Theme.getSize("default_margin").width color: UM.Theme.getColor("text") font: UM.Theme.getFont("very_small") @@ -112,7 +110,7 @@ Column return rowHTML } - function getMaterialSpecifications() + text: { var lengths = [] var weights = [] @@ -153,8 +151,6 @@ Column return text } - - text: getMaterialSpecifications() width: parent.width - 2 * UM.Theme.getSize("default_margin").width color: UM.Theme.getColor("text") font: UM.Theme.getFont("very_small") From 4659b0d38717afb0b693545e19501831d5b79e06 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 5 Nov 2018 11:36:58 +0100 Subject: [PATCH 0127/1292] Fix codestyle --- plugins/SimulationView/SimulationViewMainComponent.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/SimulationView/SimulationViewMainComponent.qml b/plugins/SimulationView/SimulationViewMainComponent.qml index 5c45da6b45..69984f85cb 100644 --- a/plugins/SimulationView/SimulationViewMainComponent.qml +++ b/plugins/SimulationView/SimulationViewMainComponent.qml @@ -72,7 +72,8 @@ Item if(is_simulation_playing) { pauseSimulation() - } else + } + else { resumeSimulation() } From f0e205423f24c4e10cb2d59f4b9ec98d69c58561 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 5 Nov 2018 11:47:22 +0100 Subject: [PATCH 0128/1292] Pause simulation view when preferences have been changed. I accidentally removed this feature when working on CURA-5829, but it was spotted in the review. --- plugins/SimulationView/SimulationViewMainComponent.qml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/plugins/SimulationView/SimulationViewMainComponent.qml b/plugins/SimulationView/SimulationViewMainComponent.qml index 69984f85cb..f34208e1b5 100644 --- a/plugins/SimulationView/SimulationViewMainComponent.qml +++ b/plugins/SimulationView/SimulationViewMainComponent.qml @@ -61,6 +61,16 @@ Item iconSource: !is_simulation_playing ? "./resources/simulation_resume.svg": "./resources/simulation_pause.svg" style: UM.Theme.styles.small_tool_button visible: !UM.SimulationView.compatibilityMode + + Connections + { + target: UM.Preferences + onPreferenceChanged: + { + playButton.pauseSimulation() + } + } + anchors { right: pathSlider.left From 9f13de9f0d07fde160fc49c7ca9f1f0a62b77336 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 5 Nov 2018 11:48:19 +0100 Subject: [PATCH 0129/1292] No longer create two instances of the setting view. This caused a bunch of issues with the getPluginId, as one of the instances didn't got added to the registry (and as such, never got an ID) CURA-5829 --- plugins/SimulationView/SimulationViewMenuComponent.qml | 2 +- plugins/SimulationView/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/SimulationView/SimulationViewMenuComponent.qml b/plugins/SimulationView/SimulationViewMenuComponent.qml index 5a146910e7..b1613dff85 100644 --- a/plugins/SimulationView/SimulationViewMenuComponent.qml +++ b/plugins/SimulationView/SimulationViewMenuComponent.qml @@ -210,7 +210,7 @@ Item target: UM.Preferences onPreferenceChanged: { - layerTypeCombobox.currentIndex = UM.SimulationView.compatibilityMode ? 1 : UM.Preferences.getValue("layerview/layer_view_type"); + layerTypeCombobox.currentIndex = UM.SimulationView.compatibilityMode ? 1 : UM.Preferences.getValue("layerview/layer_view_type") layerTypeCombobox.updateLegends(layerTypeCombobox.currentIndex) viewSettings.extruder_opacities = UM.Preferences.getValue("layerview/extruder_opacities").split("|") viewSettings.show_travel_moves = UM.Preferences.getValue("layerview/show_travel_moves") diff --git a/plugins/SimulationView/__init__.py b/plugins/SimulationView/__init__.py index 1efb7fd650..420ee60660 100644 --- a/plugins/SimulationView/__init__.py +++ b/plugins/SimulationView/__init__.py @@ -25,4 +25,4 @@ def createSimulationViewProxy(engine, script_engine): def register(app): simulation_view = SimulationView.SimulationView() qmlRegisterSingletonType(SimulationViewProxy.SimulationViewProxy, "UM", 1, 0, "SimulationView", simulation_view.getProxy) - return { "view": SimulationView.SimulationView()} + return { "view": simulation_view} From 406dd68aa4151bdc40dde21f1b66e071038b9fbb Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 5 Nov 2018 11:54:55 +0100 Subject: [PATCH 0130/1292] Made path slider widht themable. CURA-5829 --- plugins/SimulationView/SimulationViewMainComponent.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/SimulationView/SimulationViewMainComponent.qml b/plugins/SimulationView/SimulationViewMainComponent.qml index f34208e1b5..784938e5c2 100644 --- a/plugins/SimulationView/SimulationViewMainComponent.qml +++ b/plugins/SimulationView/SimulationViewMainComponent.qml @@ -18,7 +18,7 @@ Item { id: pathSlider height: UM.Theme.getSize("slider_handle").width - width: 250 + width: UM.Theme.getSize("layerview_menu_size").width anchors.bottom: parent.bottom anchors.bottomMargin: UM.Theme.getSize("default_margin").height From 2bb7b352efca961ca3f87a38251084e3a0b83914 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 5 Nov 2018 13:25:47 +0100 Subject: [PATCH 0131/1292] Hide settings when pre-sliced g-code is loaded CURA-5772 --- resources/qml/PrintSetupSelector.qml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/resources/qml/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector.qml index 987e3ecce9..8232e76a17 100644 --- a/resources/qml/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector.qml @@ -106,10 +106,10 @@ Rectangle model: modesListModel width: Math.round(parent.width * 0.55) height: UM.Theme.getSize("print_setup_mode_toggle").height + visible: !hideSettings anchors.right: parent.right anchors.rightMargin: UM.Theme.getSize("thick_margin").width - anchors.top: settingsModeLabel.top ButtonGroup @@ -191,6 +191,8 @@ Rectangle anchors.right: parent.right height: UM.Theme.getSize("print_setup_widget").height + visible: !hideSettings + // We load both of them at once (instead of using a loader) because the advanced sidebar can take // quite some time to load. So in this case we sacrifice memory for speed. SidebarAdvanced From 99bac25ab2d7a75ac5e6c9bcceebe75367babc28 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 5 Nov 2018 14:55:22 +0100 Subject: [PATCH 0132/1292] Show default avatar if user has no avatar picture set CURA-5784 --- resources/qml/Account/AccountDetails.qml | 14 +++++++++++++- resources/qml/Account/AccountWidget.qml | 14 +++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/resources/qml/Account/AccountDetails.qml b/resources/qml/Account/AccountDetails.qml index c723ca20fb..a288426e0c 100644 --- a/resources/qml/Account/AccountDetails.qml +++ b/resources/qml/Account/AccountDetails.qml @@ -11,6 +11,7 @@ Column { property var profile: null property var loggedIn: false + property var profileImage: "" padding: 2 * UM.Theme.getSize("default_margin").height spacing: 2 * UM.Theme.getSize("default_margin").height @@ -21,7 +22,18 @@ Column width: UM.Theme.getSize("avatar_image").width height: UM.Theme.getSize("avatar_image").height anchors.horizontalCenter: parent.horizontalCenter - source: loggedIn ? profile["profile_image_url"] : UM.Theme.getImage("avatar_no_user") + source: + { + if(loggedIn) + { + if(profileImage) + { + return profileImage + } + return UM.Theme.getImage("avatar_no_user") + } + return UM.Theme.getImage("avatar_no_user") + } outlineColor: loggedIn ? UM.Theme.getColor("account_widget_outline_active") : UM.Theme.getColor("lining") } diff --git a/resources/qml/Account/AccountWidget.qml b/resources/qml/Account/AccountWidget.qml index cdae457ac8..e37523296f 100644 --- a/resources/qml/Account/AccountWidget.qml +++ b/resources/qml/Account/AccountWidget.qml @@ -25,7 +25,18 @@ Button anchors.verticalCenter: accountWidget.verticalCenter anchors.horizontalCenter: accountWidget.horizontalCenter - source: loggedIn ? profile["profile_image_url"] : UM.Theme.getImage("avatar_no_user") + source: + { + if(loggedIn) + { + if(profile["profile_image_url"]) + { + return profile["profile_image_url"] + } + return UM.Theme.getImage("avatar_no_user") + } + return UM.Theme.getImage("avatar_no_user") + } outlineColor: loggedIn ? UM.Theme.getColor("account_widget_outline_active") : UM.Theme.getColor("lining") } @@ -45,6 +56,7 @@ Button id: panel profile: Cura.API.account.userProfile loggedIn: Cura.API.account.isLoggedIn + profileImage: Cura.API.account.profileImageUrl } background: UM.PointingRectangle From 8106df1ae2659da6cf460cb49a23e631be202f3b Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 5 Nov 2018 16:26:35 +0100 Subject: [PATCH 0133/1292] Bit of QML cleanup --- .../SimulationViewMenuComponent.qml | 922 +++++++++--------- resources/themes/cura-light/theme.json | 2 - 2 files changed, 454 insertions(+), 470 deletions(-) diff --git a/plugins/SimulationView/SimulationViewMenuComponent.qml b/plugins/SimulationView/SimulationViewMenuComponent.qml index b1613dff85..62f353a241 100644 --- a/plugins/SimulationView/SimulationViewMenuComponent.qml +++ b/plugins/SimulationView/SimulationViewMenuComponent.qml @@ -9,32 +9,21 @@ import QtQuick.Controls.Styles 1.1 import UM 1.0 as UM import Cura 1.0 as Cura -Item +Rectangle { id: base - width: + + color: UM.Theme.getColor("tool_panel_background") + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("lining") + + width: UM.Theme.getSize("layerview_menu_size").width + + height: { - if (UM.SimulationView.compatibilityMode) - { - return UM.Theme.getSize("layerview_menu_size_compatibility").width; - } - else - { - return UM.Theme.getSize("layerview_menu_size").width; - } - } - height: { 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) - { - return UM.Theme.getSize("layerview_menu_size_compatibility").height; + return UM.Theme.getSize("layerview_menu_size_collapsed").height } else if (UM.Preferences.getValue("layerview/layer_view_type") == 0) { @@ -45,6 +34,7 @@ Item 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: @@ -57,514 +47,510 @@ Item return Qt.point(0,0) } - Rectangle + Connections { - id: layerViewMenu - anchors.right: parent.right - anchors.top: parent.top - width: parent.width - height: parent.height - clip: true - z: layerSlider.z - 1 - color: UM.Theme.getColor("tool_panel_background") - border.width: UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("lining") - - Button + target: UM.Preferences + onPreferenceChanged: { - id: collapseButton - anchors.top: parent.top - anchors.topMargin: Math.round(UM.Theme.getSize("default_margin").height + (UM.Theme.getSize("layerview_row").height - UM.Theme.getSize("default_margin").height) / 2) - anchors.right: parent.right - anchors.rightMargin: UM.Theme.getSize("default_margin").width + layerTypeCombobox.currentIndex = UM.SimulationView.compatibilityMode ? 1 : UM.Preferences.getValue("layerview/layer_view_type") + layerTypeCombobox.updateLegends(layerTypeCombobox.currentIndex) + viewSettings.extruder_opacities = UM.Preferences.getValue("layerview/extruder_opacities").split("|") + viewSettings.show_travel_moves = UM.Preferences.getValue("layerview/show_travel_moves") + viewSettings.show_helpers = UM.Preferences.getValue("layerview/show_helpers") + viewSettings.show_skin = UM.Preferences.getValue("layerview/show_skin") + viewSettings.show_infill = UM.Preferences.getValue("layerview/show_infill") + viewSettings.only_show_top_layers = UM.Preferences.getValue("view/only_show_top_layers") + viewSettings.top_layer_count = UM.Preferences.getValue("view/top_layer_count") + } + } - width: UM.Theme.getSize("standard_arrow").width - height: UM.Theme.getSize("standard_arrow").height + Button + { + id: collapseButton - onClicked: viewSettings.collapsed = !viewSettings.collapsed - - style: ButtonStyle - { - background: UM.RecolorImage - { - width: control.width - height: control.height - sourceSize.width: width - sourceSize.height: width - color: UM.Theme.getColor("setting_control_text") - source: viewSettings.collapsed ? UM.Theme.getIcon("arrow_left") : UM.Theme.getIcon("arrow_bottom") - } - label: Label{ } - } + anchors + { + top: parent.top + topMargin: Math.round(UM.Theme.getSize("default_margin").height + (UM.Theme.getSize("layerview_row").height - UM.Theme.getSize("default_margin").height) / 2) + right: parent.right + rightMargin: UM.Theme.getSize("default_margin").width } - Column + width: UM.Theme.getSize("standard_arrow").width + height: UM.Theme.getSize("standard_arrow").height + + onClicked: viewSettings.collapsed = !viewSettings.collapsed + + style: ButtonStyle { - id: viewSettings - - property bool collapsed: false - property var extruder_opacities: UM.Preferences.getValue("layerview/extruder_opacities").split("|") - property bool show_travel_moves: UM.Preferences.getValue("layerview/show_travel_moves") - property bool show_helpers: UM.Preferences.getValue("layerview/show_helpers") - property bool show_skin: UM.Preferences.getValue("layerview/show_skin") - property bool show_infill: UM.Preferences.getValue("layerview/show_infill") - // if we are in compatibility mode, we only show the "line type" - property bool show_legend: UM.SimulationView.compatibilityMode ? true : UM.Preferences.getValue("layerview/layer_view_type") == 1 - property bool show_gradient: UM.SimulationView.compatibilityMode ? false : UM.Preferences.getValue("layerview/layer_view_type") == 2 || UM.Preferences.getValue("layerview/layer_view_type") == 3 - property bool show_feedrate_gradient: show_gradient && UM.Preferences.getValue("layerview/layer_view_type") == 2 - property bool show_thickness_gradient: show_gradient && UM.Preferences.getValue("layerview/layer_view_type") == 3 - property bool only_show_top_layers: UM.Preferences.getValue("view/only_show_top_layers") - property int top_layer_count: UM.Preferences.getValue("view/top_layer_count") - - anchors.top: parent.top - anchors.topMargin: UM.Theme.getSize("default_margin").height - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("default_margin").width - anchors.right: parent.right - anchors.rightMargin: UM.Theme.getSize("default_margin").width - spacing: UM.Theme.getSize("layerview_row_spacing").height - - Label + background: UM.RecolorImage { - id: layerViewTypesLabel - text: catalog.i18nc("@label","Color scheme") - font: UM.Theme.getFont("default"); - visible: !UM.SimulationView.compatibilityMode - width: parent.width - color: UM.Theme.getColor("setting_control_text") + width: control.width + height: control.height + sourceSize.width: width + sourceSize.height: width + color: UM.Theme.getColor("setting_control_text") + source: viewSettings.collapsed ? UM.Theme.getIcon("arrow_left") : UM.Theme.getIcon("arrow_bottom") } + label: Label{ } + } + } - ListModel // matches SimulationView.py + Column + { + id: viewSettings + + property bool collapsed: false + property var extruder_opacities: UM.Preferences.getValue("layerview/extruder_opacities").split("|") + property bool show_travel_moves: UM.Preferences.getValue("layerview/show_travel_moves") + property bool show_helpers: UM.Preferences.getValue("layerview/show_helpers") + property bool show_skin: UM.Preferences.getValue("layerview/show_skin") + property bool show_infill: UM.Preferences.getValue("layerview/show_infill") + + // If we are in compatibility mode, we only show the "line type" + property bool show_legend: UM.SimulationView.compatibilityMode ? true : UM.Preferences.getValue("layerview/layer_view_type") == 1 + property bool show_gradient: UM.SimulationView.compatibilityMode ? false : UM.Preferences.getValue("layerview/layer_view_type") == 2 || UM.Preferences.getValue("layerview/layer_view_type") == 3 + property bool show_feedrate_gradient: show_gradient && UM.Preferences.getValue("layerview/layer_view_type") == 2 + property bool show_thickness_gradient: show_gradient && UM.Preferences.getValue("layerview/layer_view_type") == 3 + property bool only_show_top_layers: UM.Preferences.getValue("view/only_show_top_layers") + property int top_layer_count: UM.Preferences.getValue("view/top_layer_count") + + anchors + { + top: parent.top + left: parent.left + right: parent.right + margins: UM.Theme.getSize("default_margin").height + } + + spacing: UM.Theme.getSize("layerview_row_spacing").height + + Label + { + id: layerViewTypesLabel + text: catalog.i18nc("@label","Color scheme") + font: UM.Theme.getFont("default"); + visible: !UM.SimulationView.compatibilityMode + width: parent.width + color: UM.Theme.getColor("setting_control_text") + } + + ListModel // matches SimulationView.py + { + id: layerViewTypes + } + + Component.onCompleted: + { + layerViewTypes.append({ + text: catalog.i18nc("@label:listbox", "Material Color"), + type_id: 0 + }) + layerViewTypes.append({ + text: catalog.i18nc("@label:listbox", "Line Type"), + type_id: 1 + }) + layerViewTypes.append({ + text: catalog.i18nc("@label:listbox", "Feedrate"), + type_id: 2 + }) + layerViewTypes.append({ + text: catalog.i18nc("@label:listbox", "Layer thickness"), + type_id: 3 // these ids match the switching in the shader + }) + } + + ComboBox + { + id: layerTypeCombobox + width: parent.width + model: layerViewTypes + visible: !UM.SimulationView.compatibilityMode + style: UM.Theme.styles.combobox + + onActivated: { - id: layerViewTypes + UM.Preferences.setValue("layerview/layer_view_type", index); } Component.onCompleted: { - layerViewTypes.append({ - text: catalog.i18nc("@label:listbox", "Material Color"), - type_id: 0 - }) - layerViewTypes.append({ - text: catalog.i18nc("@label:listbox", "Line Type"), - type_id: 1 - }) - layerViewTypes.append({ - text: catalog.i18nc("@label:listbox", "Feedrate"), - type_id: 2 - }) - layerViewTypes.append({ - text: catalog.i18nc("@label:listbox", "Layer thickness"), - type_id: 3 // these ids match the switching in the shader - }) + currentIndex = UM.SimulationView.compatibilityMode ? 1 : UM.Preferences.getValue("layerview/layer_view_type"); + updateLegends(currentIndex); } - ComboBox + function updateLegends(type_id) { - id: layerTypeCombobox - width: parent.width - model: layerViewTypes - visible: !UM.SimulationView.compatibilityMode - style: UM.Theme.styles.combobox + // Update the visibility of the legends. + viewSettings.show_legend = UM.SimulationView.compatibilityMode || (type_id == 1); + viewSettings.show_gradient = !UM.SimulationView.compatibilityMode && (type_id == 2 || type_id == 3); + viewSettings.show_feedrate_gradient = viewSettings.show_gradient && (type_id == 2); + viewSettings.show_thickness_gradient = viewSettings.show_gradient && (type_id == 3); + } + } - onActivated: + Label + { + id: compatibilityModeLabel + text: catalog.i18nc("@label","Compatibility Mode") + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + visible: UM.SimulationView.compatibilityMode + height: UM.Theme.getSize("layerview_row").height + width: parent.width + } + + Item // Spacer + { + height: Math.round(UM.Theme.getSize("default_margin").width / 2) + width: width + } + + Repeater + { + model: Cura.ExtrudersModel{} + + CheckBox + { + id: extrudersModelCheckBox + checked: viewSettings.extruder_opacities[index] > 0.5 || viewSettings.extruder_opacities[index] == undefined || viewSettings.extruder_opacities[index] == "" + height: UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("default_lining").height + width: parent.width + visible: !UM.SimulationView.compatibilityMode + enabled: index < 4 + + onClicked: { - UM.Preferences.setValue("layerview/layer_view_type", index); + viewSettings.extruder_opacities[index] = checked ? 1.0 : 0.0 + UM.Preferences.setValue("layerview/extruder_opacities", viewSettings.extruder_opacities.join("|")); } + style: UM.Theme.styles.checkbox + + Rectangle + { + anchors.verticalCenter: parent.verticalCenter + anchors.right: extrudersModelCheckBox.right + width: UM.Theme.getSize("layerview_legend_size").width + height: UM.Theme.getSize("layerview_legend_size").height + color: model.color + radius: Math.round(width / 2) + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("lining") + visible: !viewSettings.show_legend && !viewSettings.show_gradient + } + + Label + { + text: model.name + elide: Text.ElideRight + color: UM.Theme.getColor("setting_control_text") + font: UM.Theme.getFont("default") + anchors + { + verticalCenter: parent.verticalCenter + left: extrudersModelCheckBox.left + right: extrudersModelCheckBox.right + leftMargin: UM.Theme.getSize("checkbox").width + Math.round(UM.Theme.getSize("default_margin").width / 2) + rightMargin: UM.Theme.getSize("default_margin").width * 2 + } + + } + } + } + + Repeater + { + model: ListModel + { + id: typesLegendModel Component.onCompleted: { - currentIndex = UM.SimulationView.compatibilityMode ? 1 : UM.Preferences.getValue("layerview/layer_view_type"); - updateLegends(currentIndex); - } - - function updateLegends(type_id) - { - // update visibility of legends - viewSettings.show_legend = UM.SimulationView.compatibilityMode || (type_id == 1); - viewSettings.show_gradient = !UM.SimulationView.compatibilityMode && (type_id == 2 || type_id == 3); - viewSettings.show_feedrate_gradient = viewSettings.show_gradient && (type_id == 2); - viewSettings.show_thickness_gradient = viewSettings.show_gradient && (type_id == 3); + typesLegendModel.append({ + label: catalog.i18nc("@label", "Show Travels"), + initialValue: viewSettings.show_travel_moves, + preference: "layerview/show_travel_moves", + colorId: "layerview_move_combing" + }); + typesLegendModel.append({ + label: catalog.i18nc("@label", "Show Helpers"), + initialValue: viewSettings.show_helpers, + preference: "layerview/show_helpers", + colorId: "layerview_support" + }); + typesLegendModel.append({ + label: catalog.i18nc("@label", "Show Shell"), + initialValue: viewSettings.show_skin, + preference: "layerview/show_skin", + colorId: "layerview_inset_0" + }); + typesLegendModel.append({ + label: catalog.i18nc("@label", "Show Infill"), + initialValue: viewSettings.show_infill, + preference: "layerview/show_infill", + colorId: "layerview_infill" + }); } } - Label + CheckBox { - id: compatibilityModeLabel - text: catalog.i18nc("@label","Compatibility Mode") - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - visible: UM.SimulationView.compatibilityMode - height: UM.Theme.getSize("layerview_row").height + id: legendModelCheckBox + checked: model.initialValue + onClicked: UM.Preferences.setValue(model.preference, checked) + height: UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("default_lining").height width: parent.width - } - Item - { - height: Math.round(UM.Theme.getSize("default_margin").width / 2) - width: width - } - - Connections - { - target: UM.Preferences - onPreferenceChanged: - { - layerTypeCombobox.currentIndex = UM.SimulationView.compatibilityMode ? 1 : UM.Preferences.getValue("layerview/layer_view_type") - layerTypeCombobox.updateLegends(layerTypeCombobox.currentIndex) - viewSettings.extruder_opacities = UM.Preferences.getValue("layerview/extruder_opacities").split("|") - viewSettings.show_travel_moves = UM.Preferences.getValue("layerview/show_travel_moves") - viewSettings.show_helpers = UM.Preferences.getValue("layerview/show_helpers") - viewSettings.show_skin = UM.Preferences.getValue("layerview/show_skin") - viewSettings.show_infill = UM.Preferences.getValue("layerview/show_infill") - viewSettings.only_show_top_layers = UM.Preferences.getValue("view/only_show_top_layers") - viewSettings.top_layer_count = UM.Preferences.getValue("view/top_layer_count") - } - } - - Repeater - { - model: Cura.ExtrudersModel{} - CheckBox - { - id: extrudersModelCheckBox - checked: viewSettings.extruder_opacities[index] > 0.5 || viewSettings.extruder_opacities[index] == undefined || viewSettings.extruder_opacities[index] == "" - 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 - { - anchors.verticalCenter: parent.verticalCenter - anchors.right: extrudersModelCheckBox.right - width: UM.Theme.getSize("layerview_legend_size").width - height: UM.Theme.getSize("layerview_legend_size").height - color: model.color - radius: Math.round(width / 2) - border.width: UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("lining") - visible: !viewSettings.show_legend & !viewSettings.show_gradient - } - height: UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("default_lining").height - width: parent.width - - style: UM.Theme.styles.checkbox - Label - { - text: model.name - elide: Text.ElideRight - color: UM.Theme.getColor("setting_control_text") - font: UM.Theme.getFont("default") - anchors.verticalCenter: parent.verticalCenter - anchors.left: extrudersModelCheckBox.left - anchors.right: extrudersModelCheckBox.right - anchors.leftMargin: UM.Theme.getSize("checkbox").width + Math.round(UM.Theme.getSize("default_margin").width / 2) - anchors.rightMargin: UM.Theme.getSize("default_margin").width * 2 - } - } - } - - Repeater - { - model: ListModel - { - id: typesLegendModel - Component.onCompleted: - { - typesLegendModel.append({ - label: catalog.i18nc("@label", "Show Travels"), - initialValue: viewSettings.show_travel_moves, - preference: "layerview/show_travel_moves", - colorId: "layerview_move_combing" - }); - typesLegendModel.append({ - label: catalog.i18nc("@label", "Show Helpers"), - initialValue: viewSettings.show_helpers, - preference: "layerview/show_helpers", - colorId: "layerview_support" - }); - typesLegendModel.append({ - label: catalog.i18nc("@label", "Show Shell"), - initialValue: viewSettings.show_skin, - preference: "layerview/show_skin", - colorId: "layerview_inset_0" - }); - typesLegendModel.append({ - label: catalog.i18nc("@label", "Show Infill"), - initialValue: viewSettings.show_infill, - preference: "layerview/show_infill", - colorId: "layerview_infill" - }); - } - } - - CheckBox - { - id: legendModelCheckBox - checked: model.initialValue - onClicked: - { - UM.Preferences.setValue(model.preference, checked); - } - Rectangle - { - anchors.verticalCenter: parent.verticalCenter - anchors.right: legendModelCheckBox.right - width: UM.Theme.getSize("layerview_legend_size").width - height: UM.Theme.getSize("layerview_legend_size").height - color: UM.Theme.getColor(model.colorId) - border.width: UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("lining") - visible: viewSettings.show_legend - } - height: UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("default_lining").height - width: parent.width - style: UM.Theme.styles.checkbox - Label - { - text: label - font: UM.Theme.getFont("default") - elide: Text.ElideRight - color: UM.Theme.getColor("setting_control_text") - anchors.verticalCenter: parent.verticalCenter - anchors.left: legendModelCheckBox.left - anchors.right: legendModelCheckBox.right - anchors.leftMargin: UM.Theme.getSize("checkbox").width + Math.round(UM.Theme.getSize("default_margin").width / 2) - anchors.rightMargin: UM.Theme.getSize("default_margin").width * 2 - } - } - } - - CheckBox - { - checked: viewSettings.only_show_top_layers - 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 - { - checked: viewSettings.top_layer_count == 5 - onClicked: - { - UM.Preferences.setValue("view/top_layer_count", checked ? 5 : 1) - } - text: catalog.i18nc("@label", "Show 5 Detailed Layers On Top") - visible: UM.SimulationView.compatibilityMode - style: UM.Theme.styles.checkbox - } - Repeater - { - model: ListModel + Rectangle { - id: typesLegendModelNoCheck - Component.onCompleted: - { - typesLegendModelNoCheck.append({ - label: catalog.i18nc("@label", "Top / Bottom"), - colorId: "layerview_skin", - }); - typesLegendModelNoCheck.append({ - label: catalog.i18nc("@label", "Inner Wall"), - colorId: "layerview_inset_x", - }); - } + anchors.verticalCenter: parent.verticalCenter + anchors.right: legendModelCheckBox.right + width: UM.Theme.getSize("layerview_legend_size").width + height: UM.Theme.getSize("layerview_legend_size").height + color: UM.Theme.getColor(model.colorId) + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("lining") + visible: viewSettings.show_legend } Label { text: label - visible: viewSettings.show_legend - id: typesLegendModelLabel - Rectangle - { - anchors.verticalCenter: parent.verticalCenter - anchors.right: typesLegendModelLabel.right - width: UM.Theme.getSize("layerview_legend_size").width - height: UM.Theme.getSize("layerview_legend_size").height - color: UM.Theme.getColor(model.colorId) - border.width: UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("lining") - visible: viewSettings.show_legend - } - height: UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("default_lining").height - width: parent.width - color: UM.Theme.getColor("setting_control_text") font: UM.Theme.getFont("default") + elide: Text.ElideRight + color: UM.Theme.getColor("setting_control_text") + anchors.verticalCenter: parent.verticalCenter + anchors.left: legendModelCheckBox.left + anchors.right: legendModelCheckBox.right + anchors.leftMargin: UM.Theme.getSize("checkbox").width + Math.round(UM.Theme.getSize("default_margin").width / 2) + anchors.rightMargin: UM.Theme.getSize("default_margin").width * 2 + } + } + } + + CheckBox + { + checked: viewSettings.only_show_top_layers + 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 + { + checked: viewSettings.top_layer_count == 5 + onClicked: UM.Preferences.setValue("view/top_layer_count", checked ? 5 : 1) + text: catalog.i18nc("@label", "Show 5 Detailed Layers On Top") + visible: UM.SimulationView.compatibilityMode + style: UM.Theme.styles.checkbox + } + + Repeater + { + model: ListModel + { + id: typesLegendModelNoCheck + Component.onCompleted: + { + typesLegendModelNoCheck.append({ + label: catalog.i18nc("@label", "Top / Bottom"), + colorId: "layerview_skin", + }); + typesLegendModelNoCheck.append({ + label: catalog.i18nc("@label", "Inner Wall"), + colorId: "layerview_inset_x", + }); } } - // Text for the minimum, maximum and units for the feedrates and layer thickness - Item + Label { - id: gradientLegend - visible: viewSettings.show_gradient + text: label + visible: viewSettings.show_legend + id: typesLegendModelLabel + + height: UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("default_lining").height width: parent.width - height: UM.Theme.getSize("layerview_row").height + color: UM.Theme.getColor("setting_control_text") + font: UM.Theme.getFont("default") - Label + Rectangle { - text: minText() - anchors.left: parent.left - color: UM.Theme.getColor("setting_control_text") - font: UM.Theme.getFont("default") + anchors.verticalCenter: parent.verticalCenter + anchors.right: typesLegendModelLabel.right - function minText() - { - if (UM.SimulationView.layerActivity && CuraApplication.platformActivity) - { - // Feedrate selected - 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) - { - return parseFloat(UM.SimulationView.getMinThickness()).toFixed(2) - } - } - return catalog.i18nc("@label","min") - } - } + width: UM.Theme.getSize("layerview_legend_size").width + height: UM.Theme.getSize("layerview_legend_size").height - Label - { - text: unitsText() - anchors.horizontalCenter: parent.horizontalCenter - color: UM.Theme.getColor("setting_control_text") - font: UM.Theme.getFont("default") + color: UM.Theme.getColor(model.colorId) - function unitsText() - { - if (UM.SimulationView.layerActivity && CuraApplication.platformActivity) - { - // Feedrate selected - if (UM.Preferences.getValue("layerview/layer_view_type") == 2) - { - return "mm/s" - } - // Layer thickness selected - if (UM.Preferences.getValue("layerview/layer_view_type") == 3) - { - return "mm" - } - } - return "" - } - } - - 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) - { - // Feedrate selected - 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) - { - return parseFloat(UM.SimulationView.getMaxThickness()).toFixed(2) - } - } - return catalog.i18nc("@label","max") - } + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("lining") } } + } - // Gradient colors for feedrate - 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 - anchors.left: parent.right - height: parent.width - width: Math.round(UM.Theme.getSize("layerview_row").height * 1.5) - 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 - { - position: 0.000 - color: Qt.rgba(1, 0.5, 0, 1) - } - GradientStop - { - position: 0.625 - color: Qt.rgba(0.375, 0.5, 0, 1) - } - GradientStop - { - position: 0.75 - color: Qt.rgba(0.25, 1, 0, 1) - } - GradientStop - { - position: 1.0 - color: Qt.rgba(0, 0, 1, 1) - } - } - } + // Text for the minimum, maximum and units for the feedrates and layer thickness + Item + { + id: gradientLegend + visible: viewSettings.show_gradient + width: parent.width + height: UM.Theme.getSize("layerview_row").height - // Gradient colors for layer thickness (similar to parula colormap) - Rectangle // In QML 5.9 can be changed by LinearGradient + Label { - // Invert values because then the bar is rotated 90 degrees - id: thicknessGradient - visible: viewSettings.show_thickness_gradient - anchors.left: parent.right - height: parent.width - width: Math.round(UM.Theme.getSize("layerview_row").height * 1.5) - 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 + text: { - GradientStop + if (UM.SimulationView.layerActivity && CuraApplication.platformActivity) { - position: 0.000 - color: Qt.rgba(1, 1, 0, 1) + // Feedrate selected + 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) + { + return parseFloat(UM.SimulationView.getMinThickness()).toFixed(2) + } } - GradientStop + return catalog.i18nc("@label","min") + } + anchors.left: parent.left + color: UM.Theme.getColor("setting_control_text") + font: UM.Theme.getFont("default") + } + + Label + { + text: { + if (UM.SimulationView.layerActivity && CuraApplication.platformActivity) { - position: 0.25 - color: Qt.rgba(1, 0.75, 0.25, 1) + // Feedrate selected + if (UM.Preferences.getValue("layerview/layer_view_type") == 2) + { + return "mm/s" + } + // Layer thickness selected + if (UM.Preferences.getValue("layerview/layer_view_type") == 3) + { + return "mm" + } } - GradientStop + return "" + } + + anchors.horizontalCenter: parent.horizontalCenter + color: UM.Theme.getColor("setting_control_text") + font: UM.Theme.getFont("default") + } + + Label + { + text: { + if (UM.SimulationView.layerActivity && CuraApplication.platformActivity) { - position: 0.5 - color: Qt.rgba(0, 0.75, 0.5, 1) - } - GradientStop - { - position: 0.75 - color: Qt.rgba(0, 0.375, 0.75, 1) - } - GradientStop - { - position: 1.0 - color: Qt.rgba(0, 0, 0.5, 1) + // Feedrate selected + 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) + { + return parseFloat(UM.SimulationView.getMaxThickness()).toFixed(2) + } } + return catalog.i18nc("@label","max") + } + + anchors.right: parent.right + color: UM.Theme.getColor("setting_control_text") + font: UM.Theme.getFont("default") + } + } + + // Gradient colors for feedrate + 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 + anchors.left: parent.right + height: parent.width + width: Math.round(UM.Theme.getSize("layerview_row").height * 1.5) + 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 + { + position: 0.000 + color: Qt.rgba(1, 0.5, 0, 1) + } + GradientStop + { + position: 0.625 + color: Qt.rgba(0.375, 0.5, 0, 1) + } + GradientStop + { + position: 0.75 + color: Qt.rgba(0.25, 1, 0, 1) + } + GradientStop + { + position: 1.0 + color: Qt.rgba(0, 0, 1, 1) + } + } + } + + // Gradient colors for layer thickness (similar to parula colormap) + 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 + anchors.left: parent.right + height: parent.width + width: Math.round(UM.Theme.getSize("layerview_row").height * 1.5) + + 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 + { + position: 0.000 + color: Qt.rgba(1, 1, 0, 1) + } + GradientStop + { + position: 0.25 + color: Qt.rgba(1, 0.75, 0.25, 1) + } + GradientStop + { + position: 0.5 + color: Qt.rgba(0, 0.75, 0.5, 1) + } + GradientStop + { + position: 0.75 + color: Qt.rgba(0, 0.375, 0.75, 1) + } + GradientStop + { + position: 1.0 + color: Qt.rgba(0, 0, 0.5, 1) } } } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index e8de7c98ac..f1e0c08874 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -452,8 +452,6 @@ "layerview_menu_size": [15, 20], "layerview_menu_size_material_color_mode": [15, 16], "layerview_menu_size_collapsed": [15, 6], - "layerview_menu_size_compatibility": [22, 22.0], - "layerview_menu_size_compatibility_collapsed": [15, 3.5], "layerview_legend_size": [1.0, 1.0], "layerview_row": [11.0, 1.5], "layerview_row_spacing": [0.0, 0.5], From 319d52a2f9d6013a9261da8d0ec2aab61165a54f Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 5 Nov 2018 16:59:06 +0100 Subject: [PATCH 0134/1292] Make collapsible simulation view collapse to right height CURA-5829 --- .../SimulationViewMenuComponent.qml | 49 +++++++++---------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/plugins/SimulationView/SimulationViewMenuComponent.qml b/plugins/SimulationView/SimulationViewMenuComponent.qml index 62f353a241..cb70d1d78e 100644 --- a/plugins/SimulationView/SimulationViewMenuComponent.qml +++ b/plugins/SimulationView/SimulationViewMenuComponent.qml @@ -19,21 +19,7 @@ Rectangle width: UM.Theme.getSize("layerview_menu_size").width - height: - { - if (viewSettings.collapsed) - { - return UM.Theme.getSize("layerview_menu_size_collapsed").height - } - 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 - { - return UM.Theme.getSize("layerview_menu_size").height + UM.SimulationView.extruderCount * (UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("layerview_row_spacing").height) - } - } + height: viewSettings.collapsed ? layerViewTypesLabel.height + 2 * UM.Theme.getSize("default_margin").height : childrenRect.height Behavior on height { NumberAnimation { duration: 100 } } @@ -64,6 +50,23 @@ Rectangle } } + Label + { + id: layerViewTypesLabel + text: catalog.i18nc("@label","Color scheme") + font: UM.Theme.getFont("default"); + visible: !UM.SimulationView.compatibilityMode + color: UM.Theme.getColor("setting_control_text") + height: contentHeight + anchors + { + top: parent.top + margins: UM.Theme.getSize("default_margin").height + right: collapseButton.left + left: parent.left + } + } + Button { id: collapseButton @@ -71,9 +74,8 @@ Rectangle anchors { top: parent.top - topMargin: Math.round(UM.Theme.getSize("default_margin").height + (UM.Theme.getSize("layerview_row").height - UM.Theme.getSize("default_margin").height) / 2) + margins: UM.Theme.getSize("default_margin").width right: parent.right - rightMargin: UM.Theme.getSize("default_margin").width } width: UM.Theme.getSize("standard_arrow").width @@ -117,23 +119,16 @@ Rectangle anchors { - top: parent.top + top: layerViewTypesLabel.bottom left: parent.left right: parent.right margins: UM.Theme.getSize("default_margin").height + } spacing: UM.Theme.getSize("layerview_row_spacing").height - Label - { - id: layerViewTypesLabel - text: catalog.i18nc("@label","Color scheme") - font: UM.Theme.getFont("default"); - visible: !UM.SimulationView.compatibilityMode - width: parent.width - color: UM.Theme.getColor("setting_control_text") - } + visible: !collapsed ListModel // matches SimulationView.py { From 9f246910bc0e7334553490e8bacf0a7415cd487d Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 6 Nov 2018 09:18:20 +0100 Subject: [PATCH 0135/1292] Make avatar image border a bit wider This prevents a white edge from showing CURA-5772 --- resources/qml/Account/AvatarImage.qml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/resources/qml/Account/AvatarImage.qml b/resources/qml/Account/AvatarImage.qml index c730ef428f..436babe5a3 100644 --- a/resources/qml/Account/AvatarImage.qml +++ b/resources/qml/Account/AvatarImage.qml @@ -44,7 +44,10 @@ Item UM.RecolorImage { id: profileImageOutline - anchors.fill: parent + anchors.centerIn: parent + // Make it a bit bigger than it has to, otherwise it sometimes shows a white border. + width: parent.width + 2 + height: parent.height + 2 source: UM.Theme.getIcon("circle_outline") sourceSize: Qt.size(parent.width, parent.height) color: UM.Theme.getColor("account_widget_ouline_active") From 08917c37a11c8b089948c8eeffaaa2a4c780549b Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 6 Nov 2018 09:20:36 +0100 Subject: [PATCH 0136/1292] Improve rendering of scaled avatar image CURA-5772 --- resources/qml/Account/AvatarImage.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/qml/Account/AvatarImage.qml b/resources/qml/Account/AvatarImage.qml index 436babe5a3..3be81aa155 100644 --- a/resources/qml/Account/AvatarImage.qml +++ b/resources/qml/Account/AvatarImage.qml @@ -24,6 +24,7 @@ Item source: UM.Theme.getImage("avatar_default") fillMode: Image.PreserveAspectCrop visible: false + mipmap: true } Rectangle From f1f1b9f168e30ddcc15fd890362e6ed86f2e5699 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 6 Nov 2018 09:45:40 +0100 Subject: [PATCH 0137/1292] Center icon an label vertically. Contributes to CURA-5786. --- resources/qml/IconLabel.qml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/resources/qml/IconLabel.qml b/resources/qml/IconLabel.qml index 2e765e2dbc..918485751e 100644 --- a/resources/qml/IconLabel.qml +++ b/resources/qml/IconLabel.qml @@ -24,6 +24,7 @@ Item id: icon anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter source: UM.Theme.getIcon("dot") width: UM.Theme.getSize("section_icon").width @@ -40,6 +41,7 @@ Item id: label anchors.left: icon.right anchors.leftMargin: UM.Theme.getSize("thin_margin").width + anchors.verticalCenter: parent.verticalCenter text: "Empty label" color: UM.Theme.getColor("text") font: UM.Theme.getFont("very_small") From 317447aa5451ac0d4220dead40bba89b61587bbf Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 6 Nov 2018 09:52:01 +0100 Subject: [PATCH 0138/1292] Fix multi-buildplate panel location CURA-5772 --- resources/qml/Account/AvatarImage.qml | 2 +- resources/qml/Cura.qml | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/resources/qml/Account/AvatarImage.qml b/resources/qml/Account/AvatarImage.qml index 3be81aa155..b76aff6990 100644 --- a/resources/qml/Account/AvatarImage.qml +++ b/resources/qml/Account/AvatarImage.qml @@ -24,7 +24,7 @@ Item source: UM.Theme.getImage("avatar_default") fillMode: Image.PreserveAspectCrop visible: false - mipmap: true + mipmap: true } Rectangle diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 3e2515cb3e..534fffb418 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -212,8 +212,9 @@ UM.MainWindow visible: UM.Preferences.getValue("cura/use_multi_build_plate") anchors { - bottom: parent.bottom - left: parent.left + bottom: viewOrientationControls.top + left: toolbar.right + margins: UM.Theme.getSize("default_margin").width } } From 11a3da3068bf71ac3d514af893db4b4870c8b3f8 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 6 Nov 2018 11:06:20 +0100 Subject: [PATCH 0139/1292] Removed color animation from stage buttons This caused laggy updates and it didn't add that much anyway CURA-5772 --- resources/qml/ActionButton.qml | 2 -- resources/themes/cura-light/styles.qml | 2 -- 2 files changed, 4 deletions(-) diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index a1c03af143..621318c4bb 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -37,7 +37,6 @@ Button color: button.hovered ? button.textHoverColor : button.textColor visible: source != "" anchors.verticalCenter: parent.verticalCenter - Behavior on color { ColorAnimation { duration: 50 } } } Label @@ -59,7 +58,6 @@ Button radius: UM.Theme.getSize("action_button_radius").width border.width: UM.Theme.getSize("default_lining").width border.color: button.enabled ? (button.hovered ? button.outlineHoverColor : button.outlineColor) : button.outlineDisabledColor - Behavior on color { ColorAnimation { duration: 50 } } } MouseArea diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index 43e8d29b57..dacff1b42b 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -129,8 +129,6 @@ QtObject return UM.Theme.getColor("main_window_header_button_background_inactive") } } - - Behavior on color { ColorAnimation { duration: 50 } } } } From f41ae128c2c14fb05dc84058b8f5833a396805bb Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 6 Nov 2018 11:24:41 +0100 Subject: [PATCH 0140/1292] Modify alignments to avoid binding loop logs. Contributes to CURA-5786. --- resources/qml/IconLabel.qml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/resources/qml/IconLabel.qml b/resources/qml/IconLabel.qml index 918485751e..7c90382892 100644 --- a/resources/qml/IconLabel.qml +++ b/resources/qml/IconLabel.qml @@ -24,7 +24,6 @@ Item id: icon anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter source: UM.Theme.getIcon("dot") width: UM.Theme.getSize("section_icon").width @@ -41,7 +40,7 @@ Item id: label anchors.left: icon.right anchors.leftMargin: UM.Theme.getSize("thin_margin").width - anchors.verticalCenter: parent.verticalCenter + anchors.verticalCenter: icon.verticalCenter text: "Empty label" color: UM.Theme.getColor("text") font: UM.Theme.getFont("very_small") From b6b60702c054ff93c112089583c721a6ddedd44a Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 6 Nov 2018 14:32:48 +0100 Subject: [PATCH 0141/1292] Make the action panel to have a fixed width. Remove the animations when switching states. Contributes to CURA-5786. --- resources/qml/ActionPanel/ActionPanelWidget.qml | 7 +++---- resources/qml/ActionPanel/SliceProcessWidget.qml | 2 -- resources/themes/cura-light/theme.json | 1 + 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/resources/qml/ActionPanel/ActionPanelWidget.qml b/resources/qml/ActionPanel/ActionPanelWidget.qml index 1fc288af6a..0db778de5a 100644 --- a/resources/qml/ActionPanel/ActionPanelWidget.qml +++ b/resources/qml/ActionPanel/ActionPanelWidget.qml @@ -16,7 +16,7 @@ Rectangle { id: actionPanelWidget - width: childrenRect.width + 2 * UM.Theme.getSize("thick_margin").width + width: UM.Theme.getSize("action_panel_widget").width height: childrenRect.height + 2 * UM.Theme.getSize("thick_margin").height color: UM.Theme.getColor("main_background") @@ -36,13 +36,12 @@ Rectangle topMargin: UM.Theme.getSize("thick_margin").height left: parent.left leftMargin: UM.Theme.getSize("thick_margin").width + right: parent.right + rightMargin: UM.Theme.getSize("thick_margin").width } sourceComponent: outputAvailable ? outputProcessWidget : sliceProcessWidget } - Behavior on height { NumberAnimation { duration: 100 } } - Behavior on width { NumberAnimation { duration: 100 } } - Component { id: sliceProcessWidget diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index e70ec45e43..1ba5776b6b 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -17,8 +17,6 @@ Column { id: widget - width: UM.Theme.getSize("action_panel_button").width - spacing: UM.Theme.getSize("thin_margin").height UM.I18nCatalog diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index f354b521ee..27dfbaf807 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -379,6 +379,7 @@ "configuration_selector_widget": [35.0, 4.5], "configuration_selector_mode_tabs": [0.0, 3.0], + "action_panel_widget": [25.0, 0.0], "action_panel_information_widget": [20.0, 0.0], "action_panel_button": [15.0, 3.0], From 5dddcbd6664b38f091ce0565c01a5a6ece1cc35f Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 6 Nov 2018 15:14:27 +0100 Subject: [PATCH 0142/1292] Add a new property to the ActionButton to indicate whether the button has a fixed width or the width will be dependant on the content. Contributes to CURA-5786. --- resources/qml/Account/GeneralOperations.qml | 2 ++ resources/qml/Account/UserOperations.qml | 2 ++ resources/qml/ActionButton.qml | 7 +++++++ resources/qml/ActionPanel/OutputDevicesActionButton.qml | 1 + resources/qml/ActionPanel/SliceProcessWidget.qml | 1 + 5 files changed, 13 insertions(+) diff --git a/resources/qml/Account/GeneralOperations.qml b/resources/qml/Account/GeneralOperations.qml index 6bc94dd830..362e088033 100644 --- a/resources/qml/Account/GeneralOperations.qml +++ b/resources/qml/Account/GeneralOperations.qml @@ -21,6 +21,7 @@ Row textColor: UM.Theme.getColor("main_window_header_button_text_active") textHoverColor: UM.Theme.getColor("main_window_header_button_text_active") onClicked: Qt.openUrlExternally("https://account.ultimaker.com") + fixedWidthMode: true } Cura.ActionButton @@ -29,5 +30,6 @@ Row height: UM.Theme.getSize("account_button").height text: catalog.i18nc("@button", "Login") onClicked: Cura.API.account.login() + fixedWidthMode: true } } \ No newline at end of file diff --git a/resources/qml/Account/UserOperations.qml b/resources/qml/Account/UserOperations.qml index a12bfbf6d7..c167813425 100644 --- a/resources/qml/Account/UserOperations.qml +++ b/resources/qml/Account/UserOperations.qml @@ -21,6 +21,7 @@ Row textColor: UM.Theme.getColor("main_window_header_button_text_active") textHoverColor: UM.Theme.getColor("main_window_header_button_text_active") onClicked: Qt.openUrlExternally("https://account.ultimaker.com") + fixedWidthMode: true } Cura.ActionButton @@ -29,5 +30,6 @@ Row height: UM.Theme.getSize("account_button").height text: catalog.i18nc("@button", "Logout") onClicked: Cura.API.account.logout() + fixedWidthMode: true } } \ No newline at end of file diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index 05e75ac8c5..b35ad4ba87 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -24,6 +24,10 @@ Button property var outlineColor: color property var outlineHoverColor: hoverColor property var outlineDisabledColor: outlineColor + // This property is used to indicate whether the button has a fixed width or the width would depend on the contents + // Be careful when using fixedWidthMode, the translated texts can be too long that they won't fit. In any case, + // we elide the text to the right so the text will be cut off with the three dots at the end. + property var fixedWidthMode: false contentItem: Row { @@ -50,6 +54,9 @@ Button visible: text != "" renderType: Text.NativeRendering anchors.verticalCenter: parent.verticalCenter + width: fixedWidthMode ? button.width - button.leftPadding - button.rightPadding : undefined + horizontalAlignment: Text.AlignHCenter + elide: Text.ElideRight } } diff --git a/resources/qml/ActionPanel/OutputDevicesActionButton.qml b/resources/qml/ActionPanel/OutputDevicesActionButton.qml index 87faa0a2bf..be79a1893e 100644 --- a/resources/qml/ActionPanel/OutputDevicesActionButton.qml +++ b/resources/qml/ActionPanel/OutputDevicesActionButton.qml @@ -16,6 +16,7 @@ Item { id: saveToButton height: parent.height + fixedWidthMode: true anchors { diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index 1ba5776b6b..2d4a7b6b89 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -86,6 +86,7 @@ Column id: prepareButton width: parent.width height: UM.Theme.getSize("action_panel_button").height + fixedWidthMode: true text: { if ([UM.Backend.NotStarted, UM.Backend.Error].indexOf(widget.backendState) != -1) From c51995f3497dba6880014f45e077f0dd494329b1 Mon Sep 17 00:00:00 2001 From: pinchies Date: Wed, 7 Nov 2018 04:36:32 +1100 Subject: [PATCH 0143/1292] Update jgaurora_a5.def.json --- resources/definitions/jgaurora_a5.def.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/definitions/jgaurora_a5.def.json b/resources/definitions/jgaurora_a5.def.json index 0a8b93f7cf..02d9a9db4f 100644 --- a/resources/definitions/jgaurora_a5.def.json +++ b/resources/definitions/jgaurora_a5.def.json @@ -1,5 +1,5 @@ { - "name": "JGAurora A5", + "name": "JGAurora A5 & A5S", "version": 2, "inherits": "fdmprinter", "metadata": { @@ -17,7 +17,7 @@ }, "overrides": { "machine_name": { - "default_value": "JGAurora A5" + "default_value": "JGAurora A5 & A5S" }, "machine_start_gcode": { "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 ;home all axis\nM420 S1 ;turn on mesh bed levelling if enabled in firmware\nG92 E0 ;zero the extruded length\nG1 Z1 F1000 ;move up slightly\nG1 X60.0 Z0 E9.0 F1000.0;intro line\nG1 X100.0 E21.5 F1000.0 ;continue line\nG92 E0 ;zero the extruded length again\n; -- end of START GCODE --" From 70d2f407a37f186fe3712042ac84d67da1c75e12 Mon Sep 17 00:00:00 2001 From: pinchies Date: Wed, 7 Nov 2018 04:38:39 +1100 Subject: [PATCH 0144/1292] Update cocoon_create_modelmaker.def.json --- resources/definitions/cocoon_create_modelmaker.def.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/definitions/cocoon_create_modelmaker.def.json b/resources/definitions/cocoon_create_modelmaker.def.json index 7f19fb0239..204d5b9492 100644 --- a/resources/definitions/cocoon_create_modelmaker.def.json +++ b/resources/definitions/cocoon_create_modelmaker.def.json @@ -1,11 +1,11 @@ { - "name": "Cocoon Create ModelMaker", + "name": "Cocoon Create ModelMaker & Wanhao Duplicator i3 Mini", "version": 2, "inherits": "fdmprinter", "metadata": { "visible": true, "author": "Samuel Pinches", - "manufacturer": "Cocoon Create", + "manufacturer": "Cocoon Create / Wanhao", "file_formats": "text/x-gcode", "preferred_quality_type": "fine", "machine_extruder_trains": @@ -15,7 +15,7 @@ }, "overrides": { "machine_name": { - "default_value": "Cocoon Create ModelMaker" + "default_value": "Cocoon Create ModelMaker & Wanhao Duplicator i3 Mini" }, "machine_start_gcode": { "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 ;home all axis\nG92 E0 ;zero the extruded length\nG1 Z1 F1000 ;move up slightly\nG1 X60.0 Z0 E9.0 F1000.0;intro line\nG1 X100.0 E21.5 F1000.0 ;continue line\nG92 E0 ;zero the extruded length again\n; -- end of START GCODE --" From f15d03d48c84855ca30ec60017e9f00837b686f3 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 7 Nov 2018 16:30:52 +0100 Subject: [PATCH 0145/1292] Fix foldout of the layerview panel being too short or too long CURA-5829 --- .../SimulationViewMenuComponent.qml | 152 +++++++++--------- 1 file changed, 80 insertions(+), 72 deletions(-) diff --git a/plugins/SimulationView/SimulationViewMenuComponent.qml b/plugins/SimulationView/SimulationViewMenuComponent.qml index cb70d1d78e..1cbaffa65e 100644 --- a/plugins/SimulationView/SimulationViewMenuComponent.qml +++ b/plugins/SimulationView/SimulationViewMenuComponent.qml @@ -19,7 +19,7 @@ Rectangle width: UM.Theme.getSize("layerview_menu_size").width - height: viewSettings.collapsed ? layerViewTypesLabel.height + 2 * UM.Theme.getSize("default_margin").height : childrenRect.height + height: viewSettings.collapsed ? layerViewTypesLabel.height + 2 * UM.Theme.getSize("default_margin").height : childrenRect.height + 2 * UM.Theme.getSize("default_margin").height Behavior on height { NumberAnimation { duration: 100 } } @@ -469,83 +469,91 @@ Rectangle } } - // Gradient colors for feedrate - 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 - anchors.left: parent.right - height: parent.width - width: Math.round(UM.Theme.getSize("layerview_row").height * 1.5) - 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 + Item + { + // Another hack on top of the rotation of the gradient. + // Since we set the side of the panel to use childrenRect (and that uses the un-rotated height), add this + // wrapper item with the correct width & height so it doesn't get confused. + width: parent.width + height: feedrateGradient.visible || thicknessGradient.visible ? Math.round(UM.Theme.getSize("layerview_row").height * 1.5) : 0 + // Gradient colors for feedrate + 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 + anchors.left: parent.right + height: parent.width + width: Math.round(UM.Theme.getSize("layerview_row").height * 1.5) + 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 { - position: 0.000 - color: Qt.rgba(1, 0.5, 0, 1) - } - GradientStop - { - position: 0.625 - color: Qt.rgba(0.375, 0.5, 0, 1) - } - GradientStop - { - position: 0.75 - color: Qt.rgba(0.25, 1, 0, 1) - } - GradientStop - { - position: 1.0 - color: Qt.rgba(0, 0, 1, 1) + GradientStop + { + position: 0.000 + color: Qt.rgba(1, 0.5, 0, 1) + } + GradientStop + { + position: 0.625 + color: Qt.rgba(0.375, 0.5, 0, 1) + } + GradientStop + { + position: 0.75 + color: Qt.rgba(0.25, 1, 0, 1) + } + GradientStop + { + position: 1.0 + color: Qt.rgba(0, 0, 1, 1) + } } } - } - // Gradient colors for layer thickness (similar to parula colormap) - 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 - anchors.left: parent.right - height: parent.width - width: Math.round(UM.Theme.getSize("layerview_row").height * 1.5) - - 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 + // Gradient colors for layer thickness (similar to parula colormap) + Rectangle // In QML 5.9 can be changed by LinearGradient { - GradientStop + // Invert values because then the bar is rotated 90 degrees + id: thicknessGradient + visible: viewSettings.show_thickness_gradient + anchors.left: parent.right + height: parent.width + width: Math.round(UM.Theme.getSize("layerview_row").height * 1.5) + + 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 { - position: 0.000 - color: Qt.rgba(1, 1, 0, 1) - } - GradientStop - { - position: 0.25 - color: Qt.rgba(1, 0.75, 0.25, 1) - } - GradientStop - { - position: 0.5 - color: Qt.rgba(0, 0.75, 0.5, 1) - } - GradientStop - { - position: 0.75 - color: Qt.rgba(0, 0.375, 0.75, 1) - } - GradientStop - { - position: 1.0 - color: Qt.rgba(0, 0, 0.5, 1) + GradientStop + { + position: 0.000 + color: Qt.rgba(1, 1, 0, 1) + } + GradientStop + { + position: 0.25 + color: Qt.rgba(1, 0.75, 0.25, 1) + } + GradientStop + { + position: 0.5 + color: Qt.rgba(0, 0.75, 0.5, 1) + } + GradientStop + { + position: 0.75 + color: Qt.rgba(0, 0.375, 0.75, 1) + } + GradientStop + { + position: 1.0 + color: Qt.rgba(0, 0, 0.5, 1) + } } } } From 9f663cfd18b13f8504bf3d753166fe1f9a9b653c Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 7 Nov 2018 17:25:43 +0100 Subject: [PATCH 0146/1292] Change the gradient for the LinearGradient that works in the new versions of Qt. I also changed it because we had a TODO here and I thought it was the right moment to do it. Contributes to CURA-5829. --- .../SimulationViewMenuComponent.qml | 139 ++++++++++-------- 1 file changed, 80 insertions(+), 59 deletions(-) diff --git a/plugins/SimulationView/SimulationViewMenuComponent.qml b/plugins/SimulationView/SimulationViewMenuComponent.qml index 1cbaffa65e..d251244c9f 100644 --- a/plugins/SimulationView/SimulationViewMenuComponent.qml +++ b/plugins/SimulationView/SimulationViewMenuComponent.qml @@ -5,6 +5,7 @@ import QtQuick 2.4 import QtQuick.Controls 1.2 import QtQuick.Layouts 1.1 import QtQuick.Controls.Styles 1.1 +import QtGraphicalEffects 1.0 import UM 1.0 as UM import Cura 1.0 as Cura @@ -469,75 +470,95 @@ Rectangle } } - Item + // Gradient colors for feedrate + Rectangle { - // Another hack on top of the rotation of the gradient. - // Since we set the side of the panel to use childrenRect (and that uses the un-rotated height), add this - // wrapper item with the correct width & height so it doesn't get confused. - width: parent.width - height: feedrateGradient.visible || thicknessGradient.visible ? Math.round(UM.Theme.getSize("layerview_row").height * 1.5) : 0 - // Gradient colors for feedrate - 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 - anchors.left: parent.right - height: parent.width - width: Math.round(UM.Theme.getSize("layerview_row").height * 1.5) - 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 - { - position: 0.000 - color: Qt.rgba(1, 0.5, 0, 1) - } - GradientStop - { - position: 0.625 - color: Qt.rgba(0.375, 0.5, 0, 1) - } - GradientStop - { - position: 0.75 - color: Qt.rgba(0.25, 1, 0, 1) - } - GradientStop - { - position: 1.0 - color: Qt.rgba(0, 0, 1, 1) - } - } - } + id: feedrateGradient + visible: viewSettings.show_feedrate_gradient + anchors.left: parent.left + anchors.right: parent.right + height: Math.round(UM.Theme.getSize("layerview_row").height * 1.5) + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("lining") - // Gradient colors for layer thickness (similar to parula colormap) - Rectangle // In QML 5.9 can be changed by LinearGradient + LinearGradient { - // Invert values because then the bar is rotated 90 degrees - id: thicknessGradient - visible: viewSettings.show_thickness_gradient - anchors.left: parent.right - height: parent.width - width: Math.round(UM.Theme.getSize("layerview_row").height * 1.5) - - border.width: UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("lining") - - transform: Rotation {origin.x: 0; origin.y: 0; angle: 90} + anchors + { + left: parent.left + leftMargin: UM.Theme.getSize("default_lining").width + right: parent.right + rightMargin: UM.Theme.getSize("default_lining").width + top: parent.top + topMargin: UM.Theme.getSize("default_lining").width + bottom: parent.bottom + bottomMargin: UM.Theme.getSize("default_lining").width + } + start: Qt.point(0, 0) + end: Qt.point(parent.width, 0) gradient: Gradient { GradientStop { position: 0.000 - color: Qt.rgba(1, 1, 0, 1) + color: Qt.rgba(0, 0, 1, 1) } GradientStop { position: 0.25 - color: Qt.rgba(1, 0.75, 0.25, 1) + color: Qt.rgba(0.25, 1, 0, 1) + } + GradientStop + { + position: 0.375 + color: Qt.rgba(0.375, 0.5, 0, 1) + } + GradientStop + { + position: 1.0 + color: Qt.rgba(1, 0.5, 0, 1) + } + } + } + } + + // Gradient colors for layer thickness (similar to parula colormap) + Rectangle + { + id: thicknessGradient + visible: viewSettings.show_thickness_gradient + anchors.left: parent.left + anchors.right: parent.right + height: Math.round(UM.Theme.getSize("layerview_row").height * 1.5) + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("lining") + + LinearGradient + { + anchors + { + left: parent.left + leftMargin: UM.Theme.getSize("default_lining").width + right: parent.right + rightMargin: UM.Theme.getSize("default_lining").width + top: parent.top + topMargin: UM.Theme.getSize("default_lining").width + bottom: parent.bottom + bottomMargin: UM.Theme.getSize("default_lining").width + } + start: Qt.point(0, 0) + end: Qt.point(parent.width, 0) + gradient: Gradient + { + GradientStop + { + position: 0.000 + color: Qt.rgba(0, 0, 0.5, 1) + } + GradientStop + { + position: 0.25 + color: Qt.rgba(0, 0.375, 0.75, 1) } GradientStop { @@ -547,12 +568,12 @@ Rectangle GradientStop { position: 0.75 - color: Qt.rgba(0, 0.375, 0.75, 1) + color: Qt.rgba(1, 0.75, 0.25, 1) } GradientStop { position: 1.0 - color: Qt.rgba(0, 0, 0.5, 1) + color: Qt.rgba(1, 1, 0, 1) } } } From e66dd2be0b417646fa015dba7133a21b6d5a48e4 Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Thu, 8 Nov 2018 15:03:24 +0100 Subject: [PATCH 0147/1292] Action-Panel (CURA-5786) can now know about Preview-Stage (CURA-5829). --- resources/qml/ActionPanel/OutputProcessWidget.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/ActionPanel/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml index db9a23cdf3..0ea956d1dc 100644 --- a/resources/qml/ActionPanel/OutputProcessWidget.qml +++ b/resources/qml/ActionPanel/OutputProcessWidget.qml @@ -110,7 +110,7 @@ Column hoverColor: UM.Theme.getColor("secondary") textColor: UM.Theme.getColor("primary") textHoverColor: UM.Theme.getColor("text") - onClicked: UM.Controller.setActiveStage("MonitorStage") + onClicked: UM.Controller.setActiveStage("PreviewStage") } Cura.OutputDevicesActionButton From 02c97052eb54b9c2e32106f793841374fc179962 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 8 Nov 2018 17:31:30 +0100 Subject: [PATCH 0148/1292] Remove transitions when collapsing/expanding the printer category in the add printer dialog. --- resources/qml/AddMachineDialog.qml | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/resources/qml/AddMachineDialog.qml b/resources/qml/AddMachineDialog.qml index 0df8b891d9..06ef2e1fc1 100644 --- a/resources/qml/AddMachineDialog.qml +++ b/resources/qml/AddMachineDialog.qml @@ -213,28 +213,6 @@ UM.Dialog PropertyChanges { target: machineButton; opacity: 0; height: 0; } } - - transitions: - [ - Transition - { - to: "collapsed"; - SequentialAnimation - { - NumberAnimation { property: "opacity"; duration: 75; } - NumberAnimation { property: "height"; duration: 75; } - } - }, - Transition - { - from: "collapsed"; - SequentialAnimation - { - NumberAnimation { property: "height"; duration: 75; } - NumberAnimation { property: "opacity"; duration: 75; } - } - } - ] } } } From 88234f7e21620d2e045aefa6bbc9247da941e0c7 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 9 Nov 2018 10:48:22 +0100 Subject: [PATCH 0149/1292] Change ExtruderIcon to match the new design CURA-5785 --- resources/qml/CustomConfigurationSelector.qml | 4 +- resources/qml/ExtruderIcon.qml | 46 ++++++------ .../cura-light/icons/extruder_button.svg | 73 +++---------------- 3 files changed, 33 insertions(+), 90 deletions(-) diff --git a/resources/qml/CustomConfigurationSelector.qml b/resources/qml/CustomConfigurationSelector.qml index 17b652e8d8..c78ca700da 100644 --- a/resources/qml/CustomConfigurationSelector.qml +++ b/resources/qml/CustomConfigurationSelector.qml @@ -195,8 +195,8 @@ Rectangle height: width checked: control.checked - material_color: model.color - text_color: extruderStaticText.color + materialColor: model.color + textColor: extruderStaticText.color } } } diff --git a/resources/qml/ExtruderIcon.qml b/resources/qml/ExtruderIcon.qml index e4161e0058..eb4bdef0f7 100644 --- a/resources/qml/ExtruderIcon.qml +++ b/resources/qml/ExtruderIcon.qml @@ -13,46 +13,44 @@ Item implicitHeight: implicitWidth property bool checked: true - property alias material_color: materialColorCircle.color - property alias text_color: extruderNumberText.color + property alias materialColor: mainIcon.color + property alias textColor: extruderNumberText.color UM.RecolorImage { - id: mainCircle + id: mainIcon anchors.fill: parent sourceSize.width: parent.width sourceSize.height: parent.width source: UM.Theme.getIcon("extruder_button") - color: extruderNumberText.color } - Label - { - id: extruderNumberText - anchors.centerIn: parent - text: index + 1; - font: UM.Theme.getFont("default_bold") - } - - // Material colour circle - // Only draw the filling colour of the material inside the SVG border. Rectangle { - id: materialColorCircle + id: extruderNumberCircle + + width: height + height: parent.height / 2 + radius: Math.round(width / 2) + color: "white" anchors { - right: parent.right + horizontalCenter: parent.horizontalCenter + top: parent.top + // The circle needs to be slightly off center (so it sits in the middle of the square bit of the icon) + topMargin: (parent.height - height) / 2 - 0.1 * parent.height } - width: Math.round(parent.width * 0.35) - height: Math.round(parent.height * 0.35) - radius: Math.round(width / 2) - - border.width: UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("extruder_button_material_border") - - opacity: !extruderIconItem.checked ? 0.6 : 1.0 + Label + { + id: extruderNumberText + anchors.centerIn: parent + text: index + 1 + font: UM.Theme.getFont("default") + width: contentWidth + height: contentHeight + } } } \ No newline at end of file diff --git a/resources/themes/cura-light/icons/extruder_button.svg b/resources/themes/cura-light/icons/extruder_button.svg index e3c01b6a0a..c79ba5c5df 100644 --- a/resources/themes/cura-light/icons/extruder_button.svg +++ b/resources/themes/cura-light/icons/extruder_button.svg @@ -1,64 +1,9 @@ - - - - - - image/svg+xml - - Artboard 3 Copy - - - - - - Artboard 3 Copy - Created with Sketch. - - - + + + + + + + + + \ No newline at end of file From 2adb79aa39a2944ddba9397512d0c51e9d048bb5 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 9 Nov 2018 13:45:51 +0100 Subject: [PATCH 0150/1292] Added re-usable expandable component CURA-5785 --- resources/qml/ExpandableComponent.qml | 77 +++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 resources/qml/ExpandableComponent.qml diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml new file mode 100644 index 0000000000..0b728ccaff --- /dev/null +++ b/resources/qml/ExpandableComponent.qml @@ -0,0 +1,77 @@ +import QtQuick 2.7 +import QtQuick.Controls 2.3 + +// The expandable component has 3 major sub components: +// * The headerItem; Always visible and should hold some info about what happens if the component is expanded +// * The popupItem; The content that needs to be shown if the component is expanded. +// * The Button; The actual button that expands the popup. +Item +{ + // The headerItem holds the QML item that is always displayed. + property alias headerItem: headerItemLoader.sourceComponent + + // The popupItem holds the QML item that is shown when the "open" button is pressed + property var popupItem + + // The background color of the popup + property color popupBackgroundColor: "white" + + // How much spacing is needed around the popupItem + property alias padding: popup.padding + + onPopupItemChanged: + { + // Since we want the size of the popup to be set by the size of the content, + // we need to do it like this. + popup.width = popupItem.width + 2 * popup.padding + popup.height = popupItem.height + 2 * popup.padding + popup.contentItem = popupItem + } + + implicitHeight: 100 + implicitWidth: 400 + + Loader + { + id: headerItemLoader + anchors + { + left: parent.left + right: collapseButton.left + top: parent.top + bottom: parent.bottom + } + } + + Button + { + id: collapseButton + anchors + { + right: parent.right + top: parent.top + bottom: parent.bottom + } + text: popup.visible ? "close" : "open" + onClicked: popup.visible ? popup.close() : popup.open() + } + + Popup + { + id: popup + + // Ensure that the popup is located directly below the headerItem + y: headerItemLoader.height + + // Make the popup right aligned with the rest. + x: -width + collapseButton.width + headerItemLoader.width + + closePolicy: Popup.CloseOnPressOutsideParent + + background: Rectangle + { + id: background + color: popupBackgroundColor + } + } +} From 1d775c984e4ebf426bc563adcc639b3d643410bf Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 9 Nov 2018 14:31:06 +0100 Subject: [PATCH 0151/1292] Added background padding to expandable component CURA-5785 --- resources/qml/ExpandableComponent.qml | 66 +++++++++++++++++---------- 1 file changed, 41 insertions(+), 25 deletions(-) diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index 0b728ccaff..26bdf3b3ce 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -1,6 +1,8 @@ import QtQuick 2.7 import QtQuick.Controls 2.3 +import UM 1.2 as UM + // The expandable component has 3 major sub components: // * The headerItem; Always visible and should hold some info about what happens if the component is expanded // * The popupItem; The content that needs to be shown if the component is expanded. @@ -16,8 +18,13 @@ Item // The background color of the popup property color popupBackgroundColor: "white" + property alias headerBackgroundColor: background.color + // How much spacing is needed around the popupItem - property alias padding: popup.padding + property alias popupPadding: popup.padding + + // How much padding is needed around the header & button + property alias headerPadding: background.padding onPopupItemChanged: { @@ -30,30 +37,39 @@ Item implicitHeight: 100 implicitWidth: 400 - - Loader + Rectangle { - id: headerItemLoader - anchors - { - left: parent.left - right: collapseButton.left - top: parent.top - bottom: parent.bottom - } - } + id: background + property real padding: UM.Theme.getSize("default_margin").width - Button - { - id: collapseButton - anchors + color: "white" + anchors.fill: parent + Loader { - right: parent.right - top: parent.top - bottom: parent.bottom + id: headerItemLoader + anchors + { + left: parent.left + right: collapseButton.left + top: parent.top + bottom: parent.bottom + margins: background.padding + } + } + + Button + { + id: collapseButton + anchors + { + right: parent.right + top: parent.top + bottom: parent.bottom + margins: background.padding + } + text: popup.visible ? "close" : "open" + onClicked: popup.visible ? popup.close() : popup.open() } - text: popup.visible ? "close" : "open" - onClicked: popup.visible ? popup.close() : popup.open() } Popup @@ -61,16 +77,16 @@ Item id: popup // Ensure that the popup is located directly below the headerItem - y: headerItemLoader.height + y: headerItemLoader.height + 2 * background.padding - // Make the popup right aligned with the rest. - x: -width + collapseButton.width + headerItemLoader.width + // Make the popup right aligned with the rest. The 3x padding is due to left, right and padding between + //the button & text. + x: -width + collapseButton.width + headerItemLoader.width + 3 * background.padding closePolicy: Popup.CloseOnPressOutsideParent background: Rectangle { - id: background color: popupBackgroundColor } } From 2c7bdba7d009d8dfbcebb99a7e9b0b85172432f6 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 9 Nov 2018 15:20:26 +0100 Subject: [PATCH 0152/1292] Update ConfigurationSelector header to that it looks more like the new design CURA-5785 --- cura/Settings/ExtrudersModel.py | 11 ++- plugins/PrepareStage/PrepareMenu.qml | 10 ++- .../QuickConfigurationSelector.qml | 79 ++++++++++++++++++- 3 files changed, 92 insertions(+), 8 deletions(-) diff --git a/cura/Settings/ExtrudersModel.py b/cura/Settings/ExtrudersModel.py index 52fc502bfc..9b85afa10e 100644 --- a/cura/Settings/ExtrudersModel.py +++ b/cura/Settings/ExtrudersModel.py @@ -47,6 +47,9 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): VariantRole = Qt.UserRole + 7 StackRole = Qt.UserRole + 8 + MaterialBrandRole = Qt.UserRole + 9 + ColorNameRole = Qt.UserRole + 10 + ## List of colours to display if there is no material or the material has no known # colour. defaultColors = ["#ffc924", "#86ec21", "#22eeee", "#245bff", "#9124ff", "#ff24c8"] @@ -67,7 +70,8 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): self.addRoleName(self.MaterialRole, "material") self.addRoleName(self.VariantRole, "variant") self.addRoleName(self.StackRole, "stack") - + self.addRoleName(self.MaterialBrandRole, "material_brand") + self.addRoleName(self.ColorNameRole, "color_name") self._update_extruder_timer = QTimer() self._update_extruder_timer.setInterval(100) self._update_extruder_timer.setSingleShot(True) @@ -183,7 +187,8 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): default_color = self.defaultColors[position] if 0 <= position < len(self.defaultColors) else self.defaultColors[0] color = extruder.material.getMetaDataEntry("color_code", default = default_color) if extruder.material else default_color - + material_brand = extruder.material.getMetaDataEntry("brand", default = "generic") + color_name = extruder.material.getMetaDataEntry("color_name") # construct an item with only the relevant information item = { "id": extruder.getId(), @@ -195,6 +200,8 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): "material": extruder.material.getName() if extruder.material else "", "variant": extruder.variant.getName() if extruder.variant else "", # e.g. print core "stack": extruder, + "material_brand": material_brand, + "color_name": color_name } items.append(item) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index e8514a9ef9..bcc8ec4c0a 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -50,16 +50,18 @@ Item Cura.QuickConfigurationSelector { - id: configSelection + height: prepareMenu.height + width: UM.Theme.getSize("configuration_selector_widget").width + /*id: configSelection width: visible ? UM.Theme.getSize("machine_selector_widget").width * 0.2 : 0 panelWidth: UM.Theme.getSize("machine_selector_widget").width - height: prepareMenu.height + height: prepareMenu.height*/ } - Cura.CustomConfigurationSelector + /*Cura.CustomConfigurationSelector { width: UM.Theme.getSize("configuration_selector_widget").width - } + }*/ Cura.PrintSetupSelector { diff --git a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml index 740c12d340..966133d906 100644 --- a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml +++ b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml @@ -8,7 +8,82 @@ import QtQuick.Controls.Styles 1.4 import UM 1.2 as UM import Cura 1.0 as Cura -Item + +Cura.ExpandableComponent +{ + id: base + headerItem: Item + { + Cura.ExtrudersModel + { + id: extrudersModel + } + + ListView + { + // Horizontal list that shows the extruders + id: extrudersList + + orientation: ListView.Horizontal + anchors.fill: parent + model: extrudersModel + + Connections + { + target: Cura.MachineManager + onGlobalContainerChanged: forceActiveFocus() // Changing focus applies the currently-being-typed values so it can change the displayed setting values. + } + + delegate: Item + { + height: parent.height + width: Math.round(ListView.view.width / extrudersModel.rowCount()) + + Cura.ExtruderIcon + { + id: extruderIcon + materialColor: model.color + height: parent.height + width: height + } + + Label + { + id: brandNameLabel + + text: model.material_brand + elide: Text.ElideRight + + anchors + { + left: extruderIcon.right + leftMargin: UM.Theme.getSize("default_margin").width + right: parent.right + rightMargin: UM.Theme.getSize("default_margin").width + } + } + Label + { + text: model.color_name + elide: Text.ElideRight + + anchors + { + left: extruderIcon.right + leftMargin: UM.Theme.getSize("default_margin").width + right: parent.right + rightMargin: UM.Theme.getSize("default_margin").width + top: brandNameLabel.bottom + } + } + } + } + } + + +} + +/*Item { id: configurationSelector property var connectedDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null @@ -65,4 +140,4 @@ Item onClosed: visible = false onOpened: visible = true } -} \ No newline at end of file +}*/ \ No newline at end of file From 1602bf0999974c4815faa54575ad84aabb1e3867 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 9 Nov 2018 16:59:10 +0100 Subject: [PATCH 0153/1292] Re-Add the material & printcore selection to the configuration selector CURA-5785 --- .../QuickConfigurationSelector.qml | 170 ++++++++++++++++-- 1 file changed, 157 insertions(+), 13 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml index 966133d906..e093c96ae5 100644 --- a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml +++ b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml @@ -4,6 +4,9 @@ import QtQuick 2.7 import QtQuick.Controls 2.0 import QtQuick.Controls.Styles 1.4 +import QtQuick.Layouts 1.11 + +import QtQuick.Controls 1.1 as OldControls import UM 1.2 as UM import Cura 1.0 as Cura @@ -12,33 +15,28 @@ import Cura 1.0 as Cura Cura.ExpandableComponent { id: base + Cura.ExtrudersModel + { + id: extrudersModel + } + headerItem: Item { - Cura.ExtrudersModel - { - id: extrudersModel - } - + // Horizontal list that shows the extruders ListView { - // Horizontal list that shows the extruders id: extrudersList orientation: ListView.Horizontal anchors.fill: parent model: extrudersModel - Connections - { - target: Cura.MachineManager - onGlobalContainerChanged: forceActiveFocus() // Changing focus applies the currently-being-typed values so it can change the displayed setting values. - } - delegate: Item { height: parent.height width: Math.round(ListView.view.width / extrudersModel.rowCount()) + // Extruder icon. Shows extruder index and has the same color as the active material. Cura.ExtruderIcon { id: extruderIcon @@ -47,6 +45,7 @@ Cura.ExpandableComponent width: height } + // Label for the human readable material color name Label { id: brandNameLabel @@ -62,6 +61,8 @@ Cura.ExpandableComponent rightMargin: UM.Theme.getSize("default_margin").width } } + + // Label that shows the brand of the material Label { text: model.color_name @@ -80,7 +81,150 @@ Cura.ExpandableComponent } } - + popupItem: Item + { + width: base.width + height: 200 + + TabBar + { + id: tabBar + onCurrentIndexChanged: Cura.ExtruderManager.setActiveExtruderIndex(currentIndex) + width: parent.width + height: 50 + Repeater + { + model: extrudersModel + + delegate: TabButton + { + width: Math.round(ListView.view.width / extrudersModel.rowCount()) + height: parent.height + contentItem: Item + { + Cura.ExtruderIcon + { + anchors.horizontalCenter: parent.horizontalCenter + materialColor: model.color + width: parent.height + height: parent.height + } + } + } + } + } + + Item + { + id: tabControl + width: parent.width + anchors.top: tabBar.bottom + anchors.bottom: parent.bottom + property var model: extrudersModel.items[tabBar.currentIndex] + property real textWidth: Math.round(width * 0.3) + property real controlWidth: Math.round(width * 0.7) + Column + { + spacing: UM.Theme.getSize("default_margin").height + Row + { + height: UM.Theme.getSize("print_setup_item").height + + Label + { + text: "Enabled" + verticalAlignment: Text.AlignVCenter + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + height: parent.height + width: tabControl.textWidth + } + + OldControls.CheckBox + { + checked: Cura.MachineManager.getExtruder(parent.model.index).isEnabled + onClicked: Cura.MachineManager.setExtruderEnabled(parent.model.index, checked) + height: UM.Theme.getSize("setting_control").height + style: UM.Theme.styles.checkbox + } + } + + Row + { + height: UM.Theme.getSize("print_setup_item").height + Label + { + text: "Material" + verticalAlignment: Text.AlignVCenter + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + height: parent.height + width: tabControl.textWidth + } + + OldControls.ToolButton + { + id: materialSelection + + property var activeExtruder: Cura.MachineManager.activeStack + property var hasActiveExtruder: activeExtruder != null + property var currentRootMaterialName: hasActiveExtruder ? activeExtruder.material.name : "" + property var valueError: hasActiveExtruder ? Cura.ContainerManager.getContainerMetaDataEntry(activeExtruder.material.id, "compatible", "") != "True" : true + property var valueWarning: ! Cura.MachineManager.isActiveQualitySupported + + text: currentRootMaterialName + tooltip: currentRootMaterialName + visible: Cura.MachineManager.hasMaterials + + enabled: !extrudersList.visible || Cura.ExtruderManager.activeExtruderIndex > -1 + + height: UM.Theme.getSize("setting_control").height + width: tabControl.controlWidth + + style: UM.Theme.styles.sidebar_header_button + activeFocusOnPress: true + menu: Cura.MaterialMenu + { + extruderIndex: Cura.ExtruderManager.activeExtruderIndex + } + + } + } + + Row + { + height: UM.Theme.getSize("print_setup_item").height + + Label + { + text: Cura.MachineManager.activeDefinitionVariantsName + verticalAlignment: Text.AlignVCenter + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + height: parent.height + width: tabControl.textWidth + } + + OldControls.ToolButton + { + id: variantSelection + text: Cura.MachineManager.activeVariantName + tooltip: Cura.MachineManager.activeVariantName; + visible: Cura.MachineManager.hasVariants + + height: UM.Theme.getSize("setting_control").height + width: tabControl.controlWidth + style: UM.Theme.styles.sidebar_header_button + activeFocusOnPress: true; + + menu: Cura.NozzleMenu { extruderIndex: Cura.ExtruderManager.activeExtruderIndex } + } + } + } + + } + } + } /*Item From 7bdb5e93fe4a3106b0b0d9a7853bc5dad63d9d79 Mon Sep 17 00:00:00 2001 From: TiZYX Date: Fri, 9 Nov 2018 17:02:02 +0100 Subject: [PATCH 0154/1292] Update Quality --- resources/quality/tizyx_k25/tizyx_k25_normal.inst.cfg | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/quality/tizyx_k25/tizyx_k25_normal.inst.cfg b/resources/quality/tizyx_k25/tizyx_k25_normal.inst.cfg index 8b066f139f..d38f094d1a 100644 --- a/resources/quality/tizyx_k25/tizyx_k25_normal.inst.cfg +++ b/resources/quality/tizyx_k25/tizyx_k25_normal.inst.cfg @@ -13,17 +13,17 @@ global_quality = True adhesion_type = skirt skirt_line_count = 2 skirt_gap = 2 -cool_fan_speed_0 = 100 fill_outline_gaps = True -infill_angles = [0,90 ] +infill_angles = [] infill_sparse_density = 15 material_diameter = 1.75 retraction_amount = 2.5 retraction_min_travel = 2 retraction_speed = 30 -skin_angles = [0,90] +skin_angles = [] speed_print = 60 speed_topbottom = 50 speed_wall_0 = 40 top_layers = 4 wall_line_count = 2 +cool_min_layer_time = 11 From 69daa0d91a2d7a70fa9d4e3a5d90778799dbca31 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Sun, 11 Nov 2018 12:44:56 +0100 Subject: [PATCH 0155/1292] Rename Toolbox menu to Marketplace. It was remove by mistake in a merge conflict. Contributes to CURA-5784. --- resources/qml/MainWindow/ApplicationMenu.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/MainWindow/ApplicationMenu.qml b/resources/qml/MainWindow/ApplicationMenu.qml index d3bc115419..04c068cb54 100644 --- a/resources/qml/MainWindow/ApplicationMenu.qml +++ b/resources/qml/MainWindow/ApplicationMenu.qml @@ -86,7 +86,7 @@ Item Menu { id: plugin_menu - title: catalog.i18nc("@title:menu menubar:toplevel", "&Toolbox") + title: catalog.i18nc("@title:menu menubar:toplevel", "&Marketplace") MenuItem { action: Cura.Actions.browsePackages } } From 3669a3791dc04f9fa35a9ef62cd3e57b8667ce94 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Sun, 11 Nov 2018 12:56:30 +0100 Subject: [PATCH 0156/1292] Hide the Preview shortcut in the action panel when the active stage is the PreviewStage. Also adjust the size of the output button when the Preview button is not visible. Contributes to CURA-5786. --- resources/qml/ActionPanel/OutputProcessWidget.qml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/resources/qml/ActionPanel/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml index 0ea956d1dc..f4e014b1ec 100644 --- a/resources/qml/ActionPanel/OutputProcessWidget.qml +++ b/resources/qml/ActionPanel/OutputProcessWidget.qml @@ -102,6 +102,8 @@ Column Cura.ActionButton { + id: previewStageShortcut + leftPadding: UM.Theme.getSize("default_margin").width rightPadding: UM.Theme.getSize("default_margin").width height: UM.Theme.getSize("action_panel_button").height @@ -111,11 +113,12 @@ Column textColor: UM.Theme.getColor("primary") textHoverColor: UM.Theme.getColor("text") onClicked: UM.Controller.setActiveStage("PreviewStage") + visible: UM.Controller.activeStage != null && UM.Controller.activeStage.stageId != "PreviewStage" } Cura.OutputDevicesActionButton { - width: UM.Theme.getSize("action_panel_button").width + width: previewStageShortcut.visible ? UM.Theme.getSize("action_panel_button").width : parent.width height: UM.Theme.getSize("action_panel_button").height } } From f65b1f8fbc183fb1b696baacc263c54ef9246f03 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Sun, 11 Nov 2018 13:16:38 +0100 Subject: [PATCH 0157/1292] Add soft animation to the entire popup and not only in the background. This prevents the content to show before the background. Contributes to CURA-5784. --- resources/qml/Account/AccountWidget.qml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/resources/qml/Account/AccountWidget.qml b/resources/qml/Account/AccountWidget.qml index e37523296f..d3bd6fd130 100644 --- a/resources/qml/Account/AccountWidget.qml +++ b/resources/qml/Account/AccountWidget.qml @@ -51,6 +51,9 @@ Button closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent + opacity: opened ? 1 : 0 + Behavior on opacity { NumberAnimation { duration: 100 } } + contentItem: AccountDetails { id: panel @@ -61,8 +64,6 @@ Button background: UM.PointingRectangle { - opacity: visible ? 1 : 0 - Behavior on opacity { NumberAnimation { duration: 100 } } color: UM.Theme.getColor("tool_panel_background") borderColor: UM.Theme.getColor("lining") borderWidth: UM.Theme.getSize("default_lining").width From 8a63a79896b3c22f94562ddc0aec1b939103494b Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Sun, 11 Nov 2018 13:17:59 +0100 Subject: [PATCH 0158/1292] Add soft animation to the entire popup and not only in the background. This prevents the content to show before the background. Contributes to CURA-5786. --- .../ActionPanel/PrintInformationWidget.qml | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/resources/qml/ActionPanel/PrintInformationWidget.qml b/resources/qml/ActionPanel/PrintInformationWidget.qml index 620c3a408c..82707576e0 100644 --- a/resources/qml/ActionPanel/PrintInformationWidget.qml +++ b/resources/qml/ActionPanel/PrintInformationWidget.qml @@ -7,29 +7,30 @@ import QtQuick.Controls 2.1 import UM 1.1 as UM import Cura 1.0 as Cura -Button +UM.RecolorImage { id: widget - implicitHeight: UM.Theme.getSize("section_icon").height - implicitWidth: UM.Theme.getSize("section_icon").width + //implicitHeight: UM.Theme.getSize("section_icon").height + //implicitWidth: UM.Theme.getSize("section_icon").width - background: UM.RecolorImage + source: UM.Theme.getIcon("info") + width: UM.Theme.getSize("section_icon").width + height: UM.Theme.getSize("section_icon").height + + sourceSize.width: width + sourceSize.height: height + + color: popup.opened ? UM.Theme.getColor("primary") : UM.Theme.getColor("text_medium") + + MouseArea { - id: moreInformationIcon - - source: UM.Theme.getIcon("info") - width: UM.Theme.getSize("section_icon").width - height: UM.Theme.getSize("section_icon").height - - sourceSize.width: width - sourceSize.height: height - - color: widget.hovered ? UM.Theme.getColor("primary") : UM.Theme.getColor("text_medium") + anchors.fill: parent + hoverEnabled: true + onEntered: popup.open() + onExited: popup.close() } - onClicked: popup.opened ? popup.close() : popup.open() - Popup { id: popup @@ -39,6 +40,9 @@ Button closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent + opacity: opened ? 1 : 0 + Behavior on opacity { NumberAnimation { duration: 100 } } + contentItem: PrintJobInformation { id: printJobInformation @@ -47,8 +51,6 @@ Button background: UM.PointingRectangle { - opacity: visible ? 1 : 0 - Behavior on opacity { NumberAnimation { duration: 100 } } color: UM.Theme.getColor("tool_panel_background") borderColor: UM.Theme.getColor("lining") borderWidth: UM.Theme.getSize("default_lining").width From 38a80ecae59eeac754f10cd2ef00054ed09c3ba2 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Sun, 11 Nov 2018 14:06:52 +0100 Subject: [PATCH 0159/1292] Make some tweaks in the UI for the preview stage. Clean up the default theme a bit by removing unused entries. Contributes to CURA-5829. --- plugins/SimulationView/LayerSlider.qml | 10 ++--- plugins/SimulationView/PathSlider.qml | 9 ++-- .../SimulationViewMainComponent.qml | 4 +- resources/themes/cura-dark/theme.json | 1 - resources/themes/cura-light/styles.qml | 41 ------------------- resources/themes/cura-light/theme.json | 33 ++++++--------- 6 files changed, 21 insertions(+), 77 deletions(-) diff --git a/plugins/SimulationView/LayerSlider.qml b/plugins/SimulationView/LayerSlider.qml index 7916cd62b3..42b8cf0ba0 100644 --- a/plugins/SimulationView/LayerSlider.qml +++ b/plugins/SimulationView/LayerSlider.qml @@ -21,15 +21,12 @@ Item property color lowerHandleColor: UM.Theme.getColor("slider_handle") property color rangeHandleColor: UM.Theme.getColor("slider_groove_fill") property color handleActiveColor: UM.Theme.getColor("slider_handle_active") - property real handleLabelWidth: UM.Theme.getSize("slider_layerview_background").width property var activeHandle: upperHandle // Track properties property real trackThickness: UM.Theme.getSize("slider_groove").width // width of the slider track - property real trackRadius: trackThickness / 2 + property real trackRadius: UM.Theme.getSize("slider_groove_radius").width property color trackColor: UM.Theme.getColor("slider_groove") - property real trackBorderWidth: 1 - property color trackBorderColor: UM.Theme.getColor("slider_groove_border") // value properties property real maximumValue: 100 @@ -90,8 +87,6 @@ Item radius: sliderRoot.trackRadius anchors.centerIn: sliderRoot color: sliderRoot.trackColor - border.width: sliderRoot.trackBorderWidth - border.color: sliderRoot.trackBorderColor visible: sliderRoot.layersVisible } @@ -140,9 +135,10 @@ Item Rectangle { - width: sliderRoot.trackThickness - 2 * sliderRoot.trackBorderWidth + width: sliderRoot.trackThickness height: parent.height + sliderRoot.handleSize anchors.centerIn: parent + radius: sliderRoot.trackRadius color: sliderRoot.rangeHandleColor } diff --git a/plugins/SimulationView/PathSlider.qml b/plugins/SimulationView/PathSlider.qml index 701e54e398..c7a43c6407 100644 --- a/plugins/SimulationView/PathSlider.qml +++ b/plugins/SimulationView/PathSlider.qml @@ -23,10 +23,8 @@ Item // track properties property real trackThickness: UM.Theme.getSize("slider_groove").width - property real trackRadius: trackThickness / 2 + property real trackRadius: UM.Theme.getSize("slider_groove_radius").width property color trackColor: UM.Theme.getColor("slider_groove") - property real trackBorderWidth: 1 // width of the slider track border - property color trackBorderColor: UM.Theme.getColor("slider_groove_border") // value properties property real maximumValue: 100 @@ -68,8 +66,6 @@ Item radius: sliderRoot.trackRadius anchors.centerIn: sliderRoot color: sliderRoot.trackColor - border.width: sliderRoot.trackBorderWidth - border.color: sliderRoot.trackBorderColor visible: sliderRoot.pathsVisible } @@ -86,9 +82,10 @@ Item Rectangle { - height: sliderRoot.trackThickness - 2 * sliderRoot.trackBorderWidth + height: sliderRoot.trackThickness width: parent.width + sliderRoot.handleSize anchors.centerIn: parent + radius: sliderRoot.trackRadius color: sliderRoot.rangeColor } } diff --git a/plugins/SimulationView/SimulationViewMainComponent.qml b/plugins/SimulationView/SimulationViewMainComponent.qml index 784938e5c2..4e038a1cf1 100644 --- a/plugins/SimulationView/SimulationViewMainComponent.qml +++ b/plugins/SimulationView/SimulationViewMainComponent.qml @@ -18,7 +18,7 @@ Item { id: pathSlider height: UM.Theme.getSize("slider_handle").width - width: UM.Theme.getSize("layerview_menu_size").width + width: UM.Theme.getSize("slider_layerview_size").height anchors.bottom: parent.bottom anchors.bottomMargin: UM.Theme.getSize("default_margin").height @@ -166,7 +166,7 @@ Item id: layerSlider width: UM.Theme.getSize("slider_handle").width - height: UM.Theme.getSize("layerview_menu_size").height + height: UM.Theme.getSize("slider_layerview_size").height anchors { diff --git a/resources/themes/cura-dark/theme.json b/resources/themes/cura-dark/theme.json index 344efb6fd1..62b1dbfa0f 100644 --- a/resources/themes/cura-dark/theme.json +++ b/resources/themes/cura-dark/theme.json @@ -135,7 +135,6 @@ "slider_handle": [255, 255, 255, 255], "slider_handle_hover": [77, 182, 226, 255], "slider_handle_active": [68, 192, 255, 255], - "slider_handle_border": [39, 44, 48, 255], "slider_text_background": [255, 255, 255, 255], "checkbox": [43, 48, 52, 255], diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index dacff1b42b..503a3eddca 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -915,47 +915,6 @@ QtObject } } - property Component slider: Component - { - SliderStyle - { - groove: Rectangle - { - implicitWidth: control.width - implicitHeight: Theme.getSize("slider_groove").height - - color: Theme.getColor("slider_groove") - border.width: Theme.getSize("default_lining").width - border.color: Theme.getColor("slider_groove_border") - - radius: Math.round(width / 2) - - Rectangle - { - anchors - { - left: parent.left - top: parent.top - bottom: parent.bottom - } - color: Theme.getColor("slider_groove_fill"); - width: Math.round((control.value / (control.maximumValue - control.minimumValue)) * parent.width); - radius: Math.round(width / 2); - } - } - handle: Rectangle - { - width: Theme.getSize("slider_handle").width; - height: Theme.getSize("slider_handle").height; - color: control.hovered ? Theme.getColor("slider_handle_hover") : Theme.getColor("slider_handle"); - border.width: Theme.getSize("default_lining").width - border.color: control.hovered ? Theme.getColor("slider_handle_hover_border") : Theme.getColor("slider_handle_border") - radius: Math.round(Theme.getSize("slider_handle").width / 2); //Round. - Behavior on color { ColorAnimation { duration: 50; } } - } - } - } - property Component text_field: Component { TextFieldStyle diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index f882277d65..48cf5d456d 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -131,11 +131,11 @@ "button_disabled": [31, 36, 39, 255], "button_disabled_text": [255, 255, 255, 101], - "small_button": [31, 36, 39, 0], - "small_button_hover": [68, 72, 75, 255], - "small_button_active": [68, 72, 75, 255], - "small_button_active_hover": [68, 72, 75, 255], - "small_button_text": [31, 36, 39, 197], + "small_button": [0, 0, 0, 0], + "small_button_hover": [10, 8, 80, 255], + "small_button_active": [10, 8, 80, 255], + "small_button_active_hover": [10, 8, 80, 255], + "small_button_text": [171, 171, 191, 255], "small_button_text_hover": [255, 255, 255, 255], "small_button_text_active": [255, 255, 255, 255], "small_button_text_active_hover": [255, 255, 255, 255], @@ -215,13 +215,11 @@ "progressbar_background": [245, 245, 245, 255], "progressbar_control": [50, 130, 255, 255], - "slider_groove": [245, 245, 245, 255], - "slider_groove_border": [127, 127, 127, 255], - "slider_groove_fill": [127, 127, 127, 255], - "slider_handle": [0, 0, 0, 255], + "slider_groove": [223, 223, 223, 255], + "slider_groove_fill": [10, 8, 80, 255], + "slider_handle": [10, 8, 80, 255], "slider_handle_hover": [77, 182, 226, 255], - "slider_handle_active": [68, 192, 255, 255], - "slider_handle_border": [39, 44, 48, 255], + "slider_handle_active": [50, 130, 255, 255], "slider_text_background": [255, 255, 255, 255], "quality_slider_unavailable": [179, 179, 179, 255], @@ -449,17 +447,12 @@ "scrollbar": [0.75, 0.5], - "quality_slider_bar": [1, 0.2], - - "slider_groove": [0.3, 0.3], - "slider_handle": [1.0, 1.0], - "slider_layerview_size": [1.0, 22.0], - "slider_layerview_background": [4.0, 0.0], - "slider_layerview_margin": [1.0, 1.5], + "slider_groove": [0.5, 0.5], + "slider_groove_radius": [0.15, 0.15], + "slider_handle": [1.5, 1.5], + "slider_layerview_size": [1.0, 26.0], "layerview_menu_size": [15, 20], - "layerview_menu_size_material_color_mode": [15, 16], - "layerview_menu_size_collapsed": [15, 6], "layerview_legend_size": [1.0, 1.0], "layerview_row": [11.0, 1.5], "layerview_row_spacing": [0.0, 0.5], From 9bf18031ce33f41d649e5471048ac84a3dc06bd9 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Sun, 11 Nov 2018 19:15:02 +0100 Subject: [PATCH 0160/1292] Apply restyle of the toolbar according to the new designs. --- .../qml/ActionPanel/ActionPanelWidget.qml | 1 - resources/qml/Cura.qml | 2 + resources/qml/ExtruderButton.qml | 35 +++-- resources/qml/Toolbar.qml | 130 +++++++++++------- resources/themes/cura-light/styles.qml | 75 ++++++++++ resources/themes/cura-light/theme.json | 9 +- 6 files changed, 185 insertions(+), 67 deletions(-) diff --git a/resources/qml/ActionPanel/ActionPanelWidget.qml b/resources/qml/ActionPanel/ActionPanelWidget.qml index 0db778de5a..a1cd81e9e9 100644 --- a/resources/qml/ActionPanel/ActionPanelWidget.qml +++ b/resources/qml/ActionPanel/ActionPanelWidget.qml @@ -23,7 +23,6 @@ Rectangle border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") radius: UM.Theme.getSize("default_radius").width - visible: CuraApplication.platformActivity property bool outputAvailable: UM.Backend.state == UM.Backend.Done || UM.Backend.state == UM.Backend.Disabled diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index dc64aeee38..819d986ece 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -186,6 +186,7 @@ UM.MainWindow verticalCenter: parent.verticalCenter left: parent.left } + visible: CuraApplication.platformActivity } ObjectsList @@ -235,6 +236,7 @@ UM.MainWindow anchors.bottom: parent.bottom anchors.rightMargin: UM.Theme.getSize("thick_margin").width anchors.bottomMargin: UM.Theme.getSize("thick_margin").height + visible: CuraApplication.platformActivity } Loader diff --git a/resources/qml/ExtruderButton.qml b/resources/qml/ExtruderButton.qml index 2c1b80047e..7923521658 100644 --- a/resources/qml/ExtruderButton.qml +++ b/resources/qml/ExtruderButton.qml @@ -15,37 +15,36 @@ Button text: catalog.i18ncp("@label %1 is filled in with the name of an extruder", "Print Selected Model with %1", "Print Selected Models with %1", UM.Selection.selectionCount).arg(extruder.name) - style: UM.Theme.styles.tool_button; + style: UM.Theme.styles.toolbar_button iconSource: UM.Theme.getIcon("extruder_button") checked: Cura.ExtruderManager.selectedObjectExtruders.indexOf(extruder.id) != -1 enabled: UM.Selection.hasSelection && extruder.stack.isEnabled - property color customColor: base.hovered ? UM.Theme.getColor("button_hover") : UM.Theme.getColor("button"); - - Rectangle - { - anchors.fill: parent - anchors.margins: UM.Theme.getSize("default_lining").width; - - color: "transparent" - - border.width: base.checked ? UM.Theme.getSize("default_lining").width : 0; - border.color: UM.Theme.getColor("button_text") - } - Item { anchors.centerIn: parent width: UM.Theme.getSize("default_margin").width height: UM.Theme.getSize("default_margin").height + opacity: !base.enabled ? 0.2 : 1.0 Label { - anchors.centerIn: parent; - text: index + 1; - color: parent.enabled ? UM.Theme.getColor("button_text") : UM.Theme.getColor("button_disabled_text") - font: UM.Theme.getFont("default_bold"); + anchors.centerIn: parent + text: index + 1 + color: + { + if (base.checked) + { + return UM.Theme.getColor("toolbar_button_text_active") + } + else if(base.hovered) + { + return UM.Theme.getColor("toolbar_button_text_hover") + } + return UM.Theme.getColor("toolbar_button_text") + } + font: UM.Theme.getFont("default_bold") } } diff --git a/resources/qml/Toolbar.qml b/resources/qml/Toolbar.qml index a04b3650df..9955ceeba7 100644 --- a/resources/qml/Toolbar.qml +++ b/resources/qml/Toolbar.qml @@ -11,75 +11,113 @@ import Cura 1.0 as Cura Item { - id: base; + id: base - width: buttons.width; + width: buttons.width height: buttons.height property int activeY - Column + Item { - id: buttons; + id: buttons + width: parent.visible ? toolButtons.width : 0 + height: childrenRect.height - anchors.bottom: parent.bottom - anchors.left: parent.left - spacing: UM.Theme.getSize("button_lining").width + Behavior on width { NumberAnimation { duration: 100 } } - Repeater + // Used to create a rounded rectangle behind the toolButtons + Rectangle { - id: repeat + anchors.fill: toolButtons + anchors.leftMargin: -radius + radius: UM.Theme.getSize("default_radius").width + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("lining") + color: UM.Theme.getColor("toolbar_background") + } - model: UM.ToolModel { } - width: childrenRect.width - height: childrenRect.height - Button + Column + { + id: toolButtons + + anchors.top: parent.top + anchors.right: parent.right + spacing: UM.Theme.getSize("button_lining").width + + Repeater { - text: model.name + (model.shortcut ? (" (" + model.shortcut + ")") : "") - iconSource: (UM.Theme.getIcon(model.icon) != "") ? UM.Theme.getIcon(model.icon) : "file:///" + model.location + "/" + model.icon - checkable: true - checked: model.active - enabled: model.enabled && UM.Selection.hasSelection && UM.Controller.toolsEnabled - style: UM.Theme.styles.tool_button + id: repeat - onCheckedChanged: + model: UM.ToolModel { } + width: childrenRect.width + height: childrenRect.height + Button { - if (checked) - { - base.activeY = y; - } - } + text: model.name + (model.shortcut ? (" (" + model.shortcut + ")") : "") + iconSource: (UM.Theme.getIcon(model.icon) != "") ? UM.Theme.getIcon(model.icon) : "file:///" + model.location + "/" + model.icon + checkable: true + checked: model.active + enabled: model.enabled && UM.Selection.hasSelection && UM.Controller.toolsEnabled + style: UM.Theme.styles.toolbar_button - //Workaround since using ToolButton's onClicked would break the binding of the checked property, instead - //just catch the click so we do not trigger that behaviour. - MouseArea - { - anchors.fill: parent; - onClicked: + onCheckedChanged: { - forceActiveFocus() //First grab focus, so all the text fields are updated - if(parent.checked) + if (checked) { - UM.Controller.setActiveTool(null); + base.activeY = y; } - else + } + + //Workaround since using ToolButton's onClicked would break the binding of the checked property, instead + //just catch the click so we do not trigger that behaviour. + MouseArea + { + anchors.fill: parent; + onClicked: { - UM.Controller.setActiveTool(model.id); + forceActiveFocus() //First grab focus, so all the text fields are updated + if(parent.checked) + { + UM.Controller.setActiveTool(null); + } + else + { + UM.Controller.setActiveTool(model.id); + } } } } } } - Item { height: UM.Theme.getSize("default_margin").height; width: UM.Theme.getSize("default_lining").width; visible: extruders.count > 0 } - - Repeater + // Used to create a rounded rectangle behind the extruderButtons + Rectangle { - id: extruders - width: childrenRect.width - height: childrenRect.height - property var _model: Cura.ExtrudersModel { id: extrudersModel } - model: _model.items.length > 1 ? _model : 0 - ExtruderButton { extruder: model } + anchors.fill: extruderButtons + anchors.leftMargin: -radius + radius: UM.Theme.getSize("default_radius").width + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("lining") + color: UM.Theme.getColor("toolbar_background") + } + + Column + { + id: extruderButtons + + anchors.topMargin: UM.Theme.getSize("default_margin").height + anchors.top: toolButtons.bottom + anchors.right: parent.right + + Repeater + { + id: extruders + width: childrenRect.width + height: childrenRect.height + property var _model: Cura.ExtrudersModel { id: extrudersModel } + model: _model.items.length > 1 ? _model : 0 + ExtruderButton { extruder: model } + } } } @@ -91,7 +129,7 @@ Item anchors.leftMargin: UM.Theme.getSize("default_margin").width; anchors.top: base.top; anchors.topMargin: base.activeY - z: buttons.z -1 + z: buttons.z - 1 target: Qt.point(parent.right, base.activeY + Math.round(UM.Theme.getSize("button").height/2)) arrowSize: UM.Theme.getSize("default_arrow").width diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index 503a3eddca..52ae3cd243 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -171,6 +171,81 @@ QtObject } } + property Component toolbar_button: Component + { + ButtonStyle + { + background: Item + { + implicitWidth: Theme.getSize("button").width; + implicitHeight: Theme.getSize("button").height; + + UM.PointingRectangle + { + id: button_tooltip + + anchors.left: parent.right + anchors.leftMargin: Theme.getSize("button_tooltip_arrow").width * 2 + anchors.verticalCenter: parent.verticalCenter + + target: Qt.point(parent.x, y + Math.round(height/2)) + arrowSize: Theme.getSize("button_tooltip_arrow").width + color: Theme.getColor("button_tooltip") + opacity: control.hovered ? 1.0 : 0.0; + visible: control.text != "" + + width: control.hovered ? button_tip.width + Theme.getSize("button_tooltip").width : 0 + height: Theme.getSize("button_tooltip").height + + Behavior on width { NumberAnimation { duration: 100; } } + Behavior on opacity { NumberAnimation { duration: 100; } } + + Label + { + id: button_tip + + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter; + + text: control.text; + font: Theme.getFont("button_tooltip"); + color: Theme.getColor("tooltip_text"); + } + } + } + + label: Item + { + UM.RecolorImage + { + anchors.centerIn: parent; + opacity: !control.enabled ? 0.2 : 1.0 + source: control.iconSource; + width: Theme.getSize("button_icon").width; + height: Theme.getSize("button_icon").height; + color: + { + if(control.checkable && control.checked && control.hovered) + { + return Theme.getColor("toolbar_button_text_active_hover"); + } + else if(control.pressed || (control.checkable && control.checked)) + { + return Theme.getColor("toolbar_button_text_active"); + } + else if(control.hovered) + { + return Theme.getColor("toolbar_button_text_hover"); + } + return Theme.getColor("toolbar_button_text"); + } + + sourceSize: Theme.getSize("button_icon") + } + } + } + } + property Component tool_button: Component { ButtonStyle diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 48cf5d456d..a33ff87042 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -105,6 +105,8 @@ "action_panel_secondary": [27, 95, 202, 255], + "toolbar_background": [255, 255, 255, 255], + "text": [0, 0, 0, 255], "text_detail": [174, 174, 174, 128], "text_link": [50, 130, 255, 255], @@ -120,6 +122,11 @@ "error": [255, 140, 0, 255], "warning": [255, 190, 35, 255], + "toolbar_button_text": [10, 8, 80, 255], + "toolbar_button_text_hover": [50, 130, 255, 255], + "toolbar_button_text_active": [50, 130, 255, 255], + "toolbar_button_text_active_hover": [50, 130, 255, 255], + "button": [31, 36, 39, 255], "button_hover": [68, 72, 75, 255], "button_active": [68, 72, 75, 255], @@ -128,8 +135,6 @@ "button_text_hover": [255, 255, 255, 255], "button_text_active": [255, 255, 255, 255], "button_text_active_hover": [255, 255, 255, 255], - "button_disabled": [31, 36, 39, 255], - "button_disabled_text": [255, 255, 255, 101], "small_button": [0, 0, 0, 0], "small_button_hover": [10, 8, 80, 255], From f534885e341bd3fd1098d59e55c7231ff29c5b76 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 12 Nov 2018 09:35:32 +0100 Subject: [PATCH 0161/1292] Modify the color behavior of the toolbar buttons. --- resources/themes/cura-light/styles.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index 52ae3cd243..6f099bf1c5 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -225,11 +225,11 @@ QtObject height: Theme.getSize("button_icon").height; color: { - if(control.checkable && control.checked && control.hovered) + if (control.checked && control.hovered) { return Theme.getColor("toolbar_button_text_active_hover"); } - else if(control.pressed || (control.checkable && control.checked)) + else if (control.checked) { return Theme.getColor("toolbar_button_text_active"); } From e64158402137953789861adfbe77f2345b5bb983 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 12 Nov 2018 09:45:55 +0100 Subject: [PATCH 0162/1292] Made strings in ConfigurationSelector translatable. CURA-5785 --- .../ConfigurationMenu/QuickConfigurationSelector.qml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml index e093c96ae5..3c354384c7 100644 --- a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml +++ b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml @@ -15,11 +15,18 @@ import Cura 1.0 as Cura Cura.ExpandableComponent { id: base + Cura.ExtrudersModel { id: extrudersModel } + UM.I18nCatalog + { + id: catalog + name: "cura" + } + headerItem: Item { // Horizontal list that shows the extruders @@ -132,7 +139,7 @@ Cura.ExpandableComponent Label { - text: "Enabled" + text: catalog.i18nc("@label", "Enabled") verticalAlignment: Text.AlignVCenter font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") @@ -154,7 +161,7 @@ Cura.ExpandableComponent height: UM.Theme.getSize("print_setup_item").height Label { - text: "Material" + text: catalog.i18nc("@label", "Material") verticalAlignment: Text.AlignVCenter font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") From 9c555bf67f1964fcc0055c7826f1097199548dc8 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 12 Nov 2018 11:02:43 +0100 Subject: [PATCH 0163/1292] Add typing and always add error message if loading failed There were some places where it would return None. Then in the QML it would give a QML error that the null object has no dictionary items. Contributes to issue CURA-5929. --- cura/Settings/ContainerManager.py | 8 ++++---- cura/Settings/CuraContainerRegistry.py | 15 +++++++-------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 3cfca1a944..3c1e09f086 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -419,13 +419,13 @@ class ContainerManager(QObject): self._container_name_filters[name_filter] = entry ## Import single profile, file_url does not have to end with curaprofile - @pyqtSlot(QUrl, result="QVariantMap") - def importProfile(self, file_url: QUrl): + @pyqtSlot(QUrl, result = "QVariantMap") + def importProfile(self, file_url: QUrl) -> Dict[str, str]: if not file_url.isValid(): - return + return {"status": "error", "message": catalog.i18nc("@info:status", "Invalid file URL:") + " " + file_url} path = file_url.toLocalFile() if not path: - return + return {"status": "error", "message": catalog.i18nc("@info:status", "Invalid file URL:") + " " + file_url} return self._container_registry.importProfile(path) @pyqtSlot(QObject, QUrl, str) diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index 11640adc0f..63277ebce5 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -5,8 +5,7 @@ import os import re import configparser -from typing import cast, Optional - +from typing import cast, Dict, Optional from PyQt5.QtWidgets import QMessageBox from UM.Decorators import override @@ -161,20 +160,20 @@ class CuraContainerRegistry(ContainerRegistry): ## Imports a profile from a file # - # \param file_name \type{str} the full path and filename of the profile to import - # \return \type{Dict} dict with a 'status' key containing the string 'ok' or 'error', and a 'message' key - # containing a message for the user - def importProfile(self, file_name): + # \param file_name The full path and filename of the profile to import. + # \return Dict with a 'status' key containing the string 'ok' or 'error', + # and a 'message' key containing a message for the user. + def importProfile(self, file_name: str) -> Dict[str, str]: Logger.log("d", "Attempting to import profile %s", file_name) if not file_name: - return { "status": "error", "message": catalog.i18nc("@info:status Don't translate the XML tags or !", "Failed to import profile from {0}: {1}", file_name, "Invalid path")} + return { "status": "error", "message": catalog.i18nc("@info:status Don't translate the XML tags !", "Failed to import profile from {0}: {1}", file_name, "Invalid path")} plugin_registry = PluginRegistry.getInstance() extension = file_name.split(".")[-1] global_stack = Application.getInstance().getGlobalContainerStack() if not global_stack: - return + return {"status": "error", "message": catalog.i18nc("@info:status Don't translate the XML tags !", "Can't import profile from {0} before a printer is added.", file_name)} machine_extruders = [] for position in sorted(global_stack.extruders): From b60977e435676171c3bb678c98f74c449a474cd3 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 12 Nov 2018 11:14:39 +0100 Subject: [PATCH 0164/1292] Convert PrintSetupSelector to an ExpandableComponent CURA-5785 --- plugins/PrepareStage/PrepareMenu.qml | 1 + resources/qml/PrintSetupSelector.qml | 281 ++++++++++++--------------- 2 files changed, 125 insertions(+), 157 deletions(-) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index bcc8ec4c0a..ff8cdc2a47 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -66,6 +66,7 @@ Item Cura.PrintSetupSelector { width: UM.Theme.getSize("print_setup_widget").width + height: prepareMenu.height onShowTooltip: prepareMenu.showTooltip(item, location, text) onHideTooltip: prepareMenu.hideTooltip() } diff --git a/resources/qml/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector.qml index 8232e76a17..7a415b1e2e 100644 --- a/resources/qml/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector.qml @@ -10,22 +10,14 @@ import Cura 1.0 as Cura import "Menus" import "Menus/ConfigurationMenu" -Rectangle +Cura.ExpandableComponent { id: base height: childrenRect.height - property int currentModeIndex: -1 property bool hideSettings: PrintInformation.preSliced - property variant printDuration: PrintInformation.currentPrintTime - property variant printMaterialLengths: PrintInformation.materialLengths - property variant printMaterialWeights: PrintInformation.materialWeights - property variant printMaterialCosts: PrintInformation.materialCosts - property variant printMaterialNames: PrintInformation.materialNames - - color: UM.Theme.getColor("main_background") UM.I18nCatalog { id: catalog; name: "cura"} // This widget doesn't show tooltips by itself. Instead it emits signals so others can do something with it. @@ -46,40 +38,12 @@ Rectangle } } - function strPadLeft(string, pad, length) - { - return (new Array(length + 1).join(pad) + string).slice(-length); - } - - function getPrettyTime(time) - { - var hours = Math.floor(time / 3600) - time -= hours * 3600 - var minutes = Math.floor(time / 60); - time -= minutes * 60 - var seconds = Math.floor(time); - - var finalTime = strPadLeft(hours, "0", 2) + ":" + strPadLeft(minutes, "0", 2) + ":" + strPadLeft(seconds, "0", 2); - return finalTime; - } - - MouseArea - { - anchors.fill: parent - acceptedButtons: Qt.AllButtons - - onWheel: - { - wheel.accepted = true; - } - } - onCurrentModeIndexChanged: { UM.Preferences.setValue("cura/active_mode", currentModeIndex); } - Label + headerItem: Label { id: settingsModeLabel text: !hideSettings ? catalog.i18nc("@label:listbox", "Print Setup") : catalog.i18nc("@label:listbox", "Print Setup disabled\nG-code files cannot be modified") @@ -98,146 +62,149 @@ Rectangle color: UM.Theme.getColor("text") } - - ListView + popupItem: Item { - // Settings mode selection toggle - id: settingsModeSelection - model: modesListModel - width: Math.round(parent.width * 0.55) - height: UM.Theme.getSize("print_setup_mode_toggle").height - visible: !hideSettings - - anchors.right: parent.right - anchors.rightMargin: UM.Theme.getSize("thick_margin").width - anchors.top: settingsModeLabel.top - - ButtonGroup + height: settingsModeSelection.height + sidebarContents.height + width: UM.Theme.getSize("print_setup_widget").width + ListView { - id: modeMenuGroup + // Settings mode selection toggle + id: settingsModeSelection + model: modesListModel + width: Math.round(parent.width * 0.55) + height: UM.Theme.getSize("print_setup_mode_toggle").height + visible: !hideSettings + + anchors.right: parent.right + anchors.rightMargin: UM.Theme.getSize("thick_margin").width + + ButtonGroup + { + id: modeMenuGroup + } + + delegate: Button + { + id: control + + height: settingsModeSelection.height + width: Math.round(parent.width / 2) + + anchors.left: parent.left + anchors.leftMargin: model.index * Math.round(settingsModeSelection.width / 2) + anchors.verticalCenter: parent.verticalCenter + + ButtonGroup.group: modeMenuGroup + + checkable: true + checked: base.currentModeIndex == index + onClicked: base.currentModeIndex = index + + onHoveredChanged: + { + if (hovered) + { + tooltipDelayTimer.item = settingsModeSelection + tooltipDelayTimer.text = model.tooltipText + tooltipDelayTimer.start() + } + else + { + tooltipDelayTimer.stop() + base.hideTooltip() + } + } + + background: Rectangle + { + border.width: control.checked ? UM.Theme.getSize("default_lining").width * 2 : UM.Theme.getSize("default_lining").width + border.color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active_border") : control.hovered ? UM.Theme.getColor("action_button_hovered_border") : UM.Theme.getColor("action_button_border") + + // for some reason, QtQuick decided to use the color of the background property as text color for the contentItem, so here it is + color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active") : control.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") + } + + contentItem: Label + { + text: model.text + font: UM.Theme.getFont("default") + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + renderType: Text.NativeRendering + elide: Text.ElideRight + color: + { + if(control.pressed) + { + return UM.Theme.getColor("action_button_active_text"); + } + else if(control.hovered) + { + return UM.Theme.getColor("action_button_hovered_text"); + } + return UM.Theme.getColor("action_button_text"); + } + } + } } - delegate: Button + Item { - id: control - - height: settingsModeSelection.height - width: Math.round(parent.width / 2) - + id: sidebarContents + anchors.top: settingsModeSelection.bottom + anchors.topMargin: UM.Theme.getSize("thick_margin").height anchors.left: parent.left - anchors.leftMargin: model.index * Math.round(settingsModeSelection.width / 2) - anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + height: UM.Theme.getSize("print_setup_widget").height - ButtonGroup.group: modeMenuGroup + visible: !hideSettings - checkable: true - checked: base.currentModeIndex == index - onClicked: base.currentModeIndex = index - - onHoveredChanged: + // We load both of them at once (instead of using a loader) because the advanced sidebar can take + // quite some time to load. So in this case we sacrifice memory for speed. + SidebarAdvanced { - if (hovered) - { - tooltipDelayTimer.item = settingsModeSelection - tooltipDelayTimer.text = model.tooltipText - tooltipDelayTimer.start() - } - else - { - tooltipDelayTimer.stop() - base.hideTooltip() - } + anchors.fill: parent + visible: currentModeIndex == 1 + onShowTooltip: base.showTooltip(item, location, text) + onHideTooltip: base.hideTooltip() } - background: Rectangle + SidebarSimple { - border.width: control.checked ? UM.Theme.getSize("default_lining").width * 2 : UM.Theme.getSize("default_lining").width - border.color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active_border") : control.hovered ? UM.Theme.getColor("action_button_hovered_border") : UM.Theme.getColor("action_button_border") - - // for some reason, QtQuick decided to use the color of the background property as text color for the contentItem, so here it is - color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active") : control.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") - } - - contentItem: Label - { - text: model.text - font: UM.Theme.getFont("default") - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - renderType: Text.NativeRendering - elide: Text.ElideRight - color: - { - if(control.pressed) - { - return UM.Theme.getColor("action_button_active_text"); - } - else if(control.hovered) - { - return UM.Theme.getColor("action_button_hovered_text"); - } - return UM.Theme.getColor("action_button_text"); - } + anchors.fill: parent + visible: currentModeIndex != 1 + onShowTooltip: base.showTooltip(item, location, text) + onHideTooltip: base.hideTooltip() } } - } - Item - { - id: sidebarContents - anchors.top: settingsModeSelection.bottom - anchors.topMargin: UM.Theme.getSize("thick_margin").height - anchors.left: parent.left - anchors.right: parent.right - height: UM.Theme.getSize("print_setup_widget").height - - visible: !hideSettings - - // We load both of them at once (instead of using a loader) because the advanced sidebar can take - // quite some time to load. So in this case we sacrifice memory for speed. - SidebarAdvanced + // Setting mode: Recommended or Custom + ListModel { - anchors.fill: parent - visible: currentModeIndex == 1 - onShowTooltip: base.showTooltip(item, location, text) - onHideTooltip: base.hideTooltip() + id: modesListModel } - SidebarSimple + Component.onCompleted: { - anchors.fill: parent - visible: currentModeIndex != 1 - onShowTooltip: base.showTooltip(item, location, text) - onHideTooltip: base.hideTooltip() - } - } + modesListModel.append({ + text: catalog.i18nc("@title:tab", "Recommended"), + tooltipText: "%1

%2".arg(catalog.i18nc("@tooltip:title", "Recommended Print Setup")).arg(catalog.i18nc("@tooltip", "Print with the recommended settings for the selected printer, material and quality.")) + }) + modesListModel.append({ + text: catalog.i18nc("@title:tab", "Custom"), + tooltipText: "%1

%2".arg(catalog.i18nc("@tooltip:title", "Custom Print Setup")).arg(catalog.i18nc("@tooltip", "Print with finegrained control over every last bit of the slicing process.")) + }) - // Setting mode: Recommended or Custom - ListModel - { - id: modesListModel - } + var index = Math.round(UM.Preferences.getValue("cura/active_mode")) - Component.onCompleted: - { - modesListModel.append({ - text: catalog.i18nc("@title:tab", "Recommended"), - tooltipText: "%1

%2".arg(catalog.i18nc("@tooltip:title", "Recommended Print Setup")).arg(catalog.i18nc("@tooltip", "Print with the recommended settings for the selected printer, material and quality.")) - }) - modesListModel.append({ - text: catalog.i18nc("@title:tab", "Custom"), - tooltipText: "%1

%2".arg(catalog.i18nc("@tooltip:title", "Custom Print Setup")).arg(catalog.i18nc("@tooltip", "Print with finegrained control over every last bit of the slicing process.")) - }) - - var index = Math.round(UM.Preferences.getValue("cura/active_mode")) - - if(index != null && !isNaN(index)) - { - currentModeIndex = index; - } - else - { - currentModeIndex = 0; + if(index != null && !isNaN(index)) + { + currentModeIndex = index; + } + else + { + currentModeIndex = 0; + } } } } From 9d94b0d63eaf1db2b7e08a7ce7f4ae848df98f9e Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 12 Nov 2018 11:16:33 +0100 Subject: [PATCH 0165/1292] Rename input vs. output parsers Technically you could re-use the variable name but that is confusing. Contributes to issue CURA-5929. --- .../LegacyProfileReader.py | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/plugins/LegacyProfileReader/LegacyProfileReader.py b/plugins/LegacyProfileReader/LegacyProfileReader.py index cd577218d5..b5b2379b22 100644 --- a/plugins/LegacyProfileReader/LegacyProfileReader.py +++ b/plugins/LegacyProfileReader/LegacyProfileReader.py @@ -82,9 +82,9 @@ class LegacyProfileReader(ProfileReader): profile_id = container_registry.uniqueName("Imported Legacy Profile") profile = InstanceContainer(profile_id) # Create an empty profile. - parser = configparser.ConfigParser(interpolation = None) + input_parser = configparser.ConfigParser(interpolation = None) try: - parser.read([file_name]) # Parse the INI file. + input_parser.read([file_name]) # Parse the INI file. except Exception as e: Logger.log("e", "Unable to open legacy profile %s: %s", file_name, str(e)) return None @@ -92,7 +92,7 @@ class LegacyProfileReader(ProfileReader): # Legacy Cura saved the profile under the section "profile_N" where N is the ID of a machine, except when you export in which case it saves it in the section "profile". # Since importing multiple machine profiles is out of scope, just import the first section we find. section = "" - for found_section in parser.sections(): + for found_section in input_parser.sections(): if found_section.startswith("profile"): section = found_section break @@ -110,7 +110,7 @@ class LegacyProfileReader(ProfileReader): return None defaults = self.prepareDefaults(dict_of_doom) - legacy_settings = self.prepareLocals(parser, section, defaults) #Gets the settings from the legacy profile. + legacy_settings = self.prepareLocals(input_parser, section, defaults) #Gets the settings from the legacy profile. #Check the target version in the Dictionary of Doom with this application version. if "target_version" not in dict_of_doom: @@ -152,15 +152,15 @@ class LegacyProfileReader(ProfileReader): profile.setDirty(True) #Serialise and deserialise in order to perform the version upgrade. - parser = configparser.ConfigParser(interpolation = None) + output_parser = configparser.ConfigParser(interpolation = None) data = profile.serialize() - parser.read_string(data) - parser["general"]["version"] = "1" - if parser.has_section("values"): - parser["settings"] = parser["values"] - del parser["values"] + output_parser.read_string(data) + output_parser["general"]["version"] = "1" + if output_parser.has_section("values"): + output_parser["settings"] = output_parser["values"] + del output_parser["values"] stream = io.StringIO() - parser.write(stream) + output_parser.write(stream) data = stream.getvalue() profile.deserialize(data) From 88b57518d9770ea1406cd0a97fc975132588483c Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 12 Nov 2018 11:24:11 +0100 Subject: [PATCH 0166/1292] Fix codestyle CURA-5785 --- resources/qml/SidebarSimple.qml | 187 ++++++++++++++++---------------- 1 file changed, 94 insertions(+), 93 deletions(-) diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index 59980d1f55..affd1eb3a2 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -13,16 +13,18 @@ Item { id: base - signal showTooltip(Item item, point location, string text); - signal hideTooltip(); + signal showTooltip(Item item, point location, string text) + signal hideTooltip() + + property Action configureSettings - property Action configureSettings; - property variant minimumPrintTime: PrintInformation.minimumPrintTime; - property variant maximumPrintTime: PrintInformation.maximumPrintTime; property bool settingsEnabled: Cura.ExtruderManager.activeExtruderStackId || extrudersEnabledCount.properties.value == 1 - Component.onCompleted: PrintInformation.enabled = true - Component.onDestruction: PrintInformation.enabled = false - UM.I18nCatalog { id: catalog; name: "cura" } + + UM.I18nCatalog + { + id: catalog + name: "cura" + } ScrollView { @@ -313,7 +315,7 @@ Item } } - Rectangle + Item { id: rightArea width: @@ -324,7 +326,6 @@ Item return qualityModel.qualitySliderMarginRight - 10 } height: parent.height - color: "transparent" x: { if (qualityModel.availableTotalTicks == 0) @@ -450,10 +451,7 @@ Item var content = catalog.i18nc("@tooltip","A custom profile is currently active. To enable the quality slider, choose a default quality profile in Custom tab") base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), content) } - onExited: - { - base.hideTooltip(); - } + onExited: base.hideTooltip() } } @@ -575,7 +573,8 @@ Item } // We use a binding to make sure that after manually setting infillSlider.value it is still bound to the property provider - Binding { + Binding + { target: infillSlider property: "value" value: parseInt(infillDensity.properties.value) @@ -604,10 +603,12 @@ Item // set initial value from stack value: parseInt(infillDensity.properties.value) - onValueChanged: { + onValueChanged: + { // Don't round the value if it's already the same - if (parseInt(infillDensity.properties.value) == infillSlider.value) { + if (parseInt(infillDensity.properties.value) == infillSlider.value) + { return } @@ -631,7 +632,8 @@ Item style: SliderStyle { - groove: Rectangle { + groove: Rectangle + { id: groove implicitWidth: 200 * screenScaleFactor implicitHeight: 2 * screenScaleFactor @@ -639,8 +641,10 @@ Item radius: 1 } - handle: Item { - Rectangle { + handle: Item + { + Rectangle + { id: handleButton anchors.centerIn: parent color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") @@ -650,24 +654,27 @@ Item } } - tickmarks: Repeater { + tickmarks: Repeater + { id: repeater model: control.maximumValue / control.stepSize + 1 // check if a tick should be shown based on it's index and wether the infill density is a multiple of 10 (slider step size) - function shouldShowTick (index) { - if (index % 10 == 0) { + function shouldShowTick (index) + { + if (index % 10 == 0) + { return true } return false } - Rectangle { + Rectangle + { anchors.verticalCenter: parent.verticalCenter color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") width: 1 * screenScaleFactor height: 6 * screenScaleFactor - y: 0 x: Math.round(styleData.handleWidth / 2 + index * ((repeater.width - styleData.handleWidth) / (repeater.count-1))) visible: shouldShowTick(index) } @@ -693,8 +700,10 @@ Item model: infillModel anchors.fill: parent - function activeIndex () { - for (var i = 0; i < infillModel.count; i++) { + function activeIndex () + { + for (var i = 0; i < infillModel.count; i++) + { var density = Math.round(infillDensity.properties.value) var steps = Math.round(infillSteps.properties.value) var infillModelItem = infillModel.get(i) @@ -703,8 +712,8 @@ Item && density >= infillModelItem.percentageMin && density <= infillModelItem.percentageMax && steps >= infillModelItem.stepsMin - && steps <= infillModelItem.stepsMax - ){ + && steps <= infillModelItem.stepsMax) + { return i } } @@ -719,7 +728,8 @@ Item border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("quality_slider_unavailable") - UM.RecolorImage { + UM.RecolorImage + { anchors.fill: parent anchors.margins: 2 * screenScaleFactor sourceSize.width: width @@ -732,7 +742,8 @@ Item } // Gradual Support Infill Checkbox - CheckBox { + CheckBox + { id: enableGradualInfillCheckBox property alias _hovered: enableGradualInfillMouseArea.containsMouse @@ -745,7 +756,8 @@ Item visible: infillSteps.properties.enabled == "True" checked: parseInt(infillSteps.properties.value) > 0 - MouseArea { + MouseArea + { id: enableGradualInfillMouseArea anchors.fill: parent @@ -754,35 +766,37 @@ Item property var previousInfillDensity: parseInt(infillDensity.properties.value) - onClicked: { + onClicked: + { // Set to 90% only when enabling gradual infill var newInfillDensity; - if (parseInt(infillSteps.properties.value) == 0) { + if (parseInt(infillSteps.properties.value) == 0) + { previousInfillDensity = parseInt(infillDensity.properties.value) - newInfillDensity = 90; + newInfillDensity = 90 } else { - newInfillDensity = previousInfillDensity; + newInfillDensity = previousInfillDensity } Cura.MachineManager.setSettingForAllExtruders("infill_sparse_density", "value", String(newInfillDensity)) - var infill_steps_value = 0; + var infill_steps_value = 0 if (parseInt(infillSteps.properties.value) == 0) - infill_steps_value = 5; + { + infill_steps_value = 5 + } Cura.MachineManager.setSettingForAllExtruders("gradual_infill_steps", "value", infill_steps_value) } - onEntered: { - base.showTooltip(enableGradualInfillCheckBox, Qt.point(-infillCellRight.x, 0), + onEntered: base.showTooltip(enableGradualInfillCheckBox, Qt.point(-infillCellRight.x, 0), catalog.i18nc("@label", "Gradual infill will gradually increase the amount of infill towards the top.")) - } - onExited: { - base.hideTooltip() - } + onExited: base.hideTooltip() + } - Label { + Label + { id: gradualInfillLabel height: parent.height anchors.left: enableGradualInfillCheckBox.right @@ -855,9 +869,9 @@ Item anchors.rightMargin: UM.Theme.getSize("thick_margin").width anchors.verticalCenter: enableSupportCheckBox.verticalCenter - text: catalog.i18nc("@label", "Generate Support"); - font: UM.Theme.getFont("default"); - color: UM.Theme.getColor("text"); + text: catalog.i18nc("@label", "Generate Support") + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") elide: Text.ElideRight } @@ -869,32 +883,24 @@ Item anchors.top: enableSupportLabel.top anchors.left: infillCellRight.left - style: UM.Theme.styles.checkbox; + style: UM.Theme.styles.checkbox enabled: base.settingsEnabled visible: supportEnabled.properties.enabled == "True" - checked: supportEnabled.properties.value == "True"; + checked: supportEnabled.properties.value == "True" MouseArea { id: enableSupportMouseArea anchors.fill: parent hoverEnabled: true - enabled: true - onClicked: - { - // The value is a string "True" or "False" - supportEnabled.setPropertyValue("value", supportEnabled.properties.value != "True"); - } - onEntered: - { - base.showTooltip(enableSupportCheckBox, Qt.point(-enableSupportCheckBox.x, 0), - catalog.i18nc("@label", "Generate structures to support parts of the model which have overhangs. Without these structures, such parts would collapse during printing.")); - } - onExited: - { - base.hideTooltip(); - } + onClicked: supportEnabled.setPropertyValue("value", supportEnabled.properties.value != "True") + + onEntered: base.showTooltip(enableSupportCheckBox, Qt.point(-enableSupportCheckBox.x, 0), + catalog.i18nc("@label", "Generate structures to support parts of the model which have overhangs. Without these structures, such parts would collapse during printing.")) + + onExited: base.hideTooltip() + } } @@ -916,7 +922,7 @@ Item textRole: "text" // this solves that the combobox isn't populated in the first time Cura is started anchors.top: enableSupportCheckBox.top - //anchors.topMargin: ((supportEnabled.properties.value === "True") && (machineExtruderCount.properties.value > 1)) ? UM.Theme.getSize("thick_margin").height : 0 + anchors.left: enableSupportCheckBox.right anchors.leftMargin: Math.round(UM.Theme.getSize("thick_margin").width / 2) @@ -933,24 +939,21 @@ Item { if (supportExtruderNr.properties == null) { - return Cura.MachineManager.defaultExtruderPosition; + return Cura.MachineManager.defaultExtruderPosition } else { - var extruder = parseInt(supportExtruderNr.properties.value); + var extruder = parseInt(supportExtruderNr.properties.value) if ( extruder === -1) { - return Cura.MachineManager.defaultExtruderPosition; + return Cura.MachineManager.defaultExtruderPosition } return extruder; } } - onActivated: - { - // Send the extruder nr as a string. - supportExtruderNr.setPropertyValue("value", String(index)); - } + onActivated: supportExtruderNr.setPropertyValue("value", String(index)) + MouseArea { id: supportExtruderMouseArea @@ -963,17 +966,16 @@ Item base.showTooltip(supportExtruderCombobox, Qt.point(-supportExtruderCombobox.x, 0), catalog.i18nc("@label", "Select which extruder to use for support. This will build up supporting structures below the model to prevent the model from sagging or printing in mid air.")); } - onExited: - { - base.hideTooltip(); - } + onExited: base.hideTooltip() + } function updateCurrentColor() { - var current_extruder = extruderModel.get(currentIndex); - if (current_extruder !== undefined) { - supportExtruderCombobox.color_override = current_extruder.color; + var current_extruder = extruderModel.get(currentIndex) + if (current_extruder !== undefined) + { + supportExtruderCombobox.color_override = current_extruder.color } } @@ -989,7 +991,8 @@ Item color: UM.Theme.getColor("text") elide: Text.ElideRight - anchors { + anchors + { left: parent.left leftMargin: UM.Theme.getSize("thick_margin").width right: infillCellLeft.right @@ -1008,7 +1011,7 @@ Item anchors.left: infillCellRight.left //: Setting enable printing build-plate adhesion helper checkbox - style: UM.Theme.styles.checkbox; + style: UM.Theme.styles.checkbox enabled: base.settingsEnabled visible: platformAdhesionType.properties.enabled == "True" @@ -1022,29 +1025,27 @@ Item enabled: base.settingsEnabled onClicked: { - var adhesionType = "skirt"; + var adhesionType = "skirt" if(!parent.checked) { // Remove the "user" setting to see if the rest of the stack prescribes a brim or a raft - platformAdhesionType.removeFromContainer(0); - adhesionType = platformAdhesionType.properties.value; + platformAdhesionType.removeFromContainer(0) + adhesionType = platformAdhesionType.properties.value if(adhesionType == "skirt" || adhesionType == "none") { // If the rest of the stack doesn't prescribe an adhesion-type, default to a brim - adhesionType = "brim"; + adhesionType = "brim" } } - platformAdhesionType.setPropertyValue("value", adhesionType); + platformAdhesionType.setPropertyValue("value", adhesionType) } onEntered: { base.showTooltip(adhesionCheckBox, Qt.point(-adhesionCheckBox.x, 0), catalog.i18nc("@label", "Enable printing a brim or raft. This will add a flat area around or under your object which is easy to cut off afterwards.")); } - onExited: - { - base.hideTooltip(); - } + onExited: base.hideTooltip() + } } @@ -1163,6 +1164,6 @@ Item color: extruders.getItem(extruderNumber).color }) } - supportExtruderCombobox.updateCurrentColor(); + supportExtruderCombobox.updateCurrentColor() } } From 987ff1737ff11223ec986cf74d79a0d529f2c5dd Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 12 Nov 2018 11:27:54 +0100 Subject: [PATCH 0167/1292] Remove unused background from PrintSetupSelector CURA-5785 --- resources/qml/SidebarSimple.qml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index affd1eb3a2..5e723a3d70 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -33,11 +33,10 @@ Item style: UM.Theme.styles.scrollview flickableItem.flickableDirection: Flickable.VerticalFlick - Rectangle + Item { width: childrenRect.width height: childrenRect.height - color: UM.Theme.getColor("main_background") // // Quality profile From 6ad682b00db9e614ff40eb530133247744e02658 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 12 Nov 2018 12:02:49 +0100 Subject: [PATCH 0168/1292] Don't serialise legacy profile via Profile instance That profile instance was being explicitly set to version 1 (but then serialised as version 4) and then deserialised with upgrade, so the upgrade was thinking it was upgrading from version 1 to 4, but it was actually upgrading a file which was already at version 4. We shouldn't use the Profile() instance at all but just perform the upgrade on simple string data generated by the configparser. This also updates the format to the newest version (since that was easiest for me to reimplement) but we don't need to ever update this again because it gets passed through the version upgrade system, which upgrades it from version 4000005 to the latest version in the future. Contributes to issue CURA-5929. --- .../LegacyProfileReader.py | 50 ++++++++----------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/plugins/LegacyProfileReader/LegacyProfileReader.py b/plugins/LegacyProfileReader/LegacyProfileReader.py index b5b2379b22..b915242d55 100644 --- a/plugins/LegacyProfileReader/LegacyProfileReader.py +++ b/plugins/LegacyProfileReader/LegacyProfileReader.py @@ -80,7 +80,6 @@ class LegacyProfileReader(ProfileReader): Logger.log("i", "Importing legacy profile from file " + file_name + ".") container_registry = ContainerRegistry.getInstance() profile_id = container_registry.uniqueName("Imported Legacy Profile") - profile = InstanceContainer(profile_id) # Create an empty profile. input_parser = configparser.ConfigParser(interpolation = None) try: @@ -112,13 +111,11 @@ class LegacyProfileReader(ProfileReader): defaults = self.prepareDefaults(dict_of_doom) legacy_settings = self.prepareLocals(input_parser, section, defaults) #Gets the settings from the legacy profile. - #Check the target version in the Dictionary of Doom with this application version. - if "target_version" not in dict_of_doom: - Logger.log("e", "Dictionary of Doom has no target version. Is it the correct JSON file?") - return None - if InstanceContainer.Version != dict_of_doom["target_version"]: - Logger.log("e", "Dictionary of Doom of legacy profile reader (version %s) is not in sync with the current instance container version (version %s)!", dict_of_doom["target_version"], str(InstanceContainer.Version)) - return None + # Serialised format into version 4.5. Do NOT upgrade this, let the version upgrader handle it. + output_parser = configparser.ConfigParser(interpolation = None) + output_parser.add_section("general") + output_parser.add_section("metadata") + output_parser.add_section("values") if "translation" not in dict_of_doom: Logger.log("e", "Dictionary of Doom has no translation. Is it the correct JSON file?") @@ -127,7 +124,7 @@ class LegacyProfileReader(ProfileReader): quality_definition = current_printer_definition.getMetaDataEntry("quality_definition") if not quality_definition: quality_definition = current_printer_definition.getId() - profile.setDefinition(quality_definition) + output_parser["general"]["definition"] = quality_definition for new_setting in dict_of_doom["translation"]: # Evaluate all new settings that would get a value from the translations. old_setting_expression = dict_of_doom["translation"][new_setting] compiled = compile(old_setting_expression, new_setting, "eval") @@ -140,37 +137,34 @@ class LegacyProfileReader(ProfileReader): definitions = current_printer_definition.findDefinitions(key = new_setting) if definitions: if new_value != value_using_defaults and definitions[0].default_value != new_value: # Not equal to the default in the new Cura OR the default in the legacy Cura. - profile.setProperty(new_setting, "value", new_value) # Store the setting in the profile! + output_parser["values"][new_setting] = new_value # Store the setting in the profile! - if len(profile.getAllKeys()) == 0: + if len(output_parser["values"]) == 0: Logger.log("i", "A legacy profile was imported but everything evaluates to the defaults, creating an empty profile.") - profile.setMetaDataEntry("type", "profile") - # don't know what quality_type it is based on, so use "normal" by default - profile.setMetaDataEntry("quality_type", "normal") - profile.setName(profile_id) - profile.setDirty(True) + output_parser["general"]["version"] = "4" + output_parser["general"]["name"] = profile_id + output_parser["metadata"]["type"] = "quality_changes" + output_parser["metadata"]["quality_type"] = "normal" # Don't know what quality_type it is based on, so use "normal" by default. + output_parser["metadata"]["position"] = "0" # We only support single extrusion. + output_parser["metadata"]["setting_version"] = "5" # What the dictionary of doom is made for. - #Serialise and deserialise in order to perform the version upgrade. - output_parser = configparser.ConfigParser(interpolation = None) - data = profile.serialize() - output_parser.read_string(data) - output_parser["general"]["version"] = "1" - if output_parser.has_section("values"): - output_parser["settings"] = output_parser["values"] - del output_parser["values"] + # Serialise in order to perform the version upgrade. stream = io.StringIO() output_parser.write(stream) data = stream.getvalue() - profile.deserialize(data) - # The definition can get reset to fdmprinter during the deserialization's upgrade. Here we set the definition - # again. - profile.setDefinition(quality_definition) + profile = InstanceContainer(profile_id) + profile.deserialize(data) # Also performs the version upgrade. + profile.setDirty(True) #We need to return one extruder stack and one global stack. global_container_id = container_registry.uniqueName("Global Imported Legacy Profile") + # We duplicate the extruder profile into the global stack. + # This may introduce some settings that are global in the extruder stack and some settings that are per-extruder in the global stack. + # We don't care about that. The engine will ignore them anyway. global_profile = profile.duplicate(new_id = global_container_id, new_name = profile_id) #Needs to have the same name as the extruder profile. + del global_profile.getMetaData()["position"] # Has no position because it's global. global_profile.setDirty(True) profile_definition = "fdmprinter" From 6022ed0f2347001efb013cdbad7ba952fb532ab4 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 12 Nov 2018 12:06:00 +0100 Subject: [PATCH 0169/1292] Update target version in DoD There are no changes to these settings, luckily. This target version is now only here for documentation (like source_version was). It is no longer actually used by the code. Contributes to issue CURA-5929. --- plugins/LegacyProfileReader/DictionaryOfDoom.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/LegacyProfileReader/DictionaryOfDoom.json b/plugins/LegacyProfileReader/DictionaryOfDoom.json index 0be413dd2c..f65cc271d1 100644 --- a/plugins/LegacyProfileReader/DictionaryOfDoom.json +++ b/plugins/LegacyProfileReader/DictionaryOfDoom.json @@ -1,6 +1,6 @@ { "source_version": "15.04", - "target_version": 3, + "target_version": "4.5", "translation": { "machine_nozzle_size": "nozzle_size", From 27aff4e5da270f446e03545f69247f7e38abc3d3 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 12 Nov 2018 12:48:49 +0100 Subject: [PATCH 0170/1292] Fix typing issues Because this function now has typing, it's raising a load of issues with it. Contributes to issue CURA-5929. --- cura/Machines/QualityManager.py | 4 ++-- cura/Settings/CuraContainerRegistry.py | 24 ++++++++++--------- .../LegacyProfileReader.py | 2 +- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index fc8262de52..a784d17f0b 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -16,7 +16,7 @@ from .QualityGroup import QualityGroup from .QualityNode import QualityNode if TYPE_CHECKING: - from UM.Settings.DefinitionContainer import DefinitionContainer + from UM.Settings.Interfaces import DefinitionContainerInterface from cura.Settings.GlobalStack import GlobalStack from .QualityChangesGroup import QualityChangesGroup from cura.CuraApplication import CuraApplication @@ -538,7 +538,7 @@ class QualityManager(QObject): # Example: for an Ultimaker 3 Extended, it has "quality_definition = ultimaker3". This means Ultimaker 3 Extended # shares the same set of qualities profiles as Ultimaker 3. # -def getMachineDefinitionIDForQualitySearch(machine_definition: "DefinitionContainer", +def getMachineDefinitionIDForQualitySearch(machine_definition: "DefinitionContainerInterface", default_definition_id: str = "fdmprinter") -> str: machine_definition_id = default_definition_id if parseBool(machine_definition.getMetaDataEntry("has_machine_quality", False)): diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index 63277ebce5..9f44d075e0 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -10,6 +10,7 @@ from PyQt5.QtWidgets import QMessageBox from UM.Decorators import override from UM.Settings.ContainerFormatError import ContainerFormatError +from UM.Settings.Interfaces import ContainerInterface from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.ContainerStack import ContainerStack from UM.Settings.InstanceContainer import InstanceContainer @@ -27,7 +28,7 @@ from . import GlobalStack import cura.CuraApplication from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch -from cura.ReaderWriters.ProfileReader import NoProfileException +from cura.ReaderWriters.ProfileReader import NoProfileException, ProfileReader from UM.i18n import i18nCatalog catalog = i18nCatalog("cura") @@ -182,7 +183,7 @@ class CuraContainerRegistry(ContainerRegistry): for plugin_id, meta_data in self._getIOPlugins("profile_reader"): if meta_data["profile_reader"][0]["extension"] != extension: continue - profile_reader = plugin_registry.getPluginObject(plugin_id) + profile_reader = cast(ProfileReader, plugin_registry.getPluginObject(plugin_id)) try: profile_or_list = profile_reader.read(file_name) # Try to open the file with the profile reader. except NoProfileException: @@ -220,13 +221,13 @@ class CuraContainerRegistry(ContainerRegistry): # Make sure we have a profile_definition in the file: if profile_definition is None: break - machine_definition = self.findDefinitionContainers(id = profile_definition) - if not machine_definition: + machine_definitions = self.findDefinitionContainers(id = profile_definition) + if not machine_definitions: Logger.log("e", "Incorrect profile [%s]. Unknown machine type [%s]", file_name, profile_definition) return {"status": "error", "message": catalog.i18nc("@info:status Don't translate the XML tags !", "This profile {0} contains incorrect data, could not import it.", file_name) } - machine_definition = machine_definition[0] + machine_definition = machine_definitions[0] # Get the expected machine definition. # i.e.: We expect gcode for a UM2 Extended to be defined as normal UM2 gcode... @@ -273,11 +274,12 @@ class CuraContainerRegistry(ContainerRegistry): setting_value = global_profile.getProperty(qc_setting_key, "value") setting_definition = global_stack.getSettingDefinition(qc_setting_key) - new_instance = SettingInstance(setting_definition, profile) - new_instance.setProperty("value", setting_value) - new_instance.resetState() # Ensure that the state is not seen as a user state. - profile.addInstance(new_instance) - profile.setDirty(True) + if setting_definition is not None: + new_instance = SettingInstance(setting_definition, profile) + new_instance.setProperty("value", setting_value) + new_instance.resetState() # Ensure that the state is not seen as a user state. + profile.addInstance(new_instance) + profile.setDirty(True) global_profile.removeInstance(qc_setting_key, postpone_emit=True) extruder_profiles.append(profile) @@ -289,7 +291,7 @@ class CuraContainerRegistry(ContainerRegistry): for profile_index, profile in enumerate(profile_or_list): if profile_index == 0: # This is assumed to be the global profile - profile_id = (global_stack.getBottom().getId() + "_" + name_seed).lower().replace(" ", "_") + profile_id = (cast(ContainerInterface, global_stack.getBottom()).getId() + "_" + name_seed).lower().replace(" ", "_") elif profile_index < len(machine_extruders) + 1: # This is assumed to be an extruder profile diff --git a/plugins/LegacyProfileReader/LegacyProfileReader.py b/plugins/LegacyProfileReader/LegacyProfileReader.py index b915242d55..9a74c15082 100644 --- a/plugins/LegacyProfileReader/LegacyProfileReader.py +++ b/plugins/LegacyProfileReader/LegacyProfileReader.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 configparser # For reading the legacy profile INI files. From 6d1b64465a8142c7d9e52b4d3a48ac4e5438cf96 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 12 Nov 2018 12:50:18 +0100 Subject: [PATCH 0171/1292] Fix URL in error message Contributes to issue CURA-5929. --- cura/Settings/ContainerManager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 3c1e09f086..133e04e8fc 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -422,10 +422,10 @@ class ContainerManager(QObject): @pyqtSlot(QUrl, result = "QVariantMap") def importProfile(self, file_url: QUrl) -> Dict[str, str]: if not file_url.isValid(): - return {"status": "error", "message": catalog.i18nc("@info:status", "Invalid file URL:") + " " + file_url} + return {"status": "error", "message": catalog.i18nc("@info:status", "Invalid file URL:") + " " + str(file_url)} path = file_url.toLocalFile() if not path: - return {"status": "error", "message": catalog.i18nc("@info:status", "Invalid file URL:") + " " + file_url} + return {"status": "error", "message": catalog.i18nc("@info:status", "Invalid file URL:") + " " + str(file_url)} return self._container_registry.importProfile(path) @pyqtSlot(QObject, QUrl, str) From bbbb08c793e45b49e0421daf900afdc2bda31a81 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 12 Nov 2018 13:02:28 +0100 Subject: [PATCH 0172/1292] Add test for prepareDefaults Contributes to issue CURA-5929. --- .../tests/TestLegacyProfileReader.py | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py diff --git a/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py b/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py new file mode 100644 index 0000000000..9f6ffe4f24 --- /dev/null +++ b/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py @@ -0,0 +1,31 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +import pytest #To register tests with. + +from LegacyProfileReader import LegacyProfileReader #The module we're testing. + +@pytest.fixture +def legacy_profile_reader(): + return LegacyProfileReader() + +test_prepareDefaultsData = [ + { + "defaults": { + "foo": "bar" + }, + "cheese": "delicious" + }, + { + "cat": "fluffy", + "dog": "floofy" + } +] + +@pytest.mark.parametrize("input", test_prepareDefaultsData) +def test_prepareDefaults(legacy_profile_reader, input): + output = legacy_profile_reader.prepareDefaults(input) + if "defaults" in input: + assert input["defaults"] == output + else: + assert output == {} \ No newline at end of file From ca637338270e12c7dd32e20e21dd005eae2066cb Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 12 Nov 2018 13:06:12 +0100 Subject: [PATCH 0173/1292] Updated header of the settingbar CURA-5785 --- resources/qml/IconWithText.qml | 60 ++++++++++++++++++ resources/qml/PrintSetupSelector.qml | 94 ++++++++++++++++++++++++---- 2 files changed, 141 insertions(+), 13 deletions(-) create mode 100644 resources/qml/IconWithText.qml diff --git a/resources/qml/IconWithText.qml b/resources/qml/IconWithText.qml new file mode 100644 index 0000000000..0b0feea821 --- /dev/null +++ b/resources/qml/IconWithText.qml @@ -0,0 +1,60 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.0 +import QtQuick.Layouts 1.3 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +// Reusable component that holds an (re-colorable) icon on the left with some text on the right +Item +{ + property alias iconColor: icon.color + property alias source: icon.source + property alias text: label.text + + implicitWidth: icon.width + 100 + implicitHeight: icon.height + + Component.onCompleted: print(label.contentWidth) + + UM.RecolorImage + { + id: icon + width: UM.Theme.getSize("section_icon").width + height: UM.Theme.getSize("section_icon").height + + sourceSize.width: width + sourceSize.height: height + color: "black" + + anchors + { + left: parent.left + verticalCenter: parent.verticalCenter + } + + } + + Label + { + id: label + height: contentHeight + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + renderType: Text.NativeRendering + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + anchors + { + left: icon.right + right: parent.right + top: parent.top + bottom: parent.bottom + rightMargin: 0 + margins: UM.Theme.getSize("narrow_margin").width + } + } +} \ No newline at end of file diff --git a/resources/qml/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector.qml index 7a415b1e2e..2daf8adb4b 100644 --- a/resources/qml/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector.qml @@ -18,12 +18,19 @@ Cura.ExpandableComponent property int currentModeIndex: -1 property bool hideSettings: PrintInformation.preSliced - UM.I18nCatalog { id: catalog; name: "cura"} + property string enabledText: catalog.i18nc("@label", "On") + property string disabledText: catalog.i18nc("@label", "Off") // This widget doesn't show tooltips by itself. Instead it emits signals so others can do something with it. signal showTooltip(Item item, point location, string text) signal hideTooltip() + UM.I18nCatalog + { + id: catalog + name: "cura" + } + Timer { id: tooltipDelayTimer @@ -32,18 +39,82 @@ Cura.ExpandableComponent property var item property string text - onTriggered: + onTriggered: base.showTooltip(base, {x: 0, y: item.y}, text) + } + + onCurrentModeIndexChanged: UM.Preferences.setValue("cura/active_mode", currentModeIndex) + + headerItem: Row + { + anchors.fill: parent + + IconWithText { - base.showTooltip(base, {x: 0, y: item.y}, text); + source: UM.Theme.getIcon("category_layer_height") + text: Cura.MachineManager.activeQualityOrQualityChangesName + " " + layerHeight.properties.value + "mm" + width: parent.width / 4 + height: parent.height + + UM.SettingPropertyProvider + { + id: layerHeight + containerStackId: Cura.MachineManager.activeStackId + key: "layer_height" + watchedProperties: ["value"] + } + } + + IconWithText + { + source: UM.Theme.getIcon("category_infill") + text: parseInt(infillDensity.properties.value) + "%" + width: parent.width / 4 + height: parent.height + + UM.SettingPropertyProvider + { + id: infillDensity + containerStackId: Cura.MachineManager.activeStackId + key: "infill_sparse_density" + watchedProperties: ["value"] + } + } + + IconWithText + { + source: UM.Theme.getIcon("category_support") + text: supportEnabled.properties.value == "True" ? enabledText : disabledText + width: parent.width / 4 + height: parent.height + + UM.SettingPropertyProvider + { + id: supportEnabled + containerStack: Cura.MachineManager.activeMachine + key: "support_enable" + watchedProperties: ["value"] + } + } + + IconWithText + { + source: UM.Theme.getIcon("category_adhesion") + text: platformAdhesionType.properties.value != "skirt" && platformAdhesionType.properties.value != "none" ? enabledText : disabledText + width: parent.width / 4 + height: parent.height + + UM.SettingPropertyProvider + { + id: platformAdhesionType + containerStack: Cura.MachineManager.activeMachine + key: "adhesion_type" + watchedProperties: [ "value"] + } } } - onCurrentModeIndexChanged: - { - UM.Preferences.setValue("cura/active_mode", currentModeIndex); - } - headerItem: Label + /*Label { id: settingsModeLabel text: !hideSettings ? catalog.i18nc("@label:listbox", "Print Setup") : catalog.i18nc("@label:listbox", "Print Setup disabled\nG-code files cannot be modified") @@ -51,16 +122,13 @@ Cura.ExpandableComponent anchors { - left: parent.left - top: parent.top - margins: UM.Theme.getSize("thick_margin").width + fill: parent } - width: Math.round(parent.width * 0.45) height: contentHeight font: UM.Theme.getFont("large") color: UM.Theme.getColor("text") - } + }*/ popupItem: Item { From 54685c983acf1e1d5d24425b67d7d5f5e7a2c3ff Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 12 Nov 2018 13:29:21 +0100 Subject: [PATCH 0174/1292] Make PrintSetupSelector use layout instead of fixed width This makes the components autoscale a bit when needed. CURA-5785 --- resources/qml/IconWithText.qml | 22 ++++++++++++++++------ resources/qml/PrintSetupSelector.qml | 15 ++++----------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/resources/qml/IconWithText.qml b/resources/qml/IconWithText.qml index 0b0feea821..d19c7e3899 100644 --- a/resources/qml/IconWithText.qml +++ b/resources/qml/IconWithText.qml @@ -8,18 +8,29 @@ import QtQuick.Layouts 1.3 import UM 1.2 as UM import Cura 1.0 as Cura -// Reusable component that holds an (re-colorable) icon on the left with some text on the right +// Reusable component that holds an (re-colorable) icon on the left with some text on the right. +// This component is also designed to be used with layouts. It will use the width of the text + icon as preferred width +// It sets the icon size + half of the content as it's minium width (in which case it will elide the text) Item { property alias iconColor: icon.color property alias source: icon.source property alias text: label.text + property real margin: UM.Theme.getSize("narrow_margin").width + + // These properties can be used in combination with layouts. + readonly property real contentWidth: icon.width + margin + label.contentWidth + readonly property real minContentWidth: icon.width + margin + 0.5 * label.contentWidth + + Layout.minimumWidth: minContentWidth + Layout.preferredWidth: contentWidth + Layout.fillHeight: true + Layout.fillWidth: true + implicitWidth: icon.width + 100 implicitHeight: icon.height - Component.onCompleted: print(label.contentWidth) - UM.RecolorImage { id: icon @@ -35,18 +46,17 @@ Item left: parent.left verticalCenter: parent.verticalCenter } - } Label { id: label - height: contentHeight font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") renderType: Text.NativeRendering elide: Text.ElideRight verticalAlignment: Text.AlignVCenter + anchors { left: icon.right @@ -54,7 +64,7 @@ Item top: parent.top bottom: parent.bottom rightMargin: 0 - margins: UM.Theme.getSize("narrow_margin").width + margins: margin } } } \ No newline at end of file diff --git a/resources/qml/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector.qml index 2daf8adb4b..4a8ebda2b3 100644 --- a/resources/qml/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector.qml @@ -18,8 +18,8 @@ Cura.ExpandableComponent property int currentModeIndex: -1 property bool hideSettings: PrintInformation.preSliced - property string enabledText: catalog.i18nc("@label", "On") - property string disabledText: catalog.i18nc("@label", "Off") + property string enabledText: catalog.i18nc("@label:Should be short", "On") + property string disabledText: catalog.i18nc("@label:Should be short", "Off") // This widget doesn't show tooltips by itself. Instead it emits signals so others can do something with it. signal showTooltip(Item item, point location, string text) @@ -44,7 +44,7 @@ Cura.ExpandableComponent onCurrentModeIndexChanged: UM.Preferences.setValue("cura/active_mode", currentModeIndex) - headerItem: Row + headerItem: RowLayout { anchors.fill: parent @@ -52,8 +52,6 @@ Cura.ExpandableComponent { source: UM.Theme.getIcon("category_layer_height") text: Cura.MachineManager.activeQualityOrQualityChangesName + " " + layerHeight.properties.value + "mm" - width: parent.width / 4 - height: parent.height UM.SettingPropertyProvider { @@ -68,8 +66,6 @@ Cura.ExpandableComponent { source: UM.Theme.getIcon("category_infill") text: parseInt(infillDensity.properties.value) + "%" - width: parent.width / 4 - height: parent.height UM.SettingPropertyProvider { @@ -84,8 +80,7 @@ Cura.ExpandableComponent { source: UM.Theme.getIcon("category_support") text: supportEnabled.properties.value == "True" ? enabledText : disabledText - width: parent.width / 4 - height: parent.height + UM.SettingPropertyProvider { @@ -100,8 +95,6 @@ Cura.ExpandableComponent { source: UM.Theme.getIcon("category_adhesion") text: platformAdhesionType.properties.value != "skirt" && platformAdhesionType.properties.value != "none" ? enabledText : disabledText - width: parent.width / 4 - height: parent.height UM.SettingPropertyProvider { From 8d49d5a1b10fe1f6e6f1459fb0e602df1ab66bec Mon Sep 17 00:00:00 2001 From: THeijmans Date: Mon, 12 Nov 2018 13:29:51 +0100 Subject: [PATCH 0175/1292] CPE and CPE+ Comb retractions In this commit I changed all CPE and CPE+ profiles to have a 50mm combing max distance without retraction. This should decrease blobs caused by combing long distances. I also reverted the CPE infill back to triangles, as we now connect this infill type as well. --- .../ultimaker_s5/um_s5_aa0.25_CPE_Normal_Quality.inst.cfg | 1 + .../quality/ultimaker_s5/um_s5_aa0.4_CPEP_Draft_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.4_CPEP_Fast_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.4_CPEP_High_Quality.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.4_CPEP_Normal_Quality.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.4_CPE_Draft_Print.inst.cfg | 3 ++- .../quality/ultimaker_s5/um_s5_aa0.4_CPE_Fast_Print.inst.cfg | 3 ++- .../quality/ultimaker_s5/um_s5_aa0.4_CPE_High_Quality.inst.cfg | 3 ++- .../ultimaker_s5/um_s5_aa0.4_CPE_Normal_Quality.inst.cfg | 3 ++- .../um_s5_aa0.4_aluminum_CPEP_Draft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Fast_Print.inst.cfg | 2 +- .../um_s5_aa0.4_aluminum_CPEP_High_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_aluminum_CPEP_Normal_Quality.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Draft_Print.inst.cfg | 3 ++- .../ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Fast_Print.inst.cfg | 3 ++- .../um_s5_aa0.4_aluminum_CPE_High_Quality.inst.cfg | 3 ++- .../um_s5_aa0.4_aluminum_CPE_Normal_Quality.inst.cfg | 3 ++- .../quality/ultimaker_s5/um_s5_aa0.8_CPEP_Fast_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.8_CPEP_Superdraft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.8_CPEP_Verydraft_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.8_CPE_Draft_Print.inst.cfg | 1 + .../ultimaker_s5/um_s5_aa0.8_CPE_Superdraft_Print.inst.cfg | 1 + .../ultimaker_s5/um_s5_aa0.8_CPE_Verydraft_Print.inst.cfg | 1 + .../ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Fast_Print.inst.cfg | 2 +- .../um_s5_aa0.8_aluminum_CPEP_Superdraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_aluminum_CPEP_Verydraft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Draft_Print.inst.cfg | 1 + .../um_s5_aa0.8_aluminum_CPE_Superdraft_Print.inst.cfg | 1 + .../um_s5_aa0.8_aluminum_CPE_Verydraft_Print.inst.cfg | 1 + 29 files changed, 37 insertions(+), 22 deletions(-) diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.25_CPE_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.25_CPE_Normal_Quality.inst.cfg index 2068ed51c0..c15311d104 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.25_CPE_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.25_CPE_Normal_Quality.inst.cfg @@ -12,6 +12,7 @@ material = generic_cpe variant = AA 0.25 [values] +retraction_combing_max_distance = 50 retraction_extrusion_window = 0.5 speed_infill = =math.ceil(speed_print * 40 / 55) speed_topbottom = =math.ceil(speed_print * 30 / 55) diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Draft_Print.inst.cfg index 421fcdf095..627302e0ab 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Draft_Print.inst.cfg @@ -29,7 +29,7 @@ material_print_temperature_layer_0 = =material_print_temperature multiple_mesh_overlap = 0 prime_tower_enable = True prime_tower_wipe_enabled = True -retraction_combing = off +retraction_combing_max_distance = 50 retraction_extrusion_window = 1 retraction_hop = 0.2 retraction_hop_enabled = False diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Fast_Print.inst.cfg index 536c6c97b8..cda8d85211 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Fast_Print.inst.cfg @@ -29,7 +29,7 @@ material_print_temperature_layer_0 = =material_print_temperature multiple_mesh_overlap = 0 prime_tower_enable = True prime_tower_wipe_enabled = True -retraction_combing = off +retraction_combing_max_distance = 50 retraction_extrusion_window = 1 retraction_hop = 0.2 retraction_hop_enabled = False diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_High_Quality.inst.cfg index 77182c21e1..3ce76bf6be 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_High_Quality.inst.cfg @@ -31,7 +31,7 @@ material_print_temperature_layer_0 = =material_print_temperature multiple_mesh_overlap = 0 prime_tower_enable = True prime_tower_wipe_enabled = True -retraction_combing = off +retraction_combing_max_distance = 50 retraction_extrusion_window = 1 retraction_hop = 0.2 retraction_hop_enabled = False diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Normal_Quality.inst.cfg index d779baf315..d402b663c6 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Normal_Quality.inst.cfg @@ -31,7 +31,7 @@ material_print_temperature_layer_0 = =material_print_temperature multiple_mesh_overlap = 0 prime_tower_enable = True prime_tower_wipe_enabled = True -retraction_combing = off +retraction_combing_max_distance = 50 retraction_extrusion_window = 1 retraction_hop = 0.2 retraction_hop_enabled = False diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Draft_Print.inst.cfg index c51e5652e1..505cd952d2 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Draft_Print.inst.cfg @@ -15,6 +15,7 @@ variant = AA 0.4 material_print_temperature = =default_material_print_temperature + 10 material_initial_print_temperature = =material_print_temperature - 5 material_final_print_temperature = =material_print_temperature - 10 +retraction_combing_max_distance = 50 skin_overlap = 20 speed_print = 60 speed_layer_0 = =math.ceil(speed_print * 20 / 60) @@ -24,5 +25,5 @@ speed_wall_0 = =math.ceil(speed_wall * 35 / 45) wall_thickness = 1 -infill_pattern = zigzag +infill_pattern = triangles speed_infill = =math.ceil(speed_print * 50 / 60) diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Fast_Print.inst.cfg index b80d3ccf22..cc5df0abb9 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Fast_Print.inst.cfg @@ -16,11 +16,12 @@ cool_min_speed = 7 material_print_temperature = =default_material_print_temperature + 5 material_initial_print_temperature = =material_print_temperature - 5 material_final_print_temperature = =material_print_temperature - 10 +retraction_combing_max_distance = 50 speed_print = 60 speed_layer_0 = =math.ceil(speed_print * 20 / 60) speed_topbottom = =math.ceil(speed_print * 30 / 60) speed_wall = =math.ceil(speed_print * 40 / 60) speed_wall_0 = =math.ceil(speed_wall * 30 / 40) -infill_pattern = zigzag +infill_pattern = triangles speed_infill = =math.ceil(speed_print * 50 / 60) \ No newline at end of file diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_High_Quality.inst.cfg index c90eedaec3..c81dc0f5a7 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_High_Quality.inst.cfg @@ -18,10 +18,11 @@ machine_nozzle_heat_up_speed = 1.5 material_print_temperature = =default_material_print_temperature - 5 material_initial_print_temperature = =material_print_temperature - 5 material_final_print_temperature = =material_print_temperature - 10 +retraction_combing_max_distance = 50 speed_print = 50 speed_layer_0 = =math.ceil(speed_print * 20 / 50) speed_topbottom = =math.ceil(speed_print * 30 / 50) speed_wall = =math.ceil(speed_print * 30 / 50) -infill_pattern = zigzag +infill_pattern = triangles speed_infill = =math.ceil(speed_print * 40 / 50) \ No newline at end of file diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Normal_Quality.inst.cfg index e098b0ffb4..7d29f8fb7c 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Normal_Quality.inst.cfg @@ -16,10 +16,11 @@ machine_nozzle_cool_down_speed = 0.85 machine_nozzle_heat_up_speed = 1.5 material_initial_print_temperature = =material_print_temperature - 5 material_final_print_temperature = =material_print_temperature - 10 +retraction_combing_max_distance = 50 speed_print = 55 speed_layer_0 = =math.ceil(speed_print * 20 / 55) speed_topbottom = =math.ceil(speed_print * 30 / 55) speed_wall = =math.ceil(speed_print * 30 / 55) -infill_pattern = zigzag +infill_pattern = triangles speed_infill = =math.ceil(speed_print * 45 / 55) \ No newline at end of file diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Draft_Print.inst.cfg index 46e3483a6a..4a55f5d24c 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Draft_Print.inst.cfg @@ -30,7 +30,7 @@ material_print_temperature_layer_0 = =material_print_temperature multiple_mesh_overlap = 0 prime_tower_enable = True prime_tower_wipe_enabled = True -retraction_combing = off +retraction_combing_max_distance = 50 retraction_extrusion_window = 1 retraction_hop = 0.2 retraction_hop_enabled = False diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Fast_Print.inst.cfg index 5c235b656a..730e058212 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Fast_Print.inst.cfg @@ -30,7 +30,7 @@ material_print_temperature_layer_0 = =material_print_temperature multiple_mesh_overlap = 0 prime_tower_enable = True prime_tower_wipe_enabled = True -retraction_combing = off +retraction_combing_max_distance = 50 retraction_extrusion_window = 1 retraction_hop = 0.2 retraction_hop_enabled = False diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_High_Quality.inst.cfg index 326a730fe4..e6921e63d8 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_High_Quality.inst.cfg @@ -32,7 +32,7 @@ material_print_temperature_layer_0 = =material_print_temperature multiple_mesh_overlap = 0 prime_tower_enable = True prime_tower_wipe_enabled = True -retraction_combing = off +retraction_combing_max_distance = 50 retraction_extrusion_window = 1 retraction_hop = 0.2 retraction_hop_enabled = False diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Normal_Quality.inst.cfg index d40b2db90e..a4eec45e38 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Normal_Quality.inst.cfg @@ -32,7 +32,7 @@ material_print_temperature_layer_0 = =material_print_temperature multiple_mesh_overlap = 0 prime_tower_enable = True prime_tower_wipe_enabled = True -retraction_combing = off +retraction_combing_max_distance = 50 retraction_extrusion_window = 1 retraction_hop = 0.2 retraction_hop_enabled = False diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Draft_Print.inst.cfg index c812066e0c..4f085f10a6 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Draft_Print.inst.cfg @@ -16,6 +16,7 @@ buildplate = Aluminum material_print_temperature = =default_material_print_temperature + 10 material_initial_print_temperature = =material_print_temperature - 5 material_final_print_temperature = =material_print_temperature - 10 +retraction_combing_max_distance = 50 skin_overlap = 20 speed_print = 60 speed_layer_0 = 20 @@ -25,7 +26,7 @@ speed_wall_0 = =math.ceil(speed_wall * 35 / 45) wall_thickness = 1 -infill_pattern = zigzag +infill_pattern = triangles speed_infill = =math.ceil(speed_print * 50 / 60) prime_tower_purge_volume = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Fast_Print.inst.cfg index ef634316da..2580bf952d 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Fast_Print.inst.cfg @@ -17,13 +17,14 @@ cool_min_speed = 7 material_print_temperature = =default_material_print_temperature + 5 material_initial_print_temperature = =material_print_temperature - 5 material_final_print_temperature = =material_print_temperature - 10 +retraction_combing_max_distance = 50 speed_print = 60 speed_layer_0 = 20 speed_topbottom = =math.ceil(speed_print * 30 / 60) speed_wall = =math.ceil(speed_print * 40 / 60) speed_wall_0 = =math.ceil(speed_wall * 30 / 40) -infill_pattern = zigzag +infill_pattern = triangles speed_infill = =math.ceil(speed_print * 50 / 60) prime_tower_purge_volume = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_High_Quality.inst.cfg index cda97e6ab3..d6f07c37a5 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_High_Quality.inst.cfg @@ -19,12 +19,13 @@ machine_nozzle_heat_up_speed = 1.5 material_print_temperature = =default_material_print_temperature - 5 material_initial_print_temperature = =material_print_temperature - 5 material_final_print_temperature = =material_print_temperature - 10 +retraction_combing_max_distance = 50 speed_print = 50 speed_layer_0 = 20 speed_topbottom = =math.ceil(speed_print * 30 / 50) speed_wall = =math.ceil(speed_print * 30 / 50) -infill_pattern = zigzag +infill_pattern = triangles speed_infill = =math.ceil(speed_print * 40 / 50) prime_tower_purge_volume = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Normal_Quality.inst.cfg index 5a75f3b6e3..6032ff3845 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Normal_Quality.inst.cfg @@ -17,12 +17,13 @@ machine_nozzle_cool_down_speed = 0.85 machine_nozzle_heat_up_speed = 1.5 material_initial_print_temperature = =material_print_temperature - 5 material_final_print_temperature = =material_print_temperature - 10 +retraction_combing_max_distance = 50 speed_print = 55 speed_layer_0 = 20 speed_topbottom = =math.ceil(speed_print * 30 / 55) speed_wall = =math.ceil(speed_print * 30 / 55) -infill_pattern = zigzag +infill_pattern = triangles speed_infill = =math.ceil(speed_print * 45 / 55) prime_tower_purge_volume = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Fast_Print.inst.cfg index e78006689b..b855eb2c8b 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Fast_Print.inst.cfg @@ -22,7 +22,7 @@ material_print_temperature = =default_material_print_temperature - 10 material_print_temperature_layer_0 = =material_print_temperature material_standby_temperature = 100 prime_tower_enable = True -retraction_combing = off +retraction_combing_max_distance = 50 retraction_hop = 0.1 retraction_hop_enabled = False skin_overlap = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Superdraft_Print.inst.cfg index c6d0962157..d74711e8cf 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Superdraft_Print.inst.cfg @@ -22,7 +22,7 @@ material_print_temperature = =default_material_print_temperature - 5 material_print_temperature_layer_0 = =material_print_temperature material_standby_temperature = 100 prime_tower_enable = True -retraction_combing = off +retraction_combing_max_distance = 50 retraction_hop = 0.1 retraction_hop_enabled = False skin_overlap = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Verydraft_Print.inst.cfg index b80f773594..b65a7ff93c 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Verydraft_Print.inst.cfg @@ -22,7 +22,7 @@ material_print_temperature = =default_material_print_temperature - 7 material_print_temperature_layer_0 = =material_print_temperature material_standby_temperature = 100 prime_tower_enable = True -retraction_combing = off +retraction_combing_max_distance = 50 retraction_hop = 0.1 retraction_hop_enabled = False skin_overlap = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Draft_Print.inst.cfg index 532aacabf7..7cb69ba3eb 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Draft_Print.inst.cfg @@ -17,6 +17,7 @@ line_width = =machine_nozzle_size * 0.875 material_print_temperature = =default_material_print_temperature + 15 material_standby_temperature = 100 prime_tower_enable = True +retraction_combing_max_distance = 50 speed_print = 40 speed_topbottom = =math.ceil(speed_print * 25 / 40) speed_wall = =math.ceil(speed_print * 30 / 40) diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Superdraft_Print.inst.cfg index 55b9ae8315..6c323fe602 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Superdraft_Print.inst.cfg @@ -17,6 +17,7 @@ line_width = =machine_nozzle_size * 0.875 material_print_temperature = =default_material_print_temperature + 20 material_standby_temperature = 100 prime_tower_enable = True +retraction_combing_max_distance = 50 speed_print = 45 speed_topbottom = =math.ceil(speed_print * 30 / 45) speed_wall = =math.ceil(speed_print * 40 / 45) diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Verydraft_Print.inst.cfg index 01761062a4..a0380ecc0e 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Verydraft_Print.inst.cfg @@ -17,6 +17,7 @@ line_width = =machine_nozzle_size * 0.875 material_print_temperature = =default_material_print_temperature + 17 material_standby_temperature = 100 prime_tower_enable = True +retraction_combing_max_distance = 50 speed_print = 40 speed_topbottom = =math.ceil(speed_print * 25 / 40) speed_wall = =math.ceil(speed_print * 30 / 40) diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Fast_Print.inst.cfg index 3e74390840..c01f9b1ff1 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Fast_Print.inst.cfg @@ -23,7 +23,7 @@ material_print_temperature = =default_material_print_temperature - 10 material_print_temperature_layer_0 = =material_print_temperature material_standby_temperature = 100 prime_tower_enable = True -retraction_combing = off +retraction_combing_max_distance = 50 retraction_hop = 0.1 retraction_hop_enabled = False skin_overlap = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Superdraft_Print.inst.cfg index 4c1b807430..b9c9ef6611 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Superdraft_Print.inst.cfg @@ -23,7 +23,7 @@ material_print_temperature = =default_material_print_temperature - 5 material_print_temperature_layer_0 = =material_print_temperature material_standby_temperature = 100 prime_tower_enable = True -retraction_combing = off +retraction_combing_max_distance = 50 retraction_hop = 0.1 retraction_hop_enabled = False skin_overlap = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Verydraft_Print.inst.cfg index 11aefc90cd..be2cc62b08 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Verydraft_Print.inst.cfg @@ -23,7 +23,7 @@ material_print_temperature = =default_material_print_temperature - 7 material_print_temperature_layer_0 = =material_print_temperature material_standby_temperature = 100 prime_tower_enable = True -retraction_combing = off +retraction_combing_max_distance = 50 retraction_hop = 0.1 retraction_hop_enabled = False skin_overlap = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Draft_Print.inst.cfg index 80c0585061..0d0ed8f8b2 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Draft_Print.inst.cfg @@ -18,6 +18,7 @@ line_width = =machine_nozzle_size * 0.875 material_print_temperature = =default_material_print_temperature + 15 material_standby_temperature = 100 prime_tower_enable = True +retraction_combing_max_distance = 50 speed_print = 40 speed_topbottom = =math.ceil(speed_print * 25 / 40) speed_wall = =math.ceil(speed_print * 30 / 40) diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Superdraft_Print.inst.cfg index 5dcc454173..a163e0c735 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Superdraft_Print.inst.cfg @@ -18,6 +18,7 @@ line_width = =machine_nozzle_size * 0.875 material_print_temperature = =default_material_print_temperature + 20 material_standby_temperature = 100 prime_tower_enable = True +retraction_combing_max_distance = 50 speed_print = 45 speed_topbottom = =math.ceil(speed_print * 30 / 45) speed_wall = =math.ceil(speed_print * 40 / 45) diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Verydraft_Print.inst.cfg index 8423e109e8..2137cf740b 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Verydraft_Print.inst.cfg @@ -18,6 +18,7 @@ line_width = =machine_nozzle_size * 0.875 material_print_temperature = =default_material_print_temperature + 17 material_standby_temperature = 100 prime_tower_enable = True +retraction_combing_max_distance = 50 speed_print = 40 speed_topbottom = =math.ceil(speed_print * 25 / 40) speed_wall = =math.ceil(speed_print * 30 / 40) From 0bf7bf4cbe5f242c6f520d947064631bb5dd7317 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 12 Nov 2018 13:33:44 +0100 Subject: [PATCH 0176/1292] Fix handling dictionaries without 'defaults' section According to the test, this should return an empty dict then. Contributes to issue CURA-5929. --- plugins/LegacyProfileReader/LegacyProfileReader.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/plugins/LegacyProfileReader/LegacyProfileReader.py b/plugins/LegacyProfileReader/LegacyProfileReader.py index 9a74c15082..7974bbe829 100644 --- a/plugins/LegacyProfileReader/LegacyProfileReader.py +++ b/plugins/LegacyProfileReader/LegacyProfileReader.py @@ -6,6 +6,7 @@ import io import json # For reading the Dictionary of Doom. import math # For mathematical operations included in the Dictionary of Doom. import os.path # For concatenating the path to the plugin and the relative path to the Dictionary of Doom. +from typing import Dict from UM.Application import Application # To get the machine manager to create the new profile in. from UM.Logger import Logger # Logging errors. @@ -33,10 +34,11 @@ class LegacyProfileReader(ProfileReader): # \param json The JSON file to load the default setting values from. This # should not be a URL but a pre-loaded JSON handle. # \return A dictionary of the default values of the legacy Cura version. - def prepareDefaults(self, json): + def prepareDefaults(self, json: Dict[str, Dict[str, str]]) -> Dict[str, str]: defaults = {} - for key in json["defaults"]: # We have to copy over all defaults from the JSON handle to a normal dict. - defaults[key] = json["defaults"][key] + if "defaults" in json: + for key in json["defaults"]: # We have to copy over all defaults from the JSON handle to a normal dict. + defaults[key] = json["defaults"][key] return defaults ## Prepares the local variables that can be used in evaluation of computing From 91e8c177fe2c7b999d7724112c4bcb71d9e8912b Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 12 Nov 2018 13:35:18 +0100 Subject: [PATCH 0177/1292] Add test for prepareLocal Contributes to issue CURA-5929. --- .../tests/TestLegacyProfileReader.py | 43 +++++++++++++++++-- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py b/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py index 9f6ffe4f24..f54939e884 100644 --- a/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py +++ b/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py @@ -1,9 +1,10 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -import pytest #To register tests with. +import configparser # An input for some functions we're testing. +import pytest # To register tests with. -from LegacyProfileReader import LegacyProfileReader #The module we're testing. +from LegacyProfileReader import LegacyProfileReader # The module we're testing. @pytest.fixture def legacy_profile_reader(): @@ -11,7 +12,8 @@ def legacy_profile_reader(): test_prepareDefaultsData = [ { - "defaults": { + "defaults": + { "foo": "bar" }, "cheese": "delicious" @@ -28,4 +30,37 @@ def test_prepareDefaults(legacy_profile_reader, input): if "defaults" in input: assert input["defaults"] == output else: - assert output == {} \ No newline at end of file + assert output == {} + +test_prepareLocalsData = [ + ( + { # Parser data. + "profile": + { + "layer_height": "0.2", + "infill_density": "30" + } + }, + "profile", # Config section. + { # Defaults. + "layer_height": "0.1", + "infill_density": "20", + "line_width": "0.4" + } + ) +] + +@pytest.mark.parametrize("parser_data, config_section, defaults", test_prepareLocalsData) +def test_prepareLocals(legacy_profile_reader, parser_data, config_section, defaults): + parser = configparser.ConfigParser() + parser.read_dict(parser_data) + + output = legacy_profile_reader.prepareLocals(parser, config_section, defaults) + + assert set(defaults.keys()) <= set(output.keys()) # All defaults must be in there. + assert set(parser_data[config_section]) <= set(output.keys()) # All overwritten values must be in there. + for key in output: + if key in parser_data[config_section]: + assert output[key] == parser_data[config_section][key] # If overwritten, must be the overwritten value. + else: + assert output[key] == defaults[key] # Otherwise must be equal to the default. \ No newline at end of file From 53c9cdc3fe7d0a6c4efa0bd2223edd15e9be71a1 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 12 Nov 2018 13:42:14 +0100 Subject: [PATCH 0178/1292] Add alternative scenarios for prepareLocals Contributes to issue CURA-5929. --- .../tests/TestLegacyProfileReader.py | 52 ++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py b/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py index f54939e884..6d730ed786 100644 --- a/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py +++ b/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py @@ -33,7 +33,7 @@ def test_prepareDefaults(legacy_profile_reader, input): assert output == {} test_prepareLocalsData = [ - ( + ( # Ordinary case. { # Parser data. "profile": { @@ -47,6 +47,56 @@ test_prepareLocalsData = [ "infill_density": "20", "line_width": "0.4" } + ), + ( # Empty data. + { # Parser data. + "profile": + { + } + }, + "profile", # Config section. + { # Defaults. + } + ), + ( # All defaults. + { # Parser data. + "profile": + { + } + }, + "profile", # Config section. + { # Defaults. + "foo": "bar", + "boo": "far" + } + ), + ( # Multiple config sections. + { # Parser data. + "some_other_name": + { + "foo": "bar" + }, + "profile": + { + "foo": "baz" #Not the same as in some_other_name + } + }, + "profile", # Config section. + { # Defaults. + "foo": "bla" + } + ), + ( # Section does not exist. + { # Parser data. + "some_other_name": + { + "foo": "bar" + }, + }, + "profile", # Config section. + { # Defaults. + "foo": "baz" + } ) ] From e18ea4bca4d37d2feabcd47e0bf42cf36fedac68 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 12 Nov 2018 13:47:24 +0100 Subject: [PATCH 0179/1292] Expect a NoSectionError if testing with a section that is missing We want to get that error in order to debug. Contributes to issue CURA-5929. --- .../tests/TestLegacyProfileReader.py | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py b/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py index 6d730ed786..f20658ae5d 100644 --- a/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py +++ b/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py @@ -85,18 +85,6 @@ test_prepareLocalsData = [ { # Defaults. "foo": "bla" } - ), - ( # Section does not exist. - { # Parser data. - "some_other_name": - { - "foo": "bar" - }, - }, - "profile", # Config section. - { # Defaults. - "foo": "baz" - } ) ] @@ -113,4 +101,28 @@ def test_prepareLocals(legacy_profile_reader, parser_data, config_section, defau if key in parser_data[config_section]: assert output[key] == parser_data[config_section][key] # If overwritten, must be the overwritten value. else: - assert output[key] == defaults[key] # Otherwise must be equal to the default. \ No newline at end of file + assert output[key] == defaults[key] # Otherwise must be equal to the default. + +test_prepareLocalsNoSectionErrorData = [ + ( # Section does not exist. + { # Parser data. + "some_other_name": + { + "foo": "bar" + }, + }, + "profile", # Config section. + { # Defaults. + "foo": "baz" + } + ) +] + +## Test cases where a key error is expected. +@pytest.mark.parametrize("parser_data, config_section, defaults", test_prepareLocalsNoSectionErrorData) +def test_prepareLocalsNoSectionError(legacy_profile_reader, parser_data, config_section, defaults): + parser = configparser.ConfigParser() + parser.read_dict(parser_data) + + with pytest.raises(configparser.NoSectionError): + legacy_profile_reader.prepareLocals(parser, config_section, defaults) \ No newline at end of file From 7e87a303cbf54d36c9404f2a1060417ae6dcc8e4 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 12 Nov 2018 13:49:13 +0100 Subject: [PATCH 0180/1292] Remove config_section parameter Just always take 'profile'. We don't need to test with anything else. Just adjust the data to it. Contributes to issue CURA-5929. --- .../tests/TestLegacyProfileReader.py | 23 ++++++++----------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py b/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py index f20658ae5d..828c14bbf5 100644 --- a/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py +++ b/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py @@ -41,7 +41,6 @@ test_prepareLocalsData = [ "infill_density": "30" } }, - "profile", # Config section. { # Defaults. "layer_height": "0.1", "infill_density": "20", @@ -54,7 +53,6 @@ test_prepareLocalsData = [ { } }, - "profile", # Config section. { # Defaults. } ), @@ -64,7 +62,6 @@ test_prepareLocalsData = [ { } }, - "profile", # Config section. { # Defaults. "foo": "bar", "boo": "far" @@ -81,25 +78,24 @@ test_prepareLocalsData = [ "foo": "baz" #Not the same as in some_other_name } }, - "profile", # Config section. { # Defaults. "foo": "bla" } ) ] -@pytest.mark.parametrize("parser_data, config_section, defaults", test_prepareLocalsData) -def test_prepareLocals(legacy_profile_reader, parser_data, config_section, defaults): +@pytest.mark.parametrize("parser_data, defaults", test_prepareLocalsData) +def test_prepareLocals(legacy_profile_reader, parser_data, defaults): parser = configparser.ConfigParser() parser.read_dict(parser_data) - output = legacy_profile_reader.prepareLocals(parser, config_section, defaults) + output = legacy_profile_reader.prepareLocals(parser, "profile", defaults) assert set(defaults.keys()) <= set(output.keys()) # All defaults must be in there. - assert set(parser_data[config_section]) <= set(output.keys()) # All overwritten values must be in there. + assert set(parser_data["profile"]) <= set(output.keys()) # All overwritten values must be in there. for key in output: - if key in parser_data[config_section]: - assert output[key] == parser_data[config_section][key] # If overwritten, must be the overwritten value. + if key in parser_data["profile"]: + assert output[key] == parser_data["profile"][key] # If overwritten, must be the overwritten value. else: assert output[key] == defaults[key] # Otherwise must be equal to the default. @@ -111,7 +107,6 @@ test_prepareLocalsNoSectionErrorData = [ "foo": "bar" }, }, - "profile", # Config section. { # Defaults. "foo": "baz" } @@ -119,10 +114,10 @@ test_prepareLocalsNoSectionErrorData = [ ] ## Test cases where a key error is expected. -@pytest.mark.parametrize("parser_data, config_section, defaults", test_prepareLocalsNoSectionErrorData) -def test_prepareLocalsNoSectionError(legacy_profile_reader, parser_data, config_section, defaults): +@pytest.mark.parametrize("parser_data, defaults", test_prepareLocalsNoSectionErrorData) +def test_prepareLocalsNoSectionError(legacy_profile_reader, parser_data, defaults): parser = configparser.ConfigParser() parser.read_dict(parser_data) with pytest.raises(configparser.NoSectionError): - legacy_profile_reader.prepareLocals(parser, config_section, defaults) \ No newline at end of file + legacy_profile_reader.prepareLocals(parser, "profile", defaults) \ No newline at end of file From 4be33031d7553c06ed7bf5adab7d2f9c31008dae Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 12 Nov 2018 14:07:45 +0100 Subject: [PATCH 0181/1292] Added icons to ExpandableComponent This also makes the entire header react to mouse events instead of just the icon/button CURA-5785 --- resources/qml/ExpandableComponent.qml | 31 ++++++++++++++++--- .../QuickConfigurationSelector.qml | 2 ++ resources/qml/PrintSetupSelector.qml | 8 +++-- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index 26bdf3b3ce..af579340a5 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -6,7 +6,7 @@ import UM 1.2 as UM // The expandable component has 3 major sub components: // * The headerItem; Always visible and should hold some info about what happens if the component is expanded // * The popupItem; The content that needs to be shown if the component is expanded. -// * The Button; The actual button that expands the popup. +// * The Icon; An icon that is displayed on the right of the drawer. Item { // The headerItem holds the QML item that is always displayed. @@ -26,6 +26,18 @@ Item // How much padding is needed around the header & button property alias headerPadding: background.padding + // What icon should be displayed on the right. + property alias iconSource: collapseButton.source + + // What is the color of the icon? + property alias iconColor: collapseButton.color + + // The icon size (it's always drawn as a square) + property alias iconSize: collapseButton.width + + // Is the "drawer" open? + readonly property alias expanded: popup.visible + onPopupItemChanged: { // Since we want the size of the popup to be set by the size of the content, @@ -57,17 +69,26 @@ Item } } - Button + UM.RecolorImage { id: collapseButton anchors { right: parent.right - top: parent.top - bottom: parent.bottom + verticalCenter: parent.verticalCenter margins: background.padding } - text: popup.visible ? "close" : "open" + sourceSize.width: width + sourceSize.height: height + visible: source != "" + width: UM.Theme.getSize("section_icon").width + height: width + color: "black" + } + + MouseArea + { + anchors.fill: parent onClicked: popup.visible ? popup.close() : popup.open() } } diff --git a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml index 3c354384c7..75787ea033 100644 --- a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml +++ b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml @@ -27,6 +27,8 @@ Cura.ExpandableComponent name: "cura" } + iconSource: expanded ? UM.Theme.getIcon("arrow_left") : UM.Theme.getIcon("arrow_bottom") + headerItem: Item { // Horizontal list that shows the extruders diff --git a/resources/qml/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector.qml index 4a8ebda2b3..1281961ef4 100644 --- a/resources/qml/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector.qml @@ -14,7 +14,6 @@ Cura.ExpandableComponent { id: base - height: childrenRect.height property int currentModeIndex: -1 property bool hideSettings: PrintInformation.preSliced @@ -25,6 +24,11 @@ Cura.ExpandableComponent signal showTooltip(Item item, point location, string text) signal hideTooltip() + height: childrenRect.height + iconSource: UM.Theme.getIcon("pencil") + + onCurrentModeIndexChanged: UM.Preferences.setValue("cura/active_mode", currentModeIndex) + UM.I18nCatalog { id: catalog @@ -42,8 +46,6 @@ Cura.ExpandableComponent onTriggered: base.showTooltip(base, {x: 0, y: item.y}, text) } - onCurrentModeIndexChanged: UM.Preferences.setValue("cura/active_mode", currentModeIndex) - headerItem: RowLayout { anchors.fill: parent From 783fe9ab73db3c24abe5dbfcfd6e34ce4c09f911 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 12 Nov 2018 15:23:58 +0100 Subject: [PATCH 0182/1292] Updated the look of the extruder buttons CURA-5785 --- resources/qml/ExtruderButton.qml | 60 ++++---------------------------- resources/qml/Toolbar.qml | 7 +++- 2 files changed, 13 insertions(+), 54 deletions(-) diff --git a/resources/qml/ExtruderButton.qml b/resources/qml/ExtruderButton.qml index 7923521658..764e9c94cb 100644 --- a/resources/qml/ExtruderButton.qml +++ b/resources/qml/ExtruderButton.qml @@ -2,7 +2,7 @@ // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 -import QtQuick.Controls 1.1 +import QtQuick.Controls 2.0 import UM 1.2 as UM import Cura 1.0 as Cura @@ -11,65 +11,19 @@ Button { id: base - property var extruder; + property var extruder text: catalog.i18ncp("@label %1 is filled in with the name of an extruder", "Print Selected Model with %1", "Print Selected Models with %1", UM.Selection.selectionCount).arg(extruder.name) - style: UM.Theme.styles.toolbar_button - iconSource: UM.Theme.getIcon("extruder_button") - checked: Cura.ExtruderManager.selectedObjectExtruders.indexOf(extruder.id) != -1 enabled: UM.Selection.hasSelection && extruder.stack.isEnabled - Item + background: Item {} + contentItem: ExtruderIcon { - anchors.centerIn: parent - width: UM.Theme.getSize("default_margin").width - height: UM.Theme.getSize("default_margin").height - opacity: !base.enabled ? 0.2 : 1.0 - - Label - { - anchors.centerIn: parent - text: index + 1 - color: - { - if (base.checked) - { - return UM.Theme.getColor("toolbar_button_text_active") - } - else if(base.hovered) - { - return UM.Theme.getColor("toolbar_button_text_hover") - } - return UM.Theme.getColor("toolbar_button_text") - } - font: UM.Theme.getFont("default_bold") - } - } - - // Material colour circle - // Only draw the filling colour of the material inside the SVG border. - Rectangle - { - anchors - { - right: parent.right - top: parent.top - rightMargin: UM.Theme.getSize("extruder_button_material_margin").width - topMargin: UM.Theme.getSize("extruder_button_material_margin").height - } - - color: model.color - - width: UM.Theme.getSize("extruder_button_material").width - height: UM.Theme.getSize("extruder_button_material").height - radius: Math.round(width / 2) - - border.width: UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("extruder_button_material_border") - - opacity: !base.enabled ? 0.2 : 1.0 + width: UM.Theme.getSize("button_icon").width + materialColor: model.color + property int index: extruder.index } onClicked: diff --git a/resources/qml/Toolbar.qml b/resources/qml/Toolbar.qml index 9955ceeba7..2239125fbe 100644 --- a/resources/qml/Toolbar.qml +++ b/resources/qml/Toolbar.qml @@ -116,7 +116,12 @@ Item height: childrenRect.height property var _model: Cura.ExtrudersModel { id: extrudersModel } model: _model.items.length > 1 ? _model : 0 - ExtruderButton { extruder: model } + ExtruderButton + { + extruder: model + height: UM.Theme.getSize("button").width + width: UM.Theme.getSize("button").width + } } } } From 4c1a45f904faf1b7e37bef6e18c476b113a6df58 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 12 Nov 2018 15:53:09 +0100 Subject: [PATCH 0183/1292] Added sizes to the stage menu This isn't themed, but right now it does adhere to the sizes I got from UX CURA-5785 --- plugins/PrepareStage/PrepareMenu.qml | 73 +++++++++++++++------------- resources/qml/MachineSelector.qml | 2 +- 2 files changed, 41 insertions(+), 34 deletions(-) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index ff8cdc2a47..9fd8747e28 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -1,5 +1,5 @@ import QtQuick 2.7 - +import QtQuick.Layouts 1.1 import QtQuick.Controls 1.4 import UM 1.3 as UM @@ -19,9 +19,12 @@ Item name: "cura" } - Row + // Item to ensure that all of the buttons are nicely centered. + Item { anchors.horizontalCenter: parent.horizontalCenter + width: openFileButton.width + UM.Theme.getSize("default_margin").width + itemRow.width + height: parent.height Button { @@ -33,42 +36,46 @@ Item action: Cura.Actions.open } - Item + RowLayout { - id: spacing - width: UM.Theme.getSize("default_margin").width - height: prepareMenu.height - } + id: itemRow - Cura.MachineSelector - { - id: machineSelection - width: UM.Theme.getSize("machine_selector_widget").width - configSelection.width - height: prepareMenu.height - z: openFileButton.z - 1 - } + anchors.left: openFileButton.right + anchors.leftMargin: UM.Theme.getSize("default_margin").width - Cura.QuickConfigurationSelector - { - height: prepareMenu.height - width: UM.Theme.getSize("configuration_selector_widget").width - /*id: configSelection - width: visible ? UM.Theme.getSize("machine_selector_widget").width * 0.2 : 0 - panelWidth: UM.Theme.getSize("machine_selector_widget").width - height: prepareMenu.height*/ - } + width: 0.9 * prepareMenu.width + height: parent.height - /*Cura.CustomConfigurationSelector - { - width: UM.Theme.getSize("configuration_selector_widget").width - }*/ + Cura.MachineSelector + { + id: machineSelection + z: openFileButton.z - 1 - Cura.PrintSetupSelector - { - width: UM.Theme.getSize("print_setup_widget").width - height: prepareMenu.height - onShowTooltip: prepareMenu.showTooltip(item, location, text) - onHideTooltip: prepareMenu.hideTooltip() + Layout.minimumWidth: 240 + Layout.maximumWidth: 240 + Layout.fillWidth: true + Layout.fillHeight: true + } + + Cura.QuickConfigurationSelector + { + Layout.fillHeight: true + Layout.fillWidth: true + Layout.preferredWidth: itemRow.width - machineSelection.width - printSetupSelector.width + } + + Cura.PrintSetupSelector + { + id: printSetupSelector + + onShowTooltip: prepareMenu.showTooltip(item, location, text) + onHideTooltip: prepareMenu.hideTooltip() + + Layout.minimumWidth: 460 + Layout.maximumWidth: 460 + Layout.fillWidth: true + Layout.fillHeight: true + } } } } \ No newline at end of file diff --git a/resources/qml/MachineSelector.qml b/resources/qml/MachineSelector.qml index d82211af3a..b4ca9a4899 100644 --- a/resources/qml/MachineSelector.qml +++ b/resources/qml/MachineSelector.qml @@ -19,7 +19,7 @@ ToolButton text: isNetworkPrinter ? Cura.MachineManager.activeMachineNetworkGroupName : Cura.MachineManager.activeMachineName tooltip: Cura.MachineManager.activeMachineName - + width: 240 style: ButtonStyle { background: Rectangle From 7bd55f5064ae86ceadc0653b6b9f05df1186f2e1 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 12 Nov 2018 16:28:29 +0100 Subject: [PATCH 0184/1292] Add test for read() function This is complex. I don't want to get into the actual translations from the DoD here. Contributes to issue CURA-5929. --- .../tests/TestLegacyProfileReader.py | 69 ++++++++++++++++++- .../LegacyProfileReader/tests/normal_case.ini | 7 ++ 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 plugins/LegacyProfileReader/tests/normal_case.ini diff --git a/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py b/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py index 828c14bbf5..480a61f301 100644 --- a/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py +++ b/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py @@ -2,8 +2,16 @@ # Cura is released under the terms of the LGPLv3 or higher. import configparser # An input for some functions we're testing. +import os.path # To find the integration test .ini files. import pytest # To register tests with. +import unittest.mock # To mock the application, plug-in and container registry out. +import UM.Application # To mock the application out. +import UM.PluginRegistry # To mock the plug-in registry out. +import UM.Settings.ContainerRegistry # To mock the container registry out. +import UM.Settings.InstanceContainer # To intercept the serialised data from the read() function. + +import LegacyProfileReader as LegacyProfileReaderModule # To get the directory of the module. from LegacyProfileReader import LegacyProfileReader # The module we're testing. @pytest.fixture @@ -120,4 +128,63 @@ def test_prepareLocalsNoSectionError(legacy_profile_reader, parser_data, default parser.read_dict(parser_data) with pytest.raises(configparser.NoSectionError): - legacy_profile_reader.prepareLocals(parser, "profile", defaults) \ No newline at end of file + legacy_profile_reader.prepareLocals(parser, "profile", defaults) + +intercepted_data = "" + +@pytest.mark.parametrize("file_name", ["normal_case.ini"]) +def test_read(legacy_profile_reader, file_name): + # Mock out all dependencies. Quite a lot! + global_stack = unittest.mock.MagicMock() + global_stack.getProperty = unittest.mock.MagicMock(return_value = 1) # For machine_extruder_count setting. + def getMetaDataEntry(key, default_value = ""): + if key == "quality_definition": + return "mocked_quality_definition" + if key == "has_machine_quality": + return "True" + global_stack.definition.getMetaDataEntry = getMetaDataEntry + global_stack.definition.getId = unittest.mock.MagicMock(return_value = "mocked_global_definition") + application = unittest.mock.MagicMock() + application.getGlobalContainerStack = unittest.mock.MagicMock(return_value = global_stack) + application_getInstance = unittest.mock.MagicMock(return_value = application) + container_registry = unittest.mock.MagicMock() + container_registry_getInstance = unittest.mock.MagicMock(return_value = container_registry) + container_registry.uniqueName = unittest.mock.MagicMock(return_value = "Imported Legacy Profile") + container_registry.findDefinitionContainers = unittest.mock.MagicMock(return_value = [global_stack.definition]) + UM.Settings.InstanceContainer.setContainerRegistry(container_registry) + plugin_registry = unittest.mock.MagicMock() + plugin_registry_getInstance = unittest.mock.MagicMock(return_value = plugin_registry) + plugin_registry.getPluginPath = unittest.mock.MagicMock(return_value = os.path.dirname(LegacyProfileReaderModule.__file__)) + + # Mock out the resulting InstanceContainer so that we can intercept the data before it's passed through the version upgrader. + def deserialize(self, data): # Intercepts the serialised data that we'd perform the version upgrade from when deserializing. + global intercepted_data + intercepted_data = data + + parser = configparser.ConfigParser() + parser.read_string(data) + self._metadata["position"] = parser["metadata"]["position"] + def duplicate(self, new_id, new_name): + self._metadata["id"] = new_id + self._metadata["name"] = new_name + return self + + with unittest.mock.patch.object(UM.Application.Application, "getInstance", application_getInstance): + with unittest.mock.patch.object(UM.Settings.ContainerRegistry.ContainerRegistry, "getInstance", container_registry_getInstance): + with unittest.mock.patch.object(UM.PluginRegistry.PluginRegistry, "getInstance", plugin_registry_getInstance): + with unittest.mock.patch.object(UM.Settings.InstanceContainer.InstanceContainer, "deserialize", deserialize): + with unittest.mock.patch.object(UM.Settings.InstanceContainer.InstanceContainer, "duplicate", duplicate): + result = legacy_profile_reader.read(os.path.join(os.path.dirname(__file__), file_name)) + + assert len(result) == 1 + + # Let's see what's inside the actual output file that we generated. + parser = configparser.ConfigParser() + parser.read_string(intercepted_data) + assert parser["general"]["definition"] == "mocked_quality_definition" + assert parser["general"]["version"] == "4" # Yes, before we upgraded. + assert parser["general"]["name"] == "Imported Legacy Profile" # Because we overwrote uniqueName. + assert parser["metadata"]["type"] == "quality_changes" + assert parser["metadata"]["quality_type"] == "normal" + assert parser["metadata"]["position"] == "0" + assert parser["metadata"]["setting_version"] == "5" # Yes, before we upgraded. \ No newline at end of file diff --git a/plugins/LegacyProfileReader/tests/normal_case.ini b/plugins/LegacyProfileReader/tests/normal_case.ini new file mode 100644 index 0000000000..213444d2d3 --- /dev/null +++ b/plugins/LegacyProfileReader/tests/normal_case.ini @@ -0,0 +1,7 @@ +[profile] +foo = bar +boo = far +fill_overlap = 3 + +[alterations] +some = values From fe4ed464962d76abd6a8058f1f69987f8bad205d Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 12 Nov 2018 16:55:42 +0100 Subject: [PATCH 0185/1292] Show material name instead of just color CURA-5785 --- .../Menus/ConfigurationMenu/QuickConfigurationSelector.qml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml index 75787ea033..7c70229b5d 100644 --- a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml +++ b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml @@ -54,7 +54,7 @@ Cura.ExpandableComponent width: height } - // Label for the human readable material color name + // Label for the brand of the material Label { id: brandNameLabel @@ -71,10 +71,10 @@ Cura.ExpandableComponent } } - // Label that shows the brand of the material + // Label that shows the name of the material Label { - text: model.color_name + text: model.material elide: Text.ElideRight anchors From 87cbc3907c1a4912e30ca60f30d00d5b84fbef51 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 13 Nov 2018 12:05:14 +0100 Subject: [PATCH 0186/1292] Convert to string before storing in configparser Because configparser can only handle strings. Contributes to issue CURA-5929. --- plugins/LegacyProfileReader/LegacyProfileReader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/LegacyProfileReader/LegacyProfileReader.py b/plugins/LegacyProfileReader/LegacyProfileReader.py index 7974bbe829..013bab6f11 100644 --- a/plugins/LegacyProfileReader/LegacyProfileReader.py +++ b/plugins/LegacyProfileReader/LegacyProfileReader.py @@ -139,7 +139,7 @@ class LegacyProfileReader(ProfileReader): definitions = current_printer_definition.findDefinitions(key = new_setting) if definitions: if new_value != value_using_defaults and definitions[0].default_value != new_value: # Not equal to the default in the new Cura OR the default in the legacy Cura. - output_parser["values"][new_setting] = new_value # Store the setting in the profile! + output_parser["values"][new_setting] = str(new_value) # Store the setting in the profile! if len(output_parser["values"]) == 0: Logger.log("i", "A legacy profile was imported but everything evaluates to the defaults, creating an empty profile.") From c18b8241f55f425d5c6a91c00bb8d130560bbdbb Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 13 Nov 2018 14:00:00 +0100 Subject: [PATCH 0187/1292] Change MachineSelection so that it also uses the ExpandableComponent CURA-5785 --- resources/qml/Cura.qml | 1 - resources/qml/MachineSelector.qml | 176 ++++++++++++++++++------------ 2 files changed, 108 insertions(+), 69 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 819d986ece..cdbf1f3511 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -249,7 +249,6 @@ UM.MainWindow source: UM.Controller.activeStage != null ? UM.Controller.activeStage.mainComponent : "" } - Loader { // The stage menu is, as the name implies, a menu that is defined by the active stage. diff --git a/resources/qml/MachineSelector.qml b/resources/qml/MachineSelector.qml index b4ca9a4899..206229e837 100644 --- a/resources/qml/MachineSelector.qml +++ b/resources/qml/MachineSelector.qml @@ -2,7 +2,7 @@ // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 -import QtQuick.Controls 1.1 +import QtQuick.Controls 2.4 import QtQuick.Controls.Styles 1.1 import QtQuick.Layouts 1.1 @@ -10,77 +10,117 @@ import UM 1.2 as UM import Cura 1.0 as Cura import "Menus" -ToolButton + +Cura.ExpandableComponent { - id: base + id: machineSelector + property bool isNetworkPrinter: Cura.MachineManager.activeMachineNetworkKey != "" - property bool printerConnected: Cura.MachineManager.printerConnected - property var printerStatus: Cura.MachineManager.printerConnected ? "connected" : "disconnected" - text: isNetworkPrinter ? Cura.MachineManager.activeMachineNetworkGroupName : Cura.MachineManager.activeMachineName - tooltip: Cura.MachineManager.activeMachineName - width: 240 - style: ButtonStyle + iconSource: expanded ? UM.Theme.getIcon("arrow_left") : UM.Theme.getIcon("arrow_bottom") + + UM.I18nCatalog { - background: Rectangle - { - color: - { - if (control.pressed) { - return UM.Theme.getColor("machine_selector_active"); - } - else if (control.hovered) { - return UM.Theme.getColor("machine_selector_hover"); - } - else { - return UM.Theme.getColor("machine_selector_bar"); - } - } - Behavior on color { ColorAnimation { duration: 50; } } - - UM.RecolorImage - { - id: downArrow - anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - anchors.rightMargin: UM.Theme.getSize("default_margin").width - width: UM.Theme.getSize("standard_arrow").width - height: UM.Theme.getSize("standard_arrow").height - sourceSize.width: width - sourceSize.height: width - color: UM.Theme.getColor("text_emphasis") - source: UM.Theme.getIcon("arrow_bottom") - } - - PrinterStatusIcon - { - id: printerStatusIcon - visible: printerConnected || isNetworkPrinter - status: printerStatus - anchors - { - verticalCenter: parent.verticalCenter - left: parent.left - leftMargin: UM.Theme.getSize("thick_margin").width - } - } - - Label - { - id: sidebarComboBoxLabel - color: UM.Theme.getColor("machine_selector_text_active") - text: control.text; - elide: Text.ElideRight; - anchors.left: printerStatusIcon.visible ? printerStatusIcon.right : parent.left; - anchors.leftMargin: printerStatusIcon.visible ? UM.Theme.getSize("narrow_margin").width : UM.Theme.getSize("thick_margin").width - anchors.right: downArrow.left; - anchors.rightMargin: control.rightMargin; - anchors.verticalCenter: parent.verticalCenter; - font: UM.Theme.getFont("medium_bold") - } - } - label: Label {} + id: catalog + name: "cura" } - menu: PrinterMenu { } + headerItem: Item + { + Label + { + text: isNetworkPrinter ? Cura.MachineManager.activeMachineNetworkGroupName : Cura.MachineManager.activeMachineName + verticalAlignment: Text.AlignVCenter + height: parent.height + } + } + + popupItem: Item + { + id: popup + width: 240 + height: 200 + + ScrollView + { + anchors.fill: parent + contentHeight: column.implicitHeight + contentWidth: row.implicitWidth + clip: true + ScrollBar.horizontal.policy: ScrollBar.AlwaysOff + + Column + { + id: column + anchors.fill: parent + Label + { + text: catalog.i18nc("@label", "Networked Printers") + visible: networkedPrintersModel.items.length > 0 + height: visible ? contentHeight + 2 * UM.Theme.getSize("default_margin").height : 0 + font: UM.Theme.getFont("medium_bold") + verticalAlignment: Text.AlignVCenter + } + + Repeater + { + id: networkedPrinters + + model: UM.ContainerStacksModel + { + id: networkedPrintersModel + filter: {"type": "machine", "um_network_key": "*", "hidden": "False"} + } + + delegate: RoundButton + { + text: name + width: parent.width + + checkable: true + onClicked: Cura.MachineManager.setActiveMachine(model.id) + radius: UM.Theme.getSize("default_radius").width + + Connections + { + target: Cura.MachineManager + onActiveMachineNetworkGroupNameChanged: checked = Cura.MachineManager.activeMachineNetworkGroupName == model.metadata["connect_group_name"] + } + } + + } + + Label + { + text: catalog.i18nc("@label", "Virtual Printers") + visible: virtualPrintersModel.items.length > 0 + height: visible ? contentHeight + 2 * UM.Theme.getSize("default_margin").height : 0 + font: UM.Theme.getFont("medium_bold") + verticalAlignment: Text.AlignVCenter + } + + Repeater + { + id: virtualPrinters + + model: UM.ContainerStacksModel + { + id: virtualPrintersModel + filter: {"type": "machine", "um_network_key": null} + } + + delegate: RoundButton + { + text: name + width: parent.width + checked: Cura.MachineManager.activeMachineId == model.id + checkable: true + onClicked: Cura.MachineManager.setActiveMachine(model.id) + radius: UM.Theme.getSize("default_radius").width + } + + } + } + } + } } From deb5fd1926763af05bf107fe7599cff1f085ec23 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 13 Nov 2018 15:35:05 +0100 Subject: [PATCH 0188/1292] Fix PrintSetupSelector for previewStage CURA-5785 --- plugins/PreviewStage/PreviewMenu.qml | 3 ++- resources/qml/PrintSetupSelector.qml | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index 66f7d527d9..db96525365 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -25,7 +25,7 @@ Item { anchors.horizontalCenter: parent.horizontalCenter spacing: UM.Theme.getSize("default_margin").width - + height: parent.height ComboBox { // This item contains the views selector, a combobox that is dynamically created from @@ -87,6 +87,7 @@ Item Cura.PrintSetupSelector { width: UM.Theme.getSize("print_setup_widget").width + height: parent.height onShowTooltip: previewMenu.showTooltip(item, location, text) onHideTooltip: previewMenu.hideTooltip() } diff --git a/resources/qml/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector.qml index 1281961ef4..65bcee8507 100644 --- a/resources/qml/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector.qml @@ -24,6 +24,7 @@ Cura.ExpandableComponent signal showTooltip(Item item, point location, string text) signal hideTooltip() + implicitWidth: 200 height: childrenRect.height iconSource: UM.Theme.getIcon("pencil") From 785c2661a2ad382d77285cbb124bfee1e5f1985e Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 13 Nov 2018 15:57:00 +0100 Subject: [PATCH 0189/1292] Make SimulationViewMenuComponent also use the ExpandableComponent CURA-5785 --- plugins/PreviewStage/PreviewMenu.qml | 2 +- .../SimulationViewMenuComponent.qml | 74 +++---------------- resources/qml/ExpandableComponent.qml | 8 ++ 3 files changed, 20 insertions(+), 64 deletions(-) diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index db96525365..aeef2bf300 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -78,7 +78,7 @@ Item property var buttonTarget: Qt.point(viewModeButton.x + Math.round(viewModeButton.width / 2), viewModeButton.y + Math.round(viewModeButton.height / 2)) - height: childrenRect.height + height: parent.height width: childrenRect.width source: UM.Controller.activeView != null && UM.Controller.activeView.stageMenuComponent != null ? UM.Controller.activeView.stageMenuComponent : "" diff --git a/plugins/SimulationView/SimulationViewMenuComponent.qml b/plugins/SimulationView/SimulationViewMenuComponent.qml index d251244c9f..fe9f4471fd 100644 --- a/plugins/SimulationView/SimulationViewMenuComponent.qml +++ b/plugins/SimulationView/SimulationViewMenuComponent.qml @@ -10,19 +10,13 @@ import QtGraphicalEffects 1.0 import UM 1.0 as UM import Cura 1.0 as Cura -Rectangle + +Cura.ExpandableComponent { id: base - color: UM.Theme.getColor("tool_panel_background") - border.width: UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("lining") - width: UM.Theme.getSize("layerview_menu_size").width - - height: viewSettings.collapsed ? layerViewTypesLabel.height + 2 * UM.Theme.getSize("default_margin").height : childrenRect.height + 2 * UM.Theme.getSize("default_margin").height - - Behavior on height { NumberAnimation { duration: 100 } } + iconSource: UM.Theme.getIcon("pencil") property var buttonTarget: { @@ -51,59 +45,21 @@ Rectangle } } - Label + headerItem: Label { id: layerViewTypesLabel - text: catalog.i18nc("@label","Color scheme") - font: UM.Theme.getFont("default"); + text: catalog.i18nc("@label", "Color scheme") + font: UM.Theme.getFont("default") visible: !UM.SimulationView.compatibilityMode color: UM.Theme.getColor("setting_control_text") - height: contentHeight - anchors - { - top: parent.top - margins: UM.Theme.getSize("default_margin").height - right: collapseButton.left - left: parent.left - } + height: base.height + verticalAlignment: Text.AlignVCenter } - Button - { - id: collapseButton - - anchors - { - top: parent.top - margins: UM.Theme.getSize("default_margin").width - right: parent.right - } - - width: UM.Theme.getSize("standard_arrow").width - height: UM.Theme.getSize("standard_arrow").height - - onClicked: viewSettings.collapsed = !viewSettings.collapsed - - style: ButtonStyle - { - background: UM.RecolorImage - { - width: control.width - height: control.height - sourceSize.width: width - sourceSize.height: width - color: UM.Theme.getColor("setting_control_text") - source: viewSettings.collapsed ? UM.Theme.getIcon("arrow_left") : UM.Theme.getIcon("arrow_bottom") - } - label: Label{ } - } - } - - Column + popupItem: Column { id: viewSettings - property bool collapsed: false property var extruder_opacities: UM.Preferences.getValue("layerview/extruder_opacities").split("|") property bool show_travel_moves: UM.Preferences.getValue("layerview/show_travel_moves") property bool show_helpers: UM.Preferences.getValue("layerview/show_helpers") @@ -118,19 +74,11 @@ Rectangle property bool only_show_top_layers: UM.Preferences.getValue("view/only_show_top_layers") property int top_layer_count: UM.Preferences.getValue("view/top_layer_count") - anchors - { - top: layerViewTypesLabel.bottom - left: parent.left - right: parent.right - margins: UM.Theme.getSize("default_margin").height - - } + width: UM.Theme.getSize("layerview_menu_size").width + height: childrenRect.height spacing: UM.Theme.getSize("layerview_row_spacing").height - visible: !collapsed - ListModel // matches SimulationView.py { id: layerViewTypes diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index af579340a5..06b4146a57 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -47,6 +47,14 @@ Item popup.contentItem = popupItem } + Connections + { + // Since it could be that the popup is dynamically populated, we should also take these changes into account. + target: popupItem + onWidthChanged: popup.width = popupItem.width + 2 * popup.padding + onHeightChanged: popup.height = popupItem.height + 2 * popup.padding + } + implicitHeight: 100 implicitWidth: 400 Rectangle From c9389dd9ab824b40a09b13fd9f3939ffc531f874 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 13 Nov 2018 15:58:34 +0100 Subject: [PATCH 0190/1292] Codestyle fixes --- resources/qml/PrintSetupSelector.qml | 29 ++++++---------------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/resources/qml/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector.qml index 65bcee8507..7a7d438bc3 100644 --- a/resources/qml/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector.qml @@ -109,23 +109,6 @@ Cura.ExpandableComponent } } - - /*Label - { - id: settingsModeLabel - text: !hideSettings ? catalog.i18nc("@label:listbox", "Print Setup") : catalog.i18nc("@label:listbox", "Print Setup disabled\nG-code files cannot be modified") - renderType: Text.NativeRendering - - anchors - { - fill: parent - } - - height: contentHeight - font: UM.Theme.getFont("large") - color: UM.Theme.getColor("text") - }*/ - popupItem: Item { height: settingsModeSelection.height + sidebarContents.height @@ -184,7 +167,7 @@ Cura.ExpandableComponent border.width: control.checked ? UM.Theme.getSize("default_lining").width * 2 : UM.Theme.getSize("default_lining").width border.color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active_border") : control.hovered ? UM.Theme.getColor("action_button_hovered_border") : UM.Theme.getColor("action_button_border") - // for some reason, QtQuick decided to use the color of the background property as text color for the contentItem, so here it is + // For some reason, QtQuick decided to use the color of the background property as text color for the contentItem, so here it is color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active") : control.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") } @@ -200,13 +183,13 @@ Cura.ExpandableComponent { if(control.pressed) { - return UM.Theme.getColor("action_button_active_text"); + return UM.Theme.getColor("action_button_active_text") } else if(control.hovered) { - return UM.Theme.getColor("action_button_hovered_text"); + return UM.Theme.getColor("action_button_hovered_text") } - return UM.Theme.getColor("action_button_text"); + return UM.Theme.getColor("action_button_text") } } } @@ -263,11 +246,11 @@ Cura.ExpandableComponent if(index != null && !isNaN(index)) { - currentModeIndex = index; + currentModeIndex = index } else { - currentModeIndex = 0; + currentModeIndex = 0 } } } From 20e2f317de0507ec889baa5dc30cf48277165bdb Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 13 Nov 2018 16:02:45 +0100 Subject: [PATCH 0191/1292] Add background to viewModeSelection CURA-5785 --- plugins/PreviewStage/PreviewMenu.qml | 71 +++++++++++++++------------- 1 file changed, 39 insertions(+), 32 deletions(-) diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index aeef2bf300..f21c13a5bc 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -26,49 +26,56 @@ Item anchors.horizontalCenter: parent.horizontalCenter spacing: UM.Theme.getSize("default_margin").width height: parent.height - ComboBox + + Rectangle { - // This item contains the views selector, a combobox that is dynamically created from - // the list of available Views (packages that create different visualizations of the - // scene). - id: viewModeButton - - style: UM.Theme.styles.combobox - - model: UM.ViewModel { } - textRole: "name" - - // update the model's active index - function updateItemActiveFlags() + color: UM.Theme.getColor("tool_panel_background") + width: viewModeButton.width + 2 * UM.Theme.getSize("default_margin").width + height: parent.height + ComboBox { - currentIndex = getActiveIndex() - for (var i = 0; i < model.rowCount(); i++) - { - model.getItem(i).active = (i == currentIndex) - } - } + // This item contains the views selector, a combobox that is dynamically created from + // the list of available Views (packages that create different visualizations of the + // scene). + id: viewModeButton - // get the index of the active model item on start - function getActiveIndex() - { - for (var i = 0; i < model.rowCount(); i++) + style: UM.Theme.styles.combobox + anchors.centerIn: parent + model: UM.ViewModel { } + textRole: "name" + + // update the model's active index + function updateItemActiveFlags() { - if (model.getItem(i).active) + currentIndex = getActiveIndex() + for (var i = 0; i < model.rowCount(); i++) { - return i; + model.getItem(i).active = (i == currentIndex) } } - return 0 - } - onCurrentIndexChanged: - { - if (model.getItem(currentIndex).id != undefined) + // get the index of the active model item on start + function getActiveIndex() { - UM.Controller.setActiveView(model.getItem(currentIndex).id) + for (var i = 0; i < model.rowCount(); i++) + { + if (model.getItem(i).active) + { + return i; + } + } + return 0 } + + onCurrentIndexChanged: + { + if (model.getItem(currentIndex).id != undefined) + { + UM.Controller.setActiveView(model.getItem(currentIndex).id) + } + } + currentIndex: getActiveIndex() } - currentIndex: getActiveIndex() } Loader From 4b8d20cad770646c9f33c6ca5a508bedee968858 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 13 Nov 2018 16:27:19 +0100 Subject: [PATCH 0192/1292] Correct the link to create a new account Previously this button just took you to the log-in page. Fixes issue CURA-5921. --- resources/qml/Account/GeneralOperations.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Account/GeneralOperations.qml b/resources/qml/Account/GeneralOperations.qml index 362e088033..4614c4ba88 100644 --- a/resources/qml/Account/GeneralOperations.qml +++ b/resources/qml/Account/GeneralOperations.qml @@ -20,7 +20,7 @@ Row hoverColor: UM.Theme.getColor("secondary") textColor: UM.Theme.getColor("main_window_header_button_text_active") textHoverColor: UM.Theme.getColor("main_window_header_button_text_active") - onClicked: Qt.openUrlExternally("https://account.ultimaker.com") + onClicked: Qt.openUrlExternally("https://account.ultimaker.com/app/create") fixedWidthMode: true } From b83175a380e170a71e8b6cdfae0235a4777e9c44 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 13 Nov 2018 16:31:48 +0100 Subject: [PATCH 0193/1292] Add rounded corners to stage menus CURA-5785 --- plugins/PrepareStage/PrepareMenu.qml | 72 +++++++++------ plugins/PreviewStage/PreviewMenu.qml | 130 +++++++++++++++------------ 2 files changed, 117 insertions(+), 85 deletions(-) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index 9fd8747e28..7006545204 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -23,7 +23,7 @@ Item Item { anchors.horizontalCenter: parent.horizontalCenter - width: openFileButton.width + UM.Theme.getSize("default_margin").width + itemRow.width + width: openFileButton.width + itemRowBackground.width height: parent.height Button @@ -36,45 +36,59 @@ Item action: Cura.Actions.open } - RowLayout + Rectangle { - id: itemRow + id: itemRowBackground + radius: UM.Theme.getSize("default_radius").width + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("lining") + color: UM.Theme.getColor("toolbar_background") + + width: itemRow.width + UM.Theme.getSize("default_margin").width + height: parent.height anchors.left: openFileButton.right anchors.leftMargin: UM.Theme.getSize("default_margin").width - width: 0.9 * prepareMenu.width - height: parent.height - - Cura.MachineSelector + RowLayout { - id: machineSelection - z: openFileButton.z - 1 + id: itemRow - Layout.minimumWidth: 240 - Layout.maximumWidth: 240 - Layout.fillWidth: true - Layout.fillHeight: true - } + anchors.centerIn: parent - Cura.QuickConfigurationSelector - { - Layout.fillHeight: true - Layout.fillWidth: true - Layout.preferredWidth: itemRow.width - machineSelection.width - printSetupSelector.width - } + width: 0.9 * prepareMenu.width + height: parent.height - 2 * UM.Theme.getSize("default_lining").width - Cura.PrintSetupSelector - { - id: printSetupSelector + Cura.MachineSelector + { + id: machineSelection + z: openFileButton.z - 1 - onShowTooltip: prepareMenu.showTooltip(item, location, text) - onHideTooltip: prepareMenu.hideTooltip() + Layout.minimumWidth: 240 + Layout.maximumWidth: 240 + Layout.fillWidth: true + Layout.fillHeight: true + } - Layout.minimumWidth: 460 - Layout.maximumWidth: 460 - Layout.fillWidth: true - Layout.fillHeight: true + Cura.QuickConfigurationSelector + { + Layout.fillHeight: true + Layout.fillWidth: true + Layout.preferredWidth: itemRow.width - machineSelection.width - printSetupSelector.width + } + + Cura.PrintSetupSelector + { + id: printSetupSelector + + onShowTooltip: prepareMenu.showTooltip(item, location, text) + onHideTooltip: prepareMenu.hideTooltip() + + Layout.minimumWidth: 460 + Layout.maximumWidth: 460 + Layout.fillWidth: true + Layout.fillHeight: true + } } } } diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index f21c13a5bc..1741706679 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -15,88 +15,106 @@ Item signal showTooltip(Item item, point location, string text) signal hideTooltip() + property real itemHeight: height - 2 * UM.Theme.getSize("default_lining").width + UM.I18nCatalog { id: catalog name: "cura" } - Row + Rectangle { - anchors.horizontalCenter: parent.horizontalCenter - spacing: UM.Theme.getSize("default_margin").width + anchors.fill: stageMenu + anchors.leftMargin: -radius + radius: UM.Theme.getSize("default_radius").width + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("lining") + color: UM.Theme.getColor("toolbar_background") + } + + Item + { + id: stageMenu height: parent.height - - Rectangle + width: childrenRect.width + UM.Theme.getSize("default_margin").width + anchors.horizontalCenter: parent.horizontalCenter + Row { - color: UM.Theme.getColor("tool_panel_background") - width: viewModeButton.width + 2 * UM.Theme.getSize("default_margin").width - height: parent.height - ComboBox + anchors.centerIn: parent + spacing: UM.Theme.getSize("default_margin").width + height: parent.height - 2 * UM.Theme.getSize("default_lining").width + + Item { - // This item contains the views selector, a combobox that is dynamically created from - // the list of available Views (packages that create different visualizations of the - // scene). - id: viewModeButton - - style: UM.Theme.styles.combobox - anchors.centerIn: parent - model: UM.ViewModel { } - textRole: "name" - - // update the model's active index - function updateItemActiveFlags() + width: viewModeButton.width + 2 * UM.Theme.getSize("default_margin").width + height: parent.height + ComboBox { - currentIndex = getActiveIndex() - for (var i = 0; i < model.rowCount(); i++) - { - model.getItem(i).active = (i == currentIndex) - } - } + // This item contains the views selector, a combobox that is dynamically created from + // the list of available Views (packages that create different visualizations of the + // scene). + id: viewModeButton - // get the index of the active model item on start - function getActiveIndex() - { - for (var i = 0; i < model.rowCount(); i++) + style: UM.Theme.styles.combobox + anchors.centerIn: parent + model: UM.ViewModel { } + textRole: "name" + + // update the model's active index + function updateItemActiveFlags() { - if (model.getItem(i).active) + currentIndex = getActiveIndex() + for (var i = 0; i < model.rowCount(); i++) { - return i; + model.getItem(i).active = (i == currentIndex) } } - return 0 - } - onCurrentIndexChanged: - { - if (model.getItem(currentIndex).id != undefined) + // get the index of the active model item on start + function getActiveIndex() { - UM.Controller.setActiveView(model.getItem(currentIndex).id) + for (var i = 0; i < model.rowCount(); i++) + { + if (model.getItem(i).active) + { + return i; + } + } + return 0 } + + onCurrentIndexChanged: + { + if (model.getItem(currentIndex).id != undefined) + { + UM.Controller.setActiveView(model.getItem(currentIndex).id) + } + } + currentIndex: getActiveIndex() } - currentIndex: getActiveIndex() } - } - Loader - { - // TODO: Make this panel collapsable and ensure it has a standardised background. - id: viewPanel + Loader + { + // TODO: Make this panel collapsable and ensure it has a standardised background. + id: viewPanel - property var buttonTarget: Qt.point(viewModeButton.x + Math.round(viewModeButton.width / 2), viewModeButton.y + Math.round(viewModeButton.height / 2)) + property var buttonTarget: Qt.point(viewModeButton.x + Math.round(viewModeButton.width / 2), viewModeButton.y + Math.round(viewModeButton.height / 2)) - height: parent.height - width: childrenRect.width + height: parent.height + width: childrenRect.width - source: UM.Controller.activeView != null && UM.Controller.activeView.stageMenuComponent != null ? UM.Controller.activeView.stageMenuComponent : "" - } + source: UM.Controller.activeView != null && UM.Controller.activeView.stageMenuComponent != null ? UM.Controller.activeView.stageMenuComponent : "" + } - Cura.PrintSetupSelector - { - width: UM.Theme.getSize("print_setup_widget").width - height: parent.height - onShowTooltip: previewMenu.showTooltip(item, location, text) - onHideTooltip: previewMenu.hideTooltip() + Cura.PrintSetupSelector + { + width: UM.Theme.getSize("print_setup_widget").width + height: parent.height + onShowTooltip: previewMenu.showTooltip(item, location, text) + onHideTooltip: previewMenu.hideTooltip() + } } } } \ No newline at end of file From 551bc2fbd41984a4ca11a4d42a49be04736f5e9b Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 13 Nov 2018 16:40:51 +0100 Subject: [PATCH 0194/1292] Removed line around the headerbar I was checking an old design, the new one doesn't have a line around it CURA-5785 --- plugins/PrepareStage/PrepareMenu.qml | 5 ++--- plugins/PreviewStage/PreviewMenu.qml | 4 +--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index 7006545204..ac43fd5634 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -40,8 +40,7 @@ Item { id: itemRowBackground radius: UM.Theme.getSize("default_radius").width - border.width: UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("lining") + color: UM.Theme.getColor("toolbar_background") width: itemRow.width + UM.Theme.getSize("default_margin").width @@ -57,7 +56,7 @@ Item anchors.centerIn: parent width: 0.9 * prepareMenu.width - height: parent.height - 2 * UM.Theme.getSize("default_lining").width + height: parent.height Cura.MachineSelector { diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index 1741706679..b441a78dff 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -28,8 +28,6 @@ Item anchors.fill: stageMenu anchors.leftMargin: -radius radius: UM.Theme.getSize("default_radius").width - border.width: UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("lining") color: UM.Theme.getColor("toolbar_background") } @@ -43,7 +41,7 @@ Item { anchors.centerIn: parent spacing: UM.Theme.getSize("default_margin").width - height: parent.height - 2 * UM.Theme.getSize("default_lining").width + height: parent.height Item { From a9fdd455ebf39dbc66f592324ebcca08620ed14e Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 13 Nov 2018 16:47:39 +0100 Subject: [PATCH 0195/1292] Add seperator lines for the stageMenu's CURA-5785 --- plugins/PrepareStage/PrepareMenu.qml | 18 +++++++++++++++++- plugins/PreviewStage/PreviewMenu.qml | 17 ++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index ac43fd5634..c7164eb490 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -69,11 +69,27 @@ Item Layout.fillHeight: true } + // Separator line + Rectangle + { + height: parent.height + width: UM.Theme.getSize("default_lining").width + color: UM.Theme.getColor("lining") + } + Cura.QuickConfigurationSelector { Layout.fillHeight: true Layout.fillWidth: true - Layout.preferredWidth: itemRow.width - machineSelection.width - printSetupSelector.width + Layout.preferredWidth: itemRow.width - machineSelection.width - printSetupSelector.width - 2 * UM.Theme.getSize("default_lining").width + } + + // Separator line + Rectangle + { + height: parent.height + width: UM.Theme.getSize("default_lining").width + color: UM.Theme.getColor("lining") } Cura.PrintSetupSelector diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index b441a78dff..ccc0a98c6e 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -40,7 +40,7 @@ Item Row { anchors.centerIn: parent - spacing: UM.Theme.getSize("default_margin").width + //spacing: UM.Theme.getSize("default_margin").width height: parent.height Item @@ -93,6 +93,14 @@ Item } } + // Separator line + Rectangle + { + height: parent.height + width: UM.Theme.getSize("default_lining").width + color: UM.Theme.getColor("lining") + } + Loader { // TODO: Make this panel collapsable and ensure it has a standardised background. @@ -106,6 +114,13 @@ Item source: UM.Controller.activeView != null && UM.Controller.activeView.stageMenuComponent != null ? UM.Controller.activeView.stageMenuComponent : "" } + // Separator line + Rectangle + { + height: parent.height + width: UM.Theme.getSize("default_lining").width + color: UM.Theme.getColor("lining") + } Cura.PrintSetupSelector { width: UM.Theme.getSize("print_setup_widget").width From 6307784a7940e4942ea964068b6a1135329071ed Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Tue, 13 Nov 2018 16:50:00 +0100 Subject: [PATCH 0196/1292] Fix some English grammar. [CURA-5903] --- resources/definitions/fdmprinter.def.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 3b3194f1dc..e67608f579 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -4142,7 +4142,7 @@ "minimum_support_area": { "label": "Minimum Support Area", - "description": "Minimum area size for support polygons. Polygons which area is smaller than this value will not be generated.", + "description": "Minimum area size for support polygons. Polygons which have an area smaller than this value will not be generated.", "unit": "mm²", "type": "float", "default_value": 0.0, @@ -4395,7 +4395,7 @@ "minimum_interface_area": { "label": "Minimum Support Interface Area", - "description": "Minimum area size for support interface polygons. Polygons which area are smaller than this value will not be generated.", + "description": "Minimum area size for support interface polygons. Polygons which have an area smaller than this value will not be generated.", "unit": "mm²", "type": "float", "default_value": 1.0, @@ -4409,7 +4409,7 @@ "minimum_roof_area": { "label": "Minimum Support Roof Area", - "description": "Minimum area size for the roofs of the support. Polygons which area are smaller than this value will not be generated.", + "description": "Minimum area size for the roofs of the support. Polygons which have an area smaller than this value will not be generated.", "unit": "mm²", "type": "float", "default_value": 1.0, @@ -4423,7 +4423,7 @@ "minimum_bottom_area": { "label": "Minimum Support Floor Area", - "description": "Minimum area size for the floors of the support. Polygons which area are smaller than this value will not be generated.", + "description": "Minimum area size for the floors of the support. Polygons which have an area smaller than this value will not be generated.", "unit": "mm²", "type": "float", "default_value": 1.0, From 12c296241436acf72fd171f00e914be74ffd3ba7 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 13 Nov 2018 16:59:02 +0100 Subject: [PATCH 0197/1292] Update the look & feel of openButton to the new design CURA-5785 --- plugins/PrepareStage/PrepareMenu.qml | 30 +++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index c7164eb490..3c7235a26f 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -23,19 +23,30 @@ Item Item { anchors.horizontalCenter: parent.horizontalCenter - width: openFileButton.width + itemRowBackground.width + width: openFileButtonBackground.width + itemRowBackground.width height: parent.height - Button + Rectangle { - id: openFileButton - text: catalog.i18nc("@action:button", "Open File") - iconSource: UM.Theme.getIcon("load") - style: UM.Theme.styles.tool_button - tooltip: "" - action: Cura.Actions.open + id: openFileButtonBackground + height: UM.Theme.getSize("stage_menu").height + width: UM.Theme.getSize("stage_menu").height + + radius: UM.Theme.getSize("default_radius").width + color: UM.Theme.getColor("toolbar_background") + Button + { + id: openFileButton + text: catalog.i18nc("@action:button", "Open File") + iconSource: UM.Theme.getIcon("load") + style: UM.Theme.styles.toolbar_button + tooltip: "" + action: Cura.Actions.open + anchors.centerIn: parent + } } + Rectangle { id: itemRowBackground @@ -46,7 +57,7 @@ Item width: itemRow.width + UM.Theme.getSize("default_margin").width height: parent.height - anchors.left: openFileButton.right + anchors.left: openFileButtonBackground.right anchors.leftMargin: UM.Theme.getSize("default_margin").width RowLayout @@ -57,6 +68,7 @@ Item width: 0.9 * prepareMenu.width height: parent.height + spacing: 0 Cura.MachineSelector { From 13a9bb7eba2abf2a2790f732165b557ff7d4ec71 Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Tue, 13 Nov 2018 17:03:27 +0100 Subject: [PATCH 0198/1292] Remove enables for min. support area in case of TreeSupport. [CURA-5903] --- 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 e67608f579..325e4b6c79 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -4402,7 +4402,7 @@ "minimum_value": "0", "minimum_value_warning": "minimum_support_area", "limit_to_extruder": "support_interface_extruder_nr", - "enabled": "support_interface_enable and (support_enable or support_tree_enable)", + "enabled": "support_interface_enable and support_enable", "settable_per_mesh": true, "children": { @@ -4417,7 +4417,7 @@ "minimum_value": "0", "minimum_value_warning": "minimum_support_area", "limit_to_extruder": "support_roof_extruder_nr", - "enabled": "support_roof_enable and (support_enable or support_tree_enable)", + "enabled": "support_roof_enable and support_enable", "settable_per_mesh": true }, "minimum_bottom_area": @@ -4431,7 +4431,7 @@ "minimum_value": "0", "minimum_value_warning": "minimum_support_area", "limit_to_extruder": "support_bottom_extruder_nr", - "enabled": "support_bottom_enable and (support_enable or support_tree_enable)", + "enabled": "support_bottom_enable and support_enable", "settable_per_mesh": true } } From fb72f9a0594c8ac1d3e721dbad60617c227699d0 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 14 Nov 2018 09:59:56 +0100 Subject: [PATCH 0199/1292] Fixed size of expandableItem not being the correct width CURA-5785 --- plugins/PreviewStage/PreviewMenu.qml | 1 + plugins/SimulationView/SimulationViewMenuComponent.qml | 2 +- resources/qml/ExpandableComponent.qml | 2 +- .../qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index ccc0a98c6e..5b0ae4e9c5 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -121,6 +121,7 @@ Item width: UM.Theme.getSize("default_lining").width color: UM.Theme.getColor("lining") } + Cura.PrintSetupSelector { width: UM.Theme.getSize("print_setup_widget").width diff --git a/plugins/SimulationView/SimulationViewMenuComponent.qml b/plugins/SimulationView/SimulationViewMenuComponent.qml index fe9f4471fd..92a4e1e317 100644 --- a/plugins/SimulationView/SimulationViewMenuComponent.qml +++ b/plugins/SimulationView/SimulationViewMenuComponent.qml @@ -74,7 +74,7 @@ Cura.ExpandableComponent property bool only_show_top_layers: UM.Preferences.getValue("view/only_show_top_layers") property int top_layer_count: UM.Preferences.getValue("view/top_layer_count") - width: UM.Theme.getSize("layerview_menu_size").width + width: base.width - 2 * UM.Theme.getSize("default_margin").width height: childrenRect.height spacing: UM.Theme.getSize("layerview_row_spacing").height diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index 06b4146a57..c525d163fe 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -111,7 +111,7 @@ Item // Make the popup right aligned with the rest. The 3x padding is due to left, right and padding between //the button & text. x: -width + collapseButton.width + headerItemLoader.width + 3 * background.padding - + padding: UM.Theme.getSize("default_margin").width closePolicy: Popup.CloseOnPressOutsideParent background: Rectangle diff --git a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml index 7c70229b5d..721416352d 100644 --- a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml +++ b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml @@ -92,7 +92,7 @@ Cura.ExpandableComponent popupItem: Item { - width: base.width + width: base.width - 2 * UM.Theme.getSize("default_margin").width height: 200 TabBar From c35b4f1d31d295fc9d91b15167cea6ac79298bd7 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 14 Nov 2018 10:00:44 +0100 Subject: [PATCH 0200/1292] Removed old unusued code CURA-5785 --- .../QuickConfigurationSelector.qml | 62 +------------------ 1 file changed, 1 insertion(+), 61 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml index 721416352d..5565884bd8 100644 --- a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml +++ b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml @@ -233,64 +233,4 @@ Cura.ExpandableComponent } } - -} - -/*Item -{ - id: configurationSelector - property var connectedDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null - property var panelWidth: control.width - - // Make this component only visible when it's a network printer and it is connected - visible: Cura.MachineManager.activeMachineNetworkKey != "" && Cura.MachineManager.printerConnected - - function switchPopupState() - { - popup.visible ? popup.close() : popup.open() - } - - SyncButton - { - id: syncButton - onClicked: switchPopupState() - outputDevice: connectedDevice - } - - Popup - { - // TODO Change once updating to Qt5.10 - The 'opened' property is in 5.10 but the behavior is now implemented with the visible property - id: popup - clip: true - closePolicy: Popup.CloseOnPressOutsideParent - y: configurationSelector.height - UM.Theme.getSize("default_lining").height - x: configurationSelector.width - width - width: panelWidth - visible: false - padding: UM.Theme.getSize("default_lining").width - transformOrigin: Popup.Top - contentItem: ConfigurationListView - { - id: configList - width: panelWidth - 2 * popup.padding - outputDevice: connectedDevice - } - background: Rectangle - { - color: UM.Theme.getColor("setting_control") - border.color: UM.Theme.getColor("setting_control_border") - } - exit: Transition - { - // This applies a default NumberAnimation to any changes a state change makes to x or y properties - NumberAnimation { property: "visible"; duration: 75; } - } - enter: Transition - { - // This applies a default NumberAnimation to any changes a state change makes to x or y properties - NumberAnimation { property: "visible"; duration: 75; } - } - onClosed: visible = false - onOpened: visible = true - } -}*/ \ No newline at end of file +} \ No newline at end of file From 878b7432327e92f2081f153d28063c42e6905c0c Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 14 Nov 2018 10:39:03 +0100 Subject: [PATCH 0201/1292] Add elide to machine selector label. CURA-5785 --- resources/qml/MachineSelector.qml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/resources/qml/MachineSelector.qml b/resources/qml/MachineSelector.qml index 206229e837..87a3154338 100644 --- a/resources/qml/MachineSelector.qml +++ b/resources/qml/MachineSelector.qml @@ -25,14 +25,12 @@ Cura.ExpandableComponent name: "cura" } - headerItem: Item + headerItem: Label { - Label - { - text: isNetworkPrinter ? Cura.MachineManager.activeMachineNetworkGroupName : Cura.MachineManager.activeMachineName - verticalAlignment: Text.AlignVCenter - height: parent.height - } + text: isNetworkPrinter ? Cura.MachineManager.activeMachineNetworkGroupName : Cura.MachineManager.activeMachineName + verticalAlignment: Text.AlignVCenter + height: parent.height + elide: Text.ElideRight } popupItem: Item From fcfe95c7d0a7217bd5793ee5e5148b835bae29c4 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 14 Nov 2018 12:57:57 +0100 Subject: [PATCH 0202/1292] Move OpenFile button to be instantiated left so it's tooltip doesn't get messed up CURA-5785 --- plugins/PrepareStage/PrepareMenu.qml | 43 ++++++++++++++-------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index 3c7235a26f..78f9ced1e7 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -26,27 +26,6 @@ Item width: openFileButtonBackground.width + itemRowBackground.width height: parent.height - Rectangle - { - id: openFileButtonBackground - height: UM.Theme.getSize("stage_menu").height - width: UM.Theme.getSize("stage_menu").height - - radius: UM.Theme.getSize("default_radius").width - color: UM.Theme.getColor("toolbar_background") - Button - { - id: openFileButton - text: catalog.i18nc("@action:button", "Open File") - iconSource: UM.Theme.getIcon("load") - style: UM.Theme.styles.toolbar_button - tooltip: "" - action: Cura.Actions.open - anchors.centerIn: parent - } - } - - Rectangle { id: itemRowBackground @@ -73,7 +52,7 @@ Item Cura.MachineSelector { id: machineSelection - z: openFileButton.z - 1 + z: openFileButtonBackground.z - 1 Layout.minimumWidth: 240 Layout.maximumWidth: 240 @@ -118,5 +97,25 @@ Item } } } + + Rectangle + { + id: openFileButtonBackground + height: UM.Theme.getSize("stage_menu").height + width: UM.Theme.getSize("stage_menu").height + + radius: UM.Theme.getSize("default_radius").width + color: UM.Theme.getColor("toolbar_background") + Button + { + id: openFileButton + text: catalog.i18nc("@action:button", "Open File") + iconSource: UM.Theme.getIcon("load") + style: UM.Theme.styles.toolbar_button + tooltip: "" + action: Cura.Actions.open + anchors.centerIn: parent + } + } } } \ No newline at end of file From ae2b3124721c9c74730073d178c0ac1927819b1c Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 14 Nov 2018 13:41:23 +0100 Subject: [PATCH 0203/1292] Add typing for all version upgrade plug-ins Hopefully we'll take this typing along when we next copy-paste the stuffs. Contributes to issue CURA-5936. --- .../VersionUpgrade21to22/MachineInstance.py | 17 ++--- .../VersionUpgrade21to22/Preferences.py | 9 +-- .../VersionUpgrade21to22/Profile.py | 11 ++- .../VersionUpgrade21to22.py | 69 ++++++++++--------- .../VersionUpgrade21to22/__init__.py | 11 ++- .../VersionUpgrade22to24/VersionUpgrade.py | 20 +++--- .../VersionUpgrade22to24/__init__.py | 11 ++- .../VersionUpgrade25to26.py | 26 +++---- .../VersionUpgrade25to26/__init__.py | 11 ++- .../VersionUpgrade26to27.py | 13 ++-- .../VersionUpgrade26to27/__init__.py | 11 ++- .../VersionUpgrade27to30.py | 21 +++--- .../VersionUpgrade27to30/__init__.py | 11 ++- .../VersionUpgrade30to31.py | 19 ++--- .../VersionUpgrade30to31/__init__.py | 11 ++- .../VersionUpgrade32to33.py | 21 +++--- .../VersionUpgrade32to33/__init__.py | 9 ++- .../VersionUpgrade33to34.py | 8 +-- .../VersionUpgrade33to34/__init__.py | 9 ++- .../VersionUpgrade34to35.py | 23 +++---- .../VersionUpgrade34to35/__init__.py | 9 ++- 21 files changed, 200 insertions(+), 150 deletions(-) diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py b/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py index 37b6989add..a947114595 100644 --- a/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py +++ b/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py @@ -1,15 +1,16 @@ -# Copyright (c) 2016 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -import UM.VersionUpgrade #To indicate that a file is of incorrect format. -import UM.VersionUpgradeManager #To schedule more files to be upgraded. -from UM.Resources import Resources #To get the config storage path. - import configparser #To read config files. import io #To write config files to strings as if they were files. import os.path #To get the path to write new user profiles to. +from typing import List, Optional, Tuple import urllib #To serialise the user container file name properly. +import UM.VersionUpgrade #To indicate that a file is of incorrect format. +import UM.VersionUpgradeManager #To schedule more files to be upgraded. +from UM.Resources import Resources #To get the config storage path. + ## Creates a new machine instance instance by parsing a serialised machine # instance in version 1 of the file format. # @@ -18,7 +19,7 @@ import urllib #To serialise the user container file name properly. # extension. # \return A machine instance instance, or None if the file format is # incorrect. -def importFrom(serialised, filename): +def importFrom(serialised: str, filename: str) -> Optional["MachineInstance"]: try: return MachineInstance(serialised, filename) except (configparser.Error, UM.VersionUpgrade.FormatException, UM.VersionUpgrade.InvalidVersionException): @@ -32,7 +33,7 @@ class MachineInstance: # \param serialised A string with the contents of a machine instance file, # without extension. # \param filename The supposed file name of this machine instance. - def __init__(self, serialised, filename): + def __init__(self, serialised: str, filename: str) -> str: self._filename = filename config = configparser.ConfigParser(interpolation = None) @@ -67,7 +68,7 @@ class MachineInstance: # # \return A tuple containing the new filename and a serialised form of # this machine instance, serialised in version 2 of the file format. - def export(self): + def export(self) -> Tuple[List[str], List[str]]: config = configparser.ConfigParser(interpolation = None) # Build a config file in the form of version 2. config.add_section("general") diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/Preferences.py b/plugins/VersionUpgrade/VersionUpgrade21to22/Preferences.py index 842499da86..51e4b617e8 100644 --- a/plugins/VersionUpgrade/VersionUpgrade21to22/Preferences.py +++ b/plugins/VersionUpgrade/VersionUpgrade21to22/Preferences.py @@ -1,8 +1,9 @@ -# Copyright (c) 2016 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import configparser #To read config files. import io #To output config files to string. +from typing import List, Optional, Tuple import UM.VersionUpgrade #To indicate that a file is of the wrong format. @@ -14,7 +15,7 @@ import UM.VersionUpgrade #To indicate that a file is of the wrong format. # extension. # \return A representation of those preferences, or None if the file format is # incorrect. -def importFrom(serialised, filename): +def importFrom(serialised: str, filename: str) -> Optional["Preferences"]: try: return Preferences(serialised, filename) except (configparser.Error, UM.VersionUpgrade.FormatException, UM.VersionUpgrade.InvalidVersionException): @@ -28,7 +29,7 @@ class Preferences: # \param serialised A serialised version 2 preferences file. # \param filename The supposed filename of the preferences file, without # extension. - def __init__(self, serialised, filename): + def __init__(self, serialised: str, filename: str) -> None: self._filename = filename self._config = configparser.ConfigParser(interpolation = None) @@ -50,7 +51,7 @@ class Preferences: # # \return A tuple containing the new filename and a serialised version of # a preferences file in version 3. - def export(self): + def export(self) -> Tuple[List[str], List[str]]: #Reset the cura/categories_expanded property since it works differently now. if self._config.has_section("cura") and self._config.has_option("cura", "categories_expanded"): self._config.remove_option("cura", "categories_expanded") diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/Profile.py b/plugins/VersionUpgrade/VersionUpgrade21to22/Profile.py index 161edcb67c..af9635d384 100644 --- a/plugins/VersionUpgrade/VersionUpgrade21to22/Profile.py +++ b/plugins/VersionUpgrade/VersionUpgrade21to22/Profile.py @@ -1,10 +1,9 @@ -# Copyright (c) 2016 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import configparser #To read config files. import io #To write config files to strings as if they were files. -from typing import Dict -from typing import List +from typing import Dict, List, Optional, Tuple import UM.VersionUpgrade from UM.Logger import Logger @@ -15,7 +14,7 @@ from UM.Logger import Logger # \param serialised The serialised form of a profile in version 1. # \param filename The supposed filename of the profile, without extension. # \return A profile instance, or None if the file format is incorrect. -def importFrom(serialised, filename): +def importFrom(serialised: str, filename: str) -> Optional["Profile"]: try: return Profile(serialised, filename) except (configparser.Error, UM.VersionUpgrade.FormatException, UM.VersionUpgrade.InvalidVersionException): @@ -77,11 +76,11 @@ class Profile: # # \return A tuple containing the new filename and a serialised form of # this profile, serialised in version 2 of the file format. - def export(self): + def export(self) -> Optional[Tuple[List[str], List[str]]]: import VersionUpgrade21to22 # Import here to prevent circular dependencies. if self._name == "Current settings": - return None, None #Can't upgrade these, because the new current profile needs to specify the definition ID and the old file only had the machine instance, not the definition. + return None #Can't upgrade these, because the new current profile needs to specify the definition ID and the old file only had the machine instance, not the definition. config = configparser.ConfigParser(interpolation = None) diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/VersionUpgrade21to22.py b/plugins/VersionUpgrade/VersionUpgrade21to22/VersionUpgrade21to22.py index d8036491bf..89c847e606 100644 --- a/plugins/VersionUpgrade/VersionUpgrade21to22/VersionUpgrade21to22.py +++ b/plugins/VersionUpgrade/VersionUpgrade21to22/VersionUpgrade21to22.py @@ -1,7 +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 configparser #To get version numbers from config files. +from typing import Dict, Iterable, List, Optional, Set, Tuple from UM.VersionUpgrade import VersionUpgrade # Superclass of the plugin. @@ -30,7 +31,7 @@ _machines_with_machine_quality = { "materials": { "generic_abs", "generic_cpe", "generic_pla", "generic_pva", "generic_cpe_plus", "generic_nylon", "generic_pc", "generic_tpu" }, "variants": { "0.25 mm", "0.4 mm", "0.6 mm", "0.8 mm" } } -} +} # type: Dict[str, Dict[str, Set[str]]] ## How to translate material names from the old version to the new. _material_translations = { @@ -41,7 +42,7 @@ _material_translations = { "Nylon": "generic_nylon", "PC": "generic_pc", "TPU": "generic_tpu", -} +} # type: Dict[str, str] ## How to translate material names for in the profile names. _material_translations_profiles = { @@ -52,17 +53,17 @@ _material_translations_profiles = { "Nylon": "nylon", "PC": "pc", "TPU": "tpu", -} +} # type: Dict[str, str] ## How to translate printer names from the old version to the new. _printer_translations = { "ultimaker2plus": "ultimaker2_plus" -} +} # type: Dict[str, str] _printer_translations_profiles = { "ultimaker2plus": "um2p", #Does NOT get included in PLA profiles! "ultimaker2_extended_plus": "um2ep" #Has no profiles for CPE+, Nylon, PC and TPU! -} +} # type: Dict[str, str] ## How to translate profile names from the old version to the new. # @@ -116,13 +117,13 @@ _profile_translations = { "tpu_0.25_high": "um2p_tpu_0.25_high", "tpu_0.4_normal": "um2p_tpu_0.4_normal", "tpu_0.6_fast": "um2p_tpu_0.6_fast" -} +} # type: Dict[str, str] ## Settings that are no longer in the new version. _removed_settings = { "fill_perimeter_gaps", "support_area_smoothing" -} +} # type: Set[str] ## How to translate setting names from the old version to the new. _setting_name_translations = { @@ -142,7 +143,7 @@ _setting_name_translations = { "support_roof_line_distance": "support_interface_line_distance", "support_roof_line_width": "support_interface_line_width", "support_roof_pattern": "support_interface_pattern" -} +} # type: Dict[str, str] ## Custom profiles become quality_changes. This dictates which quality to base # the quality_changes profile on. @@ -190,7 +191,7 @@ _quality_fallbacks = { #No TPU. } } -} +} # type: Dict[str, Dict[str, Dict[str, str]]] ## How to translate variants of specific machines from the old version to the # new. @@ -207,7 +208,7 @@ _variant_translations = { "0.6 mm": "ultimaker2_extended_plus_0.6", "0.8 mm": "ultimaker2_extended_plus_0.8" } -} +} # type: Dict[str, Dict[str, str]] ## How to translate variant names for in the profile names. _variant_translations_profiles = { @@ -215,7 +216,7 @@ _variant_translations_profiles = { "0.4 mm": "0.4", "0.6 mm": "0.6", "0.8 mm": "0.8" -} +} # type: Dict[str, str] ## Cura 2.2's material profiles use a different naming scheme for variants. # @@ -233,7 +234,7 @@ _variant_translations_materials = { "0.6 mm": "ultimaker2_plus_0.6_mm", "0.8 mm": "ultimaker2_plus_0.8_mm" } -} +} # type: Dict[str, Dict[str, str]] ## Converts configuration from Cura 2.1's file formats to Cura 2.2's. # @@ -245,8 +246,8 @@ class VersionUpgrade21to22(VersionUpgrade): # number is stored in general/version, so get the data from that key. # # \param serialised The contents of a config file. - # \return \type{int} The version number of that config file. - def getCfgVersion(self, serialised): + # \return The version number of that config file. + def getCfgVersion(self, serialised: str) -> int: parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialised) format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised. @@ -263,7 +264,7 @@ class VersionUpgrade21to22(VersionUpgrade): # \param variant The variant ID of the user's configuration in 2.2. # \param material The material ID of the user's configuration in 2.2. @staticmethod - def getQualityFallback(machine, variant, material): + def getQualityFallback(machine: str, variant: str, material: str) -> str: if machine not in _quality_fallbacks: return "normal" if variant not in _quality_fallbacks[machine]: @@ -277,14 +278,14 @@ class VersionUpgrade21to22(VersionUpgrade): # This is required to test if profiles should be converted to a quality # profile or a quality-changes profile. @staticmethod - def builtInProfiles(): + def builtInProfiles() -> Iterable[str]: return _profile_translations.keys() ## Gets a set of the machines which now have per-material quality profiles. # # \return A set of machine identifiers. @staticmethod - def machinesWithMachineQuality(): + def machinesWithMachineQuality() -> Dict[str, Dict[str, Set[str]]]: return _machines_with_machine_quality ## Converts machine instances from format version 1 to version 2. @@ -295,10 +296,10 @@ class VersionUpgrade21to22(VersionUpgrade): # \return A tuple containing the new filename and the serialised machine # instance in version 2, or None if the input was not of the correct # format. - def upgradeMachineInstance(self, serialised, filename): + def upgradeMachineInstance(self, serialised: str, filename: str) -> Optional[Tuple[List[str], List[str]]]: machine_instance = MachineInstance.importFrom(serialised, filename) if not machine_instance: #Invalid file format. - return filename, None + return None return machine_instance.export() ## Converts preferences from format version 2 to version 3. @@ -309,10 +310,10 @@ class VersionUpgrade21to22(VersionUpgrade): # \return A tuple containing the new filename and the serialised # preferences in version 3, or None if the input was not of the correct # format. - def upgradePreferences(self, serialised, filename): + def upgradePreferences(self, serialised: str, filename: str) -> Optional[Tuple[List[str], List[str]]]: preferences = Preferences.importFrom(serialised, filename) if not preferences: #Invalid file format. - return filename, None + return None return preferences.export() ## Converts profiles from format version 1 to version 2. @@ -322,10 +323,10 @@ class VersionUpgrade21to22(VersionUpgrade): # extension. # \return A tuple containing the new filename and the serialised profile # in version 2, or None if the input was not of the correct format. - def upgradeProfile(self, serialised, filename): + def upgradeProfile(self, serialised: str, filename: str) -> Optional[Tuple[List[str], List[str]]]: profile = Profile.importFrom(serialised, filename) if not profile: # Invalid file format. - return filename, None + return None return profile.export() ## Translates a material name for the change from Cura 2.1 to 2.2. @@ -333,7 +334,7 @@ class VersionUpgrade21to22(VersionUpgrade): # \param material A material name in Cura 2.1. # \return The name of the corresponding material in Cura 2.2. @staticmethod - def translateMaterial(material): + def translateMaterial(material: str) -> str: if material in _material_translations: return _material_translations[material] return material @@ -345,7 +346,7 @@ class VersionUpgrade21to22(VersionUpgrade): # \return The name of the corresponding material in the quality profiles # in Cura 2.2. @staticmethod - def translateMaterialForProfiles(material): + def translateMaterialForProfiles(material: str) -> str: if material in _material_translations_profiles: return _material_translations_profiles[material] return material @@ -356,7 +357,7 @@ class VersionUpgrade21to22(VersionUpgrade): # \param printer A printer name in Cura 2.1. # \return The name of the corresponding printer in Cura 2.2. @staticmethod - def translatePrinter(printer): + def translatePrinter(printer: str) -> str: if printer in _printer_translations: return _printer_translations[printer] return printer #Doesn't need to be translated. @@ -367,7 +368,7 @@ class VersionUpgrade21to22(VersionUpgrade): # \param printer A printer name in 2.1. # \return The name of the corresponding printer in Cura 2.2. @staticmethod - def translatePrinterForProfile(printer): + def translatePrinterForProfile(printer: str) -> str: if printer in _printer_translations_profiles: return _printer_translations_profiles[printer] return printer @@ -378,7 +379,7 @@ class VersionUpgrade21to22(VersionUpgrade): # \param profile A profile name in the old version. # \return The corresponding profile name in the new version. @staticmethod - def translateProfile(profile): + def translateProfile(profile: str) -> str: if profile in _profile_translations: return _profile_translations[profile] return profile #Doesn't need to be translated. @@ -392,7 +393,7 @@ class VersionUpgrade21to22(VersionUpgrade): # \param settings A dictionary of settings (as key-value pairs) to update. # \return The same dictionary. @staticmethod - def translateSettings(settings): + def translateSettings(settings: Dict[str, str]) -> Dict[str, str]: new_settings = {} for key, value in settings.items(): if key in _removed_settings: @@ -414,7 +415,7 @@ class VersionUpgrade21to22(VersionUpgrade): # \param setting The name of a setting in Cura 2.1. # \return The name of the corresponding setting in Cura 2.2. @staticmethod - def translateSettingName(setting): + def translateSettingName(setting: str) -> str: if setting in _setting_name_translations: return _setting_name_translations[setting] return setting #Doesn't need to be translated. @@ -426,7 +427,7 @@ class VersionUpgrade21to22(VersionUpgrade): # 2.2's naming. # \return The name of the corresponding variant in Cura 2.2. @staticmethod - def translateVariant(variant, machine): + def translateVariant(variant: str, machine: str) -> str: if machine in _variant_translations and variant in _variant_translations[machine]: return _variant_translations[machine][variant] return variant @@ -440,7 +441,7 @@ class VersionUpgrade21to22(VersionUpgrade): # \return The name of the corresponding variant for in material profiles # in Cura 2.2. @staticmethod - def translateVariantForMaterials(variant, machine): + def translateVariantForMaterials(variant: str, machine: str) -> str: if machine in _variant_translations_materials and variant in _variant_translations_materials[machine]: return _variant_translations_materials[machine][variant] return variant @@ -452,7 +453,7 @@ class VersionUpgrade21to22(VersionUpgrade): # \return The name of the corresponding variant for in quality profiles in # Cura 2.2. @staticmethod - def translateVariantForProfiles(variant): + def translateVariantForProfiles(variant: str) -> str: if variant in _variant_translations_profiles: return _variant_translations_profiles[variant] return variant \ No newline at end of file diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/__init__.py b/plugins/VersionUpgrade/VersionUpgrade21to22/__init__.py index 609781ebfe..67530b9d45 100644 --- a/plugins/VersionUpgrade/VersionUpgrade21to22/__init__.py +++ b/plugins/VersionUpgrade/VersionUpgrade21to22/__init__.py @@ -1,11 +1,16 @@ -# Copyright (c) 2016 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +from typing import Any, Dict, TYPE_CHECKING + from . import VersionUpgrade21to22 +if TYPE_CHECKING: + from UM.Application import Application + upgrade = VersionUpgrade21to22.VersionUpgrade21to22() -def getMetaData(): +def getMetaData() -> Dict[str, Any]: return { "version_upgrade": { # From To Upgrade function @@ -33,5 +38,5 @@ def getMetaData(): } } -def register(app): +def register(app: "Application") -> Dict[str, Any]: return { "version_upgrade": upgrade } diff --git a/plugins/VersionUpgrade/VersionUpgrade22to24/VersionUpgrade.py b/plugins/VersionUpgrade/VersionUpgrade22to24/VersionUpgrade.py index a56f1f807b..48af365877 100644 --- a/plugins/VersionUpgrade/VersionUpgrade22to24/VersionUpgrade.py +++ b/plugins/VersionUpgrade/VersionUpgrade22to24/VersionUpgrade.py @@ -1,18 +1,18 @@ -# Copyright (c) 2017 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import configparser #To get version numbers from config files. +import io import os import os.path -import io +from typing import Dict, List, Optional, Tuple from UM.Resources import Resources from UM.VersionUpgrade import VersionUpgrade # Superclass of the plugin. import UM.VersionUpgrade class VersionUpgrade22to24(VersionUpgrade): - - def upgradeMachineInstance(self, serialised, filename): + def upgradeMachineInstance(self, serialised: str, filename: str) -> Optional[Tuple[List[str], List[str]]]: # All of this is needed to upgrade custom variant machines from old Cura to 2.4 where # `definition_changes` instance container has been introduced. Variant files which # look like the the handy work of the old machine settings plugin are converted directly @@ -71,7 +71,7 @@ class VersionUpgrade22to24(VersionUpgrade): config.write(output) return [filename], [output.getvalue()] - def __convertVariant(self, variant_path): + def __convertVariant(self, variant_path: str) -> str: # Copy the variant to the machine_instances/*_settings.inst.cfg variant_config = configparser.ConfigParser(interpolation = None) with open(variant_path, "r", encoding = "utf-8") as fhandle: @@ -99,7 +99,7 @@ class VersionUpgrade22to24(VersionUpgrade): return config_name - def __getUserVariants(self): + def __getUserVariants(self) -> List[Dict[str, str]]: resource_path = Resources.getDataStoragePath() variants_dir = os.path.join(resource_path, "variants") @@ -113,7 +113,7 @@ class VersionUpgrade22to24(VersionUpgrade): result.append( { "path": entry.path, "name": config.get("general", "name") } ) return result - def upgradeExtruderTrain(self, serialised, filename): + def upgradeExtruderTrain(self, serialised: str, filename: str) -> Tuple[List[str], List[str]]: config = configparser.ConfigParser(interpolation = None) config.read_string(serialised) # Read the input string as config file. config.set("general", "version", "3") # Just bump the version number. That is all we need for now. @@ -122,7 +122,7 @@ class VersionUpgrade22to24(VersionUpgrade): config.write(output) return [filename], [output.getvalue()] - def upgradePreferences(self, serialised, filename): + def upgradePreferences(self, serialised: str, filename: str) -> Tuple[List[str], List[str]]: config = configparser.ConfigParser(interpolation = None) config.read_string(serialised) @@ -142,7 +142,7 @@ class VersionUpgrade22to24(VersionUpgrade): config.write(output) return [filename], [output.getvalue()] - def upgradeQuality(self, serialised, filename): + def upgradeQuality(self, serialised: str, filename: str) -> Tuple[List[str], List[str]]: config = configparser.ConfigParser(interpolation = None) config.read_string(serialised) # Read the input string as config file. config.set("metadata", "type", "quality_changes") # Update metadata/type to quality_changes @@ -152,7 +152,7 @@ class VersionUpgrade22to24(VersionUpgrade): config.write(output) return [filename], [output.getvalue()] - def getCfgVersion(self, serialised): + def getCfgVersion(self, serialised: str) -> int: parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialised) format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised. diff --git a/plugins/VersionUpgrade/VersionUpgrade22to24/__init__.py b/plugins/VersionUpgrade/VersionUpgrade22to24/__init__.py index 278b660ec1..fe79333544 100644 --- a/plugins/VersionUpgrade/VersionUpgrade22to24/__init__.py +++ b/plugins/VersionUpgrade/VersionUpgrade22to24/__init__.py @@ -1,11 +1,16 @@ -# Copyright (c) 2016 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +from typing import Any, Dict, TYPE_CHECKING + from . import VersionUpgrade +if TYPE_CHECKING: + from UM.Application import Application + upgrade = VersionUpgrade.VersionUpgrade22to24() -def getMetaData(): +def getMetaData() -> Dict[str, Any]: return { "version_upgrade": { # From To Upgrade function @@ -26,5 +31,5 @@ def getMetaData(): } } -def register(app): +def register(app: "Application"): return { "version_upgrade": upgrade } diff --git a/plugins/VersionUpgrade/VersionUpgrade25to26/VersionUpgrade25to26.py b/plugins/VersionUpgrade/VersionUpgrade25to26/VersionUpgrade25to26.py index 6643edb765..5c9b94cca3 100644 --- a/plugins/VersionUpgrade/VersionUpgrade25to26/VersionUpgrade25to26.py +++ b/plugins/VersionUpgrade/VersionUpgrade25to26/VersionUpgrade25to26.py @@ -4,6 +4,7 @@ import configparser #To parse the files we need to upgrade and write the new files. import io #To serialise configparser output to a string. import os +from typing import Dict, List, Set, Tuple from urllib.parse import quote_plus from UM.Resources import Resources @@ -12,19 +13,18 @@ from UM.VersionUpgrade import VersionUpgrade _removed_settings = { #Settings that were removed in 2.5. "start_layers_at_same_position", "sub_div_rad_mult" -} +} # type: Set[str] _split_settings = { #These settings should be copied to all settings it was split into. "support_interface_line_distance": {"support_roof_line_distance", "support_bottom_line_distance"} -} +} # type: Dict[str, Set[str]] ## A collection of functions that convert the configuration of the user in Cura # 2.5 to a configuration for Cura 2.6. # # All of these methods are essentially stateless. class VersionUpgrade25to26(VersionUpgrade): - - def __init__(self): + def __init__(self) -> None: super().__init__() self._current_fdm_printer_count = 2 @@ -39,7 +39,7 @@ class VersionUpgrade25to26(VersionUpgrade): # \raises ValueError The format of the version number in the file is # incorrect. # \raises KeyError The format of the file is incorrect. - def getCfgVersion(self, serialised): + def getCfgVersion(self, serialised: str) -> int: parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialised) format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised. @@ -50,7 +50,7 @@ class VersionUpgrade25to26(VersionUpgrade): # # \param serialised The serialised form of a preferences file. # \param filename The name of the file to upgrade. - def upgradePreferences(self, serialised, filename): + def upgradePreferences(self, serialised: str, filename: str) -> Tuple[List[str], List[str]]: parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialised) @@ -86,7 +86,7 @@ class VersionUpgrade25to26(VersionUpgrade): # # \param serialised The serialised form of a quality profile. # \param filename The name of the file to upgrade. - def upgradeInstanceContainer(self, serialised, filename): + def upgradeInstanceContainer(self, serialised: str, filename: str) -> Tuple[List[str], List[str]]: parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialised) @@ -116,7 +116,7 @@ class VersionUpgrade25to26(VersionUpgrade): # # \param serialised The serialised form of a quality profile. # \param filename The name of the file to upgrade. - def upgradeMachineStack(self, serialised, filename): + def upgradeMachineStack(self, serialised: str, filename: str) -> Tuple[List[str], List[str]]: parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialised) @@ -149,7 +149,7 @@ class VersionUpgrade25to26(VersionUpgrade): return [filename], [output.getvalue()] ## Acquires the next unique extruder stack index number for the Custom FDM Printer. - def _acquireNextUniqueCustomFdmPrinterExtruderStackIdIndex(self): + def _acquireNextUniqueCustomFdmPrinterExtruderStackIdIndex(self) -> int: extruder_stack_dir = os.path.join(Resources.getDataStoragePath(), "extruders") file_name_list = os.listdir(extruder_stack_dir) file_name_list = [os.path.basename(file_name) for file_name in file_name_list] @@ -169,7 +169,7 @@ class VersionUpgrade25to26(VersionUpgrade): return self._current_fdm_printer_count - def _checkCustomFdmPrinterHasExtruderStack(self, machine_id): + def _checkCustomFdmPrinterHasExtruderStack(self, machine_id: str) -> bool: # go through all extruders and make sure that this custom FDM printer has extruder stacks. extruder_stack_dir = os.path.join(Resources.getDataStoragePath(), "extruders") has_extruders = False @@ -197,7 +197,7 @@ class VersionUpgrade25to26(VersionUpgrade): return has_extruders - def _createCustomFdmPrinterExtruderStack(self, machine_id: str, position: int, quality_id: str, material_id: str): + def _createCustomFdmPrinterExtruderStack(self, machine_id: str, position: int, quality_id: str, material_id: str) -> None: stack_id = "custom_extruder_%s" % (position + 1) if self._current_fdm_printer_count > 1: stack_id += " #%s" % self._current_fdm_printer_count @@ -256,7 +256,7 @@ class VersionUpgrade25to26(VersionUpgrade): ## Creates a definition changes container which doesn't contain anything for the Custom FDM Printers. # The container ID will be automatically generated according to the given stack name. - def _getCustomFdmPrinterDefinitionChanges(self, stack_id: str): + def _getCustomFdmPrinterDefinitionChanges(self, stack_id: str) -> configparser.ConfigParser: # In 2.5, there is no definition_changes container for the Custom FDM printer, so it should be safe to use the # default name unless some one names the printer as something like "Custom FDM Printer_settings". definition_changes_id = stack_id + "_settings" @@ -277,7 +277,7 @@ class VersionUpgrade25to26(VersionUpgrade): ## Creates a user settings container which doesn't contain anything for the Custom FDM Printers. # The container ID will be automatically generated according to the given stack name. - def _getCustomFdmPrinterUserSettings(self, stack_id: str): + def _getCustomFdmPrinterUserSettings(self, stack_id: str) -> configparser.ConfigParser: # For the extruder stacks created in the upgrade, also create user_settings containers so the user changes # will be saved. user_settings_id = stack_id + "_user" diff --git a/plugins/VersionUpgrade/VersionUpgrade25to26/__init__.py b/plugins/VersionUpgrade/VersionUpgrade25to26/__init__.py index 67aa73233f..c74b3218b6 100644 --- a/plugins/VersionUpgrade/VersionUpgrade25to26/__init__.py +++ b/plugins/VersionUpgrade/VersionUpgrade25to26/__init__.py @@ -1,11 +1,16 @@ -# Copyright (c) 2017 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +from typing import Any, Dict, TYPE_CHECKING + from . import VersionUpgrade25to26 +if TYPE_CHECKING: + from UM.Application import Application + upgrade = VersionUpgrade25to26.VersionUpgrade25to26() -def getMetaData(): +def getMetaData() -> Dict[str, Any]: return { "version_upgrade": { # From To Upgrade function @@ -41,5 +46,5 @@ def getMetaData(): } } -def register(app): +def register(app: "Application") -> Dict[str, Any]: return { "version_upgrade": upgrade } diff --git a/plugins/VersionUpgrade/VersionUpgrade26to27/VersionUpgrade26to27.py b/plugins/VersionUpgrade/VersionUpgrade26to27/VersionUpgrade26to27.py index dfa436e5bd..96307ca43c 100644 --- a/plugins/VersionUpgrade/VersionUpgrade26to27/VersionUpgrade26to27.py +++ b/plugins/VersionUpgrade/VersionUpgrade26to27/VersionUpgrade26to27.py @@ -3,6 +3,7 @@ import configparser #To parse the files we need to upgrade and write the new files. import io #To serialise configparser output to a string. +from typing import Dict, List, Tuple from UM.VersionUpgrade import VersionUpgrade @@ -61,7 +62,7 @@ _renamed_quality_profiles = { "um3_bb0.8_TPU_Not_Supported_Quality": "um3_bb0.8_TPU_Fast_print", "um3_bb0.8_TPU_Not_Supported_Superdraft_Quality": "um3_bb0.8_TPU_Superdraft_Print", -} +} # type: Dict[str, str] ## A collection of functions that convert the configuration of the user in Cura # 2.6 to a configuration for Cura 2.7. @@ -79,7 +80,7 @@ class VersionUpgrade26to27(VersionUpgrade): # \raises ValueError The format of the version number in the file is # incorrect. # \raises KeyError The format of the file is incorrect. - def getCfgVersion(self, serialised): + def getCfgVersion(self, serialised: str) -> int: parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialised) format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised. @@ -90,7 +91,7 @@ class VersionUpgrade26to27(VersionUpgrade): # # \param serialised The serialised form of a preferences file. # \param filename The name of the file to upgrade. - def upgradePreferences(self, serialised, filename): + def upgradePreferences(self, serialised: str, filename: str) -> Tuple[List[str], List[str]]: parser = configparser.ConfigParser(interpolation=None) parser.read_string(serialised) @@ -117,8 +118,8 @@ class VersionUpgrade26to27(VersionUpgrade): # # \param serialised The serialised form of a container file. # \param filename The name of the file to upgrade. - def upgradeOtherContainer(self, serialised, filename): - parser = configparser.ConfigParser(interpolation=None) + def upgradeOtherContainer(self, serialised: str, filename: str) -> Tuple[List[str], List[str]]: + parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialised) # Update version numbers @@ -139,7 +140,7 @@ class VersionUpgrade26to27(VersionUpgrade): # # \param serialised The serialised form of a container stack. # \param filename The name of the file to upgrade. - def upgradeStack(self, serialised, filename): + def upgradeStack(self, serialised: str, filename: str) -> Tuple[List[str], List[str]]: parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialised) diff --git a/plugins/VersionUpgrade/VersionUpgrade26to27/__init__.py b/plugins/VersionUpgrade/VersionUpgrade26to27/__init__.py index 0e26ca8bbf..1952c9ceff 100644 --- a/plugins/VersionUpgrade/VersionUpgrade26to27/__init__.py +++ b/plugins/VersionUpgrade/VersionUpgrade26to27/__init__.py @@ -1,11 +1,16 @@ -# Copyright (c) 2017 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +from typing import Any, Dict, TYPE_CHECKING + from . import VersionUpgrade26to27 +if TYPE_CHECKING: + from UM.Application import Application + upgrade = VersionUpgrade26to27.VersionUpgrade26to27() -def getMetaData(): +def getMetaData() -> Dict[str, Any]: return { "version_upgrade": { # From To Upgrade function @@ -59,5 +64,5 @@ def getMetaData(): } } -def register(app): +def register(app: "Application") -> Dict[str, Any]: return { "version_upgrade": upgrade } diff --git a/plugins/VersionUpgrade/VersionUpgrade27to30/VersionUpgrade27to30.py b/plugins/VersionUpgrade/VersionUpgrade27to30/VersionUpgrade27to30.py index 5a141f1558..c9e9e41f7e 100644 --- a/plugins/VersionUpgrade/VersionUpgrade27to30/VersionUpgrade27to30.py +++ b/plugins/VersionUpgrade/VersionUpgrade27to30/VersionUpgrade27to30.py @@ -1,9 +1,10 @@ -# Copyright (c) 2017 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import configparser #To parse preference files. import io #To serialise the preference files afterwards. import os +from typing import Dict, List, Tuple import urllib.parse import re @@ -11,7 +12,7 @@ from UM.VersionUpgrade import VersionUpgrade #We're inheriting from this. _renamed_themes = { "cura": "cura-light" -} +} # type: Dict[str, str] _renamed_i18n = { "7s": "en_7S", "de": "de_DE", @@ -28,7 +29,7 @@ _renamed_i18n = { "ptbr": "pt_BR", "ru": "ru_RU", "tr": "tr_TR" -} +} # type: Dict[str, str] class VersionUpgrade27to30(VersionUpgrade): @@ -43,7 +44,7 @@ class VersionUpgrade27to30(VersionUpgrade): # \raises ValueError The format of the version number in the file is # incorrect. # \raises KeyError The format of the file is incorrect. - def getCfgVersion(self, serialised): + def getCfgVersion(self, serialised: str) -> int: parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialised) format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised. @@ -54,8 +55,8 @@ class VersionUpgrade27to30(VersionUpgrade): # # \param serialised The serialised form of a preferences file. # \param filename The name of the file to upgrade. - def upgradePreferences(self, serialised, filename): - parser = configparser.ConfigParser(interpolation=None) + def upgradePreferences(self, serialised: str, filename: str) -> Tuple[List[str], List[str]]: + parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialised) # Update version numbers @@ -100,8 +101,8 @@ class VersionUpgrade27to30(VersionUpgrade): # # \param serialised The serialised form of the container file. # \param filename The name of the file to upgrade. - def upgradeQualityChangesContainer(self, serialised, filename): - parser = configparser.ConfigParser(interpolation=None) + def upgradeQualityChangesContainer(self, serialised: str, filename: str) -> Tuple[List[str], List[str]]: + parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialised) # Update the skin pre-shrink settings: @@ -156,7 +157,7 @@ class VersionUpgrade27to30(VersionUpgrade): # # \param serialised The serialised form of the container file. # \param filename The name of the file to upgrade. - def upgradeOtherContainer(self, serialised, filename): + def upgradeOtherContainer(self, serialised: str, filename: str) -> Tuple[List[str], List[str]]: parser = configparser.ConfigParser(interpolation=None) parser.read_string(serialised) @@ -185,7 +186,7 @@ class VersionUpgrade27to30(VersionUpgrade): # # \param serialised The serialised form of a container stack. # \param filename The name of the file to upgrade. - def upgradeStack(self, serialised, filename): + def upgradeStack(self, serialised: str, filename: str) -> Tuple[List[str], List[str]]: parser = configparser.ConfigParser(interpolation=None) parser.read_string(serialised) diff --git a/plugins/VersionUpgrade/VersionUpgrade27to30/__init__.py b/plugins/VersionUpgrade/VersionUpgrade27to30/__init__.py index 4da7257b1c..bddc71a1e0 100644 --- a/plugins/VersionUpgrade/VersionUpgrade27to30/__init__.py +++ b/plugins/VersionUpgrade/VersionUpgrade27to30/__init__.py @@ -1,11 +1,16 @@ -# Copyright (c) 2017 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +from typing import Any, Dict, TYPE_CHECKING + from . import VersionUpgrade27to30 +if TYPE_CHECKING: + from UM.Application import Application + upgrade = VersionUpgrade27to30.VersionUpgrade27to30() -def getMetaData(): +def getMetaData() -> Dict[str, Any]: return { "version_upgrade": { # From To Upgrade function @@ -51,5 +56,5 @@ def getMetaData(): } } -def register(app): +def register(app: "Application") -> Dict[str, Any]: return { "version_upgrade": upgrade } diff --git a/plugins/VersionUpgrade/VersionUpgrade30to31/VersionUpgrade30to31.py b/plugins/VersionUpgrade/VersionUpgrade30to31/VersionUpgrade30to31.py index 399eb18b5d..74467d67c6 100644 --- a/plugins/VersionUpgrade/VersionUpgrade30to31/VersionUpgrade30to31.py +++ b/plugins/VersionUpgrade/VersionUpgrade30to31/VersionUpgrade30to31.py @@ -1,14 +1,15 @@ -# Copyright (c) 2017 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import configparser #To parse preference files. import io #To serialise the preference files afterwards. +from typing import Dict, List, Set, Tuple from UM.VersionUpgrade import VersionUpgrade #We're inheriting from this. # a list of all legacy "Not Supported" quality profiles -_OLD_NOT_SUPPORTED_PROFILES = [ +_OLD_NOT_SUPPORTED_PROFILES = { "um2p_pp_0.25_normal", "um2p_tpu_0.8_normal", "um3_bb0.4_ABS_Fast_Print", @@ -42,7 +43,7 @@ _OLD_NOT_SUPPORTED_PROFILES = [ "um3_bb0.8_PP_Superdraft_Print", "um3_bb0.8_TPU_Fast_print", "um3_bb0.8_TPU_Superdraft_Print", -] +} # type: Set[str] # Some containers have their specific empty containers, those need to be set correctly. @@ -51,13 +52,13 @@ _EMPTY_CONTAINER_DICT = { "2": "empty_quality", "3": "empty_material", "4": "empty_variant", -} +} # type: Dict[str, str] # Renamed definition files _RENAMED_DEFINITION_DICT = { "jellybox": "imade3d_jellybox", -} +} # type: Dict[str, str] class VersionUpgrade30to31(VersionUpgrade): @@ -72,7 +73,7 @@ class VersionUpgrade30to31(VersionUpgrade): # \raises ValueError The format of the version number in the file is # incorrect. # \raises KeyError The format of the file is incorrect. - def getCfgVersion(self, serialised): + def getCfgVersion(self, serialised: str) -> int: parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialised) format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised. @@ -83,7 +84,7 @@ class VersionUpgrade30to31(VersionUpgrade): # # \param serialised The serialised form of a preferences file. # \param filename The name of the file to upgrade. - def upgradePreferences(self, serialised, filename): + def upgradePreferences(self, serialised: str, filename: str) -> Tuple[List[str], List[str]]: parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialised) @@ -104,7 +105,7 @@ class VersionUpgrade30to31(VersionUpgrade): # # \param serialised The serialised form of the container file. # \param filename The name of the file to upgrade. - def upgradeInstanceContainer(self, serialised, filename): + def upgradeInstanceContainer(self, serialised: str, filename: str) -> Tuple[List[str], List[str]]: parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialised) @@ -129,7 +130,7 @@ class VersionUpgrade30to31(VersionUpgrade): # # \param serialised The serialised form of a container stack. # \param filename The name of the file to upgrade. - def upgradeStack(self, serialised, filename): + def upgradeStack(self, serialised: str, filename: str) -> Tuple[List[str], List[str]]: parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialised) diff --git a/plugins/VersionUpgrade/VersionUpgrade30to31/__init__.py b/plugins/VersionUpgrade/VersionUpgrade30to31/__init__.py index 7b2c213a31..c5cc851d6a 100644 --- a/plugins/VersionUpgrade/VersionUpgrade30to31/__init__.py +++ b/plugins/VersionUpgrade/VersionUpgrade30to31/__init__.py @@ -1,11 +1,16 @@ -# Copyright (c) 2017 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +from typing import Any, Dict, TYPE_CHECKING + from . import VersionUpgrade30to31 +if TYPE_CHECKING: + from UM.Application import Application + upgrade = VersionUpgrade30to31.VersionUpgrade30to31() -def getMetaData(): +def getMetaData() -> Dict[str, Any]: return { "version_upgrade": { # From To Upgrade function @@ -55,5 +60,5 @@ def getMetaData(): } } -def register(app): +def register(app: "Application") -> Dict[str, Any]: return { "version_upgrade": upgrade } diff --git a/plugins/VersionUpgrade/VersionUpgrade32to33/VersionUpgrade32to33.py b/plugins/VersionUpgrade/VersionUpgrade32to33/VersionUpgrade32to33.py index 18851b82c7..5be58eab3b 100644 --- a/plugins/VersionUpgrade/VersionUpgrade32to33/VersionUpgrade32to33.py +++ b/plugins/VersionUpgrade/VersionUpgrade32to33/VersionUpgrade32to33.py @@ -3,6 +3,7 @@ import configparser #To parse preference files. import io #To serialise the preference files afterwards. +from typing import Dict, List, Tuple from UM.VersionUpgrade import VersionUpgrade #We're inheriting from this. @@ -51,22 +52,22 @@ _EXTRUDER_TO_POSITION = { "ultimaker_original_dual_2nd": 1, "vertex_k8400_dual_1st": 0, "vertex_k8400_dual_2nd": 1 -} +} # type: Dict[str, int] _RENAMED_QUALITY_PROFILES = { "low": "fast", "um2_low": "um2_fast" -} +} # type: Dict[str, str] _RENAMED_QUALITY_TYPES = { "low": "fast" -} +} # type: Dict[str, str] ## Upgrades configurations from the state they were in at version 3.2 to the # state they should be in at version 3.3. class VersionUpgrade32to33(VersionUpgrade): - temporary_group_name_counter = 1 + ## Gets the version number from a CFG file in Uranium's 3.2 format. # # Since the format may change, this is implemented for the 3.2 format only @@ -78,7 +79,7 @@ class VersionUpgrade32to33(VersionUpgrade): # \raises ValueError The format of the version number in the file is # incorrect. # \raises KeyError The format of the file is incorrect. - def getCfgVersion(self, serialised): + def getCfgVersion(self, serialised: str) -> int: parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialised) format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised. @@ -89,7 +90,7 @@ class VersionUpgrade32to33(VersionUpgrade): # # \param serialised The serialised form of a preferences file. # \param filename The name of the file to upgrade. - def upgradePreferences(self, serialised, filename): + def upgradePreferences(self, serialised: str, filename: str) -> Tuple[List[str], List[str]]: parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialised) @@ -117,7 +118,7 @@ class VersionUpgrade32to33(VersionUpgrade): # # \param serialised The serialised form of a container stack. # \param filename The name of the file to upgrade. - def upgradeStack(self, serialized, filename): + def upgradeStack(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]: parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialized) @@ -141,7 +142,7 @@ class VersionUpgrade32to33(VersionUpgrade): ## Upgrades non-quality-changes instance containers to have the new version # number. - def upgradeInstanceContainer(self, serialized, filename): + def upgradeInstanceContainer(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]: parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialized) @@ -153,7 +154,7 @@ class VersionUpgrade32to33(VersionUpgrade): return [filename], [result.getvalue()] ## Upgrades a quality changes container to the new format. - def upgradeQualityChanges(self, serialized, filename): + def upgradeQualityChanges(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]: parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialized) @@ -182,7 +183,7 @@ class VersionUpgrade32to33(VersionUpgrade): return [filename], [result.getvalue()] ## Upgrades a variant container to the new format. - def upgradeVariants(self, serialized, filename): + def upgradeVariants(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]: parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialized) diff --git a/plugins/VersionUpgrade/VersionUpgrade32to33/__init__.py b/plugins/VersionUpgrade/VersionUpgrade32to33/__init__.py index 5073be772d..006b21bc48 100644 --- a/plugins/VersionUpgrade/VersionUpgrade32to33/__init__.py +++ b/plugins/VersionUpgrade/VersionUpgrade32to33/__init__.py @@ -1,11 +1,16 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +from typing import Any, Dict, TYPE_CHECKING + from . import VersionUpgrade32to33 +if TYPE_CHECKING: + from UM.Application import Application + upgrade = VersionUpgrade32to33.VersionUpgrade32to33() -def getMetaData(): +def getMetaData() -> Dict[str, Any]: return { "version_upgrade": { # From To Upgrade function @@ -51,5 +56,5 @@ def getMetaData(): } } -def register(app): +def register(app: "Application") -> Dict[str, Any]: return { "version_upgrade": upgrade } \ No newline at end of file diff --git a/plugins/VersionUpgrade/VersionUpgrade33to34/VersionUpgrade33to34.py b/plugins/VersionUpgrade/VersionUpgrade33to34/VersionUpgrade33to34.py index e2241fd195..5077dda8ad 100644 --- a/plugins/VersionUpgrade/VersionUpgrade33to34/VersionUpgrade33to34.py +++ b/plugins/VersionUpgrade/VersionUpgrade33to34/VersionUpgrade33to34.py @@ -3,17 +3,17 @@ import configparser #To parse preference files. import io #To serialise the preference files afterwards. +from typing import Dict, List, Tuple from UM.VersionUpgrade import VersionUpgrade #We're inheriting from this. _renamed_settings = { "infill_hollow": "infill_support_enabled" -} +} # type: Dict[str, str] ## Upgrades configurations from the state they were in at version 3.3 to the # state they should be in at version 3.4. class VersionUpgrade33to34(VersionUpgrade): - ## Gets the version number from a CFG file in Uranium's 3.3 format. # # Since the format may change, this is implemented for the 3.3 format only @@ -25,7 +25,7 @@ class VersionUpgrade33to34(VersionUpgrade): # \raises ValueError The format of the version number in the file is # incorrect. # \raises KeyError The format of the file is incorrect. - def getCfgVersion(self, serialised): + def getCfgVersion(self, serialised: str) -> int: parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialised) format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised. @@ -34,7 +34,7 @@ class VersionUpgrade33to34(VersionUpgrade): ## Upgrades instance containers to have the new version # number. - def upgradeInstanceContainer(self, serialized, filename): + def upgradeInstanceContainer(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]: parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialized) diff --git a/plugins/VersionUpgrade/VersionUpgrade33to34/__init__.py b/plugins/VersionUpgrade/VersionUpgrade33to34/__init__.py index 1130c1e9e2..5fd757f843 100644 --- a/plugins/VersionUpgrade/VersionUpgrade33to34/__init__.py +++ b/plugins/VersionUpgrade/VersionUpgrade33to34/__init__.py @@ -1,11 +1,16 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +from typing import Any, Dict, TYPE_CHECKING + from . import VersionUpgrade33to34 +if TYPE_CHECKING: + from UM.Application import Application + upgrade = VersionUpgrade33to34.VersionUpgrade33to34() -def getMetaData(): +def getMetaData() -> Dict[str, Any]: return { "version_upgrade": { # From To Upgrade function @@ -35,5 +40,5 @@ def getMetaData(): } -def register(app): +def register(app: "Application") -> Dict[str, Any]: return { "version_upgrade": upgrade } diff --git a/plugins/VersionUpgrade/VersionUpgrade34to35/VersionUpgrade34to35.py b/plugins/VersionUpgrade/VersionUpgrade34to35/VersionUpgrade34to35.py index 9d59133036..88cc3ca420 100644 --- a/plugins/VersionUpgrade/VersionUpgrade34to35/VersionUpgrade34to35.py +++ b/plugins/VersionUpgrade/VersionUpgrade34to35/VersionUpgrade34to35.py @@ -3,13 +3,14 @@ import configparser import io +from typing import Dict, List, Set, Tuple from UM.VersionUpgrade import VersionUpgrade -deleted_settings = {"prime_tower_wall_thickness", "dual_pre_wipe", "prime_tower_purge_volume"} +deleted_settings = {"prime_tower_wall_thickness", "dual_pre_wipe", "prime_tower_purge_volume"} # type: Set[str] -changed_settings = {'retraction_combing': 'noskin'} -updated_settings = {'retraction_combing': 'infill'} +changed_settings = {"retraction_combing": "noskin"} # type: Dict[str, str] +updated_settings = {"retraction_combing": "infill"} # type: Dict[str, str] _RENAMED_MATERIAL_PROFILES = { "dsm_arnitel2045_175_cartesio_0.25_mm": "dsm_arnitel2045_175_cartesio_0.25mm_thermoplastic_extruder", @@ -57,12 +58,11 @@ _RENAMED_MATERIAL_PROFILES = { "ultimaker_pva_cartesio_0.25_mm": "ultimaker_pva_cartesio_0.25mm_thermoplastic_extruder", "ultimaker_pva_cartesio_0.4_mm": "ultimaker_pva_cartesio_0.4mm_thermoplastic_extruder", "ultimaker_pva_cartesio_0.8_mm": "ultimaker_pva_cartesio_0.8mm_thermoplastic_extruder" -} +} # type: Dict[str, str] ## Upgrades configurations from the state they were in at version 3.4 to the # state they should be in at version 3.5. class VersionUpgrade34to35(VersionUpgrade): - ## Gets the version number from a CFG file in Uranium's 3.3 format. # # Since the format may change, this is implemented for the 3.3 format only @@ -74,7 +74,7 @@ class VersionUpgrade34to35(VersionUpgrade): # \raises ValueError The format of the version number in the file is # incorrect. # \raises KeyError The format of the file is incorrect. - def getCfgVersion(self, serialised): + def getCfgVersion(self, serialised: str) -> int: parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialised) format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised. @@ -82,7 +82,7 @@ class VersionUpgrade34to35(VersionUpgrade): return format_version * 1000000 + setting_version ## Upgrades Preferences to have the new version number. - def upgradePreferences(self, serialized, filename): + def upgradePreferences(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]: parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialized) @@ -103,7 +103,7 @@ class VersionUpgrade34to35(VersionUpgrade): return [filename], [result.getvalue()] ## Upgrades stacks to have the new version number. - def upgradeStack(self, serialized, filename): + def upgradeStack(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]: parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialized) @@ -121,7 +121,7 @@ class VersionUpgrade34to35(VersionUpgrade): ## Upgrades instance containers to have the new version # number. - def upgradeInstanceContainer(self, serialized, filename): + def upgradeInstanceContainer(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]: parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialized) @@ -147,7 +147,7 @@ class VersionUpgrade34to35(VersionUpgrade): parser.write(result) return [filename], [result.getvalue()] - def _resetConcentric3DInfillPattern(self, parser): + def _resetConcentric3DInfillPattern(self, parser: configparser.ConfigParser) -> None: if "values" not in parser: return @@ -161,5 +161,4 @@ class VersionUpgrade34to35(VersionUpgrade): if key not in parser["values"]: continue if parser["values"][key] == "concentric_3d": - del parser["values"][key] - + del parser["values"][key] \ No newline at end of file diff --git a/plugins/VersionUpgrade/VersionUpgrade34to35/__init__.py b/plugins/VersionUpgrade/VersionUpgrade34to35/__init__.py index 2ea74f6194..332bc827b9 100644 --- a/plugins/VersionUpgrade/VersionUpgrade34to35/__init__.py +++ b/plugins/VersionUpgrade/VersionUpgrade34to35/__init__.py @@ -1,11 +1,16 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +from typing import Any, Dict, TYPE_CHECKING + from . import VersionUpgrade34to35 +if TYPE_CHECKING: + from UM.Application import Application + upgrade = VersionUpgrade34to35.VersionUpgrade34to35() -def getMetaData(): +def getMetaData() -> Dict[str, Any]: return { "version_upgrade": { # From To Upgrade function @@ -52,5 +57,5 @@ def getMetaData(): } -def register(app): +def register(app: "Application") -> Dict[str, Any]: return { "version_upgrade": upgrade } From b67d8d410343490b96357def995adb3a8f0d198f Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 14 Nov 2018 13:46:13 +0100 Subject: [PATCH 0204/1292] Fix type of fallback variable These have to be strings because the configparser getter can only return strings. Contributes to issue CURA-5936. --- .../VersionUpgrade21to22/VersionUpgrade21to22.py | 2 +- plugins/VersionUpgrade/VersionUpgrade22to24/VersionUpgrade.py | 2 +- .../VersionUpgrade25to26/VersionUpgrade25to26.py | 2 +- .../VersionUpgrade26to27/VersionUpgrade26to27.py | 4 ++-- .../VersionUpgrade27to30/VersionUpgrade27to30.py | 4 ++-- .../VersionUpgrade30to31/VersionUpgrade30to31.py | 2 +- .../VersionUpgrade32to33/VersionUpgrade32to33.py | 2 +- .../VersionUpgrade33to34/VersionUpgrade33to34.py | 2 +- .../VersionUpgrade34to35/VersionUpgrade34to35.py | 2 +- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/VersionUpgrade21to22.py b/plugins/VersionUpgrade/VersionUpgrade21to22/VersionUpgrade21to22.py index 89c847e606..536385b19d 100644 --- a/plugins/VersionUpgrade/VersionUpgrade21to22/VersionUpgrade21to22.py +++ b/plugins/VersionUpgrade/VersionUpgrade21to22/VersionUpgrade21to22.py @@ -251,7 +251,7 @@ class VersionUpgrade21to22(VersionUpgrade): parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialised) format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised. - setting_version = int(parser.get("metadata", "setting_version", fallback = 0)) + setting_version = int(parser.get("metadata", "setting_version", fallback = "0")) return format_version * 1000000 + setting_version ## Gets the fallback quality to use for a specific machine-variant-material diff --git a/plugins/VersionUpgrade/VersionUpgrade22to24/VersionUpgrade.py b/plugins/VersionUpgrade/VersionUpgrade22to24/VersionUpgrade.py index 48af365877..dac73683bb 100644 --- a/plugins/VersionUpgrade/VersionUpgrade22to24/VersionUpgrade.py +++ b/plugins/VersionUpgrade/VersionUpgrade22to24/VersionUpgrade.py @@ -156,5 +156,5 @@ class VersionUpgrade22to24(VersionUpgrade): parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialised) format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised. - setting_version = int(parser.get("metadata", "setting_version", fallback = 0)) + setting_version = int(parser.get("metadata", "setting_version", fallback = "0")) return format_version * 1000000 + setting_version diff --git a/plugins/VersionUpgrade/VersionUpgrade25to26/VersionUpgrade25to26.py b/plugins/VersionUpgrade/VersionUpgrade25to26/VersionUpgrade25to26.py index 5c9b94cca3..6dbcfebc46 100644 --- a/plugins/VersionUpgrade/VersionUpgrade25to26/VersionUpgrade25to26.py +++ b/plugins/VersionUpgrade/VersionUpgrade25to26/VersionUpgrade25to26.py @@ -43,7 +43,7 @@ class VersionUpgrade25to26(VersionUpgrade): parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialised) format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised. - setting_version = int(parser.get("metadata", "setting_version", fallback = 0)) + setting_version = int(parser.get("metadata", "setting_version", fallback = "0")) return format_version * 1000000 + setting_version ## Upgrades the preferences file from version 2.5 to 2.6. diff --git a/plugins/VersionUpgrade/VersionUpgrade26to27/VersionUpgrade26to27.py b/plugins/VersionUpgrade/VersionUpgrade26to27/VersionUpgrade26to27.py index 96307ca43c..39e3dea4ed 100644 --- a/plugins/VersionUpgrade/VersionUpgrade26to27/VersionUpgrade26to27.py +++ b/plugins/VersionUpgrade/VersionUpgrade26to27/VersionUpgrade26to27.py @@ -84,7 +84,7 @@ class VersionUpgrade26to27(VersionUpgrade): parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialised) format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised. - setting_version = int(parser.get("metadata", "setting_version", fallback = 0)) + setting_version = int(parser.get("metadata", "setting_version", fallback = "0")) return format_version * 1000000 + setting_version ## Upgrades a preferences file from version 2.6 to 2.7. @@ -92,7 +92,7 @@ class VersionUpgrade26to27(VersionUpgrade): # \param serialised The serialised form of a preferences file. # \param filename The name of the file to upgrade. def upgradePreferences(self, serialised: str, filename: str) -> Tuple[List[str], List[str]]: - parser = configparser.ConfigParser(interpolation=None) + parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialised) # Update version numbers diff --git a/plugins/VersionUpgrade/VersionUpgrade27to30/VersionUpgrade27to30.py b/plugins/VersionUpgrade/VersionUpgrade27to30/VersionUpgrade27to30.py index c9e9e41f7e..b594c3c6c4 100644 --- a/plugins/VersionUpgrade/VersionUpgrade27to30/VersionUpgrade27to30.py +++ b/plugins/VersionUpgrade/VersionUpgrade27to30/VersionUpgrade27to30.py @@ -48,7 +48,7 @@ class VersionUpgrade27to30(VersionUpgrade): parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialised) format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised. - setting_version = int(parser.get("metadata", "setting_version", fallback = 0)) + setting_version = int(parser.get("metadata", "setting_version", fallback = "0")) return format_version * 1000000 + setting_version ## Upgrades a preferences file from version 2.7 to 3.0. @@ -158,7 +158,7 @@ class VersionUpgrade27to30(VersionUpgrade): # \param serialised The serialised form of the container file. # \param filename The name of the file to upgrade. def upgradeOtherContainer(self, serialised: str, filename: str) -> Tuple[List[str], List[str]]: - parser = configparser.ConfigParser(interpolation=None) + parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialised) # Update the skin pre-shrink settings: diff --git a/plugins/VersionUpgrade/VersionUpgrade30to31/VersionUpgrade30to31.py b/plugins/VersionUpgrade/VersionUpgrade30to31/VersionUpgrade30to31.py index 74467d67c6..f0b2e939b9 100644 --- a/plugins/VersionUpgrade/VersionUpgrade30to31/VersionUpgrade30to31.py +++ b/plugins/VersionUpgrade/VersionUpgrade30to31/VersionUpgrade30to31.py @@ -77,7 +77,7 @@ class VersionUpgrade30to31(VersionUpgrade): parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialised) format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised. - setting_version = int(parser.get("metadata", "setting_version", fallback = 0)) + setting_version = int(parser.get("metadata", "setting_version", fallback = "0")) return format_version * 1000000 + setting_version ## Upgrades a preferences file from version 3.0 to 3.1. diff --git a/plugins/VersionUpgrade/VersionUpgrade32to33/VersionUpgrade32to33.py b/plugins/VersionUpgrade/VersionUpgrade32to33/VersionUpgrade32to33.py index 5be58eab3b..83cb15c864 100644 --- a/plugins/VersionUpgrade/VersionUpgrade32to33/VersionUpgrade32to33.py +++ b/plugins/VersionUpgrade/VersionUpgrade32to33/VersionUpgrade32to33.py @@ -83,7 +83,7 @@ class VersionUpgrade32to33(VersionUpgrade): parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialised) format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised. - setting_version = int(parser.get("metadata", "setting_version", fallback = 0)) + setting_version = int(parser.get("metadata", "setting_version", fallback = "0")) return format_version * 1000000 + setting_version ## Upgrades a preferences file from version 3.2 to 3.3. diff --git a/plugins/VersionUpgrade/VersionUpgrade33to34/VersionUpgrade33to34.py b/plugins/VersionUpgrade/VersionUpgrade33to34/VersionUpgrade33to34.py index 5077dda8ad..704ede02d6 100644 --- a/plugins/VersionUpgrade/VersionUpgrade33to34/VersionUpgrade33to34.py +++ b/plugins/VersionUpgrade/VersionUpgrade33to34/VersionUpgrade33to34.py @@ -29,7 +29,7 @@ class VersionUpgrade33to34(VersionUpgrade): parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialised) format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised. - setting_version = int(parser.get("metadata", "setting_version", fallback = 0)) + setting_version = int(parser.get("metadata", "setting_version", fallback = "0")) return format_version * 1000000 + setting_version ## Upgrades instance containers to have the new version diff --git a/plugins/VersionUpgrade/VersionUpgrade34to35/VersionUpgrade34to35.py b/plugins/VersionUpgrade/VersionUpgrade34to35/VersionUpgrade34to35.py index 88cc3ca420..d930b6e217 100644 --- a/plugins/VersionUpgrade/VersionUpgrade34to35/VersionUpgrade34to35.py +++ b/plugins/VersionUpgrade/VersionUpgrade34to35/VersionUpgrade34to35.py @@ -78,7 +78,7 @@ class VersionUpgrade34to35(VersionUpgrade): parser = configparser.ConfigParser(interpolation = None) parser.read_string(serialised) format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised. - setting_version = int(parser.get("metadata", "setting_version", fallback = 0)) + setting_version = int(parser.get("metadata", "setting_version", fallback = "0")) return format_version * 1000000 + setting_version ## Upgrades Preferences to have the new version number. From b589920f53a7192bd620e55e7d4ec87d22bbde7d Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 14 Nov 2018 13:55:39 +0100 Subject: [PATCH 0205/1292] Move a few hardcoded sizes to the theme CURA-5785 --- plugins/PrepareStage/PrepareMenu.qml | 9 ++++----- resources/themes/cura-light/theme.json | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index 78f9ced1e7..9507d786b2 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -53,9 +53,8 @@ Item { id: machineSelection z: openFileButtonBackground.z - 1 - - Layout.minimumWidth: 240 - Layout.maximumWidth: 240 + Layout.minimumWidth: UM.Theme.getSize("machine_selector_widget").width + Layout.maximumWidth: UM.Theme.getSize("machine_selector_widget").width Layout.fillWidth: true Layout.fillHeight: true } @@ -90,8 +89,8 @@ Item onShowTooltip: prepareMenu.showTooltip(item, location, text) onHideTooltip: prepareMenu.hideTooltip() - Layout.minimumWidth: 460 - Layout.maximumWidth: 460 + Layout.minimumWidth: UM.Theme.getSize("print_setup_widget").width + Layout.maximumWidth: UM.Theme.getSize("print_setup_widget").width Layout.fillWidth: true Layout.fillHeight: true } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index a33ff87042..a36940641e 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -374,7 +374,7 @@ "account_button": [12, 3], - "print_setup_widget": [35.0, 42.0], + "print_setup_widget": [30.0, 42.0], "print_setup_mode_toggle": [0.0, 2.0], "print_setup_item": [0.0, 2.0], "print_setup_extruder_box": [0.0, 6.0], @@ -386,7 +386,7 @@ "action_panel_information_widget": [20.0, 0.0], "action_panel_button": [15.0, 3.0], - "machine_selector_widget": [28.0, 4.5], + "machine_selector_widget": [16.0, 4.5], "views_selector": [0.0, 4.0], From 8ec7d6dba3b79dc88c9496185c6e49000740018a Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 14 Nov 2018 13:56:46 +0100 Subject: [PATCH 0206/1292] Fix type issues in old version upgrade plug-ins The one actual change was this: To give a KeyError when stuff can't be found in a dictionary, rather than returning None there and then getting a TypeError later. Contributes to issue CURA-5936. --- .../VersionUpgrade21to22/MachineInstance.py | 10 +++++----- .../VersionUpgrade21to22/Preferences.py | 8 ++++---- .../VersionUpgrade22to24/VersionUpgrade.py | 12 ++++++------ 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py b/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py index a947114595..478f955e49 100644 --- a/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py +++ b/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py @@ -4,7 +4,7 @@ import configparser #To read config files. import io #To write config files to strings as if they were files. import os.path #To get the path to write new user profiles to. -from typing import List, Optional, Tuple +from typing import Dict, List, Optional, Set, Tuple import urllib #To serialise the user container file name properly. import UM.VersionUpgrade #To indicate that a file is of incorrect format. @@ -33,7 +33,7 @@ class MachineInstance: # \param serialised A string with the contents of a machine instance file, # without extension. # \param filename The supposed file name of this machine instance. - def __init__(self, serialised: str, filename: str) -> str: + def __init__(self, serialised: str, filename: str) -> None: self._filename = filename config = configparser.ConfigParser(interpolation = None) @@ -54,11 +54,11 @@ class MachineInstance: self._type_name = config.get("general", "type") self._variant_name = config.get("general", "variant", fallback = "empty_variant") self._name = config.get("general", "name", fallback = "") - self._key = config.get("general", "key", fallback = None) + self._key = config.get("general", "key", fallback = "") self._active_profile_name = config.get("general", "active_profile", fallback = "empty_quality") self._active_material_name = config.get("general", "material", fallback = "empty_material") - self._machine_setting_overrides = {} + self._machine_setting_overrides = {} # type: Dict[str, str] for key, value in config["machine_settings"].items(): self._machine_setting_overrides[key] = value @@ -109,7 +109,7 @@ class MachineInstance: version_upgrade_manager = UM.VersionUpgradeManager.VersionUpgradeManager.getInstance() user_version_to_paths_dict = version_upgrade_manager.getStoragePaths("user") - paths_set = set() + paths_set = set() # type: Set[str] for paths in user_version_to_paths_dict.values(): paths_set |= paths diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/Preferences.py b/plugins/VersionUpgrade/VersionUpgrade21to22/Preferences.py index 51e4b617e8..953837b863 100644 --- a/plugins/VersionUpgrade/VersionUpgrade21to22/Preferences.py +++ b/plugins/VersionUpgrade/VersionUpgrade21to22/Preferences.py @@ -59,11 +59,11 @@ class Preferences: #Translate the setting names in the visible settings. if self._config.has_section("machines") and self._config.has_option("machines", "setting_visibility"): visible_settings = self._config.get("machines", "setting_visibility") - visible_settings = visible_settings.split(",") + visible_settings_list = visible_settings.split(",") import VersionUpgrade21to22 #Import here to prevent a circular dependency. - visible_settings = [VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.translateSettingName(setting_name) - for setting_name in visible_settings] - visible_settings = ",".join(visible_settings) + visible_settings_list = [VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.translateSettingName(setting_name) + for setting_name in visible_settings_list] + visible_settings = ",".join(visible_settings_list) self._config.set("machines", "setting_visibility", value = visible_settings) #Translate the active_instance key. diff --git a/plugins/VersionUpgrade/VersionUpgrade22to24/VersionUpgrade.py b/plugins/VersionUpgrade/VersionUpgrade22to24/VersionUpgrade.py index dac73683bb..ded892d137 100644 --- a/plugins/VersionUpgrade/VersionUpgrade22to24/VersionUpgrade.py +++ b/plugins/VersionUpgrade/VersionUpgrade22to24/VersionUpgrade.py @@ -22,11 +22,11 @@ class VersionUpgrade22to24(VersionUpgrade): config.read_string(serialised) # Read the input string as config file. if config.get("metadata", "type") == "definition_changes": # This is not a container stack, don't upgrade it here - return + return None config.set("general", "version", "3") - container_list = [] + container_list = [] # type: List[str] if config.has_section("containers"): for index, container_id in config.items("containers"): container_list.append(container_id) @@ -37,14 +37,14 @@ class VersionUpgrade22to24(VersionUpgrade): user_variants = self.__getUserVariants() name_path_dict = {} for variant in user_variants: - name_path_dict[variant.get("name")] = variant.get("path") + name_path_dict[variant["name"]] = variant["path"] user_variant_names = set(container_list).intersection(name_path_dict.keys()) if len(user_variant_names): # One of the user defined variants appears in the list of containers in the stack. for variant_name in user_variant_names: # really there should just be one variant to convert. - config_name = self.__convertVariant(name_path_dict.get(variant_name)) + config_name = self.__convertVariant(name_path_dict[variant_name]) # Change the name of variant and insert empty_variant into the stack. new_container_list = [] @@ -64,8 +64,8 @@ class VersionUpgrade22to24(VersionUpgrade): config.remove_option("general", "containers") - for index in range(len(container_list)): - config.set("containers", str(index), container_list[index]) + for idx in range(len(container_list)): + config.set("containers", str(idx), container_list[idx]) output = io.StringIO() config.write(output) From 7ca3490097027f9cb4342a52007ee558897d8c3d Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 14 Nov 2018 14:00:19 +0100 Subject: [PATCH 0207/1292] Make the collapse arrows consistent with the rest of the UI CURA-5785 --- resources/qml/ExpandableComponent.qml | 2 +- resources/qml/MachineSelector.qml | 2 +- .../qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index c525d163fe..bfafa9b29e 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -109,7 +109,7 @@ Item y: headerItemLoader.height + 2 * background.padding // Make the popup right aligned with the rest. The 3x padding is due to left, right and padding between - //the button & text. + // the button & text. x: -width + collapseButton.width + headerItemLoader.width + 3 * background.padding padding: UM.Theme.getSize("default_margin").width closePolicy: Popup.CloseOnPressOutsideParent diff --git a/resources/qml/MachineSelector.qml b/resources/qml/MachineSelector.qml index 87a3154338..6a33cf3a0e 100644 --- a/resources/qml/MachineSelector.qml +++ b/resources/qml/MachineSelector.qml @@ -17,7 +17,7 @@ Cura.ExpandableComponent property bool isNetworkPrinter: Cura.MachineManager.activeMachineNetworkKey != "" - iconSource: expanded ? UM.Theme.getIcon("arrow_left") : UM.Theme.getIcon("arrow_bottom") + iconSource: expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") UM.I18nCatalog { diff --git a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml index 5565884bd8..b2213918dd 100644 --- a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml +++ b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml @@ -27,7 +27,7 @@ Cura.ExpandableComponent name: "cura" } - iconSource: expanded ? UM.Theme.getIcon("arrow_left") : UM.Theme.getIcon("arrow_bottom") + iconSource: expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") headerItem: Item { From 429a49aa2eddc2c42c0f592181f6f77e880954c7 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 14 Nov 2018 14:06:55 +0100 Subject: [PATCH 0208/1292] Make the default size of the expandableComponent icon depend on the height of the element This is a way more sensible default. CURA-5785 --- resources/qml/ExpandableComponent.qml | 7 ++++--- .../Menus/ConfigurationMenu/QuickConfigurationSelector.qml | 1 - 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index bfafa9b29e..c098443cd7 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -9,6 +9,7 @@ import UM 1.2 as UM // * The Icon; An icon that is displayed on the right of the drawer. Item { + id: base // The headerItem holds the QML item that is always displayed. property alias headerItem: headerItemLoader.sourceComponent @@ -33,7 +34,7 @@ Item property alias iconColor: collapseButton.color // The icon size (it's always drawn as a square) - property alias iconSize: collapseButton.width + property alias iconSize: collapseButton.height // Is the "drawer" open? readonly property alias expanded: popup.visible @@ -89,8 +90,8 @@ Item sourceSize.width: width sourceSize.height: height visible: source != "" - width: UM.Theme.getSize("section_icon").width - height: width + width: height + height: 0.2 * base.height color: "black" } diff --git a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml index b2213918dd..e77f949661 100644 --- a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml +++ b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml @@ -28,7 +28,6 @@ Cura.ExpandableComponent } iconSource: expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") - headerItem: Item { // Horizontal list that shows the extruders From 66c3cc9204fdc309c993ec4b40983cdd150dc00a Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Wed, 14 Nov 2018 14:20:42 +0100 Subject: [PATCH 0209/1292] Prevent an error during start up --- cura/BuildVolume.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py index 547c3dae71..1589f16afc 100755 --- a/cura/BuildVolume.py +++ b/cura/BuildVolume.py @@ -489,7 +489,9 @@ class BuildVolume(SceneNode): def _updateRaftThickness(self): old_raft_thickness = self._raft_thickness - self._adhesion_type = self._global_container_stack.getProperty("adhesion_type", "value") + if self._global_container_stack.extruders: + # This might be called before the extruder stacks have initialised, in which case getting the adhesion_type fails + self._adhesion_type = self._global_container_stack.getProperty("adhesion_type", "value") self._raft_thickness = 0.0 if self._adhesion_type == "raft": self._raft_thickness = ( From b671a3153a0f7f7ab9745f73c300d34c6bf7a06b Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Wed, 14 Nov 2018 14:21:39 +0100 Subject: [PATCH 0210/1292] Catch an error getting an extruder value before extruders are added to the global stack --- cura/Settings/CuraFormulaFunctions.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cura/Settings/CuraFormulaFunctions.py b/cura/Settings/CuraFormulaFunctions.py index 1db01857f8..9ef80bd3d4 100644 --- a/cura/Settings/CuraFormulaFunctions.py +++ b/cura/Settings/CuraFormulaFunctions.py @@ -5,6 +5,7 @@ from typing import Any, List, Optional, TYPE_CHECKING from UM.Settings.PropertyEvaluationContext import PropertyEvaluationContext from UM.Settings.SettingFunction import SettingFunction +from UM.Logger import Logger if TYPE_CHECKING: from cura.CuraApplication import CuraApplication @@ -38,7 +39,11 @@ class CuraFormulaFunctions: extruder_position = int(machine_manager.defaultExtruderPosition) global_stack = machine_manager.activeMachine - extruder_stack = global_stack.extruders[str(extruder_position)] + try: + extruder_stack = global_stack.extruders[str(extruder_position)] + except KeyError: + Logger.log("w", "Value for %s of extruder %s was requested, but that extruder is not available" % (property_key, extruder_position)) + return None value = extruder_stack.getRawProperty(property_key, "value", context = context) if isinstance(value, SettingFunction): From c27f51d944b3dc84946f5f17a884723afbfd1a8f Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 14 Nov 2018 16:44:36 +0100 Subject: [PATCH 0211/1292] Make the view selector also use the expandableComponent CURA-5785 --- plugins/PreviewStage/PreviewMenu.qml | 91 +++++++++++++++------------- resources/qml/MachineSelector.qml | 1 + 2 files changed, 51 insertions(+), 41 deletions(-) diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index 5b0ae4e9c5..bb8b992471 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -3,7 +3,7 @@ import QtQuick 2.7 -import QtQuick.Controls 1.4 +import QtQuick.Controls 2.4 import UM 1.3 as UM import Cura 1.1 as Cura @@ -43,53 +43,62 @@ Item //spacing: UM.Theme.getSize("default_margin").width height: parent.height - Item + Cura.ExpandableComponent { - width: viewModeButton.width + 2 * UM.Theme.getSize("default_margin").width + id: viewSelector + iconSource: expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") height: parent.height - ComboBox + + property var viewModel: UM.ViewModel { } + + property var activeView: { - // This item contains the views selector, a combobox that is dynamically created from - // the list of available Views (packages that create different visualizations of the - // scene). - id: viewModeButton - - style: UM.Theme.styles.combobox - anchors.centerIn: parent - model: UM.ViewModel { } - textRole: "name" - - // update the model's active index - function updateItemActiveFlags() + for (var i = 0; i < viewModel.rowCount(); i++) { - currentIndex = getActiveIndex() - for (var i = 0; i < model.rowCount(); i++) + if(viewModel.getItem(i).active) { - model.getItem(i).active = (i == currentIndex) + return viewModel.getItem(i) + } + } + // Nothing was active, so just return the first one (the list is sorted by priority, so the most + // important one sshould be returned) + return viewModel.getItem(0) + } + + // Ensure that the controller is synced with whatever happend here. + onActiveViewChanged: UM.Controller.setActiveView(activeView.id) + + headerItem: Label + { + text: viewSelector.activeView.name + verticalAlignment: Text.AlignVCenter + height: parent.height + elide: Text.ElideRight + font: UM.Theme.getFont("default") + } + + popupItem: Column + { + id: column + width: viewSelector.width - 2 * UM.Theme.getSize("default_margin").width + + // For some reason the height of the column gets set to 0 if this is not set... + Component.onCompleted: height = implicitHeight + + Repeater + { + id: networkedPrinters + model: viewSelector.viewModel + RoundButton + { + text: name + radius: UM.Theme.getSize("default_radius").width + checkable: true + checked: active + onClicked: UM.Controller.setActiveView(id) } } - // get the index of the active model item on start - function getActiveIndex() - { - for (var i = 0; i < model.rowCount(); i++) - { - if (model.getItem(i).active) - { - return i; - } - } - return 0 - } - - onCurrentIndexChanged: - { - if (model.getItem(currentIndex).id != undefined) - { - UM.Controller.setActiveView(model.getItem(currentIndex).id) - } - } - currentIndex: getActiveIndex() } } @@ -106,7 +115,7 @@ Item // TODO: Make this panel collapsable and ensure it has a standardised background. id: viewPanel - property var buttonTarget: Qt.point(viewModeButton.x + Math.round(viewModeButton.width / 2), viewModeButton.y + Math.round(viewModeButton.height / 2)) + //property var buttonTarget: Qt.point(viewModeButton.x + Math.round(viewModeButton.width / 2), viewModeButton.y + Math.round(viewModeButton.height / 2)) height: parent.height width: childrenRect.width diff --git a/resources/qml/MachineSelector.qml b/resources/qml/MachineSelector.qml index 6a33cf3a0e..b2a34e186e 100644 --- a/resources/qml/MachineSelector.qml +++ b/resources/qml/MachineSelector.qml @@ -31,6 +31,7 @@ Cura.ExpandableComponent verticalAlignment: Text.AlignVCenter height: parent.height elide: Text.ElideRight + font: UM.Theme.getFont("default") } popupItem: Item From 9aa5b6fe3f467d50796a80a43f95770e6bb080cf Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 14 Nov 2018 16:47:53 +0100 Subject: [PATCH 0212/1292] Hide one spacer if there is no viewPanel CURA-5785 --- plugins/PreviewStage/PreviewMenu.qml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index bb8b992471..e24d0b25b1 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -106,7 +106,10 @@ Item Rectangle { height: parent.height - width: UM.Theme.getSize("default_lining").width + // If there is no viewPanel, we only need a single spacer, so hide this one. + visible: viewPanel.source != "" + width: visible ? UM.Theme.getSize("default_lining").width : 0 + color: UM.Theme.getColor("lining") } From 20b7a925a0f9525ed6e0f1ff2cb7703b739def74 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 14 Nov 2018 16:49:01 +0100 Subject: [PATCH 0213/1292] Remove unused code & outdated todo comment CURA-5785 --- plugins/PreviewStage/PreviewMenu.qml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index e24d0b25b1..df04507ba4 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -115,14 +115,9 @@ Item Loader { - // TODO: Make this panel collapsable and ensure it has a standardised background. id: viewPanel - - //property var buttonTarget: Qt.point(viewModeButton.x + Math.round(viewModeButton.width / 2), viewModeButton.y + Math.round(viewModeButton.height / 2)) - height: parent.height width: childrenRect.width - source: UM.Controller.activeView != null && UM.Controller.activeView.stageMenuComponent != null ? UM.Controller.activeView.stageMenuComponent : "" } From 21d7619a4541b122bc480630dad18e42cfa85e6d Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 14 Nov 2018 16:57:05 +0100 Subject: [PATCH 0214/1292] Added a hover effect to the expandableComponent CURA-5785 --- resources/qml/ExpandableComponent.qml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index c098443cd7..d885253173 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -19,7 +19,8 @@ Item // The background color of the popup property color popupBackgroundColor: "white" - property alias headerBackgroundColor: background.color + property color headerBackgroundColor: "white" + property color headerHoverColor: "white" // How much spacing is needed around the popupItem property alias popupPadding: popup.padding @@ -63,7 +64,7 @@ Item id: background property real padding: UM.Theme.getSize("default_margin").width - color: "white" + color: headerBackgroundColor anchors.fill: parent Loader { @@ -97,8 +98,12 @@ Item MouseArea { + id: mouseArea anchors.fill: parent onClicked: popup.visible ? popup.close() : popup.open() + hoverEnabled: true + onEntered: background.color = headerHoverColor + onExited: background.color = headerBackgroundColor } } From c08aa2205ca502580b4ba613cd9266601bfd5898 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 15 Nov 2018 09:37:54 +0100 Subject: [PATCH 0215/1292] Fix enabled checkbox for extruder selection CURA-5785 --- .../Menus/ConfigurationMenu/QuickConfigurationSelector.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml index e77f949661..6f4e58a326 100644 --- a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml +++ b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml @@ -150,8 +150,8 @@ Cura.ExpandableComponent OldControls.CheckBox { - checked: Cura.MachineManager.getExtruder(parent.model.index).isEnabled - onClicked: Cura.MachineManager.setExtruderEnabled(parent.model.index, checked) + checked: Cura.MachineManager.getExtruder(tabControl.model.index).isEnabled + onClicked: Cura.MachineManager.setExtruderEnabled(tabControl.model.index, checked) height: UM.Theme.getSize("setting_control").height style: UM.Theme.styles.checkbox } From 163f102dda027bf1337134e40d5db13450aae5e3 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 15 Nov 2018 09:38:14 +0100 Subject: [PATCH 0216/1292] Make extension menu items translatable If these extension plug-ins don't set their menu names, the plug-in name is used as the menu name. The plug-in names are not translated, so this appears as an untranslated string then. --- plugins/ChangeLogPlugin/ChangeLog.py | 3 ++- plugins/PostProcessingPlugin/PostProcessingPlugin.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/ChangeLogPlugin/ChangeLog.py b/plugins/ChangeLogPlugin/ChangeLog.py index 723c83a021..eeec5edf9b 100644 --- a/plugins/ChangeLogPlugin/ChangeLog.py +++ b/plugins/ChangeLogPlugin/ChangeLog.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. from UM.i18n import i18nCatalog @@ -29,6 +29,7 @@ class ChangeLog(Extension, QObject,): self._change_logs = None Application.getInstance().engineCreatedSignal.connect(self._onEngineCreated) Application.getInstance().getPreferences().addPreference("general/latest_version_changelog_shown", "2.0.0") #First version of CURA with uranium + self.setMenuName(catalog.i18nc("@item:inmenu", "Changelog")) self.addMenuItem(catalog.i18nc("@item:inmenu", "Show Changelog"), self.showChangelog) def getChangeLogs(self): diff --git a/plugins/PostProcessingPlugin/PostProcessingPlugin.py b/plugins/PostProcessingPlugin/PostProcessingPlugin.py index 1a1ea92d10..11ee610bec 100644 --- a/plugins/PostProcessingPlugin/PostProcessingPlugin.py +++ b/plugins/PostProcessingPlugin/PostProcessingPlugin.py @@ -32,7 +32,8 @@ class PostProcessingPlugin(QObject, Extension): def __init__(self, parent = None) -> None: QObject.__init__(self, parent) Extension.__init__(self) - self.addMenuItem(i18n_catalog.i18n("Modify G-Code"), self.showPopup) + self.setMenuName(i18n_catalog.i18nc("@item:inmenu", "Post Processing")) + self.addMenuItem(i18n_catalog.i18nc("@item:inmenu", "Modify G-Code"), self.showPopup) self._view = None # Loaded scripts are all scripts that can be used From f0b8c1e6117fc0ddb9815b09d88ea630ecc448ca Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 15 Nov 2018 09:45:46 +0100 Subject: [PATCH 0217/1292] Fix some minor display issues CURA-5785 --- resources/qml/PrintSetupSelector.qml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/resources/qml/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector.qml index 7a7d438bc3..e576dddc07 100644 --- a/resources/qml/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector.qml @@ -111,19 +111,22 @@ Cura.ExpandableComponent popupItem: Item { - height: settingsModeSelection.height + sidebarContents.height + height: settingsModeSelection.height + sidebarContents.height + 2 * UM.Theme.getSize("default_margin").height width: UM.Theme.getSize("print_setup_widget").width ListView { // Settings mode selection toggle id: settingsModeSelection model: modesListModel - width: Math.round(parent.width * 0.55) height: UM.Theme.getSize("print_setup_mode_toggle").height visible: !hideSettings - anchors.right: parent.right - anchors.rightMargin: UM.Theme.getSize("thick_margin").width + anchors + { + right: parent.right + left: parent.left + margins: UM.Theme.getSize("thick_margin").width + } ButtonGroup { From eca9820fc4a91abd8bcc87562df1ed5289edcf42 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 15 Nov 2018 13:55:33 +0100 Subject: [PATCH 0218/1292] Add toggle function to expandable popup Also ensures that the machineSelector closes the popup on making a choice CURA-5785 --- resources/qml/ExpandableComponent.qml | 15 ++++++++++++++- resources/qml/MachineSelector.qml | 13 +++++++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index d885253173..129c7dc923 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -40,6 +40,19 @@ Item // Is the "drawer" open? readonly property alias expanded: popup.visible + function togglePopup() + { + if(popup.visible) + { + popup.close() + } + else + { + popup.open() + } + } + + onPopupItemChanged: { // Since we want the size of the popup to be set by the size of the content, @@ -100,7 +113,7 @@ Item { id: mouseArea anchors.fill: parent - onClicked: popup.visible ? popup.close() : popup.open() + onClicked: togglePopup() hoverEnabled: true onEntered: background.color = headerHoverColor onExited: background.color = headerBackgroundColor diff --git a/resources/qml/MachineSelector.qml b/resources/qml/MachineSelector.qml index b2a34e186e..b18f427980 100644 --- a/resources/qml/MachineSelector.qml +++ b/resources/qml/MachineSelector.qml @@ -77,8 +77,12 @@ Cura.ExpandableComponent width: parent.width checkable: true - onClicked: Cura.MachineManager.setActiveMachine(model.id) radius: UM.Theme.getSize("default_radius").width + onClicked: + { + togglePopup() + Cura.MachineManager.setActiveMachine(model.id) + } Connections { @@ -114,8 +118,13 @@ Cura.ExpandableComponent width: parent.width checked: Cura.MachineManager.activeMachineId == model.id checkable: true - onClicked: Cura.MachineManager.setActiveMachine(model.id) + radius: UM.Theme.getSize("default_radius").width + onClicked: + { + togglePopup() + Cura.MachineManager.setActiveMachine(model.id) + } } } From 3629e3b6046a0646c951c5d914f7797f8e968165 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 15 Nov 2018 14:04:52 +0100 Subject: [PATCH 0219/1292] Added highlight to ExpandableComponent CURA-5785 --- resources/qml/ExpandableComponent.qml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index 129c7dc923..e110ed94be 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -40,6 +40,8 @@ Item // Is the "drawer" open? readonly property alias expanded: popup.visible + property alias expandedHighlightColor: expandedHightlight.color + function togglePopup() { if(popup.visible) @@ -52,7 +54,6 @@ Item } } - onPopupItemChanged: { // Since we want the size of the popup to be set by the size of the content, @@ -79,6 +80,7 @@ Item color: headerBackgroundColor anchors.fill: parent + Loader { id: headerItemLoader @@ -92,6 +94,17 @@ Item } } + // A highlight that is shown when the popup is expanded + Rectangle + { + id: expandedHightlight + width: parent.width + height: UM.Theme.getSize("thick_lining").height + color: UM.Theme.getColor("primary") + visible: expanded + anchors.bottom: parent.bottom + } + UM.RecolorImage { id: collapseButton From 6dd6f5ecc7ec6be44cd293b27925ad66771d18fa Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 15 Nov 2018 14:11:46 +0100 Subject: [PATCH 0220/1292] Made the hardcoded values of ExpandableComponent themable CURA-5785 --- resources/qml/ExpandableComponent.qml | 6 +++--- resources/themes/cura-light/theme.json | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index e110ed94be..9464a8f0ac 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -17,10 +17,10 @@ Item property var popupItem // The background color of the popup - property color popupBackgroundColor: "white" + property color popupBackgroundColor: UM.Theme.getColor("action_button") - property color headerBackgroundColor: "white" - property color headerHoverColor: "white" + property color headerBackgroundColor: UM.Theme.getColor("action_button") + property color headerHoverColor: UM.Theme.getColor("action_button_hovered") // How much spacing is needed around the popupItem property alias popupPadding: popup.padding diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index a36940641e..d28611529b 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -75,6 +75,7 @@ "lining": [192, 193, 194, 255], "viewport_overlay": [0, 0, 0, 192], + "primary": [50, 130, 255, 255], "primary_hover": [48, 182, 231, 255], "primary_text": [255, 255, 255, 255], @@ -157,7 +158,7 @@ "action_button": [255, 255, 255, 255], "action_button_text": [0, 0, 0, 255], "action_button_border": [127, 127, 127, 255], - "action_button_hovered": [255, 255, 255, 255], + "action_button_hovered": [232, 242, 252, 255], "action_button_hovered_text": [31, 36, 39, 255], "action_button_hovered_border": [50, 130, 255, 255], "action_button_active": [255, 255, 255, 255], From 78e64944307168a886a1c0ab01a4b39e4d3144c4 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 15 Nov 2018 15:13:36 +0100 Subject: [PATCH 0221/1292] Read SDK version from new semver field The sdk_version field should stay the ordinary plain number (the major version number of the semver field) so that older Cura versions don't break. Newly built packages will get built with both sdk_version_semver and the normal sdk_version, so that the packages can be read with any Cura version from 3.6 onwards. Contributes to issue CURA-5940. --- plugins/Toolbox/src/Toolbox.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 4f3722d7ba..e491a06770 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -511,7 +511,8 @@ class Toolbox(QObject, Extension): # version, we also need to check if the current one has a lower SDK version. If so, this package should also # be upgradable. elif remote_version == local_version: - can_upgrade = local_package.get("sdk_version", 0) < remote_package.get("sdk_version", 0) + # First read sdk_version_semver. If that doesn't exist, read just sdk_version (old version system). + can_upgrade = local_package.get("sdk_version_semver", local_package.get("sdk_version", 0)) < remote_package.get("sdk_version_semver", remote_package.get("sdk_version", 0)) return can_upgrade From e9216936d741acf435f260b1bd5b10baffddb594 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 15 Nov 2018 15:20:21 +0100 Subject: [PATCH 0222/1292] Compare SDK version as Version instances This allows it to compare versions that are remote as integer and local as string, or vice-versa. Much more robust. Contributes to issue CURA-5940. --- plugins/Toolbox/src/Toolbox.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index e491a06770..562a964f01 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -512,7 +512,9 @@ class Toolbox(QObject, Extension): # be upgradable. elif remote_version == local_version: # First read sdk_version_semver. If that doesn't exist, read just sdk_version (old version system). - can_upgrade = local_package.get("sdk_version_semver", local_package.get("sdk_version", 0)) < remote_package.get("sdk_version_semver", remote_package.get("sdk_version", 0)) + remote_sdk_version = Version(remote_package.get("sdk_version_semver", remote_package.get("sdk_version", 0))) + local_sdk_version = Version(local_package.get("sdk_version_semver", local_package.get("sdk_version", 0))) + can_upgrade = local_sdk_version < remote_sdk_version return can_upgrade From 2bf4354fed244e47ab00da8528f1db7b6a906a15 Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Thu, 15 Nov 2018 15:57:34 +0100 Subject: [PATCH 0223/1292] Removed minimum_value for the setting support_roof_offset and support_bottom_offset CURA-5880 --- resources/definitions/fdmprinter.def.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 325e4b6c79..7cb6720f27 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -4456,7 +4456,6 @@ "description": "Amount of offset applied to the roofs of the support.", "unit": "mm", "type": "float", - "minimum_value": "0", "default_value": 0.0, "value": "extruderValue(support_roof_extruder_nr, 'support_interface_offset')", "maximum_value": "extruderValue(support_extruder_nr, 'support_offset')", @@ -4471,7 +4470,6 @@ "description": "Amount of offset applied to the floors of the support.", "unit": "mm", "type": "float", - "minimum_value": "0", "default_value": 0.0, "value": "extruderValue(support_bottom_extruder_nr, 'support_interface_offset')", "maximum_value": "extruderValue(support_extruder_nr, 'support_offset')", From 240ac1f06b6458d154d84ce326a3dd8e16777aa1 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 16 Nov 2018 13:03:45 +0100 Subject: [PATCH 0224/1292] Clarify some setting descriptions --- resources/definitions/fdmextruder.def.json | 2 +- resources/definitions/fdmprinter.def.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/definitions/fdmextruder.def.json b/resources/definitions/fdmextruder.def.json index 19c9e92d18..55556f5764 100644 --- a/resources/definitions/fdmextruder.def.json +++ b/resources/definitions/fdmextruder.def.json @@ -78,7 +78,7 @@ "machine_extruder_start_code": { "label": "Extruder Start G-Code", - "description": "Start g-code to execute whenever turning the extruder on.", + "description": "Start g-code to execute whenever this extruder is switched to.", "type": "str", "default_value": "", "settable_per_mesh": false, diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 7cb6720f27..b1812ae705 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -2406,7 +2406,7 @@ "switch_extruder_retraction_amount": { "label": "Nozzle Switch Retraction Distance", - "description": "The amount of retraction: Set at 0 for no retraction at all. This should generally be the same as the length of the heat zone.", + "description": "The amount of retraction when switching extruder. Set to 0 for no retraction at all. This should generally be the same as the length of the heat zone.", "type": "float", "unit": "mm", "enabled": "retraction_enable", From 93bd5fee5387e45ea880ee1fc6125790546e465a Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 16 Nov 2018 13:44:46 +0100 Subject: [PATCH 0225/1292] Fix wrong push free shadow for one at a time. It was applying the size twice. CURA-5822 --- cura/Scene/ConvexHullDecorator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Scene/ConvexHullDecorator.py b/cura/Scene/ConvexHullDecorator.py index 39124c5ba3..0c03ae615b 100644 --- a/cura/Scene/ConvexHullDecorator.py +++ b/cura/Scene/ConvexHullDecorator.py @@ -272,7 +272,7 @@ class ConvexHullDecorator(SceneNodeDecorator): head_and_fans = self._getHeadAndFans().intersectionConvexHulls(mirrored) # Min head hull is used for the push free - convex_hull = self._compute2DConvexHeadFull() + convex_hull = self._compute2DConvexHull() if convex_hull: return convex_hull.getMinkowskiHull(head_and_fans) return None From e3dd5f1c39cea14bbeefed4ae2191f19ffdf8d75 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 16 Nov 2018 13:59:51 +0100 Subject: [PATCH 0226/1292] Add documentation about qml z fix Co-Authored-By: nallath --- plugins/PrepareStage/PrepareMenu.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index 9507d786b2..c464727dde 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -52,7 +52,7 @@ Item Cura.MachineSelector { id: machineSelection - z: openFileButtonBackground.z - 1 + z: openFileButtonBackground.z - 1 //Ensure that the tooltip of the open file button stays above the item row. Layout.minimumWidth: UM.Theme.getSize("machine_selector_widget").width Layout.maximumWidth: UM.Theme.getSize("machine_selector_widget").width Layout.fillWidth: true @@ -117,4 +117,4 @@ Item } } } -} \ No newline at end of file +} From de020b4c758ba05dcbf374616c955b316683e883 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 16 Nov 2018 14:02:00 +0100 Subject: [PATCH 0227/1292] Remove commented out code Co-Authored-By: nallath --- plugins/PreviewStage/PreviewMenu.qml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index df04507ba4..d7b5574035 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -40,7 +40,6 @@ Item Row { anchors.centerIn: parent - //spacing: UM.Theme.getSize("default_margin").width height: parent.height Cura.ExpandableComponent @@ -138,4 +137,4 @@ Item } } } -} \ No newline at end of file +} From 81b6f3ab11b0b73d6c0db10ff441bac1de7072e4 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 16 Nov 2018 14:03:39 +0100 Subject: [PATCH 0228/1292] Update unclear qml ID's CURA-5785 Co-Authored-By: nallath --- plugins/PreviewStage/PreviewMenu.qml | 4 ++-- resources/qml/ExpandableComponent.qml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index d7b5574035..bf162be4e3 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -78,7 +78,7 @@ Item popupItem: Column { - id: column + id: viewSelectorPopup width: viewSelector.width - 2 * UM.Theme.getSize("default_margin").width // For some reason the height of the column gets set to 0 if this is not set... @@ -86,7 +86,7 @@ Item Repeater { - id: networkedPrinters + id: viewsList model: viewSelector.viewModel RoundButton { diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index 9464a8f0ac..4d54ad9611 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -97,7 +97,7 @@ Item // A highlight that is shown when the popup is expanded Rectangle { - id: expandedHightlight + id: expandedHighlight width: parent.width height: UM.Theme.getSize("thick_lining").height color: UM.Theme.getColor("primary") From 514fc130457cbb488c06168eb51dc8e0437e8c9e Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 16 Nov 2018 14:04:33 +0100 Subject: [PATCH 0229/1292] Remove redundant documentation CURA-5875 Co-Authored-By: nallath --- resources/qml/ExpandableComponent.qml | 2 -- 1 file changed, 2 deletions(-) diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index 4d54ad9611..bbba44f743 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -16,7 +16,6 @@ Item // The popupItem holds the QML item that is shown when the "open" button is pressed property var popupItem - // The background color of the popup property color popupBackgroundColor: UM.Theme.getColor("action_button") property color headerBackgroundColor: UM.Theme.getColor("action_button") @@ -31,7 +30,6 @@ Item // What icon should be displayed on the right. property alias iconSource: collapseButton.source - // What is the color of the icon? property alias iconColor: collapseButton.color // The icon size (it's always drawn as a square) From e087db7c2e0ce3857e16b14c499d5d239abc8828 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 16 Nov 2018 13:26:03 +0100 Subject: [PATCH 0230/1292] Code style and fixes to comments Contributes to issue CURA-5785. --- plugins/PreviewStage/PreviewMenu.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index bf162be4e3..a3235d7cb8 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -54,13 +54,13 @@ Item { for (var i = 0; i < viewModel.rowCount(); i++) { - if(viewModel.getItem(i).active) + if (viewModel.getItem(i).active) { return viewModel.getItem(i) } } // Nothing was active, so just return the first one (the list is sorted by priority, so the most - // important one sshould be returned) + // important one should be returned) return viewModel.getItem(0) } From 3ef6d0544a02705eba13e5e115c3e1f40694fb95 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 16 Nov 2018 14:11:04 +0100 Subject: [PATCH 0231/1292] Fix spelling and indents Ant-fuckery, as they say in the low lands. Contributes to issue CURA-5785. --- resources/qml/IconWithText.qml | 2 +- resources/qml/MachineSelector.qml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/qml/IconWithText.qml b/resources/qml/IconWithText.qml index d19c7e3899..9ce2f412cc 100644 --- a/resources/qml/IconWithText.qml +++ b/resources/qml/IconWithText.qml @@ -10,7 +10,7 @@ import Cura 1.0 as Cura // Reusable component that holds an (re-colorable) icon on the left with some text on the right. // This component is also designed to be used with layouts. It will use the width of the text + icon as preferred width -// It sets the icon size + half of the content as it's minium width (in which case it will elide the text) +// It sets the icon size + half of the content as its minium width (in which case it will elide the text) Item { property alias iconColor: icon.color diff --git a/resources/qml/MachineSelector.qml b/resources/qml/MachineSelector.qml index b18f427980..fa680fa9a6 100644 --- a/resources/qml/MachineSelector.qml +++ b/resources/qml/MachineSelector.qml @@ -80,8 +80,8 @@ Cura.ExpandableComponent radius: UM.Theme.getSize("default_radius").width onClicked: { - togglePopup() - Cura.MachineManager.setActiveMachine(model.id) + togglePopup() + Cura.MachineManager.setActiveMachine(model.id) } Connections From e9e8c49b2d9d0c898c88dced34b8179b8bc1f0de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Fri, 16 Nov 2018 14:16:45 +0100 Subject: [PATCH 0232/1292] Added tests for SendMaterialJob and refactored SendMaterialJob for better testability. This is part of a larger project to create tests for the UM3NetworkPrinting plugin in preparation for printing from the cloud --- plugins/UM3NetworkPrinting/src/Models.py | 87 +++++ .../UM3NetworkPrinting/src/SendMaterialJob.py | 124 ++++--- .../UM3NetworkPrinting/TestSendMaterialJob.py | 327 ++++++++++++++++++ 3 files changed, 491 insertions(+), 47 deletions(-) create mode 100644 plugins/UM3NetworkPrinting/src/Models.py create mode 100644 tests/plugins/UM3NetworkPrinting/TestSendMaterialJob.py diff --git a/plugins/UM3NetworkPrinting/src/Models.py b/plugins/UM3NetworkPrinting/src/Models.py new file mode 100644 index 0000000000..6d42b39370 --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Models.py @@ -0,0 +1,87 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +from typing import Optional + + +class BaseModel: + def __init__(self, **kwargs): + self.__dict__.update(kwargs) + + def __eq__(self, other): + return self.__dict__ == other.__dict__ if type(self) == type(other) else False + + +## Represents an item in the cluster API response for installed materials. +class ClusterMaterial(BaseModel): + def __init__(self, **kwargs): + super().__init__(**kwargs) + self.version = int(self.version) + self.density = float(self.density) + + guid: None # type: Optional[str] + + material: None # type: Optional[str] + + brand: None # type: Optional[str] + + version = None # type: Optional[int] + + color: None # type: Optional[str] + + density: None # type: Optional[float] + + +class LocalMaterialProperties(BaseModel): + def __init__(self, **kwargs): + super().__init__(**kwargs) + self.density = float(self.density) + self.diameter = float(self.diameter) + self.weight = float(self.weight) + + density: None # type: Optional[float] + + diameter: None # type: Optional[float] + + weight: None # type: Optional[int] + + +class LocalMaterial(BaseModel): + def __init__(self, **kwargs): + super().__init__(**kwargs) + self.properties = LocalMaterialProperties(**self.properties) + self.approximate_diameter = float(self.approximate_diameter) + self.version = int(self.version) + + GUID: None # type: Optional[str] + + id: None # type: Optional[str] + + type: None # type: Optional[str] + + status: None # type: Optional[str] + + base_file: None # type: Optional[str] + + setting_version: None # type: Optional[str] + + version = None # type: Optional[int] + + name: None # type: Optional[str] + + brand: None # type: Optional[str] + + material: None # type: Optional[str] + + color_name: None # type: Optional[str] + + description: None # type: Optional[str] + + adhesion_info: None # type: Optional[str] + + approximate_diameter: None # type: Optional[float] + + properties: None # type: LocalMaterialProperties + + definition: None # type: Optional[str] + + compatible: None # type: Optional[bool] diff --git a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py index 8491e79c29..126ed07317 100644 --- a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py @@ -1,99 +1,129 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -import json #To understand the list of materials from the printer reply. -import os #To walk over material files. -import os.path #To filter on material files. -from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest #To listen to the reply from the printer. -from typing import Any, Dict, Set, TYPE_CHECKING -import urllib.parse #For getting material IDs from their file names. +import json # To understand the list of materials from the printer reply. +import os # To walk over material files. +import os.path # To filter on material files. +import urllib.parse # For getting material IDs from their file names. +from typing import Dict, TYPE_CHECKING -from UM.Job import Job #The interface we're implementing. +from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest # To listen to the reply from the printer. + +from UM.Job import Job # The interface we're implementing. from UM.Logger import Logger -from UM.MimeTypeDatabase import MimeTypeDatabase #To strip the extensions of the material profile files. +from UM.MimeTypeDatabase import MimeTypeDatabase # To strip the extensions of the material profile files. from UM.Resources import Resources -from UM.Settings.ContainerRegistry import ContainerRegistry #To find the GUIDs of materials. - -from cura.CuraApplication import CuraApplication #For the resource types. +from UM.Settings.ContainerRegistry import ContainerRegistry # To find the GUIDs of materials. +from cura.CuraApplication import CuraApplication # For the resource types. +from plugins.UM3NetworkPrinting.src.Models import ClusterMaterial, LocalMaterial if TYPE_CHECKING: from .ClusterUM3OutputDevice import ClusterUM3OutputDevice + ## Asynchronous job to send material profiles to the printer. # # This way it won't freeze up the interface while sending those materials. class SendMaterialJob(Job): def __init__(self, device: "ClusterUM3OutputDevice") -> None: super().__init__() - self.device = device #type: ClusterUM3OutputDevice + self.device = device # type: ClusterUM3OutputDevice def run(self) -> None: - self.device.get("materials/", on_finished = self.sendMissingMaterials) + self.device.get("materials/", on_finished=self.sendMissingMaterials) def sendMissingMaterials(self, reply: QNetworkReply) -> None: - if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) != 200: #Got an error from the HTTP request. + if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) != 200: # Got an error from the HTTP request. Logger.log("e", "Couldn't request current material storage on printer. Not syncing materials.") return - remote_materials_list = reply.readAll().data().decode("utf-8") + # Collect materials from the printer's reply try: - remote_materials_list = json.loads(remote_materials_list) + remote_materials_by_guid = self._parseReply(reply) except json.JSONDecodeError: Logger.log("e", "Request material storage on printer: I didn't understand the printer's answer.") return - try: - remote_materials_by_guid = {material["guid"]: material for material in remote_materials_list} #Index by GUID. except KeyError: Logger.log("e", "Request material storage on printer: Printer's answer was missing GUIDs.") return - container_registry = ContainerRegistry.getInstance() - local_materials_list = filter(lambda material: ("GUID" in material and "version" in material and "id" in material), container_registry.findContainersMetadata(type = "material")) - local_materials_by_guid = {material["GUID"]: material for material in local_materials_list if material["id"] == material["base_file"]} - for material in local_materials_list: #For each GUID get the material with the highest version number. - try: - if int(material["version"]) > local_materials_by_guid[material["GUID"]]["version"]: - local_materials_by_guid[material["GUID"]] = material - except ValueError: - Logger.log("e", "Material {material_id} has invalid version number {number}.".format(material_id = material["id"], number = material["version"])) - continue + # Collect local materials + local_materials_by_guid = self._getLocalMaterials() - materials_to_send = set() #type: Set[Dict[str, Any]] - for guid, material in local_materials_by_guid.items(): - if guid not in remote_materials_by_guid: - materials_to_send.add(material["id"]) - continue - try: - if int(material["version"]) > remote_materials_by_guid[guid]["version"]: - materials_to_send.add(material["id"]) - continue - except KeyError: - Logger.log("e", "Current material storage on printer was an invalid reply (missing version).") - return + # Find out what materials are new or updated annd must be sent to the printer + materials_to_send = { + material.id + for guid, material in local_materials_by_guid.items() + if guid not in remote_materials_by_guid or + material.version > remote_materials_by_guid[guid].version + } + # Send materials to the printer + self.sendMaterialsToPrinter(materials_to_send) + + def sendMaterialsToPrinter(self, materials_to_send): for file_path in Resources.getAllResourcesOfType(CuraApplication.ResourceTypes.MaterialInstanceContainer): try: mime_type = MimeTypeDatabase.getMimeTypeForFile(file_path) except MimeTypeDatabase.MimeTypeNotFoundError: - continue #Not the sort of file we'd like to send then. + continue # Not the sort of file we'd like to send then. + _, file_name = os.path.split(file_path) material_id = urllib.parse.unquote_plus(mime_type.stripExtension(file_name)) + if material_id not in materials_to_send: continue parts = [] with open(file_path, "rb") as f: - parts.append(self.device._createFormPart("name=\"file\"; filename=\"{file_name}\"".format(file_name = file_name), f.read())) + parts.append( + self.device._createFormPart("name=\"file\"; filename=\"{file_name}\"".format(file_name=file_name), + f.read())) signature_file_path = file_path + ".sig" if os.path.exists(signature_file_path): _, signature_file_name = os.path.split(signature_file_path) with open(signature_file_path, "rb") as f: - parts.append(self.device._createFormPart("name=\"signature_file\"; filename=\"{file_name}\"".format(file_name = signature_file_name), f.read())) + parts.append(self.device._createFormPart( + "name=\"signature_file\"; filename=\"{file_name}\"".format(file_name=signature_file_name), + f.read())) - Logger.log("d", "Syncing material {material_id} with cluster.".format(material_id = material_id)) - self.device.postFormWithParts(target = "materials/", parts = parts, on_finished = self.sendingFinished) + Logger.log("d", "Syncing material {material_id} with cluster.".format(material_id=material_id)) + self.device.postFormWithParts(target="materials/", parts=parts, on_finished=self.sendingFinished) def sendingFinished(self, reply: QNetworkReply): if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) != 200: - Logger.log("e", "Received error code from printer when syncing material: {code}".format(code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute))) - Logger.log("e", reply.readAll().data().decode("utf-8")) \ No newline at end of file + Logger.log("e", "Received error code from printer when syncing material: {code}".format( + code=reply.attribute(QNetworkRequest.HttpStatusCodeAttribute))) + Logger.log("e", reply.readAll().data().decode("utf-8")) + + ## Parse the reply from the printer + # + # Parses the reply to a "/materials" request to the printer + # + # \return a dictionary of ClustMaterial objects by GUID + # \throw json.JSONDecodeError Raised when the reply does not contain a valid json string + # \throw KeyErrror Raised when on of the materials does not include a valid guid + @classmethod + def _parseReply(cls, reply: QNetworkReply) -> Dict[str, ClusterMaterial]: + remote_materials_list = json.loads(reply.readAll().data().decode("utf-8")) + return {material["guid"]: ClusterMaterial(**material) for material in remote_materials_list} + + ## Retrieves a list of local materials + # + # Only the new newest version of the local materials is returned + # + # \return a dictionary of LocalMaterial objects by GUID + @classmethod + def _getLocalMaterials(cls): + result = {} + for material in ContainerRegistry.getInstance().findContainersMetadata(type="material"): + try: + localMaterial = LocalMaterial(**material) + + if localMaterial.GUID not in result or localMaterial.version > result.get(localMaterial.GUID).version: + result[localMaterial.GUID] = localMaterial + except (ValueError): + Logger.log("e", "Material {material_id} has invalid version number {number}.".format( + material_id=material["id"], number=material["version"])) + + return result diff --git a/tests/plugins/UM3NetworkPrinting/TestSendMaterialJob.py b/tests/plugins/UM3NetworkPrinting/TestSendMaterialJob.py new file mode 100644 index 0000000000..3cdb73af22 --- /dev/null +++ b/tests/plugins/UM3NetworkPrinting/TestSendMaterialJob.py @@ -0,0 +1,327 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +import io +import json +from typing import Any, List +from unittest import TestCase, mock +from unittest.mock import patch, call + +from PyQt5.QtCore import QByteArray + +from UM.Logger import Logger +from UM.MimeTypeDatabase import MimeType +from UM.Settings.ContainerRegistry import ContainerInterface, ContainerRegistryInterface, \ + DefinitionContainerInterface, ContainerRegistry +from plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice import ClusterUM3OutputDevice +from plugins.UM3NetworkPrinting.src.Models import ClusterMaterial +from plugins.UM3NetworkPrinting.src.SendMaterialJob import SendMaterialJob + +# All log entries written to Log.log by the class-under-test are written to this list. It is cleared before each test +# run and check afterwards +_logentries = [] + + +def new_log(*args): + _logentries.append(args) + + +class TestContainerRegistry(ContainerRegistryInterface): + def __init__(self): + self.containersMetaData = None + + def findContainers(self, *, ignore_case: bool = False, **kwargs: Any) -> List[ContainerInterface]: + raise NotImplementedError() + + def findDefinitionContainers(self, **kwargs: Any) -> List[DefinitionContainerInterface]: + raise NotImplementedError() + + @classmethod + def getApplication(cls) -> "Application": + raise NotImplementedError() + + def getEmptyInstanceContainer(self) -> "InstanceContainer": + raise NotImplementedError() + + def isReadOnly(self, container_id: str) -> bool: + raise NotImplementedError() + + def setContainersMetadata(self, value): + self.containersMetaData = value + + def findContainersMetadata(self, type): + return self.containersMetaData + + +class FakeDevice(ClusterUM3OutputDevice): + def _createFormPart(self, content_header, data, content_type=None): + return "xxx" + + +class TestSendMaterialJob(TestCase): + _LOCALMATERIAL_WHITE = {'type': 'material', 'status': 'unknown', 'id': 'generic_pla_white', + 'base_file': 'generic_pla_white', 'setting_version': 5, 'name': 'White PLA', + 'brand': 'Generic', 'material': 'PLA', 'color_name': 'White', + 'GUID': 'badb0ee7-87c8-4f3f-9398-938587b67dce', 'version': '1', 'color_code': '#ffffff', + 'description': 'Test PLA White', 'adhesion_info': 'Use glue.', 'approximate_diameter': '3', + 'properties': {'density': '1.00', 'diameter': '2.85', 'weight': '750'}, + 'definition': 'fdmprinter', 'compatible': True} + _LOCALMATERIAL_BLACK = {'type': 'material', 'status': 'unknown', 'id': 'generic_pla_black', + 'base_file': 'generic_pla_black', 'setting_version': 5, 'name': 'Yellow CPE', + 'brand': 'Ultimaker', 'material': 'CPE', 'color_name': 'Black', + 'GUID': '5fbb362a-41f9-4818-bb43-15ea6df34aa4', 'version': '1', 'color_code': '#000000', + 'description': 'Test PLA Black', 'adhesion_info': 'Use glue.', 'approximate_diameter': '3', + 'properties': {'density': '1.01', 'diameter': '2.85', 'weight': '750'}, + 'definition': 'fdmprinter', 'compatible': True} + + _REMOTEMATERIAL_WHITE = { + "guid": "badb0ee7-87c8-4f3f-9398-938587b67dce", + "material": "PLA", + "brand": "Generic", + "version": 1, + "color": "White", + "density": 1.00 + } + _REMOTEMATERIAL_BLACK = { + "guid": "5fbb362a-41f9-4818-bb43-15ea6df34aa4", + "material": "PLA", + "brand": "Generic", + "version": 2, + "color": "Black", + "density": 1.00 + } + + def setUp(self): + # Make sure the we start with clean (log) slate + _logentries.clear() + + def tearDown(self): + # If there are still log entries that were not checked something is wrong or we must add checks for them + self.assertEqual(len(_logentries), 0) + + @patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") + def test_run(self, device_mock): + with mock.patch.object(Logger, 'log', new=new_log): + job = SendMaterialJob(device_mock) + job.run() + + device_mock.get.assert_called_with("materials/", on_finished=job.sendMissingMaterials) + self.assertEqual(0, len(_logentries)) + + @patch("PyQt5.QtNetwork.QNetworkReply") + def test_sendMissingMaterials_withFailedRequest(self, reply_mock): + reply_mock.attribute.return_value = 404 + + with mock.patch.object(Logger, 'log', new=new_log): + SendMaterialJob(None).sendMissingMaterials(reply_mock) + + reply_mock.attribute.assert_called_with(0) + self.assertEqual(reply_mock.method_calls, [call.attribute(0)]) + self._assertLogEntries([('e', "Couldn't request current material storage on printer. Not syncing materials.")], + _logentries) + + @patch("PyQt5.QtNetwork.QNetworkReply") + def test_sendMissingMaterials_withBadJsonAnswer(self, reply_mock): + reply_mock.attribute.return_value = 200 + reply_mock.readAll.return_value = QByteArray(b'Six sick hicks nick six slick bricks with picks and sticks.') + + with mock.patch.object(Logger, 'log', new=new_log): + SendMaterialJob(None).sendMissingMaterials(reply_mock) + + reply_mock.attribute.assert_called_with(0) + self.assertEqual(reply_mock.method_calls, [call.attribute(0), call.readAll()]) + self._assertLogEntries( + [('e', "Request material storage on printer: I didn't understand the printer's answer.")], + _logentries) + + @patch("PyQt5.QtNetwork.QNetworkReply") + def test_sendMissingMaterials_withMissingGuid(self, reply_mock): + reply_mock.attribute.return_value = 200 + remoteMaterialWithoutGuid = self._REMOTEMATERIAL_WHITE.copy() + del remoteMaterialWithoutGuid["guid"] + reply_mock.readAll.return_value = QByteArray(json.dumps([remoteMaterialWithoutGuid]).encode("ascii")) + + with mock.patch.object(Logger, 'log', new=new_log): + SendMaterialJob(None).sendMissingMaterials(reply_mock) + + reply_mock.attribute.assert_called_with(0) + self.assertEqual(reply_mock.method_calls, [call.attribute(0), call.readAll()]) + self._assertLogEntries( + [('e', "Request material storage on printer: Printer's answer was missing GUIDs.")], + _logentries) + + @patch("UM.Resources.Resources.getAllResourcesOfType", lambda _: []) + @patch("PyQt5.QtNetwork.QNetworkReply") + def test_sendMissingMaterials_WithInvalidVersionInLocalMaterial(self, reply_mock): + reply_mock.attribute.return_value = 200 + reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTEMATERIAL_WHITE]).encode("ascii")) + + containerRegistry = TestContainerRegistry() + localMaterialWhiteWithInvalidVersion = self._LOCALMATERIAL_WHITE.copy() + localMaterialWhiteWithInvalidVersion["version"] = "one" + containerRegistry.setContainersMetadata([localMaterialWhiteWithInvalidVersion]) + + with mock.patch.object(Logger, "log", new=new_log): + with mock.patch.object(ContainerRegistry, "getInstance", lambda: containerRegistry): + SendMaterialJob(None).sendMissingMaterials(reply_mock) + + reply_mock.attribute.assert_called_with(0) + self.assertEqual(reply_mock.method_calls, [call.attribute(0), call.readAll()]) + self._assertLogEntries([('e', "Material generic_pla_white has invalid version number one.")], _logentries) + + @patch("UM.Resources.Resources.getAllResourcesOfType", lambda _: []) + @patch("PyQt5.QtNetwork.QNetworkReply") + def test_sendMissingMaterials_WithMultipleLocalVersionsLowFirst(self, reply_mock): + reply_mock.attribute.return_value = 200 + reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTEMATERIAL_WHITE]).encode("ascii")) + + containerRegistry = TestContainerRegistry() + localMaterialWhiteWithHigherVersion = self._LOCALMATERIAL_WHITE.copy() + localMaterialWhiteWithHigherVersion["version"] = "2" + containerRegistry.setContainersMetadata([self._LOCALMATERIAL_WHITE, localMaterialWhiteWithHigherVersion]) + + with mock.patch.object(Logger, "log", new=new_log): + with mock.patch.object(ContainerRegistry, "getInstance", lambda: containerRegistry): + SendMaterialJob(None).sendMissingMaterials(reply_mock) + + reply_mock.attribute.assert_called_with(0) + self.assertEqual(reply_mock.method_calls, [call.attribute(0), call.readAll()]) + self._assertLogEntries([], _logentries) + + @patch("UM.Resources.Resources.getAllResourcesOfType", lambda _: []) + @patch("PyQt5.QtNetwork.QNetworkReply") + def test_sendMissingMaterials_MaterialMissingOnPrinter(self, reply_mock): + reply_mock.attribute.return_value = 200 + reply_mock.readAll.return_value = QByteArray( + json.dumps([self._REMOTEMATERIAL_WHITE]).encode("ascii")) + + containerRegistry = TestContainerRegistry() + containerRegistry.setContainersMetadata([self._LOCALMATERIAL_WHITE, self._LOCALMATERIAL_BLACK]) + + with mock.patch.object(Logger, "log", new=new_log): + with mock.patch.object(ContainerRegistry, "getInstance", lambda: containerRegistry): + SendMaterialJob(None).sendMissingMaterials(reply_mock) + + reply_mock.attribute.assert_called_with(0) + self.assertEqual(reply_mock.method_calls, [call.attribute(0), call.readAll()]) + self._assertLogEntries([], _logentries) + + @patch("builtins.open", lambda a, b: io.StringIO("")) + @patch("UM.MimeTypeDatabase.MimeTypeDatabase.getMimeTypeForFile", + lambda _: MimeType(name="application/x-ultimaker-material-profile", comment="Ultimaker Material Profile", + suffixes=["xml.fdm_material"])) + @patch("UM.Resources.Resources.getAllResourcesOfType", lambda _: ["/materials/generic_pla_white.xml.fdm_material"]) + @patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") + def test_sendMaterialsToPrinter(self, device): + with mock.patch.object(Logger, "log", new=new_log): + SendMaterialJob(device).sendMaterialsToPrinter({'generic_pla_white'}) + + self._assertLogEntries([("d", "Syncing material generic_pla_white with cluster.")], _logentries) + + @patch("PyQt5.QtNetwork.QNetworkReply") + def xtest_sendMissingMaterials(self, reply_mock): + reply_mock.attribute.return_value = 200 + reply_mock.readAll.return_value = QByteArray( + json.dumps([self._REMOTEMATERIAL_WHITE], self._REMOTEMATERIAL_BLACK).encode("ascii")) + + containerRegistry = TestContainerRegistry() + containerRegistry.setContainersMetadata([self._LOCALMATERIAL_WHITE, self._LOCALMATERIAL_BLACK]) + + with mock.patch.object(Logger, "log", new=new_log): + with mock.patch.object(ContainerRegistry, "getInstance", lambda: containerRegistry): + SendMaterialJob(None).sendMissingMaterials(reply_mock) + + reply_mock.attribute.assert_called_with(0) + self.assertEqual(reply_mock.method_calls, [call.attribute(0), call.readAll()]) + self._assertLogEntries([], _logentries) + + @patch("PyQt5.QtNetwork.QNetworkReply") + def test_sendingFinished_success(self, reply_mock) -> None: + reply_mock.attribute.return_value = 200 + with mock.patch.object(Logger, 'log', new=new_log): + SendMaterialJob(None).sendingFinished(reply_mock) + + reply_mock.attribute.assert_called_once_with(0) + self.assertEqual(0, len(_logentries)) + + @patch("PyQt5.QtNetwork.QNetworkReply") + def test_sendingFinished_failed(self, reply_mock) -> None: + reply_mock.attribute.return_value = 404 + reply_mock.readAll.return_value = QByteArray(b'Six sick hicks nick six slick bricks with picks and sticks.') + + with mock.patch.object(Logger, 'log', new=new_log): + SendMaterialJob(None).sendingFinished(reply_mock) + + reply_mock.attribute.assert_called_with(0) + self.assertEqual(reply_mock.method_calls, [call.attribute(0), call.attribute(0), call.readAll()]) + + self._assertLogEntries([ + ("e", "Received error code from printer when syncing material: 404"), + ("e", "Six sick hicks nick six slick bricks with picks and sticks.") + ], _logentries) + + @patch("PyQt5.QtNetwork.QNetworkReply") + def test_parseReply(self, reply_mock): + reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTEMATERIAL_WHITE]).encode("ascii")) + + response = SendMaterialJob._parseReply(reply_mock) + + self.assertTrue(len(response) == 1) + self.assertEqual(next(iter(response.values())), ClusterMaterial(**self._REMOTEMATERIAL_WHITE)) + + @patch("PyQt5.QtNetwork.QNetworkReply") + def test_parseReplyWithInvalidMaterial(self, reply_mock): + remoteMaterialWithInvalidVersion = self._REMOTEMATERIAL_WHITE.copy() + remoteMaterialWithInvalidVersion["version"] = "one" + reply_mock.readAll.return_value = QByteArray(json.dumps([remoteMaterialWithInvalidVersion]).encode("ascii")) + + with self.assertRaises(ValueError): + SendMaterialJob._parseReply(reply_mock) + + def test__getLocalMaterials(self): + containerRegistry = TestContainerRegistry() + containerRegistry.setContainersMetadata([self._LOCALMATERIAL_WHITE, self._LOCALMATERIAL_BLACK]) + + with mock.patch.object(Logger, "log", new=new_log): + with mock.patch.object(ContainerRegistry, "getInstance", lambda: containerRegistry): + local_materials = SendMaterialJob(None)._getLocalMaterials() + + self.assertTrue(len(local_materials) == 2) + + def test__getLocalMaterialsWithMultipleVersions(self): + containerRegistry = TestContainerRegistry() + localMaterialWithNewerVersion = self._LOCALMATERIAL_WHITE.copy() + localMaterialWithNewerVersion["version"] = 2 + containerRegistry.setContainersMetadata([self._LOCALMATERIAL_WHITE, localMaterialWithNewerVersion]) + + with mock.patch.object(Logger, "log", new=new_log): + with mock.patch.object(ContainerRegistry, "getInstance", lambda: containerRegistry): + local_materials = SendMaterialJob(None)._getLocalMaterials() + + self.assertTrue(len(local_materials) == 1) + self.assertTrue(list(local_materials.values())[0].version == 2) + + containerRegistry.setContainersMetadata([localMaterialWithNewerVersion, self._LOCALMATERIAL_WHITE]) + + with mock.patch.object(Logger, "log", new=new_log): + with mock.patch.object(ContainerRegistry, "getInstance", lambda: containerRegistry): + local_materials = SendMaterialJob(None)._getLocalMaterials() + + self.assertTrue(len(local_materials) == 1) + self.assertTrue(list(local_materials.values())[0].version == 2) + + def _assertLogEntries(self, first, second): + """ + Inspects the two sets of log entry tuples and fails when they are not the same + :param first: The first set of tuples + :param second: The second set of tuples + """ + self.assertEqual(len(first), len(second)) + + while len(first) > 0: + e1, m1 = first[0] + e2, m2 = second[0] + self.assertEqual(e1, e2) + self.assertEqual(m1, m2) + first.pop(0) + second.pop(0) From 2b8b995422e63be2dbbcb6850810df11350ee3b3 Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Fri, 16 Nov 2018 14:29:34 +0100 Subject: [PATCH 0233/1292] Refactor out unnecesary 'container' parameter (to make tests easier). [UnitTests] --- .../FirmwareUpdateChecker.py | 2 +- .../FirmwareUpdateCheckerJob.py | 16 +++++++--------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/plugins/FirmwareUpdateChecker/FirmwareUpdateChecker.py b/plugins/FirmwareUpdateChecker/FirmwareUpdateChecker.py index 415931b7ec..13b2e69b63 100644 --- a/plugins/FirmwareUpdateChecker/FirmwareUpdateChecker.py +++ b/plugins/FirmwareUpdateChecker/FirmwareUpdateChecker.py @@ -76,7 +76,7 @@ class FirmwareUpdateChecker(Extension): Logger.log("i", "No machine with name {0} in list of firmware to check.".format(container_name)) return - self._check_job = FirmwareUpdateCheckerJob(container = container, silent = silent, + self._check_job = FirmwareUpdateCheckerJob(silent = silent, machine_name = container_name, metadata = metadata, callback = self._onActionTriggered) self._check_job.start() diff --git a/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py b/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py index 4c60b95824..9192b9005c 100644 --- a/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py +++ b/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py @@ -25,9 +25,8 @@ class FirmwareUpdateCheckerJob(Job): ZERO_VERSION = Version(STRING_ZERO_VERSION) EPSILON_VERSION = Version(STRING_EPSILON_VERSION) - def __init__(self, container, silent, machine_name, metadata, callback) -> None: + def __init__(self, silent, machine_name, metadata, callback) -> None: super().__init__() - self._container = container self.silent = silent self._callback = callback @@ -83,13 +82,10 @@ class FirmwareUpdateCheckerJob(Job): application_version = Application.getInstance().getVersion() self._headers = {"User-Agent": "%s - %s" % (application_name, application_version)} - # get machine name from the definition container - machine_name = self._container.definition.getName() - # If it is not None, then we compare between the checked_version and the current_version machine_id = self._lookups.getMachineId() if machine_id is not None: - Logger.log("i", "You have a(n) {0} in the printer list. Let's check the firmware!".format(machine_name)) + Logger.log("i", "You have a(n) {0} in the printer list. Do firmware-check.".format(self._machine_name)) current_version = self.getCurrentVersion() @@ -100,18 +96,20 @@ class FirmwareUpdateCheckerJob(Job): # If the checked_version is "", it's because is the first time we check firmware and in this case # we will not show the notification, but we will store it for the next time Application.getInstance().getPreferences().setValue(setting_key_str, current_version) - Logger.log("i", "Reading firmware version of %s: checked = %s - latest = %s", machine_name, checked_version, current_version) + Logger.log("i", "Reading firmware version of %s: checked = %s - latest = %s", + self._machine_name, checked_version, current_version) # The first time we want to store the current version, the notification will not be shown, # because the new version of Cura will be release before the firmware and we don't want to # notify the user when no new firmware version is available. if (checked_version != "") and (checked_version != current_version): Logger.log("i", "SHOWING FIRMWARE UPDATE MESSAGE") - message = FirmwareUpdateCheckerMessage(machine_id, machine_name, self._lookups.getRedirectUserUrl()) + message = FirmwareUpdateCheckerMessage(machine_id, self._machine_name, + self._lookups.getRedirectUserUrl()) message.actionTriggered.connect(self._callback) message.show() else: - Logger.log("i", "No machine with name {0} in list of firmware to check.".format(machine_name)) + Logger.log("i", "No machine with name {0} in list of firmware to check.".format(self._machine_name)) except Exception as e: Logger.log("w", "Failed to check for new version: %s", e) From 421af26f87892484381d398a6cbdf05e96a26165 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Fri, 16 Nov 2018 14:54:49 +0100 Subject: [PATCH 0234/1292] Extra test on test_sendMaterialsToPrinter, removed unused code --- .../UM3NetworkPrinting/TestSendMaterialJob.py | 25 +++++-------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/tests/plugins/UM3NetworkPrinting/TestSendMaterialJob.py b/tests/plugins/UM3NetworkPrinting/TestSendMaterialJob.py index 3cdb73af22..172b42cb8b 100644 --- a/tests/plugins/UM3NetworkPrinting/TestSendMaterialJob.py +++ b/tests/plugins/UM3NetworkPrinting/TestSendMaterialJob.py @@ -212,28 +212,15 @@ class TestSendMaterialJob(TestCase): suffixes=["xml.fdm_material"])) @patch("UM.Resources.Resources.getAllResourcesOfType", lambda _: ["/materials/generic_pla_white.xml.fdm_material"]) @patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") - def test_sendMaterialsToPrinter(self, device): + def test_sendMaterialsToPrinter(self, device_mock): + device_mock._createFormPart.return_value = "_xXx_" with mock.patch.object(Logger, "log", new=new_log): - SendMaterialJob(device).sendMaterialsToPrinter({'generic_pla_white'}) + job = SendMaterialJob(device_mock) + job.sendMaterialsToPrinter({'generic_pla_white'}) self._assertLogEntries([("d", "Syncing material generic_pla_white with cluster.")], _logentries) - - @patch("PyQt5.QtNetwork.QNetworkReply") - def xtest_sendMissingMaterials(self, reply_mock): - reply_mock.attribute.return_value = 200 - reply_mock.readAll.return_value = QByteArray( - json.dumps([self._REMOTEMATERIAL_WHITE], self._REMOTEMATERIAL_BLACK).encode("ascii")) - - containerRegistry = TestContainerRegistry() - containerRegistry.setContainersMetadata([self._LOCALMATERIAL_WHITE, self._LOCALMATERIAL_BLACK]) - - with mock.patch.object(Logger, "log", new=new_log): - with mock.patch.object(ContainerRegistry, "getInstance", lambda: containerRegistry): - SendMaterialJob(None).sendMissingMaterials(reply_mock) - - reply_mock.attribute.assert_called_with(0) - self.assertEqual(reply_mock.method_calls, [call.attribute(0), call.readAll()]) - self._assertLogEntries([], _logentries) + self.assertEqual([call._createFormPart('name="file"; filename="generic_pla_white.xml.fdm_material"', ''), + call.postFormWithParts(on_finished=job.sendingFinished, parts = ["_xXx_"], target = "materials/")], device_mock.method_calls) @patch("PyQt5.QtNetwork.QNetworkReply") def test_sendingFinished_success(self, reply_mock) -> None: From 3fd1cc0e8cec4c77d080860bccd9deb99bb2d62c Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 16 Nov 2018 14:58:11 +0100 Subject: [PATCH 0235/1292] Ensure that the added labels are also themable CURA-5785 --- plugins/PreviewStage/PreviewMenu.qml | 2 ++ resources/qml/ExpandableComponent.qml | 2 +- resources/qml/MachineSelector.qml | 3 +++ .../Menus/ConfigurationMenu/QuickConfigurationSelector.qml | 4 ++++ 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index bf162be4e3..90c1cb7c99 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -74,6 +74,8 @@ Item height: parent.height elide: Text.ElideRight font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + } popupItem: Column diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index bbba44f743..c177dc758d 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -38,7 +38,7 @@ Item // Is the "drawer" open? readonly property alias expanded: popup.visible - property alias expandedHighlightColor: expandedHightlight.color + property alias expandedHighlightColor: expandedHighlight.color function togglePopup() { diff --git a/resources/qml/MachineSelector.qml b/resources/qml/MachineSelector.qml index b18f427980..1f18e1ab2a 100644 --- a/resources/qml/MachineSelector.qml +++ b/resources/qml/MachineSelector.qml @@ -32,6 +32,7 @@ Cura.ExpandableComponent height: parent.height elide: Text.ElideRight font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") } popupItem: Item @@ -58,6 +59,7 @@ Cura.ExpandableComponent visible: networkedPrintersModel.items.length > 0 height: visible ? contentHeight + 2 * UM.Theme.getSize("default_margin").height : 0 font: UM.Theme.getFont("medium_bold") + color: UM.Theme.getColor("text") verticalAlignment: Text.AlignVCenter } @@ -99,6 +101,7 @@ Cura.ExpandableComponent visible: virtualPrintersModel.items.length > 0 height: visible ? contentHeight + 2 * UM.Theme.getSize("default_margin").height : 0 font: UM.Theme.getFont("medium_bold") + color: UM.Theme.getColor("text") verticalAlignment: Text.AlignVCenter } diff --git a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml index 6f4e58a326..d6b9b1c06a 100644 --- a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml +++ b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml @@ -60,6 +60,8 @@ Cura.ExpandableComponent text: model.material_brand elide: Text.ElideRight + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") anchors { @@ -75,6 +77,8 @@ Cura.ExpandableComponent { text: model.material elide: Text.ElideRight + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") anchors { From 5972bfaf0342d41f987ec38d1cb7c00c56dab4cb Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 16 Nov 2018 15:06:21 +0100 Subject: [PATCH 0236/1292] Add round to minContentWidth This prevents text from getting a weird width CURA-5785 --- resources/qml/IconWithText.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/IconWithText.qml b/resources/qml/IconWithText.qml index 9ce2f412cc..dcb3ef7851 100644 --- a/resources/qml/IconWithText.qml +++ b/resources/qml/IconWithText.qml @@ -21,7 +21,7 @@ Item // These properties can be used in combination with layouts. readonly property real contentWidth: icon.width + margin + label.contentWidth - readonly property real minContentWidth: icon.width + margin + 0.5 * label.contentWidth + readonly property real minContentWidth: Math.round(icon.width + margin + 0.5 * label.contentWidth) Layout.minimumWidth: minContentWidth Layout.preferredWidth: contentWidth From fe15a0a5132716844afe25e2cd7dd7424667efe8 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 16 Nov 2018 15:09:47 +0100 Subject: [PATCH 0237/1292] Made width of machineSelector popup depend on size of the element CURA-5785 --- resources/qml/MachineSelector.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/MachineSelector.qml b/resources/qml/MachineSelector.qml index 256e6ec218..793f45ddcf 100644 --- a/resources/qml/MachineSelector.qml +++ b/resources/qml/MachineSelector.qml @@ -38,7 +38,7 @@ Cura.ExpandableComponent popupItem: Item { id: popup - width: 240 + width: machineSelector.width - 2 * UM.Theme.getSize("default_margin").width height: 200 ScrollView From 816d844258c2126c86f9be7b2be50580932cef4d Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 16 Nov 2018 15:14:08 +0100 Subject: [PATCH 0238/1292] Use textwidth instead of round CURA-5785 Co-Authored-By: nallath --- .../Menus/ConfigurationMenu/QuickConfigurationSelector.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml index d6b9b1c06a..b1058ce627 100644 --- a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml +++ b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml @@ -134,7 +134,7 @@ Cura.ExpandableComponent anchors.bottom: parent.bottom property var model: extrudersModel.items[tabBar.currentIndex] property real textWidth: Math.round(width * 0.3) - property real controlWidth: Math.round(width * 0.7) + property real controlWidth: width - textWidth Column { spacing: UM.Theme.getSize("default_margin").height @@ -236,4 +236,4 @@ Cura.ExpandableComponent } } -} \ No newline at end of file +} From b72f1bb31403baa2c1ee48aa473ee3bbd715c780 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 16 Nov 2018 15:15:44 +0100 Subject: [PATCH 0239/1292] Add missing screenScaleFactor for implicit sizes CURA-5785 --- resources/qml/ExpandableComponent.qml | 6 +++--- resources/qml/PrintSetupSelector.qml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index c177dc758d..d4eb18f4fa 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -6,7 +6,7 @@ import UM 1.2 as UM // The expandable component has 3 major sub components: // * The headerItem; Always visible and should hold some info about what happens if the component is expanded // * The popupItem; The content that needs to be shown if the component is expanded. -// * The Icon; An icon that is displayed on the right of the drawer. +// * The icon; An icon that is displayed on the right of the drawer. Item { id: base @@ -69,8 +69,8 @@ Item onHeightChanged: popup.height = popupItem.height + 2 * popup.padding } - implicitHeight: 100 - implicitWidth: 400 + implicitHeight: 100 * screenScaleFactor + implicitWidth: 400 * screenScaleFactor Rectangle { id: background diff --git a/resources/qml/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector.qml index e576dddc07..b843244147 100644 --- a/resources/qml/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector.qml @@ -24,7 +24,7 @@ Cura.ExpandableComponent signal showTooltip(Item item, point location, string text) signal hideTooltip() - implicitWidth: 200 + implicitWidth: 200 * screenScaleFactor height: childrenRect.height iconSource: UM.Theme.getIcon("pencil") From 42399ecb24492d2f38cc85447a6ab33a1ad28d55 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 16 Nov 2018 15:17:34 +0100 Subject: [PATCH 0240/1292] Let headerItem fill entire component if no icon is set CURA-5785 --- resources/qml/ExpandableComponent.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index d4eb18f4fa..8ed6dc5674 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -85,7 +85,7 @@ Item anchors { left: parent.left - right: collapseButton.left + right: collapseButton.visible ? collapseButton.left : parent.right top: parent.top bottom: parent.bottom margins: background.padding From 695d45ffbed22396035f0d32f616e610712a1923 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Fri, 16 Nov 2018 15:54:07 +0100 Subject: [PATCH 0241/1292] Initialize the models with None --- plugins/UM3NetworkPrinting/src/Models.py | 48 ++++++++++++------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Models.py b/plugins/UM3NetworkPrinting/src/Models.py index 6d42b39370..89bf665377 100644 --- a/plugins/UM3NetworkPrinting/src/Models.py +++ b/plugins/UM3NetworkPrinting/src/Models.py @@ -18,17 +18,17 @@ class ClusterMaterial(BaseModel): self.version = int(self.version) self.density = float(self.density) - guid: None # type: Optional[str] + guid = None # type: Optional[str] - material: None # type: Optional[str] + material = None # type: Optional[str] - brand: None # type: Optional[str] + brand = None # type: Optional[str] version = None # type: Optional[int] - color: None # type: Optional[str] + color = None # type: Optional[str] - density: None # type: Optional[float] + density = None # type: Optional[float] class LocalMaterialProperties(BaseModel): @@ -38,11 +38,11 @@ class LocalMaterialProperties(BaseModel): self.diameter = float(self.diameter) self.weight = float(self.weight) - density: None # type: Optional[float] + density = None # type: Optional[float] - diameter: None # type: Optional[float] + diameter = None # type: Optional[float] - weight: None # type: Optional[int] + weight = None # type: Optional[int] class LocalMaterial(BaseModel): @@ -52,36 +52,36 @@ class LocalMaterial(BaseModel): self.approximate_diameter = float(self.approximate_diameter) self.version = int(self.version) - GUID: None # type: Optional[str] + GUID = None # type: Optional[str] - id: None # type: Optional[str] + id = None # type: Optional[str] - type: None # type: Optional[str] + type = None # type: Optional[str] - status: None # type: Optional[str] + status = None # type: Optional[str] - base_file: None # type: Optional[str] + base_file = None # type: Optional[str] - setting_version: None # type: Optional[str] + setting_version = None # type: Optional[str] version = None # type: Optional[int] - name: None # type: Optional[str] + name = None # type: Optional[str] - brand: None # type: Optional[str] + brand = None # type: Optional[str] - material: None # type: Optional[str] + material = None # type: Optional[str] - color_name: None # type: Optional[str] + color_name = None # type: Optional[str] - description: None # type: Optional[str] + description = None # type: Optional[str] - adhesion_info: None # type: Optional[str] + adhesion_info = None # type: Optional[str] - approximate_diameter: None # type: Optional[float] + approximate_diameter = None # type: Optional[float] - properties: None # type: LocalMaterialProperties + properties = None # type: LocalMaterialProperties - definition: None # type: Optional[str] + definition = None # type: Optional[str] - compatible: None # type: Optional[bool] + compatible = None # type: Optional[bool] From 7f99ed1af36f5d0ef75f7087b1c1d84676e982b2 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 16 Nov 2018 16:04:11 +0100 Subject: [PATCH 0242/1292] ExtruderIcon will now display that it's disabled correctly CURA-5785 --- cura/Settings/ExtrudersModel.py | 5 +++-- resources/qml/ExtruderButton.qml | 1 + resources/qml/ExtruderIcon.qml | 22 +++++++++++++++---- .../QuickConfigurationSelector.qml | 2 ++ 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/cura/Settings/ExtrudersModel.py b/cura/Settings/ExtrudersModel.py index 9b85afa10e..14a8dadc69 100644 --- a/cura/Settings/ExtrudersModel.py +++ b/cura/Settings/ExtrudersModel.py @@ -24,8 +24,6 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): ## Human-readable name of the extruder. NameRole = Qt.UserRole + 2 - ## Is the extruder enabled? - EnabledRole = Qt.UserRole + 9 ## Colour of the material loaded in the extruder. ColorRole = Qt.UserRole + 3 @@ -50,6 +48,9 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): MaterialBrandRole = Qt.UserRole + 9 ColorNameRole = Qt.UserRole + 10 + ## Is the extruder enabled? + EnabledRole = Qt.UserRole + 11 + ## List of colours to display if there is no material or the material has no known # colour. defaultColors = ["#ffc924", "#86ec21", "#22eeee", "#245bff", "#9124ff", "#ff24c8"] diff --git a/resources/qml/ExtruderButton.qml b/resources/qml/ExtruderButton.qml index 764e9c94cb..8a1f0af44a 100644 --- a/resources/qml/ExtruderButton.qml +++ b/resources/qml/ExtruderButton.qml @@ -23,6 +23,7 @@ Button { width: UM.Theme.getSize("button_icon").width materialColor: model.color + extruderEnabled: extruder.stack.isEnabled property int index: extruder.index } diff --git a/resources/qml/ExtruderIcon.qml b/resources/qml/ExtruderIcon.qml index eb4bdef0f7..87e210e75a 100644 --- a/resources/qml/ExtruderIcon.qml +++ b/resources/qml/ExtruderIcon.qml @@ -13,9 +13,9 @@ Item implicitHeight: implicitWidth property bool checked: true - property alias materialColor: mainIcon.color + property color materialColor property alias textColor: extruderNumberText.color - + property bool extruderEnabled: true UM.RecolorImage { id: mainIcon @@ -24,6 +24,7 @@ Item sourceSize.width: parent.width sourceSize.height: parent.width source: UM.Theme.getIcon("extruder_button") + color: extruderEnabled ? materialColor: "gray" } Rectangle @@ -31,9 +32,9 @@ Item id: extruderNumberCircle width: height - height: parent.height / 2 + height: Math.round(parent.height / 2) radius: Math.round(width / 2) - color: "white" + color: UM.Theme.getColor("toolbar_background") anchors { @@ -51,6 +52,19 @@ Item font: UM.Theme.getFont("default") width: contentWidth height: contentHeight + visible: extruderEnabled + } + + UM.RecolorImage + { + id: disabledIcon + anchors.fill: parent + anchors.margins: UM.Theme.getSize("thick_lining").width + sourceSize.width: width + sourceSize.height: width + source: UM.Theme.getIcon("cross1") + visible: !extruderEnabled + color: "black" } } } \ No newline at end of file diff --git a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml index b1058ce627..c157b0b24f 100644 --- a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml +++ b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml @@ -49,6 +49,7 @@ Cura.ExpandableComponent { id: extruderIcon materialColor: model.color + extruderEnabled: model.enabled height: parent.height width: height } @@ -118,6 +119,7 @@ Cura.ExpandableComponent { anchors.horizontalCenter: parent.horizontalCenter materialColor: model.color + extruderEnabled: model.enabled width: parent.height height: parent.height } From 0062250238030932b15dd36511c96c4bc1e6af3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Fri, 16 Nov 2018 16:06:36 +0100 Subject: [PATCH 0243/1292] Moved the test to the plugin directory --- .../UM3NetworkPrinting/tests}/TestSendMaterialJob.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {tests/plugins/UM3NetworkPrinting => plugins/UM3NetworkPrinting/tests}/TestSendMaterialJob.py (100%) diff --git a/tests/plugins/UM3NetworkPrinting/TestSendMaterialJob.py b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py similarity index 100% rename from tests/plugins/UM3NetworkPrinting/TestSendMaterialJob.py rename to plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py From 1000625d6947fe701a25cdff5f13c2ff045e29f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Fri, 16 Nov 2018 16:07:17 +0100 Subject: [PATCH 0244/1292] Added spaces around all = --- .../UM3NetworkPrinting/src/SendMaterialJob.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py index 126ed07317..baea3b9a78 100644 --- a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py @@ -30,7 +30,7 @@ class SendMaterialJob(Job): self.device = device # type: ClusterUM3OutputDevice def run(self) -> None: - self.device.get("materials/", on_finished=self.sendMissingMaterials) + self.device.get("materials/", on_finished = self.sendMissingMaterials) def sendMissingMaterials(self, reply: QNetworkReply) -> None: if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) != 200: # Got an error from the HTTP request. @@ -77,23 +77,23 @@ class SendMaterialJob(Job): parts = [] with open(file_path, "rb") as f: parts.append( - self.device._createFormPart("name=\"file\"; filename=\"{file_name}\"".format(file_name=file_name), + self.device._createFormPart("name=\"file\"; filename=\"{file_name}\"".format(file_name = file_name), f.read())) signature_file_path = file_path + ".sig" if os.path.exists(signature_file_path): _, signature_file_name = os.path.split(signature_file_path) with open(signature_file_path, "rb") as f: parts.append(self.device._createFormPart( - "name=\"signature_file\"; filename=\"{file_name}\"".format(file_name=signature_file_name), + "name=\"signature_file\"; filename=\"{file_name}\"".format(file_name = signature_file_name), f.read())) - Logger.log("d", "Syncing material {material_id} with cluster.".format(material_id=material_id)) - self.device.postFormWithParts(target="materials/", parts=parts, on_finished=self.sendingFinished) + Logger.log("d", "Syncing material {material_id} with cluster.".format(material_id = material_id)) + self.device.postFormWithParts(target = "materials/", parts = parts, on_finished = self.sendingFinished) def sendingFinished(self, reply: QNetworkReply): if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) != 200: Logger.log("e", "Received error code from printer when syncing material: {code}".format( - code=reply.attribute(QNetworkRequest.HttpStatusCodeAttribute))) + code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute))) Logger.log("e", reply.readAll().data().decode("utf-8")) ## Parse the reply from the printer @@ -116,7 +116,7 @@ class SendMaterialJob(Job): @classmethod def _getLocalMaterials(cls): result = {} - for material in ContainerRegistry.getInstance().findContainersMetadata(type="material"): + for material in ContainerRegistry.getInstance().findContainersMetadata(type = "material"): try: localMaterial = LocalMaterial(**material) @@ -124,6 +124,6 @@ class SendMaterialJob(Job): result[localMaterial.GUID] = localMaterial except (ValueError): Logger.log("e", "Material {material_id} has invalid version number {number}.".format( - material_id=material["id"], number=material["version"])) + material_id = material["id"], number = material["version"])) return result From 52b2f4579ad1620b03b0ce3f34a44af306926008 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 16 Nov 2018 16:10:26 +0100 Subject: [PATCH 0245/1292] Fix a number of QML warnings CURA-5785 --- resources/qml/Cura.qml | 16 ---------------- resources/qml/MachineSelector.qml | 2 +- .../QuickConfigurationSelector.qml | 6 +++--- 3 files changed, 4 insertions(+), 20 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index cdbf1f3511..0312a636a6 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -214,22 +214,6 @@ UM.MainWindow } } - Loader - { - id: viewPanel - - anchors.bottom: viewModeButton.top - anchors.topMargin: UM.Theme.getSize("default_margin").height - anchors.right: viewModeButton.right - - property var buttonTarget: Qt.point(viewModeButton.x + Math.round(viewModeButton.width / 2), viewModeButton.y + Math.round(viewModeButton.height / 2)) - - height: childrenRect.height - width: childrenRect.width - - source: UM.ActiveView.valid ? UM.ActiveView.activeViewPanel : "" - } - Cura.ActionPanelWidget { anchors.right: parent.right diff --git a/resources/qml/MachineSelector.qml b/resources/qml/MachineSelector.qml index 793f45ddcf..a464949192 100644 --- a/resources/qml/MachineSelector.qml +++ b/resources/qml/MachineSelector.qml @@ -45,7 +45,7 @@ Cura.ExpandableComponent { anchors.fill: parent contentHeight: column.implicitHeight - contentWidth: row.implicitWidth + contentWidth: column.implicitWidth clip: true ScrollBar.horizontal.policy: ScrollBar.AlwaysOff diff --git a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml index c157b0b24f..33610135fe 100644 --- a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml +++ b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml @@ -111,7 +111,7 @@ Cura.ExpandableComponent delegate: TabButton { - width: Math.round(ListView.view.width / extrudersModel.rowCount()) + width: ListView.view != null ? Math.round(ListView.view.width / extrudersModel.rowCount()): 0 height: parent.height contentItem: Item { @@ -156,7 +156,7 @@ Cura.ExpandableComponent OldControls.CheckBox { - checked: Cura.MachineManager.getExtruder(tabControl.model.index).isEnabled + checked: tabControl.model != null ? Cura.MachineManager.getExtruder(tabControl.model.index).isEnabled: false onClicked: Cura.MachineManager.setExtruderEnabled(tabControl.model.index, checked) height: UM.Theme.getSize("setting_control").height style: UM.Theme.styles.checkbox @@ -190,7 +190,7 @@ Cura.ExpandableComponent tooltip: currentRootMaterialName visible: Cura.MachineManager.hasMaterials - enabled: !extrudersList.visible || Cura.ExtruderManager.activeExtruderIndex > -1 + enabled: Cura.ExtruderManager.activeExtruderIndex > -1 height: UM.Theme.getSize("setting_control").height width: tabControl.controlWidth From bc5a2ce5b0c52d36a837d52ee085a8e1cb897494 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 16 Nov 2018 16:16:15 +0100 Subject: [PATCH 0246/1292] Make ViewSelector panel close upon selecting different view CURA-5785 --- plugins/PreviewStage/PreviewMenu.qml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index 31223cfa4a..0052d341fb 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -75,7 +75,6 @@ Item elide: Text.ElideRight font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") - } popupItem: Column @@ -96,7 +95,11 @@ Item radius: UM.Theme.getSize("default_radius").width checkable: true checked: active - onClicked: UM.Controller.setActiveView(id) + onClicked: + { + viewSelector.togglePopup() + UM.Controller.setActiveView(id) + } } } From 6b55490af88e30caa1afa7419141057ebe855304 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 16 Nov 2018 16:30:47 +0100 Subject: [PATCH 0247/1292] Fix final QML warnings CURA-5785 --- plugins/PreviewStage/PreviewMenu.qml | 3 ++- plugins/SimulationView/SimulationViewMenuComponent.qml | 10 ---------- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index 0052d341fb..a3cd7cb76b 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -35,10 +35,11 @@ Item { id: stageMenu height: parent.height - width: childrenRect.width + UM.Theme.getSize("default_margin").width + width: stageMenuRow.width + UM.Theme.getSize("default_margin").width anchors.horizontalCenter: parent.horizontalCenter Row { + id: stageMenuRow anchors.centerIn: parent height: parent.height diff --git a/plugins/SimulationView/SimulationViewMenuComponent.qml b/plugins/SimulationView/SimulationViewMenuComponent.qml index 92a4e1e317..c20e141734 100644 --- a/plugins/SimulationView/SimulationViewMenuComponent.qml +++ b/plugins/SimulationView/SimulationViewMenuComponent.qml @@ -18,16 +18,6 @@ Cura.ExpandableComponent width: UM.Theme.getSize("layerview_menu_size").width iconSource: UM.Theme.getIcon("pencil") - property var buttonTarget: - { - if(parent != null) - { - var force_binding = parent.y; // ensure this gets reevaluated when the panel moves - return base.mapFromItem(parent.parent, parent.buttonTarget.x, parent.buttonTarget.y) - } - return Qt.point(0,0) - } - Connections { target: UM.Preferences From 565f009e9b6ca4b447145b38c2aa6cb3ef8d4169 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Fri, 16 Nov 2018 16:34:44 +0100 Subject: [PATCH 0248/1292] Added comments --- .../UM3NetworkPrinting/src/SendMaterialJob.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py index baea3b9a78..62b98bcdbd 100644 --- a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py @@ -1,7 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -import json # To understand the list of materials from the printer reply. +import json # To decode the list of materials from the printer reply. import os # To walk over material files. import os.path # To filter on material files. import urllib.parse # For getting material IDs from their file names. @@ -29,9 +29,13 @@ class SendMaterialJob(Job): super().__init__() self.device = device # type: ClusterUM3OutputDevice + ## Send the request to the printer and register a callback def run(self) -> None: self.device.get("materials/", on_finished = self.sendMissingMaterials) + ## Process the reply from the printer and determine which materials should be updated and sent to the printer + # + # \param reply The reply from the printer, a json file def sendMissingMaterials(self, reply: QNetworkReply) -> None: if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) != 200: # Got an error from the HTTP request. Logger.log("e", "Couldn't request current material storage on printer. Not syncing materials.") @@ -50,7 +54,7 @@ class SendMaterialJob(Job): # Collect local materials local_materials_by_guid = self._getLocalMaterials() - # Find out what materials are new or updated annd must be sent to the printer + # Find out what materials are new or updated and must be sent to the printer materials_to_send = { material.id for guid, material in local_materials_by_guid.items() @@ -61,7 +65,13 @@ class SendMaterialJob(Job): # Send materials to the printer self.sendMaterialsToPrinter(materials_to_send) - def sendMaterialsToPrinter(self, materials_to_send): + ## Send the materials to the printer + # + # The given materials will be loaded from disk en sent to to printer. The given id's will be mathed with + # filenames of the locally stored materials + # + # \param materials_to_send A set with id's of materials that must be sent + def sendMaterialsToPrinter(self, materials_to_send) -> None: for file_path in Resources.getAllResourcesOfType(CuraApplication.ResourceTypes.MaterialInstanceContainer): try: mime_type = MimeTypeDatabase.getMimeTypeForFile(file_path) @@ -90,7 +100,8 @@ class SendMaterialJob(Job): Logger.log("d", "Syncing material {material_id} with cluster.".format(material_id = material_id)) self.device.postFormWithParts(target = "materials/", parts = parts, on_finished = self.sendingFinished) - def sendingFinished(self, reply: QNetworkReply): + ## Check a reply from an upload to the printer and log an error when the call failed + def sendingFinished(self, reply: QNetworkReply) -> None: if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) != 200: Logger.log("e", "Received error code from printer when syncing material: {code}".format( code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute))) From 22aac7b5665e6dbcda2107be8e0831b11e8d28b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Fri, 16 Nov 2018 16:35:08 +0100 Subject: [PATCH 0249/1292] Renamed TestContainerRegistry to ContainerRegistryMock --- .../UM3NetworkPrinting/tests/TestSendMaterialJob.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py index 172b42cb8b..03d2a81e89 100644 --- a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py @@ -26,7 +26,7 @@ def new_log(*args): _logentries.append(args) -class TestContainerRegistry(ContainerRegistryInterface): +class ContainerRegistryMock(ContainerRegistryInterface): def __init__(self): self.containersMetaData = None @@ -156,7 +156,7 @@ class TestSendMaterialJob(TestCase): reply_mock.attribute.return_value = 200 reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTEMATERIAL_WHITE]).encode("ascii")) - containerRegistry = TestContainerRegistry() + containerRegistry = ContainerRegistryMock() localMaterialWhiteWithInvalidVersion = self._LOCALMATERIAL_WHITE.copy() localMaterialWhiteWithInvalidVersion["version"] = "one" containerRegistry.setContainersMetadata([localMaterialWhiteWithInvalidVersion]) @@ -175,7 +175,7 @@ class TestSendMaterialJob(TestCase): reply_mock.attribute.return_value = 200 reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTEMATERIAL_WHITE]).encode("ascii")) - containerRegistry = TestContainerRegistry() + containerRegistry = ContainerRegistryMock() localMaterialWhiteWithHigherVersion = self._LOCALMATERIAL_WHITE.copy() localMaterialWhiteWithHigherVersion["version"] = "2" containerRegistry.setContainersMetadata([self._LOCALMATERIAL_WHITE, localMaterialWhiteWithHigherVersion]) @@ -195,7 +195,7 @@ class TestSendMaterialJob(TestCase): reply_mock.readAll.return_value = QByteArray( json.dumps([self._REMOTEMATERIAL_WHITE]).encode("ascii")) - containerRegistry = TestContainerRegistry() + containerRegistry = ContainerRegistryMock() containerRegistry.setContainersMetadata([self._LOCALMATERIAL_WHITE, self._LOCALMATERIAL_BLACK]) with mock.patch.object(Logger, "log", new=new_log): @@ -266,7 +266,7 @@ class TestSendMaterialJob(TestCase): SendMaterialJob._parseReply(reply_mock) def test__getLocalMaterials(self): - containerRegistry = TestContainerRegistry() + containerRegistry = ContainerRegistryMock() containerRegistry.setContainersMetadata([self._LOCALMATERIAL_WHITE, self._LOCALMATERIAL_BLACK]) with mock.patch.object(Logger, "log", new=new_log): @@ -276,7 +276,7 @@ class TestSendMaterialJob(TestCase): self.assertTrue(len(local_materials) == 2) def test__getLocalMaterialsWithMultipleVersions(self): - containerRegistry = TestContainerRegistry() + containerRegistry = ContainerRegistryMock() localMaterialWithNewerVersion = self._LOCALMATERIAL_WHITE.copy() localMaterialWithNewerVersion["version"] = 2 containerRegistry.setContainersMetadata([self._LOCALMATERIAL_WHITE, localMaterialWithNewerVersion]) From 3dd355976b5fad44929ce7446fbe2cea1204d7db Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Fri, 16 Nov 2018 16:41:09 +0100 Subject: [PATCH 0250/1292] Write tests for the FirmwareUpdateChecker-plugin. [UnitTests] --- .../tests/TestFirmwareUpdateChecker.py | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 plugins/FirmwareUpdateChecker/tests/TestFirmwareUpdateChecker.py diff --git a/plugins/FirmwareUpdateChecker/tests/TestFirmwareUpdateChecker.py b/plugins/FirmwareUpdateChecker/tests/TestFirmwareUpdateChecker.py new file mode 100644 index 0000000000..7ccb2fdf6a --- /dev/null +++ b/plugins/FirmwareUpdateChecker/tests/TestFirmwareUpdateChecker.py @@ -0,0 +1,70 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +import pytest +import json + +import unittest.mock +from cura.CuraApplication import CuraApplication + +from UM.Version import Version + +from plugins.FirmwareUpdateChecker.FirmwareUpdateCheckerJob import FirmwareUpdateCheckerJob +from plugins.FirmwareUpdateChecker.FirmwareUpdateCheckerLookup import FirmwareUpdateCheckerLookup + +json_data = \ + { + "ned": + { + "id": 1, + "name": "ned", + "check_urls": ["http://urlecho.appspot.com/echo?status=200&body=5.1.2.3"], + "update_url": "https://ultimaker.com/en/resources/20500-upgrade-firmware", + "version_parser": "default" + }, + "olivia": + { + "id": 3, + "name": "olivia", + "check_urls": ["http://urlecho.appspot.com/echo?status=200&body=4.3.2.1", "https://this-url-clearly-doesnt-exist.net"], + "update_url": "https://ultimaker.com/en/resources/20500-upgrade-firmware", + "version_parser": "default" + }, + "emmerson": + { + "id": 5, + "name": "emmerson", + "check_urls": ["http://urlecho.appspot.com/echo?status=200&body=0.2.2.2", "http://urlecho.appspot.com/echo?status=200&body=6.7.8.1"], + "update_url": "https://ultimaker.com/en/resources/20500-upgrade-firmware", + "version_parser": "default" + } + } + +def dummyCallback(): + pass + +@pytest.mark.parametrize("name, id", [ + ("ned" , 1), + ("olivia" , 3), + ("emmerson", 5), +]) +def test_FirmwareUpdateCheckerLookup(id, name): + lookup = FirmwareUpdateCheckerLookup(name, json_data.get(name)) + + assert lookup.getMachineName() == name + assert lookup.getMachineId() == id + assert len(lookup.getCheckUrls()) >= 1 + assert lookup.getRedirectUserUrl() is not None + +@pytest.mark.parametrize("name, version", [ + ("ned" , Version("5.1.2.3")), + ("olivia" , Version("4.3.2.1")), + ("emmerson", Version("6.7.8.1")), +]) +def test_FirmwareUpdateCheckerJob_getCurrentVersion(name, version): + machine_data = json_data.get(name) + job = FirmwareUpdateCheckerJob(False, name, machine_data, dummyCallback) + job._lookups = FirmwareUpdateCheckerLookup(name, machine_data) + job._headers = {"User-Agent": "Cura-UnitTests 0"} + + assert job.getCurrentVersion() == version From 69e2fa396e5e227751cf30c74df76e3a4fc3f188 Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Fri, 16 Nov 2018 16:53:37 +0100 Subject: [PATCH 0251/1292] Refactor out unnecesary late init (to make tests cleaner). [UnitTests] --- plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py | 5 +---- .../FirmwareUpdateChecker/tests/TestFirmwareUpdateChecker.py | 1 - 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py b/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py index 9192b9005c..b37de81f34 100644 --- a/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py +++ b/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py @@ -32,7 +32,7 @@ class FirmwareUpdateCheckerJob(Job): self._machine_name = machine_name self._metadata = metadata - self._lookups = None # type:Optional[FirmwareUpdateCheckerLookup] + self._lookups = FirmwareUpdateCheckerLookup(self._machine_name, self._metadata) self._headers = {} # type:Dict[str, str] # Don't set headers yet. def getUrlResponse(self, url: str) -> str: @@ -69,9 +69,6 @@ class FirmwareUpdateCheckerJob(Job): return max_version def run(self): - if self._lookups is None: - self._lookups = FirmwareUpdateCheckerLookup(self._machine_name, self._metadata) - try: # Initialize a Preference that stores the last version checked for this printer. Application.getInstance().getPreferences().addPreference( diff --git a/plugins/FirmwareUpdateChecker/tests/TestFirmwareUpdateChecker.py b/plugins/FirmwareUpdateChecker/tests/TestFirmwareUpdateChecker.py index 7ccb2fdf6a..21d15922a2 100644 --- a/plugins/FirmwareUpdateChecker/tests/TestFirmwareUpdateChecker.py +++ b/plugins/FirmwareUpdateChecker/tests/TestFirmwareUpdateChecker.py @@ -64,7 +64,6 @@ def test_FirmwareUpdateCheckerLookup(id, name): def test_FirmwareUpdateCheckerJob_getCurrentVersion(name, version): machine_data = json_data.get(name) job = FirmwareUpdateCheckerJob(False, name, machine_data, dummyCallback) - job._lookups = FirmwareUpdateCheckerLookup(name, machine_data) job._headers = {"User-Agent": "Cura-UnitTests 0"} assert job.getCurrentVersion() == version From f10bd28c4ae8084f9b8f8f343b3b8471a764a2a4 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 16 Nov 2018 17:25:32 +0100 Subject: [PATCH 0252/1292] Improve grammar and do similar fix for extruder end g-code Contributes to issue CURA-5906. --- resources/definitions/fdmextruder.def.json | 4 ++-- resources/definitions/fdmprinter.def.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/definitions/fdmextruder.def.json b/resources/definitions/fdmextruder.def.json index 55556f5764..cb49b1e128 100644 --- a/resources/definitions/fdmextruder.def.json +++ b/resources/definitions/fdmextruder.def.json @@ -78,7 +78,7 @@ "machine_extruder_start_code": { "label": "Extruder Start G-Code", - "description": "Start g-code to execute whenever this extruder is switched to.", + "description": "Start g-code to execute when switching to this extruder.", "type": "str", "default_value": "", "settable_per_mesh": false, @@ -124,7 +124,7 @@ "machine_extruder_end_code": { "label": "Extruder End G-Code", - "description": "End g-code to execute whenever turning the extruder off.", + "description": "End g-code to execute when switching away from this extruder.", "type": "str", "default_value": "", "settable_per_mesh": false, diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index b1812ae705..c015ab8ccb 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -2406,7 +2406,7 @@ "switch_extruder_retraction_amount": { "label": "Nozzle Switch Retraction Distance", - "description": "The amount of retraction when switching extruder. Set to 0 for no retraction at all. This should generally be the same as the length of the heat zone.", + "description": "The amount of retraction when switching extruders. Set to 0 for no retraction at all. This should generally be the same as the length of the heat zone.", "type": "float", "unit": "mm", "enabled": "retraction_enable", From e3ebf89092333942ce6ae542c46b570d1ea22593 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 16 Nov 2018 17:26:10 +0100 Subject: [PATCH 0253/1292] Ensure that width of popup does not get set to 0 CURA-5785 --- plugins/PreviewStage/PreviewMenu.qml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index a3cd7cb76b..b73c1088ae 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -83,8 +83,12 @@ Item id: viewSelectorPopup width: viewSelector.width - 2 * UM.Theme.getSize("default_margin").width - // For some reason the height of the column gets set to 0 if this is not set... - Component.onCompleted: height = implicitHeight + // For some reason the height/width of the column gets set to 0 if this is not set... + Component.onCompleted: + { + height = implicitHeight + width = viewSelector.width - 2 * UM.Theme.getSize("default_margin").width + } Repeater { From 6fe89e3d54980d403b2b42f9ace88ed813345028 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 19 Nov 2018 10:33:19 +0100 Subject: [PATCH 0254/1292] Fix width of simulationView component not being set correctly CURA-5785 --- plugins/SimulationView/SimulationViewMenuComponent.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/SimulationView/SimulationViewMenuComponent.qml b/plugins/SimulationView/SimulationViewMenuComponent.qml index c20e141734..89615f43a4 100644 --- a/plugins/SimulationView/SimulationViewMenuComponent.qml +++ b/plugins/SimulationView/SimulationViewMenuComponent.qml @@ -64,7 +64,7 @@ Cura.ExpandableComponent property bool only_show_top_layers: UM.Preferences.getValue("view/only_show_top_layers") property int top_layer_count: UM.Preferences.getValue("view/top_layer_count") - width: base.width - 2 * UM.Theme.getSize("default_margin").width + width: UM.Theme.getSize("layerview_menu_size").width - 2 * UM.Theme.getSize("default_margin").width height: childrenRect.height spacing: UM.Theme.getSize("layerview_row_spacing").height From 23e957e1c5c8fdbb36368f319feb57218dd7ab92 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 19 Nov 2018 10:44:24 +0100 Subject: [PATCH 0255/1292] Some more refactoring, splitting up methods --- .../NetworkedPrinterOutputDevice.py | 3 + .../UM3NetworkPrinting/src/SendMaterialJob.py | 180 +++++++++++------- 2 files changed, 115 insertions(+), 68 deletions(-) diff --git a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py index 35d2ce014a..9a3be936a2 100644 --- a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py +++ b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py @@ -147,6 +147,9 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): request.setHeader(QNetworkRequest.UserAgentHeader, self._user_agent) return request + def createFormPart(self, content_header: str, data: bytes, content_type: Optional[str] = None) -> QHttpPart: + return self._createFormPart(content_header, data, content_type) + def _createFormPart(self, content_header: str, data: bytes, content_type: Optional[str] = None) -> QHttpPart: part = QHttpPart() diff --git a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py index 62b98bcdbd..6763901151 100644 --- a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py @@ -1,21 +1,20 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +import json +import os +import urllib.parse +from typing import Dict, TYPE_CHECKING, Set -import json # To decode the list of materials from the printer reply. -import os # To walk over material files. -import os.path # To filter on material files. -import urllib.parse # For getting material IDs from their file names. -from typing import Dict, TYPE_CHECKING +from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest -from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest # To listen to the reply from the printer. - -from UM.Job import Job # The interface we're implementing. +from UM.Job import Job from UM.Logger import Logger -from UM.MimeTypeDatabase import MimeTypeDatabase # To strip the extensions of the material profile files. +from UM.MimeTypeDatabase import MimeTypeDatabase from UM.Resources import Resources -from UM.Settings.ContainerRegistry import ContainerRegistry # To find the GUIDs of materials. -from cura.CuraApplication import CuraApplication # For the resource types. -from plugins.UM3NetworkPrinting.src.Models import ClusterMaterial, LocalMaterial +from cura.CuraApplication import CuraApplication + +# Absolute imports don't work in plugins +from .Models import ClusterMaterial, LocalMaterial if TYPE_CHECKING: from .ClusterUM3OutputDevice import ClusterUM3OutputDevice @@ -25,95 +24,136 @@ if TYPE_CHECKING: # # This way it won't freeze up the interface while sending those materials. class SendMaterialJob(Job): + def __init__(self, device: "ClusterUM3OutputDevice") -> None: super().__init__() self.device = device # type: ClusterUM3OutputDevice + self._application = CuraApplication.getInstance() # type: CuraApplication ## Send the request to the printer and register a callback def run(self) -> None: self.device.get("materials/", on_finished = self.sendMissingMaterials) - ## Process the reply from the printer and determine which materials should be updated and sent to the printer + ## Process the materials reply from the printer. # - # \param reply The reply from the printer, a json file - def sendMissingMaterials(self, reply: QNetworkReply) -> None: - if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) != 200: # Got an error from the HTTP request. - Logger.log("e", "Couldn't request current material storage on printer. Not syncing materials.") + # \param reply The reply from the printer, a json file. + def _onGetRemoteMaterials(self, reply: QNetworkReply) -> None: + + # Got an error from the HTTP request. If we did not receive a 200 something happened. + if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) != 200: + Logger.log("e", "Error fetching materials from printer: %s", reply.errorString()) return - # Collect materials from the printer's reply + # Collect materials from the printer's reply and send the missing ones if needed. try: remote_materials_by_guid = self._parseReply(reply) - except json.JSONDecodeError: - Logger.log("e", "Request material storage on printer: I didn't understand the printer's answer.") - return - except KeyError: - Logger.log("e", "Request material storage on printer: Printer's answer was missing GUIDs.") - return + self._sendMissingMaterials(remote_materials_by_guid) + except json.JSONDecodeError as e: + Logger.log("e", "Error parsing materials from printer: %s", e) + except KeyError as e: + Logger.log("e", "Error parsing materials from printer: %s", e) + + ## Determine which materials should be updated and send them to the printer. + # + # \param remote_materials_by_guid The remote materials by GUID. + def _sendMissingMaterials(self, remote_materials_by_guid: Dict[str, ClusterMaterial]) -> None: # Collect local materials local_materials_by_guid = self._getLocalMaterials() + if len(local_materials_by_guid) == 0: + Logger.log("d", "There are no local materials to synchronize with the printer.") + return # Find out what materials are new or updated and must be sent to the printer - materials_to_send = { - material.id - for guid, material in local_materials_by_guid.items() - if guid not in remote_materials_by_guid or - material.version > remote_materials_by_guid[guid].version - } + material_ids_to_send = self._determineMaterialsToSend(local_materials_by_guid, remote_materials_by_guid) + if len(material_ids_to_send) == 0: + Logger.log("d", "There are no remote materials to update.") + return # Send materials to the printer - self.sendMaterialsToPrinter(materials_to_send) + self._sendMaterials(material_ids_to_send) - ## Send the materials to the printer + ## From the local and remote materials, determine which ones should be synchronized. # - # The given materials will be loaded from disk en sent to to printer. The given id's will be mathed with - # filenames of the locally stored materials + # Makes a Set containing only the materials that are not on the printer yet or the ones that are newer in Cura. # - # \param materials_to_send A set with id's of materials that must be sent - def sendMaterialsToPrinter(self, materials_to_send) -> None: - for file_path in Resources.getAllResourcesOfType(CuraApplication.ResourceTypes.MaterialInstanceContainer): + # \param local_materials The local materials by GUID. + # \param remote_materials The remote materials by GUID. + @staticmethod + def _determineMaterialsToSend(local_materials: Dict[str, LocalMaterial], + remote_materials: Dict[str, ClusterMaterial]) -> Set[str]: + return { + material.id for guid, material in local_materials.items() + if guid not in remote_materials or material.version > remote_materials[guid].version + } + + ## Send the materials to the printer. + # + # The given materials will be loaded from disk en sent to to printer. + # The given id's will be matched with filenames of the locally stored materials. + # + # \param materials_to_send A set with id's of materials that must be sent. + def _sendMaterials(self, materials_to_send: Set[str]) -> None: + file_paths = Resources.getAllResourcesOfType(CuraApplication.ResourceTypes.MaterialInstanceContainer) + + # Find all local material files and send them if needed. + for file_path in file_paths: try: mime_type = MimeTypeDatabase.getMimeTypeForFile(file_path) except MimeTypeDatabase.MimeTypeNotFoundError: - continue # Not the sort of file we'd like to send then. - - _, file_name = os.path.split(file_path) - material_id = urllib.parse.unquote_plus(mime_type.stripExtension(file_name)) - - if material_id not in materials_to_send: continue + file_name = os.path.basename(file_path) + material_id = urllib.parse.unquote_plus(mime_type.stripExtension(file_name)) + if material_id not in materials_to_send: + # If the material does not have to be sent we skip it. + continue + + self._sendMaterialFile(file_path, file_name, material_id) + + ## Send a single material file to the printer. + # + # Also add the material signature file if that is available. + # + # \param file_path The path of the material file. + # \param file_name The name of the material file. + # \param material_id The ID of the material in the file. + def _sendMaterialFile(self, file_path: str, file_name: str, material_id: str) -> None: + parts = [] + + # Add the material file. with open(file_path, "rb") as f: - parts.append( - self.device._createFormPart("name=\"file\"; filename=\"{file_name}\"".format(file_name = file_name), - f.read())) - signature_file_path = file_path + ".sig" + parts.append(self.device.createFormPart("name=\"file\"; filename=\"{file_name}\"" + .format(file_name = file_name), f.read())) + + # Add the material signature file if needed. + signature_file_path = "{}.sig".format(file_path) if os.path.exists(signature_file_path): - _, signature_file_name = os.path.split(signature_file_path) + signature_file_name = os.path.basename(signature_file_path) with open(signature_file_path, "rb") as f: - parts.append(self.device._createFormPart( - "name=\"signature_file\"; filename=\"{file_name}\"".format(file_name = signature_file_name), - f.read())) + parts.append(self.device.createFormPart("name=\"signature_file\"; filename=\"{file_name}\"" + .format(file_name = signature_file_name), f.read())) Logger.log("d", "Syncing material {material_id} with cluster.".format(material_id = material_id)) self.device.postFormWithParts(target = "materials/", parts = parts, on_finished = self.sendingFinished) ## Check a reply from an upload to the printer and log an error when the call failed - def sendingFinished(self, reply: QNetworkReply) -> None: + @staticmethod + def sendingFinished(reply: QNetworkReply) -> None: if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) != 200: - Logger.log("e", "Received error code from printer when syncing material: {code}".format( - code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute))) - Logger.log("e", reply.readAll().data().decode("utf-8")) + Logger.log("e", "Received error code from printer when syncing material: {code}, {text}".format( + code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute), + text = reply.errorString() + )) ## Parse the reply from the printer # # Parses the reply to a "/materials" request to the printer # - # \return a dictionary of ClustMaterial objects by GUID + # \return a dictionary of ClusterMaterial objects by GUID # \throw json.JSONDecodeError Raised when the reply does not contain a valid json string - # \throw KeyErrror Raised when on of the materials does not include a valid guid + # \throw KeyError Raised when on of the materials does not include a valid guid @classmethod def _parseReply(cls, reply: QNetworkReply) -> Dict[str, ClusterMaterial]: remote_materials_list = json.loads(reply.readAll().data().decode("utf-8")) @@ -124,17 +164,21 @@ class SendMaterialJob(Job): # Only the new newest version of the local materials is returned # # \return a dictionary of LocalMaterial objects by GUID - @classmethod - def _getLocalMaterials(cls): - result = {} - for material in ContainerRegistry.getInstance().findContainersMetadata(type = "material"): - try: - localMaterial = LocalMaterial(**material) + def _getLocalMaterials(self) -> Dict[str, LocalMaterial]: + result = {} # type: Dict[str, LocalMaterial] + container_registry = self._application.getContainerRegistry() + material_containers = container_registry.findContainersMetadata(type = "material") - if localMaterial.GUID not in result or localMaterial.version > result.get(localMaterial.GUID).version: - result[localMaterial.GUID] = localMaterial - except (ValueError): - Logger.log("e", "Material {material_id} has invalid version number {number}.".format( - material_id = material["id"], number = material["version"])) + # Find the latest version of all material containers in the registry. + for m in material_containers: + try: + material = LocalMaterial(**m) + if material.GUID not in result or material.version > result.get(material.GUID).version: + result[material.GUID] = material + except ValueError as e: + Logger.log("w", "Local material {material_id} has invalid values: {e}".format( + material_id = m["id"], + e = e + )) return result From ee9210d8d1ce895d22636c74d8bf3218f39460f2 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 19 Nov 2018 10:57:47 +0100 Subject: [PATCH 0256/1292] Rewrite tests --- .../UM3NetworkPrinting/src/SendMaterialJob.py | 2 +- .../tests/TestSendMaterialJob.py | 417 +++++++++--------- 2 files changed, 198 insertions(+), 221 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py index 6763901151..349e6929ff 100644 --- a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py @@ -32,7 +32,7 @@ class SendMaterialJob(Job): ## Send the request to the printer and register a callback def run(self) -> None: - self.device.get("materials/", on_finished = self.sendMissingMaterials) + self.device.get("materials/", on_finished = self._onGetRemoteMaterials) ## Process the materials reply from the printer. # diff --git a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py index 03d2a81e89..bc6e1def14 100644 --- a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py @@ -1,6 +1,5 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. - import io import json from typing import Any, List @@ -17,16 +16,9 @@ from plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice import ClusterUM3Outp from plugins.UM3NetworkPrinting.src.Models import ClusterMaterial from plugins.UM3NetworkPrinting.src.SendMaterialJob import SendMaterialJob -# All log entries written to Log.log by the class-under-test are written to this list. It is cleared before each test -# run and check afterwards -_logentries = [] - - -def new_log(*args): - _logentries.append(args) - class ContainerRegistryMock(ContainerRegistryInterface): + def __init__(self): self.containersMetaData = None @@ -59,14 +51,16 @@ class FakeDevice(ClusterUM3OutputDevice): class TestSendMaterialJob(TestCase): - _LOCALMATERIAL_WHITE = {'type': 'material', 'status': 'unknown', 'id': 'generic_pla_white', + + _LOCAL_MATERIAL_WHITE = {'type': 'material', 'status': 'unknown', 'id': 'generic_pla_white', 'base_file': 'generic_pla_white', 'setting_version': 5, 'name': 'White PLA', 'brand': 'Generic', 'material': 'PLA', 'color_name': 'White', 'GUID': 'badb0ee7-87c8-4f3f-9398-938587b67dce', 'version': '1', 'color_code': '#ffffff', 'description': 'Test PLA White', 'adhesion_info': 'Use glue.', 'approximate_diameter': '3', 'properties': {'density': '1.00', 'diameter': '2.85', 'weight': '750'}, 'definition': 'fdmprinter', 'compatible': True} - _LOCALMATERIAL_BLACK = {'type': 'material', 'status': 'unknown', 'id': 'generic_pla_black', + + _LOCAL_MATERIAL_BLACK = {'type': 'material', 'status': 'unknown', 'id': 'generic_pla_black', 'base_file': 'generic_pla_black', 'setting_version': 5, 'name': 'Yellow CPE', 'brand': 'Ultimaker', 'material': 'CPE', 'color_name': 'Black', 'GUID': '5fbb362a-41f9-4818-bb43-15ea6df34aa4', 'version': '1', 'color_code': '#000000', @@ -74,7 +68,7 @@ class TestSendMaterialJob(TestCase): 'properties': {'density': '1.01', 'diameter': '2.85', 'weight': '750'}, 'definition': 'fdmprinter', 'compatible': True} - _REMOTEMATERIAL_WHITE = { + _REMOTE_MATERIAL_WHITE = { "guid": "badb0ee7-87c8-4f3f-9398-938587b67dce", "material": "PLA", "brand": "Generic", @@ -82,7 +76,8 @@ class TestSendMaterialJob(TestCase): "color": "White", "density": 1.00 } - _REMOTEMATERIAL_BLACK = { + + _REMOTE_MATERIAL_BLACK = { "guid": "5fbb362a-41f9-4818-bb43-15ea6df34aa4", "material": "PLA", "brand": "Generic", @@ -91,224 +86,206 @@ class TestSendMaterialJob(TestCase): "density": 1.00 } - def setUp(self): - # Make sure the we start with clean (log) slate - _logentries.clear() - - def tearDown(self): - # If there are still log entries that were not checked something is wrong or we must add checks for them - self.assertEqual(len(_logentries), 0) - @patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") def test_run(self, device_mock): - with mock.patch.object(Logger, 'log', new=new_log): - job = SendMaterialJob(device_mock) - job.run() - - device_mock.get.assert_called_with("materials/", on_finished=job.sendMissingMaterials) - self.assertEqual(0, len(_logentries)) + job = SendMaterialJob(device_mock) + job.run() + device_mock.get.assert_called_with("materials/", on_finished=job._onGetRemoteMaterials) + @patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") @patch("PyQt5.QtNetwork.QNetworkReply") - def test_sendMissingMaterials_withFailedRequest(self, reply_mock): + def test_sendMissingMaterials_withFailedRequest(self, reply_mock, device_mock): reply_mock.attribute.return_value = 404 - - with mock.patch.object(Logger, 'log', new=new_log): - SendMaterialJob(None).sendMissingMaterials(reply_mock) - + SendMaterialJob(device_mock).run() reply_mock.attribute.assert_called_with(0) self.assertEqual(reply_mock.method_calls, [call.attribute(0)]) - self._assertLogEntries([('e', "Couldn't request current material storage on printer. Not syncing materials.")], - _logentries) + self.assertEqual(device_mock._onGetRemoteMaterials.method_calls, []) - @patch("PyQt5.QtNetwork.QNetworkReply") - def test_sendMissingMaterials_withBadJsonAnswer(self, reply_mock): - reply_mock.attribute.return_value = 200 - reply_mock.readAll.return_value = QByteArray(b'Six sick hicks nick six slick bricks with picks and sticks.') - - with mock.patch.object(Logger, 'log', new=new_log): - SendMaterialJob(None).sendMissingMaterials(reply_mock) - - reply_mock.attribute.assert_called_with(0) - self.assertEqual(reply_mock.method_calls, [call.attribute(0), call.readAll()]) - self._assertLogEntries( - [('e', "Request material storage on printer: I didn't understand the printer's answer.")], - _logentries) - - @patch("PyQt5.QtNetwork.QNetworkReply") - def test_sendMissingMaterials_withMissingGuid(self, reply_mock): - reply_mock.attribute.return_value = 200 - remoteMaterialWithoutGuid = self._REMOTEMATERIAL_WHITE.copy() - del remoteMaterialWithoutGuid["guid"] - reply_mock.readAll.return_value = QByteArray(json.dumps([remoteMaterialWithoutGuid]).encode("ascii")) - - with mock.patch.object(Logger, 'log', new=new_log): - SendMaterialJob(None).sendMissingMaterials(reply_mock) - - reply_mock.attribute.assert_called_with(0) - self.assertEqual(reply_mock.method_calls, [call.attribute(0), call.readAll()]) - self._assertLogEntries( - [('e', "Request material storage on printer: Printer's answer was missing GUIDs.")], - _logentries) - - @patch("UM.Resources.Resources.getAllResourcesOfType", lambda _: []) - @patch("PyQt5.QtNetwork.QNetworkReply") - def test_sendMissingMaterials_WithInvalidVersionInLocalMaterial(self, reply_mock): - reply_mock.attribute.return_value = 200 - reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTEMATERIAL_WHITE]).encode("ascii")) - - containerRegistry = ContainerRegistryMock() - localMaterialWhiteWithInvalidVersion = self._LOCALMATERIAL_WHITE.copy() - localMaterialWhiteWithInvalidVersion["version"] = "one" - containerRegistry.setContainersMetadata([localMaterialWhiteWithInvalidVersion]) - - with mock.patch.object(Logger, "log", new=new_log): - with mock.patch.object(ContainerRegistry, "getInstance", lambda: containerRegistry): - SendMaterialJob(None).sendMissingMaterials(reply_mock) - - reply_mock.attribute.assert_called_with(0) - self.assertEqual(reply_mock.method_calls, [call.attribute(0), call.readAll()]) - self._assertLogEntries([('e', "Material generic_pla_white has invalid version number one.")], _logentries) - - @patch("UM.Resources.Resources.getAllResourcesOfType", lambda _: []) - @patch("PyQt5.QtNetwork.QNetworkReply") - def test_sendMissingMaterials_WithMultipleLocalVersionsLowFirst(self, reply_mock): - reply_mock.attribute.return_value = 200 - reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTEMATERIAL_WHITE]).encode("ascii")) - - containerRegistry = ContainerRegistryMock() - localMaterialWhiteWithHigherVersion = self._LOCALMATERIAL_WHITE.copy() - localMaterialWhiteWithHigherVersion["version"] = "2" - containerRegistry.setContainersMetadata([self._LOCALMATERIAL_WHITE, localMaterialWhiteWithHigherVersion]) - - with mock.patch.object(Logger, "log", new=new_log): - with mock.patch.object(ContainerRegistry, "getInstance", lambda: containerRegistry): - SendMaterialJob(None).sendMissingMaterials(reply_mock) - - reply_mock.attribute.assert_called_with(0) - self.assertEqual(reply_mock.method_calls, [call.attribute(0), call.readAll()]) - self._assertLogEntries([], _logentries) - - @patch("UM.Resources.Resources.getAllResourcesOfType", lambda _: []) - @patch("PyQt5.QtNetwork.QNetworkReply") - def test_sendMissingMaterials_MaterialMissingOnPrinter(self, reply_mock): - reply_mock.attribute.return_value = 200 - reply_mock.readAll.return_value = QByteArray( - json.dumps([self._REMOTEMATERIAL_WHITE]).encode("ascii")) - - containerRegistry = ContainerRegistryMock() - containerRegistry.setContainersMetadata([self._LOCALMATERIAL_WHITE, self._LOCALMATERIAL_BLACK]) - - with mock.patch.object(Logger, "log", new=new_log): - with mock.patch.object(ContainerRegistry, "getInstance", lambda: containerRegistry): - SendMaterialJob(None).sendMissingMaterials(reply_mock) - - reply_mock.attribute.assert_called_with(0) - self.assertEqual(reply_mock.method_calls, [call.attribute(0), call.readAll()]) - self._assertLogEntries([], _logentries) - - @patch("builtins.open", lambda a, b: io.StringIO("")) - @patch("UM.MimeTypeDatabase.MimeTypeDatabase.getMimeTypeForFile", - lambda _: MimeType(name="application/x-ultimaker-material-profile", comment="Ultimaker Material Profile", - suffixes=["xml.fdm_material"])) - @patch("UM.Resources.Resources.getAllResourcesOfType", lambda _: ["/materials/generic_pla_white.xml.fdm_material"]) @patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") - def test_sendMaterialsToPrinter(self, device_mock): - device_mock._createFormPart.return_value = "_xXx_" - with mock.patch.object(Logger, "log", new=new_log): - job = SendMaterialJob(device_mock) - job.sendMaterialsToPrinter({'generic_pla_white'}) - - self._assertLogEntries([("d", "Syncing material generic_pla_white with cluster.")], _logentries) - self.assertEqual([call._createFormPart('name="file"; filename="generic_pla_white.xml.fdm_material"', ''), - call.postFormWithParts(on_finished=job.sendingFinished, parts = ["_xXx_"], target = "materials/")], device_mock.method_calls) - @patch("PyQt5.QtNetwork.QNetworkReply") - def test_sendingFinished_success(self, reply_mock) -> None: + def test_sendMissingMaterials_withBadJsonAnswer(self, reply_mock, device_mock): reply_mock.attribute.return_value = 200 - with mock.patch.object(Logger, 'log', new=new_log): - SendMaterialJob(None).sendingFinished(reply_mock) - - reply_mock.attribute.assert_called_once_with(0) - self.assertEqual(0, len(_logentries)) - - @patch("PyQt5.QtNetwork.QNetworkReply") - def test_sendingFinished_failed(self, reply_mock) -> None: - reply_mock.attribute.return_value = 404 reply_mock.readAll.return_value = QByteArray(b'Six sick hicks nick six slick bricks with picks and sticks.') - - with mock.patch.object(Logger, 'log', new=new_log): - SendMaterialJob(None).sendingFinished(reply_mock) - + SendMaterialJob(device_mock).run() reply_mock.attribute.assert_called_with(0) - self.assertEqual(reply_mock.method_calls, [call.attribute(0), call.attribute(0), call.readAll()]) + self.assertEqual(reply_mock.method_calls, [call.attribute(0), call.readAll()]) + self.assertEqual(device_mock._onGetRemoteMaterials.method_calls, []) - self._assertLogEntries([ - ("e", "Received error code from printer when syncing material: 404"), - ("e", "Six sick hicks nick six slick bricks with picks and sticks.") - ], _logentries) - - @patch("PyQt5.QtNetwork.QNetworkReply") - def test_parseReply(self, reply_mock): - reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTEMATERIAL_WHITE]).encode("ascii")) - - response = SendMaterialJob._parseReply(reply_mock) - - self.assertTrue(len(response) == 1) - self.assertEqual(next(iter(response.values())), ClusterMaterial(**self._REMOTEMATERIAL_WHITE)) - - @patch("PyQt5.QtNetwork.QNetworkReply") - def test_parseReplyWithInvalidMaterial(self, reply_mock): - remoteMaterialWithInvalidVersion = self._REMOTEMATERIAL_WHITE.copy() - remoteMaterialWithInvalidVersion["version"] = "one" - reply_mock.readAll.return_value = QByteArray(json.dumps([remoteMaterialWithInvalidVersion]).encode("ascii")) - - with self.assertRaises(ValueError): - SendMaterialJob._parseReply(reply_mock) - - def test__getLocalMaterials(self): - containerRegistry = ContainerRegistryMock() - containerRegistry.setContainersMetadata([self._LOCALMATERIAL_WHITE, self._LOCALMATERIAL_BLACK]) - - with mock.patch.object(Logger, "log", new=new_log): - with mock.patch.object(ContainerRegistry, "getInstance", lambda: containerRegistry): - local_materials = SendMaterialJob(None)._getLocalMaterials() - - self.assertTrue(len(local_materials) == 2) - - def test__getLocalMaterialsWithMultipleVersions(self): - containerRegistry = ContainerRegistryMock() - localMaterialWithNewerVersion = self._LOCALMATERIAL_WHITE.copy() - localMaterialWithNewerVersion["version"] = 2 - containerRegistry.setContainersMetadata([self._LOCALMATERIAL_WHITE, localMaterialWithNewerVersion]) - - with mock.patch.object(Logger, "log", new=new_log): - with mock.patch.object(ContainerRegistry, "getInstance", lambda: containerRegistry): - local_materials = SendMaterialJob(None)._getLocalMaterials() - - self.assertTrue(len(local_materials) == 1) - self.assertTrue(list(local_materials.values())[0].version == 2) - - containerRegistry.setContainersMetadata([localMaterialWithNewerVersion, self._LOCALMATERIAL_WHITE]) - - with mock.patch.object(Logger, "log", new=new_log): - with mock.patch.object(ContainerRegistry, "getInstance", lambda: containerRegistry): - local_materials = SendMaterialJob(None)._getLocalMaterials() - - self.assertTrue(len(local_materials) == 1) - self.assertTrue(list(local_materials.values())[0].version == 2) - - def _assertLogEntries(self, first, second): - """ - Inspects the two sets of log entry tuples and fails when they are not the same - :param first: The first set of tuples - :param second: The second set of tuples - """ - self.assertEqual(len(first), len(second)) - - while len(first) > 0: - e1, m1 = first[0] - e2, m2 = second[0] - self.assertEqual(e1, e2) - self.assertEqual(m1, m2) - first.pop(0) - second.pop(0) + # @patch("PyQt5.QtNetwork.QNetworkReply") + # def test_sendMissingMaterials_withMissingGuid(self, reply_mock): + # reply_mock.attribute.return_value = 200 + # remoteMaterialWithoutGuid = self._REMOTEMATERIAL_WHITE.copy() + # del remoteMaterialWithoutGuid["guid"] + # reply_mock.readAll.return_value = QByteArray(json.dumps([remoteMaterialWithoutGuid]).encode("ascii")) + # + # with mock.patch.object(Logger, 'log', new=new_log): + # SendMaterialJob(None).sendMissingMaterials(reply_mock) + # + # reply_mock.attribute.assert_called_with(0) + # self.assertEqual(reply_mock.method_calls, [call.attribute(0), call.readAll()]) + # self._assertLogEntries( + # [('e', "Request material storage on printer: Printer's answer was missing GUIDs.")], + # _logentries) + # + # @patch("UM.Resources.Resources.getAllResourcesOfType", lambda _: []) + # @patch("PyQt5.QtNetwork.QNetworkReply") + # def test_sendMissingMaterials_WithInvalidVersionInLocalMaterial(self, reply_mock): + # reply_mock.attribute.return_value = 200 + # reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTEMATERIAL_WHITE]).encode("ascii")) + # + # containerRegistry = ContainerRegistryMock() + # localMaterialWhiteWithInvalidVersion = self._LOCALMATERIAL_WHITE.copy() + # localMaterialWhiteWithInvalidVersion["version"] = "one" + # containerRegistry.setContainersMetadata([localMaterialWhiteWithInvalidVersion]) + # + # with mock.patch.object(Logger, "log", new=new_log): + # with mock.patch.object(ContainerRegistry, "getInstance", lambda: containerRegistry): + # SendMaterialJob(None).sendMissingMaterials(reply_mock) + # + # reply_mock.attribute.assert_called_with(0) + # self.assertEqual(reply_mock.method_calls, [call.attribute(0), call.readAll()]) + # self._assertLogEntries([('e', "Material generic_pla_white has invalid version number one.")], _logentries) + # + # @patch("UM.Resources.Resources.getAllResourcesOfType", lambda _: []) + # @patch("PyQt5.QtNetwork.QNetworkReply") + # def test_sendMissingMaterials_WithMultipleLocalVersionsLowFirst(self, reply_mock): + # reply_mock.attribute.return_value = 200 + # reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTEMATERIAL_WHITE]).encode("ascii")) + # + # containerRegistry = ContainerRegistryMock() + # localMaterialWhiteWithHigherVersion = self._LOCALMATERIAL_WHITE.copy() + # localMaterialWhiteWithHigherVersion["version"] = "2" + # containerRegistry.setContainersMetadata([self._LOCALMATERIAL_WHITE, localMaterialWhiteWithHigherVersion]) + # + # with mock.patch.object(Logger, "log", new=new_log): + # with mock.patch.object(ContainerRegistry, "getInstance", lambda: containerRegistry): + # SendMaterialJob(None).sendMissingMaterials(reply_mock) + # + # reply_mock.attribute.assert_called_with(0) + # self.assertEqual(reply_mock.method_calls, [call.attribute(0), call.readAll()]) + # self._assertLogEntries([], _logentries) + # + # @patch("UM.Resources.Resources.getAllResourcesOfType", lambda _: []) + # @patch("PyQt5.QtNetwork.QNetworkReply") + # def test_sendMissingMaterials_MaterialMissingOnPrinter(self, reply_mock): + # reply_mock.attribute.return_value = 200 + # reply_mock.readAll.return_value = QByteArray( + # json.dumps([self._REMOTEMATERIAL_WHITE]).encode("ascii")) + # + # containerRegistry = ContainerRegistryMock() + # containerRegistry.setContainersMetadata([self._LOCALMATERIAL_WHITE, self._LOCALMATERIAL_BLACK]) + # + # with mock.patch.object(Logger, "log", new=new_log): + # with mock.patch.object(ContainerRegistry, "getInstance", lambda: containerRegistry): + # SendMaterialJob(None).sendMissingMaterials(reply_mock) + # + # reply_mock.attribute.assert_called_with(0) + # self.assertEqual(reply_mock.method_calls, [call.attribute(0), call.readAll()]) + # self._assertLogEntries([], _logentries) + # + # @patch("builtins.open", lambda a, b: io.StringIO("")) + # @patch("UM.MimeTypeDatabase.MimeTypeDatabase.getMimeTypeForFile", + # lambda _: MimeType(name="application/x-ultimaker-material-profile", comment="Ultimaker Material Profile", + # suffixes=["xml.fdm_material"])) + # @patch("UM.Resources.Resources.getAllResourcesOfType", lambda _: ["/materials/generic_pla_white.xml.fdm_material"]) + # @patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") + # def test_sendMaterialsToPrinter(self, device_mock): + # device_mock._createFormPart.return_value = "_xXx_" + # with mock.patch.object(Logger, "log", new=new_log): + # job = SendMaterialJob(device_mock) + # job.sendMaterialsToPrinter({'generic_pla_white'}) + # + # self._assertLogEntries([("d", "Syncing material generic_pla_white with cluster.")], _logentries) + # self.assertEqual([call._createFormPart('name="file"; filename="generic_pla_white.xml.fdm_material"', ''), + # call.postFormWithParts(on_finished=job.sendingFinished, parts = ["_xXx_"], target = "materials/")], device_mock.method_calls) + # + # @patch("PyQt5.QtNetwork.QNetworkReply") + # def test_sendingFinished_success(self, reply_mock) -> None: + # reply_mock.attribute.return_value = 200 + # with mock.patch.object(Logger, 'log', new=new_log): + # SendMaterialJob(None).sendingFinished(reply_mock) + # + # reply_mock.attribute.assert_called_once_with(0) + # self.assertEqual(0, len(_logentries)) + # + # @patch("PyQt5.QtNetwork.QNetworkReply") + # def test_sendingFinished_failed(self, reply_mock) -> None: + # reply_mock.attribute.return_value = 404 + # reply_mock.readAll.return_value = QByteArray(b'Six sick hicks nick six slick bricks with picks and sticks.') + # + # with mock.patch.object(Logger, 'log', new=new_log): + # SendMaterialJob(None).sendingFinished(reply_mock) + # + # reply_mock.attribute.assert_called_with(0) + # self.assertEqual(reply_mock.method_calls, [call.attribute(0), call.attribute(0), call.readAll()]) + # + # self._assertLogEntries([ + # ("e", "Received error code from printer when syncing material: 404"), + # ("e", "Six sick hicks nick six slick bricks with picks and sticks.") + # ], _logentries) + # + # @patch("PyQt5.QtNetwork.QNetworkReply") + # def test_parseReply(self, reply_mock): + # reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTEMATERIAL_WHITE]).encode("ascii")) + # + # response = SendMaterialJob._parseReply(reply_mock) + # + # self.assertTrue(len(response) == 1) + # self.assertEqual(next(iter(response.values())), ClusterMaterial(**self._REMOTEMATERIAL_WHITE)) + # + # @patch("PyQt5.QtNetwork.QNetworkReply") + # def test_parseReplyWithInvalidMaterial(self, reply_mock): + # remoteMaterialWithInvalidVersion = self._REMOTEMATERIAL_WHITE.copy() + # remoteMaterialWithInvalidVersion["version"] = "one" + # reply_mock.readAll.return_value = QByteArray(json.dumps([remoteMaterialWithInvalidVersion]).encode("ascii")) + # + # with self.assertRaises(ValueError): + # SendMaterialJob._parseReply(reply_mock) + # + # def test__getLocalMaterials(self): + # containerRegistry = ContainerRegistryMock() + # containerRegistry.setContainersMetadata([self._LOCALMATERIAL_WHITE, self._LOCALMATERIAL_BLACK]) + # + # with mock.patch.object(Logger, "log", new=new_log): + # with mock.patch.object(ContainerRegistry, "getInstance", lambda: containerRegistry): + # local_materials = SendMaterialJob(None)._getLocalMaterials() + # + # self.assertTrue(len(local_materials) == 2) + # + # def test__getLocalMaterialsWithMultipleVersions(self): + # containerRegistry = ContainerRegistryMock() + # localMaterialWithNewerVersion = self._LOCALMATERIAL_WHITE.copy() + # localMaterialWithNewerVersion["version"] = 2 + # containerRegistry.setContainersMetadata([self._LOCALMATERIAL_WHITE, localMaterialWithNewerVersion]) + # + # with mock.patch.object(Logger, "log", new=new_log): + # with mock.patch.object(ContainerRegistry, "getInstance", lambda: containerRegistry): + # local_materials = SendMaterialJob(None)._getLocalMaterials() + # + # self.assertTrue(len(local_materials) == 1) + # self.assertTrue(list(local_materials.values())[0].version == 2) + # + # containerRegistry.setContainersMetadata([localMaterialWithNewerVersion, self._LOCALMATERIAL_WHITE]) + # + # with mock.patch.object(Logger, "log", new=new_log): + # with mock.patch.object(ContainerRegistry, "getInstance", lambda: containerRegistry): + # local_materials = SendMaterialJob(None)._getLocalMaterials() + # + # self.assertTrue(len(local_materials) == 1) + # self.assertTrue(list(local_materials.values())[0].version == 2) + # + # def _assertLogEntries(self, first, second): + # """ + # Inspects the two sets of log entry tuples and fails when they are not the same + # :param first: The first set of tuples + # :param second: The second set of tuples + # """ + # self.assertEqual(len(first), len(second)) + # + # while len(first) > 0: + # e1, m1 = first[0] + # e2, m2 = second[0] + # self.assertEqual(e1, e2) + # self.assertEqual(m1, m2) + # first.pop(0) + # second.pop(0) From a490e420f09327be74f0145fb055ab5021d315c7 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 19 Nov 2018 11:42:04 +0100 Subject: [PATCH 0257/1292] Prevent the setting items from being recreated every stage switch CURA-5785 --- plugins/PrepareStage/PrepareMenu.qml | 20 +++++++++----------- plugins/PreviewStage/PreviewMenu.qml | 12 +++++++----- resources/qml/Cura.qml | 11 +++++++++++ 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index c464727dde..ef01625a22 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -13,6 +13,7 @@ Item signal showTooltip(Item item, point location, string text) signal hideTooltip() + UM.I18nCatalog { id: catalog @@ -71,7 +72,7 @@ Item { Layout.fillHeight: true Layout.fillWidth: true - Layout.preferredWidth: itemRow.width - machineSelection.width - printSetupSelector.width - 2 * UM.Theme.getSize("default_lining").width + Layout.preferredWidth: itemRow.width - machineSelection.width - printSetupSelectorItem.width - 2 * UM.Theme.getSize("default_lining").width } // Separator line @@ -82,17 +83,14 @@ Item color: UM.Theme.getColor("lining") } - Cura.PrintSetupSelector + Item { - id: printSetupSelector - - onShowTooltip: prepareMenu.showTooltip(item, location, text) - onHideTooltip: prepareMenu.hideTooltip() - - Layout.minimumWidth: UM.Theme.getSize("print_setup_widget").width - Layout.maximumWidth: UM.Theme.getSize("print_setup_widget").width - Layout.fillWidth: true - Layout.fillHeight: true + id: printSetupSelectorItem + // This is a work around to prevent the printSetupSelector from having to be re-loaded every time + // a stage switch is done. + children: [printSetupSelector] + height: childrenRect.height + width: childrenRect.width } } } diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index b73c1088ae..b331ff69c5 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -138,12 +138,14 @@ Item color: UM.Theme.getColor("lining") } - Cura.PrintSetupSelector + Item { - width: UM.Theme.getSize("print_setup_widget").width - height: parent.height - onShowTooltip: previewMenu.showTooltip(item, location, text) - onHideTooltip: previewMenu.hideTooltip() + id: printSetupSelectorItem + // This is a work around to prevent the printSetupSelector from having to be re-loaded every time + // a stage switch is done. + children: [printSetupSelector] + height: childrenRect.height + width: childrenRect.width } } } diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 0312a636a6..c239dc8d6f 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -40,6 +40,7 @@ UM.MainWindow tooltip.hide(); } + Component.onCompleted: { CuraApplication.setMinimumWindowSize(UM.Theme.getSize("window_minimum_size")) @@ -249,6 +250,16 @@ UM.MainWindow height: UM.Theme.getSize("stage_menu").height source: UM.Controller.activeStage != null ? UM.Controller.activeStage.stageMenuComponent : "" + + // The printSetupSelector is defined here so that the setting list doesn't need to get re-instantiated + // Every time the stage is changed. + property var printSetupSelector: Cura.PrintSetupSelector + { + onShowTooltip: base.showTooltip(item, location, text) + onHideTooltip: base.hideTooltip() + width: UM.Theme.getSize("print_setup_widget").width + height: UM.Theme.getSize("stage_menu").height + } } UM.MessageStack From 2f624cc78f18baf189e3d39c928ebc605746a6c1 Mon Sep 17 00:00:00 2001 From: Dario Minnucci Date: Mon, 19 Nov 2018 12:37:57 +0100 Subject: [PATCH 0258/1292] Add BIBO2 printer (dual and single extruder settings) --- resources/definitions/bibo2_dual.def.json | 98 +++++++++++++++++++ .../bibo2_single_extruder_0.def.json | 98 +++++++++++++++++++ .../bibo2_single_extruder_1.def.json | 98 +++++++++++++++++++ .../extruders/bibo2_dual_extruder_0.def.json | 40 ++++++++ .../extruders/bibo2_dual_extruder_1.def.json | 40 ++++++++ .../bibo2_single_extruder_0_0.def.json | 40 ++++++++ .../bibo2_single_extruder_0_1.def.json | 40 ++++++++ .../bibo2_single_extruder_1_0.def.json | 40 ++++++++ .../bibo2_single_extruder_1_1.def.json | 40 ++++++++ 9 files changed, 534 insertions(+) create mode 100644 resources/definitions/bibo2_dual.def.json create mode 100644 resources/definitions/bibo2_single_extruder_0.def.json create mode 100644 resources/definitions/bibo2_single_extruder_1.def.json create mode 100644 resources/extruders/bibo2_dual_extruder_0.def.json create mode 100644 resources/extruders/bibo2_dual_extruder_1.def.json create mode 100644 resources/extruders/bibo2_single_extruder_0_0.def.json create mode 100644 resources/extruders/bibo2_single_extruder_0_1.def.json create mode 100644 resources/extruders/bibo2_single_extruder_1_0.def.json create mode 100644 resources/extruders/bibo2_single_extruder_1_1.def.json diff --git a/resources/definitions/bibo2_dual.def.json b/resources/definitions/bibo2_dual.def.json new file mode 100644 index 0000000000..e57fb64ec0 --- /dev/null +++ b/resources/definitions/bibo2_dual.def.json @@ -0,0 +1,98 @@ +{ + "id": "BIBO2 dual", + "version": 2, + "name": "BIBO2 dual", + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "author": "na", + "manufacturer": "BIBO", + "category": "Other", + "file_formats": "text/x-gcode", + "has_materials": true, + "machine_extruder_trains": { + "0": "bibo2_dual_extruder_0", + "1": "bibo2_dual_extruder_1" + }, + "first_start_actions": [ + "MachineSettingsAction" + ] + }, + "overrides": { + "machine_name": { + "default_value": "BIBO2 dual" + }, + "machine_width": { + "default_value": 214 + }, + "machine_height": { + "default_value": 160 + }, + "machine_depth": { + "default_value": 186 + }, + "machine_center_is_zero": { + "default_value": true + }, + "machine_heated_bed": { + "default_value": true + }, + "machine_nozzle_size": { + "default_value": 0.4 + }, + "machine_nozzle_heat_up_speed": { + "default_value": 2 + }, + "machine_nozzle_cool_down_speed": { + "default_value": 2 + }, + "machine_head_with_fans_polygon": { + "default_value": [ + [ + -68.18, + 64.63 + ], + [ + -68.18, + -47.38 + ], + [ + 35.18, + 64.63 + ], + [ + 35.18, + -47.38 + ] + ] + }, + "material_diameter": { + "default_value": 1.75 + }, + "gantry_height": { + "default_value": 12 + }, + "machine_use_extruder_offset_to_offset_coords": { + "default_value": true + }, + "machine_gcode_flavor": { + "default_value": "RepRap (Marlin/Sprinter)" + }, + "machine_start_gcode": { + "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z2.0 F400 ;move the platform down 15mm\nT0\nG92 E0\nG28\nG1 Y0 F1200 E0\nG92 E0\nM117 BIBO Printing..." + }, + "machine_end_gcode": { + "default_value": ";End GCode\nM104 T0 S0 ;extruder heater off\nM104 T1 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91\nG1 Z1 F100 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-2 X-20 Y-20 F300 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" + }, + "machine_extruder_count": { + "default_value": 2 + }, + "prime_tower_position_x": { + "default_value": 50 + }, + "prime_tower_position_y": { + "default_value": 50 + } + } +} + diff --git a/resources/definitions/bibo2_single_extruder_0.def.json b/resources/definitions/bibo2_single_extruder_0.def.json new file mode 100644 index 0000000000..93c7a4e5ae --- /dev/null +++ b/resources/definitions/bibo2_single_extruder_0.def.json @@ -0,0 +1,98 @@ +{ + "id": "BIBO2 single E1", + "version": 2, + "name": "BIBO2 single E1", + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "author": "na", + "manufacturer": "BIBO", + "category": "Other", + "file_formats": "text/x-gcode", + "has_materials": true, + "machine_extruder_trains": { + "0": "bibo2_single_extruder_0_0", + "1": "bibo2_single_extruder_0_1" + }, + "first_start_actions": [ + "MachineSettingsAction" + ] + }, + "overrides": { + "machine_name": { + "default_value": "BIBO2 single Extruder 1 (right)" + }, + "machine_width": { + "default_value": 214 + }, + "machine_height": { + "default_value": 160 + }, + "machine_depth": { + "default_value": 186 + }, + "machine_center_is_zero": { + "default_value": true + }, + "machine_heated_bed": { + "default_value": true + }, + "machine_nozzle_size": { + "default_value": 0.4 + }, + "machine_nozzle_heat_up_speed": { + "default_value": 2 + }, + "machine_nozzle_cool_down_speed": { + "default_value": 2 + }, + "machine_head_with_fans_polygon": { + "default_value": [ + [ + -68.18, + 64.63 + ], + [ + -68.18, + -47.38 + ], + [ + 35.18, + 64.63 + ], + [ + 35.18, + -47.38 + ] + ] + }, + "material_diameter": { + "default_value": 1.75 + }, + "gantry_height": { + "default_value": 12 + }, + "machine_use_extruder_offset_to_offset_coords": { + "default_value": true + }, + "machine_gcode_flavor": { + "default_value": "RepRap (Marlin/Sprinter)" + }, + "machine_start_gcode": { + "default_value": ";Startcode BIBO printers\nM109 T1 S170 ;preheat the other extruder, so it will not knock or ruin the print\nG90 ; absolute mode\nG21 ; metric values\nM82 ; Extruder in absolute mode\nM107\nG28\nG1 Z2 F400\nT0\nG90\nG92 E0\nG28\nG1 Y0 F1200 E0\nG92 E0\nG1 X-15.0 Y-92.9 Z0.3 F2400.0\t\t; move to start-line position\nG1 X15.0 Y-92.9 Z0.3 F1000.0 E2\t\t; draw 1st line\nG1 X15.0 Y-92.6 Z0.3 F3000.0\t\t; move to side a little\nG1 X-15.0 Y-92.6 Z0.3 F1000.0 E4\t\t; draw 2nd line\nG1 X-15.0 Y-92.3 Z0.3 F3000.0\t\t; move to side a little\nG1 X15.0 Y-92.3 Z0.3 F1000.0 E6\t\t; draw 3rd line\nG1 X15.0 Y-92 Z0.3 F3000.0\t\t; move to side a little\nG1 X-15.0 Y-92 Z0.3 F1000.0 E8\t\t; draw 4th line\nG1 X-16.0 Y-91.7 Z0.3 F3000.0\t\t; move to side a little\nG1 X16.0 Y-91.7 Z0.3 F1000.0 E10\t\t; draw 5th line\nG1 X16.0 Y-91.4 Z0.3 F3000.0\t\t; move to side a little\nG1 X-16.0 Y-91.4 Z0.3 F1000.0 E12\t\t; draw 5th line\nG1 E11.5 F2400\t\t\t\t; retract filament 0.5mm\nG92 E0\nM117 BIBO Printing..." + }, + "machine_end_gcode": { + "default_value": ";BIBO End GCode\nM107\nG91 ; Relative positioning\nG1 Z1 F100\nM104 T0 S0\nM104 T1 S0\nG1 X-20 Y-20 F3000\nG28 X0 Y0\nG90 ; Absolute positioning\nG92 E0 ; Reset extruder position\nM140 S0 ; Disable heated bed\nM84 ; Turn steppers off\nM117 BIBO Print complete\n " + }, + "machine_extruder_count": { + "default_value": 2 + }, + "prime_tower_position_x": { + "default_value": 50 + }, + "prime_tower_position_y": { + "default_value": 50 + } + } +} + diff --git a/resources/definitions/bibo2_single_extruder_1.def.json b/resources/definitions/bibo2_single_extruder_1.def.json new file mode 100644 index 0000000000..246add09ab --- /dev/null +++ b/resources/definitions/bibo2_single_extruder_1.def.json @@ -0,0 +1,98 @@ +{ + "id": "BIBO2 single E2", + "version": 2, + "name": "BIBO2 single E2", + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "author": "na", + "manufacturer": "BIBO", + "category": "Other", + "file_formats": "text/x-gcode", + "has_materials": true, + "machine_extruder_trains": { + "0": "bibo2_single_extruder_1_0", + "1": "bibo2_single_extruder_1_1" + }, + "first_start_actions": [ + "MachineSettingsAction" + ] + }, + "overrides": { + "machine_name": { + "default_value": "BIBO2 single Extruder 2 (left)" + }, + "machine_width": { + "default_value": 214 + }, + "machine_height": { + "default_value": 160 + }, + "machine_depth": { + "default_value": 186 + }, + "machine_center_is_zero": { + "default_value": true + }, + "machine_heated_bed": { + "default_value": true + }, + "machine_nozzle_size": { + "default_value": 0.4 + }, + "machine_nozzle_heat_up_speed": { + "default_value": 2 + }, + "machine_nozzle_cool_down_speed": { + "default_value": 2 + }, + "machine_head_with_fans_polygon": { + "default_value": [ + [ + -68.18, + 64.63 + ], + [ + -68.18, + -47.38 + ], + [ + 35.18, + 64.63 + ], + [ + 35.18, + -47.38 + ] + ] + }, + "material_diameter": { + "default_value": 1.75 + }, + "gantry_height": { + "default_value": 12 + }, + "machine_use_extruder_offset_to_offset_coords": { + "default_value": true + }, + "machine_gcode_flavor": { + "default_value": "RepRap (Marlin/Sprinter)" + }, + "machine_start_gcode": { + "default_value": ";Startcode BIBO printers\nM109 T0 S170 ;preheat the other extruder, so it will not knock or ruin the print\nG90 ; absolute mode\nG21 ; metric values\nM82 ; Extruder in absolute mode\nM107\nG28\nG1 Z2 F400\nT0\nG90\nG92 E0\nG28\nG1 Y0 F1200 E0\nG92 E0\nT1\nG92 E0\nG1 X-15.0 Y-92.9 Z0.3 F2400.0\t\t; move to start-line position\nG1 X15.0 Y-92.9 Z0.3 F1000.0 E2\t\t; draw 1st line\nG1 X15.0 Y-92.6 Z0.3 F3000.0\t\t; move to side a little\nG1 X-15.0 Y-92.6 Z0.3 F1000.0 E4\t\t; draw 2nd line\nG1 X-15.0 Y-92.3 Z0.3 F3000.0\t\t; move to side a little\nG1 X15.0 Y-92.3 Z0.3 F1000.0 E6\t\t; draw 3rd line\nG1 X15.0 Y-92 Z0.3 F3000.0\t\t; move to side a little\nG1 X-15.0 Y-92 Z0.3 F1000.0 E8\t\t; draw 4th line\nG1 X-16.0 Y-91.7 Z0.3 F3000.0\t\t; move to side a little\nG1 X16.0 Y-91.7 Z0.3 F1000.0 E10\t\t; draw 5th line\nG1 X16.0 Y-91.4 Z0.3 F3000.0\t\t; move to side a little\nG1 X-16.0 Y-91.4 Z0.3 F1000.0 E12\t\t; draw 5th line\nG1 E11.5 F2400\t\t\t\t; retract filament 0.5mm\nG92 E0\nM117 BIBO Printing..." + }, + "machine_end_gcode": { + "default_value": ";BIBO End GCode\nM107\nG91 ; Relative positioning\nG1 Z1 F100\nM104 T0 S0\nM104 T1 S0\nG1 X-20 Y-20 F3000\nG28 X0 Y0\nG90 ; Absolute positioning\nG92 E0 ; Reset extruder position\nM140 S0 ; Disable heated bed\nM84 ; Turn steppers off\nM117 BIBO Print complete\n " + }, + "machine_extruder_count": { + "default_value": 2 + }, + "prime_tower_position_x": { + "default_value": 50 + }, + "prime_tower_position_y": { + "default_value": 50 + } + } +} + diff --git a/resources/extruders/bibo2_dual_extruder_0.def.json b/resources/extruders/bibo2_dual_extruder_0.def.json new file mode 100644 index 0000000000..7cdc03d504 --- /dev/null +++ b/resources/extruders/bibo2_dual_extruder_0.def.json @@ -0,0 +1,40 @@ +{ + "id": "BIBO1", + "version": 2, + "name": "Extruder 1", + "inherits": "fdmextruder", + "metadata": { + "machine": "BIBO2 dual", + "position": "0" + }, + "overrides": { + "extruder_nr": { + "default_value": 0, + "maximum_value": "1" + }, + "machine_nozzle_offset_x": { + "default_value": 0.0 + }, + "machine_nozzle_offset_y": { + "default_value": 0.0 + }, + "machine_extruder_start_pos_abs": { + "default_value": true + }, + "machine_extruder_start_pos_x": { + "value": "prime_tower_position_x" + }, + "machine_extruder_start_pos_y": { + "value": "prime_tower_position_y" + }, + "machine_extruder_end_pos_abs": { + "default_value": true + }, + "machine_extruder_end_pos_x": { + "value": "prime_tower_position_x" + }, + "machine_extruder_end_pos_y": { + "value": "prime_tower_position_y" + } + } +} diff --git a/resources/extruders/bibo2_dual_extruder_1.def.json b/resources/extruders/bibo2_dual_extruder_1.def.json new file mode 100644 index 0000000000..daa1504220 --- /dev/null +++ b/resources/extruders/bibo2_dual_extruder_1.def.json @@ -0,0 +1,40 @@ +{ + "id": "BIBO2", + "version": 2, + "name": "Extruder 2", + "inherits": "fdmextruder", + "metadata": { + "machine": "BIBO2 dual", + "position": "1" + }, + "overrides": { + "extruder_nr": { + "default_value": 1, + "maximum_value": "1" + }, + "machine_nozzle_offset_x": { + "default_value": 0 + }, + "machine_nozzle_offset_y": { + "default_value": 0 + }, + "machine_extruder_start_pos_abs": { + "default_value": true + }, + "machine_extruder_start_pos_x": { + "value": "prime_tower_position_x" + }, + "machine_extruder_start_pos_y": { + "value": "prime_tower_position_y" + }, + "machine_extruder_end_pos_abs": { + "default_value": true + }, + "machine_extruder_end_pos_x": { + "value": "prime_tower_position_x" + }, + "machine_extruder_end_pos_y": { + "value": "prime_tower_position_y" + } + } +} diff --git a/resources/extruders/bibo2_single_extruder_0_0.def.json b/resources/extruders/bibo2_single_extruder_0_0.def.json new file mode 100644 index 0000000000..7d0b246131 --- /dev/null +++ b/resources/extruders/bibo2_single_extruder_0_0.def.json @@ -0,0 +1,40 @@ +{ + "id": "BIBO2 E1a", + "version": 2, + "name": "BIBO2 E1", + "inherits": "fdmextruder", + "metadata": { + "machine": "BIBO2 single E1", + "position": "0" + }, + "overrides": { + "extruder_nr": { + "default_value": 0, + "maximum_value": "1" + }, + "machine_nozzle_offset_x": { + "default_value": 0.0 + }, + "machine_nozzle_offset_y": { + "default_value": 0.0 + }, + "machine_extruder_start_pos_abs": { + "default_value": true + }, + "machine_extruder_start_pos_x": { + "value": "prime_tower_position_x" + }, + "machine_extruder_start_pos_y": { + "value": "prime_tower_position_y" + }, + "machine_extruder_end_pos_abs": { + "default_value": true + }, + "machine_extruder_end_pos_x": { + "value": "prime_tower_position_x" + }, + "machine_extruder_end_pos_y": { + "value": "prime_tower_position_y" + } + } +} diff --git a/resources/extruders/bibo2_single_extruder_0_1.def.json b/resources/extruders/bibo2_single_extruder_0_1.def.json new file mode 100644 index 0000000000..76187696fc --- /dev/null +++ b/resources/extruders/bibo2_single_extruder_0_1.def.json @@ -0,0 +1,40 @@ +{ + "id": "BIBO2 E1b", + "version": 2, + "name": "E2 not used", + "inherits": "fdmextruder", + "metadata": { + "machine": "BIBO2 single E1", + "position": "1" + }, + "overrides": { + "extruder_nr": { + "default_value": 1, + "maximum_value": "1" + }, + "machine_nozzle_offset_x": { + "default_value": 0.0 + }, + "machine_nozzle_offset_y": { + "default_value": 0.0 + }, + "machine_extruder_start_pos_abs": { + "default_value": true + }, + "machine_extruder_start_pos_x": { + "value": "prime_tower_position_x" + }, + "machine_extruder_start_pos_y": { + "value": "prime_tower_position_y" + }, + "machine_extruder_end_pos_abs": { + "default_value": true + }, + "machine_extruder_end_pos_x": { + "value": "prime_tower_position_x" + }, + "machine_extruder_end_pos_y": { + "value": "prime_tower_position_y" + } + } +} diff --git a/resources/extruders/bibo2_single_extruder_1_0.def.json b/resources/extruders/bibo2_single_extruder_1_0.def.json new file mode 100644 index 0000000000..3cf667de82 --- /dev/null +++ b/resources/extruders/bibo2_single_extruder_1_0.def.json @@ -0,0 +1,40 @@ +{ + "id": "BIBO2 E2a", + "version": 2, + "name": "E1 not used", + "inherits": "fdmextruder", + "metadata": { + "machine": "BIBO2 single E2", + "position": "0" + }, + "overrides": { + "extruder_nr": { + "default_value": 0, + "maximum_value": "1" + }, + "machine_nozzle_offset_x": { + "default_value": 0 + }, + "machine_nozzle_offset_y": { + "default_value": 0 + }, + "machine_extruder_start_pos_abs": { + "default_value": true + }, + "machine_extruder_start_pos_x": { + "value": "prime_tower_position_x" + }, + "machine_extruder_start_pos_y": { + "value": "prime_tower_position_y" + }, + "machine_extruder_end_pos_abs": { + "default_value": true + }, + "machine_extruder_end_pos_x": { + "value": "prime_tower_position_x" + }, + "machine_extruder_end_pos_y": { + "value": "prime_tower_position_y" + } + } +} diff --git a/resources/extruders/bibo2_single_extruder_1_1.def.json b/resources/extruders/bibo2_single_extruder_1_1.def.json new file mode 100644 index 0000000000..e8f3ec7054 --- /dev/null +++ b/resources/extruders/bibo2_single_extruder_1_1.def.json @@ -0,0 +1,40 @@ +{ + "id": "BIBO2 E2b", + "version": 2, + "name": "BIBO2 E2", + "inherits": "fdmextruder", + "metadata": { + "machine": "BIBO2 single E2", + "position": "1" + }, + "overrides": { + "extruder_nr": { + "default_value": 1, + "maximum_value": "1" + }, + "machine_nozzle_offset_x": { + "default_value": 0 + }, + "machine_nozzle_offset_y": { + "default_value": 0 + }, + "machine_extruder_start_pos_abs": { + "default_value": true + }, + "machine_extruder_start_pos_x": { + "value": "prime_tower_position_x" + }, + "machine_extruder_start_pos_y": { + "value": "prime_tower_position_y" + }, + "machine_extruder_end_pos_abs": { + "default_value": true + }, + "machine_extruder_end_pos_x": { + "value": "prime_tower_position_x" + }, + "machine_extruder_end_pos_y": { + "value": "prime_tower_position_y" + } + } +} From b0f3fedc94354d30a8677bc93f02e67a9ec3d0f0 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 19 Nov 2018 13:42:19 +0100 Subject: [PATCH 0259/1292] Fix import QtQuick versions to suit Qt 5.10 CURA-5785 --- plugins/PreviewStage/PreviewMenu.qml | 3 +-- resources/qml/MachineSelector.qml | 2 +- .../qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index b331ff69c5..1a744aeb65 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -2,8 +2,7 @@ // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 - -import QtQuick.Controls 2.4 +import QtQuick.Controls 2.3 import UM 1.3 as UM import Cura 1.1 as Cura diff --git a/resources/qml/MachineSelector.qml b/resources/qml/MachineSelector.qml index a464949192..c9756d93ba 100644 --- a/resources/qml/MachineSelector.qml +++ b/resources/qml/MachineSelector.qml @@ -2,7 +2,7 @@ // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 -import QtQuick.Controls 2.4 +import QtQuick.Controls 2.3 import QtQuick.Controls.Styles 1.1 import QtQuick.Layouts 1.1 diff --git a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml index 33610135fe..d428a05463 100644 --- a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml +++ b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml @@ -4,7 +4,7 @@ import QtQuick 2.7 import QtQuick.Controls 2.0 import QtQuick.Controls.Styles 1.4 -import QtQuick.Layouts 1.11 +import QtQuick.Layouts 1.3 import QtQuick.Controls 1.1 as OldControls From f8f133d2ef92dfabb636eac70b09e681bd4b4d63 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 19 Nov 2018 13:42:28 +0100 Subject: [PATCH 0260/1292] Fix running tests in plugin using pytest --- .../tests/TestLegacyProfileReader.py | 9 +++++---- .../tests/TestVersionUpgrade25to26.py | 11 ++++++++--- .../tests/TestVersionUpgrade26to27.py | 9 +++++---- .../tests/TestVersionUpgrade27to30.py | 8 ++++---- .../tests/TestVersionUpgrade34to35.py | 10 ++++++---- 5 files changed, 28 insertions(+), 19 deletions(-) diff --git a/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py b/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py index 480a61f301..3c9e46b6d8 100644 --- a/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py +++ b/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py @@ -1,8 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. - import configparser # An input for some functions we're testing. -import os.path # To find the integration test .ini files. +import os # To find the integration test .ini files. import pytest # To register tests with. import unittest.mock # To mock the application, plug-in and container registry out. @@ -11,13 +10,15 @@ import UM.PluginRegistry # To mock the plug-in registry out. import UM.Settings.ContainerRegistry # To mock the container registry out. import UM.Settings.InstanceContainer # To intercept the serialised data from the read() function. -import LegacyProfileReader as LegacyProfileReaderModule # To get the directory of the module. -from LegacyProfileReader import LegacyProfileReader # The module we're testing. +import plugins.LegacyProfileReader.LegacyProfileReader as LegacyProfileReaderModule +from plugins.LegacyProfileReader.LegacyProfileReader import LegacyProfileReader + @pytest.fixture def legacy_profile_reader(): return LegacyProfileReader() + test_prepareDefaultsData = [ { "defaults": diff --git a/plugins/VersionUpgrade/VersionUpgrade25to26/tests/TestVersionUpgrade25to26.py b/plugins/VersionUpgrade/VersionUpgrade25to26/tests/TestVersionUpgrade25to26.py index 9d7c7646cc..588c0cb3db 100644 --- a/plugins/VersionUpgrade/VersionUpgrade25to26/tests/TestVersionUpgrade25to26.py +++ b/plugins/VersionUpgrade/VersionUpgrade25to26/tests/TestVersionUpgrade25to26.py @@ -1,16 +1,17 @@ # Copyright (c) 2017 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +import configparser +import pytest -import configparser #To check whether the appropriate exceptions are raised. -import pytest #To register tests with. +from plugins.VersionUpgrade.VersionUpgrade25to26 import VersionUpgrade25to26 -import VersionUpgrade25to26 #The module we're testing. ## Creates an instance of the upgrader to test with. @pytest.fixture def upgrader(): return VersionUpgrade25to26.VersionUpgrade25to26() + test_cfg_version_good_data = [ { "test_name": "Simple", @@ -60,6 +61,7 @@ setting_version = -3 } ] + ## Tests the technique that gets the version number from CFG files. # # \param data The parametrised data to test with. It contains a test name @@ -116,6 +118,7 @@ version = 1.2 } ] + ## Tests whether getting a version number from bad CFG files gives an # exception. # @@ -155,6 +158,7 @@ foo = bar } ] + ## Tests whether the settings that should be removed are removed for the 2.6 # version of preferences. @pytest.mark.parametrize("data", test_upgrade_preferences_removed_settings_data) @@ -200,6 +204,7 @@ type = instance_container } ] + ## Tests whether the settings that should be removed are removed for the 2.6 # version of instance containers. @pytest.mark.parametrize("data", test_upgrade_instance_container_removed_settings_data) diff --git a/plugins/VersionUpgrade/VersionUpgrade26to27/tests/TestVersionUpgrade26to27.py b/plugins/VersionUpgrade/VersionUpgrade26to27/tests/TestVersionUpgrade26to27.py index eebaca23c6..45d41e7a1b 100644 --- a/plugins/VersionUpgrade/VersionUpgrade26to27/tests/TestVersionUpgrade26to27.py +++ b/plugins/VersionUpgrade/VersionUpgrade26to27/tests/TestVersionUpgrade26to27.py @@ -1,15 +1,16 @@ # Copyright (c) 2017 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +import configparser +import pytest -import configparser #To check whether the appropriate exceptions are raised. -import pytest #To register tests with. +from plugins.VersionUpgrade.VersionUpgrade26to27.VersionUpgrade26to27 import VersionUpgrade26to27 -import VersionUpgrade26to27 #The module we're testing. ## Creates an instance of the upgrader to test with. @pytest.fixture def upgrader(): - return VersionUpgrade26to27.VersionUpgrade26to27() + return VersionUpgrade26to27() + test_cfg_version_good_data = [ { diff --git a/plugins/VersionUpgrade/VersionUpgrade27to30/tests/TestVersionUpgrade27to30.py b/plugins/VersionUpgrade/VersionUpgrade27to30/tests/TestVersionUpgrade27to30.py index cae08ebcfd..7b77b85993 100644 --- a/plugins/VersionUpgrade/VersionUpgrade27to30/tests/TestVersionUpgrade27to30.py +++ b/plugins/VersionUpgrade/VersionUpgrade27to30/tests/TestVersionUpgrade27to30.py @@ -1,15 +1,15 @@ # Copyright (c) 2017 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +import configparser +import pytest -import configparser #To parse the resulting config files. -import pytest #To register tests with. +from plugins.VersionUpgrade.VersionUpgrade27to30.VersionUpgrade27to30 import VersionUpgrade27to30 -import VersionUpgrade27to30 #The module we're testing. ## Creates an instance of the upgrader to test with. @pytest.fixture def upgrader(): - return VersionUpgrade27to30.VersionUpgrade27to30() + return VersionUpgrade27to30() test_cfg_version_good_data = [ { diff --git a/plugins/VersionUpgrade/VersionUpgrade34to35/tests/TestVersionUpgrade34to35.py b/plugins/VersionUpgrade/VersionUpgrade34to35/tests/TestVersionUpgrade34to35.py index b74e6f35ac..4f77fcd093 100644 --- a/plugins/VersionUpgrade/VersionUpgrade34to35/tests/TestVersionUpgrade34to35.py +++ b/plugins/VersionUpgrade/VersionUpgrade34to35/tests/TestVersionUpgrade34to35.py @@ -1,15 +1,16 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +import configparser +import pytest -import configparser #To parse the resulting config files. -import pytest #To register tests with. +from plugins.VersionUpgrade.VersionUpgrade34to35.VersionUpgrade34to35 import VersionUpgrade34to35 -import VersionUpgrade34to35 #The module we're testing. ## Creates an instance of the upgrader to test with. @pytest.fixture def upgrader(): - return VersionUpgrade34to35.VersionUpgrade34to35() + return VersionUpgrade34to35() + test_upgrade_version_nr_data = [ ("Empty config file", @@ -25,6 +26,7 @@ test_upgrade_version_nr_data = [ ) ] + ## Tests whether the version numbers are updated. @pytest.mark.parametrize("test_name, file_data", test_upgrade_version_nr_data) def test_upgradeVersionNr(test_name, file_data, upgrader): From 30b20b4aa56e6bda5cc0f7f6ae0ab7a4f2a2e905 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 19 Nov 2018 13:50:32 +0100 Subject: [PATCH 0261/1292] Add borders to expandable components This adds a lining to all of the drop-downs from the stage menus. Contributes to issue CURA-5876. --- resources/qml/ExpandableComponent.qml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index 8ed6dc5674..0a80e020c9 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -17,6 +17,8 @@ Item property var popupItem property color popupBackgroundColor: UM.Theme.getColor("action_button") + property int popupBorderWidth: UM.Theme.getSize("default_lining").width + property color popupBorderColor: UM.Theme.getColor("lining") property color headerBackgroundColor: UM.Theme.getColor("action_button") property color headerHoverColor: UM.Theme.getColor("action_button_hovered") @@ -147,6 +149,8 @@ Item background: Rectangle { color: popupBackgroundColor + border.width: popupBorderWidth + border.color: popupBorderColor } } } From dc17bd849968d180dc061aff6ca7eaed53bfcff1 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 19 Nov 2018 13:54:45 +0100 Subject: [PATCH 0262/1292] Fix the first tests --- .../UM3NetworkPrinting/src/SendMaterialJob.py | 1 + .../tests/TestSendMaterialJob.py | 23 ++++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py index 349e6929ff..572558e352 100644 --- a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py @@ -157,6 +157,7 @@ class SendMaterialJob(Job): @classmethod def _parseReply(cls, reply: QNetworkReply) -> Dict[str, ClusterMaterial]: remote_materials_list = json.loads(reply.readAll().data().decode("utf-8")) + print("remote_materials_list", remote_materials_list) return {material["guid"]: ClusterMaterial(**material) for material in remote_materials_list} ## Retrieves a list of local materials diff --git a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py index bc6e1def14..b51d978ed2 100644 --- a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py @@ -90,26 +90,33 @@ class TestSendMaterialJob(TestCase): def test_run(self, device_mock): job = SendMaterialJob(device_mock) job.run() + + # We expect the materials endpoint to be called when the job runs. device_mock.get.assert_called_with("materials/", on_finished=job._onGetRemoteMaterials) @patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") @patch("PyQt5.QtNetwork.QNetworkReply") def test_sendMissingMaterials_withFailedRequest(self, reply_mock, device_mock): reply_mock.attribute.return_value = 404 - SendMaterialJob(device_mock).run() - reply_mock.attribute.assert_called_with(0) - self.assertEqual(reply_mock.method_calls, [call.attribute(0)]) - self.assertEqual(device_mock._onGetRemoteMaterials.method_calls, []) + job = SendMaterialJob(device_mock) + job._onGetRemoteMaterials(reply_mock) + + # We expect the error string to be retrieved and the device not to be called for any follow up. + self.assertEqual([call.attribute(0), call.errorString()], reply_mock.method_calls) + self.assertEqual([], device_mock.method_calls) @patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") @patch("PyQt5.QtNetwork.QNetworkReply") def test_sendMissingMaterials_withBadJsonAnswer(self, reply_mock, device_mock): reply_mock.attribute.return_value = 200 reply_mock.readAll.return_value = QByteArray(b'Six sick hicks nick six slick bricks with picks and sticks.') - SendMaterialJob(device_mock).run() - reply_mock.attribute.assert_called_with(0) - self.assertEqual(reply_mock.method_calls, [call.attribute(0), call.readAll()]) - self.assertEqual(device_mock._onGetRemoteMaterials.method_calls, []) + job = SendMaterialJob(device_mock) + job._onGetRemoteMaterials(reply_mock) + + # We expect the reply to be called once to try to get the printers from the list (readAll()). + # Given that the parsing there fails we do no expect the device to be called for any follow up. + self.assertEqual([call.attribute(0), call.readAll()], reply_mock.method_calls) + self.assertEqual([], device_mock.method_calls) # @patch("PyQt5.QtNetwork.QNetworkReply") # def test_sendMissingMaterials_withMissingGuid(self, reply_mock): From 7a210087ff0aa8c34ebe7438bc744136b3afab64 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 19 Nov 2018 14:35:34 +0100 Subject: [PATCH 0263/1292] Add header for configuration selector It currently always says 'Custom', but we will want to make that dynamic at some point. Contributes to issue CURA-5876. --- .../QuickConfigurationSelector.qml | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml index 33610135fe..d84298ee2e 100644 --- a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml +++ b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml @@ -12,6 +12,10 @@ import UM 1.2 as UM import Cura 1.0 as Cura +/** + * Menu that allows you to select the configuration of the current printer, such + * as the nozzle sizes and materials in each extruder. + */ Cura.ExpandableComponent { id: base @@ -99,10 +103,27 @@ Cura.ExpandableComponent width: base.width - 2 * UM.Theme.getSize("default_margin").width height: 200 + Label + { + id: customHeader + text: catalog.i18nc("@header", "Custom") + font: UM.Theme.getFont("large") + color: UM.Theme.getColor("text") + + anchors + { + top: parent.top + left: parent.left + right: parent.right + } + } + TabBar { id: tabBar onCurrentIndexChanged: Cura.ExtruderManager.setActiveExtruderIndex(currentIndex) + anchors.top: customHeader.bottom + anchors.topMargin: UM.Theme.getSize("default_margin").height width: parent.width height: 50 Repeater From 00a49fff26fac675207d30b6131f2d4869474197 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 19 Nov 2018 14:39:19 +0100 Subject: [PATCH 0264/1292] Rename QuickConfigurationSelector to ConfigurationMenu This is going to function as our main item for the configuration menu. It contains the part in the top bar and the glue item for the part in the popup. Contributes to issue CURA-5876. --- plugins/PrepareStage/PrepareMenu.qml | 2 +- .../{QuickConfigurationSelector.qml => ConfigurationMenu.qml} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename resources/qml/Menus/ConfigurationMenu/{QuickConfigurationSelector.qml => ConfigurationMenu.qml} (100%) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index ef01625a22..6b241e1da2 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -68,7 +68,7 @@ Item color: UM.Theme.getColor("lining") } - Cura.QuickConfigurationSelector + Cura.ConfigurationMenu { Layout.fillHeight: true Layout.fillWidth: true diff --git a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml similarity index 100% rename from resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml rename to resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml From 0b1ac87354d53457dcfba0f927e749639a7600a0 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 19 Nov 2018 15:03:43 +0100 Subject: [PATCH 0265/1292] Fix some formatting, cleanup import --- .../UM3NetworkPrinting/src/SendMaterialJob.py | 9 +++-- .../tests/TestSendMaterialJob.py | 36 ++++++++----------- 2 files changed, 19 insertions(+), 26 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py index 572558e352..62414763b6 100644 --- a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py @@ -48,10 +48,10 @@ class SendMaterialJob(Job): try: remote_materials_by_guid = self._parseReply(reply) self._sendMissingMaterials(remote_materials_by_guid) - except json.JSONDecodeError as e: - Logger.log("e", "Error parsing materials from printer: %s", e) - except KeyError as e: - Logger.log("e", "Error parsing materials from printer: %s", e) + except json.JSONDecodeError: + Logger.logException("w", "Error parsing materials from printer") + except KeyError: + Logger.logException("w", "Error parsing materials from printer") ## Determine which materials should be updated and send them to the printer. # @@ -157,7 +157,6 @@ class SendMaterialJob(Job): @classmethod def _parseReply(cls, reply: QNetworkReply) -> Dict[str, ClusterMaterial]: remote_materials_list = json.loads(reply.readAll().data().decode("utf-8")) - print("remote_materials_list", remote_materials_list) return {material["guid"]: ClusterMaterial(**material) for material in remote_materials_list} ## Retrieves a list of local materials diff --git a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py index b51d978ed2..0e907f58eb 100644 --- a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py @@ -1,19 +1,13 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -import io -import json from typing import Any, List -from unittest import TestCase, mock +from unittest import TestCase from unittest.mock import patch, call from PyQt5.QtCore import QByteArray -from UM.Logger import Logger -from UM.MimeTypeDatabase import MimeType -from UM.Settings.ContainerRegistry import ContainerInterface, ContainerRegistryInterface, \ - DefinitionContainerInterface, ContainerRegistry +from UM.Settings.ContainerRegistry import ContainerInterface, ContainerRegistryInterface, DefinitionContainerInterface from plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice import ClusterUM3OutputDevice -from plugins.UM3NetworkPrinting.src.Models import ClusterMaterial from plugins.UM3NetworkPrinting.src.SendMaterialJob import SendMaterialJob @@ -45,7 +39,7 @@ class ContainerRegistryMock(ContainerRegistryInterface): return self.containersMetaData -class FakeDevice(ClusterUM3OutputDevice): +class MockOutputDevice(ClusterUM3OutputDevice): def _createFormPart(self, content_header, data, content_type=None): return "xxx" @@ -53,20 +47,20 @@ class FakeDevice(ClusterUM3OutputDevice): class TestSendMaterialJob(TestCase): _LOCAL_MATERIAL_WHITE = {'type': 'material', 'status': 'unknown', 'id': 'generic_pla_white', - 'base_file': 'generic_pla_white', 'setting_version': 5, 'name': 'White PLA', - 'brand': 'Generic', 'material': 'PLA', 'color_name': 'White', - 'GUID': 'badb0ee7-87c8-4f3f-9398-938587b67dce', 'version': '1', 'color_code': '#ffffff', - 'description': 'Test PLA White', 'adhesion_info': 'Use glue.', 'approximate_diameter': '3', - 'properties': {'density': '1.00', 'diameter': '2.85', 'weight': '750'}, - 'definition': 'fdmprinter', 'compatible': True} + 'base_file': 'generic_pla_white', 'setting_version': 5, 'name': 'White PLA', + 'brand': 'Generic', 'material': 'PLA', 'color_name': 'White', + 'GUID': 'badb0ee7-87c8-4f3f-9398-938587b67dce', 'version': '1', 'color_code': '#ffffff', + 'description': 'Test PLA White', 'adhesion_info': 'Use glue.', 'approximate_diameter': '3', + 'properties': {'density': '1.00', 'diameter': '2.85', 'weight': '750'}, + 'definition': 'fdmprinter', 'compatible': True} _LOCAL_MATERIAL_BLACK = {'type': 'material', 'status': 'unknown', 'id': 'generic_pla_black', - 'base_file': 'generic_pla_black', 'setting_version': 5, 'name': 'Yellow CPE', - 'brand': 'Ultimaker', 'material': 'CPE', 'color_name': 'Black', - 'GUID': '5fbb362a-41f9-4818-bb43-15ea6df34aa4', 'version': '1', 'color_code': '#000000', - 'description': 'Test PLA Black', 'adhesion_info': 'Use glue.', 'approximate_diameter': '3', - 'properties': {'density': '1.01', 'diameter': '2.85', 'weight': '750'}, - 'definition': 'fdmprinter', 'compatible': True} + 'base_file': 'generic_pla_black', 'setting_version': 5, 'name': 'Yellow CPE', + 'brand': 'Ultimaker', 'material': 'CPE', 'color_name': 'Black', + 'GUID': '5fbb362a-41f9-4818-bb43-15ea6df34aa4', 'version': '1', 'color_code': '#000000', + 'description': 'Test PLA Black', 'adhesion_info': 'Use glue.', 'approximate_diameter': '3', + 'properties': {'density': '1.01', 'diameter': '2.85', 'weight': '750'}, + 'definition': 'fdmprinter', 'compatible': True} _REMOTE_MATERIAL_WHITE = { "guid": "badb0ee7-87c8-4f3f-9398-938587b67dce", From d65114bd5652398bf9b3fae91dc38b53fae0e35f Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 19 Nov 2018 15:08:58 +0100 Subject: [PATCH 0266/1292] use call_count to assert device was not called --- .../tests/TestSendMaterialJob.py | 20 ++----------------- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py index 0e907f58eb..9b1e1066ba 100644 --- a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py @@ -97,7 +97,7 @@ class TestSendMaterialJob(TestCase): # We expect the error string to be retrieved and the device not to be called for any follow up. self.assertEqual([call.attribute(0), call.errorString()], reply_mock.method_calls) - self.assertEqual([], device_mock.method_calls) + self.assertEqual(0, device_mock.call_count) @patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") @patch("PyQt5.QtNetwork.QNetworkReply") @@ -110,7 +110,7 @@ class TestSendMaterialJob(TestCase): # We expect the reply to be called once to try to get the printers from the list (readAll()). # Given that the parsing there fails we do no expect the device to be called for any follow up. self.assertEqual([call.attribute(0), call.readAll()], reply_mock.method_calls) - self.assertEqual([], device_mock.method_calls) + self.assertEqual(0, device_mock.call_count) # @patch("PyQt5.QtNetwork.QNetworkReply") # def test_sendMissingMaterials_withMissingGuid(self, reply_mock): @@ -274,19 +274,3 @@ class TestSendMaterialJob(TestCase): # # self.assertTrue(len(local_materials) == 1) # self.assertTrue(list(local_materials.values())[0].version == 2) - # - # def _assertLogEntries(self, first, second): - # """ - # Inspects the two sets of log entry tuples and fails when they are not the same - # :param first: The first set of tuples - # :param second: The second set of tuples - # """ - # self.assertEqual(len(first), len(second)) - # - # while len(first) > 0: - # e1, m1 = first[0] - # e2, m2 = second[0] - # self.assertEqual(e1, e2) - # self.assertEqual(m1, m2) - # first.pop(0) - # second.pop(0) From 9d8583a3b67682442d0ab4383bdf748770105af2 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 19 Nov 2018 15:10:35 +0100 Subject: [PATCH 0267/1292] Revert "Fix running tests in plugin using pytest" This reverts commit f8f133d2ef92dfabb636eac70b09e681bd4b4d63. --- .../tests/TestLegacyProfileReader.py | 9 ++++----- .../tests/TestVersionUpgrade25to26.py | 11 +++-------- .../tests/TestVersionUpgrade26to27.py | 9 ++++----- .../tests/TestVersionUpgrade27to30.py | 8 ++++---- .../tests/TestVersionUpgrade34to35.py | 10 ++++------ 5 files changed, 19 insertions(+), 28 deletions(-) diff --git a/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py b/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py index 3c9e46b6d8..480a61f301 100644 --- a/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py +++ b/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py @@ -1,7 +1,8 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. + import configparser # An input for some functions we're testing. -import os # To find the integration test .ini files. +import os.path # To find the integration test .ini files. import pytest # To register tests with. import unittest.mock # To mock the application, plug-in and container registry out. @@ -10,15 +11,13 @@ import UM.PluginRegistry # To mock the plug-in registry out. import UM.Settings.ContainerRegistry # To mock the container registry out. import UM.Settings.InstanceContainer # To intercept the serialised data from the read() function. -import plugins.LegacyProfileReader.LegacyProfileReader as LegacyProfileReaderModule -from plugins.LegacyProfileReader.LegacyProfileReader import LegacyProfileReader - +import LegacyProfileReader as LegacyProfileReaderModule # To get the directory of the module. +from LegacyProfileReader import LegacyProfileReader # The module we're testing. @pytest.fixture def legacy_profile_reader(): return LegacyProfileReader() - test_prepareDefaultsData = [ { "defaults": diff --git a/plugins/VersionUpgrade/VersionUpgrade25to26/tests/TestVersionUpgrade25to26.py b/plugins/VersionUpgrade/VersionUpgrade25to26/tests/TestVersionUpgrade25to26.py index 588c0cb3db..9d7c7646cc 100644 --- a/plugins/VersionUpgrade/VersionUpgrade25to26/tests/TestVersionUpgrade25to26.py +++ b/plugins/VersionUpgrade/VersionUpgrade25to26/tests/TestVersionUpgrade25to26.py @@ -1,17 +1,16 @@ # Copyright (c) 2017 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -import configparser -import pytest -from plugins.VersionUpgrade.VersionUpgrade25to26 import VersionUpgrade25to26 +import configparser #To check whether the appropriate exceptions are raised. +import pytest #To register tests with. +import VersionUpgrade25to26 #The module we're testing. ## Creates an instance of the upgrader to test with. @pytest.fixture def upgrader(): return VersionUpgrade25to26.VersionUpgrade25to26() - test_cfg_version_good_data = [ { "test_name": "Simple", @@ -61,7 +60,6 @@ setting_version = -3 } ] - ## Tests the technique that gets the version number from CFG files. # # \param data The parametrised data to test with. It contains a test name @@ -118,7 +116,6 @@ version = 1.2 } ] - ## Tests whether getting a version number from bad CFG files gives an # exception. # @@ -158,7 +155,6 @@ foo = bar } ] - ## Tests whether the settings that should be removed are removed for the 2.6 # version of preferences. @pytest.mark.parametrize("data", test_upgrade_preferences_removed_settings_data) @@ -204,7 +200,6 @@ type = instance_container } ] - ## Tests whether the settings that should be removed are removed for the 2.6 # version of instance containers. @pytest.mark.parametrize("data", test_upgrade_instance_container_removed_settings_data) diff --git a/plugins/VersionUpgrade/VersionUpgrade26to27/tests/TestVersionUpgrade26to27.py b/plugins/VersionUpgrade/VersionUpgrade26to27/tests/TestVersionUpgrade26to27.py index 45d41e7a1b..eebaca23c6 100644 --- a/plugins/VersionUpgrade/VersionUpgrade26to27/tests/TestVersionUpgrade26to27.py +++ b/plugins/VersionUpgrade/VersionUpgrade26to27/tests/TestVersionUpgrade26to27.py @@ -1,16 +1,15 @@ # Copyright (c) 2017 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -import configparser -import pytest -from plugins.VersionUpgrade.VersionUpgrade26to27.VersionUpgrade26to27 import VersionUpgrade26to27 +import configparser #To check whether the appropriate exceptions are raised. +import pytest #To register tests with. +import VersionUpgrade26to27 #The module we're testing. ## Creates an instance of the upgrader to test with. @pytest.fixture def upgrader(): - return VersionUpgrade26to27() - + return VersionUpgrade26to27.VersionUpgrade26to27() test_cfg_version_good_data = [ { diff --git a/plugins/VersionUpgrade/VersionUpgrade27to30/tests/TestVersionUpgrade27to30.py b/plugins/VersionUpgrade/VersionUpgrade27to30/tests/TestVersionUpgrade27to30.py index 7b77b85993..cae08ebcfd 100644 --- a/plugins/VersionUpgrade/VersionUpgrade27to30/tests/TestVersionUpgrade27to30.py +++ b/plugins/VersionUpgrade/VersionUpgrade27to30/tests/TestVersionUpgrade27to30.py @@ -1,15 +1,15 @@ # Copyright (c) 2017 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -import configparser -import pytest -from plugins.VersionUpgrade.VersionUpgrade27to30.VersionUpgrade27to30 import VersionUpgrade27to30 +import configparser #To parse the resulting config files. +import pytest #To register tests with. +import VersionUpgrade27to30 #The module we're testing. ## Creates an instance of the upgrader to test with. @pytest.fixture def upgrader(): - return VersionUpgrade27to30() + return VersionUpgrade27to30.VersionUpgrade27to30() test_cfg_version_good_data = [ { diff --git a/plugins/VersionUpgrade/VersionUpgrade34to35/tests/TestVersionUpgrade34to35.py b/plugins/VersionUpgrade/VersionUpgrade34to35/tests/TestVersionUpgrade34to35.py index 4f77fcd093..b74e6f35ac 100644 --- a/plugins/VersionUpgrade/VersionUpgrade34to35/tests/TestVersionUpgrade34to35.py +++ b/plugins/VersionUpgrade/VersionUpgrade34to35/tests/TestVersionUpgrade34to35.py @@ -1,16 +1,15 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -import configparser -import pytest -from plugins.VersionUpgrade.VersionUpgrade34to35.VersionUpgrade34to35 import VersionUpgrade34to35 +import configparser #To parse the resulting config files. +import pytest #To register tests with. +import VersionUpgrade34to35 #The module we're testing. ## Creates an instance of the upgrader to test with. @pytest.fixture def upgrader(): - return VersionUpgrade34to35() - + return VersionUpgrade34to35.VersionUpgrade34to35() test_upgrade_version_nr_data = [ ("Empty config file", @@ -26,7 +25,6 @@ test_upgrade_version_nr_data = [ ) ] - ## Tests whether the version numbers are updated. @pytest.mark.parametrize("test_name, file_data", test_upgrade_version_nr_data) def test_upgradeVersionNr(test_name, file_data, upgrader): From 66fbadf2dea2a734a4055b8f866b5397303b2069 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 19 Nov 2018 15:37:56 +0100 Subject: [PATCH 0268/1292] Convert all single quotes to double quotes --- .../tests/TestSendMaterialJob.py | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py index 9b1e1066ba..22e96f5ed0 100644 --- a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py @@ -46,21 +46,21 @@ class MockOutputDevice(ClusterUM3OutputDevice): class TestSendMaterialJob(TestCase): - _LOCAL_MATERIAL_WHITE = {'type': 'material', 'status': 'unknown', 'id': 'generic_pla_white', - 'base_file': 'generic_pla_white', 'setting_version': 5, 'name': 'White PLA', - 'brand': 'Generic', 'material': 'PLA', 'color_name': 'White', - 'GUID': 'badb0ee7-87c8-4f3f-9398-938587b67dce', 'version': '1', 'color_code': '#ffffff', - 'description': 'Test PLA White', 'adhesion_info': 'Use glue.', 'approximate_diameter': '3', - 'properties': {'density': '1.00', 'diameter': '2.85', 'weight': '750'}, - 'definition': 'fdmprinter', 'compatible': True} + _LOCAL_MATERIAL_WHITE = {"type": "material", "status": "unknown", "id": "generic_pla_white", + "base_file": "generic_pla_white", "setting_version": 5, "name": "White PLA", + "brand": "Generic", "material": "PLA", "color_name": "White", + "GUID": "badb0ee7-87c8-4f3f-9398-938587b67dce", "version": "1", "color_code": "#ffffff", + "description": "Test PLA White", "adhesion_info": "Use glue.", "approximate_diameter": "3", + "properties": {"density": "1.00", "diameter": "2.85", "weight": "750"}, + "definition": "fdmprinter", "compatible": True} - _LOCAL_MATERIAL_BLACK = {'type': 'material', 'status': 'unknown', 'id': 'generic_pla_black', - 'base_file': 'generic_pla_black', 'setting_version': 5, 'name': 'Yellow CPE', - 'brand': 'Ultimaker', 'material': 'CPE', 'color_name': 'Black', - 'GUID': '5fbb362a-41f9-4818-bb43-15ea6df34aa4', 'version': '1', 'color_code': '#000000', - 'description': 'Test PLA Black', 'adhesion_info': 'Use glue.', 'approximate_diameter': '3', - 'properties': {'density': '1.01', 'diameter': '2.85', 'weight': '750'}, - 'definition': 'fdmprinter', 'compatible': True} + _LOCAL_MATERIAL_BLACK = {"type": "material", "status": "unknown", "id": "generic_pla_black", + "base_file": "generic_pla_black", "setting_version": 5, "name": "Yellow CPE", + "brand": "Ultimaker", "material": "CPE", "color_name": "Black", + "GUID": "5fbb362a-41f9-4818-bb43-15ea6df34aa4", "version": "1", "color_code": "#000000", + "description": "Test PLA Black", "adhesion_info": "Use glue.", "approximate_diameter": "3", + "properties": {"density": "1.01", "diameter": "2.85", "weight": "750"}, + "definition": "fdmprinter", "compatible": True} _REMOTE_MATERIAL_WHITE = { "guid": "badb0ee7-87c8-4f3f-9398-938587b67dce", @@ -103,7 +103,7 @@ class TestSendMaterialJob(TestCase): @patch("PyQt5.QtNetwork.QNetworkReply") def test_sendMissingMaterials_withBadJsonAnswer(self, reply_mock, device_mock): reply_mock.attribute.return_value = 200 - reply_mock.readAll.return_value = QByteArray(b'Six sick hicks nick six slick bricks with picks and sticks.') + reply_mock.readAll.return_value = QByteArray(b"Six sick hicks nick six slick bricks with picks and sticks.") job = SendMaterialJob(device_mock) job._onGetRemoteMaterials(reply_mock) @@ -119,13 +119,13 @@ class TestSendMaterialJob(TestCase): # del remoteMaterialWithoutGuid["guid"] # reply_mock.readAll.return_value = QByteArray(json.dumps([remoteMaterialWithoutGuid]).encode("ascii")) # - # with mock.patch.object(Logger, 'log', new=new_log): + # with mock.patch.object(Logger, "log", new=new_log): # SendMaterialJob(None).sendMissingMaterials(reply_mock) # # reply_mock.attribute.assert_called_with(0) # self.assertEqual(reply_mock.method_calls, [call.attribute(0), call.readAll()]) # self._assertLogEntries( - # [('e', "Request material storage on printer: Printer's answer was missing GUIDs.")], + # [("e", "Request material storage on printer: Printer"s answer was missing GUIDs.")], # _logentries) # # @patch("UM.Resources.Resources.getAllResourcesOfType", lambda _: []) @@ -145,7 +145,7 @@ class TestSendMaterialJob(TestCase): # # reply_mock.attribute.assert_called_with(0) # self.assertEqual(reply_mock.method_calls, [call.attribute(0), call.readAll()]) - # self._assertLogEntries([('e', "Material generic_pla_white has invalid version number one.")], _logentries) + # self._assertLogEntries([("e", "Material generic_pla_white has invalid version number one.")], _logentries) # # @patch("UM.Resources.Resources.getAllResourcesOfType", lambda _: []) # @patch("PyQt5.QtNetwork.QNetworkReply") @@ -194,16 +194,16 @@ class TestSendMaterialJob(TestCase): # device_mock._createFormPart.return_value = "_xXx_" # with mock.patch.object(Logger, "log", new=new_log): # job = SendMaterialJob(device_mock) - # job.sendMaterialsToPrinter({'generic_pla_white'}) + # job.sendMaterialsToPrinter({"generic_pla_white"}) # # self._assertLogEntries([("d", "Syncing material generic_pla_white with cluster.")], _logentries) - # self.assertEqual([call._createFormPart('name="file"; filename="generic_pla_white.xml.fdm_material"', ''), + # self.assertEqual([call._createFormPart("name="file"; filename="generic_pla_white.xml.fdm_material"", ""), # call.postFormWithParts(on_finished=job.sendingFinished, parts = ["_xXx_"], target = "materials/")], device_mock.method_calls) # # @patch("PyQt5.QtNetwork.QNetworkReply") # def test_sendingFinished_success(self, reply_mock) -> None: # reply_mock.attribute.return_value = 200 - # with mock.patch.object(Logger, 'log', new=new_log): + # with mock.patch.object(Logger, "log", new=new_log): # SendMaterialJob(None).sendingFinished(reply_mock) # # reply_mock.attribute.assert_called_once_with(0) @@ -212,9 +212,9 @@ class TestSendMaterialJob(TestCase): # @patch("PyQt5.QtNetwork.QNetworkReply") # def test_sendingFinished_failed(self, reply_mock) -> None: # reply_mock.attribute.return_value = 404 - # reply_mock.readAll.return_value = QByteArray(b'Six sick hicks nick six slick bricks with picks and sticks.') + # reply_mock.readAll.return_value = QByteArray(b"Six sick hicks nick six slick bricks with picks and sticks.") # - # with mock.patch.object(Logger, 'log', new=new_log): + # with mock.patch.object(Logger, "log", new=new_log): # SendMaterialJob(None).sendingFinished(reply_mock) # # reply_mock.attribute.assert_called_with(0) From 60dd1303936a09c83a562067c9a8193c2f3d5e43 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 19 Nov 2018 15:39:12 +0100 Subject: [PATCH 0269/1292] Use logException where possible --- plugins/UM3NetworkPrinting/src/SendMaterialJob.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py index 62414763b6..6260752f3f 100644 --- a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py @@ -175,10 +175,7 @@ class SendMaterialJob(Job): material = LocalMaterial(**m) if material.GUID not in result or material.version > result.get(material.GUID).version: result[material.GUID] = material - except ValueError as e: - Logger.log("w", "Local material {material_id} has invalid values: {e}".format( - material_id = m["id"], - e = e - )) + except ValueError: + Logger.logException("w", "Local material {} has invalid values.".format(m["id"])) return result From c04ce7fce8df24298c1708a044ebfa4afee8a411 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 19 Nov 2018 15:44:07 +0100 Subject: [PATCH 0270/1292] Use call_count on specific method to be more precise --- plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py index 22e96f5ed0..a71ded75b6 100644 --- a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py @@ -97,7 +97,7 @@ class TestSendMaterialJob(TestCase): # We expect the error string to be retrieved and the device not to be called for any follow up. self.assertEqual([call.attribute(0), call.errorString()], reply_mock.method_calls) - self.assertEqual(0, device_mock.call_count) + self.assertEqual(0, device_mock.createFormPart.call_count) @patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") @patch("PyQt5.QtNetwork.QNetworkReply") @@ -110,7 +110,7 @@ class TestSendMaterialJob(TestCase): # We expect the reply to be called once to try to get the printers from the list (readAll()). # Given that the parsing there fails we do no expect the device to be called for any follow up. self.assertEqual([call.attribute(0), call.readAll()], reply_mock.method_calls) - self.assertEqual(0, device_mock.call_count) + self.assertEqual(0, device_mock.createFormPart.call_count) # @patch("PyQt5.QtNetwork.QNetworkReply") # def test_sendMissingMaterials_withMissingGuid(self, reply_mock): From 8683a1e07e5adc60e0be272eb4b6871d92f8c1ef Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 19 Nov 2018 16:16:41 +0100 Subject: [PATCH 0271/1292] Add previewStage to bundled cura package list CURA-5785 --- resources/bundled_packages/cura.json | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/resources/bundled_packages/cura.json b/resources/bundled_packages/cura.json index ee82b17a75..678ea0a697 100644 --- a/resources/bundled_packages/cura.json +++ b/resources/bundled_packages/cura.json @@ -356,6 +356,23 @@ } } }, + "PreviewStage": { + "package_info": { + "package_id": "PreviewStage", + "package_type": "plugin", + "display_name": "Preview Stage", + "description": "Provides a preview stage in Cura.", + "package_version": "1.0.0", + "sdk_version": 5, + "website": "https://ultimaker.com", + "author": { + "author_id": "UltimakerPackages", + "display_name": "Ultimaker B.V.", + "email": "plugins@ultimaker.com", + "website": "https://ultimaker.com" + } + } + }, "RemovableDriveOutputDevice": { "package_info": { "package_id": "RemovableDriveOutputDevice", From df38e7db8511a400fc90ba8b14213951107026d2 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 19 Nov 2018 16:31:15 +0100 Subject: [PATCH 0272/1292] Do not allow the user to activate a material if the printer is not defined to have materials. Contributes to #4550. --- resources/qml/Preferences/Materials/MaterialsPage.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Preferences/Materials/MaterialsPage.qml b/resources/qml/Preferences/Materials/MaterialsPage.qml index a00a2340cd..18e1adf381 100644 --- a/resources/qml/Preferences/Materials/MaterialsPage.qml +++ b/resources/qml/Preferences/Materials/MaterialsPage.qml @@ -83,7 +83,7 @@ Item { text: catalog.i18nc("@action:button", "Activate") iconName: "list-activate" - enabled: !isCurrentItemActivated + enabled: !isCurrentItemActivated && Cura.MachineManager.hasMaterials() onClicked: { forceActiveFocus() From 2497325d606a9246bb383fa87e2dc1707f99e321 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 19 Nov 2018 16:35:19 +0100 Subject: [PATCH 0273/1292] Test with named tuples, not working yet --- plugins/UM3NetworkPrinting/src/Models.py | 111 +++++------------- .../UM3NetworkPrinting/src/SendMaterialJob.py | 14 +-- .../tests/TestSendMaterialJob.py | 35 +++--- 3 files changed, 53 insertions(+), 107 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Models.py b/plugins/UM3NetworkPrinting/src/Models.py index 89bf665377..e8efa577f6 100644 --- a/plugins/UM3NetworkPrinting/src/Models.py +++ b/plugins/UM3NetworkPrinting/src/Models.py @@ -1,87 +1,32 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import Optional +from collections import namedtuple +ClusterMaterial = namedtuple('ClusterMaterial', [ + 'guid', + 'material', + 'brand', + 'version', + 'color', + 'density' +]) -class BaseModel: - def __init__(self, **kwargs): - self.__dict__.update(kwargs) - - def __eq__(self, other): - return self.__dict__ == other.__dict__ if type(self) == type(other) else False - - -## Represents an item in the cluster API response for installed materials. -class ClusterMaterial(BaseModel): - def __init__(self, **kwargs): - super().__init__(**kwargs) - self.version = int(self.version) - self.density = float(self.density) - - guid = None # type: Optional[str] - - material = None # type: Optional[str] - - brand = None # type: Optional[str] - - version = None # type: Optional[int] - - color = None # type: Optional[str] - - density = None # type: Optional[float] - - -class LocalMaterialProperties(BaseModel): - def __init__(self, **kwargs): - super().__init__(**kwargs) - self.density = float(self.density) - self.diameter = float(self.diameter) - self.weight = float(self.weight) - - density = None # type: Optional[float] - - diameter = None # type: Optional[float] - - weight = None # type: Optional[int] - - -class LocalMaterial(BaseModel): - def __init__(self, **kwargs): - super().__init__(**kwargs) - self.properties = LocalMaterialProperties(**self.properties) - self.approximate_diameter = float(self.approximate_diameter) - self.version = int(self.version) - - GUID = None # type: Optional[str] - - id = None # type: Optional[str] - - type = None # type: Optional[str] - - status = None # type: Optional[str] - - base_file = None # type: Optional[str] - - setting_version = None # type: Optional[str] - - version = None # type: Optional[int] - - name = None # type: Optional[str] - - brand = None # type: Optional[str] - - material = None # type: Optional[str] - - color_name = None # type: Optional[str] - - description = None # type: Optional[str] - - adhesion_info = None # type: Optional[str] - - approximate_diameter = None # type: Optional[float] - - properties = None # type: LocalMaterialProperties - - definition = None # type: Optional[str] - - compatible = None # type: Optional[bool] +LocalMaterial = namedtuple('LocalMaterial', [ + 'GUID', + 'id', + 'type', + 'status', + 'base_file', + 'setting_version', + 'version', + 'name', + 'brand', + 'material', + 'color_name', + 'description', + 'adhesion_info', + 'approximate_diameter', + 'properties', + 'definition', + 'compatible' +]) diff --git a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py index 6260752f3f..cbe79aef6a 100644 --- a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py @@ -156,8 +156,8 @@ class SendMaterialJob(Job): # \throw KeyError Raised when on of the materials does not include a valid guid @classmethod def _parseReply(cls, reply: QNetworkReply) -> Dict[str, ClusterMaterial]: - remote_materials_list = json.loads(reply.readAll().data().decode("utf-8")) - return {material["guid"]: ClusterMaterial(**material) for material in remote_materials_list} + remote_materials = json.loads(reply.readAll().data().decode("utf-8")) + return {material["id"]: ClusterMaterial(**material) for material in remote_materials} ## Retrieves a list of local materials # @@ -170,12 +170,12 @@ class SendMaterialJob(Job): material_containers = container_registry.findContainersMetadata(type = "material") # Find the latest version of all material containers in the registry. - for m in material_containers: + local_materials = {} # type: Dict[str, LocalMaterial] + for material in material_containers: try: - material = LocalMaterial(**m) + material = LocalMaterial(**material) if material.GUID not in result or material.version > result.get(material.GUID).version: - result[material.GUID] = material + local_materials[material.GUID] = material except ValueError: - Logger.logException("w", "Local material {} has invalid values.".format(m["id"])) - + Logger.logException("w", "Local material {} has invalid values.".format(material["id"])) return result diff --git a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py index a71ded75b6..73bca2b0ad 100644 --- a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py @@ -1,5 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +import json + from typing import Any, List from unittest import TestCase from unittest.mock import patch, call @@ -108,26 +110,25 @@ class TestSendMaterialJob(TestCase): job._onGetRemoteMaterials(reply_mock) # We expect the reply to be called once to try to get the printers from the list (readAll()). - # Given that the parsing there fails we do no expect the device to be called for any follow up. + # Given that the parsing fails we do no expect the device to be called for any follow up. self.assertEqual([call.attribute(0), call.readAll()], reply_mock.method_calls) self.assertEqual(0, device_mock.createFormPart.call_count) - # @patch("PyQt5.QtNetwork.QNetworkReply") - # def test_sendMissingMaterials_withMissingGuid(self, reply_mock): - # reply_mock.attribute.return_value = 200 - # remoteMaterialWithoutGuid = self._REMOTEMATERIAL_WHITE.copy() - # del remoteMaterialWithoutGuid["guid"] - # reply_mock.readAll.return_value = QByteArray(json.dumps([remoteMaterialWithoutGuid]).encode("ascii")) - # - # with mock.patch.object(Logger, "log", new=new_log): - # SendMaterialJob(None).sendMissingMaterials(reply_mock) - # - # reply_mock.attribute.assert_called_with(0) - # self.assertEqual(reply_mock.method_calls, [call.attribute(0), call.readAll()]) - # self._assertLogEntries( - # [("e", "Request material storage on printer: Printer"s answer was missing GUIDs.")], - # _logentries) - # + @patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") + @patch("PyQt5.QtNetwork.QNetworkReply") + def test_sendMissingMaterials_withMissingGuid(self, reply_mock, device_mock): + reply_mock.attribute.return_value = 200 + remote_material_without_guid = self._REMOTE_MATERIAL_WHITE.copy() + del remote_material_without_guid["guid"] + reply_mock.readAll.return_value = QByteArray(json.dumps([remote_material_without_guid]).encode("ascii")) + job = SendMaterialJob(device_mock) + job._onGetRemoteMaterials(reply_mock) + + # We expect the reply to be called once to try to get the printers from the list (readAll()). + # Given that parsing fails we do not expect the device to be called for any follow up. + self.assertEqual([call.attribute(0), call.readAll()], reply_mock.method_calls) + self.assertEqual(1, device_mock.createFormPart.call_count) + # @patch("UM.Resources.Resources.getAllResourcesOfType", lambda _: []) # @patch("PyQt5.QtNetwork.QNetworkReply") # def test_sendMissingMaterials_WithInvalidVersionInLocalMaterial(self, reply_mock): From fa39ba913220b5df91b2949c3ea3e580754c6e49 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 19 Nov 2018 16:37:12 +0100 Subject: [PATCH 0274/1292] Fix typo. Remove parenthesis. --- resources/qml/Preferences/Materials/MaterialsPage.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Preferences/Materials/MaterialsPage.qml b/resources/qml/Preferences/Materials/MaterialsPage.qml index 18e1adf381..9118f16b4d 100644 --- a/resources/qml/Preferences/Materials/MaterialsPage.qml +++ b/resources/qml/Preferences/Materials/MaterialsPage.qml @@ -83,7 +83,7 @@ Item { text: catalog.i18nc("@action:button", "Activate") iconName: "list-activate" - enabled: !isCurrentItemActivated && Cura.MachineManager.hasMaterials() + enabled: !isCurrentItemActivated && Cura.MachineManager.hasMaterials onClicked: { forceActiveFocus() From 421a64c7b0ff712ed8c5103641bda03c257df3da Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 19 Nov 2018 16:42:36 +0100 Subject: [PATCH 0275/1292] Replace queued print job cards with new design Contributes to CL-1148 --- .../resources/qml/ClusterMonitorItem.qml | 52 +++------ .../resources/qml/ExpandableCard.qml | 81 +++++++++++++ .../resources/qml/MonitorPrintJobCard.qml | 109 ++++++++++++++++++ .../resources/qml/MonitorPrintJobPreview.qml | 67 +++++++++++ 4 files changed, 272 insertions(+), 37 deletions(-) create mode 100644 plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml create mode 100644 plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml create mode 100644 plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml diff --git a/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml b/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml index d210ab40f3..ff4bc72218 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml @@ -6,13 +6,15 @@ import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.3 as UM import Cura 1.0 as Cura +import QtGraphicalEffects 1.0 Component { + Rectangle { id: monitorFrame; property var emphasisColor: UM.Theme.getColor("setting_control_border_highlight"); property var cornerRadius: UM.Theme.getSize("monitor_corner_radius").width; - color: UM.Theme.getColor("viewport_background"); + color: transparent height: maximumHeight; onVisibleChanged: { if (monitorFrame != null && !monitorFrame.visible) { @@ -21,6 +23,14 @@ Component { } width: maximumWidth; + LinearGradient { + anchors.fill: parent + gradient: Gradient { + GradientStop { position: 0.0; color: "#f6f6f6" } + GradientStop { position: 1.0; color: "#ffffff" } + } + } + UM.I18nCatalog { id: catalog; name: "cura"; @@ -60,39 +70,6 @@ Component { text: catalog.i18nc("@label", "Queued"); } - Column { - id: skeletonLoader; - anchors { - bottom: parent.bottom; - bottomMargin: UM.Theme.getSize("default_margin").height; - horizontalCenter: parent.horizontalCenter; - top: queuedLabel.bottom; - topMargin: UM.Theme.getSize("default_margin").height; - } - visible: !queuedPrintJobs.visible; - width: Math.min(800 * screenScaleFactor, maximumWidth); - - PrintJobInfoBlock { - anchors { - left: parent.left; - leftMargin: UM.Theme.getSize("default_margin").width; - right: parent.right; - rightMargin: UM.Theme.getSize("default_margin").width; - } - printJob: null; // Use as skeleton - } - - PrintJobInfoBlock { - anchors { - left: parent.left; - leftMargin: UM.Theme.getSize("default_margin").width; - right: parent.right; - rightMargin: UM.Theme.getSize("default_margin").width; - } - printJob: null; // Use as skeleton - } - } - ScrollView { id: queuedPrintJobs; anchors { @@ -104,12 +81,12 @@ Component { } style: UM.Theme.styles.scrollview; visible: OutputDevice.receivedPrintJobs; - width: Math.min(800 * screenScaleFactor, maximumWidth); + width: Math.min(834 * screenScaleFactor, maximumWidth); ListView { id: printJobList; anchors.fill: parent; - delegate: PrintJobInfoBlock { + delegate: MonitorPrintJobCard { anchors { left: parent.left; leftMargin: UM.Theme.getSize("default_margin").width; @@ -119,7 +96,7 @@ Component { printJob: modelData; } model: OutputDevice.queuedPrintJobs; - spacing: UM.Theme.getSize("default_margin").height - 2 * UM.Theme.getSize("monitor_shadow_radius").width; + spacing: 6; } } @@ -129,4 +106,5 @@ Component { visible: OutputDevice.activeCameraUrl != ""; } } + } diff --git a/plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml b/plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml new file mode 100644 index 0000000000..89d88d671a --- /dev/null +++ b/plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml @@ -0,0 +1,81 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 2.0 +import UM 1.3 as UM +import Cura 1.0 as Cura + +// The expandable component has 3 major sub components: +// * The headerItem Always visible and should hold some info about what happens if the component is expanded +// * The popupItem The content that needs to be shown if the component is expanded. +Item +{ + id: base + + property var expanded: false + property var borderWidth: 1 + property color borderColor: "#EAEAEC" + property color headerBackgroundColor: "white" + property color headerHoverColor: "#f5f5f5" + property color drawerBackgroundColor: "white" + property alias headerItem: header.children + property alias drawerItem: drawer.children + + width: parent.width + height: childrenRect.height + + Rectangle + { + id: header + border + { + color: borderColor + width: borderWidth + } + color: headerMouseArea.containsMouse ? headerHoverColor : headerBackgroundColor + height: childrenRect.height + width: parent.width + Behavior on color + { + ColorAnimation + { + duration: 100 + } + } + } + + MouseArea + { + id: headerMouseArea + anchors.fill: header + onClicked: base.expanded = !base.expanded + hoverEnabled: true + } + + Rectangle + { + id: drawer + anchors + { + top: header.bottom + topMargin: -1 + } + border + { + color: borderColor + width: borderWidth + } + clip: true + color: headerBackgroundColor + height: base.expanded ? childrenRect.height : 0 + width: parent.width + Behavior on height + { + NumberAnimation + { + duration: 100 + } + } + } +} \ No newline at end of file diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml new file mode 100644 index 0000000000..307a4f908f --- /dev/null +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml @@ -0,0 +1,109 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 2.0 +import UM 1.3 as UM +import Cura 1.0 as Cura + +// A Print Job Card is essentially just a filled-in Expandable Card item. +Item +{ + id: base + property var printJob: null + + width: parent.width + height: childrenRect.height + + ExpandableCard + { + headerItem: Row + { + height: 48 + anchors.left: parent.left + anchors.leftMargin: 24 + spacing: 18 + + MonitorPrintJobPreview + { + printJob: base.printJob + size: 32 + anchors.verticalCenter: parent.verticalCenter + } + + Label + { + text: printJob && printJob.name ? printJob.name : "" + color: "#374355" + elide: Text.ElideRight + font: UM.Theme.getFont("default_bold") + anchors.verticalCenter: parent.verticalCenter + width: 216 + height: 18 + } + + Label + { + text: printJob ? OutputDevice.formatDuration(printJob.timeTotal) : "" + color: "#374355" + elide: Text.ElideRight + font: UM.Theme.getFont("default_bold") + anchors.verticalCenter: parent.verticalCenter + width: 216 + height: 18 + } + + Label + { + color: "#374355" + height: 18 + elide: Text.ElideRight + font: UM.Theme.getFont("default_bold") + text: { + if (printJob !== null) { + if (printJob.assignedPrinter == null) + { + if (printJob.state == "error") + { + return catalog.i18nc("@label", "Waiting for: Unavailable printer") + } + return catalog.i18nc("@label", "Waiting for: First available") + } + else + { + return catalog.i18nc("@label", "Waiting for: ") + printJob.assignedPrinter.name + } + } + return "" + } + visible: printJob + anchors.verticalCenter: parent.verticalCenter + width: 216 + } + } + drawerItem: Row + { + height: 96 + anchors.left: parent.left + anchors.leftMargin: 74 + spacing: 18 + + Rectangle + { + id: printerConfiguration + width: 450 + height: 72 + color: "blue" + anchors.verticalCenter: parent.verticalCenter + } + Label { + height: 18 + text: printJob && printJob.owner ? printJob.owner : "" + color: "#374355" + elide: Text.ElideRight + font: UM.Theme.getFont("default_bold") + anchors.top: printerConfiguration.top + } + } + } +} \ No newline at end of file diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml new file mode 100644 index 0000000000..7322193451 --- /dev/null +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml @@ -0,0 +1,67 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Dialogs 1.1 +import QtQuick.Controls 2.0 +import QtQuick.Controls.Styles 1.4 +import QtGraphicalEffects 1.0 +import QtQuick.Layouts 1.1 +import QtQuick.Dialogs 1.1 +import UM 1.3 as UM + +Item +{ + id: printJobPreview + + property var printJob: null + property var size: 256 + + width: size + height: size + + // Actual content + Image + { + id: previewImage + anchors.fill: parent + opacity: printJob && printJob.state == "error" ? 0.5 : 1.0 + source: printJob ? printJob.previewImageUrl : "" + visible: printJob + } + + UM.RecolorImage + { + id: ultiBotImage + + anchors.centerIn: printJobPreview + color: UM.Theme.getColor("monitor_placeholder_image") + height: printJobPreview.height + source: "../svg/ultibot.svg" + sourceSize + { + height: height + width: width + } + /* Since print jobs ALWAYS have an image url, we have to check if that image URL errors or + not in order to determine if we show the placeholder (ultibot) image instead. */ + visible: printJob && previewImage.status == Image.Error + width: printJobPreview.width + } + + UM.RecolorImage + { + id: statusImage + anchors.centerIn: printJobPreview + color: UM.Theme.getColor("monitor_image_overlay") + height: 0.5 * printJobPreview.height + source: printJob && printJob.state == "error" ? "../svg/aborted-icon.svg" : "" + sourceSize + { + height: height + width: width + } + visible: source != "" + width: 0.5 * printJobPreview.width + } +} \ No newline at end of file From 2b88e82a2a520761ede661ba0843a77b5269b1c1 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 19 Nov 2018 16:52:02 +0100 Subject: [PATCH 0276/1292] Add option test-verbose build option to CuraTests --- cmake/CuraTests.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmake/CuraTests.cmake b/cmake/CuraTests.cmake index f2ee92d65b..b6d04de036 100644 --- a/cmake/CuraTests.cmake +++ b/cmake/CuraTests.cmake @@ -6,6 +6,8 @@ include(CMakeParseArguments) find_package(PythonInterp 3.5.0 REQUIRED) +add_custom_target(test-verbose COMMAND ${CMAKE_CTEST_COMMAND} --verbose) + function(cura_add_test) set(_single_args NAME DIRECTORY PYTHONPATH) cmake_parse_arguments("" "" "${_single_args}" "" ${ARGN}) From 16deeb09510b4bbaa6bc2c7b4ca7b939aa904caf Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 19 Nov 2018 17:10:29 +0100 Subject: [PATCH 0277/1292] Remove old QuickConfigurationSelector It doesn't exist any more. Contributes to issue CURA-5876. --- resources/qml/qmldir | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/qml/qmldir b/resources/qml/qmldir index d5e4106d33..878945b922 100644 --- a/resources/qml/qmldir +++ b/resources/qml/qmldir @@ -1,7 +1,6 @@ module Cura MachineSelector 1.0 MachineSelector.qml -QuickConfigurationSelector 1.0 QuickConfigurationSelector.qml CustomConfigurationSelector 1.0 CustomConfigurationSelector.qml PrintSetupSelector 1.0 PrintSetupSelector.qml ActionButton 1.0 ActionButton.qml From a04db164e6a0679ca684dd65ff33c50b9355a242 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 19 Nov 2018 17:11:51 +0100 Subject: [PATCH 0278/1292] Make it possible to swap between auto and custom configuration We're going to need to make this disappear when the printer is not connected. But that is for later. Contributes to issue CURA-5876. --- .../ConfigurationMenu/AutoConfiguration.qml | 25 +++ .../ConfigurationMenu/ConfigurationMenu.qml | 207 ++++++------------ .../ConfigurationMenu/CustomConfiguration.qml | 168 ++++++++++++++ 3 files changed, 263 insertions(+), 137 deletions(-) create mode 100644 resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml create mode 100644 resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml diff --git a/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml new file mode 100644 index 0000000000..e1f0ed480e --- /dev/null +++ b/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml @@ -0,0 +1,25 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.0 + +import UM 1.3 as UM + +Item +{ + Label + { + id: header + text: catalog.i18nc("@header", "Configurations") + font: UM.Theme.getFont("large") + color: UM.Theme.getColor("text") + + anchors + { + top: parent.top + left: parent.left + right: parent.right + } + } +} \ No newline at end of file diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index d84298ee2e..10c52a7b0f 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -6,8 +6,6 @@ import QtQuick.Controls 2.0 import QtQuick.Controls.Styles 1.4 import QtQuick.Layouts 1.11 -import QtQuick.Controls 1.1 as OldControls - import UM 1.2 as UM import Cura 1.0 as Cura @@ -100,163 +98,98 @@ Cura.ExpandableComponent popupItem: Item { + id: popup width: base.width - 2 * UM.Theme.getSize("default_margin").width height: 200 - Label - { - id: customHeader - text: catalog.i18nc("@header", "Custom") - font: UM.Theme.getFont("large") - color: UM.Theme.getColor("text") + property var configuration_method: "auto" + AutoConfiguration + { + id: autoConfiguration + visible: popup.configuration_method === "auto" + anchors.top: header.bottom + height: visible ? childrenRect.height : 0 + } + + CustomConfiguration + { + id: customConfiguration + visible: popup.configuration_method === "custom" + anchors.top: header.bottom + height: visible ? childrenRect.height : 0 + } + + Rectangle + { + id: separator anchors { - top: parent.top left: parent.left right: parent.right + bottom: buttonBar.top + bottomMargin: UM.Theme.getSize("default_margin").height } + height: UM.Theme.getSize("default_lining").height + color: UM.Theme.getColor("lining") } - TabBar + Rectangle { - id: tabBar - onCurrentIndexChanged: Cura.ExtruderManager.setActiveExtruderIndex(currentIndex) - anchors.top: customHeader.bottom - anchors.topMargin: UM.Theme.getSize("default_margin").height - width: parent.width - height: 50 - Repeater + id: buttonBar + anchors { - model: extrudersModel - - delegate: TabButton - { - width: ListView.view != null ? Math.round(ListView.view.width / extrudersModel.rowCount()): 0 - height: parent.height - contentItem: Item - { - Cura.ExtruderIcon - { - anchors.horizontalCenter: parent.horizontalCenter - materialColor: model.color - extruderEnabled: model.enabled - width: parent.height - height: parent.height - } - } - } + left: parent.left + right: parent.right + bottom: parent.bottom } - } + height: childrenRect.height - Item - { - id: tabControl - width: parent.width - anchors.top: tabBar.bottom - anchors.bottom: parent.bottom - property var model: extrudersModel.items[tabBar.currentIndex] - property real textWidth: Math.round(width * 0.3) - property real controlWidth: width - textWidth - Column + Cura.ActionButton { - spacing: UM.Theme.getSize("default_margin").height - Row + id: goToCustom + visible: popup.configuration_method === "auto" + text: catalog.i18nc("@label", "Custom") + + anchors { - height: UM.Theme.getSize("print_setup_item").height - - Label - { - text: catalog.i18nc("@label", "Enabled") - verticalAlignment: Text.AlignVCenter - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - height: parent.height - width: tabControl.textWidth - } - - OldControls.CheckBox - { - checked: tabControl.model != null ? Cura.MachineManager.getExtruder(tabControl.model.index).isEnabled: false - onClicked: Cura.MachineManager.setExtruderEnabled(tabControl.model.index, checked) - height: UM.Theme.getSize("setting_control").height - style: UM.Theme.styles.checkbox - } + right: parent.right + bottom: parent.bottom } - Row - { - height: UM.Theme.getSize("print_setup_item").height - Label - { - text: catalog.i18nc("@label", "Material") - verticalAlignment: Text.AlignVCenter - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - height: parent.height - width: tabControl.textWidth - } + color: UM.Theme.getColor("secondary") + hoverColor: UM.Theme.getColor("secondary") + textColor: UM.Theme.getColor("primary") + textHoverColor: UM.Theme.getColor("text") + height: UM.Theme.getSize("action_panel_button").height + leftPadding: UM.Theme.getSize("default_margin").width + rightPadding: UM.Theme.getSize("default_margin").width - OldControls.ToolButton - { - id: materialSelection - - property var activeExtruder: Cura.MachineManager.activeStack - property var hasActiveExtruder: activeExtruder != null - property var currentRootMaterialName: hasActiveExtruder ? activeExtruder.material.name : "" - property var valueError: hasActiveExtruder ? Cura.ContainerManager.getContainerMetaDataEntry(activeExtruder.material.id, "compatible", "") != "True" : true - property var valueWarning: ! Cura.MachineManager.isActiveQualitySupported - - text: currentRootMaterialName - tooltip: currentRootMaterialName - visible: Cura.MachineManager.hasMaterials - - enabled: Cura.ExtruderManager.activeExtruderIndex > -1 - - height: UM.Theme.getSize("setting_control").height - width: tabControl.controlWidth - - style: UM.Theme.styles.sidebar_header_button - activeFocusOnPress: true - menu: Cura.MaterialMenu - { - extruderIndex: Cura.ExtruderManager.activeExtruderIndex - } - - } - } - - Row - { - height: UM.Theme.getSize("print_setup_item").height - - Label - { - text: Cura.MachineManager.activeDefinitionVariantsName - verticalAlignment: Text.AlignVCenter - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - height: parent.height - width: tabControl.textWidth - } - - OldControls.ToolButton - { - id: variantSelection - text: Cura.MachineManager.activeVariantName - tooltip: Cura.MachineManager.activeVariantName; - visible: Cura.MachineManager.hasVariants - - height: UM.Theme.getSize("setting_control").height - width: tabControl.controlWidth - style: UM.Theme.styles.sidebar_header_button - activeFocusOnPress: true; - - menu: Cura.NozzleMenu { extruderIndex: Cura.ExtruderManager.activeExtruderIndex } - } - } + onClicked: popup.configuration_method = "custom" } + Cura.ActionButton + { + id: goToAuto + visible: popup.configuration_method === "custom" + text: catalog.i18nc("@label", "Configurations") + + anchors + { + left: parent.left + bottom: parent.bottom + } + + color: UM.Theme.getColor("secondary") + hoverColor: UM.Theme.getColor("secondary") + textColor: UM.Theme.getColor("primary") + textHoverColor: UM.Theme.getColor("text") + height: UM.Theme.getSize("action_panel_button").height + leftPadding: UM.Theme.getSize("default_margin").width + rightPadding: UM.Theme.getSize("default_margin").width + + onClicked: popup.configuration_method = "auto" + } } } } diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml new file mode 100644 index 0000000000..953b6a48f0 --- /dev/null +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -0,0 +1,168 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.0 +import QtQuick.Controls 2.0 +import QtQuick.Controls 1.1 as OldControls + +import Cura 1.0 as Cura +import UM 1.3 as UM + +Item +{ + Label + { + id: header + text: catalog.i18nc("@header", "Custom") + font: UM.Theme.getFont("large") + color: UM.Theme.getColor("text") + + anchors + { + top: parent.top + left: parent.left + right: parent.right + } + } + + TabBar + { + id: tabBar + onCurrentIndexChanged: Cura.ExtruderManager.setActiveExtruderIndex(currentIndex) + anchors.top: header.bottom + anchors.topMargin: UM.Theme.getSize("default_margin").height + width: parent.width + height: 50 + Repeater + { + model: extrudersModel + + delegate: TabButton + { + width: ListView.view != null ? Math.round(ListView.view.width / extrudersModel.rowCount()): 0 + height: parent.height + contentItem: Item + { + Cura.ExtruderIcon + { + anchors.horizontalCenter: parent.horizontalCenter + materialColor: model.color + extruderEnabled: model.enabled + width: parent.height + height: parent.height + } + } + } + } + } + + Item + { + id: tabControl + width: parent.width + anchors.top: tabBar.bottom + anchors.bottom: parent.bottom + property var model: extrudersModel.items[tabBar.currentIndex] + property real textWidth: Math.round(width * 0.3) + property real controlWidth: width - textWidth + Column + { + spacing: UM.Theme.getSize("default_margin").height + Row + { + height: UM.Theme.getSize("print_setup_item").height + + Label + { + text: catalog.i18nc("@label", "Enabled") + verticalAlignment: Text.AlignVCenter + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + height: parent.height + width: tabControl.textWidth + } + + OldControls.CheckBox + { + checked: tabControl.model != null ? Cura.MachineManager.getExtruder(tabControl.model.index).isEnabled: false + onClicked: Cura.MachineManager.setExtruderEnabled(tabControl.model.index, checked) + height: UM.Theme.getSize("setting_control").height + style: UM.Theme.styles.checkbox + } + } + + Row + { + height: UM.Theme.getSize("print_setup_item").height + Label + { + text: catalog.i18nc("@label", "Material") + verticalAlignment: Text.AlignVCenter + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + height: parent.height + width: tabControl.textWidth + } + + OldControls.ToolButton + { + id: materialSelection + + property var activeExtruder: Cura.MachineManager.activeStack + property var hasActiveExtruder: activeExtruder != null + property var currentRootMaterialName: hasActiveExtruder ? activeExtruder.material.name : "" + property var valueError: hasActiveExtruder ? Cura.ContainerManager.getContainerMetaDataEntry(activeExtruder.material.id, "compatible", "") != "True" : true + property var valueWarning: ! Cura.MachineManager.isActiveQualitySupported + + text: currentRootMaterialName + tooltip: currentRootMaterialName + visible: Cura.MachineManager.hasMaterials + + enabled: Cura.ExtruderManager.activeExtruderIndex > -1 + + height: UM.Theme.getSize("setting_control").height + width: tabControl.controlWidth + + style: UM.Theme.styles.sidebar_header_button + activeFocusOnPress: true + menu: Cura.MaterialMenu + { + extruderIndex: Cura.ExtruderManager.activeExtruderIndex + } + + } + } + + Row + { + height: UM.Theme.getSize("print_setup_item").height + + Label + { + text: Cura.MachineManager.activeDefinitionVariantsName + verticalAlignment: Text.AlignVCenter + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + height: parent.height + width: tabControl.textWidth + } + + OldControls.ToolButton + { + id: variantSelection + text: Cura.MachineManager.activeVariantName + tooltip: Cura.MachineManager.activeVariantName; + visible: Cura.MachineManager.hasVariants + + height: UM.Theme.getSize("setting_control").height + width: tabControl.controlWidth + style: UM.Theme.styles.sidebar_header_button + activeFocusOnPress: true; + + menu: Cura.NozzleMenu { extruderIndex: Cura.ExtruderManager.activeExtruderIndex } + } + } + } + + } +} \ No newline at end of file From 69ca7c0f893fa5f1d9af88526ddad2c796255b17 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 19 Nov 2018 20:08:05 +0100 Subject: [PATCH 0279/1292] CloudOutputDevice scaffolding --- .../src/Cloud/CloudOutputController.py | 18 +++ .../src/Cloud/CloudOutputDevice.py | 134 ++++++++++++++++++ .../UM3NetworkPrinting/src/Cloud/__init__.py | 0 plugins/UM3NetworkPrinting/src/__init__.py | 0 plugins/__init__.py | 0 5 files changed, 152 insertions(+) create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/CloudOutputController.py create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/__init__.py create mode 100644 plugins/UM3NetworkPrinting/src/__init__.py create mode 100644 plugins/__init__.py diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputController.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputController.py new file mode 100644 index 0000000000..d31d2bf486 --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputController.py @@ -0,0 +1,18 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +from cura.PrinterOutput.PrinterOutputController import PrinterOutputController + + +class CloudOutputController(PrinterOutputController): + def __init__(self, output_device): + super().__init__(output_device) + + # The cloud connection only supports fetching the printer and queue status and adding a job to the queue. + # To let the UI know this we mark all features below as False. + self.can_pause = False + self.can_abort = False + self.can_pre_heat_bed = False + self.can_pre_heat_hotends = False + self.can_send_raw_gcode = False + self.can_control_manually = False + self.can_update_firmware = False diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py new file mode 100644 index 0000000000..850eb11ed2 --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -0,0 +1,134 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +import json +from typing import List, Optional, Dict + +from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal +from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest + +from UM import i18nCatalog +from UM.FileHandler.FileHandler import FileHandler +from UM.Logger import Logger +from UM.Scene.SceneNode import SceneNode +from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice, AuthState +from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel +from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputController import CloudOutputController +from plugins.UM3NetworkPrinting.src.UM3PrintJobOutputModel import UM3PrintJobOutputModel + + +## The cloud output device is a network output device that works remotely but has limited functionality. +# Currently it only supports viewing the printer and print job status and adding a new job to the queue. +# As such, those methods have been implemented here. +# Note that this device represents a single remote cluster, not a list of multiple clusters. +# +# TODO: figure our how the QML interface for the cluster networking should operate with this limited functionality. +# TODO: figure out how to pair remote clusters, local networked clusters and local cura printer presets. +class CloudOutputDevice(NetworkedPrinterOutputDevice): + + # The translation catalog for this device. + I18N_CATALOG = i18nCatalog("cura") + + # The cloud URL to use for remote clusters. + API_ROOT_PATH_FORMAT = "https://api.ultimaker.com/connect/clusters/{cluster_id}" + + # Signal triggered when the printers in the remote cluster were changed. + printersChanged = pyqtSignal() + + # Signal triggered when the print jobs in the queue were changed. + printJobsChanged = pyqtSignal() + + def __init__(self, device_id: str, address: str, properties: Dict[bytes, bytes], parent: QObject = None): + super().__init__(device_id = device_id, address = address, properties = properties, parent = parent) + self._setInterfaceElements() + + # The API prefix is automatically added when doing any HTTP call on the device. + self._api_prefix = self.API_ROOT_PATH_FORMAT.format(device_id) # TODO: verify we can use device_id here + self._authentication_state = AuthState.Authenticated # TODO: use cura.API.Account to set this? + + # Properties to populate later on with received cloud data. + self._printers = [] + self._print_jobs = [] + self._number_of_extruders = 2 # All networked printers are dual-extrusion Ultimaker machines. + + ## Set all the interface elements and texts for this output device. + def _setInterfaceElements(self): + self.setPriority(3) + self.setName(self._id) + # TODO: how to name these? + self.setShortDescription(self.I18N_CATALOG.i18nc("@action:button", "Print via Cloud")) + self.setDescription(self.I18N_CATALOG.i18nc("@properties:tooltip", "Print via Cloud")) + self.setConnectionText(self.I18N_CATALOG.i18nc("@info:status", "Connected via Cloud")) + + ## Called when Cura requests an output device to receive a (G-code) file. + def requestWrite(self, nodes: List[SceneNode], file_name: Optional[str] = None, limit_mime_types: bool = False, + file_handler: Optional[FileHandler] = None, **kwargs: str) -> None: + self.writeStarted.emit(self) + + # TODO: actually implement this + self._addPrintJobToQueue() + + ## Get remote printers. + @pyqtProperty("QVariantList", notify = printersChanged) + def printers(self): + return self._printers + + ## Get remote print jobs. + @pyqtProperty("QVariantList", notify = printJobsChanged) + def printJobs(self) -> List[UM3PrintJobOutputModel]: + return self._print_jobs + + ## Called when the connection to the cluster changes. + def connect(self) -> None: + super().connect() + + ## Called when the network data should be updated. + def _update(self) -> None: + super()._update() + self.get("/status", on_finished = self._onStatusCallFinished) + + def _onStatusCallFinished(self, reply: QNetworkReply) -> None: + status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) + if status_code != 200: + Logger.log("w", "Got unexpected response while trying to get cloud cluster data: {}, {}" + .format(status_code, reply.getErrorString())) + return + + data = self._parseStatusResponse(reply) + if data is None: + return + + # Update all data from the cluster. + self._updatePrinters(data.get("printers", [])) + self._updatePrintJobs(data.get("print_jobs", [])) + + @staticmethod + def _parseStatusResponse(reply: QNetworkReply) -> Optional[dict]: + try: + result = json.loads(bytes(reply.readAll()).decode("utf-8")) + # TODO: use model or named tuple here. + return result + except json.decoder.JSONDecodeError: + Logger.logException("w", "Unable to decode JSON from reply.") + return None + + def _updatePrinters(self, remote_printers: List[Dict[str, any]]) -> None: + # TODO: use model or tuple for remote_printers data + for printer in remote_printers: + + # If the printer does not exist yet, create it. + if not self._getPrinterByKey(printer["uuid"]): + self._printers.append(PrinterOutputModel( + output_controller = CloudOutputController(self), + number_of_extruders = self._number_of_extruders + )) + + # TODO: properly handle removed and updated printers + self.printersChanged.emit() + + def _updatePrintJobs(self, remote_print_jobs: List[Dict[str, any]]) -> None: + # TODO: use model or tuple for remote_print_jobs data + pass + + def _addPrintJobToQueue(self): + # TODO: implement this + pass diff --git a/plugins/UM3NetworkPrinting/src/Cloud/__init__.py b/plugins/UM3NetworkPrinting/src/Cloud/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/plugins/UM3NetworkPrinting/src/__init__.py b/plugins/UM3NetworkPrinting/src/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/plugins/__init__.py b/plugins/__init__.py new file mode 100644 index 0000000000..e69de29bb2 From 115936c46bb08cec4f4c02193edea7b5f0db0f32 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 19 Nov 2018 20:27:38 +0100 Subject: [PATCH 0280/1292] Target correct cloud API version --- plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 850eb11ed2..75cef817c6 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -29,7 +29,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): I18N_CATALOG = i18nCatalog("cura") # The cloud URL to use for remote clusters. - API_ROOT_PATH_FORMAT = "https://api.ultimaker.com/connect/clusters/{cluster_id}" + API_ROOT_PATH_FORMAT = "https://api.ultimaker.com/connect/v1/clusters/{cluster_id}" # Signal triggered when the printers in the remote cluster were changed. printersChanged = pyqtSignal() From 228325eb892ee43d1173a296797e277505c3bd52 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 19 Nov 2018 21:59:57 +0100 Subject: [PATCH 0281/1292] Add CloudOutputDeviceManager, test implementation --- .../NetworkedPrinterOutputDevice.py | 1 + plugins/UM3NetworkPrinting/__init__.py | 8 +++-- .../src/Cloud/CloudOutputDevice.py | 30 +++++++++++++----- .../src/Cloud/CloudOutputDeviceManager.py | 31 +++++++++++++++++++ .../src/UM3OutputDevicePlugin.py | 25 ++++++++++----- 5 files changed, 78 insertions(+), 17 deletions(-) create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py diff --git a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py index 9a3be936a2..9a6892ce4d 100644 --- a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py +++ b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py @@ -17,6 +17,7 @@ from enum import IntEnum import os # To get the username import gzip + class AuthState(IntEnum): NotAuthenticated = 1 AuthenticationRequested = 2 diff --git a/plugins/UM3NetworkPrinting/__init__.py b/plugins/UM3NetworkPrinting/__init__.py index e2ad5a2b12..23262aed94 100644 --- a/plugins/UM3NetworkPrinting/__init__.py +++ b/plugins/UM3NetworkPrinting/__init__.py @@ -1,11 +1,15 @@ # Copyright (c) 2017 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. - from .src import DiscoverUM3Action from .src import UM3OutputDevicePlugin + def getMetaData(): return {} + def register(app): - return { "output_device": UM3OutputDevicePlugin.UM3OutputDevicePlugin(), "machine_action": DiscoverUM3Action.DiscoverUM3Action()} \ No newline at end of file + return { + "output_device": UM3OutputDevicePlugin.UM3OutputDevicePlugin(app), + "machine_action": DiscoverUM3Action.DiscoverUM3Action() + } diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 75cef817c6..61d22052be 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -3,13 +3,14 @@ import json from typing import List, Optional, Dict -from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal +from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, QUrl from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest from UM import i18nCatalog from UM.FileHandler.FileHandler import FileHandler from UM.Logger import Logger from UM.Scene.SceneNode import SceneNode +from cura.CuraApplication import CuraApplication from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice, AuthState from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputController import CloudOutputController @@ -37,19 +38,34 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # Signal triggered when the print jobs in the queue were changed. printJobsChanged = pyqtSignal() - def __init__(self, device_id: str, address: str, properties: Dict[bytes, bytes], parent: QObject = None): - super().__init__(device_id = device_id, address = address, properties = properties, parent = parent) + def __init__(self, device_id: str, parent: QObject = None): + super().__init__(device_id = device_id, address = "", properties = {}, parent = parent) self._setInterfaceElements() - # The API prefix is automatically added when doing any HTTP call on the device. - self._api_prefix = self.API_ROOT_PATH_FORMAT.format(device_id) # TODO: verify we can use device_id here - self._authentication_state = AuthState.Authenticated # TODO: use cura.API.Account to set this? + self._device_id = device_id + self._account = CuraApplication.getInstance().getCuraAPI().account # Properties to populate later on with received cloud data. self._printers = [] self._print_jobs = [] self._number_of_extruders = 2 # All networked printers are dual-extrusion Ultimaker machines. + ## We need to override _createEmptyRequest to work for the cloud. + def _createEmptyRequest(self, path: str, content_type: Optional[str] = "application/json") -> QNetworkRequest: + url = QUrl(self.API_ROOT_PATH_FORMAT.format(cluster_id = self._device_id) + path) + request = QNetworkRequest(url) + request.setHeader(QNetworkRequest.ContentTypeHeader, content_type) + request.setHeader(QNetworkRequest.UserAgentHeader, self._user_agent) + + if not self._account.isLoggedIn: + # TODO: show message to user to sign in + self.setAuthenticationState(AuthState.NotAuthenticated) + else: + self.setAuthenticationState(AuthState.Authenticated) + request.setRawHeader(b"Authorization", "Bearer {}".format(self._account.accessToken).encode()) + + return request + ## Set all the interface elements and texts for this output device. def _setInterfaceElements(self): self.setPriority(3) @@ -90,7 +106,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) if status_code != 200: Logger.log("w", "Got unexpected response while trying to get cloud cluster data: {}, {}" - .format(status_code, reply.getErrorString())) + .format(status_code, reply.readAll())) return data = self._parseStatusResponse(reply) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py new file mode 100644 index 0000000000..1f75edc2cc --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -0,0 +1,31 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +from typing import TYPE_CHECKING + +from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputDevice import CloudOutputDevice + + +if TYPE_CHECKING: + from cura.CuraApplication import CuraApplication + + +## The cloud output device manager is responsible for using the Ultimaker Cloud APIs to manage remote clusters. +# Keeping all cloud related logic in this class instead of the UM3OutputDevicePlugin results in more readable code. +class CloudOutputDeviceManager: + + def __init__(self, application: "CuraApplication"): + self._output_device_manager = application.getOutputDeviceManager() + self._account = application.getCuraAPI().account + self._getRemoteClusters() + + # For testing: + application.globalContainerStackChanged.connect(self._addCloudOutputDevice) + + def _getRemoteClusters(self): + # TODO: get list of remote clusters and create an output device for each. + pass + + def _addCloudOutputDevice(self): + device = CloudOutputDevice("xxxx-xxxx-xxxx-xxxx") + self._output_device_manager.addOutputDevice(device) + device.connect() diff --git a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py index 9c070f2de2..d7a40626b9 100644 --- a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py +++ b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py @@ -1,11 +1,12 @@ # Copyright (c) 2017 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +from typing import TYPE_CHECKING from UM.OutputDevice.OutputDevicePlugin import OutputDevicePlugin from UM.Logger import Logger -from UM.Application import Application from UM.Signal import Signal, signalemitter from UM.Version import Version +from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputDeviceManager import CloudOutputDeviceManager from . import ClusterUM3OutputDevice, LegacyUM3OutputDevice @@ -19,6 +20,9 @@ from time import time import json +if TYPE_CHECKING: + from cura.CuraApplication import CuraApplication + ## This plugin handles the connection detection & creation of output device objects for the UM3 printer. # Zero-Conf is used to detect printers, which are saved in a dict. @@ -29,8 +33,10 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): removeDeviceSignal = Signal() discoveredDevicesChanged = Signal() - def __init__(self): + def __init__(self, application: "CuraApplication"): super().__init__() + self._application = application + self._zero_conf = None self._zero_conf_browser = None @@ -38,7 +44,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): self.addDeviceSignal.connect(self._onAddDevice) self.removeDeviceSignal.connect(self._onRemoveDevice) - Application.getInstance().globalContainerStackChanged.connect(self.reCheckConnections) + application.globalContainerStackChanged.connect(self.reCheckConnections) self._discovered_devices = {} @@ -53,7 +59,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): self._cluster_api_prefix = "/cluster-api/v" + self._cluster_api_version + "/" # Get list of manual instances from preferences - self._preferences = Application.getInstance().getPreferences() + self._preferences = self._application.getPreferences() self._preferences.addPreference("um3networkprinting/manual_instances", "") # A comma-separated list of ip adresses or hostnames @@ -70,6 +76,9 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): self._service_changed_request_event = Event() self._service_changed_request_thread = Thread(target=self._handleOnServiceChangedRequests, daemon=True) self._service_changed_request_thread.start() + + # Create a cloud output device manager that abstract all cloud connection logic away. + self._cloud_output_device_manager = CloudOutputDeviceManager(self._application) def getDiscoveredDevices(self): return self._discovered_devices @@ -104,7 +113,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): self.resetLastManualDevice() def reCheckConnections(self): - active_machine = Application.getInstance().getGlobalContainerStack() + active_machine = self._application.getGlobalContainerStack() if not active_machine: return @@ -129,7 +138,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): return if self._discovered_devices[key].isConnected(): # Sometimes the status changes after changing the global container and maybe the device doesn't belong to this machine - um_network_key = Application.getInstance().getGlobalContainerStack().getMetaDataEntry("um_network_key") + um_network_key = self._application.getGlobalContainerStack().getMetaDataEntry("um_network_key") if key == um_network_key: self.getOutputDeviceManager().addOutputDevice(self._discovered_devices[key]) else: @@ -281,7 +290,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): self._discovered_devices[device.getId()] = device self.discoveredDevicesChanged.emit() - global_container_stack = Application.getInstance().getGlobalContainerStack() + global_container_stack = self._application.getGlobalContainerStack() if global_container_stack and device.getId() == global_container_stack.getMetaDataEntry("um_network_key"): device.connect() device.connectionStateChanged.connect(self._onDeviceConnectionStateChanged) @@ -299,7 +308,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): self._service_changed_request_event.wait(timeout = 5.0) # Stop if the application is shutting down - if Application.getInstance().isShuttingDown(): + if self._application.isShuttingDown(): return self._service_changed_request_event.clear() From 10576d12426ae520f42167d3dcc2afa7ffd808d9 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 19 Nov 2018 22:24:35 +0100 Subject: [PATCH 0282/1292] Some scaffolding and implementation for cloud output device manager --- .../src/Cloud/CloudOutputDevice.py | 9 ++-- .../src/Cloud/CloudOutputDeviceManager.py | 42 +++++++++++++++---- .../src/UM3OutputDevicePlugin.py | 6 +-- 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 61d22052be..ff83c3fd5e 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -23,14 +23,13 @@ from plugins.UM3NetworkPrinting.src.UM3PrintJobOutputModel import UM3PrintJobOut # Note that this device represents a single remote cluster, not a list of multiple clusters. # # TODO: figure our how the QML interface for the cluster networking should operate with this limited functionality. -# TODO: figure out how to pair remote clusters, local networked clusters and local cura printer presets. class CloudOutputDevice(NetworkedPrinterOutputDevice): # The translation catalog for this device. I18N_CATALOG = i18nCatalog("cura") - # The cloud URL to use for remote clusters. - API_ROOT_PATH_FORMAT = "https://api.ultimaker.com/connect/v1/clusters/{cluster_id}" + # The cloud URL to use for this remote cluster. + API_ROOT_PATH_FORMAT = "https://api-staging.ultimaker.com/connect/v1/clusters/{cluster_id}" # Signal triggered when the printers in the remote cluster were changed. printersChanged = pyqtSignal() @@ -79,8 +78,6 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def requestWrite(self, nodes: List[SceneNode], file_name: Optional[str] = None, limit_mime_types: bool = False, file_handler: Optional[FileHandler] = None, **kwargs: str) -> None: self.writeStarted.emit(self) - - # TODO: actually implement this self._addPrintJobToQueue() ## Get remote printers. @@ -102,6 +99,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): super()._update() self.get("/status", on_finished = self._onStatusCallFinished) + ## Method called when HTTP request to status endpoint is finished. + # Contains both printers and print jobs statuses in a single response. def _onStatusCallFinished(self, reply: QNetworkReply) -> None: status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) if status_code != 200: diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 1f75edc2cc..53f64241e5 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -1,6 +1,6 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Dict from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputDevice import CloudOutputDevice @@ -11,21 +11,47 @@ if TYPE_CHECKING: ## The cloud output device manager is responsible for using the Ultimaker Cloud APIs to manage remote clusters. # Keeping all cloud related logic in this class instead of the UM3OutputDevicePlugin results in more readable code. +# +# TODO: figure out how to pair remote clusters, local networked clusters and local cura printer presets. class CloudOutputDeviceManager: + # The cloud URL to use for remote clusters. + API_ROOT_PATH = "https://api-staging.ultimaker.com/connect/v1" + def __init__(self, application: "CuraApplication"): + self._application = application self._output_device_manager = application.getOutputDeviceManager() self._account = application.getCuraAPI().account - self._getRemoteClusters() - # For testing: - application.globalContainerStackChanged.connect(self._addCloudOutputDevice) + # Persistent dict containing the remote clusters for the authenticated user. + self._remote_clusters = {} # type: Dict[str, CloudOutputDevice] + + # When switching machines we check if we have to activate a remote cluster. + self._application.globalContainerStackChanged.connect(self._activeMachineChanged) + + # Fetch all remote clusters for the authenticated user. + self._getRemoteClusters() def _getRemoteClusters(self): # TODO: get list of remote clusters and create an output device for each. - pass + # For testing we add a dummy device: + self._addCloudOutputDevice({"cluster_id": "LJ0tciiuZZjarrXAvFLEZ6ox4Cvx8FvtXUlQv4vIhV6w"}) - def _addCloudOutputDevice(self): - device = CloudOutputDevice("xxxx-xxxx-xxxx-xxxx") + def _addCloudOutputDevice(self, cluster_data: Dict[str, any]): + # TODO: use model or named tuple for cluster_data + device = CloudOutputDevice(cluster_data["cluster_id"]) self._output_device_manager.addOutputDevice(device) - device.connect() + self._remote_clusters[cluster_data["cluster_id"]] = device + + def _activeMachineChanged(self): + active_machine = self._application.getGlobalContainerStack() + if not active_machine: + return + + stored_cluster_id = active_machine.getMetaDataEntry("um_cloud_cluster_id") + if stored_cluster_id not in self._remote_clusters.keys(): + # Currently authenticated user does not have access to stored cluster or no user is signed in. + return + + # We found the active machine as remote cluster so let's connect to it. + self._remote_clusters.get(stored_cluster_id).connect() diff --git a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py index d7a40626b9..b441df9eb5 100644 --- a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py +++ b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py @@ -40,6 +40,9 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): self._zero_conf = None self._zero_conf_browser = None + # Create a cloud output device manager that abstract all cloud connection logic away. + self._cloud_output_device_manager = CloudOutputDeviceManager(self._application) + # Because the model needs to be created in the same thread as the QMLEngine, we use a signal. self.addDeviceSignal.connect(self._onAddDevice) self.removeDeviceSignal.connect(self._onRemoveDevice) @@ -76,9 +79,6 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): self._service_changed_request_event = Event() self._service_changed_request_thread = Thread(target=self._handleOnServiceChangedRequests, daemon=True) self._service_changed_request_thread.start() - - # Create a cloud output device manager that abstract all cloud connection logic away. - self._cloud_output_device_manager = CloudOutputDeviceManager(self._application) def getDiscoveredDevices(self): return self._discovered_devices From ca1c5fb48cacdeec7383d5bc6c8d579ee6ac44e4 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 19 Nov 2018 22:30:17 +0100 Subject: [PATCH 0283/1292] Add some documentation --- .../src/Cloud/CloudOutputDeviceManager.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 53f64241e5..d5c4abae09 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -12,7 +12,10 @@ if TYPE_CHECKING: ## The cloud output device manager is responsible for using the Ultimaker Cloud APIs to manage remote clusters. # Keeping all cloud related logic in this class instead of the UM3OutputDevicePlugin results in more readable code. # +# API spec is available on https://api.ultimaker.com/docs/connect/spec/. +# # TODO: figure out how to pair remote clusters, local networked clusters and local cura printer presets. +# TODO: for now we just have multiple output devices if the cluster is available both locally and remote. class CloudOutputDeviceManager: # The cloud URL to use for remote clusters. @@ -32,17 +35,20 @@ class CloudOutputDeviceManager: # Fetch all remote clusters for the authenticated user. self._getRemoteClusters() + ## Gets all remote clusters from the API. def _getRemoteClusters(self): # TODO: get list of remote clusters and create an output device for each. # For testing we add a dummy device: self._addCloudOutputDevice({"cluster_id": "LJ0tciiuZZjarrXAvFLEZ6ox4Cvx8FvtXUlQv4vIhV6w"}) + ## Adds a CloudOutputDevice for each entry in the remote cluster list from the API. def _addCloudOutputDevice(self, cluster_data: Dict[str, any]): # TODO: use model or named tuple for cluster_data device = CloudOutputDevice(cluster_data["cluster_id"]) self._output_device_manager.addOutputDevice(device) self._remote_clusters[cluster_data["cluster_id"]] = device + ## Callback for when the active machine was changed by the user. def _activeMachineChanged(self): active_machine = self._application.getGlobalContainerStack() if not active_machine: From 04cc6193d6a6f7098732a808cd87841235a8e29b Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 19 Nov 2018 23:25:54 +0100 Subject: [PATCH 0284/1292] More implementation for getting remote clusters, add some TODOs --- .../src/Cloud/CloudOutputDevice.py | 1 + .../src/Cloud/CloudOutputDeviceManager.py | 67 +++++++++++++++++-- 2 files changed, 61 insertions(+), 7 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index ff83c3fd5e..8f0bd62035 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -60,6 +60,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # TODO: show message to user to sign in self.setAuthenticationState(AuthState.NotAuthenticated) else: + # TODO: not execute call at all when not signed in? self.setAuthenticationState(AuthState.Authenticated) request.setRawHeader(b"Authorization", "Bearer {}".format(self._account.accessToken).encode()) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index d5c4abae09..e88ee4dced 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -1,7 +1,12 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import TYPE_CHECKING, Dict +import json +from typing import TYPE_CHECKING, Dict, Optional +from PyQt5.QtCore import QUrl +from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply + +from UM.Logger import Logger from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputDevice import CloudOutputDevice @@ -19,31 +24,79 @@ if TYPE_CHECKING: class CloudOutputDeviceManager: # The cloud URL to use for remote clusters. - API_ROOT_PATH = "https://api-staging.ultimaker.com/connect/v1" + API_ROOT_PATH = "https://api.ultimaker.com/connect/v1" def __init__(self, application: "CuraApplication"): self._application = application self._output_device_manager = application.getOutputDeviceManager() self._account = application.getCuraAPI().account + # Network manager for getting the cluster list. + self._network_manager = QNetworkAccessManager() + self._network_manager.finished.connect(self._onNetworkRequestFinished) + # Persistent dict containing the remote clusters for the authenticated user. self._remote_clusters = {} # type: Dict[str, CloudOutputDevice] # When switching machines we check if we have to activate a remote cluster. self._application.globalContainerStackChanged.connect(self._activeMachineChanged) - + # Fetch all remote clusters for the authenticated user. - self._getRemoteClusters() + # TODO: update remote clusters periodically + self._account.loginStateChanged.connect(self._getRemoteClusters) ## Gets all remote clusters from the API. def _getRemoteClusters(self): - # TODO: get list of remote clusters and create an output device for each. - # For testing we add a dummy device: - self._addCloudOutputDevice({"cluster_id": "LJ0tciiuZZjarrXAvFLEZ6ox4Cvx8FvtXUlQv4vIhV6w"}) + url = QUrl("{}/clusters".format(self.API_ROOT_PATH)) + request = QNetworkRequest(url) + request.setHeader(QNetworkRequest.ContentTypeHeader, "application/json") + + if not self._account.isLoggedIn: + # TODO: show message to user to sign in + Logger.log("w", "User is not signed in, cannot get remote print clusters") + return + + request.setRawHeader(b"Authorization", "Bearer {}".format(self._account.accessToken).encode()) + self._network_manager.get(request) + + ## Callback for network requests. + def _onNetworkRequestFinished(self, reply: QNetworkReply): + # TODO: right now we assume that each reply is from /clusters, we should fix this + status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) + if status_code != 200: + # TODO: add correct scopes to OAuth2 client to use remote connect API. + Logger.log("w", "Got unexpected response while trying to get cloud cluster data: {}, {}" + .format(status_code, reply.readAll())) + return + + # Parse the response (returns the "data" field from the body). + clusters_data = self._parseStatusResponse(reply) + if not clusters_data: + return + + # Add an output device for each remote cluster. + # The clusters are an array of objects in a field called "data". + for cluster in clusters_data: + self._addCloudOutputDevice(cluster) + + # # For testing we add a dummy device: + # self._addCloudOutputDevice({ "cluster_id": "LJ0tciiuZZjarrXAvFLEZ6ox4Cvx8FvtXUlQv4vIhV6w" }) + + @staticmethod + def _parseStatusResponse(reply: QNetworkReply) -> Optional[dict]: + try: + result = json.loads(bytes(reply.readAll()).decode("utf-8")) + print("result=====", result) + # TODO: use model or named tuple here. + return result.data + except json.decoder.JSONDecodeError: + Logger.logException("w", "Unable to decode JSON from reply.") + return None ## Adds a CloudOutputDevice for each entry in the remote cluster list from the API. def _addCloudOutputDevice(self, cluster_data: Dict[str, any]): # TODO: use model or named tuple for cluster_data + print("cluster_data====", cluster_data) device = CloudOutputDevice(cluster_data["cluster_id"]) self._output_device_manager.addOutputDevice(device) self._remote_clusters[cluster_data["cluster_id"]] = device From e6d9ad31ab0e432a7357dfa702332cae25aead88 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 20 Nov 2018 09:20:45 +0100 Subject: [PATCH 0285/1292] Use generated Makefiles to run tests --- Jenkinsfile | 43 ++----------------------------------------- 1 file changed, 2 insertions(+), 41 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index f9a3a9864a..a345ebbd05 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -38,20 +38,9 @@ parallel_nodes(['linux && cura', 'windows && cura']) { if (isUnix()) { - // For Linux to show everything - def branch = env.BRANCH_NAME - if(!fileExists("${env.CURA_ENVIRONMENT_PATH}/${branch}")) - { - branch = "master" - } - def uranium_dir = get_workspace_dir("Ultimaker/Uranium/${branch}") - + // For Linux try { - sh """ - cd .. - export PYTHONPATH=.:"${uranium_dir}" - ${env.CURA_ENVIRONMENT_PATH}/${branch}/bin/pytest -x --verbose --full-trace --capture=no ./tests - """ + sh 'make CTEST_OUTPUT_ON_FAILURE=TRUE test' } catch(e) { currentBuild.result = "UNSTABLE" @@ -70,34 +59,6 @@ parallel_nodes(['linux && cura', 'windows && cura']) } } } - - stage('Code Style') - { - if (isUnix()) - { - // For Linux to show everything. - // CMake also runs this test, but if it fails then the test just shows "failed" without details of what exactly failed. - def branch = env.BRANCH_NAME - if(!fileExists("${env.CURA_ENVIRONMENT_PATH}/${branch}")) - { - branch = "master" - } - def uranium_dir = get_workspace_dir("Ultimaker/Uranium/${branch}") - - try - { - sh """ - cd .. - export PYTHONPATH=.:"${uranium_dir}" - ${env.CURA_ENVIRONMENT_PATH}/${branch}/bin/python3 run_mypy.py - """ - } - catch(e) - { - currentBuild.result = "UNSTABLE" - } - } - } } } From 76f2aeb43c8ab19a638ade5016229a5f542664cb Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 20 Nov 2018 11:27:45 +0100 Subject: [PATCH 0286/1292] Fix the title's top margin size in the add machine dialog. --- resources/qml/AddMachineDialog.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/AddMachineDialog.qml b/resources/qml/AddMachineDialog.qml index 0df8b891d9..aa160acd4d 100644 --- a/resources/qml/AddMachineDialog.qml +++ b/resources/qml/AddMachineDialog.qml @@ -73,7 +73,7 @@ UM.Dialog { top: parent.top left: parent.left - topMargin: UM.Theme.getSize("default_margin") + topMargin: UM.Theme.getSize("default_margin").height } text: catalog.i18nc("@title:tab", "Add a printer to Cura") From fab0d5a4b7f1e3b5dd9bfc6ccecba5cc73c0a799 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 20 Nov 2018 13:25:15 +0100 Subject: [PATCH 0287/1292] Rename the color of the sidebar to main_background, since it was deleted but not updated in the usages. Contributes to CURA-5785. --- plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml | 2 +- plugins/UM3NetworkPrinting/resources/qml/ClusterControlItem.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml b/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml index a48cb2ee3f..62e1e3ab86 100644 --- a/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml +++ b/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml @@ -83,7 +83,7 @@ Item model: packageData.supported_configs headerDelegate: Rectangle { - color: UM.Theme.getColor("sidebar") + color: UM.Theme.getColor("main_background") height: UM.Theme.getSize("toolbox_chart_row").height Label { diff --git a/plugins/UM3NetworkPrinting/resources/qml/ClusterControlItem.qml b/plugins/UM3NetworkPrinting/resources/qml/ClusterControlItem.qml index 068c369a3f..94e75a6de0 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/ClusterControlItem.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/ClusterControlItem.qml @@ -13,7 +13,7 @@ Component { property var shadowRadius: UM.Theme.getSize("monitor_shadow_radius").width; property var cornerRadius: UM.Theme.getSize("monitor_corner_radius").width; anchors.fill: parent; - color: UM.Theme.getColor("sidebar"); + color: UM.Theme.getColor("main_background"); visible: OutputDevice != null; UM.I18nCatalog { From fb3cb67da05115779cd6964d0d24e0760180ec99 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 20 Nov 2018 13:46:41 +0100 Subject: [PATCH 0288/1292] Add printer configuration components Contributes to CL-1148 --- .../qml/MonitorBuildplateConfiguration.qml | 63 +++++++++++++++ .../qml/MonitorExtruderConfiguration.qml | 76 +++++++++++++++++++ .../resources/qml/MonitorIconExtruder.qml | 60 +++++++++++++++ .../resources/qml/MonitorPrintJobCard.qml | 74 +++++++++++------- .../resources/qml/MonitorPrintJobPreview.qml | 6 +- .../qml/MonitorPrinterConfiguration.qml | 56 ++++++++++++++ .../resources/svg/icons/buildplate.svg | 5 ++ .../resources/svg/icons/extruder.svg | 5 ++ 8 files changed, 314 insertions(+), 31 deletions(-) create mode 100644 plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml create mode 100644 plugins/UM3NetworkPrinting/resources/qml/MonitorExtruderConfiguration.qml create mode 100644 plugins/UM3NetworkPrinting/resources/qml/MonitorIconExtruder.qml create mode 100644 plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterConfiguration.qml create mode 100644 plugins/UM3NetworkPrinting/resources/svg/icons/buildplate.svg create mode 100644 plugins/UM3NetworkPrinting/resources/svg/icons/extruder.svg diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml new file mode 100644 index 0000000000..d14277a1ff --- /dev/null +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml @@ -0,0 +1,63 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 2.0 +import UM 1.3 as UM + +/** + * This component comprises a buildplate icon and the buildplate name. It is + * used by the MonitorPrinterConfiguration component along with two instances + * of MonitorExtruderConfiguration. + * + * NOTE: For most labels, a fixed height with vertical alignment is used to make + * layouts more deterministic (like the fixed-size textboxes used in original + * mock-ups). This is also a stand-in for CSS's 'line-height' property. Denoted + * with '// FIXED-LINE-HEIGHT:'. + */ +Item +{ + // The buildplate name + property alias buildplate: buildplateLabel.text + + // Height is one 18px label/icon + height: 18 * screenScaleFactor // TODO: Theme! + width: childrenRect.width + + Row + { + height: parent.height + spacing: 12 * screenScaleFactor // TODO: Theme! (Should be same as extruder spacing) + + // This wrapper ensures that the buildplate icon is located centered + // below an extruder icon. + Item + { + height: parent.height + width: 32 * screenScaleFactor // TODO: Theme! (Should be same as extruder icon width) + + UM.RecolorImage + { + id: buildplateIcon + anchors.centerIn: parent + color: "#0a0850" // TODO: Theme! (Standard purple) + elide: Text.ElideRight + height: parent.height + source: "../svg/icons/buildplate.svg" + width: height + } + } + + Label + { + id: buildplateLabel + color: "#191919" // TODO: Theme! + font: UM.Theme.getFont("very_small") // 12pt, regular + text: "" + + // FIXED-LINE-HEIGHT: + height: 18 * screenScaleFactor // TODO: Theme! + verticalAlignment: Text.AlignVCenter + } + } +} \ No newline at end of file diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorExtruderConfiguration.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorExtruderConfiguration.qml new file mode 100644 index 0000000000..afbd4c3641 --- /dev/null +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorExtruderConfiguration.qml @@ -0,0 +1,76 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 2.0 +import UM 1.3 as UM + +/** + * This component comprises a colored extruder icon, the material name, and the + * print core name. It is used by the MonitorPrinterConfiguration component with + * a sibling instance as well as a MonitorBuildplateConfiguration instance. + * + * NOTE: For most labels, a fixed height with vertical alignment is used to make + * layouts more deterministic (like the fixed-size textboxes used in original + * mock-ups). This is also a stand-in for CSS's 'line-height' property. Denoted + * with '// FIXED-LINE-HEIGHT:'. + */ +Item +{ + // The material color + property alias color: extruderIcon.color + + // The extruder position; NOTE: Decent human beings count from 0 + property alias position: extruderIcon.position + + // The material name + property alias material: materialLabel.text + + // The print core name (referred to as hotendID in Python) + property alias printCore: printCoreLabel.text + + // Height is 2 x 18px labels, plus 4px spacing between them + height: 40 * screenScaleFactor // TODO: Theme! + width: childrenRect.width + + MonitorIconExtruder + { + id: extruderIcon + color: "#eeeeee" // TODO: Theme! + position: 0 + } + Label + { + id: materialLabel + anchors + { + left: extruderIcon.right + leftMargin: 12 * screenScaleFactor // TODO: Theme! + } + color: "#191919" // TODO: Theme! + elide: Text.ElideRight + font: UM.Theme.getFont("very_small") // 12pt, regular + text: "" + + // FIXED-LINE-HEIGHT: + height: 18 * screenScaleFactor // TODO: Theme! + verticalAlignment: Text.AlignVCenter + } + Label + { + id: printCoreLabel + anchors + { + left: materialLabel.left + bottom: parent.bottom + } + color: "#191919" // TODO: Theme! + elide: Text.ElideRight + font: UM.Theme.getFont("small") // 12pt, bold + text: "" + + // FIXED-LINE-HEIGHT: + height: 18 * screenScaleFactor // TODO: Theme! + verticalAlignment: Text.AlignVCenter + } +} \ No newline at end of file diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorIconExtruder.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorIconExtruder.qml new file mode 100644 index 0000000000..971c6b2251 --- /dev/null +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorIconExtruder.qml @@ -0,0 +1,60 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 2.0 +import UM 1.3 as UM + +/** + * This component is a sort of "super icon" which includes a colored SVG image + * as well as the extruder position number. It is used in the the + * MonitorExtruderConfiguration component. + */ +Item +{ + // The material color + property alias color: icon.color + + // The extruder position; NOTE: Decent human beings count from 0 + property int position: 0 + + // The extruder icon size; NOTE: This shouldn't need to be changed + property int size: 32 // TODO: Theme! + + // THe extruder icon source; NOTE: This shouldn't need to be changed + property string iconSource: "../svg/icons/extruder.svg" + + height: size + width: size + + UM.RecolorImage + { + id: icon + anchors.fill: parent + source: iconSource + width: size + } + + /* + * The label uses some "fancy" math to ensure that if you change the overall + * icon size, the number scales with it. That is to say, the font properties + * are linked to the icon size, NOT the theme. And that's intentional. + */ + Label + { + id: positionLabel + font + { + pointSize: Math.round(size * 0.3125) + weight: Font.Bold + } + height: Math.round(size / 2) * screenScaleFactor + horizontalAlignment: Text.AlignHCenter + text: position + 1 + verticalAlignment: Text.AlignVCenter + width: Math.round(size / 2) * screenScaleFactor + x: Math.round(size * 0.25) * screenScaleFactor + y: Math.round(size * 0.15625) * screenScaleFactor + // TODO: Once 'size' is themed, screenScaleFactor won't be needed + } +} \ No newline at end of file diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml index 307a4f908f..6d02c40776 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml @@ -4,12 +4,21 @@ import QtQuick 2.2 import QtQuick.Controls 2.0 import UM 1.3 as UM -import Cura 1.0 as Cura -// A Print Job Card is essentially just a filled-in Expandable Card item. +/** + * A Print Job Card is essentially just a filled-in Expandable Card item. All + * data within it is derived from being passed a printJob property. + * + * NOTE: For most labels, a fixed height with vertical alignment is used to make + * layouts more deterministic (like the fixed-size textboxes used in original + * mock-ups). This is also a stand-in for CSS's 'line-height' property. Denoted + * with '// FIXED-LINE-HEIGHT:'. + */ Item { id: base + + // The print job which all other data is derived from property var printJob: null width: parent.width @@ -19,15 +28,15 @@ Item { headerItem: Row { - height: 48 + height: 48 * screenScaleFactor // TODO: Theme! anchors.left: parent.left - anchors.leftMargin: 24 - spacing: 18 + anchors.leftMargin: 24 * screenScaleFactor // TODO: Theme! + spacing: 18 * screenScaleFactor // TODO: Theme! MonitorPrintJobPreview { printJob: base.printJob - size: 32 + size: 32 * screenScaleFactor // TODO: Theme! anchors.verticalCenter: parent.verticalCenter } @@ -36,10 +45,13 @@ Item text: printJob && printJob.name ? printJob.name : "" color: "#374355" elide: Text.ElideRight - font: UM.Theme.getFont("default_bold") + font: UM.Theme.getFont("medium") // 14pt, regular anchors.verticalCenter: parent.verticalCenter - width: 216 - height: 18 + width: 216 * screenScaleFactor // TODO: Theme! + + // FIXED-LINE-HEIGHT: + height: 18 * screenScaleFactor // TODO: Theme! + verticalAlignment: Text.AlignVCenter } Label @@ -47,18 +59,20 @@ Item text: printJob ? OutputDevice.formatDuration(printJob.timeTotal) : "" color: "#374355" elide: Text.ElideRight - font: UM.Theme.getFont("default_bold") + font: UM.Theme.getFont("medium") // 14pt, regular anchors.verticalCenter: parent.verticalCenter - width: 216 - height: 18 + width: 216 * screenScaleFactor // TODO: Theme! + + // FIXED-LINE-HEIGHT: + height: 18 * screenScaleFactor // TODO: Theme! + verticalAlignment: Text.AlignVCenter } Label { color: "#374355" - height: 18 elide: Text.ElideRight - font: UM.Theme.getFont("default_bold") + font: UM.Theme.getFont("medium") // 14pt, regular text: { if (printJob !== null) { if (printJob.assignedPrinter == null) @@ -78,31 +92,39 @@ Item } visible: printJob anchors.verticalCenter: parent.verticalCenter - width: 216 + width: 216 * screenScaleFactor // TODO: Theme! + + // FIXED-LINE-HEIGHT: + height: 18 * screenScaleFactor // TODO: Theme! + verticalAlignment: Text.AlignVCenter } } drawerItem: Row { - height: 96 - anchors.left: parent.left - anchors.leftMargin: 74 - spacing: 18 + anchors + { + left: parent.left + leftMargin: 74 * screenScaleFactor // TODO: Theme! + } + height: 96 * screenScaleFactor // TODO: Theme! + spacing: 18 * screenScaleFactor // TODO: Theme! - Rectangle + MonitorPrinterConfiguration { id: printerConfiguration - width: 450 - height: 72 - color: "blue" anchors.verticalCenter: parent.verticalCenter + printJob: base.printJob } Label { - height: 18 text: printJob && printJob.owner ? printJob.owner : "" - color: "#374355" + color: "#374355" // TODO: Theme! elide: Text.ElideRight - font: UM.Theme.getFont("default_bold") + font: UM.Theme.getFont("medium") // 14pt, regular anchors.top: printerConfiguration.top + + // FIXED-LINE-HEIGHT: + height: 18 * screenScaleFactor // TODO: Theme! + verticalAlignment: Text.AlignVCenter } } } diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml index 7322193451..1a69d2dc12 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml @@ -2,14 +2,10 @@ // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 -import QtQuick.Dialogs 1.1 import QtQuick.Controls 2.0 -import QtQuick.Controls.Styles 1.4 -import QtGraphicalEffects 1.0 -import QtQuick.Layouts 1.1 -import QtQuick.Dialogs 1.1 import UM 1.3 as UM +// TODO: Documentation! Item { id: printJobPreview diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterConfiguration.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterConfiguration.qml new file mode 100644 index 0000000000..5d4d408b8e --- /dev/null +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterConfiguration.qml @@ -0,0 +1,56 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 2.0 +import UM 1.3 as UM + +/** + * + */ +Item +{ + id: base + + property var printJob: null + property var config0: printJob ? printJob.configuration.extruderConfigurations[0] : null + property var config1: printJob ? printJob.configuration.extruderConfigurations[1] : null + + height: 72 * screenScaleFactor // TODO: Theme! + width: 450 * screenScaleFactor // TODO: Theme! + + Row + { + spacing: 18 * screenScaleFactor // TODO: Theme! + + MonitorExtruderConfiguration + { + color: config0 ? config0.activeMaterial.color : "#eeeeee" // TODO: Theme! + material: config0 ? config0.activeMaterial.name : "" + position: config0.position + printCore: config0 ? config0.hotendID : "" + visible: config0 + + // Keep things responsive! + width: Math.floor((base.width - parent.spacing) / 2) + } + + MonitorExtruderConfiguration + { + color: config1 ? config1.activeMaterial.color : "#eeeeee" // TODO: Theme! + material: config1 ? config1.activeMaterial.name : "" + position: config1.position + printCore: config1 ? config1.hotendID : "" + visible: config1 + + // Keep things responsive! + width: Math.floor((base.width - parent.spacing) / 2) + } + } + + MonitorBuildplateConfiguration + { + anchors.bottom: parent.bottom + buildplate: "Glass" + } +} \ No newline at end of file diff --git a/plugins/UM3NetworkPrinting/resources/svg/icons/buildplate.svg b/plugins/UM3NetworkPrinting/resources/svg/icons/buildplate.svg new file mode 100644 index 0000000000..bcb278a8ca --- /dev/null +++ b/plugins/UM3NetworkPrinting/resources/svg/icons/buildplate.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/plugins/UM3NetworkPrinting/resources/svg/icons/extruder.svg b/plugins/UM3NetworkPrinting/resources/svg/icons/extruder.svg new file mode 100644 index 0000000000..235cb432e9 --- /dev/null +++ b/plugins/UM3NetworkPrinting/resources/svg/icons/extruder.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file From cbd5238738b1656c986caf87b58957ff605d4fb3 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 20 Nov 2018 13:55:28 +0100 Subject: [PATCH 0289/1292] Don't show custom/auto toggle buttons when not connected In order to prevent suddenly switching to the other side when the connection is lost or restored, we only evaluate this upon opening the popup. This way you might be surprised that closing and then opening it can show something else, but it will never surprise you while working on the popup itself as a user. Contributes to issue CURA-5876. --- .../ConfigurationMenu/ConfigurationMenu.qml | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index 10c52a7b0f..fe292799a5 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -98,31 +98,37 @@ Cura.ExpandableComponent popupItem: Item { - id: popup + id: popupItem width: base.width - 2 * UM.Theme.getSize("default_margin").width height: 200 - property var configuration_method: "auto" + property var is_connected: false //If current machine is connected to a printer. Only evaluated upon making popup visible. + onVisibleChanged: + { + is_connected = Cura.MachineManager.activeMachineNetworkKey != "" && Cura.MachineManager.printerConnected //Re-evaluate. + } + + property var configuration_method: buttonBar.visible ? "auto" : "custom" //Auto if connected to a printer at start-up, or Custom if not. AutoConfiguration { id: autoConfiguration - visible: popup.configuration_method === "auto" - anchors.top: header.bottom - height: visible ? childrenRect.height : 0 + visible: popupItem.configuration_method === "auto" + anchors.top: parent.top } CustomConfiguration { id: customConfiguration - visible: popup.configuration_method === "custom" - anchors.top: header.bottom - height: visible ? childrenRect.height : 0 + visible: popupItem.configuration_method === "custom" + anchors.top: parent.top } Rectangle { id: separator + visible: buttonBar.visible + anchors { left: parent.left @@ -131,12 +137,16 @@ Cura.ExpandableComponent bottomMargin: UM.Theme.getSize("default_margin").height } height: UM.Theme.getSize("default_lining").height + color: UM.Theme.getColor("lining") } + //Allow switching between custom and auto. Rectangle { id: buttonBar + visible: popupItem.is_connected //Switching only makes sense if the "auto" part is possible. + anchors { left: parent.left @@ -148,7 +158,7 @@ Cura.ExpandableComponent Cura.ActionButton { id: goToCustom - visible: popup.configuration_method === "auto" + visible: popupItem.configuration_method === "auto" text: catalog.i18nc("@label", "Custom") anchors @@ -165,13 +175,13 @@ Cura.ExpandableComponent leftPadding: UM.Theme.getSize("default_margin").width rightPadding: UM.Theme.getSize("default_margin").width - onClicked: popup.configuration_method = "custom" + onClicked: popupItem.configuration_method = "custom" } Cura.ActionButton { id: goToAuto - visible: popup.configuration_method === "custom" + visible: popupItem.configuration_method === "custom" text: catalog.i18nc("@label", "Configurations") anchors @@ -188,7 +198,7 @@ Cura.ExpandableComponent leftPadding: UM.Theme.getSize("default_margin").width rightPadding: UM.Theme.getSize("default_margin").width - onClicked: popup.configuration_method = "auto" + onClicked: popupItem.configuration_method = "auto" } } } From 42d73836f400357e73d288d0a3be56848f7743f6 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 20 Nov 2018 14:19:55 +0100 Subject: [PATCH 0290/1292] Move default margin by default to Cura's action buttons So we don't have to repeat that every time you create a new button. Contributes to issue CURA-5876. --- resources/qml/ActionButton.qml | 3 +++ resources/qml/ActionPanel/OutputDevicesActionButton.qml | 2 ++ resources/qml/ActionPanel/OutputProcessWidget.qml | 2 -- resources/qml/MainWindow/MainWindowHeader.qml | 2 -- resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml | 4 ---- 5 files changed, 5 insertions(+), 8 deletions(-) diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index 2a8b894867..08c44fb473 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -29,6 +29,9 @@ Button // we elide the text to the right so the text will be cut off with the three dots at the end. property var fixedWidthMode: false + leftPadding: UM.Theme.getSize("default_margin").width + rightPadding: UM.Theme.getSize("default_margin").width + contentItem: Row { UM.RecolorImage diff --git a/resources/qml/ActionPanel/OutputDevicesActionButton.qml b/resources/qml/ActionPanel/OutputDevicesActionButton.qml index be79a1893e..a2a69ed526 100644 --- a/resources/qml/ActionPanel/OutputDevicesActionButton.qml +++ b/resources/qml/ActionPanel/OutputDevicesActionButton.qml @@ -48,6 +48,8 @@ Item right: parent.right } + leftPadding: UM.Theme.getSize("narrow_margin").width //Need more space than usual here for wide text. + rightPadding: UM.Theme.getSize("narrow_margin").width tooltip: catalog.i18nc("@info:tooltip", "Select the active output device") iconSource: popup.opened ? UM.Theme.getIcon("arrow_top") : UM.Theme.getIcon("arrow_bottom") color: UM.Theme.getColor("action_panel_secondary") diff --git a/resources/qml/ActionPanel/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml index f4e014b1ec..772c05741f 100644 --- a/resources/qml/ActionPanel/OutputProcessWidget.qml +++ b/resources/qml/ActionPanel/OutputProcessWidget.qml @@ -104,8 +104,6 @@ Column { id: previewStageShortcut - leftPadding: UM.Theme.getSize("default_margin").width - rightPadding: UM.Theme.getSize("default_margin").width height: UM.Theme.getSize("action_panel_button").height text: catalog.i18nc("@button", "Preview") color: UM.Theme.getColor("secondary") diff --git a/resources/qml/MainWindow/MainWindowHeader.qml b/resources/qml/MainWindow/MainWindowHeader.qml index 59ec542e6b..6f3358648b 100644 --- a/resources/qml/MainWindow/MainWindowHeader.qml +++ b/resources/qml/MainWindow/MainWindowHeader.qml @@ -81,8 +81,6 @@ Rectangle rightMargin: UM.Theme.getSize("default_margin").width verticalCenter: parent.verticalCenter } - leftPadding: UM.Theme.getSize("default_margin").width - rightPadding: UM.Theme.getSize("default_margin").width text: catalog.i18nc("@action:button", "Marketplace") height: Math.round(0.5 * UM.Theme.getSize("main_window_header").height) color: UM.Theme.getColor("main_window_header_secondary_button_background_active") diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index fe292799a5..cb90735250 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -172,8 +172,6 @@ Cura.ExpandableComponent textColor: UM.Theme.getColor("primary") textHoverColor: UM.Theme.getColor("text") height: UM.Theme.getSize("action_panel_button").height - leftPadding: UM.Theme.getSize("default_margin").width - rightPadding: UM.Theme.getSize("default_margin").width onClicked: popupItem.configuration_method = "custom" } @@ -195,8 +193,6 @@ Cura.ExpandableComponent textColor: UM.Theme.getColor("primary") textHoverColor: UM.Theme.getColor("text") height: UM.Theme.getSize("action_panel_button").height - leftPadding: UM.Theme.getSize("default_margin").width - rightPadding: UM.Theme.getSize("default_margin").width onClicked: popupItem.configuration_method = "auto" } From a1068a3ef27d7fa3499ae8c149a3d0da2945e2cb Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 20 Nov 2018 14:24:09 +0100 Subject: [PATCH 0291/1292] Rename action_panel_button theme entry to action_button Because it's not just used in the save panel. Contributes to issue CURA-5876. --- resources/qml/ActionPanel/OutputProcessWidget.qml | 6 +++--- resources/qml/ActionPanel/SliceProcessWidget.qml | 2 +- resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml | 4 ++-- resources/themes/cura-light/theme.json | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/resources/qml/ActionPanel/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml index 772c05741f..61efda2f2d 100644 --- a/resources/qml/ActionPanel/OutputProcessWidget.qml +++ b/resources/qml/ActionPanel/OutputProcessWidget.qml @@ -104,7 +104,7 @@ Column { id: previewStageShortcut - height: UM.Theme.getSize("action_panel_button").height + height: UM.Theme.getSize("action_button").height text: catalog.i18nc("@button", "Preview") color: UM.Theme.getColor("secondary") hoverColor: UM.Theme.getColor("secondary") @@ -116,8 +116,8 @@ Column Cura.OutputDevicesActionButton { - width: previewStageShortcut.visible ? UM.Theme.getSize("action_panel_button").width : parent.width - height: UM.Theme.getSize("action_panel_button").height + width: previewStageShortcut.visible ? UM.Theme.getSize("action_button").width : parent.width + height: UM.Theme.getSize("action_button").height } } } \ No newline at end of file diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index 2d4a7b6b89..7de1a22edb 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -85,7 +85,7 @@ Column { id: prepareButton width: parent.width - height: UM.Theme.getSize("action_panel_button").height + height: UM.Theme.getSize("action_button").height fixedWidthMode: true text: { diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index cb90735250..1015f67a2e 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -171,7 +171,7 @@ Cura.ExpandableComponent hoverColor: UM.Theme.getColor("secondary") textColor: UM.Theme.getColor("primary") textHoverColor: UM.Theme.getColor("text") - height: UM.Theme.getSize("action_panel_button").height + height: UM.Theme.getSize("action_button").height onClicked: popupItem.configuration_method = "custom" } @@ -192,7 +192,7 @@ Cura.ExpandableComponent hoverColor: UM.Theme.getColor("secondary") textColor: UM.Theme.getColor("primary") textHoverColor: UM.Theme.getColor("text") - height: UM.Theme.getSize("action_panel_button").height + height: UM.Theme.getSize("action_button").height onClicked: popupItem.configuration_method = "auto" } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index d28611529b..8b3e606094 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -385,7 +385,6 @@ "action_panel_widget": [25.0, 0.0], "action_panel_information_widget": [20.0, 0.0], - "action_panel_button": [15.0, 3.0], "machine_selector_widget": [16.0, 4.5], @@ -432,6 +431,9 @@ "button_icon": [2.5, 2.5], "button_lining": [0, 0], + "action_button": [15.0, 3.0], + "action_button_radius": [0.15, 0.15], + "small_button": [2, 2], "small_button_icon": [1.5, 1.5], @@ -520,8 +522,6 @@ "avatar_image": [6.8, 6.8], - "action_button_radius": [0.15, 0.15], - "monitor_config_override_box": [1.0, 14.0], "monitor_extruder_circle": [2.75, 2.75], "monitor_text_line": [1.16, 1.16], From 895590c3d0a445d4e114766348cdc5de676442e5 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 20 Nov 2018 14:28:54 +0100 Subject: [PATCH 0292/1292] Change the size of the progress bar control. Also add the rounded rectangle. Contributes to the new Cura UI-Flow. --- resources/themes/cura-light/styles.qml | 1 + resources/themes/cura-light/theme.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index 6f099bf1c5..58035ae3bd 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -515,6 +515,7 @@ QtObject implicitWidth: Theme.getSize("message").width - (Theme.getSize("default_margin").width * 2) implicitHeight: Theme.getSize("progressbar").height color: control.hasOwnProperty("backgroundColor") ? control.backgroundColor : Theme.getColor("progressbar_background") + radius: Theme.getSize("progressbar_radius").width } progress: Rectangle { diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index a33ff87042..f4d50e4c79 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -448,7 +448,7 @@ "progressbar": [26.0, 0.75], "progressbar_radius": [0.15, 0.15], - "progressbar_control": [8.0, 0.4], + "progressbar_control": [8.0, 0.75], "scrollbar": [0.75, 0.5], From dca286cea51e1f336df2a5fa2aa0f7f80dc9917e Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 20 Nov 2018 14:34:06 +0100 Subject: [PATCH 0293/1292] Give action button a sane default height We don't want to give it a default width since that should just adjust to its contents by default, which is fine. Contributes to issue CURA-5876. --- resources/qml/ActionButton.qml | 1 + resources/qml/ActionPanel/OutputProcessWidget.qml | 1 - resources/qml/ActionPanel/SliceProcessWidget.qml | 1 - resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml | 2 -- 4 files changed, 1 insertion(+), 4 deletions(-) diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index 08c44fb473..0ed639db75 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -31,6 +31,7 @@ Button leftPadding: UM.Theme.getSize("default_margin").width rightPadding: UM.Theme.getSize("default_margin").width + height: UM.Theme.getSize("action_button").height contentItem: Row { diff --git a/resources/qml/ActionPanel/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml index 61efda2f2d..98dbe5bd2c 100644 --- a/resources/qml/ActionPanel/OutputProcessWidget.qml +++ b/resources/qml/ActionPanel/OutputProcessWidget.qml @@ -104,7 +104,6 @@ Column { id: previewStageShortcut - height: UM.Theme.getSize("action_button").height text: catalog.i18nc("@button", "Preview") color: UM.Theme.getColor("secondary") hoverColor: UM.Theme.getColor("secondary") diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index 7de1a22edb..09e0b2584a 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -85,7 +85,6 @@ Column { id: prepareButton width: parent.width - height: UM.Theme.getSize("action_button").height fixedWidthMode: true text: { diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index 1015f67a2e..aa30a1236b 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -171,7 +171,6 @@ Cura.ExpandableComponent hoverColor: UM.Theme.getColor("secondary") textColor: UM.Theme.getColor("primary") textHoverColor: UM.Theme.getColor("text") - height: UM.Theme.getSize("action_button").height onClicked: popupItem.configuration_method = "custom" } @@ -192,7 +191,6 @@ Cura.ExpandableComponent hoverColor: UM.Theme.getColor("secondary") textColor: UM.Theme.getColor("primary") textHoverColor: UM.Theme.getColor("text") - height: UM.Theme.getSize("action_button").height onClicked: popupItem.configuration_method = "auto" } From 3b4d728d6a134237c708b0093bc6925122859056 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 20 Nov 2018 14:35:13 +0100 Subject: [PATCH 0294/1292] Fix Simulation view popup not sizing down I have no idea why implictHeight does work and childrenRect.height doesn't (eg; childrenRect.height only scales up for some reason, never down) CURA-5785 --- plugins/SimulationView/SimulationViewMenuComponent.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/SimulationView/SimulationViewMenuComponent.qml b/plugins/SimulationView/SimulationViewMenuComponent.qml index 89615f43a4..caf47508e3 100644 --- a/plugins/SimulationView/SimulationViewMenuComponent.qml +++ b/plugins/SimulationView/SimulationViewMenuComponent.qml @@ -65,7 +65,7 @@ Cura.ExpandableComponent property int top_layer_count: UM.Preferences.getValue("view/top_layer_count") width: UM.Theme.getSize("layerview_menu_size").width - 2 * UM.Theme.getSize("default_margin").width - height: childrenRect.height + height: implicitHeight spacing: UM.Theme.getSize("layerview_row_spacing").height From d42ddad606111ffcf3a1e764e3bc0af6c7064d79 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 20 Nov 2018 14:47:41 +0100 Subject: [PATCH 0295/1292] Add icons on left and right side of text For this I had to implement functionality in ActionButton to be able to display the icon on either side. Contributes to issue CURA-5876. --- resources/qml/ActionButton.qml | 24 +++++++++++++++---- .../ConfigurationMenu/ConfigurationMenu.qml | 5 ++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index 0ed639db75..28bda7fd35 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -11,7 +11,8 @@ Button { id: button property alias cursorShape: mouseArea.cursorShape - property alias iconSource: buttonIcon.source + property alias iconSource: buttonIconLeft.source + property var iconOnRightSide: false property alias textFont: buttonText.font property alias cornerRadius: backgroundRect.radius property alias tooltip: tooltip.text @@ -35,16 +36,17 @@ Button contentItem: Row { + //Icon if displayed on the left side. UM.RecolorImage { - id: buttonIcon + id: buttonIconLeft source: "" height: Math.round(0.6 * parent.height) - width: height + width: visible ? height : 0 sourceSize.width: width sourceSize.height: height color: button.hovered ? button.textHoverColor : button.textColor - visible: source != "" + visible: source != "" && !button.iconOnRightSide anchors.verticalCenter: parent.verticalCenter } @@ -61,6 +63,20 @@ Button horizontalAlignment: Text.AlignHCenter elide: Text.ElideRight } + + //Icon if displayed on the right side. + UM.RecolorImage + { + id: buttonIconRight + source: buttonIconLeft.source + height: Math.round(0.6 * parent.height) + width: visible ? height : 0 + sourceSize.width: width + sourceSize.height: height + color: button.hovered ? button.textHoverColor : button.textColor + visible: source != "" && button.iconOnRightSide + anchors.verticalCenter: parent.verticalCenter + } } background: Rectangle diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index aa30a1236b..b38384ef8a 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -172,6 +172,9 @@ Cura.ExpandableComponent textColor: UM.Theme.getColor("primary") textHoverColor: UM.Theme.getColor("text") + iconSource: UM.Theme.icons.arrow_right + iconOnRightSide: true + onClicked: popupItem.configuration_method = "custom" } @@ -192,6 +195,8 @@ Cura.ExpandableComponent textColor: UM.Theme.getColor("primary") textHoverColor: UM.Theme.getColor("text") + iconSource: UM.Theme.icons.arrow_left + onClicked: popupItem.configuration_method = "auto" } } From 6de24250edbb5d5a86dbdea6eff79e15f7196326 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 20 Nov 2018 14:50:12 +0100 Subject: [PATCH 0296/1292] Make icon height equal to text height This seems to be about the same actually as what it was. But now the relation is in there. I also made the right icon inherit as much as possible from the left icon so that if we change something, we only have to change it in the left icon. Contributes to issue CURA-5876. --- resources/qml/ActionButton.qml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index 28bda7fd35..7ecaeda4b0 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -41,7 +41,7 @@ Button { id: buttonIconLeft source: "" - height: Math.round(0.6 * parent.height) + height: buttonText.height width: visible ? height : 0 sourceSize.width: width sourceSize.height: height @@ -69,13 +69,13 @@ Button { id: buttonIconRight source: buttonIconLeft.source - height: Math.round(0.6 * parent.height) + height: buttonText.height width: visible ? height : 0 sourceSize.width: width sourceSize.height: height - color: button.hovered ? button.textHoverColor : button.textColor + color: buttonIconLeft.color visible: source != "" && button.iconOnRightSide - anchors.verticalCenter: parent.verticalCenter + anchors.verticalCenter: buttonIconLeft.verticalCenter } } From 2f84339f5cb51be69098c0a9c6e33cc535f508ad Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 20 Nov 2018 15:58:09 +0100 Subject: [PATCH 0297/1292] Finalize queue Contributes to CL-1148 --- .../resources/qml/ClusterMonitorItem.qml | 269 ++++++++++++------ .../resources/qml/ExpandableCard.qml | 1 + .../qml/MonitorBuildplateConfiguration.qml | 2 +- .../resources/qml/MonitorPrintJobCard.qml | 108 +++++-- .../qml/MonitorPrinterConfiguration.qml | 30 +- .../resources/qml/MonitorPrinterPill.qml | 34 +++ .../resources/svg/icons/external_link.svg | 8 + 7 files changed, 327 insertions(+), 125 deletions(-) create mode 100644 plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterPill.qml create mode 100644 plugins/UM3NetworkPrinting/resources/svg/icons/external_link.svg diff --git a/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml b/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml index ff4bc72218..d055071521 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml @@ -8,102 +8,203 @@ import UM 1.3 as UM import Cura 1.0 as Cura import QtGraphicalEffects 1.0 -Component { - - Rectangle { - id: monitorFrame; - property var emphasisColor: UM.Theme.getColor("setting_control_border_highlight"); - property var cornerRadius: UM.Theme.getSize("monitor_corner_radius").width; +Component +{ + Rectangle + { + id: monitorFrame + + property var emphasisColor: UM.Theme.getColor("setting_control_border_highlight") + property var cornerRadius: UM.Theme.getSize("monitor_corner_radius").width + color: transparent - height: maximumHeight; - onVisibleChanged: { - if (monitorFrame != null && !monitorFrame.visible) { - OutputDevice.setActiveCameraUrl(""); + height: maximumHeight + onVisibleChanged: + { + if (monitorFrame != null && !monitorFrame.visible) + { + OutputDevice.setActiveCameraUrl("") } } - width: maximumWidth; + width: maximumWidth + + UM.I18nCatalog + { + id: catalog + name: "cura" + } LinearGradient { anchors.fill: parent gradient: Gradient { - GradientStop { position: 0.0; color: "#f6f6f6" } - GradientStop { position: 1.0; color: "#ffffff" } - } - } - - UM.I18nCatalog { - id: catalog; - name: "cura"; - } - - Label { - id: manageQueueLabel; - anchors { - bottom: queuedLabel.bottom; - right: queuedPrintJobs.right; - rightMargin: 3 * UM.Theme.getSize("default_margin").width; - } - color: UM.Theme.getColor("primary"); - font: UM.Theme.getFont("default"); - linkColor: UM.Theme.getColor("primary"); - text: catalog.i18nc("@label link to connect manager", "Manage queue"); - } - - MouseArea { - anchors.fill: manageQueueLabel; - hoverEnabled: true; - onClicked: Cura.MachineManager.printerOutputDevices[0].openPrintJobControlPanel(); - onEntered: manageQueueLabel.font.underline = true; - onExited: manageQueueLabel.font.underline = false; - } - - Label { - id: queuedLabel; - anchors { - left: queuedPrintJobs.left; - leftMargin: 3 * UM.Theme.getSize("default_margin").width + 5 * screenScaleFactor; - top: parent.top; - topMargin: 2 * UM.Theme.getSize("default_margin").height; - } - color: UM.Theme.getColor("text"); - font: UM.Theme.getFont("large"); - text: catalog.i18nc("@label", "Queued"); - } - - ScrollView { - id: queuedPrintJobs; - anchors { - top: queuedLabel.bottom; - topMargin: UM.Theme.getSize("default_margin").height; - horizontalCenter: parent.horizontalCenter; - bottomMargin: UM.Theme.getSize("default_margin").height; - bottom: parent.bottom; - } - style: UM.Theme.styles.scrollview; - visible: OutputDevice.receivedPrintJobs; - width: Math.min(834 * screenScaleFactor, maximumWidth); - - ListView { - id: printJobList; - anchors.fill: parent; - delegate: MonitorPrintJobCard { - anchors { - left: parent.left; - leftMargin: UM.Theme.getSize("default_margin").width; - right: parent.right; - rightMargin: UM.Theme.getSize("default_margin").width; - } - printJob: modelData; + GradientStop { + position: 0.0 + color: "#f6f6f6" + } + GradientStop { + position: 1.0 + color: "#ffffff" + } + } + } + + Item + { + id: queue + + anchors.fill: parent + anchors.top: parent.top + anchors.topMargin: 400 * screenScaleFactor // TODO: Insert carousel here + + Label + { + id: queuedLabel + anchors + { + left: queuedPrintJobs.left + top: parent.top + } + color: UM.Theme.getColor("text") + font: UM.Theme.getFont("large_nonbold") + text: catalog.i18nc("@label", "Queued") + } + + Item + { + id: manageQueueLabel + anchors + { + right: queuedPrintJobs.right + verticalCenter: queuedLabel.verticalCenter + } + height: 18 * screenScaleFactor // TODO: Theme! + width: childrenRect.width + + UM.RecolorImage + { + id: externalLinkIcon + anchors.verticalCenter: externalLinkIcon.verticalCenter + color: UM.Theme.getColor("primary") + source: "../svg/icons/external_link.svg" + width: 16 * screenScaleFactor // TODO: Theme! (Y U NO USE 18 LIKE ALL OTHER ICONS?!) + height: 16 * screenScaleFactor // TODO: Theme! (Y U NO USE 18 LIKE ALL OTHER ICONS?!) + } + Label + { + anchors + { + left: externalLinkIcon.right + leftMargin: 6 * screenScaleFactor // TODO: Theme! + verticalCenter: externalLinkIcon.verticalCenter + } + color: UM.Theme.getColor("primary") + font: UM.Theme.getFont("default") + linkColor: UM.Theme.getColor("primary") + text: catalog.i18nc("@label link to connect manager", "Manage queue in Cura Connect") + } + } + + + MouseArea + { + anchors.fill: manageQueueLabel + hoverEnabled: true + onClicked: Cura.MachineManager.printerOutputDevices[0].openPrintJobControlPanel() + onEntered: manageQueueLabel.font.underline = true + onExited: manageQueueLabel.font.underline = false + } + + Row + { + id: printJobQueueHeadings + anchors + { + left: queuedPrintJobs.left + leftMargin: 6 * screenScaleFactor // TODO: Theme! + top: queuedLabel.bottom + topMargin: 24 * screenScaleFactor // TODO: Theme! + } + spacing: 18 * screenScaleFactor // TODO: Theme! + + Label + { + text: catalog.i18nc("@label", "Print jobs") + color: "#666666" + elide: Text.ElideRight + font: UM.Theme.getFont("medium") // 14pt, regular + anchors.verticalCenter: parent.verticalCenter + width: 284 * screenScaleFactor // TODO: Theme! (Should match column size) + + // FIXED-LINE-HEIGHT: + height: 18 * screenScaleFactor // TODO: Theme! + verticalAlignment: Text.AlignVCenter + } + + Label + { + text: catalog.i18nc("@label", "Total print time") + color: "#666666" + elide: Text.ElideRight + font: UM.Theme.getFont("medium") // 14pt, regular + anchors.verticalCenter: parent.verticalCenter + width: 216 * screenScaleFactor // TODO: Theme! (Should match column size) + + // FIXED-LINE-HEIGHT: + height: 18 * screenScaleFactor // TODO: Theme! + verticalAlignment: Text.AlignVCenter + } + + Label + { + text: catalog.i18nc("@label", "Waiting for") + color: "#666666" + elide: Text.ElideRight + font: UM.Theme.getFont("medium") // 14pt, regular + anchors.verticalCenter: parent.verticalCenter + width: 216 * screenScaleFactor // TODO: Theme! (Should match column size) + + // FIXED-LINE-HEIGHT: + height: 18 * screenScaleFactor // TODO: Theme! + verticalAlignment: Text.AlignVCenter + } + } + + ScrollView + { + id: queuedPrintJobs + anchors { + bottom: parent.bottom + horizontalCenter: parent.horizontalCenter + top: printJobQueueHeadings.bottom + topMargin: 12 * screenScaleFactor // TODO: Theme! + } + style: UM.Theme.styles.scrollview + visible: OutputDevice.receivedPrintJobs + width: Math.min(834 * screenScaleFactor, maximumWidth) + + ListView + { + id: printJobList + anchors.fill: parent + delegate: MonitorPrintJobCard + { + anchors + { + left: parent.left + right: parent.right + } + printJob: modelData + } + model: OutputDevice.queuedPrintJobs + spacing: 6 } - model: OutputDevice.queuedPrintJobs; - spacing: 6; } } PrinterVideoStream { - anchors.fill: parent; - cameraUrl: OutputDevice.activeCameraUrl; - visible: OutputDevice.activeCameraUrl != ""; + anchors.fill: parent + cameraUrl: OutputDevice.activeCameraUrl + visible: OutputDevice.activeCameraUrl != "" } } diff --git a/plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml b/plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml index 89d88d671a..4922aea853 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml @@ -6,6 +6,7 @@ import QtQuick.Controls 2.0 import UM 1.3 as UM import Cura 1.0 as Cura +// TODO: Theme & documentation! // The expandable component has 3 major sub components: // * The headerItem Always visible and should hold some info about what happens if the component is expanded // * The popupItem The content that needs to be shown if the component is expanded. diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml index d14277a1ff..9ffb1eabb4 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml @@ -41,7 +41,6 @@ Item id: buildplateIcon anchors.centerIn: parent color: "#0a0850" // TODO: Theme! (Standard purple) - elide: Text.ElideRight height: parent.height source: "../svg/icons/buildplate.svg" width: height @@ -52,6 +51,7 @@ Item { id: buildplateLabel color: "#191919" // TODO: Theme! + elide: Text.ElideRight font: UM.Theme.getFont("very_small") // 12pt, regular text: "" diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml index 6d02c40776..ada6f8a644 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml @@ -47,7 +47,7 @@ Item elide: Text.ElideRight font: UM.Theme.getFont("medium") // 14pt, regular anchors.verticalCenter: parent.verticalCenter - width: 216 * screenScaleFactor // TODO: Theme! + width: 216 * screenScaleFactor // TODO: Theme! (Should match column size) // FIXED-LINE-HEIGHT: height: 18 * screenScaleFactor // TODO: Theme! @@ -61,42 +61,72 @@ Item elide: Text.ElideRight font: UM.Theme.getFont("medium") // 14pt, regular anchors.verticalCenter: parent.verticalCenter - width: 216 * screenScaleFactor // TODO: Theme! + width: 216 * screenScaleFactor // TODO: Theme! (Should match column size) // FIXED-LINE-HEIGHT: height: 18 * screenScaleFactor // TODO: Theme! verticalAlignment: Text.AlignVCenter } - Label + Item { - color: "#374355" - elide: Text.ElideRight - font: UM.Theme.getFont("medium") // 14pt, regular - text: { - if (printJob !== null) { - if (printJob.assignedPrinter == null) - { - if (printJob.state == "error") - { - return catalog.i18nc("@label", "Waiting for: Unavailable printer") - } - return catalog.i18nc("@label", "Waiting for: First available") - } - else - { - return catalog.i18nc("@label", "Waiting for: ") + printJob.assignedPrinter.name - } - } - return "" - } - visible: printJob anchors.verticalCenter: parent.verticalCenter - width: 216 * screenScaleFactor // TODO: Theme! + height: childrenRect.height + width: childrenRect.width - // FIXED-LINE-HEIGHT: - height: 18 * screenScaleFactor // TODO: Theme! - verticalAlignment: Text.AlignVCenter + Label + { + id: printerAssignmentLabel + anchors.verticalCenter: parent.verticalCenter + color: "#374355" + elide: Text.ElideRight + font: UM.Theme.getFont("medium") // 14pt, regular + text: { + if (printJob !== null) { + if (printJob.assignedPrinter == null) + { + if (printJob.state == "error") + { + return catalog.i18nc("@label", "Unavailable printer") + } + return catalog.i18nc("@label", "First available") + } + else + { + return printJob.assignedPrinter.name + } + } + return "" + } + visible: printJob + + // FIXED-LINE-HEIGHT: + height: 18 * screenScaleFactor // TODO: Theme! + verticalAlignment: Text.AlignVCenter + } + + Row + { + id: printerFamilyPills + anchors + { + left: printerAssignmentLabel.right; + leftMargin: 12 // TODO: Theme! + verticalCenter: parent.verticalCenter + } + height: childrenRect.height + spacing: 6 // TODO: Theme! + + Repeater + { + id: compatiblePills + delegate: MonitorPrinterPill + { + text: modelData + } + model: printJob ? printJob.compatibleMachineFamilies : [] + } + } } } drawerItem: Row @@ -106,14 +136,17 @@ Item left: parent.left leftMargin: 74 * screenScaleFactor // TODO: Theme! } - height: 96 * screenScaleFactor // TODO: Theme! + height: 108 * screenScaleFactor // TODO: Theme! spacing: 18 * screenScaleFactor // TODO: Theme! MonitorPrinterConfiguration { id: printerConfiguration anchors.verticalCenter: parent.verticalCenter - printJob: base.printJob + buildplate: "Glass" + config0: base.printJob.configuration.extruderConfigurations[0] + config1: base.printJob.configuration.extruderConfigurations[1] + height: 72 * screenScaleFactor // TODO: Theme! } Label { text: printJob && printJob.owner ? printJob.owner : "" @@ -128,4 +161,19 @@ Item } } } + + PrintJobContextMenu + { + id: contextButton + anchors + { + right: parent.right; + rightMargin: 8 * screenScaleFactor // TODO: Theme! + top: parent.top + topMargin: 8 * screenScaleFactor // TODO: Theme! + } + printJob: base.printJob + width: 32 * screenScaleFactor // TODO: Theme! + height: 32 * screenScaleFactor // TODO: Theme! + } } \ No newline at end of file diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterConfiguration.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterConfiguration.qml index 5d4d408b8e..a31c8bbd99 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterConfiguration.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterConfiguration.qml @@ -6,17 +6,26 @@ import QtQuick.Controls 2.0 import UM 1.3 as UM /** - * + * The MonitorPrinterConfiguration accepts 2 configuration objects as input and + * applies them to a MonitorBuildplateConfiguration instance and two instances + * of MonitorExtruderConfiguration. It's used in both the MonitorPrintJobCard + * component as well as the MonitorPrinterCard component. */ Item { id: base - property var printJob: null - property var config0: printJob ? printJob.configuration.extruderConfigurations[0] : null - property var config1: printJob ? printJob.configuration.extruderConfigurations[1] : null + // Extracted buildplate configuration + property alias buildplate: buildplateConfig.buildplate - height: 72 * screenScaleFactor // TODO: Theme! + // Extracted extruder configuration for position 0 + property var config0: null + + // Extracted extruder configuration for position 1 + property var config1: null + + // Default size, but should be stretched to fill parent + height: 72 * parent.height width: 450 * screenScaleFactor // TODO: Theme! Row @@ -25,8 +34,8 @@ Item MonitorExtruderConfiguration { - color: config0 ? config0.activeMaterial.color : "#eeeeee" // TODO: Theme! - material: config0 ? config0.activeMaterial.name : "" + color: config0 && config0.activeMaterial ? config0.activeMaterial.color : "#eeeeee" // TODO: Theme! + material: config0 && config0.activeMaterial ? config0.activeMaterial.name : "" position: config0.position printCore: config0 ? config0.hotendID : "" visible: config0 @@ -37,8 +46,8 @@ Item MonitorExtruderConfiguration { - color: config1 ? config1.activeMaterial.color : "#eeeeee" // TODO: Theme! - material: config1 ? config1.activeMaterial.name : "" + color: config1 && config1.activeMaterial ? config1.activeMaterial.color : "#eeeeee" // TODO: Theme! + material: config1 && config1.activeMaterial ? config1.activeMaterial.name : "" position: config1.position printCore: config1 ? config1.hotendID : "" visible: config1 @@ -50,7 +59,8 @@ Item MonitorBuildplateConfiguration { + id: buildplateConfig anchors.bottom: parent.bottom - buildplate: "Glass" + buildplate: "Glass" // 'Glass' as a default } } \ No newline at end of file diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterPill.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterPill.qml new file mode 100644 index 0000000000..cd78f1b11f --- /dev/null +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterPill.qml @@ -0,0 +1,34 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 1.4 +import UM 1.2 as UM + +/** + * A MonitorPrinterPill is a blue-colored tag indicating which printers a print + * job is compatible with. It is used by the MonitorPrintJobCard component. + */ +Item +{ + // The printer name + property alias text: printerNameLabel.text; + + implicitHeight: 18 * screenScaleFactor // TODO: Theme! + implicitWidth: printerNameLabel.contentWidth + 12 // TODO: Theme! + + Rectangle { + id: background + anchors.fill: parent + color: "#e4e4f2" // TODO: Theme! + radius: 2 * screenScaleFactor // TODO: Theme! + } + + Label { + id: printerNameLabel + anchors.centerIn: parent + color: "#535369" // TODO: Theme! + text: "" + font.pointSize: 10 + } +} \ No newline at end of file diff --git a/plugins/UM3NetworkPrinting/resources/svg/icons/external_link.svg b/plugins/UM3NetworkPrinting/resources/svg/icons/external_link.svg new file mode 100644 index 0000000000..a2130fb97b --- /dev/null +++ b/plugins/UM3NetworkPrinting/resources/svg/icons/external_link.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file From 669648d3e11a969ec75b83c5d5b763cef9705f71 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 20 Nov 2018 16:28:21 +0100 Subject: [PATCH 0298/1292] Improve the toolbar style by modifying the rectangles and the behavior to get a rounded rectangle on the right-top and right-bottom. Contributes to CURA-5962. --- resources/qml/ExtruderButton.qml | 16 ++---- resources/qml/Toolbar.qml | 36 ++++++++---- resources/themes/cura-light/styles.qml | 80 ++++++++++++++++++++------ resources/themes/cura-light/theme.json | 6 +- 4 files changed, 92 insertions(+), 46 deletions(-) diff --git a/resources/qml/ExtruderButton.qml b/resources/qml/ExtruderButton.qml index 7923521658..cdd0386d30 100644 --- a/resources/qml/ExtruderButton.qml +++ b/resources/qml/ExtruderButton.qml @@ -21,6 +21,9 @@ Button checked: Cura.ExtruderManager.selectedObjectExtruders.indexOf(extruder.id) != -1 enabled: UM.Selection.hasSelection && extruder.stack.isEnabled + property bool isFirstElement: extrudersModel.getItem(0).name == model.name + property bool isLastElement: extrudersModel.getItem(extrudersModel.rowCount() - 1).name == model.name + Item { anchors.centerIn: parent @@ -32,18 +35,7 @@ Button { anchors.centerIn: parent text: index + 1 - color: - { - if (base.checked) - { - return UM.Theme.getColor("toolbar_button_text_active") - } - else if(base.hovered) - { - return UM.Theme.getColor("toolbar_button_text_hover") - } - return UM.Theme.getColor("toolbar_button_text") - } + color: UM.Theme.getColor("toolbar_button_text") font: UM.Theme.getFont("default_bold") } } diff --git a/resources/qml/Toolbar.qml b/resources/qml/Toolbar.qml index 9955ceeba7..81896f1a75 100644 --- a/resources/qml/Toolbar.qml +++ b/resources/qml/Toolbar.qml @@ -28,12 +28,16 @@ Item // Used to create a rounded rectangle behind the toolButtons Rectangle { - anchors.fill: toolButtons - anchors.leftMargin: -radius + anchors + { + fill: toolButtons + leftMargin: -radius - border.width + rightMargin: -border.width + topMargin: -border.width + bottomMargin: -border.width + } radius: UM.Theme.getSize("default_radius").width - border.width: UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("lining") - color: UM.Theme.getColor("toolbar_background") + color: UM.Theme.getColor("lining") } Column @@ -42,13 +46,13 @@ Item anchors.top: parent.top anchors.right: parent.right - spacing: UM.Theme.getSize("button_lining").width + spacing: UM.Theme.getSize("default_lining").height Repeater { id: repeat - model: UM.ToolModel { } + model: UM.ToolModel { id: toolsModel } width: childrenRect.width height: childrenRect.height Button @@ -60,6 +64,9 @@ Item enabled: model.enabled && UM.Selection.hasSelection && UM.Controller.toolsEnabled style: UM.Theme.styles.toolbar_button + property bool isFirstElement: toolsModel.getItem(0).id == model.id + property bool isLastElement: toolsModel.getItem(toolsModel.rowCount() - 1).id == model.id + onCheckedChanged: { if (checked) @@ -93,12 +100,16 @@ Item // Used to create a rounded rectangle behind the extruderButtons Rectangle { - anchors.fill: extruderButtons - anchors.leftMargin: -radius + anchors + { + fill: extruderButtons + leftMargin: -radius - border.width + rightMargin: -border.width + topMargin: -border.width + bottomMargin: -border.width + } radius: UM.Theme.getSize("default_radius").width - border.width: UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("lining") - color: UM.Theme.getColor("toolbar_background") + color: UM.Theme.getColor("lining") } Column @@ -108,6 +119,7 @@ Item anchors.topMargin: UM.Theme.getSize("default_margin").height anchors.top: toolButtons.bottom anchors.right: parent.right + spacing: UM.Theme.getSize("default_lining").height Repeater { diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index 58035ae3bd..723b393efa 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -175,11 +175,68 @@ QtObject { ButtonStyle { - background: Item + background: Rectangle { - implicitWidth: Theme.getSize("button").width; - implicitHeight: Theme.getSize("button").height; + implicitWidth: Theme.getSize("button").width + implicitHeight: Theme.getSize("button").height + color: + { + if (control.checked && control.hovered) + { + return Theme.getColor("toolbar_button_active_hover") + } + else if (control.checked) + { + return Theme.getColor("toolbar_button_active") + } + else if(control.hovered) + { + return Theme.getColor("toolbar_button_hover") + } + return Theme.getColor("toolbar_background") + } + radius: UM.Theme.getSize("default_radius").width + Rectangle + { + id: topSquare + anchors + { + left: parent.left + right: parent.right + top: parent.top + } + height: parent.radius + color: control.isFirstElement ? "transparent" : parent.color + } + + Rectangle + { + id: bottomSquare + anchors + { + left: parent.left + right: parent.right + bottom: parent.bottom + } + height: parent.radius + color: control.isLastElement ? "transparent" : parent.color + } + + Rectangle + { + id: leftSquare + anchors + { + left: parent.left + top: parent.top + bottom: parent.bottom + } + width: parent.radius + color: parent.color + } + + // This is the tooltip UM.PointingRectangle { id: button_tooltip @@ -223,22 +280,7 @@ QtObject source: control.iconSource; width: Theme.getSize("button_icon").width; height: Theme.getSize("button_icon").height; - color: - { - if (control.checked && control.hovered) - { - return Theme.getColor("toolbar_button_text_active_hover"); - } - else if (control.checked) - { - return Theme.getColor("toolbar_button_text_active"); - } - else if(control.hovered) - { - return Theme.getColor("toolbar_button_text_hover"); - } - return Theme.getColor("toolbar_button_text"); - } + color: Theme.getColor("toolbar_button_text"); sourceSize: Theme.getSize("button_icon") } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index f4d50e4c79..d00e998cc8 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -123,9 +123,9 @@ "warning": [255, 190, 35, 255], "toolbar_button_text": [10, 8, 80, 255], - "toolbar_button_text_hover": [50, 130, 255, 255], - "toolbar_button_text_active": [50, 130, 255, 255], - "toolbar_button_text_active_hover": [50, 130, 255, 255], + "toolbar_button_hover": [232, 242, 252, 255], + "toolbar_button_active": [232, 242, 252, 255], + "toolbar_button_active_hover": [232, 242, 252, 255], "button": [31, 36, 39, 255], "button_hover": [68, 72, 75, 255], From 481ca8cd2f2e61ba7591695c7b318346cad4364d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Tue, 20 Nov 2018 16:33:52 +0100 Subject: [PATCH 0299/1292] Fixed some bugs and added the color_code field to the named tuple --- plugins/UM3NetworkPrinting/src/Models.py | 1 + .../UM3NetworkPrinting/src/SendMaterialJob.py | 20 +++++++++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Models.py b/plugins/UM3NetworkPrinting/src/Models.py index e8efa577f6..a9210ac5b4 100644 --- a/plugins/UM3NetworkPrinting/src/Models.py +++ b/plugins/UM3NetworkPrinting/src/Models.py @@ -23,6 +23,7 @@ LocalMaterial = namedtuple('LocalMaterial', [ 'brand', 'material', 'color_name', + 'color_code', 'description', 'adhesion_info', 'approximate_diameter', diff --git a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py index cbe79aef6a..0599101379 100644 --- a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py @@ -2,6 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. import json import os +import re import urllib.parse from typing import Dict, TYPE_CHECKING, Set @@ -19,7 +20,6 @@ from .Models import ClusterMaterial, LocalMaterial if TYPE_CHECKING: from .ClusterUM3OutputDevice import ClusterUM3OutputDevice - ## Asynchronous job to send material profiles to the printer. # # This way it won't freeze up the interface while sending those materials. @@ -50,7 +50,7 @@ class SendMaterialJob(Job): self._sendMissingMaterials(remote_materials_by_guid) except json.JSONDecodeError: Logger.logException("w", "Error parsing materials from printer") - except KeyError: + except TypeError: Logger.logException("w", "Error parsing materials from printer") ## Determine which materials should be updated and send them to the printer. @@ -75,7 +75,8 @@ class SendMaterialJob(Job): ## From the local and remote materials, determine which ones should be synchronized. # - # Makes a Set containing only the materials that are not on the printer yet or the ones that are newer in Cura. + # Makes a Set of id's containing only the id's of the materials that are not on the printer yet or the ones that + # are newer in Cura. # # \param local_materials The local materials by GUID. # \param remote_materials The remote materials by GUID. @@ -157,7 +158,7 @@ class SendMaterialJob(Job): @classmethod def _parseReply(cls, reply: QNetworkReply) -> Dict[str, ClusterMaterial]: remote_materials = json.loads(reply.readAll().data().decode("utf-8")) - return {material["id"]: ClusterMaterial(**material) for material in remote_materials} + return {material["guid"]: ClusterMaterial(**material) for material in remote_materials} ## Retrieves a list of local materials # @@ -170,12 +171,19 @@ class SendMaterialJob(Job): material_containers = container_registry.findContainersMetadata(type = "material") # Find the latest version of all material containers in the registry. - local_materials = {} # type: Dict[str, LocalMaterial] for material in material_containers: try: material = LocalMaterial(**material) + + # material version must be an int + if not re.match("\d+", material.version): + Logger.logException("w", "Local material {} has invalid version '{}'." + .format(material["id"], material.version)) + continue + if material.GUID not in result or material.version > result.get(material.GUID).version: - local_materials[material.GUID] = material + result[material.GUID] = material except ValueError: Logger.logException("w", "Local material {} has invalid values.".format(material["id"])) + return result From ca6074429290b6ae5fa1f3ccfbfa74107ed1284a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Tue, 20 Nov 2018 16:34:11 +0100 Subject: [PATCH 0300/1292] Made the tests work with the named tuples Tests only use the _onGetRemoteMaterial --- .../tests/TestSendMaterialJob.py | 313 +++++++----------- 1 file changed, 123 insertions(+), 190 deletions(-) diff --git a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py index 73bca2b0ad..f4604580fe 100644 --- a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py @@ -1,53 +1,23 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +import io import json - -from typing import Any, List -from unittest import TestCase +from unittest import TestCase, mock from unittest.mock import patch, call from PyQt5.QtCore import QByteArray -from UM.Settings.ContainerRegistry import ContainerInterface, ContainerRegistryInterface, DefinitionContainerInterface -from plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice import ClusterUM3OutputDevice +from UM.MimeTypeDatabase import MimeType +from cura.CuraApplication import CuraApplication from plugins.UM3NetworkPrinting.src.SendMaterialJob import SendMaterialJob -class ContainerRegistryMock(ContainerRegistryInterface): - - def __init__(self): - self.containersMetaData = None - - def findContainers(self, *, ignore_case: bool = False, **kwargs: Any) -> List[ContainerInterface]: - raise NotImplementedError() - - def findDefinitionContainers(self, **kwargs: Any) -> List[DefinitionContainerInterface]: - raise NotImplementedError() - - @classmethod - def getApplication(cls) -> "Application": - raise NotImplementedError() - - def getEmptyInstanceContainer(self) -> "InstanceContainer": - raise NotImplementedError() - - def isReadOnly(self, container_id: str) -> bool: - raise NotImplementedError() - - def setContainersMetadata(self, value): - self.containersMetaData = value - - def findContainersMetadata(self, type): - return self.containersMetaData - - -class MockOutputDevice(ClusterUM3OutputDevice): - def _createFormPart(self, content_header, data, content_type=None): - return "xxx" - - +@patch("builtins.open", lambda _, __: io.StringIO("")) +@patch("UM.MimeTypeDatabase.MimeTypeDatabase.getMimeTypeForFile", + lambda _: MimeType(name = "application/x-ultimaker-material-profile", comment = "Ultimaker Material Profile", + suffixes = ["xml.fdm_material"])) +@patch("UM.Resources.Resources.getAllResourcesOfType", lambda _: ["/materials/generic_pla_white.xml.fdm_material"]) class TestSendMaterialJob(TestCase): - _LOCAL_MATERIAL_WHITE = {"type": "material", "status": "unknown", "id": "generic_pla_white", "base_file": "generic_pla_white", "setting_version": 5, "name": "White PLA", "brand": "Generic", "material": "PLA", "color_name": "White", @@ -88,11 +58,11 @@ class TestSendMaterialJob(TestCase): job.run() # We expect the materials endpoint to be called when the job runs. - device_mock.get.assert_called_with("materials/", on_finished=job._onGetRemoteMaterials) + device_mock.get.assert_called_with("materials/", on_finished = job._onGetRemoteMaterials) @patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") @patch("PyQt5.QtNetwork.QNetworkReply") - def test_sendMissingMaterials_withFailedRequest(self, reply_mock, device_mock): + def test__onGetRemoteMaterials_withFailedRequest(self, reply_mock, device_mock): reply_mock.attribute.return_value = 404 job = SendMaterialJob(device_mock) job._onGetRemoteMaterials(reply_mock) @@ -103,7 +73,7 @@ class TestSendMaterialJob(TestCase): @patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") @patch("PyQt5.QtNetwork.QNetworkReply") - def test_sendMissingMaterials_withBadJsonAnswer(self, reply_mock, device_mock): + def test__onGetRemoteMaterials_withBadJsonAnswer(self, reply_mock, device_mock): reply_mock.attribute.return_value = 200 reply_mock.readAll.return_value = QByteArray(b"Six sick hicks nick six slick bricks with picks and sticks.") job = SendMaterialJob(device_mock) @@ -116,7 +86,7 @@ class TestSendMaterialJob(TestCase): @patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") @patch("PyQt5.QtNetwork.QNetworkReply") - def test_sendMissingMaterials_withMissingGuid(self, reply_mock, device_mock): + def test__onGetRemoteMaterials_withMissingGuidInRemoteMaterial(self, reply_mock, device_mock): reply_mock.attribute.return_value = 200 remote_material_without_guid = self._REMOTE_MATERIAL_WHITE.copy() del remote_material_without_guid["guid"] @@ -127,151 +97,114 @@ class TestSendMaterialJob(TestCase): # We expect the reply to be called once to try to get the printers from the list (readAll()). # Given that parsing fails we do not expect the device to be called for any follow up. self.assertEqual([call.attribute(0), call.readAll()], reply_mock.method_calls) - self.assertEqual(1, device_mock.createFormPart.call_count) + self.assertEqual(0, device_mock.createFormPart.call_count) - # @patch("UM.Resources.Resources.getAllResourcesOfType", lambda _: []) - # @patch("PyQt5.QtNetwork.QNetworkReply") - # def test_sendMissingMaterials_WithInvalidVersionInLocalMaterial(self, reply_mock): - # reply_mock.attribute.return_value = 200 - # reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTEMATERIAL_WHITE]).encode("ascii")) - # - # containerRegistry = ContainerRegistryMock() - # localMaterialWhiteWithInvalidVersion = self._LOCALMATERIAL_WHITE.copy() - # localMaterialWhiteWithInvalidVersion["version"] = "one" - # containerRegistry.setContainersMetadata([localMaterialWhiteWithInvalidVersion]) - # - # with mock.patch.object(Logger, "log", new=new_log): - # with mock.patch.object(ContainerRegistry, "getInstance", lambda: containerRegistry): - # SendMaterialJob(None).sendMissingMaterials(reply_mock) - # - # reply_mock.attribute.assert_called_with(0) - # self.assertEqual(reply_mock.method_calls, [call.attribute(0), call.readAll()]) - # self._assertLogEntries([("e", "Material generic_pla_white has invalid version number one.")], _logentries) - # - # @patch("UM.Resources.Resources.getAllResourcesOfType", lambda _: []) - # @patch("PyQt5.QtNetwork.QNetworkReply") - # def test_sendMissingMaterials_WithMultipleLocalVersionsLowFirst(self, reply_mock): - # reply_mock.attribute.return_value = 200 - # reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTEMATERIAL_WHITE]).encode("ascii")) - # - # containerRegistry = ContainerRegistryMock() - # localMaterialWhiteWithHigherVersion = self._LOCALMATERIAL_WHITE.copy() - # localMaterialWhiteWithHigherVersion["version"] = "2" - # containerRegistry.setContainersMetadata([self._LOCALMATERIAL_WHITE, localMaterialWhiteWithHigherVersion]) - # - # with mock.patch.object(Logger, "log", new=new_log): - # with mock.patch.object(ContainerRegistry, "getInstance", lambda: containerRegistry): - # SendMaterialJob(None).sendMissingMaterials(reply_mock) - # - # reply_mock.attribute.assert_called_with(0) - # self.assertEqual(reply_mock.method_calls, [call.attribute(0), call.readAll()]) - # self._assertLogEntries([], _logentries) - # - # @patch("UM.Resources.Resources.getAllResourcesOfType", lambda _: []) - # @patch("PyQt5.QtNetwork.QNetworkReply") - # def test_sendMissingMaterials_MaterialMissingOnPrinter(self, reply_mock): - # reply_mock.attribute.return_value = 200 - # reply_mock.readAll.return_value = QByteArray( - # json.dumps([self._REMOTEMATERIAL_WHITE]).encode("ascii")) - # - # containerRegistry = ContainerRegistryMock() - # containerRegistry.setContainersMetadata([self._LOCALMATERIAL_WHITE, self._LOCALMATERIAL_BLACK]) - # - # with mock.patch.object(Logger, "log", new=new_log): - # with mock.patch.object(ContainerRegistry, "getInstance", lambda: containerRegistry): - # SendMaterialJob(None).sendMissingMaterials(reply_mock) - # - # reply_mock.attribute.assert_called_with(0) - # self.assertEqual(reply_mock.method_calls, [call.attribute(0), call.readAll()]) - # self._assertLogEntries([], _logentries) - # - # @patch("builtins.open", lambda a, b: io.StringIO("")) - # @patch("UM.MimeTypeDatabase.MimeTypeDatabase.getMimeTypeForFile", - # lambda _: MimeType(name="application/x-ultimaker-material-profile", comment="Ultimaker Material Profile", - # suffixes=["xml.fdm_material"])) - # @patch("UM.Resources.Resources.getAllResourcesOfType", lambda _: ["/materials/generic_pla_white.xml.fdm_material"]) - # @patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") - # def test_sendMaterialsToPrinter(self, device_mock): - # device_mock._createFormPart.return_value = "_xXx_" - # with mock.patch.object(Logger, "log", new=new_log): - # job = SendMaterialJob(device_mock) - # job.sendMaterialsToPrinter({"generic_pla_white"}) - # - # self._assertLogEntries([("d", "Syncing material generic_pla_white with cluster.")], _logentries) - # self.assertEqual([call._createFormPart("name="file"; filename="generic_pla_white.xml.fdm_material"", ""), - # call.postFormWithParts(on_finished=job.sendingFinished, parts = ["_xXx_"], target = "materials/")], device_mock.method_calls) - # - # @patch("PyQt5.QtNetwork.QNetworkReply") - # def test_sendingFinished_success(self, reply_mock) -> None: - # reply_mock.attribute.return_value = 200 - # with mock.patch.object(Logger, "log", new=new_log): - # SendMaterialJob(None).sendingFinished(reply_mock) - # - # reply_mock.attribute.assert_called_once_with(0) - # self.assertEqual(0, len(_logentries)) - # - # @patch("PyQt5.QtNetwork.QNetworkReply") - # def test_sendingFinished_failed(self, reply_mock) -> None: - # reply_mock.attribute.return_value = 404 - # reply_mock.readAll.return_value = QByteArray(b"Six sick hicks nick six slick bricks with picks and sticks.") - # - # with mock.patch.object(Logger, "log", new=new_log): - # SendMaterialJob(None).sendingFinished(reply_mock) - # - # reply_mock.attribute.assert_called_with(0) - # self.assertEqual(reply_mock.method_calls, [call.attribute(0), call.attribute(0), call.readAll()]) - # - # self._assertLogEntries([ - # ("e", "Received error code from printer when syncing material: 404"), - # ("e", "Six sick hicks nick six slick bricks with picks and sticks.") - # ], _logentries) - # - # @patch("PyQt5.QtNetwork.QNetworkReply") - # def test_parseReply(self, reply_mock): - # reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTEMATERIAL_WHITE]).encode("ascii")) - # - # response = SendMaterialJob._parseReply(reply_mock) - # - # self.assertTrue(len(response) == 1) - # self.assertEqual(next(iter(response.values())), ClusterMaterial(**self._REMOTEMATERIAL_WHITE)) - # - # @patch("PyQt5.QtNetwork.QNetworkReply") - # def test_parseReplyWithInvalidMaterial(self, reply_mock): - # remoteMaterialWithInvalidVersion = self._REMOTEMATERIAL_WHITE.copy() - # remoteMaterialWithInvalidVersion["version"] = "one" - # reply_mock.readAll.return_value = QByteArray(json.dumps([remoteMaterialWithInvalidVersion]).encode("ascii")) - # - # with self.assertRaises(ValueError): - # SendMaterialJob._parseReply(reply_mock) - # - # def test__getLocalMaterials(self): - # containerRegistry = ContainerRegistryMock() - # containerRegistry.setContainersMetadata([self._LOCALMATERIAL_WHITE, self._LOCALMATERIAL_BLACK]) - # - # with mock.patch.object(Logger, "log", new=new_log): - # with mock.patch.object(ContainerRegistry, "getInstance", lambda: containerRegistry): - # local_materials = SendMaterialJob(None)._getLocalMaterials() - # - # self.assertTrue(len(local_materials) == 2) - # - # def test__getLocalMaterialsWithMultipleVersions(self): - # containerRegistry = ContainerRegistryMock() - # localMaterialWithNewerVersion = self._LOCALMATERIAL_WHITE.copy() - # localMaterialWithNewerVersion["version"] = 2 - # containerRegistry.setContainersMetadata([self._LOCALMATERIAL_WHITE, localMaterialWithNewerVersion]) - # - # with mock.patch.object(Logger, "log", new=new_log): - # with mock.patch.object(ContainerRegistry, "getInstance", lambda: containerRegistry): - # local_materials = SendMaterialJob(None)._getLocalMaterials() - # - # self.assertTrue(len(local_materials) == 1) - # self.assertTrue(list(local_materials.values())[0].version == 2) - # - # containerRegistry.setContainersMetadata([localMaterialWithNewerVersion, self._LOCALMATERIAL_WHITE]) - # - # with mock.patch.object(Logger, "log", new=new_log): - # with mock.patch.object(ContainerRegistry, "getInstance", lambda: containerRegistry): - # local_materials = SendMaterialJob(None)._getLocalMaterials() - # - # self.assertTrue(len(local_materials) == 1) - # self.assertTrue(list(local_materials.values())[0].version == 2) + @patch("cura.Settings.CuraContainerRegistry") + @patch("cura.CuraApplication") + @patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") + @patch("PyQt5.QtNetwork.QNetworkReply") + def test__onGetRemoteMaterials_withInvalidVersionInLocalMaterial(self, reply_mock, device_mock, application_mock, + container_registry_mock): + reply_mock.attribute.return_value = 200 + reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTE_MATERIAL_WHITE]).encode("ascii")) + + localMaterialWhiteWithInvalidVersion = self._LOCAL_MATERIAL_WHITE.copy() + localMaterialWhiteWithInvalidVersion["version"] = "one" + container_registry_mock.findContainersMetadata.return_value = [localMaterialWhiteWithInvalidVersion] + + application_mock.getContainerRegistry.return_value = container_registry_mock + + with mock.patch.object(CuraApplication, "getInstance", new = lambda: application_mock): + job = SendMaterialJob(device_mock) + job._onGetRemoteMaterials(reply_mock) + + self.assertEqual([call.attribute(0), call.readAll()], reply_mock.method_calls) + self.assertEqual([call.getContainerRegistry()], application_mock.method_calls) + self.assertEqual([call.findContainersMetadata(type = "material")], container_registry_mock.method_calls) + self.assertEqual(0, device_mock.createFormPart.call_count) + + @patch("cura.Settings.CuraContainerRegistry") + @patch("cura.CuraApplication") + @patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") + @patch("PyQt5.QtNetwork.QNetworkReply") + def test__onGetRemoteMaterials_withNoUpdate(self, reply_mock, device_mock, application_mock, + container_registry_mock): + application_mock.getContainerRegistry.return_value = container_registry_mock + + device_mock.createFormPart.return_value = "_xXx_" + + container_registry_mock.findContainersMetadata.return_value = [self._LOCAL_MATERIAL_WHITE] + + reply_mock.attribute.return_value = 200 + reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTE_MATERIAL_WHITE]).encode("ascii")) + + with mock.patch.object(CuraApplication, "getInstance", new = lambda: application_mock): + job = SendMaterialJob(device_mock) + job._onGetRemoteMaterials(reply_mock) + + self.assertEqual([call.attribute(0), call.readAll()], reply_mock.method_calls) + self.assertEqual([call.getContainerRegistry()], application_mock.method_calls) + self.assertEqual([call.findContainersMetadata(type = "material")], container_registry_mock.method_calls) + self.assertEqual(0, device_mock.createFormPart.call_count) + self.assertEqual(0, device_mock.postFormWithParts.call_count) + + @patch("cura.Settings.CuraContainerRegistry") + @patch("cura.CuraApplication") + @patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") + @patch("PyQt5.QtNetwork.QNetworkReply") + def test__onGetRemoteMaterials_withUpdatedMaterial(self, reply_mock, device_mock, application_mock, + container_registry_mock): + application_mock.getContainerRegistry.return_value = container_registry_mock + + device_mock.createFormPart.return_value = "_xXx_" + + localMaterialWhiteWithHigherVersion = self._LOCAL_MATERIAL_WHITE.copy() + localMaterialWhiteWithHigherVersion["version"] = "2" + container_registry_mock.findContainersMetadata.return_value = [localMaterialWhiteWithHigherVersion] + + reply_mock.attribute.return_value = 200 + reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTE_MATERIAL_WHITE]).encode("ascii")) + + with mock.patch.object(CuraApplication, "getInstance", new = lambda: application_mock): + job = SendMaterialJob(device_mock) + job._onGetRemoteMaterials(reply_mock) + + self.assertEqual([call.attribute(0), call.readAll()], reply_mock.method_calls) + self.assertEqual([call.getContainerRegistry()], application_mock.method_calls) + self.assertEqual([call.findContainersMetadata(type = "material")], container_registry_mock.method_calls) + self.assertEqual(1, device_mock.createFormPart.call_count) + self.assertEqual(1, device_mock.postFormWithParts.call_count) + self.assertEquals( + [call.createFormPart("name=\"file\"; filename=\"generic_pla_white.xml.fdm_material\"", ""), + call.postFormWithParts(target = "materials/", parts = ["_xXx_"], on_finished = job.sendingFinished)], + device_mock.method_calls) + + @patch("cura.Settings.CuraContainerRegistry") + @patch("cura.CuraApplication") + @patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") + @patch("PyQt5.QtNetwork.QNetworkReply") + def test__onGetRemoteMaterials_withNewMaterial(self, reply_mock, device_mock, application_mock, + container_registry_mock): + application_mock.getContainerRegistry.return_value = container_registry_mock + + device_mock.createFormPart.return_value = "_xXx_" + + container_registry_mock.findContainersMetadata.return_value = [self._LOCAL_MATERIAL_WHITE, + self._LOCAL_MATERIAL_BLACK] + + reply_mock.attribute.return_value = 200 + reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTE_MATERIAL_BLACK]).encode("ascii")) + + with mock.patch.object(CuraApplication, "getInstance", new = lambda: application_mock): + job = SendMaterialJob(device_mock) + job._onGetRemoteMaterials(reply_mock) + + self.assertEqual([call.attribute(0), call.readAll()], reply_mock.method_calls) + self.assertEqual([call.getContainerRegistry()], application_mock.method_calls) + self.assertEqual([call.findContainersMetadata(type = "material")], container_registry_mock.method_calls) + self.assertEqual(1, device_mock.createFormPart.call_count) + self.assertEqual(1, device_mock.postFormWithParts.call_count) + self.assertEquals( + [call.createFormPart("name=\"file\"; filename=\"generic_pla_white.xml.fdm_material\"", ""), + call.postFormWithParts(target = "materials/", parts = ["_xXx_"], on_finished = job.sendingFinished)], + device_mock.method_calls) From f3338aa187bfe607664d0d79d5848d7cdee5fc06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Tue, 20 Nov 2018 16:53:01 +0100 Subject: [PATCH 0301/1292] Fixed the failing tests --- plugins/UM3NetworkPrinting/src/SendMaterialJob.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py index 0599101379..fe0cd98964 100644 --- a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py @@ -84,8 +84,9 @@ class SendMaterialJob(Job): def _determineMaterialsToSend(local_materials: Dict[str, LocalMaterial], remote_materials: Dict[str, ClusterMaterial]) -> Set[str]: return { - material.id for guid, material in local_materials.items() - if guid not in remote_materials or material.version > remote_materials[guid].version + material.id + for guid, material in local_materials.items() + if guid not in remote_materials or int(material.version) > remote_materials[guid].version } ## Send the materials to the printer. From 4e8979334e0d794b2cd8cae72ce9c351890577c8 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 20 Nov 2018 19:18:48 +0100 Subject: [PATCH 0302/1292] Switch Ultimaker Account OAuth2 client The new client has access to more permissions and is labeled as "Ultimaker Cura" instead of "Cura Backups Plugin". Also removes `self._cloud_api_root` as that's not used anymore now that `self._oauth_root` is used for the redirect URLs. --- cura/API/Account.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cura/API/Account.py b/cura/API/Account.py index 397e220478..64d63c7025 100644 --- a/cura/API/Account.py +++ b/cura/API/Account.py @@ -38,13 +38,12 @@ class Account(QObject): self._callback_port = 32118 self._oauth_root = "https://account.ultimaker.com" - self._cloud_api_root = "https://api.ultimaker.com" self._oauth_settings = OAuth2Settings( OAUTH_SERVER_URL= self._oauth_root, CALLBACK_PORT=self._callback_port, CALLBACK_URL="http://localhost:{}/callback".format(self._callback_port), - CLIENT_ID="um---------------ultimaker_cura_drive_plugin", + CLIENT_ID="um----------------------------ultimaker_cura", CLIENT_SCOPES="account.user.read drive.backup.read drive.backup.write packages.download packages.rating.read packages.rating.write", AUTH_DATA_PREFERENCE_KEY="general/ultimaker_auth_data", AUTH_SUCCESS_REDIRECT="{}/app/auth-success".format(self._oauth_root), From c7bb6931f48604aebcefaaa8ed8007edc4f49f9f Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 20 Nov 2018 23:44:28 +0100 Subject: [PATCH 0303/1292] Refactor networked output device All networking related stuff is moved to a separate class called NetworkClient for reusability. As example it is now also used in the WIP CloudOutputDeviceManager to clean up network calling there. --- cura/NetworkClient.py | 220 ++++++++++++++++++ .../NetworkedPrinterOutputDevice.py | 189 ++------------- .../src/Cloud/CloudOutputDeviceManager.py | 43 ++-- 3 files changed, 260 insertions(+), 192 deletions(-) create mode 100644 cura/NetworkClient.py diff --git a/cura/NetworkClient.py b/cura/NetworkClient.py new file mode 100644 index 0000000000..ce9cc50cf6 --- /dev/null +++ b/cura/NetworkClient.py @@ -0,0 +1,220 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +from time import time +from typing import Optional, Dict, Callable, List + +from PyQt5.QtCore import QUrl +from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkReply, QHttpMultiPart, QNetworkRequest, QHttpPart, \ + QAuthenticator + +from UM.Logger import Logger +from cura.CuraApplication import CuraApplication + + +## Abstraction of QNetworkAccessManager for easier networking in Cura. +# This was originally part of NetworkedPrinterOutputDevice but was moved out for re-use in other classes. +class NetworkClient: + + def __init__(self, application: CuraApplication = None): + + # Use the given application instance or get the singleton instance. + self._application = application or CuraApplication.getInstance() + + # Network manager instance to use for this client. + self._manager = None # type: Optional[QNetworkAccessManager] + + # Timings. + self._last_manager_create_time = None # type: Optional[float] + self._last_response_time = None # type: Optional[float] + self._last_request_time = None # type: Optional[float] + + # The user agent of Cura. + self._user_agent = "%s/%s " % (self._application.getApplicationName(), self._application.getVersion()) + + # Uses to store callback methods for finished network requests. + # This allows us to register network calls with a callback directly instead of having to dissect the reply. + self._on_finished_callbacks = {} # type: Dict[str, Callable[[QNetworkReply], None]] + + # QHttpMultiPart objects need to be kept alive and not garbage collected during the + # HTTP which uses them. We hold references to these QHttpMultiPart objects here. + self._kept_alive_multiparts = {} # type: Dict[QNetworkReply, QHttpMultiPart] + + ## Creates a network manager with all the required properties and event bindings. + def _createNetworkManager(self) -> None: + if self._manager: + self._manager.finished.disconnect(self.__handleOnFinished) + self._manager.authenticationRequired.disconnect(self._onAuthenticationRequired) + self._manager = QNetworkAccessManager() + self._manager.finished.connect(self.__handleOnFinished) + self._last_manager_create_time = time() + self._manager.authenticationRequired.connect(self._onAuthenticationRequired) + + ## Create a new empty network request. + # Automatically adds the required HTTP headers. + def _createEmptyRequest(self, url: str, content_type: Optional[str] = "application/json") -> QNetworkRequest: + request = QNetworkRequest(QUrl(url)) + if content_type: + request.setHeader(QNetworkRequest.ContentTypeHeader, content_type) + request.setHeader(QNetworkRequest.UserAgentHeader, self._user_agent) + return request + + ## Executes the correct callback method when a network request finishes. + def __handleOnFinished(self, reply: QNetworkReply) -> None: + + # Due to garbage collection, we need to cache certain bits of post operations. + # As we don't want to keep them around forever, delete them if we get a reply. + if reply.operation() == QNetworkAccessManager.PostOperation: + self._clearCachedMultiPart(reply) + + # No status code means it never even reached remote. + if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) is None: + return + + # Not used by this class itself, but children might need it for better network handling. + # An example of this is the _update method in the NetworkedPrinterOutputDevice. + self._last_response_time = time() + + # Find the right callback and execute it. + # It always takes the full reply as single parameter. + callback_key = reply.url().toString() + str(reply.operation()) + if callback_key in self._on_finished_callbacks: + self._on_finished_callbacks[callback_key](reply) + + ## Removes all cached Multi-Part items. + def _clearCachedMultiPart(self, reply: QNetworkReply) -> None: + if reply in self._kept_alive_multiparts: + del self._kept_alive_multiparts[reply] + + ## Makes sure the network manager is created. + def _validateManager(self) -> None: + if self._manager is None: + self._createNetworkManager() + assert (self._manager is not None) + + ## Callback for when the network manager detects that authentication is required but was not given. + @staticmethod + def _onAuthenticationRequired(reply: QNetworkReply, authenticator: QAuthenticator) -> None: + Logger.log("w", "Request to {} required authentication but was not given".format(reply.url().toString())) + + ## Register a method to be executed when the associated network request finishes. + def _registerOnFinishedCallback(self, reply: QNetworkReply, + on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: + if on_finished is not None: + self._on_finished_callbacks[reply.url().toString() + str(reply.operation())] = on_finished + + ## Add a part to a Multi-Part form. + @staticmethod + def _createFormPart(content_header: str, data: bytes, content_type: Optional[str] = None) -> QHttpPart: + part = QHttpPart() + + if not content_header.startswith("form-data;"): + content_header = "form_data; " + content_header + + part.setHeader(QNetworkRequest.ContentDispositionHeader, content_header) + + if content_type is not None: + part.setHeader(QNetworkRequest.ContentTypeHeader, content_type) + + part.setBody(data) + return part + + ## Public version of _createFormPart. Both are needed for backward compatibility with 3rd party plugins. + def createFormPart(self, content_header: str, data: bytes, content_type: Optional[str] = None) -> QHttpPart: + return self._createFormPart(content_header, data, content_type) + + ## Does a PUT request to the given URL. + def put(self, url: str, data: str, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: + self._validateManager() + + request = self._createEmptyRequest(url) + self._last_request_time = time() + + if not self._manager: + Logger.log("e", "No network manager was created to execute the PUT call with.") + return + + reply = self._manager.put(request, data.encode()) + self._registerOnFinishedCallback(reply, on_finished) + + ## Does a DELETE request to the given URL. + def delete(self, url: str, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: + self._validateManager() + + request = self._createEmptyRequest(url) + self._last_request_time = time() + + if not self._manager: + Logger.log("e", "No network manager was created to execute the DELETE call with.") + return + + reply = self._manager.deleteResource(request) + self._registerOnFinishedCallback(reply, on_finished) + + ## Does a GET request to the given URL. + def get(self, url: str, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: + self._validateManager() + + request = self._createEmptyRequest(url) + self._last_request_time = time() + + if not self._manager: + Logger.log("e", "No network manager was created to execute the GET call with.") + return + + reply = self._manager.get(request) + self._registerOnFinishedCallback(reply, on_finished) + + ## Does a POST request to the given URL. + def post(self, url: str, data: str, on_finished: Optional[Callable[[QNetworkReply], None]], + on_progress: Callable = None) -> None: + self._validateManager() + + request = self._createEmptyRequest(url) + self._last_request_time = time() + + if not self._manager: + Logger.log("e", "No network manager was created to execute the GET call with.") + return + + reply = self._manager.post(request, data.encode()) + + if on_progress is not None: + reply.uploadProgress.connect(on_progress) + + self._registerOnFinishedCallback(reply, on_finished) + + ## Does a POST request with form data to the given URL. + def postForm(self, url: str, header_data: str, body_data: bytes, + on_finished: Optional[Callable[[QNetworkReply], None]], + on_progress: Callable = None) -> None: + post_part = QHttpPart() + post_part.setHeader(QNetworkRequest.ContentDispositionHeader, header_data) + post_part.setBody(body_data) + self.postFormWithParts(url, [post_part], on_finished, on_progress) + + ## Does a POST request with form parts to the given URL. + def postFormWithParts(self, target: str, parts: List[QHttpPart], + on_finished: Optional[Callable[[QNetworkReply], None]], + on_progress: Callable = None) -> None: + self._validateManager() + + request = self._createEmptyRequest(target, content_type = None) + multi_post_part = QHttpMultiPart(QHttpMultiPart.FormDataType) + + for part in parts: + multi_post_part.append(part) + + self._last_request_time = time() + + if not self._manager: + Logger.log("e", "No network manager was created to execute the POST call with.") + return + + reply = self._manager.post(request, multi_post_part) + + self._kept_alive_multiparts[reply] = multi_post_part + + if on_progress is not None: + reply.uploadProgress.connect(on_progress) + + self._registerOnFinishedCallback(reply, on_finished) diff --git a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py index 9a6892ce4d..b5bb1a5452 100644 --- a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py +++ b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py @@ -5,6 +5,7 @@ from UM.FileHandler.FileHandler import FileHandler #For typing. from UM.Logger import Logger from UM.Scene.SceneNode import SceneNode #For typing. from cura.CuraApplication import CuraApplication +from cura.NetworkClient import NetworkClient from cura.PrinterOutputDevice import PrinterOutputDevice, ConnectionState @@ -26,35 +27,29 @@ class AuthState(IntEnum): AuthenticationReceived = 5 -class NetworkedPrinterOutputDevice(PrinterOutputDevice): +class NetworkedPrinterOutputDevice(PrinterOutputDevice, NetworkClient): authenticationStateChanged = pyqtSignal() def __init__(self, device_id, address: str, properties: Dict[bytes, bytes], parent: QObject = None) -> None: - super().__init__(device_id = device_id, parent = parent) - self._manager = None # type: Optional[QNetworkAccessManager] - self._last_manager_create_time = None # type: Optional[float] - self._recreate_network_manager_time = 30 - self._timeout_time = 10 # After how many seconds of no response should a timeout occur? - - self._last_response_time = None # type: Optional[float] - self._last_request_time = None # type: Optional[float] - + PrinterOutputDevice.__init__(self, device_id = device_id, parent = parent) + NetworkClient.__init__(self) + self._api_prefix = "" self._address = address self._properties = properties - self._user_agent = "%s/%s " % (CuraApplication.getInstance().getApplicationName(), CuraApplication.getInstance().getVersion()) - - self._onFinishedCallbacks = {} # type: Dict[str, Callable[[QNetworkReply], None]] self._authentication_state = AuthState.NotAuthenticated - - # QHttpMultiPart objects need to be kept alive and not garbage collected during the - # HTTP which uses them. We hold references to these QHttpMultiPart objects here. - self._kept_alive_multiparts = {} # type: Dict[QNetworkReply, QHttpMultiPart] - self._sending_gcode = False self._compressing_gcode = False self._gcode = [] # type: List[str] + self._connection_state_before_timeout = None # type: Optional[ConnectionState] + self._timeout_time = 10 # After how many seconds of no response should a timeout occur? + self._recreate_network_manager_time = 30 + + ## Override creating empty request to compile the full URL. + # Needed to keep NetworkedPrinterOutputDevice backwards compatible after refactoring NetworkClient out of it. + def _createEmptyRequest(self, target: str, content_type: Optional[str] = "application/json") -> QNetworkRequest: + return super()._createEmptyRequest("http://" + self._address + self._api_prefix + target, content_type) def requestWrite(self, nodes: List[SceneNode], file_name: Optional[str] = None, limit_mimetypes: bool = False, file_handler: Optional[FileHandler] = None, **kwargs: str) -> None: raise NotImplementedError("requestWrite needs to be implemented") @@ -140,30 +135,6 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): self.setConnectionState(self._connection_state_before_timeout) self._connection_state_before_timeout = None - def _createEmptyRequest(self, target: str, content_type: Optional[str] = "application/json") -> QNetworkRequest: - url = QUrl("http://" + self._address + self._api_prefix + target) - request = QNetworkRequest(url) - if content_type is not None: - request.setHeader(QNetworkRequest.ContentTypeHeader, "application/json") - request.setHeader(QNetworkRequest.UserAgentHeader, self._user_agent) - return request - - def createFormPart(self, content_header: str, data: bytes, content_type: Optional[str] = None) -> QHttpPart: - return self._createFormPart(content_header, data, content_type) - - def _createFormPart(self, content_header: str, data: bytes, content_type: Optional[str] = None) -> QHttpPart: - part = QHttpPart() - - if not content_header.startswith("form-data;"): - content_header = "form_data; " + content_header - part.setHeader(QNetworkRequest.ContentDispositionHeader, content_header) - - if content_type is not None: - part.setHeader(QNetworkRequest.ContentTypeHeader, content_type) - - part.setBody(data) - return part - ## Convenience function to get the username from the OS. # The code was copied from the getpass module, as we try to use as little dependencies as possible. def _getUserName(self) -> str: @@ -173,130 +144,7 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): return user return "Unknown User" # Couldn't find out username. - def _clearCachedMultiPart(self, reply: QNetworkReply) -> None: - if reply in self._kept_alive_multiparts: - del self._kept_alive_multiparts[reply] - - def _validateManager(self) -> None: - if self._manager is None: - self._createNetworkManager() - assert (self._manager is not None) - - def put(self, target: str, data: str, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: - self._validateManager() - request = self._createEmptyRequest(target) - self._last_request_time = time() - if self._manager is not None: - reply = self._manager.put(request, data.encode()) - self._registerOnFinishedCallback(reply, on_finished) - else: - Logger.log("e", "Could not find manager.") - - def delete(self, target: str, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: - self._validateManager() - request = self._createEmptyRequest(target) - self._last_request_time = time() - if self._manager is not None: - reply = self._manager.deleteResource(request) - self._registerOnFinishedCallback(reply, on_finished) - else: - Logger.log("e", "Could not find manager.") - - def get(self, target: str, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: - self._validateManager() - request = self._createEmptyRequest(target) - self._last_request_time = time() - if self._manager is not None: - reply = self._manager.get(request) - self._registerOnFinishedCallback(reply, on_finished) - else: - Logger.log("e", "Could not find manager.") - - def post(self, target: str, data: str, on_finished: Optional[Callable[[QNetworkReply], None]], on_progress: Callable = None) -> None: - self._validateManager() - request = self._createEmptyRequest(target) - self._last_request_time = time() - if self._manager is not None: - reply = self._manager.post(request, data.encode()) - if on_progress is not None: - reply.uploadProgress.connect(on_progress) - self._registerOnFinishedCallback(reply, on_finished) - else: - Logger.log("e", "Could not find manager.") - - def postFormWithParts(self, target: str, parts: List[QHttpPart], on_finished: Optional[Callable[[QNetworkReply], None]], on_progress: Callable = None) -> QNetworkReply: - self._validateManager() - request = self._createEmptyRequest(target, content_type=None) - multi_post_part = QHttpMultiPart(QHttpMultiPart.FormDataType) - for part in parts: - multi_post_part.append(part) - - self._last_request_time = time() - - if self._manager is not None: - reply = self._manager.post(request, multi_post_part) - - self._kept_alive_multiparts[reply] = multi_post_part - - if on_progress is not None: - reply.uploadProgress.connect(on_progress) - self._registerOnFinishedCallback(reply, on_finished) - - return reply - else: - Logger.log("e", "Could not find manager.") - - def postForm(self, target: str, header_data: str, body_data: bytes, on_finished: Optional[Callable[[QNetworkReply], None]], on_progress: Callable = None) -> None: - post_part = QHttpPart() - post_part.setHeader(QNetworkRequest.ContentDispositionHeader, header_data) - post_part.setBody(body_data) - - self.postFormWithParts(target, [post_part], on_finished, on_progress) - - def _onAuthenticationRequired(self, reply: QNetworkReply, authenticator: QAuthenticator) -> None: - Logger.log("w", "Request to {url} required authentication, which was not implemented".format(url = reply.url().toString())) - - def _createNetworkManager(self) -> None: - Logger.log("d", "Creating network manager") - if self._manager: - self._manager.finished.disconnect(self.__handleOnFinished) - self._manager.authenticationRequired.disconnect(self._onAuthenticationRequired) - - self._manager = QNetworkAccessManager() - self._manager.finished.connect(self.__handleOnFinished) - self._last_manager_create_time = time() - self._manager.authenticationRequired.connect(self._onAuthenticationRequired) - - if self._properties.get(b"temporary", b"false") != b"true": - CuraApplication.getInstance().getMachineManager().checkCorrectGroupName(self.getId(), self.name) - - def _registerOnFinishedCallback(self, reply: QNetworkReply, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: - if on_finished is not None: - self._onFinishedCallbacks[reply.url().toString() + str(reply.operation())] = on_finished - - def __handleOnFinished(self, reply: QNetworkReply) -> None: - # Due to garbage collection, we need to cache certain bits of post operations. - # As we don't want to keep them around forever, delete them if we get a reply. - if reply.operation() == QNetworkAccessManager.PostOperation: - self._clearCachedMultiPart(reply) - - if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) is None: - # No status code means it never even reached remote. - return - - self._last_response_time = time() - - if self._connection_state == ConnectionState.connecting: - self.setConnectionState(ConnectionState.connected) - - callback_key = reply.url().toString() + str(reply.operation()) - try: - if callback_key in self._onFinishedCallbacks: - self._onFinishedCallbacks[callback_key](reply) - except Exception: - Logger.logException("w", "something went wrong with callback") - - @pyqtSlot(str, result=str) + @pyqtSlot(str, result = str) def getProperty(self, key: str) -> str: bytes_key = key.encode("utf-8") if bytes_key in self._properties: @@ -332,7 +180,14 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): def printerType(self) -> str: return self._properties.get(b"printer_type", b"Unknown").decode("utf-8") - ## IP adress of this printer + ## IP address of this printer @pyqtProperty(str, constant = True) def ipAddress(self) -> str: return self._address + + def __handleOnFinished(self, reply: QNetworkReply) -> None: + super().__handleOnFinished(reply) + + # Since we got a reply from the network manager we can now be sure we are actually connected. + if self._connection_state == ConnectionState.connecting: + self.setConnectionState(ConnectionState.connected) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index e88ee4dced..08e43152ae 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -3,10 +3,10 @@ import json from typing import TYPE_CHECKING, Dict, Optional -from PyQt5.QtCore import QUrl -from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply +from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply from UM.Logger import Logger +from cura.NetworkClient import NetworkClient from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputDevice import CloudOutputDevice @@ -21,20 +21,17 @@ if TYPE_CHECKING: # # TODO: figure out how to pair remote clusters, local networked clusters and local cura printer presets. # TODO: for now we just have multiple output devices if the cluster is available both locally and remote. -class CloudOutputDeviceManager: +class CloudOutputDeviceManager(NetworkClient): # The cloud URL to use for remote clusters. API_ROOT_PATH = "https://api.ultimaker.com/connect/v1" def __init__(self, application: "CuraApplication"): - self._application = application + super().__init__(application) + self._output_device_manager = application.getOutputDeviceManager() self._account = application.getCuraAPI().account - # Network manager for getting the cluster list. - self._network_manager = QNetworkAccessManager() - self._network_manager.finished.connect(self._onNetworkRequestFinished) - # Persistent dict containing the remote clusters for the authenticated user. self._remote_clusters = {} # type: Dict[str, CloudOutputDevice] @@ -44,27 +41,24 @@ class CloudOutputDeviceManager: # Fetch all remote clusters for the authenticated user. # TODO: update remote clusters periodically self._account.loginStateChanged.connect(self._getRemoteClusters) + + ## Override _createEmptyRequest to add the needed authentication header for talking to the Ultimaker Cloud API. + def _createEmptyRequest(self, path: str, content_type: Optional[str] = "application/json") -> QNetworkRequest: + request = super()._createEmptyRequest(self.API_ROOT_PATH + path, content_type = content_type) + if self._account.isLoggedIn: + # TODO: add correct scopes to OAuth2 client to use remote connect API. + # TODO: don't create the client when not signed in? + request.setRawHeader(b"Authorization", "Bearer {}".format(self._account.accessToken).encode()) + return request ## Gets all remote clusters from the API. - def _getRemoteClusters(self): - url = QUrl("{}/clusters".format(self.API_ROOT_PATH)) - request = QNetworkRequest(url) - request.setHeader(QNetworkRequest.ContentTypeHeader, "application/json") - - if not self._account.isLoggedIn: - # TODO: show message to user to sign in - Logger.log("w", "User is not signed in, cannot get remote print clusters") - return - - request.setRawHeader(b"Authorization", "Bearer {}".format(self._account.accessToken).encode()) - self._network_manager.get(request) + def _getRemoteClusters(self) -> None: + self.get("/clusters", on_finished = self._onGetRemoteClustersFinished) - ## Callback for network requests. - def _onNetworkRequestFinished(self, reply: QNetworkReply): - # TODO: right now we assume that each reply is from /clusters, we should fix this + ## Callback for when the request for getting the clusters. is finished. + def _onGetRemoteClustersFinished(self, reply: QNetworkReply) -> None: status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) if status_code != 200: - # TODO: add correct scopes to OAuth2 client to use remote connect API. Logger.log("w", "Got unexpected response while trying to get cloud cluster data: {}, {}" .format(status_code, reply.readAll())) return @@ -86,7 +80,6 @@ class CloudOutputDeviceManager: def _parseStatusResponse(reply: QNetworkReply) -> Optional[dict]: try: result = json.loads(bytes(reply.readAll()).decode("utf-8")) - print("result=====", result) # TODO: use model or named tuple here. return result.data except json.decoder.JSONDecodeError: From 4bccd2b7b5b0faac7ddd6140c5bebe81c43659cf Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Tue, 20 Nov 2018 23:46:03 +0100 Subject: [PATCH 0304/1292] Restyle printer settings dropdown CURA-5941 --- plugins/PreviewStage/PreviewMenu.qml | 2 +- resources/qml/ActionButton.qml | 18 +- resources/qml/MachineSelector.qml | 2 +- .../QuickConfigurationSelector.qml | 2 +- resources/qml/PrintSetupSelector.qml | 343 ++++++++++++------ resources/themes/cura-light/theme.json | 7 +- 6 files changed, 251 insertions(+), 123 deletions(-) diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index b331ff69c5..7b3a3af4e3 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -3,7 +3,7 @@ import QtQuick 2.7 -import QtQuick.Controls 2.4 +import QtQuick.Controls 2.3 import UM 1.3 as UM import Cura 1.1 as Cura diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index 2a8b894867..08f4d9d679 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -12,6 +12,7 @@ Button id: button property alias cursorShape: mouseArea.cursorShape property alias iconSource: buttonIcon.source + property alias iconSourceRight: buttonIconRight.source property alias textFont: buttonText.font property alias cornerRadius: backgroundRect.radius property alias tooltip: tooltip.text @@ -29,7 +30,8 @@ Button // we elide the text to the right so the text will be cut off with the three dots at the end. property var fixedWidthMode: false - contentItem: Row + width: buttonIcon.width + buttonText.width + buttonIconRight.width + contentItem: Item { UM.RecolorImage { @@ -57,6 +59,20 @@ Button horizontalAlignment: Text.AlignHCenter elide: Text.ElideRight } + + UM.RecolorImage + { + id: buttonIconRight + source: "" + height: Math.round(0.6 * parent.height) + width: height + sourceSize.width: width + sourceSize.height: height + color: button.hovered ? button.textHoverColor : button.textColor + visible: source != "" + anchors.verticalCenter: parent.verticalCenter + anchors.right: source != "" ? parent.right : undefined + } } background: Rectangle diff --git a/resources/qml/MachineSelector.qml b/resources/qml/MachineSelector.qml index a464949192..c9756d93ba 100644 --- a/resources/qml/MachineSelector.qml +++ b/resources/qml/MachineSelector.qml @@ -2,7 +2,7 @@ // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 -import QtQuick.Controls 2.4 +import QtQuick.Controls 2.3 import QtQuick.Controls.Styles 1.1 import QtQuick.Layouts 1.1 diff --git a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml index 33610135fe..d428a05463 100644 --- a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml +++ b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml @@ -4,7 +4,7 @@ import QtQuick 2.7 import QtQuick.Controls 2.0 import QtQuick.Controls.Styles 1.4 -import QtQuick.Layouts 1.11 +import QtQuick.Layouts 1.3 import QtQuick.Controls 1.1 as OldControls diff --git a/resources/qml/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector.qml index b843244147..ed09238b51 100644 --- a/resources/qml/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector.qml @@ -28,8 +28,15 @@ Cura.ExpandableComponent height: childrenRect.height iconSource: UM.Theme.getIcon("pencil") + popupPadding : 0 + onCurrentModeIndexChanged: UM.Preferences.setValue("cura/active_mode", currentModeIndex) + Component.onCompleted: + { + popupItemWrapper.width = base.width + } + UM.I18nCatalog { id: catalog @@ -109,142 +116,242 @@ Cura.ExpandableComponent } } - popupItem: Item + + Cura.ExtrudersModel { - height: settingsModeSelection.height + sidebarContents.height + 2 * UM.Theme.getSize("default_margin").height - width: UM.Theme.getSize("print_setup_widget").width - ListView - { - // Settings mode selection toggle - id: settingsModeSelection - model: modesListModel - height: UM.Theme.getSize("print_setup_mode_toggle").height - visible: !hideSettings + id: extrudersModel + } - anchors - { - right: parent.right - left: parent.left - margins: UM.Theme.getSize("thick_margin").width - } + popupItem: Rectangle + { + property var total_height: popupItemHeader.height + popupItemContent.height + 10 + separator_footer.height + id: popupItemWrapper + height: total_height - ButtonGroup - { - id: modeMenuGroup - } - - delegate: Button - { - id: control - - height: settingsModeSelection.height - width: Math.round(parent.width / 2) - - anchors.left: parent.left - anchors.leftMargin: model.index * Math.round(settingsModeSelection.width / 2) - anchors.verticalCenter: parent.verticalCenter - - ButtonGroup.group: modeMenuGroup - - checkable: true - checked: base.currentModeIndex == index - onClicked: base.currentModeIndex = index - - onHoveredChanged: - { - if (hovered) - { - tooltipDelayTimer.item = settingsModeSelection - tooltipDelayTimer.text = model.tooltipText - tooltipDelayTimer.start() - } - else - { - tooltipDelayTimer.stop() - base.hideTooltip() - } - } - - background: Rectangle - { - border.width: control.checked ? UM.Theme.getSize("default_lining").width * 2 : UM.Theme.getSize("default_lining").width - border.color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active_border") : control.hovered ? UM.Theme.getColor("action_button_hovered_border") : UM.Theme.getColor("action_button_border") - - // For some reason, QtQuick decided to use the color of the background property as text color for the contentItem, so here it is - color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active") : control.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") - } - - contentItem: Label - { - text: model.text - font: UM.Theme.getFont("default") - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - renderType: Text.NativeRendering - elide: Text.ElideRight - color: - { - if(control.pressed) - { - return UM.Theme.getColor("action_button_active_text") - } - else if(control.hovered) - { - return UM.Theme.getColor("action_button_hovered_text") - } - return UM.Theme.getColor("action_button_text") - } - } - } - } + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("lining") Item { - id: sidebarContents - anchors.top: settingsModeSelection.bottom - anchors.topMargin: UM.Theme.getSize("thick_margin").height - anchors.left: parent.left - anchors.right: parent.right - height: UM.Theme.getSize("print_setup_widget").height + id: popupItemHeader + height: 36 - visible: !hideSettings - - // We load both of them at once (instead of using a loader) because the advanced sidebar can take - // quite some time to load. So in this case we sacrifice memory for speed. - SidebarAdvanced + anchors { - anchors.fill: parent - visible: currentModeIndex == 1 - onShowTooltip: base.showTooltip(item, location, text) - onHideTooltip: base.hideTooltip() + top: parent.top + right: parent.right + left: parent.left } - SidebarSimple + Label { - anchors.fill: parent - visible: currentModeIndex != 1 - onShowTooltip: base.showTooltip(item, location, text) - onHideTooltip: base.hideTooltip() + id: popupItemHeaderText + text: catalog.i18nc("@label", "Print settings"); + font: UM.Theme.getFont("default") + verticalAlignment: Text.AlignVCenter + color: UM.Theme.getColor("text") + height: parent.height + anchors.topMargin: UM.Theme.getSize("sidebar_margin").height + anchors.bottomMargin: UM.Theme.getSize("sidebar_margin").height + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("print_setup_selector_margin").height + } + + Rectangle + { + width: parent.width + height: UM.Theme.getSize("default_lining").height + anchors.top: popupItemHeaderText.bottom + color: UM.Theme.getColor("action_button_border") + + } } - // Setting mode: Recommended or Custom - ListModel + Rectangle { - id: modesListModel + id: popupItemContent + width: parent.width + height: tabBar.height + sidebarContents.height + anchors + { + top: popupItemHeader.bottom + topMargin: 10 + right: parent.right + left: parent.left + leftMargin: 5 + rightMargin: 5 + } + + + TabBar + { + id: tabBar + onCurrentIndexChanged: Cura.ExtruderManager.setActiveExtruderIndex(currentIndex) + width: parent.width + height: UM.Theme.getSize("print_setup_tap_bar").width + z: 1 + Repeater + { + id: extruder_model_repeater + model: extrudersModel + + delegate: TabButton + { + z: 2 + width: ListView.view != null ? Math.round(ListView.view.width / extrudersModel.rowCount()): 0 + implicitHeight: parent.height + + contentItem: Rectangle + { + z: 2 + Cura.ExtruderIcon + { + anchors.horizontalCenter: parent.horizontalCenter + materialColor: model.color + extruderEnabled: model.enabled + width: parent.height + height: parent.height + } + + } + + background: Rectangle + { + + width: parent.width + z: 1 + border.width: UM.Theme.getSize("default_lining").width * 2 + border.color: UM.Theme.getColor("action_button_border") + + visible: + { + return index == tabBar.currentIndex + } + + // overlap bottom border + Rectangle + { + width: parent.width - 4 + height: 4 + anchors.bottom: parent.bottom + anchors.bottomMargin: -2 + anchors.leftMargin: 2 + anchors.left: parent.left + + } + } + } + } + } + + Rectangle + { + id: sidebarContents + anchors.top: tabBar.bottom + anchors.left: parent.left + anchors.right: parent.right + height: UM.Theme.getSize("print_setup_widget").height + + + border.width: UM.Theme.getSize("default_lining").width * 2 + border.color: UM.Theme.getColor("action_button_border") + + SidebarSimple + { + anchors.topMargin: UM.Theme.getSize("print_setup_content_top_margin").height + id: sidebar_simple_id + anchors.fill: parent + visible: currentModeIndex != 1 + onShowTooltip: base.showTooltip(item, location, text) + onHideTooltip: base.hideTooltip() + } + + SidebarAdvanced + { + anchors.topMargin: UM.Theme.getSize("print_setup_content_top_margin").height + anchors.bottomMargin: 2 //does not overlap bottom border + anchors.fill: parent + visible: currentModeIndex == 1 + onShowTooltip: base.showTooltip(item, location, text) + onHideTooltip: base.hideTooltip() + } + + } } + + Item + { + id: separator_footer + anchors.top: popupItemContent.bottom + anchors.topMargin: 10 + width: parent.width + height: settingControlButton.height + 4 + + Rectangle + { + width: parent.width + height: UM.Theme.getSize("default_lining").height + color: UM.Theme.getColor("action_button_border") + } + + Cura.ActionButton + { + id: settingControlButton + + leftPadding: UM.Theme.getSize("default_margin").width + rightPadding: UM.Theme.getSize("default_margin").width + height: UM.Theme.getSize("action_panel_button").height + text: catalog.i18nc("@button", "Custom") + color: UM.Theme.getColor("secondary") + hoverColor: UM.Theme.getColor("secondary") + textColor: UM.Theme.getColor("primary") + textHoverColor: UM.Theme.getColor("text") + iconSourceRight: UM.Theme.getIcon("arrow_right") + width: UM.Theme.getSize("print_setup_action_button").width + fixedWidthMode: true + visible: currentModeIndex == 0 + anchors + { + top: parent.top + topMargin: 10 + bottomMargin: 10 + right: parent.right + rightMargin: 5 + } + + onClicked: currentModeIndex = 1 + } + + Cura.ActionButton + { + height: UM.Theme.getSize("action_panel_button").height + text: catalog.i18nc("@button", "Recommended") + color: UM.Theme.getColor("secondary") + hoverColor: UM.Theme.getColor("secondary") + textColor: UM.Theme.getColor("primary") + textHoverColor: UM.Theme.getColor("text") + iconSource: UM.Theme.getIcon("arrow_left") + width: UM.Theme.getSize("print_setup_action_button").width + + + fixedWidthMode: true + visible: currentModeIndex == 1 + anchors + { + top: parent.top + topMargin: UM.Theme.getSize("print_setup_selector_margin").height * 2 + bottomMargin: UM.Theme.getSize("print_setup_selector_margin").height * 2 + left: parent.left + leftMargin: UM.Theme.getSize("print_setup_selector_margin").height + } + + onClicked: currentModeIndex = 0 + } + } Component.onCompleted: { - modesListModel.append({ - text: catalog.i18nc("@title:tab", "Recommended"), - tooltipText: "%1

%2".arg(catalog.i18nc("@tooltip:title", "Recommended Print Setup")).arg(catalog.i18nc("@tooltip", "Print with the recommended settings for the selected printer, material and quality.")) - }) - modesListModel.append({ - text: catalog.i18nc("@title:tab", "Custom"), - tooltipText: "%1

%2".arg(catalog.i18nc("@tooltip:title", "Custom Print Setup")).arg(catalog.i18nc("@tooltip", "Print with finegrained control over every last bit of the slicing process.")) - }) - var index = Math.round(UM.Preferences.getValue("cura/active_mode")) if(index != null && !isNaN(index)) @@ -257,4 +364,4 @@ Cura.ExpandableComponent } } } -} +} \ No newline at end of file diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index d28611529b..fc62edc480 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -528,6 +528,11 @@ "monitor_thick_lining": [0.16, 0.16], "monitor_corner_radius": [0.3, 0.3], "monitor_shadow_radius": [0.4, 0.4], - "monitor_shadow_offset": [0.15, 0.15] + "monitor_shadow_offset": [0.15, 0.15], + + "print_setup_selector_margin": [0.5, 0.5], + "print_setup_action_button": [13, 5], + "print_setup_tap_bar": [4, 4], + "print_setup_content_top_margin": [3, 3] } } From 8b085aa877194c45a3122ccbafa5460d57f9e28d Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 20 Nov 2018 23:47:25 +0100 Subject: [PATCH 0305/1292] Revert "Switch Ultimaker Account OAuth2 client" This reverts commit 4e8979334e0d794b2cd8cae72ce9c351890577c8. --- cura/API/Account.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cura/API/Account.py b/cura/API/Account.py index 64d63c7025..397e220478 100644 --- a/cura/API/Account.py +++ b/cura/API/Account.py @@ -38,12 +38,13 @@ class Account(QObject): self._callback_port = 32118 self._oauth_root = "https://account.ultimaker.com" + self._cloud_api_root = "https://api.ultimaker.com" self._oauth_settings = OAuth2Settings( OAUTH_SERVER_URL= self._oauth_root, CALLBACK_PORT=self._callback_port, CALLBACK_URL="http://localhost:{}/callback".format(self._callback_port), - CLIENT_ID="um----------------------------ultimaker_cura", + CLIENT_ID="um---------------ultimaker_cura_drive_plugin", CLIENT_SCOPES="account.user.read drive.backup.read drive.backup.write packages.download packages.rating.read packages.rating.write", AUTH_DATA_PREFERENCE_KEY="general/ultimaker_auth_data", AUTH_SUCCESS_REDIRECT="{}/app/auth-success".format(self._oauth_root), From 791929d6897942e971a112a26839c0fa6f94f847 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 20 Nov 2018 23:47:46 +0100 Subject: [PATCH 0306/1292] Revert "Merge branch 'fix-oauth2-client' into CURA-5785-Restyle_stage_menu" This reverts commit 4caf770a62f07b71a646b7f09a08623485b89582, reversing changes made to 0cdcd61ff2dfe2677e636cc2f1ee993cbd9d641d. --- resources/qml/Dialogs/AddMachineDialog.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Dialogs/AddMachineDialog.qml b/resources/qml/Dialogs/AddMachineDialog.qml index aa160acd4d..0df8b891d9 100644 --- a/resources/qml/Dialogs/AddMachineDialog.qml +++ b/resources/qml/Dialogs/AddMachineDialog.qml @@ -73,7 +73,7 @@ UM.Dialog { top: parent.top left: parent.left - topMargin: UM.Theme.getSize("default_margin").height + topMargin: UM.Theme.getSize("default_margin") } text: catalog.i18nc("@title:tab", "Add a printer to Cura") From 60ed0ddc2493f357417922529f25ce242d8daba7 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 20 Nov 2018 23:49:33 +0100 Subject: [PATCH 0307/1292] Revert "Revert "Merge branch 'fix-oauth2-client' into CURA-5785-Restyle_stage_menu"" This reverts commit 791929d6897942e971a112a26839c0fa6f94f847. --- resources/qml/Dialogs/AddMachineDialog.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Dialogs/AddMachineDialog.qml b/resources/qml/Dialogs/AddMachineDialog.qml index 0df8b891d9..aa160acd4d 100644 --- a/resources/qml/Dialogs/AddMachineDialog.qml +++ b/resources/qml/Dialogs/AddMachineDialog.qml @@ -73,7 +73,7 @@ UM.Dialog { top: parent.top left: parent.left - topMargin: UM.Theme.getSize("default_margin") + topMargin: UM.Theme.getSize("default_margin").height } text: catalog.i18nc("@title:tab", "Add a printer to Cura") From 8ad8489af0afeb7278d325b1db9eb26e31473086 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Wed, 21 Nov 2018 00:03:36 +0100 Subject: [PATCH 0308/1292] Fix returning reply on postFormWithParts --- cura/NetworkClient.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cura/NetworkClient.py b/cura/NetworkClient.py index ce9cc50cf6..da27456ac8 100644 --- a/cura/NetworkClient.py +++ b/cura/NetworkClient.py @@ -195,7 +195,7 @@ class NetworkClient: ## Does a POST request with form parts to the given URL. def postFormWithParts(self, target: str, parts: List[QHttpPart], on_finished: Optional[Callable[[QNetworkReply], None]], - on_progress: Callable = None) -> None: + on_progress: Callable = None) -> QNetworkReply: self._validateManager() request = self._createEmptyRequest(target, content_type = None) @@ -218,3 +218,4 @@ class NetworkClient: reply.uploadProgress.connect(on_progress) self._registerOnFinishedCallback(reply, on_finished) + return reply From 8453cd693e98bf7d0e5a632b0a6ef8380826c931 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Wed, 21 Nov 2018 00:04:34 +0100 Subject: [PATCH 0309/1292] Make QNetworkReply optional --- cura/NetworkClient.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/NetworkClient.py b/cura/NetworkClient.py index da27456ac8..20c026f4e6 100644 --- a/cura/NetworkClient.py +++ b/cura/NetworkClient.py @@ -195,7 +195,7 @@ class NetworkClient: ## Does a POST request with form parts to the given URL. def postFormWithParts(self, target: str, parts: List[QHttpPart], on_finished: Optional[Callable[[QNetworkReply], None]], - on_progress: Callable = None) -> QNetworkReply: + on_progress: Callable = None) -> Optional[QNetworkReply]: self._validateManager() request = self._createEmptyRequest(target, content_type = None) From 23744e42d1f4480fdc7f3c56f3591074b3ae8723 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 21 Nov 2018 09:15:18 +0100 Subject: [PATCH 0310/1292] Remove SaveButton file, since it's not used anymore. Contributes to CURA-5942 --- resources/qml/SaveButton.qml | 478 ----------------------------------- 1 file changed, 478 deletions(-) delete mode 100644 resources/qml/SaveButton.qml diff --git a/resources/qml/SaveButton.qml b/resources/qml/SaveButton.qml deleted file mode 100644 index c2d310e30c..0000000000 --- a/resources/qml/SaveButton.qml +++ /dev/null @@ -1,478 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.7 -import QtQuick.Controls 1.1 -import QtQuick.Controls.Styles 1.1 -import QtQuick.Layouts 1.1 - -import UM 1.1 as UM -import Cura 1.0 as Cura - -// This widget does so much more than "just" being a save button, so it should be refactored at some point in time. -Item -{ - id: base; - UM.I18nCatalog { id: catalog; name: "cura"} - - property real progress: UM.Backend.progress - property int backendState: UM.Backend.state - property bool activity: CuraApplication.platformActivity - - property alias buttonRowWidth: saveRow.width - - property string fileBaseName - property string statusText: - { - if(!activity) - { - return catalog.i18nc("@label:PrintjobStatus", "Please load a 3D model"); - } - - switch(base.backendState) - { - case 1: - return catalog.i18nc("@label:PrintjobStatus", "Ready to slice"); - case 2: - return catalog.i18nc("@label:PrintjobStatus", "Slicing..."); - case 3: - return catalog.i18nc("@label:PrintjobStatus %1 is target operation", "Ready to %1").arg(UM.OutputDeviceManager.activeDeviceShortDescription); - case 4: - return catalog.i18nc("@label:PrintjobStatus", "Unable to Slice"); - case 5: - return catalog.i18nc("@label:PrintjobStatus", "Slicing unavailable"); - default: - return ""; - } - } - - function sliceOrStopSlicing() - { - try - { - if ([1, 5].indexOf(base.backendState) != -1) - { - CuraApplication.backend.forceSlice(); - } - else - { - CuraApplication.backend.stopSlicing(); - } - } - catch (e) - { - console.log("Could not start or stop slicing.", e) - } - } - - Label - { - id: statusLabel - width: parent.width - 2 * UM.Theme.getSize("thick_margin").width - anchors.top: parent.top - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("thick_margin").width - - color: UM.Theme.getColor("text") - font: UM.Theme.getFont("default_bold") - text: statusText; - } - - Rectangle - { - id: progressBar - width: parent.width - 2 * UM.Theme.getSize("thick_margin").width - height: UM.Theme.getSize("progressbar").height - anchors.top: statusLabel.bottom - anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height / 4) - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("thick_margin").width - radius: UM.Theme.getSize("progressbar_radius").width - color: UM.Theme.getColor("progressbar_background") - - Rectangle - { - width: Math.max(parent.width * base.progress) - height: parent.height - color: UM.Theme.getColor("progressbar_control") - radius: UM.Theme.getSize("progressbar_radius").width - visible: base.backendState == 2 - } - } - - // Shortcut for "save as/print/..." - Action - { - shortcut: "Ctrl+P" - onTriggered: - { - // only work when the button is enabled - if (saveToButton.enabled) - { - saveToButton.clicked(); - } - // prepare button - if (prepareButton.enabled) - { - sliceOrStopSlicing(); - } - } - } - - Item - { - id: saveRow - width: { - // using childrenRect.width directly causes a binding loop, because setting the width affects the childrenRect - var children_width = UM.Theme.getSize("default_margin").width; - for (var index in children) - { - var child = children[index]; - if(child.visible) - { - children_width += child.width + child.anchors.rightMargin; - } - } - return Math.min(children_width, base.width - UM.Theme.getSize("thick_margin").width); - } - height: saveToButton.height - anchors.bottom: parent.bottom - anchors.bottomMargin: UM.Theme.getSize("thick_margin").height - anchors.right: parent.right - clip: true - - Row - { - id: additionalComponentsRow - anchors.top: parent.top - anchors.right: saveToButton.visible ? saveToButton.left : (prepareButton.visible ? prepareButton.left : parent.right) - anchors.rightMargin: UM.Theme.getSize("default_margin").width - - spacing: UM.Theme.getSize("default_margin").width - } - - Component.onCompleted: - { - saveRow.addAdditionalComponents("saveButton") - } - - Connections - { - target: CuraApplication - onAdditionalComponentsChanged: saveRow.addAdditionalComponents("saveButton") - } - - function addAdditionalComponents (areaId) - { - if(areaId == "saveButton") - { - for (var component in CuraApplication.additionalComponents["saveButton"]) - { - CuraApplication.additionalComponents["saveButton"][component].parent = additionalComponentsRow - } - } - } - - Connections - { - target: UM.Preferences - onPreferenceChanged: - { - var autoSlice = UM.Preferences.getValue("general/auto_slice"); - prepareButton.autoSlice = autoSlice; - saveToButton.autoSlice = autoSlice; - } - } - - // Prepare button, only shows if auto_slice is off - Button - { - id: prepareButton - - tooltip: [1, 5].indexOf(base.backendState) != -1 ? catalog.i18nc("@info:tooltip","Slice current printjob") : catalog.i18nc("@info:tooltip","Cancel slicing process") - // 1 = not started, 2 = Processing - enabled: ([1, 2].indexOf(base.backendState) != -1) && base.activity - visible: !autoSlice && ([1, 2, 4].indexOf(base.backendState) != -1) && base.activity - property bool autoSlice - height: UM.Theme.getSize("save_button_save_to_button").height - - anchors.top: parent.top - anchors.right: parent.right - anchors.rightMargin: UM.Theme.getSize("thick_margin").width - - // 1 = not started, 4 = error, 5 = disabled - text: [1, 4, 5].indexOf(base.backendState) != -1 ? catalog.i18nc("@label:Printjob", "Prepare") : catalog.i18nc("@label:Printjob", "Cancel") - onClicked: - { - sliceOrStopSlicing(); - } - - style: ButtonStyle - { - background: Rectangle - { - border.width: UM.Theme.getSize("default_lining").width - border.color: - { - if(!control.enabled) - { - return UM.Theme.getColor("action_button_disabled_border"); - } - else if(control.pressed) - { - return UM.Theme.getColor("action_button_active_border"); - } - else if(control.hovered) - { - return UM.Theme.getColor("action_button_hovered_border"); - } - else - { - return UM.Theme.getColor("action_button_border"); - } - } - color: - { - if(!control.enabled) - { - return UM.Theme.getColor("action_button_disabled"); - } - else if(control.pressed) - { - return UM.Theme.getColor("action_button_active"); - } - else if(control.hovered) - { - return UM.Theme.getColor("action_button_hovered"); - } - else - { - return UM.Theme.getColor("action_button"); - } - } - - Behavior on color { ColorAnimation { duration: 50; } } - - implicitWidth: actualLabel.contentWidth + (UM.Theme.getSize("thick_margin").width * 2) - - Label - { - id: actualLabel - anchors.centerIn: parent - color: - { - if(!control.enabled) - { - return UM.Theme.getColor("action_button_disabled_text"); - } - else if(control.pressed) - { - return UM.Theme.getColor("action_button_active_text"); - } - else if(control.hovered) - { - return UM.Theme.getColor("action_button_hovered_text"); - } - else - { - return UM.Theme.getColor("action_button_text"); - } - } - font: UM.Theme.getFont("action_button") - text: control.text; - } - } - label: Item {} - } - } - - Button - { - id: saveToButton - - tooltip: UM.OutputDeviceManager.activeDeviceDescription; - // 3 = done, 5 = disabled - enabled: base.backendState != "undefined" && (base.backendState == 3 || base.backendState == 5) && base.activity == true - visible: base.backendState != "undefined" && autoSlice || ((base.backendState == 3 || base.backendState == 5) && base.activity == true) - property bool autoSlice - height: UM.Theme.getSize("save_button_save_to_button").height - - anchors.top: parent.top - anchors.right: deviceSelectionMenu.visible ? deviceSelectionMenu.left : parent.right - anchors.rightMargin: deviceSelectionMenu.visible ? -3 * UM.Theme.getSize("default_lining").width : UM.Theme.getSize("thick_margin").width - - text: UM.OutputDeviceManager.activeDeviceShortDescription - onClicked: - { - forceActiveFocus(); - UM.OutputDeviceManager.requestWriteToDevice(UM.OutputDeviceManager.activeDevice, PrintInformation.jobName, - { "filter_by_machine": true, "preferred_mimetypes": Cura.MachineManager.activeMachine.preferred_output_file_formats }); - } - - style: ButtonStyle - { - background: Rectangle - { - border.width: UM.Theme.getSize("default_lining").width - border.color: - { - if(!control.enabled) - { - return UM.Theme.getColor("action_button_disabled_border"); - } - else if(control.pressed) - { - return UM.Theme.getColor("print_button_ready_pressed_border"); - } - else if(control.hovered) - { - return UM.Theme.getColor("print_button_ready_hovered_border"); - } - else - { - return UM.Theme.getColor("print_button_ready_border"); - } - } - color: - { - if(!control.enabled) - { - return UM.Theme.getColor("action_button_disabled"); - } - else if(control.pressed) - { - return UM.Theme.getColor("print_button_ready_pressed"); - } - else if(control.hovered) - { - return UM.Theme.getColor("print_button_ready_hovered"); - } - else - { - return UM.Theme.getColor("print_button_ready"); - } - } - - Behavior on color { ColorAnimation { duration: 50; } } - - implicitWidth: actualLabel.contentWidth + (UM.Theme.getSize("thick_margin").width * 2) - - Label - { - id: actualLabel - anchors.centerIn: parent - color: control.enabled ? UM.Theme.getColor("print_button_ready_text") : UM.Theme.getColor("action_button_disabled_text") - font: UM.Theme.getFont("action_button") - text: control.text - } - } - label: Item { } - } - } - - Button - { - id: deviceSelectionMenu - tooltip: catalog.i18nc("@info:tooltip","Select the active output device"); - anchors.top: parent.top - anchors.right: parent.right - - anchors.rightMargin: UM.Theme.getSize("thick_margin").width - width: UM.Theme.getSize("save_button_save_to_button").height - height: UM.Theme.getSize("save_button_save_to_button").height - - // 3 = Done, 5 = Disabled - enabled: (base.backendState == 3 || base.backendState == 5) && base.activity == true - visible: (devicesModel.deviceCount > 1) && (base.backendState == 3 || base.backendState == 5) && base.activity == true - - - style: ButtonStyle - { - background: Rectangle - { - id: deviceSelectionIcon - border.width: UM.Theme.getSize("default_lining").width - border.color: - { - if(!control.enabled) - { - return UM.Theme.getColor("action_button_disabled_border") - } - else if(control.pressed) - { - return UM.Theme.getColor("print_button_ready_pressed_border") - } - else if(control.hovered) - { - return UM.Theme.getColor("print_button_ready_hovered_border") - } - else - { - return UM.Theme.getColor("print_button_ready_border") - } - } - color: - { - if(!control.enabled) - { - return UM.Theme.getColor("action_button_disabled") - } - else if(control.pressed) - { - return UM.Theme.getColor("print_button_ready_pressed") - } - else if(control.hovered) - { - return UM.Theme.getColor("print_button_ready_hovered") - } - else - { - return UM.Theme.getColor("print_button_ready") - } - } - Behavior on color { ColorAnimation { duration: 50; } } - anchors.left: parent.left - anchors.leftMargin: Math.round(UM.Theme.getSize("save_button_text_margin").width / 2); - width: parent.height - height: parent.height - - UM.RecolorImage - { - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.horizontalCenter - width: UM.Theme.getSize("standard_arrow").width - height: UM.Theme.getSize("standard_arrow").height - sourceSize.width: width - sourceSize.height: height - color: control.enabled ? UM.Theme.getColor("print_button_ready_text") : UM.Theme.getColor("action_button_disabled_text") - source: UM.Theme.getIcon("arrow_bottom") - } - } - } - - menu: Menu - { - id: devicesMenu; - Instantiator - { - model: devicesModel; - MenuItem - { - text: model.description - checkable: true; - checked: model.id == UM.OutputDeviceManager.activeDevice - exclusiveGroup: devicesMenuGroup - onTriggered: - { - UM.OutputDeviceManager.setActiveDevice(model.id); - } - } - onObjectAdded: devicesMenu.insertItem(index, object) - onObjectRemoved: devicesMenu.removeItem(object) - } - ExclusiveGroup { id: devicesMenuGroup } - } - } - UM.OutputDevicesModel { id: devicesModel } - } -} From d74393498b18805de9453e05bded2e9c09a3d928 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 21 Nov 2018 09:35:35 +0100 Subject: [PATCH 0311/1292] Fixed view selector header not updating correctly CURA-5785 --- plugins/PreviewStage/PreviewMenu.qml | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index 1a744aeb65..fa1b6aae0f 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -54,22 +54,27 @@ Item { for (var i = 0; i < viewModel.rowCount(); i++) { - if (viewModel.getItem(i).active) + if (viewModel.items[i].active) { - return viewModel.getItem(i) + return viewModel.items[i] } } - // Nothing was active, so just return the first one (the list is sorted by priority, so the most - // important one should be returned) - return viewModel.getItem(0) + return null } - // Ensure that the controller is synced with whatever happend here. - onActiveViewChanged: UM.Controller.setActiveView(activeView.id) + Component.onCompleted: + { + // Nothing was active, so just return the first one (the list is sorted by priority, so the most + // important one should be returned) + if(activeView == null) + { + UM.Controller.setActiveView(viewModel.getItem(0).id) + } + } headerItem: Label { - text: viewSelector.activeView.name + text: viewSelector.activeView ? viewSelector.activeView.name : "" verticalAlignment: Text.AlignVCenter height: parent.height elide: Text.ElideRight @@ -98,7 +103,7 @@ Item text: name radius: UM.Theme.getSize("default_radius").width checkable: true - checked: active + checked: viewSelector.activeView != null ? viewSelector.activeView.id == id : false onClicked: { viewSelector.togglePopup() From 9e8be286af8736a97bf05db3b4bb5b0063be944b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Wed, 21 Nov 2018 10:12:53 +0100 Subject: [PATCH 0312/1292] Used NamedTuple from typing iso namedtuple from collections so we can at least give type hints --- plugins/UM3NetworkPrinting/src/Models.py | 54 +++++++++---------- .../UM3NetworkPrinting/src/SendMaterialJob.py | 51 +++++++++--------- .../tests/TestSendMaterialJob.py | 4 +- 3 files changed, 55 insertions(+), 54 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Models.py b/plugins/UM3NetworkPrinting/src/Models.py index a9210ac5b4..e84a39db5a 100644 --- a/plugins/UM3NetworkPrinting/src/Models.py +++ b/plugins/UM3NetworkPrinting/src/Models.py @@ -1,33 +1,33 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from collections import namedtuple +from typing import NamedTuple -ClusterMaterial = namedtuple('ClusterMaterial', [ - 'guid', - 'material', - 'brand', - 'version', - 'color', - 'density' +ClusterMaterial = NamedTuple("ClusterMaterial", [ + ("guid", str), + ("material", str), + ("brand", str), + ("version", int), + ("color", str), + ("density", str), ]) -LocalMaterial = namedtuple('LocalMaterial', [ - 'GUID', - 'id', - 'type', - 'status', - 'base_file', - 'setting_version', - 'version', - 'name', - 'brand', - 'material', - 'color_name', - 'color_code', - 'description', - 'adhesion_info', - 'approximate_diameter', - 'properties', - 'definition', - 'compatible' +LocalMaterial = NamedTuple("LocalMaterial", [ + ("GUID", str), + ("id", str), + ("type", str), + ("status", str), + ("base_file", str), + ("setting_version", int), + ("version", int), + ("name", str), + ("brand", str), + ("material", str), + ("color_name", str), + ("color_code", str), + ("description", str), + ("adhesion_info", str), + ("approximate_diameter", str), + ("properties", str), + ("definition", str), + ("compatible", str), ]) diff --git a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py index fe0cd98964..ee8dd8042d 100644 --- a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py @@ -2,7 +2,6 @@ # Cura is released under the terms of the LGPLv3 or higher. import json import os -import re import urllib.parse from typing import Dict, TYPE_CHECKING, Set @@ -13,13 +12,13 @@ from UM.Logger import Logger from UM.MimeTypeDatabase import MimeTypeDatabase from UM.Resources import Resources from cura.CuraApplication import CuraApplication - # Absolute imports don't work in plugins from .Models import ClusterMaterial, LocalMaterial if TYPE_CHECKING: from .ClusterUM3OutputDevice import ClusterUM3OutputDevice + ## Asynchronous job to send material profiles to the printer. # # This way it won't freeze up the interface while sending those materials. @@ -86,7 +85,7 @@ class SendMaterialJob(Job): return { material.id for guid, material in local_materials.items() - if guid not in remote_materials or int(material.version) > remote_materials[guid].version + if guid not in remote_materials or material.version > remote_materials[guid].version } ## Send the materials to the printer. @@ -122,23 +121,23 @@ class SendMaterialJob(Job): # \param material_id The ID of the material in the file. def _sendMaterialFile(self, file_path: str, file_name: str, material_id: str) -> None: - parts = [] + parts = [] - # Add the material file. - with open(file_path, "rb") as f: - parts.append(self.device.createFormPart("name=\"file\"; filename=\"{file_name}\"" - .format(file_name = file_name), f.read())) + # Add the material file. + with open(file_path, "rb") as f: + parts.append(self.device.createFormPart("name=\"file\"; filename=\"{file_name}\"" + .format(file_name = file_name), f.read())) - # Add the material signature file if needed. - signature_file_path = "{}.sig".format(file_path) - if os.path.exists(signature_file_path): - signature_file_name = os.path.basename(signature_file_path) - with open(signature_file_path, "rb") as f: - parts.append(self.device.createFormPart("name=\"signature_file\"; filename=\"{file_name}\"" - .format(file_name = signature_file_name), f.read())) + # Add the material signature file if needed. + signature_file_path = "{}.sig".format(file_path) + if os.path.exists(signature_file_path): + signature_file_name = os.path.basename(signature_file_path) + with open(signature_file_path, "rb") as f: + parts.append(self.device.createFormPart("name=\"signature_file\"; filename=\"{file_name}\"" + .format(file_name = signature_file_name), f.read())) - Logger.log("d", "Syncing material {material_id} with cluster.".format(material_id = material_id)) - self.device.postFormWithParts(target = "materials/", parts = parts, on_finished = self.sendingFinished) + Logger.log("d", "Syncing material {material_id} with cluster.".format(material_id = material_id)) + self.device.postFormWithParts(target = "materials/", parts = parts, on_finished = self.sendingFinished) ## Check a reply from an upload to the printer and log an error when the call failed @staticmethod @@ -174,16 +173,18 @@ class SendMaterialJob(Job): # Find the latest version of all material containers in the registry. for material in material_containers: try: - material = LocalMaterial(**material) - # material version must be an int - if not re.match("\d+", material.version): - Logger.logException("w", "Local material {} has invalid version '{}'." - .format(material["id"], material.version)) - continue + material["version"] = int(material["version"]) - if material.GUID not in result or material.version > result.get(material.GUID).version: - result[material.GUID] = material + # Create a new local material + local_material = LocalMaterial(**material) + + if local_material.GUID not in result or \ + local_material.version > result.get(local_material.GUID).version: + result[local_material.GUID] = local_material + + except KeyError: + Logger.logException("w", "Local material {} has missing values.".format(material["id"])) except ValueError: Logger.logException("w", "Local material {} has invalid values.".format(material["id"])) diff --git a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py index f4604580fe..ff896683e1 100644 --- a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py @@ -19,7 +19,7 @@ from plugins.UM3NetworkPrinting.src.SendMaterialJob import SendMaterialJob @patch("UM.Resources.Resources.getAllResourcesOfType", lambda _: ["/materials/generic_pla_white.xml.fdm_material"]) class TestSendMaterialJob(TestCase): _LOCAL_MATERIAL_WHITE = {"type": "material", "status": "unknown", "id": "generic_pla_white", - "base_file": "generic_pla_white", "setting_version": 5, "name": "White PLA", + "base_file": "generic_pla_white", "setting_version": "5", "name": "White PLA", "brand": "Generic", "material": "PLA", "color_name": "White", "GUID": "badb0ee7-87c8-4f3f-9398-938587b67dce", "version": "1", "color_code": "#ffffff", "description": "Test PLA White", "adhesion_info": "Use glue.", "approximate_diameter": "3", @@ -27,7 +27,7 @@ class TestSendMaterialJob(TestCase): "definition": "fdmprinter", "compatible": True} _LOCAL_MATERIAL_BLACK = {"type": "material", "status": "unknown", "id": "generic_pla_black", - "base_file": "generic_pla_black", "setting_version": 5, "name": "Yellow CPE", + "base_file": "generic_pla_black", "setting_version": "5", "name": "Yellow CPE", "brand": "Ultimaker", "material": "CPE", "color_name": "Black", "GUID": "5fbb362a-41f9-4818-bb43-15ea6df34aa4", "version": "1", "color_code": "#000000", "description": "Test PLA Black", "adhesion_info": "Use glue.", "approximate_diameter": "3", From 7b0f8882a2715d4beb9378646bc915e77c8f4963 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Wed, 21 Nov 2018 11:01:26 +0100 Subject: [PATCH 0313/1292] Reverted models to namedtuples from collections because NamedTuple is a Python3.6 feature --- plugins/UM3NetworkPrinting/src/Models.py | 54 ++++++++++++------------ 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Models.py b/plugins/UM3NetworkPrinting/src/Models.py index e84a39db5a..d5e1007555 100644 --- a/plugins/UM3NetworkPrinting/src/Models.py +++ b/plugins/UM3NetworkPrinting/src/Models.py @@ -1,33 +1,33 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import NamedTuple +from collections import namedtuple -ClusterMaterial = NamedTuple("ClusterMaterial", [ - ("guid", str), - ("material", str), - ("brand", str), - ("version", int), - ("color", str), - ("density", str), +ClusterMaterial = namedtuple('ClusterMaterial', [ + 'guid', # Type: str + 'material', # Type: str + 'brand', # Type: str + 'version', # Type: int + 'color', # Type: str + 'density' # Type: str ]) -LocalMaterial = NamedTuple("LocalMaterial", [ - ("GUID", str), - ("id", str), - ("type", str), - ("status", str), - ("base_file", str), - ("setting_version", int), - ("version", int), - ("name", str), - ("brand", str), - ("material", str), - ("color_name", str), - ("color_code", str), - ("description", str), - ("adhesion_info", str), - ("approximate_diameter", str), - ("properties", str), - ("definition", str), - ("compatible", str), +LocalMaterial = namedtuple('LocalMaterial', [ + 'GUID', # Type: str + 'id', # Type: str + 'type', # Type: str + 'status', # Type: str + 'base_file', # Type: str + 'setting_version', # Type: int + 'version', # Type: int + 'name', # Type: str + 'brand', # Type: str + 'material', # Type: str + 'color_name', # Type: str + 'color_code', # Type: str + 'description', # Type: str + 'adhesion_info', # Type: str + 'approximate_diameter', # Type: str + 'properties', # Type: str + 'definition', # Type: str + 'compatible' # Type: str ]) From 8e47d0475632296030f9e2d1f49c6d8797b93982 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 21 Nov 2018 11:12:59 +0100 Subject: [PATCH 0314/1292] Adjust sizes and alignments to the print selector panel. Contributes to CURA-5942. --- plugins/PrepareStage/PrepareMenu.qml | 2 +- resources/qml/ExpandableComponent.qml | 19 +++++++++++++++--- resources/qml/MachineSelector.qml | 27 +++++++++++++------------- resources/themes/cura-light/theme.json | 9 +++++---- 4 files changed, 35 insertions(+), 22 deletions(-) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index ef01625a22..121928e19f 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -46,7 +46,7 @@ Item anchors.centerIn: parent - width: 0.9 * prepareMenu.width + width: Math.round(0.9 * prepareMenu.width) height: parent.height spacing: 0 diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index 8ed6dc5674..c1e3bc7985 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -10,6 +10,13 @@ import UM 1.2 as UM Item { id: base + + // Enumeration with the different possible alignments of the popup with respect of the headerItem + enum PopupAlignment { + AlignLeft, + AlignRight + } + // The headerItem holds the QML item that is always displayed. property alias headerItem: headerItemLoader.sourceComponent @@ -21,6 +28,9 @@ Item property color headerBackgroundColor: UM.Theme.getColor("action_button") property color headerHoverColor: UM.Theme.getColor("action_button_hovered") + // Defines the alignment of the popup with respect of the headerItem, by default to the right + property int popupAlignment: ExpandableComponent.PopupAlignment.AlignRight + // How much spacing is needed around the popupItem property alias popupPadding: popup.padding @@ -42,6 +52,7 @@ Item function togglePopup() { +// print(popupAlignment, popupAlignment == PopupAlignment.AlignRight) if(popup.visible) { popup.close() @@ -116,8 +127,8 @@ Item sourceSize.height: height visible: source != "" width: height - height: 0.2 * base.height - color: "black" + height: Math.round(0.2 * base.height) + color: UM.Theme.getColor("text") } MouseArea @@ -140,13 +151,15 @@ Item // Make the popup right aligned with the rest. The 3x padding is due to left, right and padding between // the button & text. - x: -width + collapseButton.width + headerItemLoader.width + 3 * background.padding + x: popupAlignment == ExpandableComponent.PopupAlignment.AlignRight ? -width + collapseButton.width + headerItemLoader.width + 3 * background.padding : 0 padding: UM.Theme.getSize("default_margin").width closePolicy: Popup.CloseOnPressOutsideParent background: Rectangle { color: popupBackgroundColor + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("lining") } } } diff --git a/resources/qml/MachineSelector.qml b/resources/qml/MachineSelector.qml index c9756d93ba..f029914884 100644 --- a/resources/qml/MachineSelector.qml +++ b/resources/qml/MachineSelector.qml @@ -17,6 +17,8 @@ Cura.ExpandableComponent property bool isNetworkPrinter: Cura.MachineManager.activeMachineNetworkKey != "" + popupPadding: 0 + popupAlignment: ExpandableComponent.PopupAlignment.AlignLeft iconSource: expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") UM.I18nCatalog @@ -31,6 +33,7 @@ Cura.ExpandableComponent verticalAlignment: Text.AlignVCenter height: parent.height elide: Text.ElideRight + renderType: Text.NativeRendering font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") } @@ -38,26 +41,25 @@ Cura.ExpandableComponent popupItem: Item { id: popup - width: machineSelector.width - 2 * UM.Theme.getSize("default_margin").width - height: 200 + width: UM.Theme.getSize("machine_selector_widget_content").width + height: UM.Theme.getSize("machine_selector_widget_content").height ScrollView { anchors.fill: parent - contentHeight: column.implicitHeight - contentWidth: column.implicitWidth clip: true - ScrollBar.horizontal.policy: ScrollBar.AlwaysOff Column { id: column anchors.fill: parent + Label { - text: catalog.i18nc("@label", "Networked Printers") + text: catalog.i18nc("@label", "Network connected printers") visible: networkedPrintersModel.items.length > 0 height: visible ? contentHeight + 2 * UM.Theme.getSize("default_margin").height : 0 + renderType: Text.NativeRendering font: UM.Theme.getFont("medium_bold") color: UM.Theme.getColor("text") verticalAlignment: Text.AlignVCenter @@ -73,13 +75,12 @@ Cura.ExpandableComponent filter: {"type": "machine", "um_network_key": "*", "hidden": "False"} } - delegate: RoundButton + delegate: Button { text: name width: parent.width - checkable: true - radius: UM.Theme.getSize("default_radius").width + onClicked: { togglePopup() @@ -92,14 +93,14 @@ Cura.ExpandableComponent onActiveMachineNetworkGroupNameChanged: checked = Cura.MachineManager.activeMachineNetworkGroupName == model.metadata["connect_group_name"] } } - } Label { - text: catalog.i18nc("@label", "Virtual Printers") + text: catalog.i18nc("@label", "Preset printers") visible: virtualPrintersModel.items.length > 0 height: visible ? contentHeight + 2 * UM.Theme.getSize("default_margin").height : 0 + renderType: Text.NativeRendering font: UM.Theme.getFont("medium_bold") color: UM.Theme.getColor("text") verticalAlignment: Text.AlignVCenter @@ -115,21 +116,19 @@ Cura.ExpandableComponent filter: {"type": "machine", "um_network_key": null} } - delegate: RoundButton + delegate: Button { text: name width: parent.width checked: Cura.MachineManager.activeMachineId == model.id checkable: true - radius: UM.Theme.getSize("default_radius").width onClicked: { togglePopup() Cura.MachineManager.setActiveMachine(model.id) } } - } } } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index d28611529b..5f52adff14 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -367,11 +367,11 @@ "sizes": { "window_minimum_size": [106, 66], - "main_window_header": [0.0, 4.5], + "main_window_header": [0.0, 4.0], "main_window_header_button": [8, 2.35], "main_window_header_button_icon": [1.2, 1.2], - "stage_menu": [0.0, 4.5], + "stage_menu": [0.0, 4.0], "account_button": [12, 3], @@ -380,14 +380,15 @@ "print_setup_item": [0.0, 2.0], "print_setup_extruder_box": [0.0, 6.0], - "configuration_selector_widget": [35.0, 4.5], + "configuration_selector_widget": [35.0, 4.0], "configuration_selector_mode_tabs": [0.0, 3.0], "action_panel_widget": [25.0, 0.0], "action_panel_information_widget": [20.0, 0.0], "action_panel_button": [15.0, 3.0], - "machine_selector_widget": [16.0, 4.5], + "machine_selector_widget": [20.0, 4.0], + "machine_selector_widget_content": [25.0, 32.0], "views_selector": [0.0, 4.0], From b826a420265051cefd6483eb228e3716182b1380 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 21 Nov 2018 11:37:58 +0100 Subject: [PATCH 0315/1292] Add the RoundedRectangle as background to the ExpandableComponent This way the expandable components can have rounded corners only on one side, thus preventing the need to do add backgrounds to the rows that they are in. CURA-5785 --- plugins/PrepareStage/PrepareMenu.qml | 99 ++++++------- plugins/PreviewStage/PreviewMenu.qml | 191 ++++++++++++-------------- resources/qml/Cura.qml | 1 + resources/qml/ExpandableComponent.qml | 9 +- resources/qml/RoundedRectangle.qml | 39 ++++++ 5 files changed, 181 insertions(+), 158 deletions(-) create mode 100644 resources/qml/RoundedRectangle.qml diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index ef01625a22..22f93aa5f2 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -24,77 +24,66 @@ Item Item { anchors.horizontalCenter: parent.horizontalCenter - width: openFileButtonBackground.width + itemRowBackground.width + width: openFileButtonBackground.width + itemRow.width + UM.Theme.getSize("default_margin").width height: parent.height - Rectangle + RowLayout { - id: itemRowBackground - radius: UM.Theme.getSize("default_radius").width - - color: UM.Theme.getColor("toolbar_background") - - width: itemRow.width + UM.Theme.getSize("default_margin").width - height: parent.height + id: itemRow anchors.left: openFileButtonBackground.right anchors.leftMargin: UM.Theme.getSize("default_margin").width - RowLayout + width: 0.9 * prepareMenu.width + height: parent.height + spacing: 0 + + Cura.MachineSelector { - id: itemRow + id: machineSelection + z: openFileButtonBackground.z - 1 //Ensure that the tooltip of the open file button stays above the item row. + headerCornerSide: 2 // Show corners on the left. + Layout.minimumWidth: UM.Theme.getSize("machine_selector_widget").width + Layout.maximumWidth: UM.Theme.getSize("machine_selector_widget").width + Layout.fillWidth: true + Layout.fillHeight: true + } - anchors.centerIn: parent - - width: 0.9 * prepareMenu.width + // Separator line + Rectangle + { height: parent.height - spacing: 0 + width: UM.Theme.getSize("default_lining").width + color: UM.Theme.getColor("lining") + } - Cura.MachineSelector - { - id: machineSelection - z: openFileButtonBackground.z - 1 //Ensure that the tooltip of the open file button stays above the item row. - Layout.minimumWidth: UM.Theme.getSize("machine_selector_widget").width - Layout.maximumWidth: UM.Theme.getSize("machine_selector_widget").width - Layout.fillWidth: true - Layout.fillHeight: true - } + Cura.QuickConfigurationSelector + { + Layout.fillHeight: true + Layout.fillWidth: true + Layout.preferredWidth: itemRow.width - machineSelection.width - printSetupSelectorItem.width - 2 * UM.Theme.getSize("default_lining").width + } - // Separator line - Rectangle - { - height: parent.height - width: UM.Theme.getSize("default_lining").width - color: UM.Theme.getColor("lining") - } + // Separator line + Rectangle + { + height: parent.height + width: UM.Theme.getSize("default_lining").width + color: UM.Theme.getColor("lining") + } - Cura.QuickConfigurationSelector - { - Layout.fillHeight: true - Layout.fillWidth: true - Layout.preferredWidth: itemRow.width - machineSelection.width - printSetupSelectorItem.width - 2 * UM.Theme.getSize("default_lining").width - } - - // Separator line - Rectangle - { - height: parent.height - width: UM.Theme.getSize("default_lining").width - color: UM.Theme.getColor("lining") - } - - Item - { - id: printSetupSelectorItem - // This is a work around to prevent the printSetupSelector from having to be re-loaded every time - // a stage switch is done. - children: [printSetupSelector] - height: childrenRect.height - width: childrenRect.width - } + Item + { + id: printSetupSelectorItem + // This is a work around to prevent the printSetupSelector from having to be re-loaded every time + // a stage switch is done. + children: [printSetupSelector] + height: childrenRect.height + width: childrenRect.width } } + Rectangle { id: openFileButtonBackground diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index fa1b6aae0f..d6033d6272 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -22,135 +22,122 @@ Item name: "cura" } - Rectangle - { - anchors.fill: stageMenu - anchors.leftMargin: -radius - radius: UM.Theme.getSize("default_radius").width - color: UM.Theme.getColor("toolbar_background") - } - Item + Row { - id: stageMenu + id: stageMenuRow + anchors.centerIn: parent height: parent.height - width: stageMenuRow.width + UM.Theme.getSize("default_margin").width - anchors.horizontalCenter: parent.horizontalCenter - Row + + Cura.ExpandableComponent { - id: stageMenuRow - anchors.centerIn: parent + id: viewSelector + iconSource: expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") height: parent.height + headerCornerSide: 2 // Show corners on the left side - Cura.ExpandableComponent + property var viewModel: UM.ViewModel { } + + property var activeView: { - id: viewSelector - iconSource: expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") - height: parent.height - - property var viewModel: UM.ViewModel { } - - property var activeView: + for (var i = 0; i < viewModel.rowCount(); i++) { - for (var i = 0; i < viewModel.rowCount(); i++) + if (viewModel.items[i].active) { - if (viewModel.items[i].active) - { - return viewModel.items[i] - } + return viewModel.items[i] } - return null } + return null + } + Component.onCompleted: + { + // Nothing was active, so just return the first one (the list is sorted by priority, so the most + // important one should be returned) + if(activeView == null) + { + UM.Controller.setActiveView(viewModel.getItem(0).id) + } + } + + headerItem: Label + { + text: viewSelector.activeView ? viewSelector.activeView.name : "" + verticalAlignment: Text.AlignVCenter + height: parent.height + elide: Text.ElideRight + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + } + + popupItem: Column + { + id: viewSelectorPopup + width: viewSelector.width - 2 * UM.Theme.getSize("default_margin").width + + // For some reason the height/width of the column gets set to 0 if this is not set... Component.onCompleted: { - // Nothing was active, so just return the first one (the list is sorted by priority, so the most - // important one should be returned) - if(activeView == null) - { - UM.Controller.setActiveView(viewModel.getItem(0).id) - } + height = implicitHeight + width = viewSelector.width - 2 * UM.Theme.getSize("default_margin").width } - headerItem: Label + Repeater { - text: viewSelector.activeView ? viewSelector.activeView.name : "" - verticalAlignment: Text.AlignVCenter - height: parent.height - elide: Text.ElideRight - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - } - - popupItem: Column - { - id: viewSelectorPopup - width: viewSelector.width - 2 * UM.Theme.getSize("default_margin").width - - // For some reason the height/width of the column gets set to 0 if this is not set... - Component.onCompleted: + id: viewsList + model: viewSelector.viewModel + RoundButton { - height = implicitHeight - width = viewSelector.width - 2 * UM.Theme.getSize("default_margin").width - } - - Repeater - { - id: viewsList - model: viewSelector.viewModel - RoundButton + text: name + radius: UM.Theme.getSize("default_radius").width + checkable: true + checked: viewSelector.activeView != null ? viewSelector.activeView.id == id : false + onClicked: { - text: name - radius: UM.Theme.getSize("default_radius").width - checkable: true - checked: viewSelector.activeView != null ? viewSelector.activeView.id == id : false - onClicked: - { - viewSelector.togglePopup() - UM.Controller.setActiveView(id) - } + viewSelector.togglePopup() + UM.Controller.setActiveView(id) } } - } - } - // Separator line - Rectangle - { - height: parent.height - // If there is no viewPanel, we only need a single spacer, so hide this one. - visible: viewPanel.source != "" - width: visible ? UM.Theme.getSize("default_lining").width : 0 - - color: UM.Theme.getColor("lining") } + } - Loader - { - id: viewPanel - height: parent.height - width: childrenRect.width - source: UM.Controller.activeView != null && UM.Controller.activeView.stageMenuComponent != null ? UM.Controller.activeView.stageMenuComponent : "" - } + // Separator line + Rectangle + { + height: parent.height + // If there is no viewPanel, we only need a single spacer, so hide this one. + visible: viewPanel.source != "" + width: visible ? UM.Theme.getSize("default_lining").width : 0 - // Separator line - Rectangle - { - height: parent.height - width: UM.Theme.getSize("default_lining").width - color: UM.Theme.getColor("lining") - } + color: UM.Theme.getColor("lining") + } - Item - { - id: printSetupSelectorItem - // This is a work around to prevent the printSetupSelector from having to be re-loaded every time - // a stage switch is done. - children: [printSetupSelector] - height: childrenRect.height - width: childrenRect.width - } + Loader + { + id: viewPanel + height: parent.height + width: childrenRect.width + source: UM.Controller.activeView != null && UM.Controller.activeView.stageMenuComponent != null ? UM.Controller.activeView.stageMenuComponent : "" + } + + // Separator line + Rectangle + { + height: parent.height + width: UM.Theme.getSize("default_lining").width + color: UM.Theme.getColor("lining") + } + + Item + { + id: printSetupSelectorItem + // This is a work around to prevent the printSetupSelector from having to be re-loaded every time + // a stage switch is done. + children: [printSetupSelector] + height: childrenRect.height + width: childrenRect.width } } } diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index c239dc8d6f..711c05c64c 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -259,6 +259,7 @@ UM.MainWindow onHideTooltip: base.hideTooltip() width: UM.Theme.getSize("print_setup_widget").width height: UM.Theme.getSize("stage_menu").height + headerCornerSide: 4 // Show corners on the right side } } diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index 8ed6dc5674..262c6bfd3f 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -40,6 +40,12 @@ Item property alias expandedHighlightColor: expandedHighlight.color + // What should the radius of the header be. This is also influenced by the headerCornerSide + property alias headerRadius: background.radius + + // On what side should the header corners be shown? 1 is down, 2 is left, 3 is up and 4 is right. + property alias headerCornerSide: background.cornerSide + function togglePopup() { if(popup.visible) @@ -71,7 +77,8 @@ Item implicitHeight: 100 * screenScaleFactor implicitWidth: 400 * screenScaleFactor - Rectangle + + RoundedRectangle { id: background property real padding: UM.Theme.getSize("default_margin").width diff --git a/resources/qml/RoundedRectangle.qml b/resources/qml/RoundedRectangle.qml new file mode 100644 index 0000000000..d7ba7d6d13 --- /dev/null +++ b/resources/qml/RoundedRectangle.qml @@ -0,0 +1,39 @@ +import QtQuick 2.0 + +import UM 1.2 as UM + +// The rounded rectangle works mostly like a regular rectangle, but provides the option to have rounded corners on only one side of the rectangle. +Item +{ + // As per the regular rectangle + property color color: "transparent" + + // As per regular rectangle + property int radius: UM.Theme.getSize("default_radius").width + + // On what side should the corners be shown 0 can be used if no radius is needed. + // 1 is down, 2 is left, 3 is up and 4 is right. + property int cornerSide: 0 + + Rectangle + { + id: background + anchors.fill: parent + radius: cornerSide != 0 ? parent.radius : 0 + color: parent.color + } + + // The item that covers 2 of the corners to make them not rounded. + Rectangle + { + visible: cornerSide != 0 + height: cornerSide % 2 ? parent.radius: parent.height + width: cornerSide % 2 ? parent.width : parent.radius + color: parent.color + anchors + { + right: cornerSide == 2 ? parent.right: undefined + bottom: cornerSide == 3 ? parent.bottom: undefined + } + } +} From de650300e20abf2a54baa953076bb71cf2943e1b Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 21 Nov 2018 11:43:20 +0100 Subject: [PATCH 0316/1292] Add the buttons to add printer and manage printers in the bottom of the print selector panel. Contributes to CURA-5942. --- resources/qml/ExpandableComponent.qml | 6 ++-- resources/qml/MachineSelector.qml | 52 +++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index c1e3bc7985..aa9e1467fa 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -52,7 +52,6 @@ Item function togglePopup() { -// print(popupAlignment, popupAlignment == PopupAlignment.AlignRight) if(popup.visible) { popup.close() @@ -149,8 +148,8 @@ Item // Ensure that the popup is located directly below the headerItem y: headerItemLoader.height + 2 * background.padding - // Make the popup right aligned with the rest. The 3x padding is due to left, right and padding between - // the button & text. + // Make the popup aligned with the rest, using the property popupAlignment to decide whether is right or left. + // In case of right alignment, the 3x padding is due to left, right and padding between the button & text. x: popupAlignment == ExpandableComponent.PopupAlignment.AlignRight ? -width + collapseButton.width + headerItemLoader.width + 3 * background.padding : 0 padding: UM.Theme.getSize("default_margin").width closePolicy: Popup.CloseOnPressOutsideParent @@ -160,6 +159,7 @@ Item color: popupBackgroundColor border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") + radius: UM.Theme.getSize("default_radius").width } } } diff --git a/resources/qml/MachineSelector.qml b/resources/qml/MachineSelector.qml index f029914884..3e70fda299 100644 --- a/resources/qml/MachineSelector.qml +++ b/resources/qml/MachineSelector.qml @@ -1,7 +1,7 @@ // Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.2 +import QtQuick 2.7 import QtQuick.Controls 2.3 import QtQuick.Controls.Styles 1.1 import QtQuick.Layouts 1.1 @@ -46,7 +46,9 @@ Cura.ExpandableComponent ScrollView { - anchors.fill: parent + width: parent.width + anchors.top: parent.top + anchors.bottom: separator.top clip: true Column @@ -80,7 +82,7 @@ Cura.ExpandableComponent text: name width: parent.width checkable: true - + onClicked: { togglePopup() @@ -132,5 +134,49 @@ Cura.ExpandableComponent } } } + + Rectangle + { + id: separator + + anchors.bottom: buttonRow.top + width: parent.width + height: UM.Theme.getSize("default_lining").height + color: UM.Theme.getColor("lining") + } + + Row + { + id: buttonRow + + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + padding: UM.Theme.getSize("default_margin").width + spacing: UM.Theme.getSize("default_margin").width + + Cura.ActionButton + { + leftPadding: UM.Theme.getSize("default_margin").width + rightPadding: UM.Theme.getSize("default_margin").width + text: catalog.i18nc("@button", "Add printer") + color: UM.Theme.getColor("secondary") + hoverColor: UM.Theme.getColor("secondary") + textColor: UM.Theme.getColor("primary") + textHoverColor: UM.Theme.getColor("text") + onClicked: Cura.Actions.addMachine.trigger() + } + + Cura.ActionButton + { + leftPadding: UM.Theme.getSize("default_margin").width + rightPadding: UM.Theme.getSize("default_margin").width + text: catalog.i18nc("@button", "Manage printers") + color: UM.Theme.getColor("secondary") + hoverColor: UM.Theme.getColor("secondary") + textColor: UM.Theme.getColor("primary") + textHoverColor: UM.Theme.getColor("text") + onClicked: Cura.Actions.configureMachines.trigger() + } + } } } From 64bbab9d4024df8d1be956040d81a69551922308 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 21 Nov 2018 11:50:00 +0100 Subject: [PATCH 0317/1292] Use the group name to show in the printer list if it's a network connected printer. Contributes to CURA-5942. --- resources/qml/MachineSelector.qml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/resources/qml/MachineSelector.qml b/resources/qml/MachineSelector.qml index 3e70fda299..417c5722b4 100644 --- a/resources/qml/MachineSelector.qml +++ b/resources/qml/MachineSelector.qml @@ -79,8 +79,9 @@ Cura.ExpandableComponent delegate: Button { - text: name + text: model.metadata["connect_group_name"] width: parent.width + checked: Cura.MachineManager.activeMachineNetworkGroupName == model.metadata["connect_group_name"] checkable: true onClicked: @@ -120,7 +121,7 @@ Cura.ExpandableComponent delegate: Button { - text: name + text: model.name width: parent.width checked: Cura.MachineManager.activeMachineId == model.id checkable: true From eef6ad662d816ac8266faaa391342accab36f07d Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 21 Nov 2018 11:50:39 +0100 Subject: [PATCH 0318/1292] Added enum for the roundedCorner property This makes it a whole lot easier to read what is being set. CURA-5785 --- plugins/PrepareStage/PrepareMenu.qml | 2 +- plugins/PreviewStage/PreviewMenu.qml | 2 +- resources/qml/Cura.qml | 2 +- resources/qml/RoundedRectangle.qml | 24 +++++++++++++++++------- 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index 22f93aa5f2..bf2a0e1283 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -42,7 +42,7 @@ Item { id: machineSelection z: openFileButtonBackground.z - 1 //Ensure that the tooltip of the open file button stays above the item row. - headerCornerSide: 2 // Show corners on the left. + headerCornerSide: Cura.RoundedRectangle.Direction.Left Layout.minimumWidth: UM.Theme.getSize("machine_selector_widget").width Layout.maximumWidth: UM.Theme.getSize("machine_selector_widget").width Layout.fillWidth: true diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index d6033d6272..29632e5f00 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -34,7 +34,7 @@ Item id: viewSelector iconSource: expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") height: parent.height - headerCornerSide: 2 // Show corners on the left side + headerCornerSide: Cura.RoundedRectangle.Direction.Left property var viewModel: UM.ViewModel { } diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 711c05c64c..2814bb9eb2 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -259,7 +259,7 @@ UM.MainWindow onHideTooltip: base.hideTooltip() width: UM.Theme.getSize("print_setup_widget").width height: UM.Theme.getSize("stage_menu").height - headerCornerSide: 4 // Show corners on the right side + headerCornerSide: RoundedRectangle.Direction.Right } } diff --git a/resources/qml/RoundedRectangle.qml b/resources/qml/RoundedRectangle.qml index d7ba7d6d13..9ad2230be5 100644 --- a/resources/qml/RoundedRectangle.qml +++ b/resources/qml/RoundedRectangle.qml @@ -1,4 +1,4 @@ -import QtQuick 2.0 +import QtQuick 2.7 import UM 1.2 as UM @@ -11,29 +11,39 @@ Item // As per regular rectangle property int radius: UM.Theme.getSize("default_radius").width - // On what side should the corners be shown 0 can be used if no radius is needed. + // On what side should the corners be shown 5 can be used if no radius is needed. // 1 is down, 2 is left, 3 is up and 4 is right. - property int cornerSide: 0 + property int cornerSide: RoundedRectangle.Direction.None + + enum Direction + { + None = 0, + Down = 1, + Left = 2, + Up = 3, + Right = 4, + All = 5 + } Rectangle { id: background anchors.fill: parent - radius: cornerSide != 0 ? parent.radius : 0 + radius: cornerSide != RoundedRectangle.Direction.None ? parent.radius : 0 color: parent.color } // The item that covers 2 of the corners to make them not rounded. Rectangle { - visible: cornerSide != 0 + visible: cornerSide != RoundedRectangle.Direction.None && cornerSide != RoundedRectangle.Direction.All height: cornerSide % 2 ? parent.radius: parent.height width: cornerSide % 2 ? parent.width : parent.radius color: parent.color anchors { - right: cornerSide == 2 ? parent.right: undefined - bottom: cornerSide == 3 ? parent.bottom: undefined + right: cornerSide == RoundedRectangle.Direction.Left ? parent.right: undefined + bottom: cornerSide == RoundedRectangle.Direction.Up ? parent.bottom: undefined } } } From bfd8e666570d636293bae9dbda0c2134de992065 Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Wed, 21 Nov 2018 12:50:18 +0100 Subject: [PATCH 0319/1292] Removed margins and unused arches CURA-5941 --- resources/qml/PrintSetupSelector.qml | 46 +++++++++++++--------------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/resources/qml/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector.qml index ed09238b51..61cc06b426 100644 --- a/resources/qml/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector.qml @@ -116,7 +116,6 @@ Cura.ExpandableComponent } } - Cura.ExtrudersModel { id: extrudersModel @@ -124,7 +123,7 @@ Cura.ExpandableComponent popupItem: Rectangle { - property var total_height: popupItemHeader.height + popupItemContent.height + 10 + separator_footer.height + property var total_height: popupItemHeader.height + popupItemContent.height + footerControll.height + UM.Theme.getSize("print_setup_selector_margin").height * 2 id: popupItemWrapper height: total_height @@ -176,7 +175,7 @@ Cura.ExpandableComponent anchors { top: popupItemHeader.bottom - topMargin: 10 + topMargin: UM.Theme.getSize("print_setup_selector_margin").height right: parent.right left: parent.left leftMargin: 5 @@ -213,7 +212,6 @@ Cura.ExpandableComponent width: parent.height height: parent.height } - } background: Rectangle @@ -232,11 +230,11 @@ Cura.ExpandableComponent // overlap bottom border Rectangle { - width: parent.width - 4 - height: 4 + width: parent.width - UM.Theme.getSize("default_lining").width * 4 + height: UM.Theme.getSize("default_lining").width * 4 anchors.bottom: parent.bottom - anchors.bottomMargin: -2 - anchors.leftMargin: 2 + anchors.bottomMargin: - (UM.Theme.getSize("default_lining").width * 2) + anchors.leftMargin: UM.Theme.getSize("default_lining").width * 2 anchors.left: parent.left } @@ -249,18 +247,17 @@ Cura.ExpandableComponent { id: sidebarContents anchors.top: tabBar.bottom + anchors.bottom: parent.bottom anchors.left: parent.left anchors.right: parent.right height: UM.Theme.getSize("print_setup_widget").height - border.width: UM.Theme.getSize("default_lining").width * 2 border.color: UM.Theme.getColor("action_button_border") SidebarSimple { anchors.topMargin: UM.Theme.getSize("print_setup_content_top_margin").height - id: sidebar_simple_id anchors.fill: parent visible: currentModeIndex != 1 onShowTooltip: base.showTooltip(item, location, text) @@ -270,25 +267,22 @@ Cura.ExpandableComponent SidebarAdvanced { anchors.topMargin: UM.Theme.getSize("print_setup_content_top_margin").height - anchors.bottomMargin: 2 //does not overlap bottom border + anchors.bottomMargin: 2 //don't overlap bottom border anchors.fill: parent visible: currentModeIndex == 1 onShowTooltip: base.showTooltip(item, location, text) onHideTooltip: base.hideTooltip() } - } } - Item { - id: separator_footer + id: footerControll anchors.top: popupItemContent.bottom - anchors.topMargin: 10 + anchors.topMargin: UM.Theme.getSize("print_setup_selector_margin").height * 2 width: parent.width - height: settingControlButton.height + 4 - + height: settingControlButton.height + UM.Theme.getSize("default_lining").height * 4 Rectangle { width: parent.width @@ -299,7 +293,6 @@ Cura.ExpandableComponent Cura.ActionButton { id: settingControlButton - leftPadding: UM.Theme.getSize("default_margin").width rightPadding: UM.Theme.getSize("default_margin").width height: UM.Theme.getSize("action_panel_button").height @@ -315,10 +308,10 @@ Cura.ExpandableComponent anchors { top: parent.top - topMargin: 10 - bottomMargin: 10 + topMargin: UM.Theme.getSize("print_setup_selector_margin").height * 2 + bottomMargin: UM.Theme.getSize("print_setup_selector_margin").height * 2 right: parent.right - rightMargin: 5 + rightMargin: UM.Theme.getSize("print_setup_selector_margin").height } onClicked: currentModeIndex = 1 @@ -334,8 +327,6 @@ Cura.ExpandableComponent textHoverColor: UM.Theme.getColor("text") iconSource: UM.Theme.getIcon("arrow_left") width: UM.Theme.getSize("print_setup_action_button").width - - fixedWidthMode: true visible: currentModeIndex == 1 anchors @@ -347,7 +338,14 @@ Cura.ExpandableComponent leftMargin: UM.Theme.getSize("print_setup_selector_margin").height } - onClicked: currentModeIndex = 0 +// onClicked: currentModeIndex = 0 + MouseArea { + anchors.fill: parent + onClicked: { + currentModeIndex = 0 + + } + } } } Component.onCompleted: From bd636e61a0577b8f5f7eac160fa0af05757240c6 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 21 Nov 2018 13:17:36 +0100 Subject: [PATCH 0320/1292] Minor changes suggested in review CURA-5785 --- plugins/PrepareStage/PrepareMenu.qml | 2 +- plugins/PreviewStage/PreviewMenu.qml | 3 ++- plugins/SimulationView/SimulationViewMenuComponent.qml | 7 +++++-- resources/qml/ExtruderIcon.qml | 1 + resources/qml/MachineSelector.qml | 3 +++ resources/qml/PrintSetupSelector.qml | 1 + 6 files changed, 13 insertions(+), 4 deletions(-) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index bf2a0e1283..963908cea6 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -34,7 +34,7 @@ Item anchors.left: openFileButtonBackground.right anchors.leftMargin: UM.Theme.getSize("default_margin").width - width: 0.9 * prepareMenu.width + width: Math.round(0.9 * prepareMenu.width) height: parent.height spacing: 0 diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index 29632e5f00..656cf185d5 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -54,7 +54,7 @@ Item { // Nothing was active, so just return the first one (the list is sorted by priority, so the most // important one should be returned) - if(activeView == null) + if (activeView == null) { UM.Controller.setActiveView(viewModel.getItem(0).id) } @@ -68,6 +68,7 @@ Item elide: Text.ElideRight font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") + renderType: Text.NativeRendering } popupItem: Column diff --git a/plugins/SimulationView/SimulationViewMenuComponent.qml b/plugins/SimulationView/SimulationViewMenuComponent.qml index caf47508e3..110cd1c109 100644 --- a/plugins/SimulationView/SimulationViewMenuComponent.qml +++ b/plugins/SimulationView/SimulationViewMenuComponent.qml @@ -132,6 +132,7 @@ Cura.ExpandableComponent visible: UM.SimulationView.compatibilityMode height: UM.Theme.getSize("layerview_row").height width: parent.width + renderType: Text.NativeRendering } Item // Spacer @@ -188,7 +189,7 @@ Cura.ExpandableComponent leftMargin: UM.Theme.getSize("checkbox").width + Math.round(UM.Theme.getSize("default_margin").width / 2) rightMargin: UM.Theme.getSize("default_margin").width * 2 } - + renderType: Text.NativeRendering } } } @@ -254,6 +255,7 @@ Cura.ExpandableComponent text: label font: UM.Theme.getFont("default") elide: Text.ElideRight + renderType: Text.NativeRendering color: UM.Theme.getColor("setting_control_text") anchors.verticalCenter: parent.verticalCenter anchors.left: legendModelCheckBox.left @@ -310,7 +312,7 @@ Cura.ExpandableComponent width: parent.width color: UM.Theme.getColor("setting_control_text") font: UM.Theme.getFont("default") - + renderType: Text.NativeRendering Rectangle { anchors.verticalCenter: parent.verticalCenter @@ -357,6 +359,7 @@ Cura.ExpandableComponent anchors.left: parent.left color: UM.Theme.getColor("setting_control_text") font: UM.Theme.getFont("default") + renderType: Text.NativeRendering } Label diff --git a/resources/qml/ExtruderIcon.qml b/resources/qml/ExtruderIcon.qml index 87e210e75a..79106bdd3a 100644 --- a/resources/qml/ExtruderIcon.qml +++ b/resources/qml/ExtruderIcon.qml @@ -53,6 +53,7 @@ Item width: contentWidth height: contentHeight visible: extruderEnabled + renderType: Text.NativeRendering } UM.RecolorImage diff --git a/resources/qml/MachineSelector.qml b/resources/qml/MachineSelector.qml index c9756d93ba..750ac7f620 100644 --- a/resources/qml/MachineSelector.qml +++ b/resources/qml/MachineSelector.qml @@ -33,6 +33,7 @@ Cura.ExpandableComponent elide: Text.ElideRight font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") + renderType: Text.NativeRendering } popupItem: Item @@ -60,6 +61,7 @@ Cura.ExpandableComponent height: visible ? contentHeight + 2 * UM.Theme.getSize("default_margin").height : 0 font: UM.Theme.getFont("medium_bold") color: UM.Theme.getColor("text") + renderType: Text.NativeRendering verticalAlignment: Text.AlignVCenter } @@ -103,6 +105,7 @@ Cura.ExpandableComponent font: UM.Theme.getFont("medium_bold") color: UM.Theme.getColor("text") verticalAlignment: Text.AlignVCenter + renderType: Text.NativeRendering } Repeater diff --git a/resources/qml/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector.qml index b843244147..2ecdc9e546 100644 --- a/resources/qml/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector.qml @@ -182,6 +182,7 @@ Cura.ExpandableComponent verticalAlignment: Text.AlignVCenter renderType: Text.NativeRendering elide: Text.ElideRight + color: { if(control.pressed) From c7dbaa3a001fbca621e94134e15ce0d0c5ae4fae Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 21 Nov 2018 13:22:03 +0100 Subject: [PATCH 0321/1292] Add rendertype for labels in quickConfigurationSelector CURA-5785 --- .../qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml index d428a05463..ef7a425a87 100644 --- a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml +++ b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml @@ -152,6 +152,7 @@ Cura.ExpandableComponent color: UM.Theme.getColor("text") height: parent.height width: tabControl.textWidth + renderType: Text.NativeRendering } OldControls.CheckBox @@ -174,6 +175,7 @@ Cura.ExpandableComponent color: UM.Theme.getColor("text") height: parent.height width: tabControl.textWidth + renderType: Text.NativeRendering } OldControls.ToolButton @@ -217,6 +219,7 @@ Cura.ExpandableComponent color: UM.Theme.getColor("text") height: parent.height width: tabControl.textWidth + renderType: Text.NativeRendering } OldControls.ToolButton From 406fac9e605578422417cdbb7a666343a4260129 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 21 Nov 2018 13:38:08 +0100 Subject: [PATCH 0322/1292] Remove duplicate entries of renderType. Contributes to CURA-5942. --- resources/qml/MachineSelector.qml | 3 --- 1 file changed, 3 deletions(-) diff --git a/resources/qml/MachineSelector.qml b/resources/qml/MachineSelector.qml index 1796df5678..417c5722b4 100644 --- a/resources/qml/MachineSelector.qml +++ b/resources/qml/MachineSelector.qml @@ -36,7 +36,6 @@ Cura.ExpandableComponent renderType: Text.NativeRendering font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") - renderType: Text.NativeRendering } popupItem: Item @@ -65,7 +64,6 @@ Cura.ExpandableComponent renderType: Text.NativeRendering font: UM.Theme.getFont("medium_bold") color: UM.Theme.getColor("text") - renderType: Text.NativeRendering verticalAlignment: Text.AlignVCenter } @@ -109,7 +107,6 @@ Cura.ExpandableComponent font: UM.Theme.getFont("medium_bold") color: UM.Theme.getColor("text") verticalAlignment: Text.AlignVCenter - renderType: Text.NativeRendering } Repeater From a9672458fd31ffb7c64273b88a779a9f262b19d6 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 21 Nov 2018 13:46:50 +0100 Subject: [PATCH 0323/1292] Update extruderIcon to be more in line with the design CURA-5785 --- resources/qml/ExtruderIcon.qml | 10 ++++++---- .../ConfigurationMenu/QuickConfigurationSelector.qml | 3 +-- resources/themes/cura-light/theme.json | 9 +++++++-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/resources/qml/ExtruderIcon.qml b/resources/qml/ExtruderIcon.qml index 79106bdd3a..1e51835d60 100644 --- a/resources/qml/ExtruderIcon.qml +++ b/resources/qml/ExtruderIcon.qml @@ -9,8 +9,8 @@ Item { id: extruderIconItem - implicitWidth: UM.Theme.getSize("button").width - implicitHeight: implicitWidth + implicitWidth: UM.Theme.getSize("extruder_icon").width + implicitHeight: UM.Theme.getSize("extruder_icon").height property bool checked: true property color materialColor @@ -22,7 +22,7 @@ Item anchors.fill: parent sourceSize.width: parent.width - sourceSize.height: parent.width + sourceSize.height: parent.height source: UM.Theme.getIcon("extruder_button") color: extruderEnabled ? materialColor: "gray" } @@ -49,11 +49,13 @@ Item id: extruderNumberText anchors.centerIn: parent text: index + 1 - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("extruder_icon") width: contentWidth height: contentHeight visible: extruderEnabled renderType: Text.NativeRendering + horizontalAlignment: Text.alignHCenter + verticalAlignment: Text.alignVCenter } UM.RecolorImage diff --git a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml index ef7a425a87..eb6800cb36 100644 --- a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml +++ b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml @@ -50,8 +50,7 @@ Cura.ExpandableComponent id: extruderIcon materialColor: model.color extruderEnabled: model.enabled - height: parent.height - width: height + anchors.verticalCenter: parent.verticalCenter } // Label for the brand of the material diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index d28611529b..b09370ccdb 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -64,6 +64,12 @@ "size": 1.15, "weight": 50, "family": "Noto Sans" + }, + "extruder_icon": + { + "size": 0.7, + "weight": 50, + "family": "Noto Sans" } }, @@ -406,8 +412,7 @@ "thin_margin": [0.71, 0.71], "narrow_margin": [0.5, 0.5], - "extruder_button_material_margin": [0.70, 0.9], - "extruder_button_material": [0.75, 0.75], + "extruder_icon": [1.8, 1.8], "simple_mode_infill_caption": [0.0, 5.0], "simple_mode_infill_height": [0.0, 8.0], From a1f3ebc25b97f555362a1dead86d7cc6081f718a Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 21 Nov 2018 13:58:21 +0100 Subject: [PATCH 0324/1292] Fix typo. Contributes to CURA-5785. --- resources/qml/ExtruderIcon.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/ExtruderIcon.qml b/resources/qml/ExtruderIcon.qml index 1e51835d60..c103ee245c 100644 --- a/resources/qml/ExtruderIcon.qml +++ b/resources/qml/ExtruderIcon.qml @@ -54,8 +54,8 @@ Item height: contentHeight visible: extruderEnabled renderType: Text.NativeRendering - horizontalAlignment: Text.alignHCenter - verticalAlignment: Text.alignVCenter + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter } UM.RecolorImage From eb056ee17bbc7d843a83ce108e95d51bc6f499ba Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 21 Nov 2018 16:06:26 +0100 Subject: [PATCH 0325/1292] Fix display of custom configuration Since it had no width, everything was resized to 0. Contributes to issue CURA-5876. --- resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index 953b6a48f0..aa4cf3624b 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -10,6 +10,8 @@ import UM 1.3 as UM Item { + width: parent.width + Label { id: header From a052b8ec69e014c0ebce92ffb4fcb0067d85831c Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 21 Nov 2018 16:08:29 +0100 Subject: [PATCH 0326/1292] Use Theme.getIcon instead of Theme.icons This is better for performance, according to the deprecation warning I got. Contributes to issue CURA-5876. --- resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index b38384ef8a..111f42483e 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -172,7 +172,7 @@ Cura.ExpandableComponent textColor: UM.Theme.getColor("primary") textHoverColor: UM.Theme.getColor("text") - iconSource: UM.Theme.icons.arrow_right + iconSource: UM.Theme.getIcon("arrow_right") iconOnRightSide: true onClicked: popupItem.configuration_method = "custom" @@ -195,7 +195,7 @@ Cura.ExpandableComponent textColor: UM.Theme.getColor("primary") textHoverColor: UM.Theme.getColor("text") - iconSource: UM.Theme.icons.arrow_left + iconSource: UM.Theme.getIcon("arrow_left") onClicked: popupItem.configuration_method = "auto" } From a826dfb156c46acfbe26533eab594aa27305040d Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 21 Nov 2018 16:12:00 +0100 Subject: [PATCH 0327/1292] Fix binding loop in height of view selection bar Since these were part of the childrenRect of the bar, and attached to the bottom of the bar, the childrenRect depended on the position of the children and that depends on the childrenRect again. So just attach it to the top, it's logical. Contributes to issue CURA-5876. --- resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index 111f42483e..8f31d80810 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -164,7 +164,7 @@ Cura.ExpandableComponent anchors { right: parent.right - bottom: parent.bottom + top: parent.top } color: UM.Theme.getColor("secondary") @@ -187,7 +187,7 @@ Cura.ExpandableComponent anchors { left: parent.left - bottom: parent.bottom + top: parent.top } color: UM.Theme.getColor("secondary") From fe7d1825d4f124788e9fc0ec19db6528fae388c3 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 21 Nov 2018 16:54:57 +0100 Subject: [PATCH 0328/1292] Add styling to the buttons in the printer list. Contributes to CURA-5942. --- plugins/PrepareStage/PrepareMenu.qml | 2 +- resources/qml/MachineSelector.qml | 34 +++++++++++++++---- .../cura-light/images/header_pattern.svg | 1 + resources/themes/cura-light/theme.json | 1 + 4 files changed, 30 insertions(+), 8 deletions(-) create mode 100644 resources/themes/cura-light/images/header_pattern.svg diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index fd296144c7..eed1da0ad8 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -91,7 +91,7 @@ Item radius: UM.Theme.getSize("default_radius").width color: UM.Theme.getColor("toolbar_background") - + Button { id: openFileButton diff --git a/resources/qml/MachineSelector.qml b/resources/qml/MachineSelector.qml index 417c5722b4..a6339e2621 100644 --- a/resources/qml/MachineSelector.qml +++ b/resources/qml/MachineSelector.qml @@ -46,6 +46,7 @@ Cura.ExpandableComponent ScrollView { + id: scroll width: parent.width anchors.top: parent.top anchors.bottom: separator.top @@ -54,16 +55,20 @@ Cura.ExpandableComponent Column { id: column - anchors.fill: parent + + // Can't use parent.width since the parent is the flickable component and not the ScrollView + width: scroll.width - 2 * UM.Theme.getSize("default_lining").width + x: UM.Theme.getSize("default_lining").width Label { text: catalog.i18nc("@label", "Network connected printers") visible: networkedPrintersModel.items.length > 0 + leftPadding: UM.Theme.getSize("default_margin").width height: visible ? contentHeight + 2 * UM.Theme.getSize("default_margin").height : 0 renderType: Text.NativeRendering - font: UM.Theme.getFont("medium_bold") - color: UM.Theme.getColor("text") + font: UM.Theme.getFont("medium") + color: UM.Theme.getColor("text_medium") verticalAlignment: Text.AlignVCenter } @@ -77,13 +82,20 @@ Cura.ExpandableComponent filter: {"type": "machine", "um_network_key": "*", "hidden": "False"} } - delegate: Button + delegate: Cura.ActionButton { text: model.metadata["connect_group_name"] width: parent.width + height: UM.Theme.getSize("action_button").height checked: Cura.MachineManager.activeMachineNetworkGroupName == model.metadata["connect_group_name"] checkable: true + color: "transparent" + hoverColor: UM.Theme.getColor("action_button_hovered") + textColor: UM.Theme.getColor("text") + textHoverColor: UM.Theme.getColor("text") + outlineColor: checked ? UM.Theme.getColor("primary") : "transparent" + onClicked: { togglePopup() @@ -102,10 +114,11 @@ Cura.ExpandableComponent { text: catalog.i18nc("@label", "Preset printers") visible: virtualPrintersModel.items.length > 0 + leftPadding: UM.Theme.getSize("default_margin").width height: visible ? contentHeight + 2 * UM.Theme.getSize("default_margin").height : 0 renderType: Text.NativeRendering - font: UM.Theme.getFont("medium_bold") - color: UM.Theme.getColor("text") + font: UM.Theme.getFont("medium") + color: UM.Theme.getColor("text_medium") verticalAlignment: Text.AlignVCenter } @@ -119,13 +132,20 @@ Cura.ExpandableComponent filter: {"type": "machine", "um_network_key": null} } - delegate: Button + delegate: Cura.ActionButton { text: model.name width: parent.width + height: UM.Theme.getSize("action_button").height checked: Cura.MachineManager.activeMachineId == model.id checkable: true + color: "transparent" + hoverColor: UM.Theme.getColor("action_button_hovered") + textColor: UM.Theme.getColor("text") + textHoverColor: UM.Theme.getColor("text") + outlineColor: checked ? UM.Theme.getColor("primary") : "transparent" + onClicked: { togglePopup() diff --git a/resources/themes/cura-light/images/header_pattern.svg b/resources/themes/cura-light/images/header_pattern.svg new file mode 100644 index 0000000000..2a9de2f3e9 --- /dev/null +++ b/resources/themes/cura-light/images/header_pattern.svg @@ -0,0 +1 @@ +Pattern \ No newline at end of file diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 5f52adff14..4e6fe0776a 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -521,6 +521,7 @@ "avatar_image": [6.8, 6.8], + "action_button": [15.0, 3.0], "action_button_radius": [0.15, 0.15], "monitor_config_override_box": [1.0, 14.0], From f866390c7bb0cc9ac4af65d78a30c6b7995f6201 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 21 Nov 2018 16:56:25 +0100 Subject: [PATCH 0329/1292] Fix an issue in the action panel. When the panel is created while the user is in the preview stage, the row has no width. Contributes to CURA-5786. --- resources/qml/ActionPanel/OutputProcessWidget.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/qml/ActionPanel/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml index f4e014b1ec..3c4386f079 100644 --- a/resources/qml/ActionPanel/OutputProcessWidget.qml +++ b/resources/qml/ActionPanel/OutputProcessWidget.qml @@ -99,6 +99,7 @@ Column { id: buttonRow spacing: UM.Theme.getSize("default_margin").width + width: parent.width Cura.ActionButton { From a9f0402f636b652585c23c5ea7299f0256ba195d Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 22 Nov 2018 09:37:36 +0100 Subject: [PATCH 0330/1292] Made size of viewselector themable CURA-5785 --- plugins/PreviewStage/PreviewMenu.qml | 1 + resources/themes/cura-light/theme.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index 656cf185d5..d660db549b 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -34,6 +34,7 @@ Item id: viewSelector iconSource: expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") height: parent.height + width: UM.Theme.getSize("views_selector").width headerCornerSide: Cura.RoundedRectangle.Direction.Left property var viewModel: UM.ViewModel { } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index b09370ccdb..0df1c8eb31 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -395,7 +395,7 @@ "machine_selector_widget": [16.0, 4.5], - "views_selector": [0.0, 4.0], + "views_selector": [16.0, 4.5], "default_radius": [0.25, 0.25], From 7e3f86f0913b7432c46b20507e33be57b7a1d514 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Thu, 22 Nov 2018 09:37:47 +0100 Subject: [PATCH 0331/1292] Moved some of the mocks to class level because they are used in every test method --- .../tests/TestSendMaterialJob.py | 35 ++++++------------- 1 file changed, 11 insertions(+), 24 deletions(-) diff --git a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py index ff896683e1..548704fd33 100644 --- a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py @@ -17,6 +17,8 @@ from plugins.UM3NetworkPrinting.src.SendMaterialJob import SendMaterialJob lambda _: MimeType(name = "application/x-ultimaker-material-profile", comment = "Ultimaker Material Profile", suffixes = ["xml.fdm_material"])) @patch("UM.Resources.Resources.getAllResourcesOfType", lambda _: ["/materials/generic_pla_white.xml.fdm_material"]) +@patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") +@patch("PyQt5.QtNetwork.QNetworkReply") class TestSendMaterialJob(TestCase): _LOCAL_MATERIAL_WHITE = {"type": "material", "status": "unknown", "id": "generic_pla_white", "base_file": "generic_pla_white", "setting_version": "5", "name": "White PLA", @@ -52,16 +54,13 @@ class TestSendMaterialJob(TestCase): "density": 1.00 } - @patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") - def test_run(self, device_mock): + def test_run(self, device_mock, reply_mock): job = SendMaterialJob(device_mock) job.run() # We expect the materials endpoint to be called when the job runs. device_mock.get.assert_called_with("materials/", on_finished = job._onGetRemoteMaterials) - @patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") - @patch("PyQt5.QtNetwork.QNetworkReply") def test__onGetRemoteMaterials_withFailedRequest(self, reply_mock, device_mock): reply_mock.attribute.return_value = 404 job = SendMaterialJob(device_mock) @@ -71,8 +70,6 @@ class TestSendMaterialJob(TestCase): self.assertEqual([call.attribute(0), call.errorString()], reply_mock.method_calls) self.assertEqual(0, device_mock.createFormPart.call_count) - @patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") - @patch("PyQt5.QtNetwork.QNetworkReply") def test__onGetRemoteMaterials_withBadJsonAnswer(self, reply_mock, device_mock): reply_mock.attribute.return_value = 200 reply_mock.readAll.return_value = QByteArray(b"Six sick hicks nick six slick bricks with picks and sticks.") @@ -84,8 +81,6 @@ class TestSendMaterialJob(TestCase): self.assertEqual([call.attribute(0), call.readAll()], reply_mock.method_calls) self.assertEqual(0, device_mock.createFormPart.call_count) - @patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") - @patch("PyQt5.QtNetwork.QNetworkReply") def test__onGetRemoteMaterials_withMissingGuidInRemoteMaterial(self, reply_mock, device_mock): reply_mock.attribute.return_value = 200 remote_material_without_guid = self._REMOTE_MATERIAL_WHITE.copy() @@ -101,10 +96,8 @@ class TestSendMaterialJob(TestCase): @patch("cura.Settings.CuraContainerRegistry") @patch("cura.CuraApplication") - @patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") - @patch("PyQt5.QtNetwork.QNetworkReply") - def test__onGetRemoteMaterials_withInvalidVersionInLocalMaterial(self, reply_mock, device_mock, application_mock, - container_registry_mock): + def test__onGetRemoteMaterials_withInvalidVersionInLocalMaterial(self, application_mock, container_registry_mock, + reply_mock, device_mock): reply_mock.attribute.return_value = 200 reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTE_MATERIAL_WHITE]).encode("ascii")) @@ -125,10 +118,8 @@ class TestSendMaterialJob(TestCase): @patch("cura.Settings.CuraContainerRegistry") @patch("cura.CuraApplication") - @patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") - @patch("PyQt5.QtNetwork.QNetworkReply") - def test__onGetRemoteMaterials_withNoUpdate(self, reply_mock, device_mock, application_mock, - container_registry_mock): + def test__onGetRemoteMaterials_withNoUpdate(self, application_mock, container_registry_mock, reply_mock, + device_mock): application_mock.getContainerRegistry.return_value = container_registry_mock device_mock.createFormPart.return_value = "_xXx_" @@ -150,10 +141,8 @@ class TestSendMaterialJob(TestCase): @patch("cura.Settings.CuraContainerRegistry") @patch("cura.CuraApplication") - @patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") - @patch("PyQt5.QtNetwork.QNetworkReply") - def test__onGetRemoteMaterials_withUpdatedMaterial(self, reply_mock, device_mock, application_mock, - container_registry_mock): + def test__onGetRemoteMaterials_withUpdatedMaterial(self, application_mock, container_registry_mock, reply_mock, + device_mock): application_mock.getContainerRegistry.return_value = container_registry_mock device_mock.createFormPart.return_value = "_xXx_" @@ -181,10 +170,8 @@ class TestSendMaterialJob(TestCase): @patch("cura.Settings.CuraContainerRegistry") @patch("cura.CuraApplication") - @patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") - @patch("PyQt5.QtNetwork.QNetworkReply") - def test__onGetRemoteMaterials_withNewMaterial(self, reply_mock, device_mock, application_mock, - container_registry_mock): + def test__onGetRemoteMaterials_withNewMaterial(self, application_mock, container_registry_mock, reply_mock, + device_mock): application_mock.getContainerRegistry.return_value = container_registry_mock device_mock.createFormPart.return_value = "_xXx_" From 352427e4601204851daba848599153ebab3f8c41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Thu, 22 Nov 2018 10:01:15 +0100 Subject: [PATCH 0332/1292] Moved exception handling closer to the cause of error --- plugins/UM3NetworkPrinting/src/SendMaterialJob.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py index ee8dd8042d..72269040e7 100644 --- a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py @@ -46,9 +46,8 @@ class SendMaterialJob(Job): # Collect materials from the printer's reply and send the missing ones if needed. try: remote_materials_by_guid = self._parseReply(reply) - self._sendMissingMaterials(remote_materials_by_guid) - except json.JSONDecodeError: - Logger.logException("w", "Error parsing materials from printer") + if remote_materials_by_guid: + self._sendMissingMaterials(remote_materials_by_guid) except TypeError: Logger.logException("w", "Error parsing materials from printer") @@ -153,12 +152,14 @@ class SendMaterialJob(Job): # Parses the reply to a "/materials" request to the printer # # \return a dictionary of ClusterMaterial objects by GUID - # \throw json.JSONDecodeError Raised when the reply does not contain a valid json string # \throw KeyError Raised when on of the materials does not include a valid guid @classmethod def _parseReply(cls, reply: QNetworkReply) -> Dict[str, ClusterMaterial]: - remote_materials = json.loads(reply.readAll().data().decode("utf-8")) - return {material["guid"]: ClusterMaterial(**material) for material in remote_materials} + try: + remote_materials = json.loads(reply.readAll().data().decode("utf-8")) + return {material["guid"]: ClusterMaterial(**material) for material in remote_materials} + except json.JSONDecodeError: + Logger.logException("w", "Error parsing materials from printer") ## Retrieves a list of local materials # From b890e40e81f62da2eade839ad48d7168cdcde7ff Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 22 Nov 2018 10:54:25 +0100 Subject: [PATCH 0333/1292] Close the popup panel when the user clicks in some of the buttons in the printer selector. Contributes to CURA-5942. --- resources/qml/ExtruderIcon.qml | 1 + resources/qml/MachineSelector.qml | 12 ++++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/resources/qml/ExtruderIcon.qml b/resources/qml/ExtruderIcon.qml index c103ee245c..8f312adb85 100644 --- a/resources/qml/ExtruderIcon.qml +++ b/resources/qml/ExtruderIcon.qml @@ -16,6 +16,7 @@ Item property color materialColor property alias textColor: extruderNumberText.color property bool extruderEnabled: true + UM.RecolorImage { id: mainIcon diff --git a/resources/qml/MachineSelector.qml b/resources/qml/MachineSelector.qml index a6339e2621..14e1ebb48e 100644 --- a/resources/qml/MachineSelector.qml +++ b/resources/qml/MachineSelector.qml @@ -184,7 +184,11 @@ Cura.ExpandableComponent hoverColor: UM.Theme.getColor("secondary") textColor: UM.Theme.getColor("primary") textHoverColor: UM.Theme.getColor("text") - onClicked: Cura.Actions.addMachine.trigger() + onClicked: + { + togglePopup() + Cura.Actions.addMachine.trigger() + } } Cura.ActionButton @@ -196,7 +200,11 @@ Cura.ExpandableComponent hoverColor: UM.Theme.getColor("secondary") textColor: UM.Theme.getColor("primary") textHoverColor: UM.Theme.getColor("text") - onClicked: Cura.Actions.configureMachines.trigger() + onClicked: + { + togglePopup() + Cura.Actions.configureMachines.trigger() + } } } } From d4e4e507411dbc6e63c26737c0ae6931847ceba3 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 22 Nov 2018 10:55:53 +0100 Subject: [PATCH 0334/1292] Fix typo --- resources/definitions/fdmextruder.def.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/definitions/fdmextruder.def.json b/resources/definitions/fdmextruder.def.json index cb49b1e128..0af1e68075 100644 --- a/resources/definitions/fdmextruder.def.json +++ b/resources/definitions/fdmextruder.def.json @@ -189,7 +189,7 @@ "settable_per_mesh": false, "settable_per_extruder": true, "settable_per_meshgroup": false, - "setttable_globally": false + "settable_globally": false } } }, From bf8a04fa4049b4a7bf99c4903b437109ec415b73 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 22 Nov 2018 11:08:46 +0100 Subject: [PATCH 0335/1292] Fix some minor display issues for simulation view CURA-5785 --- plugins/SimulationView/SimulationViewMenuComponent.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/SimulationView/SimulationViewMenuComponent.qml b/plugins/SimulationView/SimulationViewMenuComponent.qml index 110cd1c109..53b64afb47 100644 --- a/plugins/SimulationView/SimulationViewMenuComponent.qml +++ b/plugins/SimulationView/SimulationViewMenuComponent.qml @@ -40,7 +40,6 @@ Cura.ExpandableComponent id: layerViewTypesLabel text: catalog.i18nc("@label", "Color scheme") font: UM.Theme.getFont("default") - visible: !UM.SimulationView.compatibilityMode color: UM.Theme.getColor("setting_control_text") height: base.height verticalAlignment: Text.AlignVCenter @@ -273,6 +272,7 @@ Cura.ExpandableComponent text: catalog.i18nc("@label", "Only Show Top Layers") visible: UM.SimulationView.compatibilityMode style: UM.Theme.styles.checkbox + width: parent.width } CheckBox @@ -280,6 +280,7 @@ Cura.ExpandableComponent checked: viewSettings.top_layer_count == 5 onClicked: UM.Preferences.setValue("view/top_layer_count", checked ? 5 : 1) text: catalog.i18nc("@label", "Show 5 Detailed Layers On Top") + width: parent.width visible: UM.SimulationView.compatibilityMode style: UM.Theme.styles.checkbox } From ba7863c9d9640ce30f01cf47fff8d1ec9564d06f Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Thu, 22 Nov 2018 11:09:35 +0100 Subject: [PATCH 0336/1292] Fix type error for hovering manage queue link Contributes to CL-1148 --- .../resources/qml/ClusterMonitorItem.qml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml b/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml index d055071521..328f82dec5 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml @@ -91,6 +91,7 @@ Component } Label { + id: manageQueueText anchors { left: externalLinkIcon.right @@ -110,8 +111,14 @@ Component anchors.fill: manageQueueLabel hoverEnabled: true onClicked: Cura.MachineManager.printerOutputDevices[0].openPrintJobControlPanel() - onEntered: manageQueueLabel.font.underline = true - onExited: manageQueueLabel.font.underline = false + onEntered: + { + manageQueueText.font.underline = true + } + onExited: + { + manageQueueText.font.underline = false + } } Row From 088b2f6f2808d3aca074e68e47e05d0d0b46808c Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Thu, 22 Nov 2018 11:36:32 +0100 Subject: [PATCH 0337/1292] Added an extra import module, did not pass coding style test CURA-5936 --- plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py b/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py index 478f955e49..ff5c33517d 100644 --- a/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py +++ b/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py @@ -6,6 +6,7 @@ import io #To write config files to strings as if they were files. import os.path #To get the path to write new user profiles to. from typing import Dict, List, Optional, Set, Tuple import urllib #To serialise the user container file name properly. +import urllib.parse import UM.VersionUpgrade #To indicate that a file is of incorrect format. import UM.VersionUpgradeManager #To schedule more files to be upgraded. From 3c3343a4073f7cf574ee3aa45eaeb17a0d25f166 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Thu, 22 Nov 2018 13:11:59 +0100 Subject: [PATCH 0338/1292] Use bool for expanded or collapsed state Contributes to CL-1148 --- plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml b/plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml index 4922aea853..0877a15f00 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml @@ -14,7 +14,7 @@ Item { id: base - property var expanded: false + property bool expanded: false property var borderWidth: 1 property color borderColor: "#EAEAEC" property color headerBackgroundColor: "white" From 1de21c1d94a5be627c125694118edf39ea5a2f9b Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Thu, 22 Nov 2018 13:13:06 +0100 Subject: [PATCH 0339/1292] Remove unnecessary "else" Contributes to CL-1148 --- .../UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml index ada6f8a644..913e684827 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml @@ -91,10 +91,7 @@ Item } return catalog.i18nc("@label", "First available") } - else - { - return printJob.assignedPrinter.name - } + return printJob.assignedPrinter.name } return "" } From a1613c7f816c0d9c10659972f32bbed3a1995ea1 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 22 Nov 2018 13:53:27 +0100 Subject: [PATCH 0340/1292] Set the variable types of the Action button to the right kind. Because of boyscouting; these must be colors (and not generic vars) --- resources/qml/ActionButton.qml | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index 2a8b894867..69d65e1c3f 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -15,15 +15,17 @@ Button property alias textFont: buttonText.font property alias cornerRadius: backgroundRect.radius property alias tooltip: tooltip.text - property var color: UM.Theme.getColor("primary") - property var hoverColor: UM.Theme.getColor("primary_hover") - property var disabledColor: color - property var textColor: UM.Theme.getColor("button_text") - property var textHoverColor: UM.Theme.getColor("button_text_hover") - property var textDisabledColor: textColor - property var outlineColor: color - property var outlineHoverColor: hoverColor - property var outlineDisabledColor: outlineColor + + property color color: UM.Theme.getColor("primary") + property color hoverColor: UM.Theme.getColor("primary_hover") + property color disabledColor: color + property color textColor: UM.Theme.getColor("button_text") + property color textHoverColor: UM.Theme.getColor("button_text_hover") + property color textDisabledColor: textColor + property color outlineColor: color + property color outlineHoverColor: hoverColor + property color outlineDisabledColor: outlineColor + // This property is used to indicate whether the button has a fixed width or the width would depend on the contents // Be careful when using fixedWidthMode, the translated texts can be too long that they won't fit. In any case, // we elide the text to the right so the text will be cut off with the three dots at the end. @@ -80,6 +82,7 @@ Button { id: mouseArea anchors.fill: parent + // Ensure that the button will still accept the clicks on it's own. onPressed: mouse.accepted = false hoverEnabled: true } From 9720512f50d87de2b6149f1d2475704309f3c07d Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 22 Nov 2018 13:54:10 +0100 Subject: [PATCH 0341/1292] Add a new printer selector button that is connected to the output devices and shows labels containing the type of printers that are in the same group. Contributes to CURA-5942. --- cura/PrinterOutputDevice.py | 5 + .../ConfigurationListView.qml | 2 +- .../{ => PrinterSelector}/MachineSelector.qml | 38 +----- .../PrinterSelector/MachineSelectorButton.qml | 110 ++++++++++++++++++ resources/qml/qmldir | 3 +- 5 files changed, 121 insertions(+), 37 deletions(-) rename resources/qml/{ => PrinterSelector}/MachineSelector.qml (79%) create mode 100644 resources/qml/PrinterSelector/MachineSelectorButton.qml diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index 969aa3c460..f8a663f0e4 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -211,6 +211,11 @@ class PrinterOutputDevice(QObject, OutputDevice): self._unique_configurations.sort(key = lambda k: k.printerType) self.uniqueConfigurationsChanged.emit() + # Returns the unique configurations of the printers within this output device + @pyqtProperty("QVariantList", notify = uniqueConfigurationsChanged) + def uniquePrinterTypes(self) -> List[str]: + return list(set([configuration.printerType for configuration in self._unique_configurations])) + def _onPrintersChanged(self) -> None: for printer in self._printers: printer.configurationChanged.connect(self._updateUniqueConfigurations) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index 7aaf87b4df..210ff6057f 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -21,7 +21,7 @@ Column { // FIXME For now the model should be removed and then created again, otherwise changes in the printer don't automatically update the UI configurationList.model = [] - if(outputDevice) + if (outputDevice) { configurationList.model = outputDevice.uniqueConfigurations } diff --git a/resources/qml/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml similarity index 79% rename from resources/qml/MachineSelector.qml rename to resources/qml/PrinterSelector/MachineSelector.qml index 14e1ebb48e..9280c45cf4 100644 --- a/resources/qml/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -8,8 +8,6 @@ import QtQuick.Layouts 1.1 import UM 1.2 as UM import Cura 1.0 as Cura -import "Menus" - Cura.ExpandableComponent { @@ -18,7 +16,7 @@ Cura.ExpandableComponent property bool isNetworkPrinter: Cura.MachineManager.activeMachineNetworkKey != "" popupPadding: 0 - popupAlignment: ExpandableComponent.PopupAlignment.AlignLeft + popupAlignment: Cura.ExpandableComponent.PopupAlignment.AlignLeft iconSource: expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") UM.I18nCatalog @@ -82,25 +80,10 @@ Cura.ExpandableComponent filter: {"type": "machine", "um_network_key": "*", "hidden": "False"} } - delegate: Cura.ActionButton + delegate: MachineSelectorButton { text: model.metadata["connect_group_name"] - width: parent.width - height: UM.Theme.getSize("action_button").height checked: Cura.MachineManager.activeMachineNetworkGroupName == model.metadata["connect_group_name"] - checkable: true - - color: "transparent" - hoverColor: UM.Theme.getColor("action_button_hovered") - textColor: UM.Theme.getColor("text") - textHoverColor: UM.Theme.getColor("text") - outlineColor: checked ? UM.Theme.getColor("primary") : "transparent" - - onClicked: - { - togglePopup() - Cura.MachineManager.setActiveMachine(model.id) - } Connections { @@ -132,25 +115,10 @@ Cura.ExpandableComponent filter: {"type": "machine", "um_network_key": null} } - delegate: Cura.ActionButton + delegate: MachineSelectorButton { text: model.name - width: parent.width - height: UM.Theme.getSize("action_button").height checked: Cura.MachineManager.activeMachineId == model.id - checkable: true - - color: "transparent" - hoverColor: UM.Theme.getColor("action_button_hovered") - textColor: UM.Theme.getColor("text") - textHoverColor: UM.Theme.getColor("text") - outlineColor: checked ? UM.Theme.getColor("primary") : "transparent" - - onClicked: - { - togglePopup() - Cura.MachineManager.setActiveMachine(model.id) - } } } } diff --git a/resources/qml/PrinterSelector/MachineSelectorButton.qml b/resources/qml/PrinterSelector/MachineSelectorButton.qml new file mode 100644 index 0000000000..5ba229c31c --- /dev/null +++ b/resources/qml/PrinterSelector/MachineSelectorButton.qml @@ -0,0 +1,110 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.1 +import QtQuick.Layouts 1.3 + +import UM 1.1 as UM +import Cura 1.0 as Cura + +Button +{ + id: machineSelectorButton + + width: parent.width + height: UM.Theme.getSize("action_button").height + leftPadding: Math.round(1.5 * UM.Theme.getSize("default_margin").width) + checkable: true + + property var outputDevice: Cura.MachineManager.printerOutputDevices[0] + property var printerTypesList: [] + + function setPrinterTypesList() + { + printerTypesList = (checked && (outputDevice != null)) ? outputDevice.uniquePrinterTypes : [] + } + + contentItem: Item + { + width: machineSelectorButton.width - machineSelectorButton.leftPadding + height: UM.Theme.getSize("action_button").height + + Label + { + id: buttonText + anchors + { + left: parent.left + right: printerTypes.left + verticalCenter: parent.verticalCenter + } + text: machineSelectorButton.text + color: UM.Theme.getColor("text") + font: UM.Theme.getFont("action_button") + visible: text != "" + renderType: Text.NativeRendering + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + + Row + { + id: printerTypes + width: childrenRect.width + + anchors + { + right: parent.right + verticalCenter: parent.verticalCenter + } + spacing: UM.Theme.getSize("narrow_margin").width + + Repeater + { + model: printerTypesList + delegate: Label + { + text: modelData + } + } + } + } + + background: Rectangle + { + id: backgroundRect + color: machineSelectorButton.hovered ? UM.Theme.getColor("action_button_hovered") : "transparent" + radius: UM.Theme.getSize("action_button_radius").width + border.width: UM.Theme.getSize("default_lining").width + border.color: machineSelectorButton.checked ? UM.Theme.getColor("primary") : "transparent" + } + + onClicked: + { + togglePopup() + Cura.MachineManager.setActiveMachine(model.id) + } + + MouseArea + { + id: mouseArea + anchors.fill: parent + onPressed: mouse.accepted = false + hoverEnabled: true + } + + Connections + { + target: outputDevice + onUniqueConfigurationsChanged: setPrinterTypesList() + } + + Connections + { + target: Cura.MachineManager + onOutputDevicesChanged: setPrinterTypesList() + } + + Component.onCompleted: setPrinterTypesList() +} diff --git a/resources/qml/qmldir b/resources/qml/qmldir index d5e4106d33..458338c78a 100644 --- a/resources/qml/qmldir +++ b/resources/qml/qmldir @@ -9,4 +9,5 @@ MaterialMenu 1.0 MaterialMenu.qml NozzleMenu 1.0 NozzleMenu.qml ActionPanelWidget 1.0 ActionPanelWidget.qml IconLabel 1.0 IconLabel.qml -OutputDevicesActionButton 1.0 OutputDevicesActionButton.qml \ No newline at end of file +OutputDevicesActionButton 1.0 OutputDevicesActionButton.qml +ExpandableComponent 1.0 ExpandableComponent.qml \ No newline at end of file From da834d6a1fdf4ef7123e737015acdc10b555bece Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Thu, 22 Nov 2018 13:55:22 +0100 Subject: [PATCH 0342/1292] Silence binding loop Contributes to CL-1148 --- .../UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml index 913e684827..0f2ae67442 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml @@ -71,7 +71,7 @@ Item Item { anchors.verticalCenter: parent.verticalCenter - height: childrenRect.height + height: 18 * screenScaleFactor // TODO: This should be childrenRect.height but QML throws warnings width: childrenRect.width Label From 55554c62a9a4d8995ae6358b9d29cb2a4b6861d3 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Thu, 22 Nov 2018 13:55:43 +0100 Subject: [PATCH 0343/1292] Use array for extruder configurations Contributes to CL-1148 --- .../resources/qml/MonitorPrintJobCard.qml | 7 +++- .../qml/MonitorPrinterConfiguration.qml | 38 ++++++++----------- 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml index 0f2ae67442..8231870c21 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml @@ -141,8 +141,11 @@ Item id: printerConfiguration anchors.verticalCenter: parent.verticalCenter buildplate: "Glass" - config0: base.printJob.configuration.extruderConfigurations[0] - config1: base.printJob.configuration.extruderConfigurations[1] + configurations: + [ + base.printJob.configuration.extruderConfigurations[0], + base.printJob.configuration.extruderConfigurations[1] + ] height: 72 * screenScaleFactor // TODO: Theme! } Label { diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterConfiguration.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterConfiguration.qml index a31c8bbd99..6aa11528de 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterConfiguration.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterConfiguration.qml @@ -18,11 +18,8 @@ Item // Extracted buildplate configuration property alias buildplate: buildplateConfig.buildplate - // Extracted extruder configuration for position 0 - property var config0: null - - // Extracted extruder configuration for position 1 - property var config1: null + // Array of extracted extruder configurations + property var configurations: null // Default size, but should be stretched to fill parent height: 72 * parent.height @@ -30,30 +27,25 @@ Item Row { + id: extruderConfigurationRow spacing: 18 * screenScaleFactor // TODO: Theme! - MonitorExtruderConfiguration + Repeater { - color: config0 && config0.activeMaterial ? config0.activeMaterial.color : "#eeeeee" // TODO: Theme! - material: config0 && config0.activeMaterial ? config0.activeMaterial.name : "" - position: config0.position - printCore: config0 ? config0.hotendID : "" - visible: config0 + id: extruderConfigurationRepeater + model: configurations - // Keep things responsive! - width: Math.floor((base.width - parent.spacing) / 2) - } + MonitorExtruderConfiguration + { + color: modelData.activeMaterial ? modelData.activeMaterial.color : "#eeeeee" // TODO: Theme! + material: modelData.activeMaterial ? modelData.activeMaterial.name : "" + position: modelData.position + printCore: modelData.hotendID - MonitorExtruderConfiguration - { - color: config1 && config1.activeMaterial ? config1.activeMaterial.color : "#eeeeee" // TODO: Theme! - material: config1 && config1.activeMaterial ? config1.activeMaterial.name : "" - position: config1.position - printCore: config1 ? config1.hotendID : "" - visible: config1 + // Keep things responsive! + width: Math.floor((base.width - (configurations.length - 1) * extruderConfigurationRow.spacing) / configurations.length) + } - // Keep things responsive! - width: Math.floor((base.width - parent.spacing) / 2) } } From 963b8aa97487bc839ec051473eb79f1839767316 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Thu, 22 Nov 2018 13:56:01 +0100 Subject: [PATCH 0344/1292] Fix QML warnings Contributes to CL-1148 --- .../UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml b/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml index 328f82dec5..19a152e6eb 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml @@ -17,7 +17,7 @@ Component property var emphasisColor: UM.Theme.getColor("setting_control_border_highlight") property var cornerRadius: UM.Theme.getSize("monitor_corner_radius").width - color: transparent + color: "transparent" height: maximumHeight onVisibleChanged: { @@ -83,7 +83,7 @@ Component UM.RecolorImage { id: externalLinkIcon - anchors.verticalCenter: externalLinkIcon.verticalCenter + anchors.verticalCenter: manageQueueLabel.verticalCenter color: UM.Theme.getColor("primary") source: "../svg/icons/external_link.svg" width: 16 * screenScaleFactor // TODO: Theme! (Y U NO USE 18 LIKE ALL OTHER ICONS?!) From 698409803d6c3717dea8312741e0f188aee9a7b5 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 22 Nov 2018 09:07:22 +0100 Subject: [PATCH 0345/1292] Fix null warning in QML CURA-5943 --- .../qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml index 97b5bee745..73fc342d66 100644 --- a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml @@ -70,7 +70,7 @@ Column Label { id: materialLabel - text: printCoreConfiguration.material.name + text: printCoreConfiguration.material == null ? "" : printCoreConfiguration.material.name renderType: Text.NativeRendering elide: Text.ElideRight width: parent.width From 45d4f2ad3d4ba05d42757a4b0aef7433b22589b7 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 22 Nov 2018 13:48:50 +0100 Subject: [PATCH 0346/1292] Update MonitorSection CURA-5943 --- resources/qml/PrinterOutput/MonitorSection.qml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/resources/qml/PrinterOutput/MonitorSection.qml b/resources/qml/PrinterOutput/MonitorSection.qml index 6ed762362d..7ef89dabf7 100644 --- a/resources/qml/PrinterOutput/MonitorSection.qml +++ b/resources/qml/PrinterOutput/MonitorSection.qml @@ -1,10 +1,10 @@ // Copyright (c) 2017 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.2 -import QtQuick.Controls 1.1 -import QtQuick.Controls.Styles 1.1 -import QtQuick.Layouts 1.1 +import QtQuick 2.10 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import QtQuick.Layouts 1.3 import UM 1.2 as UM import Cura 1.0 as Cura @@ -13,7 +13,8 @@ Item { id: base property string label - height: childrenRect.height; + height: childrenRect.height + Rectangle { color: UM.Theme.getColor("setting_category") @@ -30,4 +31,4 @@ Item color: UM.Theme.getColor("setting_category_text") } } -} \ No newline at end of file +} From cf0994037c962a35adbf26ace560fc0e749e239d Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 22 Nov 2018 13:56:03 +0100 Subject: [PATCH 0347/1292] Move MonitorButtonSytle to a separate QML file CURA-5943 --- .../PrinterOutput/ManualPrinterControl.qml | 84 ++---------------- .../qml/PrinterOutput/MonitorButtonStyle.qml | 88 +++++++++++++++++++ 2 files changed, 93 insertions(+), 79 deletions(-) create mode 100644 resources/qml/PrinterOutput/MonitorButtonStyle.qml diff --git a/resources/qml/PrinterOutput/ManualPrinterControl.qml b/resources/qml/PrinterOutput/ManualPrinterControl.qml index 70961a2eb2..3219dc5792 100644 --- a/resources/qml/PrinterOutput/ManualPrinterControl.qml +++ b/resources/qml/PrinterOutput/ManualPrinterControl.qml @@ -9,6 +9,9 @@ import QtQuick.Layouts 1.1 import UM 1.2 as UM import Cura 1.0 as Cura +import "." + + Item { property var printerModel @@ -16,86 +19,9 @@ Item implicitWidth: parent.width implicitHeight: childrenRect.height - Component + MonitorButtonStyle { id: monitorButtonStyle - - ButtonStyle - { - background: Rectangle - { - border.width: UM.Theme.getSize("default_lining").width - border.color: - { - if(!control.enabled) - { - return UM.Theme.getColor("action_button_disabled_border"); - } - else if(control.pressed) - { - return UM.Theme.getColor("action_button_active_border"); - } - else if(control.hovered) - { - return UM.Theme.getColor("action_button_hovered_border"); - } - return UM.Theme.getColor("action_button_border"); - } - color: - { - if(!control.enabled) - { - return UM.Theme.getColor("action_button_disabled"); - } - else if(control.pressed) - { - return UM.Theme.getColor("action_button_active"); - } - else if(control.hovered) - { - return UM.Theme.getColor("action_button_hovered"); - } - return UM.Theme.getColor("action_button"); - } - Behavior on color - { - ColorAnimation - { - duration: 50 - } - } - } - - label: Item - { - UM.RecolorImage - { - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.horizontalCenter - width: Math.floor(control.width / 2) - height: Math.floor(control.height / 2) - sourceSize.width: width - sourceSize.height: width - color: - { - if(!control.enabled) - { - return UM.Theme.getColor("action_button_disabled_text"); - } - else if(control.pressed) - { - return UM.Theme.getColor("action_button_active_text"); - } - else if(control.hovered) - { - return UM.Theme.getColor("action_button_hovered_text"); - } - return UM.Theme.getColor("action_button_text"); - } - source: control.iconSource - } - } - } } Column @@ -551,4 +477,4 @@ Item } ExclusiveGroup { id: distanceGroup } } -} \ No newline at end of file +} diff --git a/resources/qml/PrinterOutput/MonitorButtonStyle.qml b/resources/qml/PrinterOutput/MonitorButtonStyle.qml new file mode 100644 index 0000000000..7bb1b91e55 --- /dev/null +++ b/resources/qml/PrinterOutput/MonitorButtonStyle.qml @@ -0,0 +1,88 @@ +import QtQuick 2.10 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import QtQuick.Layouts 1.3 + +import UM 1.2 as UM +import Cura 1.0 as Cura + + +Component +{ + ButtonStyle + { + background: Rectangle + { + border.width: UM.Theme.getSize("default_lining").width + border.color: + { + if(!control.enabled) + { + return UM.Theme.getColor("action_button_disabled_border"); + } + else if(control.pressed) + { + return UM.Theme.getColor("action_button_active_border"); + } + else if(control.hovered) + { + return UM.Theme.getColor("action_button_hovered_border"); + } + return UM.Theme.getColor("action_button_border"); + } + color: + { + if(!control.enabled) + { + return UM.Theme.getColor("action_button_disabled"); + } + else if(control.pressed) + { + return UM.Theme.getColor("action_button_active"); + } + else if(control.hovered) + { + return UM.Theme.getColor("action_button_hovered"); + } + return UM.Theme.getColor("action_button"); + } + Behavior on color + { + ColorAnimation + { + duration: 50 + } + } + } + + label: Item + { + UM.RecolorImage + { + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + width: Math.floor(control.width / 2) + height: Math.floor(control.height / 2) + sourceSize.width: width + sourceSize.height: width + color: + { + if(!control.enabled) + { + return UM.Theme.getColor("action_button_disabled_text"); + } + else if(control.pressed) + { + return UM.Theme.getColor("action_button_active_text"); + } + else if(control.hovered) + { + return UM.Theme.getColor("action_button_hovered_text"); + } + return UM.Theme.getColor("action_button_text"); + } + source: control.iconSource + } + } + } +} From 5a1691839169ba0ee3f4ca6be15514d5714f062a Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 22 Nov 2018 13:58:18 +0100 Subject: [PATCH 0348/1292] Update ManualPrinterControl CURA-5943 --- .../qml/PrinterOutput/ManualPrinterControl.qml | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/resources/qml/PrinterOutput/ManualPrinterControl.qml b/resources/qml/PrinterOutput/ManualPrinterControl.qml index 3219dc5792..1a719c379e 100644 --- a/resources/qml/PrinterOutput/ManualPrinterControl.qml +++ b/resources/qml/PrinterOutput/ManualPrinterControl.qml @@ -1,12 +1,12 @@ // Copyright (c) 2017 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.2 -import QtQuick.Controls 1.1 -import QtQuick.Controls.Styles 1.1 -import QtQuick.Layouts 1.1 +import QtQuick 2.10 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import QtQuick.Layouts 1.3 -import UM 1.2 as UM +import UM 1.3 as UM import Cura 1.0 as Cura import "." @@ -14,8 +14,10 @@ import "." Item { - property var printerModel + property var printerModel: null property var activePrintJob: printerModel != null ? printerModel.activePrintJob : null + property var connectedPrinter: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null + implicitWidth: parent.width implicitHeight: childrenRect.height @@ -388,7 +390,7 @@ Item if (printerModel == null) { return false // Can't send custom commands if not connected. } - if (!connectedPrinter.acceptsCommands) { + if (connectedPrinter == null || !connectedPrinter.acceptsCommands) { return false // Not allowed to do anything } if (connectedPrinter.jobState == "printing" || connectedPrinter.jobState == "pre_print" || connectedPrinter.jobState == "resuming" || connectedPrinter.jobState == "pausing" || connectedPrinter.jobState == "paused" || connectedPrinter.jobState == "error" || connectedPrinter.jobState == "offline") { From e65f2d66a631d43dfa0c3da716ac332db7767a9f Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 22 Nov 2018 14:02:17 +0100 Subject: [PATCH 0349/1292] Add connectedPrinter to MonitorItem CURA-5943 --- resources/qml/PrinterOutput/MonitorItem.qml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/resources/qml/PrinterOutput/MonitorItem.qml b/resources/qml/PrinterOutput/MonitorItem.qml index cad8d2f7f3..a26ec20f64 100644 --- a/resources/qml/PrinterOutput/MonitorItem.qml +++ b/resources/qml/PrinterOutput/MonitorItem.qml @@ -15,6 +15,8 @@ Item property string value: "" height: childrenRect.height; + property var connectedPrinter: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null + Row { height: UM.Theme.getSize("setting_control").height From 75661d9bba0079df9dfe3288c38282ca8e857c35 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 22 Nov 2018 14:04:08 +0100 Subject: [PATCH 0350/1292] Fix MonitorSidebar due to widget renaming CURA-5943 --- resources/qml/MonitorSidebar.qml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/resources/qml/MonitorSidebar.qml b/resources/qml/MonitorSidebar.qml index 2282034739..50416e34ab 100644 --- a/resources/qml/MonitorSidebar.qml +++ b/resources/qml/MonitorSidebar.qml @@ -1,15 +1,17 @@ // Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.7 +import QtQuick 2.10 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.3 import UM 1.2 as UM import Cura 1.0 as Cura + import "Menus" import "Menus/ConfigurationMenu" + Rectangle { id: base @@ -85,7 +87,7 @@ Rectangle } } - MachineSelection + MachineSelector { id: machineSelection width: base.width - configSelection.width - separator.width @@ -104,7 +106,7 @@ Rectangle anchors.left: machineSelection.right } - ConfigurationSelection + CustomConfigurationSelector { id: configSelection visible: isNetworkPrinter && printerConnected @@ -112,7 +114,6 @@ Rectangle height: UM.Theme.getSize("stage_menu").height anchors.top: base.top anchors.right: parent.right - panelWidth: base.width } Loader From 8eb0f66df384a50f5f9afb12d8747737c20c4deb Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 22 Nov 2018 14:05:23 +0100 Subject: [PATCH 0351/1292] Add connectedPrinter to ExtruderBox CURA-5943 --- resources/qml/PrinterOutput/ExtruderBox.qml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/resources/qml/PrinterOutput/ExtruderBox.qml b/resources/qml/PrinterOutput/ExtruderBox.qml index 510a44f9da..f5a1bd75c4 100644 --- a/resources/qml/PrinterOutput/ExtruderBox.qml +++ b/resources/qml/PrinterOutput/ExtruderBox.qml @@ -12,6 +12,8 @@ Item property alias color: background.color property var extruderModel property var position: index + property var connectedPrinter: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null + implicitWidth: parent.width implicitHeight: UM.Theme.getSize("print_setup_extruder_box").height From d8c3078d78fc176fc764ee54bd12264850076b3e Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 22 Nov 2018 14:10:04 +0100 Subject: [PATCH 0352/1292] Add connectedPrinter to HeatedBedBox CURA-5943 --- resources/qml/PrinterOutput/HeatedBedBox.qml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/resources/qml/PrinterOutput/HeatedBedBox.qml b/resources/qml/PrinterOutput/HeatedBedBox.qml index 962ffa9b01..8c99814e02 100644 --- a/resources/qml/PrinterOutput/HeatedBedBox.qml +++ b/resources/qml/PrinterOutput/HeatedBedBox.qml @@ -1,10 +1,10 @@ // Copyright (c) 2017 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.2 -import QtQuick.Controls 1.1 -import QtQuick.Controls.Styles 1.1 -import QtQuick.Layouts 1.1 +import QtQuick 2.10 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import QtQuick.Layouts 1.3 import UM 1.2 as UM import Cura 1.0 as Cura @@ -14,6 +14,7 @@ Item implicitWidth: parent.width height: visible ? UM.Theme.getSize("print_setup_extruder_box").height : 0 property var printerModel + property var connectedPrinter: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null Rectangle { @@ -114,7 +115,7 @@ Item { return false; //Can't preheat if not connected. } - if (!connectedPrinter.acceptsCommands) + if (connectedPrinter == null || !connectedPrinter.acceptsCommands) { return false; //Not allowed to do anything. } From 0211122b1209d55db109cb00d8a442d30b4c970b Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 22 Nov 2018 14:46:13 +0100 Subject: [PATCH 0353/1292] Add a proper component with a label and a rectangle in the background that shows the type of printer. Contributes to CURA-5942. --- .../qml/PrinterSelector/MachineSelector.qml | 1 + .../PrinterSelector/MachineSelectorButton.qml | 24 ++++++++++++++++--- resources/qml/ViewOrientationControls.qml | 2 +- resources/themes/cura-light/theme.json | 5 +++- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index 9280c45cf4..66ed4d4a2c 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -84,6 +84,7 @@ Cura.ExpandableComponent { text: model.metadata["connect_group_name"] checked: Cura.MachineManager.activeMachineNetworkGroupName == model.metadata["connect_group_name"] + outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null Connections { diff --git a/resources/qml/PrinterSelector/MachineSelectorButton.qml b/resources/qml/PrinterSelector/MachineSelectorButton.qml index 5ba229c31c..44b162d00d 100644 --- a/resources/qml/PrinterSelector/MachineSelectorButton.qml +++ b/resources/qml/PrinterSelector/MachineSelectorButton.qml @@ -17,7 +17,7 @@ Button leftPadding: Math.round(1.5 * UM.Theme.getSize("default_margin").width) checkable: true - property var outputDevice: Cura.MachineManager.printerOutputDevices[0] + property var outputDevice: null property var printerTypesList: [] function setPrinterTypesList() @@ -63,9 +63,27 @@ Button Repeater { model: printerTypesList - delegate: Label + delegate: Item { - text: modelData + width: UM.Theme.getSize("printer_type_label").width + height: UM.Theme.getSize("printer_type_label").height + + Rectangle + { + anchors.fill: parent + color: UM.Theme.getColor("printer_type_label_background") + } + + Label + { + id: printerTypeLabel + text: modelData + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + renderType: Text.NativeRendering + font: UM.Theme.getFont("very_small") + color: UM.Theme.getColor("text") + } } } } diff --git a/resources/qml/ViewOrientationControls.qml b/resources/qml/ViewOrientationControls.qml index acf75b1b48..fa5a51181d 100644 --- a/resources/qml/ViewOrientationControls.qml +++ b/resources/qml/ViewOrientationControls.qml @@ -21,7 +21,7 @@ Row { iconSource: UM.Theme.getIcon("view_3d") style: UM.Theme.styles.small_tool_button - onClicked:UM.Controller.rotateView("3d", 0) + onClicked: UM.Controller.rotateView("3d", 0) } // #2 Front view diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 2f86829f11..94a89342e7 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -81,7 +81,6 @@ "lining": [192, 193, 194, 255], "viewport_overlay": [0, 0, 0, 192], - "primary": [50, 130, 255, 255], "primary_hover": [48, 182, 231, 255], "primary_text": [255, 255, 255, 255], @@ -114,6 +113,8 @@ "toolbar_background": [255, 255, 255, 255], + "printer_type_label_background": [171, 171, 191, 255], + "text": [0, 0, 0, 255], "text_detail": [174, 174, 174, 128], "text_link": [50, 130, 255, 255], @@ -398,6 +399,8 @@ "views_selector": [0.0, 4.0], + "printer_type_label": [3.5, 1.5], + "default_radius": [0.25, 0.25], "wide_lining": [0.5, 0.5], From 7f11142d5086b40164b490d90617a31bf41f63d8 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 22 Nov 2018 14:57:55 +0100 Subject: [PATCH 0354/1292] Fix height and vertical layout of popup Many things were made simpler. This took some time to fix... Contributes to issue CURA-5876. --- .../ConfigurationMenu/AutoConfiguration.qml | 4 ++ .../ConfigurationMenu/ConfigurationMenu.qml | 49 ++++++++----------- .../ConfigurationMenu/CustomConfiguration.qml | 6 ++- 3 files changed, 29 insertions(+), 30 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml index e1f0ed480e..cde18ab488 100644 --- a/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml @@ -8,12 +8,16 @@ import UM 1.3 as UM Item { + width: parent.width + height: visible ? childrenRect.height : 0 + Label { id: header text: catalog.i18nc("@header", "Configurations") font: UM.Theme.getFont("large") color: UM.Theme.getColor("text") + height: contentHeight anchors { diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index 8f31d80810..4aa8d66caa 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -96,32 +96,36 @@ Cura.ExpandableComponent } } - popupItem: Item + popupItem: Column { id: popupItem width: base.width - 2 * UM.Theme.getSize("default_margin").width - height: 200 + height: implicitHeight //Required because ExpandableComponent will try to use this to determine the size of the background of the pop-up. + spacing: UM.Theme.getSize("default_margin").height property var is_connected: false //If current machine is connected to a printer. Only evaluated upon making popup visible. onVisibleChanged: { - is_connected = Cura.MachineManager.activeMachineNetworkKey != "" && Cura.MachineManager.printerConnected //Re-evaluate. + is_connected = Cura.MachineManager.activeMachineNetworkKey !== "" && Cura.MachineManager.printerConnected //Re-evaluate. } - property var configuration_method: buttonBar.visible ? "auto" : "custom" //Auto if connected to a printer at start-up, or Custom if not. + property var configuration_method: is_connected ? "auto" : "custom" //Auto if connected to a printer at start-up, or Custom if not. - AutoConfiguration + Item { - id: autoConfiguration - visible: popupItem.configuration_method === "auto" - anchors.top: parent.top - } + width: parent.width + height: childrenRect.height + AutoConfiguration + { + id: autoConfiguration + visible: popupItem.configuration_method === "auto" + } - CustomConfiguration - { - id: customConfiguration - visible: popupItem.configuration_method === "custom" - anchors.top: parent.top + CustomConfiguration + { + id: customConfiguration + visible: popupItem.configuration_method === "custom" + } } Rectangle @@ -129,30 +133,19 @@ Cura.ExpandableComponent id: separator visible: buttonBar.visible - anchors - { - left: parent.left - right: parent.right - bottom: buttonBar.top - bottomMargin: UM.Theme.getSize("default_margin").height - } + width: parent.width height: UM.Theme.getSize("default_lining").height color: UM.Theme.getColor("lining") } //Allow switching between custom and auto. - Rectangle + Item { id: buttonBar visible: popupItem.is_connected //Switching only makes sense if the "auto" part is possible. - anchors - { - left: parent.left - right: parent.right - bottom: parent.bottom - } + width: parent.width height: childrenRect.height Cura.ActionButton diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index aa4cf3624b..d424f35ebe 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -11,6 +11,7 @@ import UM 1.3 as UM Item { width: parent.width + height: visible ? childrenRect.height : 0 Label { @@ -18,6 +19,7 @@ Item text: catalog.i18nc("@header", "Custom") font: UM.Theme.getFont("large") color: UM.Theme.getColor("text") + height: contentHeight anchors { @@ -62,14 +64,15 @@ Item { id: tabControl width: parent.width + height: childrenRect.height anchors.top: tabBar.bottom - anchors.bottom: parent.bottom property var model: extrudersModel.items[tabBar.currentIndex] property real textWidth: Math.round(width * 0.3) property real controlWidth: width - textWidth Column { spacing: UM.Theme.getSize("default_margin").height + Row { height: UM.Theme.getSize("print_setup_item").height @@ -165,6 +168,5 @@ Item } } } - } } \ No newline at end of file From 5c30df2a688d858fb5b23e6ccc4250acae1dc9b6 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 22 Nov 2018 15:00:35 +0100 Subject: [PATCH 0355/1292] Create a reusable component for the printer type label. Other parts of the UI can just reuse it. Contributes to CURA-5942. --- resources/qml/ActionButton.qml | 1 - .../PrinterSelector/MachineSelectorButton.qml | 24 ++----------- .../qml/PrinterSelector/PrinterTypeLabel.qml | 34 +++++++++++++++++++ resources/qml/qmldir | 3 +- 4 files changed, 39 insertions(+), 23 deletions(-) create mode 100644 resources/qml/PrinterSelector/PrinterTypeLabel.qml diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index 2a8b894867..ff8ee4b149 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -3,7 +3,6 @@ import QtQuick 2.7 import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.3 import UM 1.1 as UM diff --git a/resources/qml/PrinterSelector/MachineSelectorButton.qml b/resources/qml/PrinterSelector/MachineSelectorButton.qml index 44b162d00d..e98036dbc8 100644 --- a/resources/qml/PrinterSelector/MachineSelectorButton.qml +++ b/resources/qml/PrinterSelector/MachineSelectorButton.qml @@ -3,7 +3,6 @@ import QtQuick 2.7 import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.3 import UM 1.1 as UM import Cura 1.0 as Cura @@ -15,6 +14,7 @@ Button width: parent.width height: UM.Theme.getSize("action_button").height leftPadding: Math.round(1.5 * UM.Theme.getSize("default_margin").width) + rightPadding: Math.round(1.5 * UM.Theme.getSize("default_margin").width) checkable: true property var outputDevice: null @@ -63,27 +63,9 @@ Button Repeater { model: printerTypesList - delegate: Item + delegate: Cura.PrinterTypeLabel { - width: UM.Theme.getSize("printer_type_label").width - height: UM.Theme.getSize("printer_type_label").height - - Rectangle - { - anchors.fill: parent - color: UM.Theme.getColor("printer_type_label_background") - } - - Label - { - id: printerTypeLabel - text: modelData - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.horizontalCenter - renderType: Text.NativeRendering - font: UM.Theme.getFont("very_small") - color: UM.Theme.getColor("text") - } + text: modelData } } } diff --git a/resources/qml/PrinterSelector/PrinterTypeLabel.qml b/resources/qml/PrinterSelector/PrinterTypeLabel.qml new file mode 100644 index 0000000000..cd9f3b9743 --- /dev/null +++ b/resources/qml/PrinterSelector/PrinterTypeLabel.qml @@ -0,0 +1,34 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.1 + +import UM 1.1 as UM + +// This component creates a label with the abbreviated name of a printer, with a rectangle surrounding the label. +// It is created in a separated place in order to be reused whenever needed. +Item +{ + property alias text: printerTypeLabel.text + + width: UM.Theme.getSize("printer_type_label").width + height: UM.Theme.getSize("printer_type_label").height + + Rectangle + { + anchors.fill: parent + color: UM.Theme.getColor("printer_type_label_background") + } + + Label + { + id: printerTypeLabel + text: "CFFFP" // As an abbreviated name of the Custom FFF Printer + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + renderType: Text.NativeRendering + font: UM.Theme.getFont("very_small") + color: UM.Theme.getColor("text") + } +} \ No newline at end of file diff --git a/resources/qml/qmldir b/resources/qml/qmldir index 458338c78a..67388100ca 100644 --- a/resources/qml/qmldir +++ b/resources/qml/qmldir @@ -10,4 +10,5 @@ NozzleMenu 1.0 NozzleMenu.qml ActionPanelWidget 1.0 ActionPanelWidget.qml IconLabel 1.0 IconLabel.qml OutputDevicesActionButton 1.0 OutputDevicesActionButton.qml -ExpandableComponent 1.0 ExpandableComponent.qml \ No newline at end of file +ExpandableComponent 1.0 ExpandableComponent.qml +PrinterTypeLabel 1.0 PrinterTypeLabel.qml \ No newline at end of file From 2d2f24251dcaac15bed5bba3e0ec782161743181 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 22 Nov 2018 15:07:49 +0100 Subject: [PATCH 0356/1292] Fix MonitorMainView for USB printing CURA-5943 --- plugins/MonitorStage/MonitorMainView.qml | 106 +++++++++++++---------- 1 file changed, 61 insertions(+), 45 deletions(-) diff --git a/plugins/MonitorStage/MonitorMainView.qml b/plugins/MonitorStage/MonitorMainView.qml index c48f6d0aab..57dd033792 100644 --- a/plugins/MonitorStage/MonitorMainView.qml +++ b/plugins/MonitorStage/MonitorMainView.qml @@ -1,45 +1,61 @@ -// Copyright (c) 2017 Ultimaker B.V. - -import QtQuick 2.2 -import QtQuick.Controls 1.1 - -import UM 1.3 as UM -import Cura 1.0 as Cura - -Item -{ - // parent could be undefined as this component is not visible at all times - width: parent ? parent.width : 0 - height: parent ? parent.height : 0 - - // We show a nice overlay on the 3D viewer when the current output device has no monitor view - Rectangle - { - id: viewportOverlay - - color: UM.Theme.getColor("viewport_overlay") - width: parent.width - height: parent.height - - MouseArea - { - anchors.fill: parent - acceptedButtons: Qt.AllButtons - onWheel: wheel.accepted = true - } - } - - Loader - { - id: monitorViewComponent - - width: parent.width - height: parent.height - - property real maximumWidth: parent.width - property real maximumHeight: parent.height - - sourceComponent: Cura.MachineManager.printerOutputDevices.length > 0 ? Cura.MachineManager.printerOutputDevices[0].monitorItem: null - visible: sourceComponent != null - } -} +// Copyright (c) 2017 Ultimaker B.V. + +import QtQuick 2.10 +import QtQuick.Controls 1.4 + +import UM 1.3 as UM +import Cura 1.0 as Cura + + +Item +{ + // parent could be undefined as this component is not visible at all times + width: parent ? parent.width : 0 + height: parent ? parent.height : 0 + + // We show a nice overlay on the 3D viewer when the current output device has no monitor view + Rectangle + { + id: viewportOverlay + + color: UM.Theme.getColor("viewport_overlay") + width: parent.width + height: parent.height + + MouseArea + { + anchors.fill: parent + acceptedButtons: Qt.AllButtons + onWheel: wheel.accepted = true + } + } + + Loader + { + id: monitorViewComponent + + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: parent.left + + width: parent.width * 0.7 + height: parent.height + + property real maximumWidth: parent.width + property real maximumHeight: parent.height + + sourceComponent: Cura.MachineManager.printerOutputDevices.length > 0 ? Cura.MachineManager.printerOutputDevices[0].monitorItem: null + } + + Loader + { + id: monitorSidebarComponent + + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: monitorViewComponent.right + anchors.right: parent.right + + source: UM.Controller.activeStage.sidebarComponent != null ? UM.Controller.activeStage.sidebarComponent : "" + } +} From 3f4d379908add0ec7054eb65e87ae91587ffaebd Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 22 Nov 2018 15:35:40 +0100 Subject: [PATCH 0357/1292] Added shadow to slice button CURA-5959 --- resources/qml/ActionButton.qml | 18 +++++++++++ .../qml/ActionPanel/SliceProcessWidget.qml | 31 +++++++++---------- resources/themes/cura-light/theme.json | 2 ++ 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index 69d65e1c3f..8cd53b5d7e 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -5,6 +5,8 @@ import QtQuick 2.7 import QtQuick.Controls 2.1 import QtQuick.Layouts 1.3 +import QtGraphicalEffects 1.0 // For the dropshadow + import UM 1.1 as UM Button @@ -26,6 +28,9 @@ Button property color outlineHoverColor: hoverColor property color outlineDisabledColor: outlineColor + property alias shadowColor: shadow.color + property alias shadowEnabled: shadow.visible + // This property is used to indicate whether the button has a fixed width or the width would depend on the contents // Be careful when using fixedWidthMode, the translated texts can be too long that they won't fit. In any case, // we elide the text to the right so the text will be cut off with the three dots at the end. @@ -70,6 +75,19 @@ Button border.color: button.enabled ? (button.hovered ? button.outlineHoverColor : button.outlineColor) : button.outlineDisabledColor } + DropShadow + { + id: shadow + // Don't blur the shadow + radius: 0 + anchors.fill: backgroundRect + source: backgroundRect + verticalOffset: 2 + visible: false + // Should always be drawn behind the background. + z: backgroundRect.z - 1 + } + ToolTip { id: tooltip diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index 2d4a7b6b89..4f10e6879b 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -87,28 +87,27 @@ Column width: parent.width height: UM.Theme.getSize("action_panel_button").height fixedWidthMode: true - text: - { - if ([UM.Backend.NotStarted, UM.Backend.Error].indexOf(widget.backendState) != -1) - { - return catalog.i18nc("@button", "Slice") - } - if (autoSlice) - { - return catalog.i18nc("@button", "Auto slicing...") - } - return catalog.i18nc("@button", "Cancel") - } - enabled: !autoSlice && !disabledSlice // Get the current value from the preferences property bool autoSlice: UM.Preferences.getValue("general/auto_slice") // Disable the slice process when property bool disabledSlice: [UM.Backend.Done, UM.Backend.Error].indexOf(widget.backendState) != -1 - disabledColor: disabledSlice ? UM.Theme.getColor("action_button_disabled") : "transparent" - textDisabledColor: disabledSlice ? UM.Theme.getColor("action_button_disabled_text") : UM.Theme.getColor("primary") - outlineDisabledColor: disabledSlice ? UM.Theme.getColor("action_button_disabled_border") : "transparent" + text: + { + if ([UM.Backend.NotStarted, UM.Backend.Error].indexOf(widget.backendState) != -1) + { + return catalog.i18nc("@button", "Slice") + } + return catalog.i18nc("@button", "Cancel") + } + enabled: !autoSlice && !disabledSlice + visible: !autoSlice + + disabledColor: UM.Theme.getColor("action_button_disabled") + textDisabledColor: UM.Theme.getColor("action_button_disabled_text") + shadowEnabled: true + shadowColor: enabled ? UM.Theme.getColor("action_button_shadow"): UM.Theme.getColor("action_button_disabled_shadow") onClicked: sliceOrStopSlicing() } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index fefc4adc14..748a4e2643 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -173,6 +173,8 @@ "action_button_disabled": [245, 245, 245, 255], "action_button_disabled_text": [127, 127, 127, 255], "action_button_disabled_border": [245, 245, 245, 255], + "action_button_shadow": [64, 47, 205, 255], + "action_button_disabled_shadow": [228, 228, 228, 255], "print_button_ready": [50, 130, 255, 255], "print_button_ready_border": [50, 130, 255, 255], From 692868a0b4f25ba4aa8f2a1fedfe05fe36c9f0c9 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 22 Nov 2018 15:45:38 +0100 Subject: [PATCH 0358/1292] Create a function that given a printer type name, it will return and abbreviated name. Contributes to CURA-5942. --- cura/PrintInformation.py | 16 +------------- cura/Settings/MachineManager.py | 21 +++++++++++++++++++ .../PrinterSelector/MachineSelectorButton.qml | 2 +- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/cura/PrintInformation.py b/cura/PrintInformation.py index e11f70a54c..f1d8e81b3a 100644 --- a/cura/PrintInformation.py +++ b/cura/PrintInformation.py @@ -395,21 +395,7 @@ class PrintInformation(QObject): return active_machine_type_name = global_container_stack.definition.getName() - abbr_machine = "" - for word in re.findall(r"[\w']+", active_machine_type_name): - if word.lower() == "ultimaker": - abbr_machine += "UM" - elif word.isdigit(): - abbr_machine += word - else: - stripped_word = self._stripAccents(word.upper()) - # - use only the first character if the word is too long (> 3 characters) - # - use the whole word if it's not too long (<= 3 characters) - if len(stripped_word) > 3: - stripped_word = stripped_word[0] - abbr_machine += stripped_word - - self._abbr_machine = abbr_machine + self._abbr_machine = self._application.getMachineManager().getAbbreviatedMachineName(active_machine_type_name) ## Utility method that strips accents from characters (eg: â -> a) def _stripAccents(self, to_strip: str) -> str: diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index f321ce94a6..a65d2ed302 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -3,6 +3,8 @@ import collections import time +import re +import unicodedata from typing import Any, Callable, List, Dict, TYPE_CHECKING, Optional, cast from UM.ConfigurationErrorMessage import ConfigurationErrorMessage @@ -1537,3 +1539,22 @@ class MachineManager(QObject): with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): self.updateMaterialWithVariant(None) self._updateQualityWithMaterial() + + ## This function will translate any printer type name to an abbreviated printer type name + @pyqtSlot(str, result = str) + def getAbbreviatedMachineName(self, machine_type_name: str) -> str: + abbr_machine = "" + for word in re.findall(r"[\w']+", machine_type_name): + if word.lower() == "ultimaker": + abbr_machine += "UM" + elif word.isdigit(): + abbr_machine += word + else: + stripped_word = ''.join(char for char in unicodedata.normalize('NFD', word.upper()) if unicodedata.category(char) != 'Mn') + # - use only the first character if the word is too long (> 3 characters) + # - use the whole word if it's not too long (<= 3 characters) + if len(stripped_word) > 3: + stripped_word = stripped_word[0] + abbr_machine += stripped_word + + return abbr_machine diff --git a/resources/qml/PrinterSelector/MachineSelectorButton.qml b/resources/qml/PrinterSelector/MachineSelectorButton.qml index e98036dbc8..e7b44a4447 100644 --- a/resources/qml/PrinterSelector/MachineSelectorButton.qml +++ b/resources/qml/PrinterSelector/MachineSelectorButton.qml @@ -65,7 +65,7 @@ Button model: printerTypesList delegate: Cura.PrinterTypeLabel { - text: modelData + text: Cura.MachineManager.getAbbreviatedMachineName(modelData) } } } From 06cb628699bf23e04c5ab6e06b462582053f64c3 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 22 Nov 2018 15:46:56 +0100 Subject: [PATCH 0359/1292] Update desktop and mimeinfo to add gcode mime type CURA-5878 --- cura.desktop.in | 2 +- cura.sharedmimeinfo | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/cura.desktop.in b/cura.desktop.in index fbe8b30fed..b0195015a5 100644 --- a/cura.desktop.in +++ b/cura.desktop.in @@ -13,6 +13,6 @@ TryExec=@CMAKE_INSTALL_FULL_BINDIR@/cura Icon=cura-icon Terminal=false Type=Application -MimeType=model/stl;application/vnd.ms-3mfdocument;application/prs.wavefront-obj;image/bmp;image/gif;image/jpeg;image/png;model/x3d+xml; +MimeType=model/stl;application/vnd.ms-3mfdocument;application/prs.wavefront-obj;image/bmp;image/gif;image/jpeg;image/png;model/x3d+xml;text/x-gcode; Categories=Graphics; Keywords=3D;Printing;Slicer; diff --git a/cura.sharedmimeinfo b/cura.sharedmimeinfo index 23d38795eb..ed9099d425 100644 --- a/cura.sharedmimeinfo +++ b/cura.sharedmimeinfo @@ -19,4 +19,12 @@ + + + Gcode file + + + + + \ No newline at end of file From 4c26262054877c502e9244d06df9c2dce138c365 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 22 Nov 2018 17:06:56 +0100 Subject: [PATCH 0360/1292] Use re-usable TabRow component Contributes to issue CURA-5876. --- .../Menus/ConfigurationMenu/CustomConfiguration.qml | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index d424f35ebe..50ff108431 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -29,22 +29,19 @@ Item } } - TabBar + UM.TabRow { id: tabBar - onCurrentIndexChanged: Cura.ExtruderManager.setActiveExtruderIndex(currentIndex) anchors.top: header.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height - width: parent.width - height: 50 + + onCurrentIndexChanged: Cura.ExtruderManager.setActiveExtruderIndex(currentIndex) + Repeater { model: extrudersModel - - delegate: TabButton + delegate: UM.TabRowButton { - width: ListView.view != null ? Math.round(ListView.view.width / extrudersModel.rowCount()): 0 - height: parent.height contentItem: Item { Cura.ExtruderIcon From 1d84bd735660cc8c8b98157854fc15b46d5cd55e Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 22 Nov 2018 17:37:10 +0100 Subject: [PATCH 0361/1292] Improve the machine selector header to show an icon in case it is a network printer. Contributes to CURA-5942. --- .../qml/ActionPanel/OutputProcessWidget.qml | 2 ++ .../qml/ActionPanel/SliceProcessWidget.qml | 1 + resources/qml/IconLabel.qml | 13 ++++++----- .../qml/PrinterSelector/MachineSelector.qml | 22 ++++++++++++++----- ...us_connected.svg => printer_connected.svg} | 0 .../themes/cura-light/icons/printer_group.svg | 22 +++++++++++++------ .../cura-light/icons/printer_single.svg | 15 ++++++------- .../cura-light/icons/tab_status_busy.svg | 13 ----------- .../cura-light/icons/tab_status_finished.svg | 13 ----------- .../cura-light/icons/tab_status_paused.svg | 13 ----------- .../cura-light/icons/tab_status_stopped.svg | 13 ----------- .../cura-light/icons/tab_status_unknown.svg | 13 ----------- resources/themes/cura-light/theme.json | 1 + 13 files changed, 50 insertions(+), 91 deletions(-) rename resources/themes/cura-light/icons/{tab_status_connected.svg => printer_connected.svg} (100%) delete mode 100644 resources/themes/cura-light/icons/tab_status_busy.svg delete mode 100644 resources/themes/cura-light/icons/tab_status_finished.svg delete mode 100644 resources/themes/cura-light/icons/tab_status_paused.svg delete mode 100644 resources/themes/cura-light/icons/tab_status_stopped.svg delete mode 100644 resources/themes/cura-light/icons/tab_status_unknown.svg diff --git a/resources/qml/ActionPanel/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml index 3c4386f079..87f9d2015d 100644 --- a/resources/qml/ActionPanel/OutputProcessWidget.qml +++ b/resources/qml/ActionPanel/OutputProcessWidget.qml @@ -47,6 +47,7 @@ Column { id: estimatedTime width: parent.width + height: childrenRect.height text: PrintInformation.currentPrintTime.getDisplayString(UM.DurationFormat.Long) source: UM.Theme.getIcon("clock") @@ -57,6 +58,7 @@ Column { id: estimatedCosts width: parent.width + height: childrenRect.height property var printMaterialLengths: PrintInformation.materialLengths property var printMaterialWeights: PrintInformation.materialWeights diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index 2d4a7b6b89..9c46539220 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -44,6 +44,7 @@ Column { id: message width: parent.width + height: childrenRect.height visible: widget.backendState == UM.Backend.Error text: catalog.i18nc("@label:PrintjobStatus", "Unable to Slice") diff --git a/resources/qml/IconLabel.qml b/resources/qml/IconLabel.qml index 7c90382892..90930e91c7 100644 --- a/resources/qml/IconLabel.qml +++ b/resources/qml/IconLabel.qml @@ -16,32 +16,35 @@ Item property alias source: icon.source property alias color: label.color property alias font: label.font - - height: childrenRect.height + property alias iconSize: icon.width UM.RecolorImage { id: icon anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter - source: UM.Theme.getIcon("dot") + source: "" width: UM.Theme.getSize("section_icon").width - height: UM.Theme.getSize("section_icon").height + height: width sourceSize.width: width sourceSize.height: height color: label.color + visible: source != "" } Label { id: label - anchors.left: icon.right + anchors.left: icon.visible ? icon.right : parent.left + anchors.right: parent.right anchors.leftMargin: UM.Theme.getSize("thin_margin").width anchors.verticalCenter: icon.verticalCenter text: "Empty label" + elide: Text.ElideRight color: UM.Theme.getColor("text") font: UM.Theme.getFont("very_small") renderType: Text.NativeRendering diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index 66ed4d4a2c..d10478227a 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -14,6 +14,7 @@ Cura.ExpandableComponent id: machineSelector property bool isNetworkPrinter: Cura.MachineManager.activeMachineNetworkKey != "" + property var outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null popupPadding: 0 popupAlignment: Cura.ExpandableComponent.PopupAlignment.AlignLeft @@ -25,15 +26,24 @@ Cura.ExpandableComponent name: "cura" } - headerItem: Label + headerItem: Cura.IconLabel { text: isNetworkPrinter ? Cura.MachineManager.activeMachineNetworkGroupName : Cura.MachineManager.activeMachineName - verticalAlignment: Text.AlignVCenter - height: parent.height - elide: Text.ElideRight - renderType: Text.NativeRendering - font: UM.Theme.getFont("default") + source: + { + if (isNetworkPrinter && machineSelector.outputDevice != null) + { + if (machineSelector.outputDevice.clusterSize > 1) + { + return UM.Theme.getIcon("printer_group") + } + return UM.Theme.getIcon("printer_single") + } + return "" + } + font: UM.Theme.getFont("medium") color: UM.Theme.getColor("text") + iconSize: UM.Theme.getSize("machine_selector_icon").width } popupItem: Item diff --git a/resources/themes/cura-light/icons/tab_status_connected.svg b/resources/themes/cura-light/icons/printer_connected.svg similarity index 100% rename from resources/themes/cura-light/icons/tab_status_connected.svg rename to resources/themes/cura-light/icons/printer_connected.svg diff --git a/resources/themes/cura-light/icons/printer_group.svg b/resources/themes/cura-light/icons/printer_group.svg index 614bea90b8..5e439faca4 100644 --- a/resources/themes/cura-light/icons/printer_group.svg +++ b/resources/themes/cura-light/icons/printer_group.svg @@ -1,12 +1,20 @@ - - - icn_groupPrinters + + + Icon/ group printer/ disconnected Created with Sketch. - - - - + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/themes/cura-light/icons/printer_single.svg b/resources/themes/cura-light/icons/printer_single.svg index f7dc83987d..69c4e212bc 100644 --- a/resources/themes/cura-light/icons/printer_single.svg +++ b/resources/themes/cura-light/icons/printer_single.svg @@ -1,13 +1,12 @@ - - - icn_singlePrinter + + + Icon/ single printer/ disconnected Created with Sketch. - - - - - + + + + diff --git a/resources/themes/cura-light/icons/tab_status_busy.svg b/resources/themes/cura-light/icons/tab_status_busy.svg deleted file mode 100644 index debe4f6360..0000000000 --- a/resources/themes/cura-light/icons/tab_status_busy.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - Busy - Created with Sketch. - - - - - - - - \ No newline at end of file diff --git a/resources/themes/cura-light/icons/tab_status_finished.svg b/resources/themes/cura-light/icons/tab_status_finished.svg deleted file mode 100644 index 2519f2f862..0000000000 --- a/resources/themes/cura-light/icons/tab_status_finished.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - Wait cleanup - Created with Sketch. - - - - - - - - \ No newline at end of file diff --git a/resources/themes/cura-light/icons/tab_status_paused.svg b/resources/themes/cura-light/icons/tab_status_paused.svg deleted file mode 100644 index bab6c9ca6b..0000000000 --- a/resources/themes/cura-light/icons/tab_status_paused.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - paused - Created with Sketch. - - - - - - - - \ No newline at end of file diff --git a/resources/themes/cura-light/icons/tab_status_stopped.svg b/resources/themes/cura-light/icons/tab_status_stopped.svg deleted file mode 100644 index c9b150db3a..0000000000 --- a/resources/themes/cura-light/icons/tab_status_stopped.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - Aborted - Created with Sketch. - - - - - - - - \ No newline at end of file diff --git a/resources/themes/cura-light/icons/tab_status_unknown.svg b/resources/themes/cura-light/icons/tab_status_unknown.svg deleted file mode 100644 index 9f413baffc..0000000000 --- a/resources/themes/cura-light/icons/tab_status_unknown.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - Unknown - Created with Sketch. - - - - - - - - \ No newline at end of file diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 61b7600384..8f110db65d 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -396,6 +396,7 @@ "machine_selector_widget": [20.0, 4.0], "machine_selector_widget_content": [25.0, 32.0], + "machine_selector_icon": [2.66, 2.66], "views_selector": [16.0, 4.5], From 5be8b2810dbcde6274513f71abaadf9e792b5fa6 Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Thu, 22 Nov 2018 22:10:54 +0100 Subject: [PATCH 0362/1292] Fix: if load a model and scale it up to 0.1mm and then load another model then Cura will crash. It happens because the model 1 does not have any points for arranging it on the build plate CURA-5867 --- cura/Arranging/Arrange.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cura/Arranging/Arrange.py b/cura/Arranging/Arrange.py index 5657ee991a..32796005c8 100644 --- a/cura/Arranging/Arrange.py +++ b/cura/Arranging/Arrange.py @@ -66,6 +66,11 @@ class Arrange: continue vertices = vertices.getMinkowskiHull(Polygon.approximatedCircle(min_offset)) points = copy.deepcopy(vertices._points) + + # After scaling (like up to 0.1 mm) the node might not have points + if len(points) == 0: + continue + shape_arr = ShapeArray.fromPolygon(points, scale = scale) arranger.place(0, 0, shape_arr) From fa59a6a7dba646b18ab543dbf58c4e349e6eda4e Mon Sep 17 00:00:00 2001 From: THeijmans Date: Fri, 23 Nov 2018 09:17:32 +0100 Subject: [PATCH 0363/1292] UM3 ABS first layer temperature Fixed the first layer temperature for ABS Fine and Extra Fine profiles on the UM3 (ST-2281). --- resources/quality/ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg | 1 + .../quality/ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg | 1 + 2 files changed, 2 insertions(+) diff --git a/resources/quality/ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg index 9ceab110e9..4e79728945 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg @@ -17,6 +17,7 @@ machine_nozzle_cool_down_speed = 0.8 machine_nozzle_heat_up_speed = 1.5 material_standby_temperature = 100 material_print_temperature = =default_material_print_temperature - 5 +material_print_temperature_layer_0 = =material_print_temperature + 15 material_initial_print_temperature = =material_print_temperature - 5 material_final_print_temperature = =material_print_temperature - 10 prime_tower_enable = False diff --git a/resources/quality/ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg index e5b699c35f..3bded3b97c 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg @@ -14,6 +14,7 @@ variant = AA 0.4 [values] machine_nozzle_cool_down_speed = 0.85 machine_nozzle_heat_up_speed = 1.5 +material_print_temperature_layer_0 = =material_print_temperature + 10 material_initial_print_temperature = =material_print_temperature - 5 material_final_print_temperature = =material_print_temperature - 10 material_standby_temperature = 100 From bb5c0326de589ee09b2398b74a542f838d6ea8e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Fri, 23 Nov 2018 09:20:19 +0100 Subject: [PATCH 0364/1292] Used duoble quotes iso single quotes --- plugins/UM3NetworkPrinting/src/Models.py | 52 ++++++++++++------------ 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Models.py b/plugins/UM3NetworkPrinting/src/Models.py index d5e1007555..bcdeb8299c 100644 --- a/plugins/UM3NetworkPrinting/src/Models.py +++ b/plugins/UM3NetworkPrinting/src/Models.py @@ -2,32 +2,32 @@ # Cura is released under the terms of the LGPLv3 or higher. from collections import namedtuple -ClusterMaterial = namedtuple('ClusterMaterial', [ - 'guid', # Type: str - 'material', # Type: str - 'brand', # Type: str - 'version', # Type: int - 'color', # Type: str - 'density' # Type: str +ClusterMaterial = namedtuple("ClusterMaterial", [ + "guid", # Type: str + "material", # Type: str + "brand", # Type: str + "version", # Type: int + "color", # Type: str + "density" # Type: str ]) -LocalMaterial = namedtuple('LocalMaterial', [ - 'GUID', # Type: str - 'id', # Type: str - 'type', # Type: str - 'status', # Type: str - 'base_file', # Type: str - 'setting_version', # Type: int - 'version', # Type: int - 'name', # Type: str - 'brand', # Type: str - 'material', # Type: str - 'color_name', # Type: str - 'color_code', # Type: str - 'description', # Type: str - 'adhesion_info', # Type: str - 'approximate_diameter', # Type: str - 'properties', # Type: str - 'definition', # Type: str - 'compatible' # Type: str +LocalMaterial = namedtuple("LocalMaterial", [ + "GUID", # Type: str + "id", # Type: str + "type", # Type: str + "status", # Type: str + "base_file", # Type: str + "setting_version", # Type: int + "version", # Type: int + "name", # Type: str + "brand", # Type: str + "material", # Type: str + "color_name", # Type: str + "color_code", # Type: str + "description", # Type: str + "adhesion_info", # Type: str + "approximate_diameter", # Type: str + "properties", # Type: str + "definition", # Type: str + "compatible" # Type: str ]) From 294527f7febf96d81f4bcdf62b142a552d58fbbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Fri, 23 Nov 2018 09:21:09 +0100 Subject: [PATCH 0365/1292] Review changes --- .../UM3NetworkPrinting/src/SendMaterialJob.py | 19 ++++++------ .../tests/TestSendMaterialJob.py | 29 +++++++++++++------ 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py index 72269040e7..48760af28e 100644 --- a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py @@ -7,6 +7,7 @@ from typing import Dict, TYPE_CHECKING, Set from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest +from UM.Application import Application from UM.Job import Job from UM.Logger import Logger from UM.MimeTypeDatabase import MimeTypeDatabase @@ -27,7 +28,6 @@ class SendMaterialJob(Job): def __init__(self, device: "ClusterUM3OutputDevice") -> None: super().__init__() self.device = device # type: ClusterUM3OutputDevice - self._application = CuraApplication.getInstance() # type: CuraApplication ## Send the request to the printer and register a callback def run(self) -> None: @@ -44,12 +44,9 @@ class SendMaterialJob(Job): return # Collect materials from the printer's reply and send the missing ones if needed. - try: - remote_materials_by_guid = self._parseReply(reply) - if remote_materials_by_guid: - self._sendMissingMaterials(remote_materials_by_guid) - except TypeError: - Logger.logException("w", "Error parsing materials from printer") + remote_materials_by_guid = self._parseReply(reply) + if remote_materials_by_guid: + self._sendMissingMaterials(remote_materials_by_guid) ## Determine which materials should be updated and send them to the printer. # @@ -158,8 +155,12 @@ class SendMaterialJob(Job): try: remote_materials = json.loads(reply.readAll().data().decode("utf-8")) return {material["guid"]: ClusterMaterial(**material) for material in remote_materials} + except UnicodeDecodeError: + Logger.log("e", "Request material storage on printer: I didn't understand the printer's answer.") except json.JSONDecodeError: - Logger.logException("w", "Error parsing materials from printer") + Logger.log("e", "Request material storage on printer: I didn't understand the printer's answer.") + except TypeError: + Logger.log("e", "Request material storage on printer: Printer's answer was missing GUIDs.") ## Retrieves a list of local materials # @@ -168,7 +169,7 @@ class SendMaterialJob(Job): # \return a dictionary of LocalMaterial objects by GUID def _getLocalMaterials(self) -> Dict[str, LocalMaterial]: result = {} # type: Dict[str, LocalMaterial] - container_registry = self._application.getContainerRegistry() + container_registry = Application.getInstance().getContainerRegistry() material_containers = container_registry.findContainersMetadata(type = "material") # Find the latest version of all material containers in the registry. diff --git a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py index 548704fd33..f5a475b3ab 100644 --- a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py @@ -8,7 +8,7 @@ from unittest.mock import patch, call from PyQt5.QtCore import QByteArray from UM.MimeTypeDatabase import MimeType -from cura.CuraApplication import CuraApplication +from UM.Application import Application from plugins.UM3NetworkPrinting.src.SendMaterialJob import SendMaterialJob @@ -70,6 +70,17 @@ class TestSendMaterialJob(TestCase): self.assertEqual([call.attribute(0), call.errorString()], reply_mock.method_calls) self.assertEqual(0, device_mock.createFormPart.call_count) + def test__onGetRemoteMaterials_withWrongEncoding(self, reply_mock, device_mock): + reply_mock.attribute.return_value = 200 + reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTE_MATERIAL_WHITE]).encode("cp500")) + job = SendMaterialJob(device_mock) + job._onGetRemoteMaterials(reply_mock) + + # We expect the reply to be called once to try to get the printers from the list (readAll()). + # Given that the parsing fails we do no expect the device to be called for any follow up. + self.assertEqual([call.attribute(0), call.readAll()], reply_mock.method_calls) + self.assertEqual(0, device_mock.createFormPart.call_count) + def test__onGetRemoteMaterials_withBadJsonAnswer(self, reply_mock, device_mock): reply_mock.attribute.return_value = 200 reply_mock.readAll.return_value = QByteArray(b"Six sick hicks nick six slick bricks with picks and sticks.") @@ -95,7 +106,7 @@ class TestSendMaterialJob(TestCase): self.assertEqual(0, device_mock.createFormPart.call_count) @patch("cura.Settings.CuraContainerRegistry") - @patch("cura.CuraApplication") + @patch("UM.Application") def test__onGetRemoteMaterials_withInvalidVersionInLocalMaterial(self, application_mock, container_registry_mock, reply_mock, device_mock): reply_mock.attribute.return_value = 200 @@ -107,7 +118,7 @@ class TestSendMaterialJob(TestCase): application_mock.getContainerRegistry.return_value = container_registry_mock - with mock.patch.object(CuraApplication, "getInstance", new = lambda: application_mock): + with mock.patch.object(Application, "getInstance", new = lambda: application_mock): job = SendMaterialJob(device_mock) job._onGetRemoteMaterials(reply_mock) @@ -117,7 +128,7 @@ class TestSendMaterialJob(TestCase): self.assertEqual(0, device_mock.createFormPart.call_count) @patch("cura.Settings.CuraContainerRegistry") - @patch("cura.CuraApplication") + @patch("UM.Application") def test__onGetRemoteMaterials_withNoUpdate(self, application_mock, container_registry_mock, reply_mock, device_mock): application_mock.getContainerRegistry.return_value = container_registry_mock @@ -129,7 +140,7 @@ class TestSendMaterialJob(TestCase): reply_mock.attribute.return_value = 200 reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTE_MATERIAL_WHITE]).encode("ascii")) - with mock.patch.object(CuraApplication, "getInstance", new = lambda: application_mock): + with mock.patch.object(Application, "getInstance", new = lambda: application_mock): job = SendMaterialJob(device_mock) job._onGetRemoteMaterials(reply_mock) @@ -140,7 +151,7 @@ class TestSendMaterialJob(TestCase): self.assertEqual(0, device_mock.postFormWithParts.call_count) @patch("cura.Settings.CuraContainerRegistry") - @patch("cura.CuraApplication") + @patch("UM.Application") def test__onGetRemoteMaterials_withUpdatedMaterial(self, application_mock, container_registry_mock, reply_mock, device_mock): application_mock.getContainerRegistry.return_value = container_registry_mock @@ -154,7 +165,7 @@ class TestSendMaterialJob(TestCase): reply_mock.attribute.return_value = 200 reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTE_MATERIAL_WHITE]).encode("ascii")) - with mock.patch.object(CuraApplication, "getInstance", new = lambda: application_mock): + with mock.patch.object(Application, "getInstance", new = lambda: application_mock): job = SendMaterialJob(device_mock) job._onGetRemoteMaterials(reply_mock) @@ -169,7 +180,7 @@ class TestSendMaterialJob(TestCase): device_mock.method_calls) @patch("cura.Settings.CuraContainerRegistry") - @patch("cura.CuraApplication") + @patch("UM.Application") def test__onGetRemoteMaterials_withNewMaterial(self, application_mock, container_registry_mock, reply_mock, device_mock): application_mock.getContainerRegistry.return_value = container_registry_mock @@ -182,7 +193,7 @@ class TestSendMaterialJob(TestCase): reply_mock.attribute.return_value = 200 reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTE_MATERIAL_BLACK]).encode("ascii")) - with mock.patch.object(CuraApplication, "getInstance", new = lambda: application_mock): + with mock.patch.object(Application, "getInstance", new = lambda: application_mock): job = SendMaterialJob(device_mock) job._onGetRemoteMaterials(reply_mock) From 9f1ce72b9e428cab43a35b84cbc7f3ae76698069 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Fri, 23 Nov 2018 10:03:08 +0100 Subject: [PATCH 0366/1292] Add Cura 4.0 printer cards Contributes to CL-1150 --- .../resources/qml/ClusterMonitorItem.qml | 40 ++- .../qml/MonitorPrintJobProgressBar.qml | 112 +++++++++ .../resources/qml/MonitorPrinterCard.qml | 228 ++++++++++++++++++ 3 files changed, 375 insertions(+), 5 deletions(-) create mode 100644 plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml create mode 100644 plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml diff --git a/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml b/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml index 19a152e6eb..6bbc338c17 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml @@ -10,14 +10,13 @@ import QtGraphicalEffects 1.0 Component { - Rectangle + Item { id: monitorFrame property var emphasisColor: UM.Theme.getColor("setting_control_border_highlight") property var cornerRadius: UM.Theme.getSize("monitor_corner_radius").width - color: "transparent" height: maximumHeight onVisibleChanged: { @@ -48,13 +47,44 @@ Component } } + ScrollView + { + id: printers + anchors + { + left: parent.left + right: parent.right + top: parent.top + topMargin: 48 * screenScaleFactor // TODO: Theme! + } + height: 264 * screenScaleFactor // TODO: Theme! + Row + { + spacing: 60 * screenScaleFactor // TODO: Theme! + + Repeater + { + model: OutputDevice.printers + + MonitorPrinterCard + { + printer: modelData + } + } + } + } + Item { id: queue - anchors.fill: parent - anchors.top: parent.top - anchors.topMargin: 400 * screenScaleFactor // TODO: Insert carousel here + anchors { + bottom: parent.bottom + left: parent.left + right: parent.right + top: printers.bottom + topMargin: 48 + } Label { diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml new file mode 100644 index 0000000000..e7f9799310 --- /dev/null +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml @@ -0,0 +1,112 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.3 +import QtQuick.Controls.Styles 1.3 +import QtQuick.Controls 1.4 +import UM 1.3 as UM + +ProgressBar +{ + property var printJob: null + property var progress: { + if (!printJob) { + return 0; + } + var result = printJob.timeElapsed / printJob.timeTotal; + if (result > 1.0) { + result = 1.0; + } + return result; + } + width: 180 * screenScaleFactor // TODO: Theme! + value: progress; + style: ProgressBarStyle { + property var remainingTime: { + if (!printJob) { + return 0; + } + /* Sometimes total minus elapsed is less than 0. Use Math.max() to prevent remaining + time from ever being less than 0. Negative durations cause strange behavior such + as displaying "-1h -1m". */ + return Math.max(printer.activePrintJob.timeTotal - printer.activePrintJob.timeElapsed, 0); + } + property var progressText: { + if (!printJob) { + return ""; + } + switch (printJob.state) { + case "wait_cleanup": + if (printJob.timeTotal > printJob.timeElapsed) { + return catalog.i18nc("@label:status", "Aborted"); + } + return catalog.i18nc("@label:status", "Finished"); + case "pre_print": + case "sent_to_printer": + return catalog.i18nc("@label:status", "Preparing"); + case "aborted": + return catalog.i18nc("@label:status", "Aborted"); + case "wait_user_action": + return catalog.i18nc("@label:status", "Aborted"); + case "pausing": + return catalog.i18nc("@label:status", "Pausing"); + case "paused": + return OutputDevice.formatDuration( remainingTime ); + case "resuming": + return catalog.i18nc("@label:status", "Resuming"); + case "queued": + return catalog.i18nc("@label:status", "Action required"); + default: + return OutputDevice.formatDuration( remainingTime ); + } + } + background: Rectangle { + color: "#e4e4f2" // TODO: Theme! + implicitHeight: visible ? 8 : 0; + implicitWidth: 180; + radius: 4 + } + progress: Rectangle { + id: progressItem; + color: { + if (!printJob) { + return "black"; + } + var state = printJob.state + var inactiveStates = [ + "pausing", + "paused", + "resuming", + "wait_cleanup" + ]; + if (inactiveStates.indexOf(state) > -1 && remainingTime > 0) { + return UM.Theme.getColor("monitor_progress_fill_inactive"); + } else { + return "#0a0850" // TODO: Theme! + } + } + radius: 4 + + Label { + id: progressLabel; + anchors { + left: parent.left; + leftMargin: getTextOffset(); + } + text: progressText; + anchors.verticalCenter: parent.verticalCenter; + color: progressItem.width + progressLabel.width < control.width ? UM.Theme.getColor("text") : UM.Theme.getColor("monitor_progress_fill_text"); + width: contentWidth; + font: UM.Theme.getFont("default"); + } + + function getTextOffset() { + if (progressItem.width + progressLabel.width + 16 < control.width) { + return progressItem.width + UM.Theme.getSize("default_margin").width; + } else { + return progressItem.width - progressLabel.width - UM.Theme.getSize("default_margin").width; + } + } + } + } +} \ No newline at end of file diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml new file mode 100644 index 0000000000..2fd3f2ead2 --- /dev/null +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml @@ -0,0 +1,228 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 2.0 +import UM 1.3 as UM + +/** + * A Printer Card is has two main components: the printer portion and the print + * job portion, the latter being paired in the UI when a print job is paired + * a printer in-cluster. + * + * NOTE: For most labels, a fixed height with vertical alignment is used to make + * layouts more deterministic (like the fixed-size textboxes used in original + * mock-ups). This is also a stand-in for CSS's 'line-height' property. Denoted + * with '// FIXED-LINE-HEIGHT:'. + */ +Item +{ + id: base + + // The printer which all printer data is derived from + property var printer: null + + property var borderSize: 1 * screenScaleFactor // TODO: Theme, and remove from here + + width: 834 * screenScaleFactor // TODO: Theme! + height: 216 * screenScaleFactor // TODO: Theme! + + // Printer portion + Rectangle + { + id: printerInfo + border + { + color: "#EAEAEC" // TODO: Theme! + width: borderSize // TODO: Remove once themed + } + color: "white" // TODO: Theme! + width: parent.width + height: 144 * screenScaleFactor // TODO: Theme! + + Row + { + anchors + { + left: parent.left + leftMargin: 36 * screenScaleFactor // TODO: Theme! + verticalCenter: parent.verticalCenter + } + spacing: 18 * screenScaleFactor // TODO: Theme! + + Rectangle + { + id: printerImage + color: "#eeeeee" + width: 108 + height: 108 + } + + Item + { + anchors + { + verticalCenter: parent.verticalCenter + } + width: 216 * screenScaleFactor // TODO: Theme! + height: printerNameLabel.height + printerFamilyPill.height + 6 * screenScaleFactor // TODO: Theme! + + Label + { + id: printerNameLabel + text: printer && printer.name ? printer.name : "" + color: "#414054" // TODO: Theme! + elide: Text.ElideRight + font: UM.Theme.getFont("large") // 16pt, bold + width: parent.width + + // FIXED-LINE-HEIGHT: + height: 18 * screenScaleFactor // TODO: Theme! + verticalAlignment: Text.AlignVCenter + } + + MonitorPrinterPill + { + id: printerFamilyPill + anchors + { + top: printerNameLabel.bottom + topMargin: 6 * screenScaleFactor // TODO: Theme! + left: printerNameLabel.left + } + text: printer.type + } + } + + MonitorPrinterConfiguration + { + id: printerConfiguration + anchors.verticalCenter: parent.verticalCenter + buildplate: "Glass" + configurations: + [ + base.printer.printerConfiguration.extruderConfigurations[0], + base.printer.printerConfiguration.extruderConfigurations[1] + ] + height: 72 * screenScaleFactor // TODO: Theme! + } + } + + PrintJobContextMenu + { + id: contextButton + // anchors + // { + // right: parent.right + // rightMargin: 8 * screenScaleFactor // TODO: Theme! + // top: parent.top + // topMargin: 8 * screenScaleFactor // TODO: Theme! + // } + printJob: base.printJob + width: 32 * screenScaleFactor // TODO: Theme! + height: 32 * screenScaleFactor // TODO: Theme! + } + } + + + // Print job portion + Rectangle + { + id: printJobInfo + anchors + { + top: printerInfo.bottom + topMargin: -borderSize * screenScaleFactor // TODO: Theme! + } + border + { + color: "#EAEAEC" // TODO: Theme! + width: borderSize // TODO: Remove once themed + } + color: "white" // TODO: Theme! + height: 84 * screenScaleFactor + borderSize // TODO: Remove once themed + width: parent.width + + Row + { + anchors + { + fill: parent + topMargin: 12 * screenScaleFactor + borderSize // TODO: Theme! + bottomMargin: 12 * screenScaleFactor // TODO: Theme! + leftMargin: 36 * screenScaleFactor // TODO: Theme! + } + height: childrenRect.height + spacing: 18 * screenScaleFactor // TODO: Theme! + + Item + { + anchors + { + verticalCenter: parent.verticalCenter + } + width: printerImage.width + height: childrenRect.height + MonitorPrintJobPreview + { + anchors.centerIn: parent + printJob: base.printer.activePrintJob + size: 60 * screenScaleFactor // TODO: Theme! + } + } + + Item + { + anchors + { + verticalCenter: parent.verticalCenter + } + width: 216 * screenScaleFactor // TODO: Theme! + height: printerNameLabel.height + printerFamilyPill.height + 6 * screenScaleFactor // TODO: Theme! + + Label + { + id: printerJobNameLabel + text: base.printer.activePrintJob ? base.printer.activePrintJob.name : "Untitled" // TODO: I18N + color: "#414054" // TODO: Theme! + elide: Text.ElideRight + font: UM.Theme.getFont("large") // 16pt, bold + width: parent.width + + // FIXED-LINE-HEIGHT: + height: 18 * screenScaleFactor // TODO: Theme! + verticalAlignment: Text.AlignVCenter + } + + Label + { + id: printerJobOwnerLabel + anchors + { + top: printerJobNameLabel.bottom + topMargin: 6 * screenScaleFactor // TODO: Theme! + left: printerJobNameLabel.left + } + text: printer.activePrintJob ? printer.activePrintJob.owner : "Anonymous" // TODO: I18N + color: "#53657d" // TODO: Theme! + elide: Text.ElideRight + font: UM.Theme.getFont("very_small") // 12pt, regular + width: parent.width + + // FIXED-LINE-HEIGHT: + height: 18 * screenScaleFactor // TODO: Theme! + verticalAlignment: Text.AlignVCenter + } + } + + MonitorPrintJobProgressBar + { + anchors + { + verticalCenter: parent.verticalCenter + } + printJob: printer.activePrintJob + } + } + } +} \ No newline at end of file From 76542a82d5a19b3dd9ea2a3f2c785d8fd956fc57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Fri, 23 Nov 2018 10:33:57 +0100 Subject: [PATCH 0367/1292] Removed the asserts on internals --- .../tests/TestSendMaterialJob.py | 22 ++----------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py index f5a475b3ab..b669eb192a 100644 --- a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py @@ -1,4 +1,5 @@ # Copyright (c) 2018 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import io import json @@ -66,8 +67,7 @@ class TestSendMaterialJob(TestCase): job = SendMaterialJob(device_mock) job._onGetRemoteMaterials(reply_mock) - # We expect the error string to be retrieved and the device not to be called for any follow up. - self.assertEqual([call.attribute(0), call.errorString()], reply_mock.method_calls) + # We expect the device not to be called for any follow up. self.assertEqual(0, device_mock.createFormPart.call_count) def test__onGetRemoteMaterials_withWrongEncoding(self, reply_mock, device_mock): @@ -76,9 +76,7 @@ class TestSendMaterialJob(TestCase): job = SendMaterialJob(device_mock) job._onGetRemoteMaterials(reply_mock) - # We expect the reply to be called once to try to get the printers from the list (readAll()). # Given that the parsing fails we do no expect the device to be called for any follow up. - self.assertEqual([call.attribute(0), call.readAll()], reply_mock.method_calls) self.assertEqual(0, device_mock.createFormPart.call_count) def test__onGetRemoteMaterials_withBadJsonAnswer(self, reply_mock, device_mock): @@ -87,9 +85,7 @@ class TestSendMaterialJob(TestCase): job = SendMaterialJob(device_mock) job._onGetRemoteMaterials(reply_mock) - # We expect the reply to be called once to try to get the printers from the list (readAll()). # Given that the parsing fails we do no expect the device to be called for any follow up. - self.assertEqual([call.attribute(0), call.readAll()], reply_mock.method_calls) self.assertEqual(0, device_mock.createFormPart.call_count) def test__onGetRemoteMaterials_withMissingGuidInRemoteMaterial(self, reply_mock, device_mock): @@ -100,9 +96,7 @@ class TestSendMaterialJob(TestCase): job = SendMaterialJob(device_mock) job._onGetRemoteMaterials(reply_mock) - # We expect the reply to be called once to try to get the printers from the list (readAll()). # Given that parsing fails we do not expect the device to be called for any follow up. - self.assertEqual([call.attribute(0), call.readAll()], reply_mock.method_calls) self.assertEqual(0, device_mock.createFormPart.call_count) @patch("cura.Settings.CuraContainerRegistry") @@ -122,9 +116,6 @@ class TestSendMaterialJob(TestCase): job = SendMaterialJob(device_mock) job._onGetRemoteMaterials(reply_mock) - self.assertEqual([call.attribute(0), call.readAll()], reply_mock.method_calls) - self.assertEqual([call.getContainerRegistry()], application_mock.method_calls) - self.assertEqual([call.findContainersMetadata(type = "material")], container_registry_mock.method_calls) self.assertEqual(0, device_mock.createFormPart.call_count) @patch("cura.Settings.CuraContainerRegistry") @@ -144,9 +135,6 @@ class TestSendMaterialJob(TestCase): job = SendMaterialJob(device_mock) job._onGetRemoteMaterials(reply_mock) - self.assertEqual([call.attribute(0), call.readAll()], reply_mock.method_calls) - self.assertEqual([call.getContainerRegistry()], application_mock.method_calls) - self.assertEqual([call.findContainersMetadata(type = "material")], container_registry_mock.method_calls) self.assertEqual(0, device_mock.createFormPart.call_count) self.assertEqual(0, device_mock.postFormWithParts.call_count) @@ -169,9 +157,6 @@ class TestSendMaterialJob(TestCase): job = SendMaterialJob(device_mock) job._onGetRemoteMaterials(reply_mock) - self.assertEqual([call.attribute(0), call.readAll()], reply_mock.method_calls) - self.assertEqual([call.getContainerRegistry()], application_mock.method_calls) - self.assertEqual([call.findContainersMetadata(type = "material")], container_registry_mock.method_calls) self.assertEqual(1, device_mock.createFormPart.call_count) self.assertEqual(1, device_mock.postFormWithParts.call_count) self.assertEquals( @@ -197,9 +182,6 @@ class TestSendMaterialJob(TestCase): job = SendMaterialJob(device_mock) job._onGetRemoteMaterials(reply_mock) - self.assertEqual([call.attribute(0), call.readAll()], reply_mock.method_calls) - self.assertEqual([call.getContainerRegistry()], application_mock.method_calls) - self.assertEqual([call.findContainersMetadata(type = "material")], container_registry_mock.method_calls) self.assertEqual(1, device_mock.createFormPart.call_count) self.assertEqual(1, device_mock.postFormWithParts.call_count) self.assertEquals( From 67dc415b58eec45b497b3cd29eedee538514ec0a Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 23 Nov 2018 10:46:55 +0100 Subject: [PATCH 0368/1292] Add the connected icon to the printer selector that shows a blue icon when the printer is connected. If not connected then there is no icon. Contributes to CURA-5942. --- .../qml/PrinterSelector/MachineSelector.qml | 36 +++++++++++++++++-- .../themes/cura-light/icons/connected.svg | 5 --- .../themes/cura-light/icons/disconnected.svg | 6 ---- resources/themes/cura-light/theme.json | 2 +- 4 files changed, 35 insertions(+), 14 deletions(-) delete mode 100644 resources/themes/cura-light/icons/connected.svg delete mode 100644 resources/themes/cura-light/icons/disconnected.svg diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index d10478227a..a33c54ed88 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -14,6 +14,7 @@ Cura.ExpandableComponent id: machineSelector property bool isNetworkPrinter: Cura.MachineManager.activeMachineNetworkKey != "" + property bool isPrinterConnected: Cura.MachineManager.printerConnected property var outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null popupPadding: 0 @@ -31,9 +32,9 @@ Cura.ExpandableComponent text: isNetworkPrinter ? Cura.MachineManager.activeMachineNetworkGroupName : Cura.MachineManager.activeMachineName source: { - if (isNetworkPrinter && machineSelector.outputDevice != null) + if (isNetworkPrinter) { - if (machineSelector.outputDevice.clusterSize > 1) + if (machineSelector.outputDevice != null && machineSelector.outputDevice.clusterSize > 1) { return UM.Theme.getIcon("printer_group") } @@ -44,6 +45,37 @@ Cura.ExpandableComponent font: UM.Theme.getFont("medium") color: UM.Theme.getColor("text") iconSize: UM.Theme.getSize("machine_selector_icon").width + + UM.RecolorImage + { + id: icon + + anchors.bottom: parent.bottom + x: UM.Theme.getSize("thick_margin").width + + source: UM.Theme.getIcon("printer_connected") + width: UM.Theme.getSize("printer_status_icon").width + height: UM.Theme.getSize("printer_status_icon").height + + sourceSize.width: width + sourceSize.height: height + + color: UM.Theme.getColor("primary") + visible: isNetworkPrinter && isPrinterConnected + + // Make a themable circle in the background so we can change it in other themes + Rectangle + { + id: iconBackground + anchors.centerIn: parent + // Make it a bit bigger so there is an outline + width: parent.width + 2 + height: parent.height + 2 + radius: Math.round(width / 2) + color: UM.Theme.getColor("main_background") + z: parent.z - 1 + } + } } popupItem: Item diff --git a/resources/themes/cura-light/icons/connected.svg b/resources/themes/cura-light/icons/connected.svg deleted file mode 100644 index 18423bb6c4..0000000000 --- a/resources/themes/cura-light/icons/connected.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/resources/themes/cura-light/icons/disconnected.svg b/resources/themes/cura-light/icons/disconnected.svg deleted file mode 100644 index 019dff117e..0000000000 --- a/resources/themes/cura-light/icons/disconnected.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 8f110db65d..23b1ffcada 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -449,7 +449,7 @@ "favorites_button": [2, 2], "favorites_button_icon": [1.2, 1.2], - "printer_status_icon": [1.8, 1.8], + "printer_status_icon": [1.0, 1.0], "printer_sync_icon": [1.2, 1.2], "button_tooltip": [1.0, 1.3], From 48c24b103484ddf40a1e3da13ac480a983a4f493 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 23 Nov 2018 10:49:50 +0100 Subject: [PATCH 0369/1292] Remove log entry for bonjour services added For most networks that would not be a problematic log entry. But for our own debugging on Ultimaker's network this is a very spammy log entry and doesn't add much value anyway. --- plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py index 9c070f2de2..daea696cd1 100644 --- a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py +++ b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.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. from UM.OutputDevice.OutputDevicePlugin import OutputDevicePlugin @@ -325,13 +325,12 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): ## Handler for zeroConf detection. # Return True or False indicating if the process succeeded. - # Note that this function can take over 3 seconds to complete. Be carefull calling it from the main thread. + # Note that this function can take over 3 seconds to complete. Be careful + # calling it from the main thread. def _onServiceChanged(self, zero_conf, service_type, name, state_change): if state_change == ServiceStateChange.Added: - Logger.log("d", "Bonjour service added: %s" % name) - # First try getting info from zero-conf cache - info = ServiceInfo(service_type, name, properties={}) + info = ServiceInfo(service_type, name, properties = {}) for record in zero_conf.cache.entries_with_name(name.lower()): info.update_record(zero_conf, time(), record) From 3ba4b9fd81ac3b38aa393d71697f9e1514ecb6d7 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 23 Nov 2018 11:20:53 +0100 Subject: [PATCH 0370/1292] Add shadows to various used actionbuttons CURA-5959 --- .../ActionPanel/OutputDevicesActionButton.qml | 6 +++++- .../qml/ActionPanel/OutputProcessWidget.qml | 3 +++ .../qml/ActionPanel/SliceProcessWidget.qml | 17 ++++++++--------- resources/themes/cura-light/theme.json | 2 ++ 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/resources/qml/ActionPanel/OutputDevicesActionButton.qml b/resources/qml/ActionPanel/OutputDevicesActionButton.qml index be79a1893e..9682dddf14 100644 --- a/resources/qml/ActionPanel/OutputDevicesActionButton.qml +++ b/resources/qml/ActionPanel/OutputDevicesActionButton.qml @@ -17,7 +17,8 @@ Item id: saveToButton height: parent.height fixedWidthMode: true - + shadowEnabled: true + shadowColor: UM.Theme.getColor("primary_shadow") anchors { top: parent.top @@ -42,6 +43,9 @@ Item id: deviceSelectionMenu height: parent.height + shadowEnabled: true + shadowColor: UM.Theme.getColor("primary_shadow") + anchors { top: parent.top diff --git a/resources/qml/ActionPanel/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml index 3c4386f079..79b9898e49 100644 --- a/resources/qml/ActionPanel/OutputProcessWidget.qml +++ b/resources/qml/ActionPanel/OutputProcessWidget.qml @@ -115,6 +115,9 @@ Column textHoverColor: UM.Theme.getColor("text") onClicked: UM.Controller.setActiveStage("PreviewStage") visible: UM.Controller.activeStage != null && UM.Controller.activeStage.stageId != "PreviewStage" + + shadowEnabled: true + shadowColor: UM.Theme.getColor("action_button_disabled_shadow") } Cura.OutputDevicesActionButton diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index 4f10e6879b..7cce323905 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -93,21 +93,20 @@ Column // Disable the slice process when property bool disabledSlice: [UM.Backend.Done, UM.Backend.Error].indexOf(widget.backendState) != -1 - text: - { - if ([UM.Backend.NotStarted, UM.Backend.Error].indexOf(widget.backendState) != -1) - { - return catalog.i18nc("@button", "Slice") - } - return catalog.i18nc("@button", "Cancel") - } + property bool isSlicing: [UM.Backend.NotStarted, UM.Backend.Error].indexOf(widget.backendState) == -1 + + text: isSlicing ? catalog.i18nc("@button", "Cancel") : catalog.i18nc("@button", "Slice") + enabled: !autoSlice && !disabledSlice visible: !autoSlice + color: isSlicing ? UM.Theme.getColor("secondary"): UM.Theme.getColor("primary") + textColor: isSlicing ? UM.Theme.getColor("primary"): UM.Theme.getColor("button_text") + disabledColor: UM.Theme.getColor("action_button_disabled") textDisabledColor: UM.Theme.getColor("action_button_disabled_text") shadowEnabled: true - shadowColor: enabled ? UM.Theme.getColor("action_button_shadow"): UM.Theme.getColor("action_button_disabled_shadow") + shadowColor: isSlicing ? UM.Theme.getColor("secondary_shadow") : enabled ? UM.Theme.getColor("action_button_shadow"): UM.Theme.getColor("action_button_disabled_shadow") onClicked: sliceOrStopSlicing() } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 748a4e2643..c5802b6a7e 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -83,10 +83,12 @@ "primary": [50, 130, 255, 255], + "primary_shadow": [64, 47, 205, 255], "primary_hover": [48, 182, 231, 255], "primary_text": [255, 255, 255, 255], "border": [127, 127, 127, 255], "secondary": [245, 245, 245, 255], + "secondary_shadow": [228, 228, 228, 255], "main_window_header_background": [10, 8, 80, 255], "main_window_header_button_text_active": [10, 8, 80, 255], From 666ed595e5ed91cf4140b164abb745a021da03e7 Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Fri, 23 Nov 2018 11:36:31 +0100 Subject: [PATCH 0371/1292] Added space --- resources/qml/PrintSetupSelector.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/qml/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector.qml index 61cc06b426..7cb47002a7 100644 --- a/resources/qml/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector.qml @@ -348,6 +348,7 @@ Cura.ExpandableComponent } } } + Component.onCompleted: { var index = Math.round(UM.Preferences.getValue("cura/active_mode")) From 1a8df9e10ecff985d8ae70ff960b4337e294f721 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 23 Nov 2018 11:46:38 +0100 Subject: [PATCH 0372/1292] Removed blue border if slicing is not possible CURA-5959 --- resources/qml/ActionPanel/SliceProcessWidget.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index 7cce323905..9a9f40ffac 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -102,7 +102,7 @@ Column color: isSlicing ? UM.Theme.getColor("secondary"): UM.Theme.getColor("primary") textColor: isSlicing ? UM.Theme.getColor("primary"): UM.Theme.getColor("button_text") - + outlineColor: "transparent" disabledColor: UM.Theme.getColor("action_button_disabled") textDisabledColor: UM.Theme.getColor("action_button_disabled_text") shadowEnabled: true From c4d0207cc13abfb75da88a8c50c3a9c19147b964 Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Fri, 23 Nov 2018 13:10:48 +0100 Subject: [PATCH 0373/1292] Added close button in right top corner CURA-5941 --- resources/qml/PrintSetupSelector.qml | 33 +++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/resources/qml/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector.qml index 7cb47002a7..8271484e6a 100644 --- a/resources/qml/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector.qml @@ -151,7 +151,7 @@ Cura.ExpandableComponent color: UM.Theme.getColor("text") height: parent.height anchors.topMargin: UM.Theme.getSize("sidebar_margin").height - anchors.bottomMargin: UM.Theme.getSize("sidebar_margin").height +// anchors.bottomMargin: UM.Theme.getSize("sidebar_margin").height anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("print_setup_selector_margin").height } @@ -165,6 +165,37 @@ Cura.ExpandableComponent } + + Button + { + id: closeButton; + width: UM.Theme.getSize("message_close").width; + height: UM.Theme.getSize("message_close").height; + + anchors + { + right: parent.right; + rightMargin: UM.Theme.getSize("default_margin").width; + top: parent.top; + topMargin: 10 + } + + UM.RecolorImage + { + anchors.fill: parent; + sourceSize.width: width + sourceSize.height: width + color: UM.Theme.getColor("message_text") + source: UM.Theme.getIcon("cross1") + } + + onClicked: base.model.hideMessage(model.id) + + background: Rectangle + { + color: UM.Theme.getColor("message_background") + } + } } Rectangle From 2fc5061c41ae93d664320d30413c766eeaecdd5c Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Fri, 23 Nov 2018 14:11:43 +0100 Subject: [PATCH 0374/1292] Fix some PR comments, cleanup imports --- cura/NetworkClient.py | 6 ++--- .../NetworkedPrinterOutputDevice.py | 24 ++++++++----------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/cura/NetworkClient.py b/cura/NetworkClient.py index 20c026f4e6..eeedfeaa79 100644 --- a/cura/NetworkClient.py +++ b/cura/NetworkClient.py @@ -15,10 +15,10 @@ from cura.CuraApplication import CuraApplication # This was originally part of NetworkedPrinterOutputDevice but was moved out for re-use in other classes. class NetworkClient: - def __init__(self, application: CuraApplication = None): + def __init__(self) -> None: # Use the given application instance or get the singleton instance. - self._application = application or CuraApplication.getInstance() + self._application = CuraApplication.getInstance() # Network manager instance to use for this client. self._manager = None # type: Optional[QNetworkAccessManager] @@ -89,7 +89,7 @@ class NetworkClient: def _validateManager(self) -> None: if self._manager is None: self._createNetworkManager() - assert (self._manager is not None) + assert self._manager is not None ## Callback for when the network manager detects that authentication is required but was not given. @staticmethod diff --git a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py index b5bb1a5452..12769208f4 100644 --- a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py +++ b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py @@ -1,22 +1,18 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. - -from UM.FileHandler.FileHandler import FileHandler #For typing. -from UM.Logger import Logger -from UM.Scene.SceneNode import SceneNode #For typing. -from cura.CuraApplication import CuraApplication -from cura.NetworkClient import NetworkClient - -from cura.PrinterOutputDevice import PrinterOutputDevice, ConnectionState - -from PyQt5.QtNetwork import QHttpMultiPart, QHttpPart, QNetworkRequest, QNetworkAccessManager, QNetworkReply, QAuthenticator -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QUrl, QCoreApplication +import os +import gzip from time import time -from typing import Any, Callable, Dict, List, Optional +from typing import Dict, List, Optional from enum import IntEnum -import os # To get the username -import gzip +from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply +from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QCoreApplication + +from UM.FileHandler.FileHandler import FileHandler +from UM.Scene.SceneNode import SceneNode +from cura.NetworkClient import NetworkClient +from cura.PrinterOutputDevice import PrinterOutputDevice, ConnectionState class AuthState(IntEnum): From 3e100775df7c295931cfc0613309205f8d8c0ea5 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Fri, 23 Nov 2018 14:14:35 +0100 Subject: [PATCH 0375/1292] Fix instantiating CloudOutputDeviceManager --- .../src/Cloud/CloudOutputDeviceManager.py | 8 ++++---- plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 08e43152ae..0ec07df923 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -26,11 +26,11 @@ class CloudOutputDeviceManager(NetworkClient): # The cloud URL to use for remote clusters. API_ROOT_PATH = "https://api.ultimaker.com/connect/v1" - def __init__(self, application: "CuraApplication"): - super().__init__(application) + def __init__(self): + super().__init__() - self._output_device_manager = application.getOutputDeviceManager() - self._account = application.getCuraAPI().account + self._output_device_manager = self._application.getOutputDeviceManager() + self._account = self._application.getCuraAPI().account # Persistent dict containing the remote clusters for the authenticated user. self._remote_clusters = {} # type: Dict[str, CloudOutputDevice] diff --git a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py index b441df9eb5..f3e2b66d50 100644 --- a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py +++ b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py @@ -41,7 +41,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): self._zero_conf_browser = None # Create a cloud output device manager that abstract all cloud connection logic away. - self._cloud_output_device_manager = CloudOutputDeviceManager(self._application) + self._cloud_output_device_manager = CloudOutputDeviceManager() # Because the model needs to be created in the same thread as the QMLEngine, we use a signal. self.addDeviceSignal.connect(self._onAddDevice) From ef5ca6f5a9f8b2eb5ee3f5ffd84998003404ac5b Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Fri, 23 Nov 2018 14:15:21 +0100 Subject: [PATCH 0376/1292] Remove unused typing import --- .../UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 0ec07df923..75d2efd4f7 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -8,10 +8,6 @@ from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply from UM.Logger import Logger from cura.NetworkClient import NetworkClient from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputDevice import CloudOutputDevice - - -if TYPE_CHECKING: - from cura.CuraApplication import CuraApplication ## The cloud output device manager is responsible for using the Ultimaker Cloud APIs to manage remote clusters. From cf27a211df10e592c0d509321017c0f620159786 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Fri, 23 Nov 2018 14:15:40 +0100 Subject: [PATCH 0377/1292] Remove unused TYPE_CHECKING import --- .../UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 75d2efd4f7..8459527d39 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -1,7 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import json -from typing import TYPE_CHECKING, Dict, Optional +from typing import Dict, Optional from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply From a3bcdaf3b625087204a04867e8a9a374c9bfa857 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 23 Nov 2018 16:58:57 +0100 Subject: [PATCH 0378/1292] Make the popup in the printer selector resizable depending on the contents. Also there is a maximum height that will fit 9 printers. Contributes to CURA-5942. --- plugins/PrepareStage/PrepareMenu.qml | 3 + .../qml/PrinterSelector/MachineSelector.qml | 78 ++----------------- .../PrinterSelector/MachineSelectorList.qml | 78 +++++++++++++++++++ 3 files changed, 89 insertions(+), 70 deletions(-) create mode 100644 resources/qml/PrinterSelector/MachineSelectorList.qml diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index eed1da0ad8..a99426acd8 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -1,3 +1,6 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + import QtQuick 2.7 import QtQuick.Layouts 1.1 import QtQuick.Controls 1.4 diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index a33c54ed88..c73836ad6a 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -82,87 +82,24 @@ Cura.ExpandableComponent { id: popup width: UM.Theme.getSize("machine_selector_widget_content").width - height: UM.Theme.getSize("machine_selector_widget_content").height ScrollView { id: scroll width: parent.width - anchors.top: parent.top - anchors.bottom: separator.top clip: true - Column + MachineSelectorList { - id: column - // Can't use parent.width since the parent is the flickable component and not the ScrollView width: scroll.width - 2 * UM.Theme.getSize("default_lining").width x: UM.Theme.getSize("default_lining").width + property real maximumHeight: UM.Theme.getSize("machine_selector_widget_content").height - buttonRow.height - Label + onHeightChanged: { - text: catalog.i18nc("@label", "Network connected printers") - visible: networkedPrintersModel.items.length > 0 - leftPadding: UM.Theme.getSize("default_margin").width - height: visible ? contentHeight + 2 * UM.Theme.getSize("default_margin").height : 0 - renderType: Text.NativeRendering - font: UM.Theme.getFont("medium") - color: UM.Theme.getColor("text_medium") - verticalAlignment: Text.AlignVCenter - } - - Repeater - { - id: networkedPrinters - - model: UM.ContainerStacksModel - { - id: networkedPrintersModel - filter: {"type": "machine", "um_network_key": "*", "hidden": "False"} - } - - delegate: MachineSelectorButton - { - text: model.metadata["connect_group_name"] - checked: Cura.MachineManager.activeMachineNetworkGroupName == model.metadata["connect_group_name"] - outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null - - Connections - { - target: Cura.MachineManager - onActiveMachineNetworkGroupNameChanged: checked = Cura.MachineManager.activeMachineNetworkGroupName == model.metadata["connect_group_name"] - } - } - } - - Label - { - text: catalog.i18nc("@label", "Preset printers") - visible: virtualPrintersModel.items.length > 0 - leftPadding: UM.Theme.getSize("default_margin").width - height: visible ? contentHeight + 2 * UM.Theme.getSize("default_margin").height : 0 - renderType: Text.NativeRendering - font: UM.Theme.getFont("medium") - color: UM.Theme.getColor("text_medium") - verticalAlignment: Text.AlignVCenter - } - - Repeater - { - id: virtualPrinters - - model: UM.ContainerStacksModel - { - id: virtualPrintersModel - filter: {"type": "machine", "um_network_key": null} - } - - delegate: MachineSelectorButton - { - text: model.name - checked: Cura.MachineManager.activeMachineId == model.id - } + scroll.height = Math.min(height, maximumHeight) + popup.height = scroll.height + buttonRow.height } } } @@ -171,7 +108,7 @@ Cura.ExpandableComponent { id: separator - anchors.bottom: buttonRow.top + anchors.top: scroll.bottom width: parent.width height: UM.Theme.getSize("default_lining").height color: UM.Theme.getColor("lining") @@ -181,7 +118,8 @@ Cura.ExpandableComponent { id: buttonRow - anchors.bottom: parent.bottom + // The separator is inside the buttonRow. This is to avoid some weird behaviours with the scroll bar. + anchors.top: separator.top anchors.horizontalCenter: parent.horizontalCenter padding: UM.Theme.getSize("default_margin").width spacing: UM.Theme.getSize("default_margin").width diff --git a/resources/qml/PrinterSelector/MachineSelectorList.qml b/resources/qml/PrinterSelector/MachineSelectorList.qml new file mode 100644 index 0000000000..11a61194b7 --- /dev/null +++ b/resources/qml/PrinterSelector/MachineSelectorList.qml @@ -0,0 +1,78 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.3 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +Column +{ + id: machineSelectorList + + Label + { + text: catalog.i18nc("@label", "Network connected printers") + visible: networkedPrintersModel.items.length > 0 + leftPadding: UM.Theme.getSize("default_margin").width + height: visible ? contentHeight + 2 * UM.Theme.getSize("default_margin").height : 0 + renderType: Text.NativeRendering + font: UM.Theme.getFont("medium") + color: UM.Theme.getColor("text_medium") + verticalAlignment: Text.AlignVCenter + } + + Repeater + { + id: networkedPrinters + + model: UM.ContainerStacksModel + { + id: networkedPrintersModel + filter: {"type": "machine", "um_network_key": "*", "hidden": "False"} + } + + delegate: MachineSelectorButton + { + text: model.metadata["connect_group_name"] + checked: Cura.MachineManager.activeMachineNetworkGroupName == model.metadata["connect_group_name"] + outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null + + Connections + { + target: Cura.MachineManager + onActiveMachineNetworkGroupNameChanged: checked = Cura.MachineManager.activeMachineNetworkGroupName == model.metadata["connect_group_name"] + } + } + } + + Label + { + text: catalog.i18nc("@label", "Preset printers") + visible: virtualPrintersModel.items.length > 0 + leftPadding: UM.Theme.getSize("default_margin").width + height: visible ? contentHeight + 2 * UM.Theme.getSize("default_margin").height : 0 + renderType: Text.NativeRendering + font: UM.Theme.getFont("medium") + color: UM.Theme.getColor("text_medium") + verticalAlignment: Text.AlignVCenter + } + + Repeater + { + id: virtualPrinters + + model: UM.ContainerStacksModel + { + id: virtualPrintersModel + filter: {"type": "machine", "um_network_key": null} + } + + delegate: MachineSelectorButton + { + text: model.name + checked: Cura.MachineManager.activeMachineId == model.id + } + } +} \ No newline at end of file From e1f3e07f049376240293cc2956c0afce4fd18432 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 23 Nov 2018 17:11:20 +0100 Subject: [PATCH 0379/1292] Changed Marketplace button to no longer use the action button The actionButton is weirdly named and overly used. That being said, the marketplace button is unique, so there is little sense in re-using it --- resources/qml/MainWindow/MainWindowHeader.qml | 35 ++++++++++++------- resources/themes/cura-light/theme.json | 7 ---- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/resources/qml/MainWindow/MainWindowHeader.qml b/resources/qml/MainWindow/MainWindowHeader.qml index 59ec542e6b..ceb27dd726 100644 --- a/resources/qml/MainWindow/MainWindowHeader.qml +++ b/resources/qml/MainWindow/MainWindowHeader.qml @@ -2,6 +2,7 @@ // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 +import QtQuick.Controls 2.0 as Controls2 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.1 @@ -73,25 +74,35 @@ Rectangle } // Shortcut button to quick access the Toolbox - Cura.ActionButton + Controls2.Button { + id: marketplaceButton + text: catalog.i18nc("@action:button", "Marketplace") + height: Math.round(0.5 * UM.Theme.getSize("main_window_header").height) + onClicked: Cura.Actions.browsePackages.trigger() + + background: Rectangle + { + radius: UM.Theme.getSize("action_button_radius").width + color: "transparent" + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("primary_text") + } + + contentItem: Label + { + id: label + text: marketplaceButton.text + color: UM.Theme.getColor("primary_text") + width: contentWidth + } + anchors { right: accountWidget.left rightMargin: UM.Theme.getSize("default_margin").width verticalCenter: parent.verticalCenter } - leftPadding: UM.Theme.getSize("default_margin").width - rightPadding: UM.Theme.getSize("default_margin").width - text: catalog.i18nc("@action:button", "Marketplace") - height: Math.round(0.5 * UM.Theme.getSize("main_window_header").height) - color: UM.Theme.getColor("main_window_header_secondary_button_background_active") - hoverColor: UM.Theme.getColor("main_window_header_secondary_button_background_hovered") - outlineColor: UM.Theme.getColor("main_window_header_secondary_button_outline_active") - outlineHoverColor: UM.Theme.getColor("main_window_header_secondary_button_outline_hovered") - textColor: UM.Theme.getColor("main_window_header_secondary_button_text_active") - textHoverColor: UM.Theme.getColor("main_window_header_secondary_button_text_hovered") - onClicked: Cura.Actions.browsePackages.trigger() } AccountWidget diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index c5802b6a7e..888bc9bfa6 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -98,13 +98,6 @@ "main_window_header_button_background_inactive": [255, 255, 255, 0], "main_window_header_button_background_hovered": [255, 255, 255, 102], - "main_window_header_secondary_button_text_active": [255, 255, 255, 255], - "main_window_header_secondary_button_text_hovered": [10, 8, 80, 255], - "main_window_header_secondary_button_background_active": [255, 255, 255, 0], - "main_window_header_secondary_button_background_hovered": [255, 255, 255, 255], - "main_window_header_secondary_button_outline_active": [255, 255, 255, 255], - "main_window_header_secondary_button_outline_hovered": [255, 255, 255, 255], - "account_widget_outline_active": [70, 66, 126, 255], "machine_selector_bar": [31, 36, 39, 255], From 2e262dd9d22add74f7ee5b638a64c1b9bc63ff27 Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Fri, 23 Nov 2018 17:35:55 +0100 Subject: [PATCH 0380/1292] Added Icons to SidebarSimple --- resources/qml/SidebarSimple.qml | 58 ++++++++++++++++----------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index 5e723a3d70..52fc9320f2 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -187,12 +187,11 @@ Item } } - Label + IconWithText { id: qualityRowTitle + source: UM.Theme.getIcon("category_layer_height") text: catalog.i18nc("@label", "Layer Height") - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") } // Show titles for the each quality slider ticks @@ -532,17 +531,19 @@ Item width: Math.round(UM.Theme.getSize("print_setup_widget").width * .45) - UM.Theme.getSize("thick_margin").width - Label + IconWithText { id: infillLabel - text: catalog.i18nc("@label", "Infill") - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") + source: UM.Theme.getIcon("category_infill") + text: catalog.i18nc("@label", "Infill") + " (%)" - anchors.top: parent.top - anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height * 1.7) - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("thick_margin").width + anchors + { + top: parent.top + topMargin: Math.round(UM.Theme.getSize("thick_margin").height * 1.7) + left: parent.left + leftMargin: UM.Theme.getSize("thick_margin").width + } } } @@ -855,23 +856,23 @@ Item // // Enable support // - Label + IconWithText { id: enableSupportLabel visible: enableSupportCheckBox.visible + source: UM.Theme.getIcon("category_support") + text: catalog.i18nc("@label", "Support") - anchors.top: infillCellRight.bottom - anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height * 1.5) - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("thick_margin").width - anchors.right: infillCellLeft.right - anchors.rightMargin: UM.Theme.getSize("thick_margin").width - anchors.verticalCenter: enableSupportCheckBox.verticalCenter - - text: catalog.i18nc("@label", "Generate Support") - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - elide: Text.ElideRight + anchors + { + top: infillCellRight.bottom + topMargin: Math.round(UM.Theme.getSize("thick_margin").height * 1.5) + left: parent.left + leftMargin: UM.Theme.getSize("thick_margin").width + right: infillCellLeft.right + rightMargin: UM.Theme.getSize("thick_margin").width + verticalCenter: enableSupportCheckBox.verticalCenter + } } CheckBox @@ -980,15 +981,12 @@ Item } - Label + IconWithText { id: adhesionHelperLabel visible: adhesionCheckBox.visible - - text: catalog.i18nc("@label", "Build Plate Adhesion") - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - elide: Text.ElideRight + source: UM.Theme.getIcon("category_adhesion") + text: catalog.i18nc("@label", "Adhesion") anchors { From af1ee535788b4d64945ef578bde3764551297ab4 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 23 Nov 2018 17:41:58 +0100 Subject: [PATCH 0381/1292] Fix the hover effect of action button CURA-5959 --- resources/qml/ActionButton.qml | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index 8cd53b5d7e..6dd5839bb9 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -12,7 +12,6 @@ import UM 1.1 as UM Button { id: button - property alias cursorShape: mouseArea.cursorShape property alias iconSource: buttonIcon.source property alias textFont: buttonText.font property alias cornerRadius: backgroundRect.radius @@ -22,12 +21,14 @@ Button property color hoverColor: UM.Theme.getColor("primary_hover") property color disabledColor: color property color textColor: UM.Theme.getColor("button_text") - property color textHoverColor: UM.Theme.getColor("button_text_hover") + property color textHoverColor: textColor property color textDisabledColor: textColor property color outlineColor: color property color outlineHoverColor: hoverColor property color outlineDisabledColor: outlineColor + hoverEnabled: true + property alias shadowColor: shadow.color property alias shadowEnabled: shadow.visible @@ -95,13 +96,4 @@ Button delay: 500 visible: text != "" && button.hovered } - - MouseArea - { - id: mouseArea - anchors.fill: parent - // Ensure that the button will still accept the clicks on it's own. - onPressed: mouse.accepted = false - hoverEnabled: true - } } From b82ea58bc815b28815cd6991230d5a3b4d8ca78d Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 23 Nov 2018 18:07:50 +0100 Subject: [PATCH 0382/1292] Changed all the action buttons to either use primary or secondary button CURA-5959 --- resources/qml/Account/GeneralOperations.qml | 8 +-- resources/qml/Account/UserOperations.qml | 8 +-- .../ActionPanel/OutputDevicesActionButton.qml | 5 +- .../qml/ActionPanel/OutputProcessWidget.qml | 9 +--- .../qml/ActionPanel/SliceProcessWidget.qml | 49 ++++++++++--------- resources/qml/PrimaryButton.qml | 18 +++++++ resources/qml/SecondaryButton.qml | 18 +++++++ resources/themes/cura-light/theme.json | 10 ++++ 8 files changed, 81 insertions(+), 44 deletions(-) create mode 100644 resources/qml/PrimaryButton.qml create mode 100644 resources/qml/SecondaryButton.qml diff --git a/resources/qml/Account/GeneralOperations.qml b/resources/qml/Account/GeneralOperations.qml index 4614c4ba88..b9f1025d5e 100644 --- a/resources/qml/Account/GeneralOperations.qml +++ b/resources/qml/Account/GeneralOperations.qml @@ -11,20 +11,16 @@ Row { spacing: UM.Theme.getSize("default_margin").width - Cura.ActionButton + Cura.SecondaryButton { width: UM.Theme.getSize("account_button").width height: UM.Theme.getSize("account_button").height text: catalog.i18nc("@button", "Create account") - color: UM.Theme.getColor("secondary") - hoverColor: UM.Theme.getColor("secondary") - textColor: UM.Theme.getColor("main_window_header_button_text_active") - textHoverColor: UM.Theme.getColor("main_window_header_button_text_active") onClicked: Qt.openUrlExternally("https://account.ultimaker.com/app/create") fixedWidthMode: true } - Cura.ActionButton + Cura.PrimaryButton { width: UM.Theme.getSize("account_button").width height: UM.Theme.getSize("account_button").height diff --git a/resources/qml/Account/UserOperations.qml b/resources/qml/Account/UserOperations.qml index c167813425..b9ffa395d6 100644 --- a/resources/qml/Account/UserOperations.qml +++ b/resources/qml/Account/UserOperations.qml @@ -11,20 +11,16 @@ Row { spacing: UM.Theme.getSize("default_margin").width - Cura.ActionButton + Cura.SecondaryButton { width: UM.Theme.getSize("account_button").width height: UM.Theme.getSize("account_button").height text: catalog.i18nc("@button", "Manage account") - color: UM.Theme.getColor("secondary") - hoverColor: UM.Theme.getColor("secondary") - textColor: UM.Theme.getColor("main_window_header_button_text_active") - textHoverColor: UM.Theme.getColor("main_window_header_button_text_active") onClicked: Qt.openUrlExternally("https://account.ultimaker.com") fixedWidthMode: true } - Cura.ActionButton + Cura.PrimaryButton { width: UM.Theme.getSize("account_button").width height: UM.Theme.getSize("account_button").height diff --git a/resources/qml/ActionPanel/OutputDevicesActionButton.qml b/resources/qml/ActionPanel/OutputDevicesActionButton.qml index 9682dddf14..d24d440241 100644 --- a/resources/qml/ActionPanel/OutputDevicesActionButton.qml +++ b/resources/qml/ActionPanel/OutputDevicesActionButton.qml @@ -12,13 +12,12 @@ Item { id: widget - Cura.ActionButton + Cura.PrimaryButton { id: saveToButton height: parent.height fixedWidthMode: true - shadowEnabled: true - shadowColor: UM.Theme.getColor("primary_shadow") + anchors { top: parent.top diff --git a/resources/qml/ActionPanel/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml index 79b9898e49..ddbe709a84 100644 --- a/resources/qml/ActionPanel/OutputProcessWidget.qml +++ b/resources/qml/ActionPanel/OutputProcessWidget.qml @@ -101,18 +101,13 @@ Column spacing: UM.Theme.getSize("default_margin").width width: parent.width - Cura.ActionButton + Cura.SecondaryButton { id: previewStageShortcut - leftPadding: UM.Theme.getSize("default_margin").width - rightPadding: UM.Theme.getSize("default_margin").width height: UM.Theme.getSize("action_panel_button").height text: catalog.i18nc("@button", "Preview") - color: UM.Theme.getColor("secondary") - hoverColor: UM.Theme.getColor("secondary") - textColor: UM.Theme.getColor("primary") - textHoverColor: UM.Theme.getColor("text") + onClicked: UM.Controller.setActiveStage("PreviewStage") visible: UM.Controller.activeStage != null && UM.Controller.activeStage.stageId != "PreviewStage" diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index 9a9f40ffac..199b94ab33 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -81,36 +81,41 @@ Column } } - Cura.ActionButton - { - id: prepareButton - width: parent.width - height: UM.Theme.getSize("action_panel_button").height - fixedWidthMode: true + Item + { + id: prepareButtons // Get the current value from the preferences property bool autoSlice: UM.Preferences.getValue("general/auto_slice") // Disable the slice process when - property bool disabledSlice: [UM.Backend.Done, UM.Backend.Error].indexOf(widget.backendState) != -1 - property bool isSlicing: [UM.Backend.NotStarted, UM.Backend.Error].indexOf(widget.backendState) == -1 - - text: isSlicing ? catalog.i18nc("@button", "Cancel") : catalog.i18nc("@button", "Slice") - - enabled: !autoSlice && !disabledSlice + width: parent.width + height: UM.Theme.getSize("action_panel_button").height visible: !autoSlice + Cura.PrimaryButton + { + id: sliceButton + fixedWidthMode: true + anchors.fill: parent + text: catalog.i18nc("@button", "Slice") + enabled: !autoSlice && widget.backendState != UM.Backend.Error + visible: widget.backendState == UM.Backend.NotStarted || widget.backendState == UM.Backend.Error + onClicked: sliceOrStopSlicing() + } - color: isSlicing ? UM.Theme.getColor("secondary"): UM.Theme.getColor("primary") - textColor: isSlicing ? UM.Theme.getColor("primary"): UM.Theme.getColor("button_text") - outlineColor: "transparent" - disabledColor: UM.Theme.getColor("action_button_disabled") - textDisabledColor: UM.Theme.getColor("action_button_disabled_text") - shadowEnabled: true - shadowColor: isSlicing ? UM.Theme.getColor("secondary_shadow") : enabled ? UM.Theme.getColor("action_button_shadow"): UM.Theme.getColor("action_button_disabled_shadow") - - onClicked: sliceOrStopSlicing() + Cura.SecondaryButton + { + id: cancelButton + fixedWidthMode: true + anchors.fill: parent + text: catalog.i18nc("@button", "Cancel") + enabled: sliceButton.enabled + visible: !sliceButton.visible + onClicked: sliceOrStopSlicing() + } } + // React when the user changes the preference of having the auto slice enabled Connections { @@ -118,7 +123,7 @@ Column onPreferenceChanged: { var autoSlice = UM.Preferences.getValue("general/auto_slice") - prepareButton.autoSlice = autoSlice + prepareButtons.autoSlice = autoSlice } } diff --git a/resources/qml/PrimaryButton.qml b/resources/qml/PrimaryButton.qml new file mode 100644 index 0000000000..8450e524e2 --- /dev/null +++ b/resources/qml/PrimaryButton.qml @@ -0,0 +1,18 @@ +import QtQuick 2.2 +import QtQuick.Controls 1.1 + +import UM 1.4 as UM +import Cura 1.1 as Cura + + +Cura.ActionButton +{ + shadowEnabled: true + shadowColor: enabled ? UM.Theme.getColor("primary_button_shadow"): UM.Theme.getColor("action_button_disabled_shadow") + color: UM.Theme.getColor("primary_button") + textColor: UM.Theme.getColor("primary_button_text") + outlineColor: "transparent" + disabledColor: UM.Theme.getColor("action_button_disabled") + textDisabledColor: UM.Theme.getColor("action_button_disabled_text") + hoverColor: UM.Theme.getColor("primary_button_hover") +} \ No newline at end of file diff --git a/resources/qml/SecondaryButton.qml b/resources/qml/SecondaryButton.qml new file mode 100644 index 0000000000..0e6b79b3a7 --- /dev/null +++ b/resources/qml/SecondaryButton.qml @@ -0,0 +1,18 @@ +import QtQuick 2.2 +import QtQuick.Controls 1.1 + +import UM 1.4 as UM +import Cura 1.1 as Cura + + +Cura.ActionButton +{ + shadowEnabled: true + shadowColor: enabled ? UM.Theme.getColor("secondary_button_shadow"): UM.Theme.getColor("action_button_disabled_shadow") + color: UM.Theme.getColor("secondary_button") + textColor: UM.Theme.getColor("secondary_button_text") + outlineColor: "transparent" + disabledColor: UM.Theme.getColor("action_button_disabled") + textDisabledColor: UM.Theme.getColor("action_button_disabled_text") + hoverColor: UM.Theme.getColor("secondary_button_hover") +} \ No newline at end of file diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 888bc9bfa6..cbdc37caa1 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -90,6 +90,16 @@ "secondary": [245, 245, 245, 255], "secondary_shadow": [228, 228, 228, 255], + "primary_button": [38,113,231,255], + "primary_button_shadow": [27,95,202, 255], + "primary_button_hover": [81,145,247, 255], + "primary_button_text": [255, 255, 255, 255], + + "secondary_button": [240,240,240, 255], + "secondary_button_shadow": [228, 228, 228, 255], + "secondary_button_hover": [228,228,228, 255], + "secondary_button_text": [30,102,215, 255], + "main_window_header_background": [10, 8, 80, 255], "main_window_header_button_text_active": [10, 8, 80, 255], "main_window_header_button_text_inactive": [255, 255, 255, 255], From 9e92542eeec397440f2f383d68650c291e30c8d7 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Sun, 25 Nov 2018 18:14:01 +0100 Subject: [PATCH 0383/1292] Fix the height of the IconLabel to avoid getting binding loops. Contributes to CURA-5942. --- resources/qml/ActionPanel/OutputProcessWidget.qml | 2 -- resources/qml/ActionPanel/SliceProcessWidget.qml | 1 - resources/qml/IconLabel.qml | 2 ++ 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/resources/qml/ActionPanel/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml index 87f9d2015d..3c4386f079 100644 --- a/resources/qml/ActionPanel/OutputProcessWidget.qml +++ b/resources/qml/ActionPanel/OutputProcessWidget.qml @@ -47,7 +47,6 @@ Column { id: estimatedTime width: parent.width - height: childrenRect.height text: PrintInformation.currentPrintTime.getDisplayString(UM.DurationFormat.Long) source: UM.Theme.getIcon("clock") @@ -58,7 +57,6 @@ Column { id: estimatedCosts width: parent.width - height: childrenRect.height property var printMaterialLengths: PrintInformation.materialLengths property var printMaterialWeights: PrintInformation.materialWeights diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index 9c46539220..2d4a7b6b89 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -44,7 +44,6 @@ Column { id: message width: parent.width - height: childrenRect.height visible: widget.backendState == UM.Backend.Error text: catalog.i18nc("@label:PrintjobStatus", "Unable to Slice") diff --git a/resources/qml/IconLabel.qml b/resources/qml/IconLabel.qml index 90930e91c7..0941254e7b 100644 --- a/resources/qml/IconLabel.qml +++ b/resources/qml/IconLabel.qml @@ -18,6 +18,8 @@ Item property alias font: label.font property alias iconSize: icon.width + implicitHeight: icon.height + UM.RecolorImage { id: icon From f3bf20ca1b8f17a9b63aa14f57df56a2e17b95f4 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Sun, 25 Nov 2018 18:24:21 +0100 Subject: [PATCH 0384/1292] Separate the view selector into a different file. --- plugins/PreviewStage/PreviewMenu.qml | 72 +--------------- .../qml/PrinterSelector/MachineSelector.qml | 2 - resources/qml/ViewsSelector.qml | 82 +++++++++++++++++++ resources/qml/qmldir | 3 +- 4 files changed, 86 insertions(+), 73 deletions(-) create mode 100644 resources/qml/ViewsSelector.qml diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index d660db549b..a1f59cd4ca 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -29,80 +29,12 @@ Item anchors.centerIn: parent height: parent.height - Cura.ExpandableComponent + Cura.ViewsSelector { - id: viewSelector - iconSource: expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") + id: viewsSelector height: parent.height width: UM.Theme.getSize("views_selector").width headerCornerSide: Cura.RoundedRectangle.Direction.Left - - property var viewModel: UM.ViewModel { } - - property var activeView: - { - for (var i = 0; i < viewModel.rowCount(); i++) - { - if (viewModel.items[i].active) - { - return viewModel.items[i] - } - } - return null - } - - Component.onCompleted: - { - // Nothing was active, so just return the first one (the list is sorted by priority, so the most - // important one should be returned) - if (activeView == null) - { - UM.Controller.setActiveView(viewModel.getItem(0).id) - } - } - - headerItem: Label - { - text: viewSelector.activeView ? viewSelector.activeView.name : "" - verticalAlignment: Text.AlignVCenter - height: parent.height - elide: Text.ElideRight - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - renderType: Text.NativeRendering - } - - popupItem: Column - { - id: viewSelectorPopup - width: viewSelector.width - 2 * UM.Theme.getSize("default_margin").width - - // For some reason the height/width of the column gets set to 0 if this is not set... - Component.onCompleted: - { - height = implicitHeight - width = viewSelector.width - 2 * UM.Theme.getSize("default_margin").width - } - - Repeater - { - id: viewsList - model: viewSelector.viewModel - RoundButton - { - text: name - radius: UM.Theme.getSize("default_radius").width - checkable: true - checked: viewSelector.activeView != null ? viewSelector.activeView.id == id : false - onClicked: - { - viewSelector.togglePopup() - UM.Controller.setActiveView(id) - } - } - } - - } } // Separator line diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index c73836ad6a..b14734dfb1 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -3,8 +3,6 @@ import QtQuick 2.7 import QtQuick.Controls 2.3 -import QtQuick.Controls.Styles 1.1 -import QtQuick.Layouts 1.1 import UM 1.2 as UM import Cura 1.0 as Cura diff --git a/resources/qml/ViewsSelector.qml b/resources/qml/ViewsSelector.qml new file mode 100644 index 0000000000..0e11cccc5a --- /dev/null +++ b/resources/qml/ViewsSelector.qml @@ -0,0 +1,82 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.3 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +Cura.ExpandableComponent +{ + id: viewSelector + + iconSource: expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") + + property var viewModel: UM.ViewModel { } + + property var activeView: + { + for (var i = 0; i < viewModel.rowCount(); i++) + { + if (viewModel.items[i].active) + { + return viewModel.items[i] + } + } + return null + } + + Component.onCompleted: + { + // Nothing was active, so just return the first one (the list is sorted by priority, so the most + // important one should be returned) + if (activeView == null) + { + UM.Controller.setActiveView(viewModel.getItem(0).id) + } + } + + headerItem: Label + { + text: viewSelector.activeView ? viewSelector.activeView.name : "" + verticalAlignment: Text.AlignVCenter + height: parent.height + elide: Text.ElideRight + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + renderType: Text.NativeRendering + } + + popupItem: Column + { + id: viewSelectorPopup + width: viewSelector.width - 2 * UM.Theme.getSize("default_margin").width + + // For some reason the height/width of the column gets set to 0 if this is not set... + Component.onCompleted: + { + height = implicitHeight + width = viewSelector.width - 2 * UM.Theme.getSize("default_margin").width + } + + Repeater + { + id: viewsList + model: viewSelector.viewModel + RoundButton + { + text: name + radius: UM.Theme.getSize("default_radius").width + checkable: true + checked: viewSelector.activeView != null ? viewSelector.activeView.id == id : false + onClicked: + { + viewSelector.togglePopup() + UM.Controller.setActiveView(id) + } + } + } + + } +} \ No newline at end of file diff --git a/resources/qml/qmldir b/resources/qml/qmldir index 67388100ca..43ae4411af 100644 --- a/resources/qml/qmldir +++ b/resources/qml/qmldir @@ -11,4 +11,5 @@ ActionPanelWidget 1.0 ActionPanelWidget.qml IconLabel 1.0 IconLabel.qml OutputDevicesActionButton 1.0 OutputDevicesActionButton.qml ExpandableComponent 1.0 ExpandableComponent.qml -PrinterTypeLabel 1.0 PrinterTypeLabel.qml \ No newline at end of file +PrinterTypeLabel 1.0 PrinterTypeLabel.qml +ViewsSelector 1.0 ViewsSelector.qml \ No newline at end of file From 68c96a25775c6be13bdcdba64544e68837cc41c2 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Sun, 25 Nov 2018 19:42:00 +0100 Subject: [PATCH 0385/1292] Modify the header item of the view selector. --- resources/qml/ViewsSelector.qml | 36 +++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/resources/qml/ViewsSelector.qml b/resources/qml/ViewsSelector.qml index 0e11cccc5a..b9048803a2 100644 --- a/resources/qml/ViewsSelector.qml +++ b/resources/qml/ViewsSelector.qml @@ -37,15 +37,35 @@ Cura.ExpandableComponent } } - headerItem: Label + headerItem: Item { - text: viewSelector.activeView ? viewSelector.activeView.name : "" - verticalAlignment: Text.AlignVCenter - height: parent.height - elide: Text.ElideRight - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - renderType: Text.NativeRendering + Label + { + id: title + text: catalog.i18nc("@button", "View types") + verticalAlignment: Text.AlignVCenter + height: parent.height + elide: Text.ElideRight + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text_medium") + renderType: Text.NativeRendering + } + + Label + { + text: viewSelector.activeView ? viewSelector.activeView.name : "" + verticalAlignment: Text.AlignVCenter + anchors + { + left: title.right + leftMargin: UM.Theme.getSize("default_margin").width + } + height: parent.height + elide: Text.ElideRight + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + renderType: Text.NativeRendering + } } popupItem: Column From c5d0ed26513e12045b2fb84d6408a79f729a81df Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Sun, 25 Nov 2018 20:13:56 +0100 Subject: [PATCH 0386/1292] Define the look and feel of the view selector button. Adjust the sizes. --- .../qml/PrinterSelector/MachineSelector.qml | 5 +-- resources/qml/ViewsSelector.qml | 39 ++++++++++++++++--- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index b14734dfb1..b6657f112e 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -15,7 +15,7 @@ Cura.ExpandableComponent property bool isPrinterConnected: Cura.MachineManager.printerConnected property var outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null - popupPadding: 0 + popupPadding: UM.Theme.getSize("default_lining").width popupAlignment: Cura.ExpandableComponent.PopupAlignment.AlignLeft iconSource: expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") @@ -90,8 +90,7 @@ Cura.ExpandableComponent MachineSelectorList { // Can't use parent.width since the parent is the flickable component and not the ScrollView - width: scroll.width - 2 * UM.Theme.getSize("default_lining").width - x: UM.Theme.getSize("default_lining").width + width: scroll.width property real maximumHeight: UM.Theme.getSize("machine_selector_widget_content").height - buttonRow.height onHeightChanged: diff --git a/resources/qml/ViewsSelector.qml b/resources/qml/ViewsSelector.qml index b9048803a2..e9fdd57177 100644 --- a/resources/qml/ViewsSelector.qml +++ b/resources/qml/ViewsSelector.qml @@ -11,6 +11,8 @@ Cura.ExpandableComponent { id: viewSelector + popupPadding: UM.Theme.getSize("default_lining").width + popupAlignment: Cura.ExpandableComponent.PopupAlignment.AlignLeft iconSource: expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") property var viewModel: UM.ViewModel { } @@ -71,25 +73,51 @@ Cura.ExpandableComponent popupItem: Column { id: viewSelectorPopup - width: viewSelector.width - 2 * UM.Theme.getSize("default_margin").width + width: viewSelector.width - 2 * viewSelector.popupPadding // For some reason the height/width of the column gets set to 0 if this is not set... Component.onCompleted: { height = implicitHeight - width = viewSelector.width - 2 * UM.Theme.getSize("default_margin").width + width = viewSelector.width - 2 * viewSelector.popupPadding } Repeater { id: viewsList model: viewSelector.viewModel - RoundButton + + delegate: Button { - text: name - radius: UM.Theme.getSize("default_radius").width + id: viewsSelectorButton + text: model.name + width: parent.width + height: UM.Theme.getSize("action_button").height + leftPadding: UM.Theme.getSize("default_margin").width + rightPadding: UM.Theme.getSize("default_margin").width checkable: true checked: viewSelector.activeView != null ? viewSelector.activeView.id == id : false + + contentItem: Label + { + id: buttonText + text: viewsSelectorButton.text + color: UM.Theme.getColor("text") + font: UM.Theme.getFont("action_button") + renderType: Text.NativeRendering + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + + background: Rectangle + { + id: backgroundRect + color: viewsSelectorButton.hovered ? UM.Theme.getColor("action_button_hovered") : "transparent" + radius: UM.Theme.getSize("action_button_radius").width + border.width: UM.Theme.getSize("default_lining").width + border.color: viewsSelectorButton.checked ? UM.Theme.getColor("primary") : "transparent" + } + onClicked: { viewSelector.togglePopup() @@ -97,6 +125,5 @@ Cura.ExpandableComponent } } } - } } \ No newline at end of file From 8f9d6bee6243f32c9d966202e1f9a4ea5086b611 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 26 Nov 2018 08:30:24 +0100 Subject: [PATCH 0387/1292] Document dependency on fdm_materials Without it, Cura simply won't start if you had a printer loaded with material profiles. Fixes #4460. --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 70466e9c22..93abcc0c61 100644 --- a/README.md +++ b/README.md @@ -20,8 +20,9 @@ Dependencies ------------ * [Uranium](https://github.com/Ultimaker/Uranium) Cura is built on top of the Uranium framework. * [CuraEngine](https://github.com/Ultimaker/CuraEngine) This will be needed at runtime to perform the actual slicing. +* [fdm_materials](https://github.com/Ultimaker/fdm_materials) Required to load a printer that has swappable material profiles. * [PySerial](https://github.com/pyserial/pyserial) Only required for USB printing support. -* [python-zeroconf](https://github.com/jstasiak/python-zeroconf) Only required to detect mDNS-enabled printers +* [python-zeroconf](https://github.com/jstasiak/python-zeroconf) Only required to detect mDNS-enabled printers. Build scripts ------------- From c9eb57ceade38f567fc49f5e5ad0f6f1c8913d79 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 26 Nov 2018 09:32:59 +0100 Subject: [PATCH 0388/1292] Don't copy preference file to the same location This crashes Cura on start-up for some people. --- cura/Backups/Backup.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cura/Backups/Backup.py b/cura/Backups/Backup.py index 897d5fa979..80681acb4f 100644 --- a/cura/Backups/Backup.py +++ b/cura/Backups/Backup.py @@ -46,12 +46,13 @@ class Backup: # We copy the preferences file to the user data directory in Linux as it's in a different location there. # When restoring a backup on Linux, we move it back. - if Platform.isLinux(): + if Platform.isLinux(): #TODO: This should check for the config directory not being the same as the data directory, rather than hard-coding that to Linux systems. preferences_file_name = self._application.getApplicationName() preferences_file = Resources.getPath(Resources.Preferences, "{}.cfg".format(preferences_file_name)) backup_preferences_file = os.path.join(version_data_dir, "{}.cfg".format(preferences_file_name)) - Logger.log("d", "Copying preferences file from %s to %s", preferences_file, backup_preferences_file) - shutil.copyfile(preferences_file, backup_preferences_file) + if not os.path.samefile(preferences_file, backup_preferences_file): + Logger.log("d", "Copying preferences file from %s to %s", preferences_file, backup_preferences_file) + shutil.copyfile(preferences_file, backup_preferences_file) # Create an empty buffer and write the archive to it. buffer = io.BytesIO() From 09af7a9435178bc9a6e811c7ade4889880a745f9 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 26 Nov 2018 09:34:27 +0100 Subject: [PATCH 0389/1292] Slice button will now be disabled on error CURA-5959 --- resources/qml/ActionPanel/SliceProcessWidget.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index 199b94ab33..05a9345585 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -42,7 +42,7 @@ Column Cura.IconLabel { - id: message + id: unableToSliceMessage width: parent.width visible: widget.backendState == UM.Backend.Error @@ -98,7 +98,7 @@ Column fixedWidthMode: true anchors.fill: parent text: catalog.i18nc("@button", "Slice") - enabled: !autoSlice && widget.backendState != UM.Backend.Error + enabled: widget.backendState != UM.Backend.Error visible: widget.backendState == UM.Backend.NotStarted || widget.backendState == UM.Backend.Error onClicked: sliceOrStopSlicing() } From 5469613c17c0caa34b58750a1aeeb664333886ca Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 26 Nov 2018 09:40:14 +0100 Subject: [PATCH 0390/1292] Don't fail the samefile check if second file didn't exist If the backup file didn't exist but the original did, then apparently they are not the same file so the copy should be allowed. --- cura/Backups/Backup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Backups/Backup.py b/cura/Backups/Backup.py index 80681acb4f..714d6527fe 100644 --- a/cura/Backups/Backup.py +++ b/cura/Backups/Backup.py @@ -50,7 +50,7 @@ class Backup: preferences_file_name = self._application.getApplicationName() preferences_file = Resources.getPath(Resources.Preferences, "{}.cfg".format(preferences_file_name)) backup_preferences_file = os.path.join(version_data_dir, "{}.cfg".format(preferences_file_name)) - if not os.path.samefile(preferences_file, backup_preferences_file): + if os.path.exists(preferences_file) and (not os.path.exists(backup_preferences_file) or not os.path.samefile(preferences_file, backup_preferences_file)): Logger.log("d", "Copying preferences file from %s to %s", preferences_file, backup_preferences_file) shutil.copyfile(preferences_file, backup_preferences_file) From c8e065d7a78f3d62b26cded3cd0063e5a05fead4 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 26 Nov 2018 10:21:15 +0100 Subject: [PATCH 0391/1292] Fix code-style Contributes to CURA-5942. Co-Authored-By: diegopradogesto --- resources/qml/ExpandableComponent.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index 80c65f12a7..ccfb9c6da2 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -12,7 +12,8 @@ Item id: base // Enumeration with the different possible alignments of the popup with respect of the headerItem - enum PopupAlignment { + enum PopupAlignment + { AlignLeft, AlignRight } From 5b940b524204ca56b5fafe05bad28d5e477b8ea7 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 26 Nov 2018 10:28:36 +0100 Subject: [PATCH 0392/1292] Use thick margin and change some anchors. Contributes to CURA-5942. --- resources/qml/PrinterSelector/MachineSelector.qml | 8 ++++++-- resources/qml/PrinterSelector/MachineSelectorButton.qml | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index b6657f112e..d721ed5b83 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -48,8 +48,12 @@ Cura.ExpandableComponent { id: icon - anchors.bottom: parent.bottom - x: UM.Theme.getSize("thick_margin").width + anchors + { + bottom: parent.bottom + left: parent.left + leftMargin: UM.Theme.getSize("thick_margin").width + } source: UM.Theme.getIcon("printer_connected") width: UM.Theme.getSize("printer_status_icon").width diff --git a/resources/qml/PrinterSelector/MachineSelectorButton.qml b/resources/qml/PrinterSelector/MachineSelectorButton.qml index e7b44a4447..fef6867e35 100644 --- a/resources/qml/PrinterSelector/MachineSelectorButton.qml +++ b/resources/qml/PrinterSelector/MachineSelectorButton.qml @@ -13,8 +13,8 @@ Button width: parent.width height: UM.Theme.getSize("action_button").height - leftPadding: Math.round(1.5 * UM.Theme.getSize("default_margin").width) - rightPadding: Math.round(1.5 * UM.Theme.getSize("default_margin").width) + leftPadding: UM.Theme.getSize("thick_margin").width + rightPadding: UM.Theme.getSize("thick_margin").width checkable: true property var outputDevice: null From 908628e2aadcff72826e099577049be0a6287a8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Mon, 26 Nov 2018 10:47:53 +0100 Subject: [PATCH 0393/1292] Added a model to represent a cluster --- .../src/Cloud/CloudOutputDeviceManager.py | 32 +++++++++++-------- .../UM3NetworkPrinting/src/Cloud/Models.py | 11 +++++++ 2 files changed, 29 insertions(+), 14 deletions(-) create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Models.py diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 8459527d39..e93393d736 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -8,7 +8,8 @@ from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply from UM.Logger import Logger from cura.NetworkClient import NetworkClient from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputDevice import CloudOutputDevice - +from .Models import Cluster + ## The cloud output device manager is responsible for using the Ultimaker Cloud APIs to manage remote clusters. # Keeping all cloud related logic in this class instead of the UM3OutputDevicePlugin results in more readable code. @@ -60,35 +61,38 @@ class CloudOutputDeviceManager(NetworkClient): return # Parse the response (returns the "data" field from the body). - clusters_data = self._parseStatusResponse(reply) - if not clusters_data: + clusters = self._parseStatusResponse(reply) + if not clusters: return # Add an output device for each remote cluster. # The clusters are an array of objects in a field called "data". - for cluster in clusters_data: + for cluster in clusters: self._addCloudOutputDevice(cluster) # # For testing we add a dummy device: # self._addCloudOutputDevice({ "cluster_id": "LJ0tciiuZZjarrXAvFLEZ6ox4Cvx8FvtXUlQv4vIhV6w" }) @staticmethod - def _parseStatusResponse(reply: QNetworkReply) -> Optional[dict]: + def _parseStatusResponse(reply: QNetworkReply) -> Optional[Cluster]: try: - result = json.loads(bytes(reply.readAll()).decode("utf-8")) - # TODO: use model or named tuple here. - return result.data + return [Cluster(**c) for c in json.loads(reply.readAll().data().decode("utf-8"))] except json.decoder.JSONDecodeError: Logger.logException("w", "Unable to decode JSON from reply.") return None - + except UnicodeDecodeError: + Logger.log("e", "Unable to read server response") + except json.JSONDecodeError: + Logger.logException("w", "Unable to decode JSON from reply.") + + return None + ## Adds a CloudOutputDevice for each entry in the remote cluster list from the API. - def _addCloudOutputDevice(self, cluster_data: Dict[str, any]): - # TODO: use model or named tuple for cluster_data - print("cluster_data====", cluster_data) - device = CloudOutputDevice(cluster_data["cluster_id"]) + def _addCloudOutputDevice(self, cluster: Cluster): + print("cluster_data====", cluster) + device = CloudOutputDevice(cluster["cluster_id"]) self._output_device_manager.addOutputDevice(device) - self._remote_clusters[cluster_data["cluster_id"]] = device + self._remote_clusters[cluster["cluster_id"]] = device ## Callback for when the active machine was changed by the user. def _activeMachineChanged(self): diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models.py b/plugins/UM3NetworkPrinting/src/Cloud/Models.py new file mode 100644 index 0000000000..7d9bba32f7 --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models.py @@ -0,0 +1,11 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +from collections import namedtuple + +Cluster = namedtuple("Cluster", [ + "cluster_id", # Type: str + "host_guid", # Type: str + "host_name", # Type: str + "host_version", # Type: str + "status", # Type: str +]) \ No newline at end of file From 63fab9f038e8615432a8c592138e915351131386 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 26 Nov 2018 10:49:43 +0100 Subject: [PATCH 0394/1292] Use theme sizes. Contributes to CURA-5942. --- resources/qml/PrinterSelector/MachineSelector.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index d721ed5b83..120ce02edd 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -71,8 +71,8 @@ Cura.ExpandableComponent id: iconBackground anchors.centerIn: parent // Make it a bit bigger so there is an outline - width: parent.width + 2 - height: parent.height + 2 + width: parent.width + 2 * UM.Theme.getSize("default_lining").width + height: parent.height + 2 * UM.Theme.getSize("default_lining").height radius: Math.round(width / 2) color: UM.Theme.getColor("main_background") z: parent.z - 1 From fa1ef5c45c70ebdebaef3d9d19b026e6586523b2 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 26 Nov 2018 10:51:08 +0100 Subject: [PATCH 0395/1292] Rename function name to be more clear to what it does. Contributes to CURA-5942. --- resources/qml/PrinterSelector/MachineSelectorButton.qml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/qml/PrinterSelector/MachineSelectorButton.qml b/resources/qml/PrinterSelector/MachineSelectorButton.qml index fef6867e35..992ea55b1d 100644 --- a/resources/qml/PrinterSelector/MachineSelectorButton.qml +++ b/resources/qml/PrinterSelector/MachineSelectorButton.qml @@ -20,7 +20,7 @@ Button property var outputDevice: null property var printerTypesList: [] - function setPrinterTypesList() + function updatePrinterTypesList() { printerTypesList = (checked && (outputDevice != null)) ? outputDevice.uniquePrinterTypes : [] } @@ -97,14 +97,14 @@ Button Connections { target: outputDevice - onUniqueConfigurationsChanged: setPrinterTypesList() + onUniqueConfigurationsChanged: updatePrinterTypesList() } Connections { target: Cura.MachineManager - onOutputDevicesChanged: setPrinterTypesList() + onOutputDevicesChanged: updatePrinterTypesList() } - Component.onCompleted: setPrinterTypesList() + Component.onCompleted: updatePrinterTypesList() } From 4990f205662aeba91bce43c57fe41a94abd1d545 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 26 Nov 2018 10:55:32 +0100 Subject: [PATCH 0396/1292] Use QStringList instead of QVariantList since the return value is a list of strings. Co-Authored-By: diegopradogesto --- cura/PrinterOutputDevice.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index f8a663f0e4..99c48189cc 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -212,7 +212,7 @@ class PrinterOutputDevice(QObject, OutputDevice): self.uniqueConfigurationsChanged.emit() # Returns the unique configurations of the printers within this output device - @pyqtProperty("QVariantList", notify = uniqueConfigurationsChanged) + @pyqtProperty("QStringList", notify = uniqueConfigurationsChanged) def uniquePrinterTypes(self) -> List[str]: return list(set([configuration.printerType for configuration in self._unique_configurations])) @@ -243,4 +243,4 @@ class PrinterOutputDevice(QObject, OutputDevice): if not self._firmware_updater: return - self._firmware_updater.updateFirmware(firmware_file) \ No newline at end of file + self._firmware_updater.updateFirmware(firmware_file) From 21bfa6e4c20819e09b8cb2f27f62427dc71c8476 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 26 Nov 2018 10:58:38 +0100 Subject: [PATCH 0397/1292] Fix code style. Add brackets in new line. Contributes to CURA-5942. --- resources/qml/PrinterSelector/MachineSelectorList.qml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/resources/qml/PrinterSelector/MachineSelectorList.qml b/resources/qml/PrinterSelector/MachineSelectorList.qml index 11a61194b7..5ef04b7351 100644 --- a/resources/qml/PrinterSelector/MachineSelectorList.qml +++ b/resources/qml/PrinterSelector/MachineSelectorList.qml @@ -30,7 +30,10 @@ Column model: UM.ContainerStacksModel { id: networkedPrintersModel - filter: {"type": "machine", "um_network_key": "*", "hidden": "False"} + filter: + { + "type": "machine", "um_network_key": "*", "hidden": "False" + } } delegate: MachineSelectorButton @@ -66,7 +69,10 @@ Column model: UM.ContainerStacksModel { id: virtualPrintersModel - filter: {"type": "machine", "um_network_key": null} + filter: + { + "type": "machine", "um_network_key": null + } } delegate: MachineSelectorButton From 72d972c8b428e8ad8d6bf0b831b67d6301058049 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 26 Nov 2018 11:03:58 +0100 Subject: [PATCH 0398/1292] Remove PrinterStatusIcon that is not used anymore. Contributes to CURA-5942. --- resources/qml/Menus/PrinterStatusIcon.qml | 27 ----------------------- 1 file changed, 27 deletions(-) delete mode 100644 resources/qml/Menus/PrinterStatusIcon.qml diff --git a/resources/qml/Menus/PrinterStatusIcon.qml b/resources/qml/Menus/PrinterStatusIcon.qml deleted file mode 100644 index 6ff6b07af8..0000000000 --- a/resources/qml/Menus/PrinterStatusIcon.qml +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2017 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.2 - -import UM 1.2 as UM -import Cura 1.0 as Cura - -Item -{ - property var status: "disconnected" - width: childrenRect.width - height: childrenRect.height - UM.RecolorImage - { - id: statusIcon - width: UM.Theme.getSize("printer_status_icon").width - height: UM.Theme.getSize("printer_status_icon").height - sourceSize.width: width - sourceSize.height: width - color: UM.Theme.getColor("tab_status_" + parent.status) - source: UM.Theme.getIcon(parent.status) - } -} - - - From 5397cda2b4d3077a76ca5a3d9444e09cf386a318 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 26 Nov 2018 12:00:06 +0100 Subject: [PATCH 0399/1292] Add a label to the action panel when auto slice is ON, indicating that the process runs automatically. Contributes to CURA-5942. --- resources/qml/ActionPanel/SliceProcessWidget.qml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index 05a9345585..3329ac4b23 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -40,6 +40,18 @@ Column } } + Label + { + id: autoSlicingLabel + width: parent.width + visible: prepareButtons.autoSlice && widget.backendState == UM.Backend.Processing + + text: catalog.i18nc("@label:PrintjobStatus", "Auto slicing...") + color: UM.Theme.getColor("text") + font: UM.Theme.getFont("very_small") + renderType: Text.NativeRendering + } + Cura.IconLabel { id: unableToSliceMessage From 845b3209819f8e7b1449c15118c6c995b2c548c3 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 26 Nov 2018 13:08:30 +0100 Subject: [PATCH 0400/1292] Fix adjustable monitor component width CURA-5943 - Add rounding - If there's no sidebar, use full width --- plugins/MonitorStage/MonitorMainView.qml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/MonitorStage/MonitorMainView.qml b/plugins/MonitorStage/MonitorMainView.qml index 57dd033792..f5696bbf54 100644 --- a/plugins/MonitorStage/MonitorMainView.qml +++ b/plugins/MonitorStage/MonitorMainView.qml @@ -38,7 +38,10 @@ Item anchors.bottom: parent.bottom anchors.left: parent.left - width: parent.width * 0.7 + // If the sidebar is not set, the view should take the complete space. + property var widthFactor: monitorSidebarComponent.source == "" ? 1.0 : 0.7 + + width: Math.round(parent.width * widthFactor) height: parent.height property real maximumWidth: parent.width From 6bb010e74a09a95c68bc9010cfcf8ea9dfffb454 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 26 Nov 2018 13:14:24 +0100 Subject: [PATCH 0401/1292] Move MonitorButtonStyle to styles.qml CURA-5943 --- .../PrinterOutput/ManualPrinterControl.qml | 21 ++--- .../qml/PrinterOutput/MonitorButtonStyle.qml | 88 ------------------- resources/themes/cura-light/styles.qml | 80 +++++++++++++++++ 3 files changed, 88 insertions(+), 101 deletions(-) delete mode 100644 resources/qml/PrinterOutput/MonitorButtonStyle.qml diff --git a/resources/qml/PrinterOutput/ManualPrinterControl.qml b/resources/qml/PrinterOutput/ManualPrinterControl.qml index 1a719c379e..5d07bd5fc8 100644 --- a/resources/qml/PrinterOutput/ManualPrinterControl.qml +++ b/resources/qml/PrinterOutput/ManualPrinterControl.qml @@ -21,11 +21,6 @@ Item implicitWidth: parent.width implicitHeight: childrenRect.height - MonitorButtonStyle - { - id: monitorButtonStyle - } - Column { enabled: @@ -108,7 +103,7 @@ Item Layout.preferredWidth: width Layout.preferredHeight: height iconSource: UM.Theme.getIcon("arrow_top"); - style: monitorButtonStyle + style: UM.Theme.styles.monitor_button_style width: height height: UM.Theme.getSize("setting_control").height @@ -125,7 +120,7 @@ Item Layout.preferredWidth: width Layout.preferredHeight: height iconSource: UM.Theme.getIcon("arrow_left"); - style: monitorButtonStyle + style: UM.Theme.styles.monitor_button_style width: height height: UM.Theme.getSize("setting_control").height @@ -142,7 +137,7 @@ Item Layout.preferredWidth: width Layout.preferredHeight: height iconSource: UM.Theme.getIcon("arrow_right"); - style: monitorButtonStyle + style: UM.Theme.styles.monitor_button_style width: height height: UM.Theme.getSize("setting_control").height @@ -159,7 +154,7 @@ Item Layout.preferredWidth: width Layout.preferredHeight: height iconSource: UM.Theme.getIcon("arrow_bottom"); - style: monitorButtonStyle + style: UM.Theme.styles.monitor_button_style width: height height: UM.Theme.getSize("setting_control").height @@ -176,7 +171,7 @@ Item Layout.preferredWidth: width Layout.preferredHeight: height iconSource: UM.Theme.getIcon("home"); - style: monitorButtonStyle + style: UM.Theme.styles.monitor_button_style width: height height: UM.Theme.getSize("setting_control").height @@ -206,7 +201,7 @@ Item Button { iconSource: UM.Theme.getIcon("arrow_top"); - style: monitorButtonStyle + style: UM.Theme.styles.monitor_button_style width: height height: UM.Theme.getSize("setting_control").height @@ -219,7 +214,7 @@ Item Button { iconSource: UM.Theme.getIcon("home"); - style: monitorButtonStyle + style: UM.Theme.styles.monitor_button_style width: height height: UM.Theme.getSize("setting_control").height @@ -232,7 +227,7 @@ Item Button { iconSource: UM.Theme.getIcon("arrow_bottom"); - style: monitorButtonStyle + style: UM.Theme.styles.monitor_button_style width: height height: UM.Theme.getSize("setting_control").height diff --git a/resources/qml/PrinterOutput/MonitorButtonStyle.qml b/resources/qml/PrinterOutput/MonitorButtonStyle.qml deleted file mode 100644 index 7bb1b91e55..0000000000 --- a/resources/qml/PrinterOutput/MonitorButtonStyle.qml +++ /dev/null @@ -1,88 +0,0 @@ -import QtQuick 2.10 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 -import QtQuick.Layouts 1.3 - -import UM 1.2 as UM -import Cura 1.0 as Cura - - -Component -{ - ButtonStyle - { - background: Rectangle - { - border.width: UM.Theme.getSize("default_lining").width - border.color: - { - if(!control.enabled) - { - return UM.Theme.getColor("action_button_disabled_border"); - } - else if(control.pressed) - { - return UM.Theme.getColor("action_button_active_border"); - } - else if(control.hovered) - { - return UM.Theme.getColor("action_button_hovered_border"); - } - return UM.Theme.getColor("action_button_border"); - } - color: - { - if(!control.enabled) - { - return UM.Theme.getColor("action_button_disabled"); - } - else if(control.pressed) - { - return UM.Theme.getColor("action_button_active"); - } - else if(control.hovered) - { - return UM.Theme.getColor("action_button_hovered"); - } - return UM.Theme.getColor("action_button"); - } - Behavior on color - { - ColorAnimation - { - duration: 50 - } - } - } - - label: Item - { - UM.RecolorImage - { - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.horizontalCenter - width: Math.floor(control.width / 2) - height: Math.floor(control.height / 2) - sourceSize.width: width - sourceSize.height: width - color: - { - if(!control.enabled) - { - return UM.Theme.getColor("action_button_disabled_text"); - } - else if(control.pressed) - { - return UM.Theme.getColor("action_button_active_text"); - } - else if(control.hovered) - { - return UM.Theme.getColor("action_button_hovered_text"); - } - return UM.Theme.getColor("action_button_text"); - } - source: control.iconSource - } - } - } -} diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index 723b393efa..ee9c530d9b 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -1200,4 +1200,84 @@ QtObject } } } + + property Component monitor_button_style: Component + { + ButtonStyle + { + background: Rectangle + { + border.width: UM.Theme.getSize("default_lining").width + border.color: + { + if(!control.enabled) + { + return UM.Theme.getColor("action_button_disabled_border"); + } + else if(control.pressed) + { + return UM.Theme.getColor("action_button_active_border"); + } + else if(control.hovered) + { + return UM.Theme.getColor("action_button_hovered_border"); + } + return UM.Theme.getColor("action_button_border"); + } + color: + { + if(!control.enabled) + { + return UM.Theme.getColor("action_button_disabled"); + } + else if(control.pressed) + { + return UM.Theme.getColor("action_button_active"); + } + else if(control.hovered) + { + return UM.Theme.getColor("action_button_hovered"); + } + return UM.Theme.getColor("action_button"); + } + Behavior on color + { + ColorAnimation + { + duration: 50 + } + } + } + + label: Item + { + UM.RecolorImage + { + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + width: Math.floor(control.width / 2) + height: Math.floor(control.height / 2) + sourceSize.width: width + sourceSize.height: width + color: + { + if(!control.enabled) + { + return UM.Theme.getColor("action_button_disabled_text"); + } + else if(control.pressed) + { + return UM.Theme.getColor("action_button_active_text"); + } + else if(control.hovered) + { + return UM.Theme.getColor("action_button_hovered_text"); + } + return UM.Theme.getColor("action_button_text"); + } + source: control.iconSource + } + } + } + } } From d6614941dc1b63aca417e0b27d9cc45c2e9477fe Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 26 Nov 2018 13:15:23 +0100 Subject: [PATCH 0402/1292] Update QtQuick import versions in styles.qml CURA-5943 --- resources/themes/cura-light/styles.qml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index ee9c530d9b..010e5564f1 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -1,9 +1,9 @@ // Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.1 -import QtQuick.Controls 1.1 -import QtQuick.Controls.Styles 1.1 +import QtQuick 2.10 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM From 6bed1c1390b33720621ae781668a93135f1a7fba Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 26 Nov 2018 13:21:52 +0100 Subject: [PATCH 0403/1292] Move monitor_checkable_button_style out to styles.qml CURA-5943 --- .../PrinterOutput/ManualPrinterControl.qml | 67 +----------------- resources/themes/cura-light/styles.qml | 70 +++++++++++++++++++ 2 files changed, 71 insertions(+), 66 deletions(-) diff --git a/resources/qml/PrinterOutput/ManualPrinterControl.qml b/resources/qml/PrinterOutput/ManualPrinterControl.qml index 5d07bd5fc8..106ae7db03 100644 --- a/resources/qml/PrinterOutput/ManualPrinterControl.qml +++ b/resources/qml/PrinterOutput/ManualPrinterControl.qml @@ -279,72 +279,7 @@ Item checked: distancesRow.currentDistance == model.value onClicked: distancesRow.currentDistance = model.value - style: ButtonStyle { - background: Rectangle { - border.width: control.checked ? UM.Theme.getSize("default_lining").width * 2 : UM.Theme.getSize("default_lining").width - border.color: - { - if(!control.enabled) - { - return UM.Theme.getColor("action_button_disabled_border"); - } - else if (control.checked || control.pressed) - { - return UM.Theme.getColor("action_button_active_border"); - } - else if(control.hovered) - { - return UM.Theme.getColor("action_button_hovered_border"); - } - return UM.Theme.getColor("action_button_border"); - } - color: - { - if(!control.enabled) - { - return UM.Theme.getColor("action_button_disabled"); - } - else if (control.checked || control.pressed) - { - return UM.Theme.getColor("action_button_active"); - } - else if (control.hovered) - { - return UM.Theme.getColor("action_button_hovered"); - } - return UM.Theme.getColor("action_button"); - } - Behavior on color { ColorAnimation { duration: 50; } } - Label { - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: UM.Theme.getSize("default_lining").width * 2 - anchors.rightMargin: UM.Theme.getSize("default_lining").width * 2 - color: - { - if(!control.enabled) - { - return UM.Theme.getColor("action_button_disabled_text"); - } - else if (control.checked || control.pressed) - { - return UM.Theme.getColor("action_button_active_text"); - } - else if (control.hovered) - { - return UM.Theme.getColor("action_button_hovered_text"); - } - return UM.Theme.getColor("action_button_text"); - } - font: UM.Theme.getFont("default") - text: control.text - horizontalAlignment: Text.AlignHCenter - elide: Text.ElideMiddle - } - } - label: Item { } - } + style: UM.Theme.styles.monitor_checkable_button_style } } } diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index 010e5564f1..f982b1eac8 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -1280,4 +1280,74 @@ QtObject } } } + + property Component monitor_checkable_button_style: Component + { + ButtonStyle { + background: Rectangle { + border.width: control.checked ? UM.Theme.getSize("default_lining").width * 2 : UM.Theme.getSize("default_lining").width + border.color: + { + if(!control.enabled) + { + return UM.Theme.getColor("action_button_disabled_border"); + } + else if (control.checked || control.pressed) + { + return UM.Theme.getColor("action_button_active_border"); + } + else if(control.hovered) + { + return UM.Theme.getColor("action_button_hovered_border"); + } + return UM.Theme.getColor("action_button_border"); + } + color: + { + if(!control.enabled) + { + return UM.Theme.getColor("action_button_disabled"); + } + else if (control.checked || control.pressed) + { + return UM.Theme.getColor("action_button_active"); + } + else if (control.hovered) + { + return UM.Theme.getColor("action_button_hovered"); + } + return UM.Theme.getColor("action_button"); + } + Behavior on color { ColorAnimation { duration: 50; } } + Label { + anchors.left: parent.left + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + anchors.leftMargin: UM.Theme.getSize("default_lining").width * 2 + anchors.rightMargin: UM.Theme.getSize("default_lining").width * 2 + color: + { + if(!control.enabled) + { + return UM.Theme.getColor("action_button_disabled_text"); + } + else if (control.checked || control.pressed) + { + return UM.Theme.getColor("action_button_active_text"); + } + else if (control.hovered) + { + return UM.Theme.getColor("action_button_hovered_text"); + } + return UM.Theme.getColor("action_button_text"); + } + font: UM.Theme.getFont("default") + text: control.text + horizontalAlignment: Text.AlignHCenter + elide: Text.ElideMiddle + } + } + label: Item { } + } + } } From eea6490e75cea6cd30555edc674bd58969fcd72b Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 26 Nov 2018 13:27:26 +0100 Subject: [PATCH 0404/1292] Hover of output device now spans the popup CURA-5959 --- resources/qml/ActionPanel/OutputDevicesActionButton.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/ActionPanel/OutputDevicesActionButton.qml b/resources/qml/ActionPanel/OutputDevicesActionButton.qml index d24d440241..e4b4884794 100644 --- a/resources/qml/ActionPanel/OutputDevicesActionButton.qml +++ b/resources/qml/ActionPanel/OutputDevicesActionButton.qml @@ -68,7 +68,7 @@ Item closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent - contentItem: Column + contentItem: ColumnLayout { Repeater { @@ -80,7 +80,7 @@ Item color: "transparent" cornerRadius: 0 hoverColor: UM.Theme.getColor("primary") - + Layout.fillWidth: true onClicked: { UM.OutputDeviceManager.setActiveDevice(model.id) From 21c81603b491ab7378752b5afd2e16dd0b648899 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 26 Nov 2018 13:33:14 +0100 Subject: [PATCH 0405/1292] Use application singleton instead of locally cached application --- cura/NetworkClient.py | 8 +++----- .../src/Cloud/CloudOutputDeviceManager.py | 14 ++++++++------ plugins/UM3NetworkPrinting/src/Cloud/Models.py | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/cura/NetworkClient.py b/cura/NetworkClient.py index eeedfeaa79..b150f59011 100644 --- a/cura/NetworkClient.py +++ b/cura/NetworkClient.py @@ -7,8 +7,8 @@ from PyQt5.QtCore import QUrl from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkReply, QHttpMultiPart, QNetworkRequest, QHttpPart, \ QAuthenticator +from UM.Application import Application from UM.Logger import Logger -from cura.CuraApplication import CuraApplication ## Abstraction of QNetworkAccessManager for easier networking in Cura. @@ -17,9 +17,6 @@ class NetworkClient: def __init__(self) -> None: - # Use the given application instance or get the singleton instance. - self._application = CuraApplication.getInstance() - # Network manager instance to use for this client. self._manager = None # type: Optional[QNetworkAccessManager] @@ -29,7 +26,8 @@ class NetworkClient: self._last_request_time = None # type: Optional[float] # The user agent of Cura. - self._user_agent = "%s/%s " % (self._application.getApplicationName(), self._application.getVersion()) + application = Application.getInstance() + self._user_agent = "%s/%s " % (application.getApplicationName(), application.getVersion()) # Uses to store callback methods for finished network requests. # This allows us to register network calls with a callback directly instead of having to dissect the reply. diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index e93393d736..17e82417ef 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -6,6 +6,7 @@ from typing import Dict, Optional from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply from UM.Logger import Logger +from cura.CuraApplication import CuraApplication from cura.NetworkClient import NetworkClient from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputDevice import CloudOutputDevice from .Models import Cluster @@ -25,15 +26,16 @@ class CloudOutputDeviceManager(NetworkClient): def __init__(self): super().__init__() - - self._output_device_manager = self._application.getOutputDeviceManager() - self._account = self._application.getCuraAPI().account - + # Persistent dict containing the remote clusters for the authenticated user. self._remote_clusters = {} # type: Dict[str, CloudOutputDevice] + + application = CuraApplication.getInstance() + self._output_device_manager = application.getOutputDeviceManager() + self._account = application.getCuraAPI().account # When switching machines we check if we have to activate a remote cluster. - self._application.globalContainerStackChanged.connect(self._activeMachineChanged) + application.globalContainerStackChanged.connect(self._activeMachineChanged) # Fetch all remote clusters for the authenticated user. # TODO: update remote clusters periodically @@ -96,7 +98,7 @@ class CloudOutputDeviceManager(NetworkClient): ## Callback for when the active machine was changed by the user. def _activeMachineChanged(self): - active_machine = self._application.getGlobalContainerStack() + active_machine = CuraApplication.getInstance().getGlobalContainerStack() if not active_machine: return diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models.py b/plugins/UM3NetworkPrinting/src/Cloud/Models.py index 7d9bba32f7..b118f3e61c 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models.py @@ -8,4 +8,4 @@ Cluster = namedtuple("Cluster", [ "host_name", # Type: str "host_version", # Type: str "status", # Type: str -]) \ No newline at end of file +]) From 098714254d8a5d366f22d1894083fba4fee4aaad Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 26 Nov 2018 13:35:02 +0100 Subject: [PATCH 0406/1292] Remove unused code CURA-5959 --- resources/qml/SaveButton.qml | 478 ----------------------------------- 1 file changed, 478 deletions(-) delete mode 100644 resources/qml/SaveButton.qml diff --git a/resources/qml/SaveButton.qml b/resources/qml/SaveButton.qml deleted file mode 100644 index c2d310e30c..0000000000 --- a/resources/qml/SaveButton.qml +++ /dev/null @@ -1,478 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.7 -import QtQuick.Controls 1.1 -import QtQuick.Controls.Styles 1.1 -import QtQuick.Layouts 1.1 - -import UM 1.1 as UM -import Cura 1.0 as Cura - -// This widget does so much more than "just" being a save button, so it should be refactored at some point in time. -Item -{ - id: base; - UM.I18nCatalog { id: catalog; name: "cura"} - - property real progress: UM.Backend.progress - property int backendState: UM.Backend.state - property bool activity: CuraApplication.platformActivity - - property alias buttonRowWidth: saveRow.width - - property string fileBaseName - property string statusText: - { - if(!activity) - { - return catalog.i18nc("@label:PrintjobStatus", "Please load a 3D model"); - } - - switch(base.backendState) - { - case 1: - return catalog.i18nc("@label:PrintjobStatus", "Ready to slice"); - case 2: - return catalog.i18nc("@label:PrintjobStatus", "Slicing..."); - case 3: - return catalog.i18nc("@label:PrintjobStatus %1 is target operation", "Ready to %1").arg(UM.OutputDeviceManager.activeDeviceShortDescription); - case 4: - return catalog.i18nc("@label:PrintjobStatus", "Unable to Slice"); - case 5: - return catalog.i18nc("@label:PrintjobStatus", "Slicing unavailable"); - default: - return ""; - } - } - - function sliceOrStopSlicing() - { - try - { - if ([1, 5].indexOf(base.backendState) != -1) - { - CuraApplication.backend.forceSlice(); - } - else - { - CuraApplication.backend.stopSlicing(); - } - } - catch (e) - { - console.log("Could not start or stop slicing.", e) - } - } - - Label - { - id: statusLabel - width: parent.width - 2 * UM.Theme.getSize("thick_margin").width - anchors.top: parent.top - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("thick_margin").width - - color: UM.Theme.getColor("text") - font: UM.Theme.getFont("default_bold") - text: statusText; - } - - Rectangle - { - id: progressBar - width: parent.width - 2 * UM.Theme.getSize("thick_margin").width - height: UM.Theme.getSize("progressbar").height - anchors.top: statusLabel.bottom - anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height / 4) - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("thick_margin").width - radius: UM.Theme.getSize("progressbar_radius").width - color: UM.Theme.getColor("progressbar_background") - - Rectangle - { - width: Math.max(parent.width * base.progress) - height: parent.height - color: UM.Theme.getColor("progressbar_control") - radius: UM.Theme.getSize("progressbar_radius").width - visible: base.backendState == 2 - } - } - - // Shortcut for "save as/print/..." - Action - { - shortcut: "Ctrl+P" - onTriggered: - { - // only work when the button is enabled - if (saveToButton.enabled) - { - saveToButton.clicked(); - } - // prepare button - if (prepareButton.enabled) - { - sliceOrStopSlicing(); - } - } - } - - Item - { - id: saveRow - width: { - // using childrenRect.width directly causes a binding loop, because setting the width affects the childrenRect - var children_width = UM.Theme.getSize("default_margin").width; - for (var index in children) - { - var child = children[index]; - if(child.visible) - { - children_width += child.width + child.anchors.rightMargin; - } - } - return Math.min(children_width, base.width - UM.Theme.getSize("thick_margin").width); - } - height: saveToButton.height - anchors.bottom: parent.bottom - anchors.bottomMargin: UM.Theme.getSize("thick_margin").height - anchors.right: parent.right - clip: true - - Row - { - id: additionalComponentsRow - anchors.top: parent.top - anchors.right: saveToButton.visible ? saveToButton.left : (prepareButton.visible ? prepareButton.left : parent.right) - anchors.rightMargin: UM.Theme.getSize("default_margin").width - - spacing: UM.Theme.getSize("default_margin").width - } - - Component.onCompleted: - { - saveRow.addAdditionalComponents("saveButton") - } - - Connections - { - target: CuraApplication - onAdditionalComponentsChanged: saveRow.addAdditionalComponents("saveButton") - } - - function addAdditionalComponents (areaId) - { - if(areaId == "saveButton") - { - for (var component in CuraApplication.additionalComponents["saveButton"]) - { - CuraApplication.additionalComponents["saveButton"][component].parent = additionalComponentsRow - } - } - } - - Connections - { - target: UM.Preferences - onPreferenceChanged: - { - var autoSlice = UM.Preferences.getValue("general/auto_slice"); - prepareButton.autoSlice = autoSlice; - saveToButton.autoSlice = autoSlice; - } - } - - // Prepare button, only shows if auto_slice is off - Button - { - id: prepareButton - - tooltip: [1, 5].indexOf(base.backendState) != -1 ? catalog.i18nc("@info:tooltip","Slice current printjob") : catalog.i18nc("@info:tooltip","Cancel slicing process") - // 1 = not started, 2 = Processing - enabled: ([1, 2].indexOf(base.backendState) != -1) && base.activity - visible: !autoSlice && ([1, 2, 4].indexOf(base.backendState) != -1) && base.activity - property bool autoSlice - height: UM.Theme.getSize("save_button_save_to_button").height - - anchors.top: parent.top - anchors.right: parent.right - anchors.rightMargin: UM.Theme.getSize("thick_margin").width - - // 1 = not started, 4 = error, 5 = disabled - text: [1, 4, 5].indexOf(base.backendState) != -1 ? catalog.i18nc("@label:Printjob", "Prepare") : catalog.i18nc("@label:Printjob", "Cancel") - onClicked: - { - sliceOrStopSlicing(); - } - - style: ButtonStyle - { - background: Rectangle - { - border.width: UM.Theme.getSize("default_lining").width - border.color: - { - if(!control.enabled) - { - return UM.Theme.getColor("action_button_disabled_border"); - } - else if(control.pressed) - { - return UM.Theme.getColor("action_button_active_border"); - } - else if(control.hovered) - { - return UM.Theme.getColor("action_button_hovered_border"); - } - else - { - return UM.Theme.getColor("action_button_border"); - } - } - color: - { - if(!control.enabled) - { - return UM.Theme.getColor("action_button_disabled"); - } - else if(control.pressed) - { - return UM.Theme.getColor("action_button_active"); - } - else if(control.hovered) - { - return UM.Theme.getColor("action_button_hovered"); - } - else - { - return UM.Theme.getColor("action_button"); - } - } - - Behavior on color { ColorAnimation { duration: 50; } } - - implicitWidth: actualLabel.contentWidth + (UM.Theme.getSize("thick_margin").width * 2) - - Label - { - id: actualLabel - anchors.centerIn: parent - color: - { - if(!control.enabled) - { - return UM.Theme.getColor("action_button_disabled_text"); - } - else if(control.pressed) - { - return UM.Theme.getColor("action_button_active_text"); - } - else if(control.hovered) - { - return UM.Theme.getColor("action_button_hovered_text"); - } - else - { - return UM.Theme.getColor("action_button_text"); - } - } - font: UM.Theme.getFont("action_button") - text: control.text; - } - } - label: Item {} - } - } - - Button - { - id: saveToButton - - tooltip: UM.OutputDeviceManager.activeDeviceDescription; - // 3 = done, 5 = disabled - enabled: base.backendState != "undefined" && (base.backendState == 3 || base.backendState == 5) && base.activity == true - visible: base.backendState != "undefined" && autoSlice || ((base.backendState == 3 || base.backendState == 5) && base.activity == true) - property bool autoSlice - height: UM.Theme.getSize("save_button_save_to_button").height - - anchors.top: parent.top - anchors.right: deviceSelectionMenu.visible ? deviceSelectionMenu.left : parent.right - anchors.rightMargin: deviceSelectionMenu.visible ? -3 * UM.Theme.getSize("default_lining").width : UM.Theme.getSize("thick_margin").width - - text: UM.OutputDeviceManager.activeDeviceShortDescription - onClicked: - { - forceActiveFocus(); - UM.OutputDeviceManager.requestWriteToDevice(UM.OutputDeviceManager.activeDevice, PrintInformation.jobName, - { "filter_by_machine": true, "preferred_mimetypes": Cura.MachineManager.activeMachine.preferred_output_file_formats }); - } - - style: ButtonStyle - { - background: Rectangle - { - border.width: UM.Theme.getSize("default_lining").width - border.color: - { - if(!control.enabled) - { - return UM.Theme.getColor("action_button_disabled_border"); - } - else if(control.pressed) - { - return UM.Theme.getColor("print_button_ready_pressed_border"); - } - else if(control.hovered) - { - return UM.Theme.getColor("print_button_ready_hovered_border"); - } - else - { - return UM.Theme.getColor("print_button_ready_border"); - } - } - color: - { - if(!control.enabled) - { - return UM.Theme.getColor("action_button_disabled"); - } - else if(control.pressed) - { - return UM.Theme.getColor("print_button_ready_pressed"); - } - else if(control.hovered) - { - return UM.Theme.getColor("print_button_ready_hovered"); - } - else - { - return UM.Theme.getColor("print_button_ready"); - } - } - - Behavior on color { ColorAnimation { duration: 50; } } - - implicitWidth: actualLabel.contentWidth + (UM.Theme.getSize("thick_margin").width * 2) - - Label - { - id: actualLabel - anchors.centerIn: parent - color: control.enabled ? UM.Theme.getColor("print_button_ready_text") : UM.Theme.getColor("action_button_disabled_text") - font: UM.Theme.getFont("action_button") - text: control.text - } - } - label: Item { } - } - } - - Button - { - id: deviceSelectionMenu - tooltip: catalog.i18nc("@info:tooltip","Select the active output device"); - anchors.top: parent.top - anchors.right: parent.right - - anchors.rightMargin: UM.Theme.getSize("thick_margin").width - width: UM.Theme.getSize("save_button_save_to_button").height - height: UM.Theme.getSize("save_button_save_to_button").height - - // 3 = Done, 5 = Disabled - enabled: (base.backendState == 3 || base.backendState == 5) && base.activity == true - visible: (devicesModel.deviceCount > 1) && (base.backendState == 3 || base.backendState == 5) && base.activity == true - - - style: ButtonStyle - { - background: Rectangle - { - id: deviceSelectionIcon - border.width: UM.Theme.getSize("default_lining").width - border.color: - { - if(!control.enabled) - { - return UM.Theme.getColor("action_button_disabled_border") - } - else if(control.pressed) - { - return UM.Theme.getColor("print_button_ready_pressed_border") - } - else if(control.hovered) - { - return UM.Theme.getColor("print_button_ready_hovered_border") - } - else - { - return UM.Theme.getColor("print_button_ready_border") - } - } - color: - { - if(!control.enabled) - { - return UM.Theme.getColor("action_button_disabled") - } - else if(control.pressed) - { - return UM.Theme.getColor("print_button_ready_pressed") - } - else if(control.hovered) - { - return UM.Theme.getColor("print_button_ready_hovered") - } - else - { - return UM.Theme.getColor("print_button_ready") - } - } - Behavior on color { ColorAnimation { duration: 50; } } - anchors.left: parent.left - anchors.leftMargin: Math.round(UM.Theme.getSize("save_button_text_margin").width / 2); - width: parent.height - height: parent.height - - UM.RecolorImage - { - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.horizontalCenter - width: UM.Theme.getSize("standard_arrow").width - height: UM.Theme.getSize("standard_arrow").height - sourceSize.width: width - sourceSize.height: height - color: control.enabled ? UM.Theme.getColor("print_button_ready_text") : UM.Theme.getColor("action_button_disabled_text") - source: UM.Theme.getIcon("arrow_bottom") - } - } - } - - menu: Menu - { - id: devicesMenu; - Instantiator - { - model: devicesModel; - MenuItem - { - text: model.description - checkable: true; - checked: model.id == UM.OutputDeviceManager.activeDevice - exclusiveGroup: devicesMenuGroup - onTriggered: - { - UM.OutputDeviceManager.setActiveDevice(model.id); - } - } - onObjectAdded: devicesMenu.insertItem(index, object) - onObjectRemoved: devicesMenu.removeItem(object) - } - ExclusiveGroup { id: devicesMenuGroup } - } - } - UM.OutputDevicesModel { id: devicesModel } - } -} From 1fe65013584b6bb1130a8fc4a7bac3e3ddff618c Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 26 Nov 2018 13:35:41 +0100 Subject: [PATCH 0407/1292] Removed unused entries from theme --- resources/themes/cura-light/theme.json | 8 -------- 1 file changed, 8 deletions(-) diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index cbdc37caa1..59927da663 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -181,14 +181,6 @@ "action_button_shadow": [64, 47, 205, 255], "action_button_disabled_shadow": [228, 228, 228, 255], - "print_button_ready": [50, 130, 255, 255], - "print_button_ready_border": [50, 130, 255, 255], - "print_button_ready_text": [255, 255, 255, 255], - "print_button_ready_hovered": [30, 186, 245, 243], - "print_button_ready_hovered_border": [30, 186, 245, 243], - "print_button_ready_pressed": [30, 186, 245, 243], - "print_button_ready_pressed_border": [30, 186, 245, 243], - "scrollbar_background": [255, 255, 255, 255], "scrollbar_handle": [31, 36, 39, 255], "scrollbar_handle_hover": [12, 159, 227, 255], From 3c86c0ae6c691c4eb1be17f0fe15b1ff1cc5919f Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 26 Nov 2018 13:36:45 +0100 Subject: [PATCH 0408/1292] Fix spacing CURA-5959 --- resources/themes/cura-light/theme.json | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 59927da663..001818c2f8 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -80,8 +80,7 @@ "thick_lining": [127, 127, 127, 255], "lining": [192, 193, 194, 255], "viewport_overlay": [0, 0, 0, 192], - - + "primary": [50, 130, 255, 255], "primary_shadow": [64, 47, 205, 255], "primary_hover": [48, 182, 231, 255], @@ -90,15 +89,15 @@ "secondary": [245, 245, 245, 255], "secondary_shadow": [228, 228, 228, 255], - "primary_button": [38,113,231,255], - "primary_button_shadow": [27,95,202, 255], - "primary_button_hover": [81,145,247, 255], + "primary_button": [38, 113, 231, 255], + "primary_button_shadow": [27, 95, 202, 255], + "primary_button_hover": [81, 145, 247, 255], "primary_button_text": [255, 255, 255, 255], - "secondary_button": [240,240,240, 255], - "secondary_button_shadow": [228, 228, 228, 255], - "secondary_button_hover": [228,228,228, 255], - "secondary_button_text": [30,102,215, 255], + "secondary_button": [240, 240, 240, 255], + "secondary_button_shadow": [228, 228, 228, 255], + "secondary_button_hover": [228, 228, 228, 255], + "secondary_button_text": [30, 102, 215, 255], "main_window_header_background": [10, 8, 80, 255], "main_window_header_button_text_active": [10, 8, 80, 255], From ebae4347a841e90f257d3296b24ca3e8531e6852 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 26 Nov 2018 13:44:32 +0100 Subject: [PATCH 0409/1292] Fix unit tests that were failing after adding the getAbbreviatedMachineName to the machine manager. Contributes to CURA-5942. --- tests/TestPrintInformation.py | 52 ++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/tests/TestPrintInformation.py b/tests/TestPrintInformation.py index a226a437c6..baa36fb338 100644 --- a/tests/TestPrintInformation.py +++ b/tests/TestPrintInformation.py @@ -1,5 +1,7 @@ +import functools from cura import PrintInformation +from cura.Settings.MachineManager import MachineManager from unittest.mock import MagicMock, patch from UM.Application import Application @@ -11,14 +13,20 @@ def getPrintInformation(printer_name) -> PrintInformation: mock_application = MagicMock() global_container_stack = MagicMock() - global_container_stack.definition.getName = MagicMock(return_value=printer_name) - mock_application.getGlobalContainerStack = MagicMock(return_value=global_container_stack) + global_container_stack.definition.getName = MagicMock(return_value = printer_name) + mock_application.getGlobalContainerStack = MagicMock(return_value = global_container_stack) - multiBuildPlateModel = MagicMock() - multiBuildPlateModel.maxBuildPlate = 0 - mock_application.getMultiBuildPlateModel = MagicMock(return_value=multiBuildPlateModel) + multi_build_plate_model = MagicMock() + multi_build_plate_model.maxBuildPlate = 0 + mock_application.getMultiBuildPlateModel = MagicMock(return_value = multi_build_plate_model) - Application.getInstance = MagicMock(return_type=mock_application) + # Mock-up the entire machine manager except the function that needs to be tested: getAbbreviatedMachineName + original_get_abbreviated_name = MachineManager.getAbbreviatedMachineName + mock_machine_manager = MagicMock() + mock_machine_manager.getAbbreviatedMachineName = functools.partial(original_get_abbreviated_name, mock_machine_manager) + mock_application.getMachineManager = MagicMock(return_value = mock_machine_manager) + + Application.getInstance = MagicMock(return_type = mock_application) with patch("json.loads", lambda x: {}): print_information = PrintInformation.PrintInformation(mock_application) @@ -28,17 +36,17 @@ def getPrintInformation(printer_name) -> PrintInformation: def setup_module(): MimeTypeDatabase.addMimeType( MimeType( - name="application/vnd.ms-package.3dmanufacturing-3dmodel+xml", - comment="3MF", - suffixes=["3mf"] + name = "application/vnd.ms-package.3dmanufacturing-3dmodel+xml", + comment = "3MF", + suffixes = ["3mf"] ) ) MimeTypeDatabase.addMimeType( MimeType( - name="application/x-cura-gcode-file", - comment="Cura GCode File", - suffixes=["gcode"] + name = "application/x-cura-gcode-file", + comment = "Cura GCode File", + suffixes = ["gcode"] ) ) @@ -49,42 +57,42 @@ def test_setProjectName(): print_information = getPrintInformation("ultimaker") # Test simple name - project_name = ["HelloWorld",".3mf"] + project_name = ["HelloWorld", ".3mf"] print_information.setProjectName(project_name[0] + project_name[1]) assert "UM_" + project_name[0] == print_information._job_name # Test the name with one dot - project_name = ["Hello.World",".3mf"] + project_name = ["Hello.World", ".3mf"] print_information.setProjectName(project_name[0] + project_name[1]) assert "UM_" + project_name[0] == print_information._job_name # Test the name with two dot - project_name = ["Hello.World.World",".3mf"] + project_name = ["Hello.World.World", ".3mf"] print_information.setProjectName(project_name[0] + project_name[1]) assert "UM_" + project_name[0] == print_information._job_name # Test the name with dot at the beginning - project_name = [".Hello.World",".3mf"] + project_name = [".Hello.World", ".3mf"] print_information.setProjectName(project_name[0] + project_name[1]) assert "UM_" + project_name[0] == print_information._job_name # Test the name with underline - project_name = ["Hello_World",".3mf"] + project_name = ["Hello_World", ".3mf"] print_information.setProjectName(project_name[0] + project_name[1]) assert "UM_" + project_name[0] == print_information._job_name # Test gcode extension - project_name = ["Hello_World",".gcode"] + project_name = ["Hello_World", ".gcode"] print_information.setProjectName(project_name[0] + project_name[1]) assert "UM_" + project_name[0] == print_information._job_name # Test empty project name - project_name = ["",""] + project_name = ["", ""] print_information.setProjectName(project_name[0] + project_name[1]) assert print_information.UNTITLED_JOB_NAME == print_information._job_name # Test wrong file extension - project_name = ["Hello_World",".test"] + project_name = ["Hello_World", ".test"] print_information.setProjectName(project_name[0] + project_name[1]) assert "UM_" + project_name[0] != print_information._job_name @@ -93,7 +101,7 @@ def test_setJobName(): print_information = getPrintInformation("ultimaker") print_information._abbr_machine = "UM" - print_information.setJobName("UM_HelloWorld", is_user_specified_job_name=False) + print_information.setJobName("UM_HelloWorld", is_user_specified_job_name = False) def test_defineAbbreviatedMachineName(): @@ -102,6 +110,6 @@ def test_defineAbbreviatedMachineName(): print_information = getPrintInformation(printer_name) # Test not ultimaker printer, name suffix should have first letter from the printer name - project_name = ["HelloWorld",".3mf"] + project_name = ["HelloWorld", ".3mf"] print_information.setProjectName(project_name[0] + project_name[1]) assert printer_name[0] + "_" + project_name[0] == print_information._job_name \ No newline at end of file From 014b1d6e4ee4e3e9193bed7ba8b188865416ed4d Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 26 Nov 2018 13:45:37 +0100 Subject: [PATCH 0410/1292] test --- cura/PrinterOutput/NetworkedPrinterOutputDevice.py | 10 ++++++---- .../UM3NetworkPrinting/src/UM3OutputDevicePlugin.py | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py index 12769208f4..a44b42a8ba 100644 --- a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py +++ b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py @@ -36,7 +36,7 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice, NetworkClient): self._authentication_state = AuthState.NotAuthenticated self._sending_gcode = False self._compressing_gcode = False - self._gcode = [] # type: List[str] + self._gcode = [] # type: List[str] self._connection_state_before_timeout = None # type: Optional[ConnectionState] self._timeout_time = 10 # After how many seconds of no response should a timeout occur? @@ -182,8 +182,10 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice, NetworkClient): return self._address def __handleOnFinished(self, reply: QNetworkReply) -> None: - super().__handleOnFinished(reply) - # Since we got a reply from the network manager we can now be sure we are actually connected. - if self._connection_state == ConnectionState.connecting: + # Since we got a 200 reply from the network manager we can now be sure we are actually connected. + if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) == 200 and \ + self._connection_state == ConnectionState.connecting: self.setConnectionState(ConnectionState.connected) + + super().__handleOnFinished(reply) diff --git a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py index 09aecb2187..47c3482aa5 100644 --- a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py +++ b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py @@ -41,7 +41,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): self._zero_conf_browser = None # Create a cloud output device manager that abstract all cloud connection logic away. - self._cloud_output_device_manager = CloudOutputDeviceManager() + # self._cloud_output_device_manager = CloudOutputDeviceManager() # Because the model needs to be created in the same thread as the QMLEngine, we use a signal. self.addDeviceSignal.connect(self._onAddDevice) From a6544997525f0a066429223da1bd432eb3653ec5 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 26 Nov 2018 13:47:22 +0100 Subject: [PATCH 0411/1292] Re-enable hover for marketplace button CURA-5959 --- plugins/Toolbox/resources/qml/ToolboxDetailPage.qml | 2 +- resources/qml/MainWindow/MainWindowHeader.qml | 6 ++++-- resources/themes/cura-light/theme.json | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 437a2ef351..0c04dc2bab 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -37,7 +37,7 @@ Item leftMargin: UM.Theme.getSize("wide_margin").width topMargin: UM.Theme.getSize("wide_margin").height } - color: white //Always a white background for image (regardless of theme). + color: "white" //Always a white background for image (regardless of theme). Image { anchors.fill: parent diff --git a/resources/qml/MainWindow/MainWindowHeader.qml b/resources/qml/MainWindow/MainWindowHeader.qml index ceb27dd726..a24af7ee45 100644 --- a/resources/qml/MainWindow/MainWindowHeader.qml +++ b/resources/qml/MainWindow/MainWindowHeader.qml @@ -81,10 +81,12 @@ Rectangle height: Math.round(0.5 * UM.Theme.getSize("main_window_header").height) onClicked: Cura.Actions.browsePackages.trigger() + hoverEnabled: true + background: Rectangle { radius: UM.Theme.getSize("action_button_radius").width - color: "transparent" + color: marketplaceButton.hovered ? UM.Theme.getColor("primary_text") : UM.Theme.getColor("main_window_header_background") border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("primary_text") } @@ -93,7 +95,7 @@ Rectangle { id: label text: marketplaceButton.text - color: UM.Theme.getColor("primary_text") + color: marketplaceButton.hovered ? UM.Theme.getColor("main_window_header_background") : UM.Theme.getColor("primary_text") width: contentWidth } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 001818c2f8..2343cd3f2a 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -80,7 +80,7 @@ "thick_lining": [127, 127, 127, 255], "lining": [192, 193, 194, 255], "viewport_overlay": [0, 0, 0, 192], - + "primary": [50, 130, 255, 255], "primary_shadow": [64, 47, 205, 255], "primary_hover": [48, 182, 231, 255], From b63c4f7a74a06f6b167f6c48d3538b9566fc2e9f Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 26 Nov 2018 14:06:34 +0100 Subject: [PATCH 0412/1292] Add header in new files. Remove unused imports. Contributes to CURA-5959. --- resources/qml/ActionButton.qml | 1 - resources/qml/PrimaryButton.qml | 4 +++- resources/qml/SecondaryButton.qml | 4 +++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index 6dd5839bb9..b9a04f3b46 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -3,7 +3,6 @@ import QtQuick 2.7 import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.3 import QtGraphicalEffects 1.0 // For the dropshadow diff --git a/resources/qml/PrimaryButton.qml b/resources/qml/PrimaryButton.qml index 8450e524e2..fca63d2cdb 100644 --- a/resources/qml/PrimaryButton.qml +++ b/resources/qml/PrimaryButton.qml @@ -1,5 +1,7 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + import QtQuick 2.2 -import QtQuick.Controls 1.1 import UM 1.4 as UM import Cura 1.1 as Cura diff --git a/resources/qml/SecondaryButton.qml b/resources/qml/SecondaryButton.qml index 0e6b79b3a7..f03d8acdfa 100644 --- a/resources/qml/SecondaryButton.qml +++ b/resources/qml/SecondaryButton.qml @@ -1,5 +1,7 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + import QtQuick 2.2 -import QtQuick.Controls 1.1 import UM 1.4 as UM import Cura 1.1 as Cura From 68a90ec510b15d41ba585f013c7d9c5fe52fb94f Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 26 Nov 2018 14:08:21 +0100 Subject: [PATCH 0413/1292] Use simple models instead of namedtuples Named tuples would throw a TypeError if an unknown attribute was set, but we just want to ignore those --- plugins/UM3NetworkPrinting/src/Models.py | 67 ++++++++++++++---------- 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Models.py b/plugins/UM3NetworkPrinting/src/Models.py index bcdeb8299c..e2ad411e90 100644 --- a/plugins/UM3NetworkPrinting/src/Models.py +++ b/plugins/UM3NetworkPrinting/src/Models.py @@ -1,33 +1,42 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from collections import namedtuple -ClusterMaterial = namedtuple("ClusterMaterial", [ - "guid", # Type: str - "material", # Type: str - "brand", # Type: str - "version", # Type: int - "color", # Type: str - "density" # Type: str -]) -LocalMaterial = namedtuple("LocalMaterial", [ - "GUID", # Type: str - "id", # Type: str - "type", # Type: str - "status", # Type: str - "base_file", # Type: str - "setting_version", # Type: int - "version", # Type: int - "name", # Type: str - "brand", # Type: str - "material", # Type: str - "color_name", # Type: str - "color_code", # Type: str - "description", # Type: str - "adhesion_info", # Type: str - "approximate_diameter", # Type: str - "properties", # Type: str - "definition", # Type: str - "compatible" # Type: str -]) +## Base model that maps kwargs to instance attributes. +class BaseModel: + def __init__(self, **kwargs): + self.__dict__.update(kwargs) + + +## Class representing a material that was fetched from the cluster API. +class ClusterMaterial(BaseModel): + def __init__(self, **kwargs): + self.guid = None # type: str + self.material = None # type: str + self.brand = None # type: str + self.version = None # type: int + self.color = None # type: str + self.density = None # type: str + super().__init__(**kwargs) + + +## Class representing a local material that was fetched from the container registry. +class LocalMaterial(BaseModel): + def __init__(self, **kwargs): + self.GUID = None # type: str + self.id = None # type: str + self.type = None # type: str + self.status = None # type: str + self.base_file = None # type: str + self.setting_version = None # type: int + self.version = None # type: int + self.brand = None # type: str + self.material = None # type: str + self.color_name = None # type: str + self.color_code = None # type: str + self.description = None # type: str + self.adhesion_info = None # type: str + self.approximate_diameter = None # type: str + self.definition = None # type: str + self.compatible = None # type: bool + super().__init__(**kwargs) From 89e88a73bbf2e998e846fc11a803107fefafc170 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 26 Nov 2018 14:11:20 +0100 Subject: [PATCH 0414/1292] Temporary patch for when printer has one or more materials not installed --- plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index 8314b0f089..54b888d2f0 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -592,7 +592,7 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): def _createMaterialOutputModel(self, material_data: Dict[str, Any]) -> "MaterialOutputModel": material_manager = CuraApplication.getInstance().getMaterialManager() - material_group_list = material_manager.getMaterialGroupListByGUID(material_data["guid"]) + material_group_list = material_manager.getMaterialGroupListByGUID(material_data["guid"]) or [] # Sort the material groups by "is_read_only = True" first, and then the name alphabetically. read_only_material_group_list = list(filter(lambda x: x.is_read_only, material_group_list)) From 90a73f351da7bfa695ab5fcb6e9e9361e6200a44 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 26 Nov 2018 14:12:34 +0100 Subject: [PATCH 0415/1292] Fix positioning of tabs in custom menu The label's bottom side is at its top, so we must add its height so that it gets positioned correctly. Contributes to issue CURA-5876. --- .../qml/Menus/ConfigurationMenu/CustomConfiguration.qml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index 50ff108431..25111a9365 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -33,7 +33,7 @@ Item { id: tabBar anchors.top: header.bottom - anchors.topMargin: UM.Theme.getSize("default_margin").height + anchors.topMargin: UM.Theme.getSize("default_margin").height + header.height onCurrentIndexChanged: Cura.ExtruderManager.setActiveExtruderIndex(currentIndex) @@ -114,7 +114,7 @@ Item property var hasActiveExtruder: activeExtruder != null property var currentRootMaterialName: hasActiveExtruder ? activeExtruder.material.name : "" property var valueError: hasActiveExtruder ? Cura.ContainerManager.getContainerMetaDataEntry(activeExtruder.material.id, "compatible", "") != "True" : true - property var valueWarning: ! Cura.MachineManager.isActiveQualitySupported + property var valueWarning: !Cura.MachineManager.isActiveQualitySupported text: currentRootMaterialName tooltip: currentRootMaterialName @@ -131,7 +131,6 @@ Item { extruderIndex: Cura.ExtruderManager.activeExtruderIndex } - } } From 12f78fa21ad022d9f1f278fb5f3d56ced7e65f60 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 26 Nov 2018 14:29:42 +0100 Subject: [PATCH 0416/1292] Remove border of the popup selector for the output devices. Contributes to CURA-5959. --- resources/qml/ActionPanel/OutputDevicesActionButton.qml | 3 --- 1 file changed, 3 deletions(-) diff --git a/resources/qml/ActionPanel/OutputDevicesActionButton.qml b/resources/qml/ActionPanel/OutputDevicesActionButton.qml index e4b4884794..2111038cfc 100644 --- a/resources/qml/ActionPanel/OutputDevicesActionButton.qml +++ b/resources/qml/ActionPanel/OutputDevicesActionButton.qml @@ -94,10 +94,7 @@ Item { opacity: visible ? 1 : 0 Behavior on opacity { NumberAnimation { duration: 100 } } - radius: UM.Theme.getSize("default_radius").width color: UM.Theme.getColor("action_panel_secondary") - border.color: UM.Theme.getColor("lining") - border.width: UM.Theme.getSize("default_lining").width } } } From a382b77eaa81998d5a413a019701137117b45eb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Mon, 26 Nov 2018 14:30:17 +0100 Subject: [PATCH 0417/1292] Added validation to the models --- plugins/UM3NetworkPrinting/src/Models.py | 14 ++++++++++++++ plugins/UM3NetworkPrinting/src/SendMaterialJob.py | 4 ++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Models.py b/plugins/UM3NetworkPrinting/src/Models.py index e2ad411e90..d0708c8127 100644 --- a/plugins/UM3NetworkPrinting/src/Models.py +++ b/plugins/UM3NetworkPrinting/src/Models.py @@ -6,6 +6,10 @@ class BaseModel: def __init__(self, **kwargs): self.__dict__.update(kwargs) + self.validate() + + def validate(self): + pass ## Class representing a material that was fetched from the cluster API. @@ -19,6 +23,10 @@ class ClusterMaterial(BaseModel): self.density = None # type: str super().__init__(**kwargs) + def validate(self): + if not self.guid: + raise ValueError("guid is required on ClusterMaterial") + ## Class representing a local material that was fetched from the container registry. class LocalMaterial(BaseModel): @@ -40,3 +48,9 @@ class LocalMaterial(BaseModel): self.definition = None # type: str self.compatible = None # type: bool super().__init__(**kwargs) + + def validate(self): + if not self.GUID: + raise ValueError("guid is required on LocalMaterial") + if not self.id: + raise ValueError("id is required on LocalMaterial") diff --git a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py index 48760af28e..6f33e75ee1 100644 --- a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py @@ -159,8 +159,8 @@ class SendMaterialJob(Job): Logger.log("e", "Request material storage on printer: I didn't understand the printer's answer.") except json.JSONDecodeError: Logger.log("e", "Request material storage on printer: I didn't understand the printer's answer.") - except TypeError: - Logger.log("e", "Request material storage on printer: Printer's answer was missing GUIDs.") + except ValueError: + Logger.log("e", "Request material storage on printer: Printer's answer was missing a value.") ## Retrieves a list of local materials # From 0a1c0e18d1bca499168b062f1e0538665768cd85 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 26 Nov 2018 14:38:43 +0100 Subject: [PATCH 0418/1292] Reuse the component SecondaryButton in the printer selector. Contributes to CURA-5942. --- resources/qml/PrinterSelector/MachineSelector.qml | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index 120ce02edd..93e5103aa8 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -125,15 +125,11 @@ Cura.ExpandableComponent padding: UM.Theme.getSize("default_margin").width spacing: UM.Theme.getSize("default_margin").width - Cura.ActionButton + Cura.SecondaryButton { leftPadding: UM.Theme.getSize("default_margin").width rightPadding: UM.Theme.getSize("default_margin").width text: catalog.i18nc("@button", "Add printer") - color: UM.Theme.getColor("secondary") - hoverColor: UM.Theme.getColor("secondary") - textColor: UM.Theme.getColor("primary") - textHoverColor: UM.Theme.getColor("text") onClicked: { togglePopup() @@ -141,15 +137,11 @@ Cura.ExpandableComponent } } - Cura.ActionButton + Cura.SecondaryButton { leftPadding: UM.Theme.getSize("default_margin").width rightPadding: UM.Theme.getSize("default_margin").width text: catalog.i18nc("@button", "Manage printers") - color: UM.Theme.getColor("secondary") - hoverColor: UM.Theme.getColor("secondary") - textColor: UM.Theme.getColor("primary") - textHoverColor: UM.Theme.getColor("text") onClicked: { togglePopup() From 579522857a99505aedaf8c6bf7cfcd1ab0aca521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Mon, 26 Nov 2018 14:42:50 +0100 Subject: [PATCH 0419/1292] Fix the code-style test --- cura/NetworkClient.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/NetworkClient.py b/cura/NetworkClient.py index b150f59011..fbe0c63c36 100644 --- a/cura/NetworkClient.py +++ b/cura/NetworkClient.py @@ -206,7 +206,7 @@ class NetworkClient: if not self._manager: Logger.log("e", "No network manager was created to execute the POST call with.") - return + return None reply = self._manager.post(request, multi_post_part) From 6a43d10982e41e175c54338383435ca91d666199 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 26 Nov 2018 14:51:24 +0100 Subject: [PATCH 0420/1292] Use BaseModel for CloudCluster, some fixes --- plugins/UM3NetworkPrinting/__init__.py | 2 +- .../src/Cloud/CloudOutputDeviceManager.py | 21 ++++++++--------- .../UM3NetworkPrinting/src/Cloud/Models.py | 23 ++++++++++++------- .../src/UM3OutputDevicePlugin.py | 23 ++++++++----------- 4 files changed, 34 insertions(+), 35 deletions(-) diff --git a/plugins/UM3NetworkPrinting/__init__.py b/plugins/UM3NetworkPrinting/__init__.py index 23262aed94..3da7795589 100644 --- a/plugins/UM3NetworkPrinting/__init__.py +++ b/plugins/UM3NetworkPrinting/__init__.py @@ -10,6 +10,6 @@ def getMetaData(): def register(app): return { - "output_device": UM3OutputDevicePlugin.UM3OutputDevicePlugin(app), + "output_device": UM3OutputDevicePlugin.UM3OutputDevicePlugin(), "machine_action": DiscoverUM3Action.DiscoverUM3Action() } diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 17e82417ef..e48c06dbe9 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -9,7 +9,7 @@ from UM.Logger import Logger from cura.CuraApplication import CuraApplication from cura.NetworkClient import NetworkClient from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputDevice import CloudOutputDevice -from .Models import Cluster +from .Models import CloudCluster ## The cloud output device manager is responsible for using the Ultimaker Cloud APIs to manage remote clusters. @@ -78,23 +78,20 @@ class CloudOutputDeviceManager(NetworkClient): @staticmethod def _parseStatusResponse(reply: QNetworkReply) -> Optional[Cluster]: try: - return [Cluster(**c) for c in json.loads(reply.readAll().data().decode("utf-8"))] + return [CloudCluster(**c) for c in json.loads(reply.readAll().data().decode("utf-8"))] + except UnicodeDecodeError: + Logger.log("w", "Unable to read server response") except json.decoder.JSONDecodeError: Logger.logException("w", "Unable to decode JSON from reply.") - return None - except UnicodeDecodeError: - Logger.log("e", "Unable to read server response") - except json.JSONDecodeError: - Logger.logException("w", "Unable to decode JSON from reply.") - + except ValueError: + Logger.logException("w", "Response was missing values.") return None ## Adds a CloudOutputDevice for each entry in the remote cluster list from the API. - def _addCloudOutputDevice(self, cluster: Cluster): - print("cluster_data====", cluster) - device = CloudOutputDevice(cluster["cluster_id"]) + def _addCloudOutputDevice(self, cluster: CloudCluster): + device = CloudOutputDevice(cluster.cluster_id) self._output_device_manager.addOutputDevice(device) - self._remote_clusters[cluster["cluster_id"]] = device + self._remote_clusters[cluster.cluster_id] = device ## Callback for when the active machine was changed by the user. def _activeMachineChanged(self): diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models.py b/plugins/UM3NetworkPrinting/src/Cloud/Models.py index b118f3e61c..3cbfecadfb 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models.py @@ -1,11 +1,18 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from collections import namedtuple +from plugins.UM3NetworkPrinting.src.Models import BaseModel -Cluster = namedtuple("Cluster", [ - "cluster_id", # Type: str - "host_guid", # Type: str - "host_name", # Type: str - "host_version", # Type: str - "status", # Type: str -]) + +## Class representing a cloud connected cluster. +class CloudCluster(BaseModel): + def __init__(self, **kwargs): + self.cluster_id = None # type: str + self.host_guid = None # type: str + self.host_name = None # type: str + self.host_version = None # type: str + self.status = None # type: str + super().__init__(**kwargs) + + def validate(self): + if not self.cluster_id: + raise ValueError("cluster_id is required on CloudCluster") diff --git a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py index 47c3482aa5..086bca03e2 100644 --- a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py +++ b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py @@ -1,7 +1,6 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import TYPE_CHECKING - +from UM.Application import Application from UM.OutputDevice.OutputDevicePlugin import OutputDevicePlugin from UM.Logger import Logger from UM.Signal import Signal, signalemitter @@ -20,9 +19,6 @@ from time import time import json -if TYPE_CHECKING: - from cura.CuraApplication import CuraApplication - ## This plugin handles the connection detection & creation of output device objects for the UM3 printer. # Zero-Conf is used to detect printers, which are saved in a dict. @@ -33,21 +29,20 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): removeDeviceSignal = Signal() discoveredDevicesChanged = Signal() - def __init__(self, application: "CuraApplication"): + def __init__(self): super().__init__() - self._application = application self._zero_conf = None self._zero_conf_browser = None # Create a cloud output device manager that abstract all cloud connection logic away. - # self._cloud_output_device_manager = CloudOutputDeviceManager() + self._cloud_output_device_manager = CloudOutputDeviceManager() # Because the model needs to be created in the same thread as the QMLEngine, we use a signal. self.addDeviceSignal.connect(self._onAddDevice) self.removeDeviceSignal.connect(self._onRemoveDevice) - application.globalContainerStackChanged.connect(self.reCheckConnections) + Application.getInstance().globalContainerStackChanged.connect(self.reCheckConnections) self._discovered_devices = {} @@ -62,7 +57,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): self._cluster_api_prefix = "/cluster-api/v" + self._cluster_api_version + "/" # Get list of manual instances from preferences - self._preferences = self._application.getPreferences() + self._preferences = Application.getInstance().getPreferences() self._preferences.addPreference("um3networkprinting/manual_instances", "") # A comma-separated list of ip adresses or hostnames @@ -113,7 +108,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): self.resetLastManualDevice() def reCheckConnections(self): - active_machine = self._application.getGlobalContainerStack() + active_machine = Application.getInstance().getGlobalContainerStack() if not active_machine: return @@ -138,7 +133,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): return if self._discovered_devices[key].isConnected(): # Sometimes the status changes after changing the global container and maybe the device doesn't belong to this machine - um_network_key = self._application.getGlobalContainerStack().getMetaDataEntry("um_network_key") + um_network_key = Application.getInstance().getGlobalContainerStack().getMetaDataEntry("um_network_key") if key == um_network_key: self.getOutputDeviceManager().addOutputDevice(self._discovered_devices[key]) else: @@ -290,7 +285,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): self._discovered_devices[device.getId()] = device self.discoveredDevicesChanged.emit() - global_container_stack = self._application.getGlobalContainerStack() + global_container_stack = Application.getInstance().getGlobalContainerStack() if global_container_stack and device.getId() == global_container_stack.getMetaDataEntry("um_network_key"): device.connect() device.connectionStateChanged.connect(self._onDeviceConnectionStateChanged) @@ -308,7 +303,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): self._service_changed_request_event.wait(timeout = 5.0) # Stop if the application is shutting down - if self._application.isShuttingDown(): + if Application.getInstance().isShuttingDown(): return self._service_changed_request_event.clear() From 856276d8b782b0bacaca0047a47ab2afbae867da Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 26 Nov 2018 14:53:08 +0100 Subject: [PATCH 0421/1292] Cleanup plugin imports --- .../src/UM3OutputDevicePlugin.py | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py index 086bca03e2..47720f3ef8 100644 --- a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py +++ b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py @@ -1,23 +1,22 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +import json +from queue import Queue +from threading import Event, Thread +from time import time + +from zeroconf import Zeroconf, ServiceBrowser, ServiceStateChange, ServiceInfo +from PyQt5.QtNetwork import QNetworkRequest, QNetworkAccessManager +from PyQt5.QtCore import QUrl + from UM.Application import Application from UM.OutputDevice.OutputDevicePlugin import OutputDevicePlugin from UM.Logger import Logger from UM.Signal import Signal, signalemitter from UM.Version import Version -from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputDeviceManager import CloudOutputDeviceManager from . import ClusterUM3OutputDevice, LegacyUM3OutputDevice - -from PyQt5.QtNetwork import QNetworkRequest, QNetworkAccessManager -from PyQt5.QtCore import QUrl - -from zeroconf import Zeroconf, ServiceBrowser, ServiceStateChange, ServiceInfo -from queue import Queue -from threading import Event, Thread -from time import time - -import json +from .Cloud.CloudOutputDeviceManager import CloudOutputDeviceManager ## This plugin handles the connection detection & creation of output device objects for the UM3 printer. From 269d596f5da45dc1d61a6002901092e00c0546a1 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 26 Nov 2018 14:54:24 +0100 Subject: [PATCH 0422/1292] Fix typing for cluster list --- .../src/Cloud/CloudOutputDeviceManager.py | 6 +++--- plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index e48c06dbe9..9aba01d164 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -1,7 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import json -from typing import Dict, Optional +from typing import Dict, Optional, List from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply @@ -76,7 +76,7 @@ class CloudOutputDeviceManager(NetworkClient): # self._addCloudOutputDevice({ "cluster_id": "LJ0tciiuZZjarrXAvFLEZ6ox4Cvx8FvtXUlQv4vIhV6w" }) @staticmethod - def _parseStatusResponse(reply: QNetworkReply) -> Optional[Cluster]: + def _parseStatusResponse(reply: QNetworkReply) -> List[CloudCluster]: try: return [CloudCluster(**c) for c in json.loads(reply.readAll().data().decode("utf-8"))] except UnicodeDecodeError: @@ -85,7 +85,7 @@ class CloudOutputDeviceManager(NetworkClient): Logger.logException("w", "Unable to decode JSON from reply.") except ValueError: Logger.logException("w", "Response was missing values.") - return None + return [] ## Adds a CloudOutputDevice for each entry in the remote cluster list from the API. def _addCloudOutputDevice(self, cluster: CloudCluster): diff --git a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py index 47720f3ef8..e4b4c2bb0a 100644 --- a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py +++ b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py @@ -34,7 +34,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): self._zero_conf = None self._zero_conf_browser = None - # Create a cloud output device manager that abstract all cloud connection logic away. + # Create a cloud output device manager that abstracts all cloud connection logic away. self._cloud_output_device_manager = CloudOutputDeviceManager() # Because the model needs to be created in the same thread as the QMLEngine, we use a signal. From 39f92ced90194a3f818c87c653ccb1604a2d87d6 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 26 Nov 2018 15:02:52 +0100 Subject: [PATCH 0423/1292] Comment out test --- .../UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 9aba01d164..8efce87094 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -72,8 +72,8 @@ class CloudOutputDeviceManager(NetworkClient): for cluster in clusters: self._addCloudOutputDevice(cluster) - # # For testing we add a dummy device: - # self._addCloudOutputDevice({ "cluster_id": "LJ0tciiuZZjarrXAvFLEZ6ox4Cvx8FvtXUlQv4vIhV6w" }) + # For testing we add a dummy device: + # self._addCloudOutputDevice(CloudCluster(cluster_id = "LJ0tciiuZZjarrXAvFLEZ6ox4Cvx8FvtXUlQv4vIhV6w")) @staticmethod def _parseStatusResponse(reply: QNetworkReply) -> List[CloudCluster]: From a9fedb4f66a8717c1d35e9ecca51197b06ad082e Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 26 Nov 2018 15:05:53 +0100 Subject: [PATCH 0424/1292] Restore NetworkedPrinterOutputDevice for now --- .../NetworkedPrinterOutputDevice.py | 211 +++++++++++++++--- 1 file changed, 177 insertions(+), 34 deletions(-) diff --git a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py index a44b42a8ba..35d2ce014a 100644 --- a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py +++ b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py @@ -1,19 +1,21 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -import os -import gzip -from time import time -from typing import Dict, List, Optional -from enum import IntEnum -from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QCoreApplication +from UM.FileHandler.FileHandler import FileHandler #For typing. +from UM.Logger import Logger +from UM.Scene.SceneNode import SceneNode #For typing. +from cura.CuraApplication import CuraApplication -from UM.FileHandler.FileHandler import FileHandler -from UM.Scene.SceneNode import SceneNode -from cura.NetworkClient import NetworkClient from cura.PrinterOutputDevice import PrinterOutputDevice, ConnectionState +from PyQt5.QtNetwork import QHttpMultiPart, QHttpPart, QNetworkRequest, QNetworkAccessManager, QNetworkReply, QAuthenticator +from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QUrl, QCoreApplication +from time import time +from typing import Any, Callable, Dict, List, Optional +from enum import IntEnum + +import os # To get the username +import gzip class AuthState(IntEnum): NotAuthenticated = 1 @@ -23,29 +25,35 @@ class AuthState(IntEnum): AuthenticationReceived = 5 -class NetworkedPrinterOutputDevice(PrinterOutputDevice, NetworkClient): +class NetworkedPrinterOutputDevice(PrinterOutputDevice): authenticationStateChanged = pyqtSignal() def __init__(self, device_id, address: str, properties: Dict[bytes, bytes], parent: QObject = None) -> None: - PrinterOutputDevice.__init__(self, device_id = device_id, parent = parent) - NetworkClient.__init__(self) - + super().__init__(device_id = device_id, parent = parent) + self._manager = None # type: Optional[QNetworkAccessManager] + self._last_manager_create_time = None # type: Optional[float] + self._recreate_network_manager_time = 30 + self._timeout_time = 10 # After how many seconds of no response should a timeout occur? + + self._last_response_time = None # type: Optional[float] + self._last_request_time = None # type: Optional[float] + self._api_prefix = "" self._address = address self._properties = properties + self._user_agent = "%s/%s " % (CuraApplication.getInstance().getApplicationName(), CuraApplication.getInstance().getVersion()) + + self._onFinishedCallbacks = {} # type: Dict[str, Callable[[QNetworkReply], None]] self._authentication_state = AuthState.NotAuthenticated + + # QHttpMultiPart objects need to be kept alive and not garbage collected during the + # HTTP which uses them. We hold references to these QHttpMultiPart objects here. + self._kept_alive_multiparts = {} # type: Dict[QNetworkReply, QHttpMultiPart] + self._sending_gcode = False self._compressing_gcode = False - self._gcode = [] # type: List[str] - + self._gcode = [] # type: List[str] self._connection_state_before_timeout = None # type: Optional[ConnectionState] - self._timeout_time = 10 # After how many seconds of no response should a timeout occur? - self._recreate_network_manager_time = 30 - - ## Override creating empty request to compile the full URL. - # Needed to keep NetworkedPrinterOutputDevice backwards compatible after refactoring NetworkClient out of it. - def _createEmptyRequest(self, target: str, content_type: Optional[str] = "application/json") -> QNetworkRequest: - return super()._createEmptyRequest("http://" + self._address + self._api_prefix + target, content_type) def requestWrite(self, nodes: List[SceneNode], file_name: Optional[str] = None, limit_mimetypes: bool = False, file_handler: Optional[FileHandler] = None, **kwargs: str) -> None: raise NotImplementedError("requestWrite needs to be implemented") @@ -131,6 +139,27 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice, NetworkClient): self.setConnectionState(self._connection_state_before_timeout) self._connection_state_before_timeout = None + def _createEmptyRequest(self, target: str, content_type: Optional[str] = "application/json") -> QNetworkRequest: + url = QUrl("http://" + self._address + self._api_prefix + target) + request = QNetworkRequest(url) + if content_type is not None: + request.setHeader(QNetworkRequest.ContentTypeHeader, "application/json") + request.setHeader(QNetworkRequest.UserAgentHeader, self._user_agent) + return request + + def _createFormPart(self, content_header: str, data: bytes, content_type: Optional[str] = None) -> QHttpPart: + part = QHttpPart() + + if not content_header.startswith("form-data;"): + content_header = "form_data; " + content_header + part.setHeader(QNetworkRequest.ContentDispositionHeader, content_header) + + if content_type is not None: + part.setHeader(QNetworkRequest.ContentTypeHeader, content_type) + + part.setBody(data) + return part + ## Convenience function to get the username from the OS. # The code was copied from the getpass module, as we try to use as little dependencies as possible. def _getUserName(self) -> str: @@ -140,7 +169,130 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice, NetworkClient): return user return "Unknown User" # Couldn't find out username. - @pyqtSlot(str, result = str) + def _clearCachedMultiPart(self, reply: QNetworkReply) -> None: + if reply in self._kept_alive_multiparts: + del self._kept_alive_multiparts[reply] + + def _validateManager(self) -> None: + if self._manager is None: + self._createNetworkManager() + assert (self._manager is not None) + + def put(self, target: str, data: str, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: + self._validateManager() + request = self._createEmptyRequest(target) + self._last_request_time = time() + if self._manager is not None: + reply = self._manager.put(request, data.encode()) + self._registerOnFinishedCallback(reply, on_finished) + else: + Logger.log("e", "Could not find manager.") + + def delete(self, target: str, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: + self._validateManager() + request = self._createEmptyRequest(target) + self._last_request_time = time() + if self._manager is not None: + reply = self._manager.deleteResource(request) + self._registerOnFinishedCallback(reply, on_finished) + else: + Logger.log("e", "Could not find manager.") + + def get(self, target: str, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: + self._validateManager() + request = self._createEmptyRequest(target) + self._last_request_time = time() + if self._manager is not None: + reply = self._manager.get(request) + self._registerOnFinishedCallback(reply, on_finished) + else: + Logger.log("e", "Could not find manager.") + + def post(self, target: str, data: str, on_finished: Optional[Callable[[QNetworkReply], None]], on_progress: Callable = None) -> None: + self._validateManager() + request = self._createEmptyRequest(target) + self._last_request_time = time() + if self._manager is not None: + reply = self._manager.post(request, data.encode()) + if on_progress is not None: + reply.uploadProgress.connect(on_progress) + self._registerOnFinishedCallback(reply, on_finished) + else: + Logger.log("e", "Could not find manager.") + + def postFormWithParts(self, target: str, parts: List[QHttpPart], on_finished: Optional[Callable[[QNetworkReply], None]], on_progress: Callable = None) -> QNetworkReply: + self._validateManager() + request = self._createEmptyRequest(target, content_type=None) + multi_post_part = QHttpMultiPart(QHttpMultiPart.FormDataType) + for part in parts: + multi_post_part.append(part) + + self._last_request_time = time() + + if self._manager is not None: + reply = self._manager.post(request, multi_post_part) + + self._kept_alive_multiparts[reply] = multi_post_part + + if on_progress is not None: + reply.uploadProgress.connect(on_progress) + self._registerOnFinishedCallback(reply, on_finished) + + return reply + else: + Logger.log("e", "Could not find manager.") + + def postForm(self, target: str, header_data: str, body_data: bytes, on_finished: Optional[Callable[[QNetworkReply], None]], on_progress: Callable = None) -> None: + post_part = QHttpPart() + post_part.setHeader(QNetworkRequest.ContentDispositionHeader, header_data) + post_part.setBody(body_data) + + self.postFormWithParts(target, [post_part], on_finished, on_progress) + + def _onAuthenticationRequired(self, reply: QNetworkReply, authenticator: QAuthenticator) -> None: + Logger.log("w", "Request to {url} required authentication, which was not implemented".format(url = reply.url().toString())) + + def _createNetworkManager(self) -> None: + Logger.log("d", "Creating network manager") + if self._manager: + self._manager.finished.disconnect(self.__handleOnFinished) + self._manager.authenticationRequired.disconnect(self._onAuthenticationRequired) + + self._manager = QNetworkAccessManager() + self._manager.finished.connect(self.__handleOnFinished) + self._last_manager_create_time = time() + self._manager.authenticationRequired.connect(self._onAuthenticationRequired) + + if self._properties.get(b"temporary", b"false") != b"true": + CuraApplication.getInstance().getMachineManager().checkCorrectGroupName(self.getId(), self.name) + + def _registerOnFinishedCallback(self, reply: QNetworkReply, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: + if on_finished is not None: + self._onFinishedCallbacks[reply.url().toString() + str(reply.operation())] = on_finished + + def __handleOnFinished(self, reply: QNetworkReply) -> None: + # Due to garbage collection, we need to cache certain bits of post operations. + # As we don't want to keep them around forever, delete them if we get a reply. + if reply.operation() == QNetworkAccessManager.PostOperation: + self._clearCachedMultiPart(reply) + + if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) is None: + # No status code means it never even reached remote. + return + + self._last_response_time = time() + + if self._connection_state == ConnectionState.connecting: + self.setConnectionState(ConnectionState.connected) + + callback_key = reply.url().toString() + str(reply.operation()) + try: + if callback_key in self._onFinishedCallbacks: + self._onFinishedCallbacks[callback_key](reply) + except Exception: + Logger.logException("w", "something went wrong with callback") + + @pyqtSlot(str, result=str) def getProperty(self, key: str) -> str: bytes_key = key.encode("utf-8") if bytes_key in self._properties: @@ -176,16 +328,7 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice, NetworkClient): def printerType(self) -> str: return self._properties.get(b"printer_type", b"Unknown").decode("utf-8") - ## IP address of this printer + ## IP adress of this printer @pyqtProperty(str, constant = True) def ipAddress(self) -> str: return self._address - - def __handleOnFinished(self, reply: QNetworkReply) -> None: - - # Since we got a 200 reply from the network manager we can now be sure we are actually connected. - if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) == 200 and \ - self._connection_state == ConnectionState.connecting: - self.setConnectionState(ConnectionState.connected) - - super().__handleOnFinished(reply) From 84f263f1111a58d46817c2d9d6572e7676a8dcf3 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 26 Nov 2018 15:08:33 +0100 Subject: [PATCH 0425/1292] Fix style for the open file button in the prepare menu. Contributes to CURA-5942. --- plugins/PrepareStage/PrepareMenu.qml | 41 ++++++++++++++++------------ 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index a99426acd8..a953c2b5d1 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -3,7 +3,7 @@ import QtQuick 2.7 import QtQuick.Layouts 1.1 -import QtQuick.Controls 1.4 +import QtQuick.Controls 2.3 import UM 1.3 as UM import Cura 1.1 as Cura @@ -27,14 +27,14 @@ Item Item { anchors.horizontalCenter: parent.horizontalCenter - width: openFileButtonBackground.width + itemRow.width + UM.Theme.getSize("default_margin").width + width: openFileButton.width + itemRow.width + UM.Theme.getSize("default_margin").width height: parent.height RowLayout { id: itemRow - anchors.left: openFileButtonBackground.right + anchors.left: openFileButton.right anchors.leftMargin: UM.Theme.getSize("default_margin").width width: Math.round(0.9 * prepareMenu.width) @@ -44,7 +44,7 @@ Item Cura.MachineSelector { id: machineSelection - z: openFileButtonBackground.z - 1 //Ensure that the tooltip of the open file button stays above the item row. + z: openFileButton.z - 1 //Ensure that the tooltip of the open file button stays above the item row. headerCornerSide: Cura.RoundedRectangle.Direction.Left Layout.minimumWidth: UM.Theme.getSize("machine_selector_widget").width Layout.maximumWidth: UM.Theme.getSize("machine_selector_widget").width @@ -86,24 +86,31 @@ Item } } - Rectangle + Button { - id: openFileButtonBackground + id: openFileButton height: UM.Theme.getSize("stage_menu").height width: UM.Theme.getSize("stage_menu").height + onClicked: Cura.Actions.open.trigger() - radius: UM.Theme.getSize("default_radius").width - color: UM.Theme.getColor("toolbar_background") - - Button + contentItem: UM.RecolorImage { - id: openFileButton - text: catalog.i18nc("@action:button", "Open File") - iconSource: UM.Theme.getIcon("load") - style: UM.Theme.styles.toolbar_button - tooltip: "" - action: Cura.Actions.open - anchors.centerIn: parent + id: buttonIcon + source: UM.Theme.getIcon("load") + width: UM.Theme.getSize("button_icon").width + height: UM.Theme.getSize("button_icon").height + color: UM.Theme.getColor("toolbar_button_text") + + sourceSize: UM.Theme.getSize("button_icon") + } + + background: Rectangle + { + height: UM.Theme.getSize("stage_menu").height + width: UM.Theme.getSize("stage_menu").height + + radius: UM.Theme.getSize("default_radius").width + color: openFileButton.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") } } } From 42ccabc7b6426307fe370abbf5a7312d267353ae Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 26 Nov 2018 15:09:56 +0100 Subject: [PATCH 0426/1292] Fix relative imports for plugin --- plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py | 4 ++-- .../UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 8f0bd62035..93e97a7c71 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -13,8 +13,8 @@ from UM.Scene.SceneNode import SceneNode from cura.CuraApplication import CuraApplication from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice, AuthState from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel -from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputController import CloudOutputController -from plugins.UM3NetworkPrinting.src.UM3PrintJobOutputModel import UM3PrintJobOutputModel +from .CloudOutputController import CloudOutputController +from ..UM3PrintJobOutputModel import UM3PrintJobOutputModel ## The cloud output device is a network output device that works remotely but has limited functionality. diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 8efce87094..a252f9e4d3 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -8,7 +8,8 @@ from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply from UM.Logger import Logger from cura.CuraApplication import CuraApplication from cura.NetworkClient import NetworkClient -from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputDevice import CloudOutputDevice + +from .CloudOutputDevice import CloudOutputDevice from .Models import CloudCluster From aaf0f69820ee06f8c2a8646328c68b6e3b7e6f3e Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 26 Nov 2018 15:10:36 +0100 Subject: [PATCH 0427/1292] Fix some more relative imports --- plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py | 1 + plugins/UM3NetworkPrinting/src/Cloud/Models.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 93e97a7c71..accc8429b1 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -13,6 +13,7 @@ from UM.Scene.SceneNode import SceneNode from cura.CuraApplication import CuraApplication from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice, AuthState from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel + from .CloudOutputController import CloudOutputController from ..UM3PrintJobOutputModel import UM3PrintJobOutputModel diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models.py b/plugins/UM3NetworkPrinting/src/Cloud/Models.py index 3cbfecadfb..e98d848d51 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models.py @@ -1,6 +1,6 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from plugins.UM3NetworkPrinting.src.Models import BaseModel +from ..Models import BaseModel ## Class representing a cloud connected cluster. From 9732099250f9085137883907293f5dbd1080691a Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 26 Nov 2018 15:14:32 +0100 Subject: [PATCH 0428/1292] Add border to rounded rectangle. It's designed so that it works in exactly the same way as rectangle. --- resources/qml/BorderGroup.qml | 7 +++++++ resources/qml/RoundedRectangle.qml | 23 +++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 resources/qml/BorderGroup.qml diff --git a/resources/qml/BorderGroup.qml b/resources/qml/BorderGroup.qml new file mode 100644 index 0000000000..94d0d68594 --- /dev/null +++ b/resources/qml/BorderGroup.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 + +QtObject +{ + property real width: 0 + property color color: "black" +} diff --git a/resources/qml/RoundedRectangle.qml b/resources/qml/RoundedRectangle.qml index 9ad2230be5..3ca05e2125 100644 --- a/resources/qml/RoundedRectangle.qml +++ b/resources/qml/RoundedRectangle.qml @@ -5,6 +5,7 @@ import UM 1.2 as UM // The rounded rectangle works mostly like a regular rectangle, but provides the option to have rounded corners on only one side of the rectangle. Item { + id: roundedRectangle // As per the regular rectangle property color color: "transparent" @@ -15,6 +16,9 @@ Item // 1 is down, 2 is left, 3 is up and 4 is right. property int cornerSide: RoundedRectangle.Direction.None + // Simple object to ensure that border.width and border.color work + property BorderGroup border: BorderGroup {} + enum Direction { None = 0, @@ -31,6 +35,8 @@ Item anchors.fill: parent radius: cornerSide != RoundedRectangle.Direction.None ? parent.radius : 0 color: parent.color + border.width: parent.border.width + border.color: parent.border.color } // The item that covers 2 of the corners to make them not rounded. @@ -45,5 +51,22 @@ Item right: cornerSide == RoundedRectangle.Direction.Left ? parent.right: undefined bottom: cornerSide == RoundedRectangle.Direction.Up ? parent.bottom: undefined } + + border.width: parent.border.width + border.color: parent.border.color + + Rectangle + { + color: roundedRectangle.color + height: cornerSide % 2 ? roundedRectangle.border.width: roundedRectangle.height - 2 * roundedRectangle.border.width + width: cornerSide % 2 ? roundedRectangle.width - 2 * roundedRectangle.border.width: roundedRectangle.border.width + anchors + { + right: cornerSide == RoundedRectangle.Direction.Right ? parent.right : undefined + bottom: cornerSide == RoundedRectangle.Direction.Down ? parent.bottom: undefined + horizontalCenter: cornerSide % 2 ? parent.horizontalCenter: undefined + verticalCenter: cornerSide % 2 ? undefined: parent.verticalCenter + } + } } } From da5683c876682019fe2360cf56fd27afe9f39844 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 26 Nov 2018 15:30:30 +0100 Subject: [PATCH 0429/1292] add typing to models --- plugins/UM3NetworkPrinting/src/Models.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Models.py b/plugins/UM3NetworkPrinting/src/Models.py index d0708c8127..2a34e41f86 100644 --- a/plugins/UM3NetworkPrinting/src/Models.py +++ b/plugins/UM3NetworkPrinting/src/Models.py @@ -4,17 +4,17 @@ ## Base model that maps kwargs to instance attributes. class BaseModel: - def __init__(self, **kwargs): + def __init__(self, **kwargs) -> None: self.__dict__.update(kwargs) self.validate() - def validate(self): + def validate(self) -> None: pass ## Class representing a material that was fetched from the cluster API. class ClusterMaterial(BaseModel): - def __init__(self, **kwargs): + def __init__(self, **kwargs) -> None: self.guid = None # type: str self.material = None # type: str self.brand = None # type: str @@ -23,14 +23,14 @@ class ClusterMaterial(BaseModel): self.density = None # type: str super().__init__(**kwargs) - def validate(self): + def validate(self) -> None: if not self.guid: raise ValueError("guid is required on ClusterMaterial") ## Class representing a local material that was fetched from the container registry. class LocalMaterial(BaseModel): - def __init__(self, **kwargs): + def __init__(self, **kwargs) -> None: self.GUID = None # type: str self.id = None # type: str self.type = None # type: str @@ -49,7 +49,7 @@ class LocalMaterial(BaseModel): self.compatible = None # type: bool super().__init__(**kwargs) - def validate(self): + def validate(self) -> None: if not self.GUID: raise ValueError("guid is required on LocalMaterial") if not self.id: From 9afc5748a8ec1eb7bbbdb8ba7395f7b3d2554a49 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 26 Nov 2018 15:39:34 +0100 Subject: [PATCH 0430/1292] Add copyright header. --- resources/qml/BorderGroup.qml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/resources/qml/BorderGroup.qml b/resources/qml/BorderGroup.qml index 94d0d68594..38ad9fadff 100644 --- a/resources/qml/BorderGroup.qml +++ b/resources/qml/BorderGroup.qml @@ -1,3 +1,6 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + import QtQuick 2.0 QtObject From ac5f79ba2ced74cb13fe1fc00fe328f0b7d5a8a0 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 26 Nov 2018 15:47:32 +0100 Subject: [PATCH 0431/1292] Add tab style to tabbed content It now gets a proper background colour, lining and radius. Contributes to issue CURA-5876. --- .../ConfigurationMenu/CustomConfiguration.qml | 35 +++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index 25111a9365..1f7673cd0a 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -1,7 +1,7 @@ // Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.0 +import QtQuick 2.6 import QtQuick.Controls 2.0 import QtQuick.Controls 1.1 as OldControls @@ -33,7 +33,7 @@ Item { id: tabBar anchors.top: header.bottom - anchors.topMargin: UM.Theme.getSize("default_margin").height + header.height + anchors.topMargin: UM.Theme.getSize("default_margin").height onCurrentIndexChanged: Cura.ExtruderManager.setActiveExtruderIndex(currentIndex) @@ -57,17 +57,46 @@ Item } } - Item + Rectangle { id: tabControl width: parent.width height: childrenRect.height anchors.top: tabBar.bottom + + radius: UM.Theme.getSize("default_radius").width + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("lining") + color: UM.Theme.getColor("secondary") + + //Remove rounding and lining at the top. + Rectangle + { + width: parent.width + height: parent.radius + anchors.top: parent.top + color: UM.Theme.getColor("lining") + Rectangle + { + anchors + { + left: parent.left + leftMargin: parent.parent.border.width + right: parent.right + rightMargin: parent.parent.border.width + top: parent.top + } + height: parent.parent.radius + color: parent.parent.color + } + } + property var model: extrudersModel.items[tabBar.currentIndex] property real textWidth: Math.round(width * 0.3) property real controlWidth: width - textWidth Column { + padding: UM.Theme.getSize("default_margin").width spacing: UM.Theme.getSize("default_margin").height Row From 3d1157522a4d9c318a2c2d3f068c3326e3e3b81c Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 26 Nov 2018 15:51:36 +0100 Subject: [PATCH 0432/1292] Reuse the RoundedRectangle component and indicate that only the bottom part of the popup should be rounded. Contributes to CURA-5942. --- resources/qml/ExpandableComponent.qml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index ccfb9c6da2..9b2826daed 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -2,6 +2,7 @@ import QtQuick 2.7 import QtQuick.Controls 2.3 import UM 1.2 as UM +import Cura 1.0 as Cura // The expandable component has 3 major sub components: // * The headerItem; Always visible and should hold some info about what happens if the component is expanded @@ -162,8 +163,9 @@ Item padding: UM.Theme.getSize("default_margin").width closePolicy: Popup.CloseOnPressOutsideParent - background: Rectangle + background: Cura.RoundedRectangle { + cornerSide: Cura.RoundedRectangle.Direction.Down color: popupBackgroundColor border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") From e4d8fb36abccd5e1a5f7f68bef086ae82ec3b9a4 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 26 Nov 2018 15:53:04 +0100 Subject: [PATCH 0433/1292] Add more typing as per request from @sedwards2009 --- plugins/UM3NetworkPrinting/src/Models.py | 35 ++++++++---------------- 1 file changed, 11 insertions(+), 24 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Models.py b/plugins/UM3NetworkPrinting/src/Models.py index 2a34e41f86..5ef44bc006 100644 --- a/plugins/UM3NetworkPrinting/src/Models.py +++ b/plugins/UM3NetworkPrinting/src/Models.py @@ -14,43 +14,30 @@ class BaseModel: ## Class representing a material that was fetched from the cluster API. class ClusterMaterial(BaseModel): - def __init__(self, **kwargs) -> None: - self.guid = None # type: str - self.material = None # type: str - self.brand = None # type: str - self.version = None # type: int - self.color = None # type: str - self.density = None # type: str + def __init__(self, guid = str, version = str, **kwargs) -> None: + self.guid = guid # type: str + self.version = version # type: int super().__init__(**kwargs) def validate(self) -> None: if not self.guid: raise ValueError("guid is required on ClusterMaterial") + if not self.version: + raise ValueError("version is required on ClusterMaterial") ## Class representing a local material that was fetched from the container registry. class LocalMaterial(BaseModel): - def __init__(self, **kwargs) -> None: - self.GUID = None # type: str - self.id = None # type: str - self.type = None # type: str - self.status = None # type: str - self.base_file = None # type: str - self.setting_version = None # type: int - self.version = None # type: int - self.brand = None # type: str - self.material = None # type: str - self.color_name = None # type: str - self.color_code = None # type: str - self.description = None # type: str - self.adhesion_info = None # type: str - self.approximate_diameter = None # type: str - self.definition = None # type: str - self.compatible = None # type: bool + def __init__(self, GUID = str, id = str, version = str, **kwargs) -> None: + self.GUID = GUID # type: str + self.id = id # type: str + self.version = version # type: int super().__init__(**kwargs) def validate(self) -> None: if not self.GUID: raise ValueError("guid is required on LocalMaterial") + if not self.version: + raise ValueError("version is required on LocalMaterial") if not self.id: raise ValueError("id is required on LocalMaterial") From 4b897ffd67a5572f305a981cba79ace625d086d9 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 26 Nov 2018 16:03:40 +0100 Subject: [PATCH 0434/1292] Fix width of content in tabbed content Contributes to issue CURA-5876. --- .../ConfigurationMenu/CustomConfiguration.qml | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index 1f7673cd0a..78448d5be5 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -59,7 +59,6 @@ Item Rectangle { - id: tabControl width: parent.width height: childrenRect.height anchors.top: tabBar.bottom @@ -91,14 +90,18 @@ Item } } - property var model: extrudersModel.items[tabBar.currentIndex] - property real textWidth: Math.round(width * 0.3) - property real controlWidth: width - textWidth Column { + id: selectors padding: UM.Theme.getSize("default_margin").width spacing: UM.Theme.getSize("default_margin").height + property var model: extrudersModel.items[tabBar.currentIndex] + + readonly property real paddedWidth: parent.width - padding * 2 + property real textWidth: Math.round(paddedWidth * 0.3) + property real controlWidth: paddedWidth - textWidth + Row { height: UM.Theme.getSize("print_setup_item").height @@ -110,13 +113,13 @@ Item font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") height: parent.height - width: tabControl.textWidth + width: selectors.textWidth } OldControls.CheckBox { - checked: tabControl.model != null ? Cura.MachineManager.getExtruder(tabControl.model.index).isEnabled: false - onClicked: Cura.MachineManager.setExtruderEnabled(tabControl.model.index, checked) + checked: selectors.model != null ? Cura.MachineManager.getExtruder(selectors.model.index).isEnabled: false + onClicked: Cura.MachineManager.setExtruderEnabled(selectors.model.index, checked) height: UM.Theme.getSize("setting_control").height style: UM.Theme.styles.checkbox } @@ -132,7 +135,7 @@ Item font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") height: parent.height - width: tabControl.textWidth + width: selectors.textWidth } OldControls.ToolButton @@ -152,7 +155,7 @@ Item enabled: Cura.ExtruderManager.activeExtruderIndex > -1 height: UM.Theme.getSize("setting_control").height - width: tabControl.controlWidth + width: selectors.controlWidth style: UM.Theme.styles.sidebar_header_button activeFocusOnPress: true @@ -174,7 +177,7 @@ Item font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") height: parent.height - width: tabControl.textWidth + width: selectors.textWidth } OldControls.ToolButton @@ -185,7 +188,7 @@ Item visible: Cura.MachineManager.hasVariants height: UM.Theme.getSize("setting_control").height - width: tabControl.controlWidth + width: selectors.controlWidth style: UM.Theme.styles.sidebar_header_button activeFocusOnPress: true; From 6506596eceeb241decdc8456f8d2d3d21a9b140e Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 26 Nov 2018 16:19:01 +0100 Subject: [PATCH 0435/1292] Fix typing syntax --- plugins/UM3NetworkPrinting/src/Models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Models.py b/plugins/UM3NetworkPrinting/src/Models.py index 5ef44bc006..2bcac70766 100644 --- a/plugins/UM3NetworkPrinting/src/Models.py +++ b/plugins/UM3NetworkPrinting/src/Models.py @@ -14,7 +14,7 @@ class BaseModel: ## Class representing a material that was fetched from the cluster API. class ClusterMaterial(BaseModel): - def __init__(self, guid = str, version = str, **kwargs) -> None: + def __init__(self, guid: str, version: int, **kwargs) -> None: self.guid = guid # type: str self.version = version # type: int super().__init__(**kwargs) @@ -28,7 +28,7 @@ class ClusterMaterial(BaseModel): ## Class representing a local material that was fetched from the container registry. class LocalMaterial(BaseModel): - def __init__(self, GUID = str, id = str, version = str, **kwargs) -> None: + def __init__(self, GUID: str, id: str, version: int, **kwargs) -> None: self.GUID = GUID # type: str self.id = id # type: str self.version = version # type: int From efd5f3799bdb1c156722046bc2056b961d217f4d Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 26 Nov 2018 16:31:32 +0100 Subject: [PATCH 0436/1292] Also catch TypeError now that we have explicit arguments --- plugins/UM3NetworkPrinting/src/SendMaterialJob.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py index 6f33e75ee1..f536fad49a 100644 --- a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py @@ -160,7 +160,9 @@ class SendMaterialJob(Job): except json.JSONDecodeError: Logger.log("e", "Request material storage on printer: I didn't understand the printer's answer.") except ValueError: - Logger.log("e", "Request material storage on printer: Printer's answer was missing a value.") + Logger.log("e", "Request material storage on printer: Printer's answer had an incorrect value.") + except TypeError: + Logger.log("e", "Request material storage on printer: Printer's answer was missing a required value.") ## Retrieves a list of local materials # @@ -189,5 +191,7 @@ class SendMaterialJob(Job): Logger.logException("w", "Local material {} has missing values.".format(material["id"])) except ValueError: Logger.logException("w", "Local material {} has invalid values.".format(material["id"])) + except TypeError: + Logger.logException("w", "Local material {} has invalid values.".format(material["id"])) return result From d85aee1c53cb27983f73d153685a1681efa78b58 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 26 Nov 2018 16:40:29 +0100 Subject: [PATCH 0437/1292] Ensure that no weird data is set in the printSetupSelector on first start CURA-5961 --- resources/qml/PrintSetupSelector.qml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/qml/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector.qml index 2ecdc9e546..9b90d8589f 100644 --- a/resources/qml/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector.qml @@ -54,12 +54,12 @@ Cura.ExpandableComponent IconWithText { source: UM.Theme.getIcon("category_layer_height") - text: Cura.MachineManager.activeQualityOrQualityChangesName + " " + layerHeight.properties.value + "mm" + text: Cura.MachineManager.activeStack ? Cura.MachineManager.activeQualityOrQualityChangesName + " " + layerHeight.properties.value + "mm" : "" UM.SettingPropertyProvider { id: layerHeight - containerStackId: Cura.MachineManager.activeStackId + containerStack: Cura.MachineManager.activeStack key: "layer_height" watchedProperties: ["value"] } @@ -68,12 +68,12 @@ Cura.ExpandableComponent IconWithText { source: UM.Theme.getIcon("category_infill") - text: parseInt(infillDensity.properties.value) + "%" + text: Cura.MachineManager.activeStack ? parseInt(infillDensity.properties.value) + "%" : "0%" UM.SettingPropertyProvider { id: infillDensity - containerStackId: Cura.MachineManager.activeStackId + containerStack: Cura.MachineManager.activeStack key: "infill_sparse_density" watchedProperties: ["value"] } From 87a0dc65e17742760fe7b551e2b8b5c4db0035a2 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 26 Nov 2018 17:09:36 +0100 Subject: [PATCH 0438/1292] Add list of available configurations to AutoConfiguration This is the main item it needs to display. Contributes to issue CURA-5876. --- .../qml/Menus/ConfigurationMenu/AutoConfiguration.qml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml index cde18ab488..8e86549e17 100644 --- a/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml @@ -5,6 +5,7 @@ import QtQuick 2.7 import QtQuick.Controls 2.0 import UM 1.3 as UM +import Cura 1.0 as Cura Item { @@ -26,4 +27,13 @@ Item right: parent.right } } + + ConfigurationListView + { + anchors.top: header.bottom + anchors.topMargin: UM.Theme.getSize("default_margin").width + width: parent.width + + outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null + } } \ No newline at end of file From a825daea9565cdb5cfe405a1bb58750a76cdf988 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 26 Nov 2018 17:10:48 +0100 Subject: [PATCH 0439/1292] Cleanup the Theme.json There were a lot of sizes that weren't used --- resources/qml/Dialogs/AddMachineDialog.qml | 1 - resources/themes/cura-dark/theme.json | 4 - resources/themes/cura-light/styles.qml | 248 --------------------- resources/themes/cura-light/theme.json | 20 -- 4 files changed, 273 deletions(-) diff --git a/resources/qml/Dialogs/AddMachineDialog.qml b/resources/qml/Dialogs/AddMachineDialog.qml index aa160acd4d..8b2b9d1868 100644 --- a/resources/qml/Dialogs/AddMachineDialog.qml +++ b/resources/qml/Dialogs/AddMachineDialog.qml @@ -298,7 +298,6 @@ UM.Dialog id: machineName text: getMachineName() width: Math.floor(parent.width * 0.75) - implicitWidth: UM.Theme.getSize("standard_list_input").width maximumLength: 40 //validator: Cura.MachineNameValidator { } //TODO: Gives a segfault in PyQt5.6. For now, we must use a signal on text changed. validator: RegExpValidator diff --git a/resources/themes/cura-dark/theme.json b/resources/themes/cura-dark/theme.json index 62b1dbfa0f..34b944b25b 100644 --- a/resources/themes/cura-dark/theme.json +++ b/resources/themes/cura-dark/theme.json @@ -133,7 +133,6 @@ "slider_groove_border": [127, 127, 127, 255], "slider_groove_fill": [245, 245, 245, 255], "slider_handle": [255, 255, 255, 255], - "slider_handle_hover": [77, 182, 226, 255], "slider_handle_active": [68, 192, 255, 255], "slider_text_background": [255, 255, 255, 255], @@ -209,9 +208,6 @@ "quality_slider_unavailable": [179, 179, 179, 255], "quality_slider_available": [255, 255, 255, 255], - "quality_slider_handle": [255, 255, 255, 255], - "quality_slider_handle_hover": [127, 127, 127, 255], - "quality_slider_text": [255, 255, 255, 255], "toolbox_header_button_text_active": [255, 255, 255, 255], "toolbox_header_button_text_inactive": [128, 128, 128, 255], diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index 723b393efa..f4aeb95bb3 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -599,198 +599,6 @@ QtObject } } - property Component sidebar_category: Component - { - ButtonStyle - { - background: Rectangle - { - anchors.fill: parent - anchors.left: parent.left - anchors.leftMargin: Theme.getSize("thick_margin").width - anchors.right: parent.right - anchors.rightMargin: Theme.getSize("thick_margin").width - implicitHeight: Theme.getSize("section").height - color: - { - if(control.color) - { - return control.color; - } - else if(!control.enabled) - { - return Theme.getColor("setting_category_disabled"); - } - else if(control.hovered && control.checkable && control.checked) - { - return Theme.getColor("setting_category_active_hover"); - } - else if(control.pressed || (control.checkable && control.checked)) - { - return Theme.getColor("setting_category_active"); - } - else if(control.hovered) - { - return Theme.getColor("setting_category_hover"); - } - else - { - return Theme.getColor("setting_category"); - } - } - Behavior on color { ColorAnimation { duration: 50; } } - Rectangle - { - height: Theme.getSize("default_lining").height - width: parent.width - anchors.bottom: parent.bottom - color: - { - if(!control.enabled) - { - return Theme.getColor("setting_category_disabled_border"); - } - else if((control.hovered || control.activeFocus) && control.checkable && control.checked) - { - return Theme.getColor("setting_category_active_hover_border"); - } - else if(control.pressed || (control.checkable && control.checked)) - { - return Theme.getColor("setting_category_active_border"); - } - else if(control.hovered || control.activeFocus) - { - return Theme.getColor("setting_category_hover_border"); - } - else - { - return Theme.getColor("setting_category_border"); - } - } - } - } - label: Item - { - anchors.fill: parent - anchors.left: parent.left - Item - { - id: icon - anchors.left: parent.left - height: parent.height - width: Theme.getSize("section_icon_column").width - UM.RecolorImage - { - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - anchors.leftMargin: Theme.getSize("thick_margin").width - color: - { - if(!control.enabled) - { - return Theme.getColor("setting_category_disabled_text"); - } - else if((control.hovered || control.activeFocus) && control.checkable && control.checked) - { - return Theme.getColor("setting_category_active_hover_text"); - } - else if(control.pressed || (control.checkable && control.checked)) - { - return Theme.getColor("setting_category_active_text"); - } - else if(control.hovered || control.activeFocus) - { - return Theme.getColor("setting_category_hover_text"); - } - else - { - return Theme.getColor("setting_category_text"); - } - } - source: control.iconSource; - width: Theme.getSize("section_icon").width; - height: Theme.getSize("section_icon").height; - sourceSize.width: width + 15 * screenScaleFactor - sourceSize.height: width + 15 * screenScaleFactor - } - } - - Label - { - anchors - { - left: icon.right - leftMargin: Theme.getSize("default_margin").width - right: parent.right - verticalCenter: parent.verticalCenter - } - text: control.text - font: Theme.getFont("setting_category") - color: - { - if(!control.enabled) - { - return Theme.getColor("setting_category_disabled_text"); - } - else if((control.hovered || control.activeFocus) && control.checkable && control.checked) - { - return Theme.getColor("setting_category_active_hover_text"); - } - else if(control.pressed || (control.checkable && control.checked)) - { - return Theme.getColor("setting_category_active_text"); - } - else if(control.hovered || control.activeFocus) - { - return Theme.getColor("setting_category_hover_text"); - } - else - { - return Theme.getColor("setting_category_text"); - } - } - fontSizeMode: Text.HorizontalFit - minimumPointSize: 8 - } - UM.RecolorImage - { - id: category_arrow - anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - anchors.rightMargin: Theme.getSize("default_margin").width * 3 - Math.round(width / 2) - width: Theme.getSize("standard_arrow").width - height: Theme.getSize("standard_arrow").height - sourceSize.width: width - sourceSize.height: width - color: - { - if(!control.enabled) - { - return Theme.getColor("setting_category_disabled_text"); - } - else if((control.hovered || control.activeFocus) && control.checkable && control.checked) - { - return Theme.getColor("setting_category_active_hover_text"); - } - else if(control.pressed || (control.checkable && control.checked)) - { - return Theme.getColor("setting_category_active_text"); - } - else if(control.hovered || control.activeFocus) - { - return Theme.getColor("setting_category_hover_text"); - } - else - { - return Theme.getColor("setting_category_text"); - } - } - source: control.checked ? Theme.getIcon("arrow_bottom") : Theme.getIcon("arrow_left") - } - } - } - } - property Component scrollview: Component { ScrollViewStyle @@ -1144,60 +952,4 @@ QtObject label: Item { } } } - - property Component toolbox_action_button: Component - { - ButtonStyle - { - background: Rectangle - { - implicitWidth: UM.Theme.getSize("toolbox_action_button").width - implicitHeight: UM.Theme.getSize("toolbox_action_button").height - color: - { - if (control.installed) - { - return UM.Theme.getColor("action_button_disabled"); - } - else - { - if (control.hovered) - { - return UM.Theme.getColor("primary_hover"); - } - else - { - return UM.Theme.getColor("primary"); - } - } - - } - } - label: Label - { - text: control.text - color: - { - if (control.installed) - { - return UM.Theme.getColor("action_button_disabled_text"); - } - else - { - if (control.hovered) - { - return UM.Theme.getColor("button_text_hover"); - } - else - { - return UM.Theme.getColor("button_text"); - } - } - } - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - font: UM.Theme.getFont("default_bold") - } - } - } } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 2343cd3f2a..67e0c701c2 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -122,7 +122,6 @@ "text_detail": [174, 174, 174, 128], "text_link": [50, 130, 255, 255], "text_inactive": [174, 174, 174, 255], - "text_hover": [70, 84, 113, 255], "text_pressed": [50, 130, 255, 255], "text_subtext": [0, 0, 0, 255], "text_medium": [128, 128, 128, 255], @@ -228,15 +227,11 @@ "slider_groove": [223, 223, 223, 255], "slider_groove_fill": [10, 8, 80, 255], "slider_handle": [10, 8, 80, 255], - "slider_handle_hover": [77, 182, 226, 255], "slider_handle_active": [50, 130, 255, 255], "slider_text_background": [255, 255, 255, 255], "quality_slider_unavailable": [179, 179, 179, 255], "quality_slider_available": [0, 0, 0, 255], - "quality_slider_handle": [0, 0, 0, 255], - "quality_slider_handle_hover": [127, 127, 127, 255], - "quality_slider_text": [0, 0, 0, 255], "checkbox": [255, 255, 255, 255], "checkbox_hover": [255, 255, 255, 255], @@ -245,15 +240,6 @@ "checkbox_mark": [119, 122, 124, 255], "checkbox_text": [27, 27, 27, 255], - "mode_switch": [255, 255, 255, 255], - "mode_switch_hover": [255, 255, 255, 255], - "mode_switch_border": [127, 127, 127, 255], - "mode_switch_border_hover": [50, 130, 255, 255], - "mode_switch_handle": [31, 36, 39, 255], - "mode_switch_text": [31, 36, 39, 255], - "mode_switch_text_hover": [31, 36, 39, 255], - "mode_switch_text_checked": [50, 130, 255, 255], - "tooltip": [68, 192, 255, 255], "tooltip_text": [255, 255, 255, 255], @@ -384,7 +370,6 @@ "print_setup_item": [0.0, 2.0], "print_setup_extruder_box": [0.0, 6.0], - "configuration_selector_widget": [35.0, 4.5], "configuration_selector_mode_tabs": [0.0, 3.0], "action_panel_widget": [25.0, 0.0], @@ -412,9 +397,6 @@ "extruder_icon": [1.8, 1.8], - "simple_mode_infill_caption": [0.0, 5.0], - "simple_mode_infill_height": [0.0, 8.0], - "section": [0.0, 2.2], "section_icon": [1.6, 1.6], "section_icon_column": [2.8, 0.0], @@ -428,7 +410,6 @@ "setting_text_maxwidth": [40.0, 0.0], "standard_list_lineheight": [1.5, 1.5], - "standard_list_input": [20.0, 25.0], "standard_arrow": [0.8, 0.8], "button": [4, 4], @@ -482,7 +463,6 @@ "modal_window_minimum": [60.0, 45], "license_window_minimum": [45, 45], - "wizard_progress": [10.0, 0.0], "message": [30.0, 5.0], "message_close": [1, 1], From a268c95559fcfda0e90048c666a1c9e3ed62f002 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 26 Nov 2018 17:10:56 +0100 Subject: [PATCH 0440/1292] Remove double header This header is no longer necessary since the AutoConfiguration item provides its own header that doesn't scroll along. Contributes to issue CURA-5876. --- .../Menus/ConfigurationMenu/ConfigurationListView.qml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index 7aaf87b4df..ef967dfa35 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -12,7 +12,6 @@ Column { id: base property var outputDevice: null - property var computedHeight: container.height + configurationListHeading.height + 3 * padding height: childrenRect.height + 2 * padding padding: UM.Theme.getSize("default_margin").width spacing: Math.round(UM.Theme.getSize("default_margin").height / 2) @@ -27,15 +26,6 @@ Column } } - Label - { - id: configurationListHeading - text: catalog.i18nc("@label:header configurations", "Available configurations") - font: UM.Theme.getFont("large") - width: parent.width - 2 * parent.padding - color: UM.Theme.getColor("configuration_item_text") - } - Component { id: sectionHeading From 3b219e3ac331e3404867433e1f968d2a29be4fa6 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 26 Nov 2018 17:13:25 +0100 Subject: [PATCH 0441/1292] Remove padding The padding is already done by the enveloping Column and its parent popupItem. Contributes to issue CURA-5876. --- resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index ef967dfa35..be9aad6d04 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -13,7 +13,6 @@ Column id: base property var outputDevice: null height: childrenRect.height + 2 * padding - padding: UM.Theme.getSize("default_margin").width spacing: Math.round(UM.Theme.getSize("default_margin").height / 2) function forceModelUpdate() From a03e1be6011362cb044cc589373640e60aab1e5a Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 26 Nov 2018 17:19:32 +0100 Subject: [PATCH 0442/1292] Simplify sectionHeading element No need to define that component in a higher location, just define it where you need it. Also, no need to use a Rectangle for this if it has no colour, just use an Item, but the Item itself is also not necessary if you just need the padding. Contributes to issue CURA-5876. --- .../ConfigurationListView.qml | 23 ++++++------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index be9aad6d04..25dc3fac11 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -25,21 +25,6 @@ Column } } - Component - { - id: sectionHeading - Rectangle - { - height: childrenRect.height + UM.Theme.getSize("default_margin").height - Label - { - text: section - font: UM.Theme.getFont("default_bold") - color: UM.Theme.getColor("configuration_item_text") - } - } - } - ScrollView { id: container @@ -58,7 +43,13 @@ Column section.property: "modelData.printerType" section.criteria: ViewSection.FullString - section.delegate: sectionHeading + section.delegate: Label + { + text: section + font: UM.Theme.getFont("default_bold") + color: UM.Theme.getColor("configuration_item_text") + bottomPadding: UM.Theme.getSize("default_margin").height + } model: (outputDevice != null) ? outputDevice.uniqueConfigurations : [] delegate: ConfigurationItem From a3fe9839baafe17c2c221a50c16f590d5b1acd39 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 26 Nov 2018 17:33:37 +0100 Subject: [PATCH 0443/1292] Change all uses of 'small' and 'very small' fonts to default These two fonts are exactly the same, but I want to use the 'small' font to be something a bit smaller. I'm 'removing' the superfluous font but will be re-using it immediately to look a bit smaller. Contributes to issue CURA-5876. --- .../Toolbox/resources/qml/ToolboxAuthorPage.qml | 8 ++++---- .../resources/qml/ToolboxCompatibilityChart.qml | 2 +- .../Toolbox/resources/qml/ToolboxDetailPage.qml | 16 ++++++++-------- .../resources/qml/ToolboxDownloadsGridTile.qml | 2 +- .../qml/MonitorBuildplateConfiguration.qml | 2 +- .../qml/MonitorExtruderConfiguration.qml | 4 ++-- .../qml/ActionPanel/OutputProcessWidget.qml | 4 ++-- .../qml/ActionPanel/PrintJobInformation.qml | 8 ++++---- resources/qml/ActionPanel/SliceProcessWidget.qml | 2 +- resources/qml/IconLabel.qml | 2 +- resources/qml/JobSpecs.qml | 2 +- .../ConfigurationMenu/ConfigurationListView.qml | 2 +- resources/qml/PrinterOutput/ExtruderBox.qml | 2 +- resources/qml/PrinterOutput/HeatedBedBox.qml | 2 +- .../qml/PrinterOutput/OutputDeviceHeader.qml | 4 ++-- 15 files changed, 31 insertions(+), 31 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml index 4aaea20813..9c1df0c49e 100644 --- a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml @@ -86,13 +86,13 @@ Item Label { text: catalog.i18nc("@label", "Website") + ":" - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("text_medium") } Label { text: catalog.i18nc("@label", "Email") + ":" - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("text_medium") } } @@ -118,7 +118,7 @@ Item } return "" } - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") linkColor: UM.Theme.getColor("text_link") onLinkActivated: Qt.openUrlExternally(link) @@ -134,7 +134,7 @@ Item } return "" } - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") linkColor: UM.Theme.getColor("text_link") onLinkActivated: Qt.openUrlExternally(link) diff --git a/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml b/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml index 62e1e3ab86..6a01d7ff2f 100644 --- a/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml +++ b/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml @@ -210,7 +210,7 @@ Item } return result } - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") linkColor: UM.Theme.getColor("text_link") onLinkActivated: Qt.openUrlExternally(link) diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 437a2ef351..90f372cf87 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -82,25 +82,25 @@ Item Label { text: catalog.i18nc("@label", "Version") + ":" - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("text_medium") } Label { text: catalog.i18nc("@label", "Last updated") + ":" - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("text_medium") } Label { text: catalog.i18nc("@label", "Author") + ":" - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("text_medium") } Label { text: catalog.i18nc("@label", "Downloads") + ":" - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("text_medium") } } @@ -119,7 +119,7 @@ Item Label { text: details === null ? "" : (details.version || catalog.i18nc("@label", "Unknown")) - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") } Label @@ -133,7 +133,7 @@ Item var date = new Date(details.last_updated) return date.toLocaleString(UM.Preferences.getValue("general/language")) } - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") } Label @@ -153,7 +153,7 @@ Item return "" + details.author_name + "" } } - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") linkColor: UM.Theme.getColor("text_link") onLinkActivated: Qt.openUrlExternally(link) @@ -161,7 +161,7 @@ Item Label { text: details === null ? "" : (details.download_count || catalog.i18nc("@label", "Unknown")) - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index 887140bbfa..be44c0f374 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -81,7 +81,7 @@ Item width: parent.width wrapMode: Text.WordWrap color: UM.Theme.getColor("text_medium") - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") } } } diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml index 9ffb1eabb4..7edeb81a96 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml @@ -52,7 +52,7 @@ Item id: buildplateLabel color: "#191919" // TODO: Theme! elide: Text.ElideRight - font: UM.Theme.getFont("very_small") // 12pt, regular + font: UM.Theme.getFont("default") // 12pt, regular text: "" // FIXED-LINE-HEIGHT: diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorExtruderConfiguration.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorExtruderConfiguration.qml index afbd4c3641..1e53191d8c 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorExtruderConfiguration.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorExtruderConfiguration.qml @@ -49,7 +49,7 @@ Item } color: "#191919" // TODO: Theme! elide: Text.ElideRight - font: UM.Theme.getFont("very_small") // 12pt, regular + font: UM.Theme.getFont("default") // 12pt, regular text: "" // FIXED-LINE-HEIGHT: @@ -66,7 +66,7 @@ Item } color: "#191919" // TODO: Theme! elide: Text.ElideRight - font: UM.Theme.getFont("small") // 12pt, bold + font: UM.Theme.getFont("default_bold") // 12pt, bold text: "" // FIXED-LINE-HEIGHT: diff --git a/resources/qml/ActionPanel/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml index 6f9e6a02c3..296ee2fc16 100644 --- a/resources/qml/ActionPanel/OutputProcessWidget.qml +++ b/resources/qml/ActionPanel/OutputProcessWidget.qml @@ -50,7 +50,7 @@ Column text: PrintInformation.currentPrintTime.getDisplayString(UM.DurationFormat.Long) source: UM.Theme.getIcon("clock") - font: UM.Theme.getFont("small") + font: UM.Theme.getFont("default_bold") } Cura.IconLabel @@ -79,7 +79,7 @@ Column return totalWeights + "g · " + totalLengths.toFixed(2) + "m" } source: UM.Theme.getIcon("spool") - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") } } diff --git a/resources/qml/ActionPanel/PrintJobInformation.qml b/resources/qml/ActionPanel/PrintJobInformation.qml index e53a92a994..b1172a91e0 100644 --- a/resources/qml/ActionPanel/PrintJobInformation.qml +++ b/resources/qml/ActionPanel/PrintJobInformation.qml @@ -31,7 +31,7 @@ Column { text: catalog.i18nc("@label", "Time specification").toUpperCase() color: UM.Theme.getColor("primary") - font: UM.Theme.getFont("small") + font: UM.Theme.getFont("default_bold") renderType: Text.NativeRendering } @@ -62,7 +62,7 @@ Column } width: parent.width - 2 * UM.Theme.getSize("default_margin").width color: UM.Theme.getColor("text") - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") renderType: Text.NativeRendering textFormat: Text.RichText } @@ -81,7 +81,7 @@ Column { text: catalog.i18nc("@label", "Material specification").toUpperCase() color: UM.Theme.getColor("primary") - font: UM.Theme.getFont("small") + font: UM.Theme.getFont("default_bold") renderType: Text.NativeRendering } @@ -153,7 +153,7 @@ Column } width: parent.width - 2 * UM.Theme.getSize("default_margin").width color: UM.Theme.getColor("text") - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") renderType: Text.NativeRendering textFormat: Text.RichText } diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index 09e0b2584a..9ce86463f8 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -49,7 +49,7 @@ Column text: catalog.i18nc("@label:PrintjobStatus", "Unable to Slice") source: UM.Theme.getIcon("warning") color: UM.Theme.getColor("warning") - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") } // Progress bar, only visible when the backend is in the process of slice the printjob diff --git a/resources/qml/IconLabel.qml b/resources/qml/IconLabel.qml index 7c90382892..1f15e0823f 100644 --- a/resources/qml/IconLabel.qml +++ b/resources/qml/IconLabel.qml @@ -43,7 +43,7 @@ Item anchors.verticalCenter: icon.verticalCenter text: "Empty label" color: UM.Theme.getColor("text") - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") renderType: Text.NativeRendering } } \ No newline at end of file diff --git a/resources/qml/JobSpecs.qml b/resources/qml/JobSpecs.qml index 45111992c1..717d6e925b 100644 --- a/resources/qml/JobSpecs.qml +++ b/resources/qml/JobSpecs.qml @@ -124,7 +124,7 @@ Item { } height: UM.Theme.getSize("jobspecs_line").height verticalAlignment: Text.AlignVCenter - font: UM.Theme.getFont("small") + font: UM.Theme.getFont("default_bold") color: UM.Theme.getColor("text_scene") text: CuraApplication.getSceneBoundingBoxString } diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index 25dc3fac11..8a7094497e 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -46,7 +46,7 @@ Column section.delegate: Label { text: section - font: UM.Theme.getFont("default_bold") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("configuration_item_text") bottomPadding: UM.Theme.getSize("default_margin").height } diff --git a/resources/qml/PrinterOutput/ExtruderBox.qml b/resources/qml/PrinterOutput/ExtruderBox.qml index 510a44f9da..d72f9ba0b2 100644 --- a/resources/qml/PrinterOutput/ExtruderBox.qml +++ b/resources/qml/PrinterOutput/ExtruderBox.qml @@ -45,7 +45,7 @@ Item { id: extruderTargetTemperature text: Math.round(extruderModel.targetHotendTemperature) + "°C" - font: UM.Theme.getFont("small") + font: UM.Theme.getFont("default_bold") color: UM.Theme.getColor("text_inactive") anchors.right: parent.right anchors.rightMargin: UM.Theme.getSize("default_margin").width diff --git a/resources/qml/PrinterOutput/HeatedBedBox.qml b/resources/qml/PrinterOutput/HeatedBedBox.qml index 962ffa9b01..59f7fa7bc6 100644 --- a/resources/qml/PrinterOutput/HeatedBedBox.qml +++ b/resources/qml/PrinterOutput/HeatedBedBox.qml @@ -34,7 +34,7 @@ Item { id: bedTargetTemperature text: printerModel != null ? printerModel.targetBedTemperature + "°C" : "" - font: UM.Theme.getFont("small") + font: UM.Theme.getFont("default_bold") color: UM.Theme.getColor("text_inactive") anchors.right: parent.right anchors.rightMargin: UM.Theme.getSize("default_margin").width diff --git a/resources/qml/PrinterOutput/OutputDeviceHeader.qml b/resources/qml/PrinterOutput/OutputDeviceHeader.qml index b5ed1b7b4e..4e81d852bb 100644 --- a/resources/qml/PrinterOutput/OutputDeviceHeader.qml +++ b/resources/qml/PrinterOutput/OutputDeviceHeader.qml @@ -43,7 +43,7 @@ Item { id: outputDeviceAddressLabel text: (outputDevice != null && outputDevice.address != null) ? outputDevice.address : "" - font: UM.Theme.getFont("small") + font: UM.Theme.getFont("default_bold") color: UM.Theme.getColor("text_inactive") anchors.top: parent.top anchors.right: parent.right @@ -54,7 +54,7 @@ Item { text: outputDevice != null ? "" : catalog.i18nc("@info:status", "The printer is not connected.") color: outputDevice != null && outputDevice.acceptsCommands ? UM.Theme.getColor("setting_control_text") : UM.Theme.getColor("setting_control_disabled_text") - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") wrapMode: Text.WordWrap anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("default_margin").width From a3b45ff2039c22981643ff501780ee016f9a2bef Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 26 Nov 2018 17:35:23 +0100 Subject: [PATCH 0444/1292] Simplify the viewOrientation controls --- resources/qml/ViewOrientationButton.qml | 16 +++++++++++++++ resources/qml/ViewOrientationControls.qml | 24 +++++++---------------- 2 files changed, 23 insertions(+), 17 deletions(-) create mode 100644 resources/qml/ViewOrientationButton.qml diff --git a/resources/qml/ViewOrientationButton.qml b/resources/qml/ViewOrientationButton.qml new file mode 100644 index 0000000000..682fd71b4e --- /dev/null +++ b/resources/qml/ViewOrientationButton.qml @@ -0,0 +1,16 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 + +import UM 1.4 as UM + +UM.SimpleButton +{ + width: UM.Theme.getSize("small_button").width + height: UM.Theme.getSize("small_button").height + hoverBackgroundColor: UM.Theme.getColor("small_button_hover") + hoverColor: UM.Theme.getColor("small_button_text_hover") + color: UM.Theme.getColor("small_button_text") + iconMargin: 0.5 * UM.Theme.getSize("wide_lining").width +} \ No newline at end of file diff --git a/resources/qml/ViewOrientationControls.qml b/resources/qml/ViewOrientationControls.qml index acf75b1b48..51ed6e3dcb 100644 --- a/resources/qml/ViewOrientationControls.qml +++ b/resources/qml/ViewOrientationControls.qml @@ -7,7 +7,7 @@ import QtQuick.Controls.Styles 1.1 import UM 1.4 as UM -// View orientation Item +// A row of buttons that control the view direction Row { id: viewOrientationControl @@ -16,43 +16,33 @@ Row height: childrenRect.height width: childrenRect.width - // #1 3d view - Button + ViewOrientationButton { iconSource: UM.Theme.getIcon("view_3d") - style: UM.Theme.styles.small_tool_button - onClicked:UM.Controller.rotateView("3d", 0) + onClicked: UM.Controller.rotateView("3d", 0) } - // #2 Front view - Button + ViewOrientationButton { iconSource: UM.Theme.getIcon("view_front") - style: UM.Theme.styles.small_tool_button onClicked: UM.Controller.rotateView("home", 0) } - // #3 Top view - Button + ViewOrientationButton { iconSource: UM.Theme.getIcon("view_top") - style: UM.Theme.styles.small_tool_button onClicked: UM.Controller.rotateView("y", 90) } - // #4 Left view - Button + ViewOrientationButton { iconSource: UM.Theme.getIcon("view_left") - style: UM.Theme.styles.small_tool_button onClicked: UM.Controller.rotateView("x", 90) } - // #5 Right view - Button + ViewOrientationButton { iconSource: UM.Theme.getIcon("view_right") - style: UM.Theme.styles.small_tool_button onClicked: UM.Controller.rotateView("x", -90) } } From 7f2f2090da66caa3686de27c3f5d6474aeeab8fe Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 26 Nov 2018 17:35:58 +0100 Subject: [PATCH 0445/1292] Make small and very_small fonts actually smaller Rather than the same as default_bold and default. This also makes the extruder_icon font obsolete. Turns out it's actually just a very small font. Contributes to issue CURA-5876. --- resources/qml/ExtruderIcon.qml | 2 +- resources/themes/cura-light/theme.json | 12 +++--------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/resources/qml/ExtruderIcon.qml b/resources/qml/ExtruderIcon.qml index c103ee245c..7151719fb9 100644 --- a/resources/qml/ExtruderIcon.qml +++ b/resources/qml/ExtruderIcon.qml @@ -49,7 +49,7 @@ Item id: extruderNumberText anchors.centerIn: parent text: index + 1 - font: UM.Theme.getFont("extruder_icon") + font: UM.Theme.getFont("very_small") width: contentWidth height: contentHeight visible: extruderEnabled diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 57007827a8..a51b397262 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -41,12 +41,12 @@ "family": "Noto Sans" }, "small": { - "size": 1.0, - "weight": 63, + "size": 0.85, + "weight": 50, "family": "Noto Sans" }, "very_small": { - "size": 1.0, + "size": 0.7, "weight": 50, "family": "Noto Sans" }, @@ -64,12 +64,6 @@ "size": 1.15, "weight": 50, "family": "Noto Sans" - }, - "extruder_icon": - { - "size": 0.7, - "weight": 50, - "family": "Noto Sans" } }, From 5ddb3ff90994bd5e5579fc6a8f8ecaeac81a6859 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 26 Nov 2018 17:40:34 +0100 Subject: [PATCH 0446/1292] Factor out superfluous use of small_tool_button style The style was overly complicated for what it should do --- .../SimulationViewMainComponent.qml | 11 +- resources/themes/cura-light/styles.qml | 112 ------------------ 2 files changed, 8 insertions(+), 115 deletions(-) diff --git a/plugins/SimulationView/SimulationViewMainComponent.qml b/plugins/SimulationView/SimulationViewMainComponent.qml index 4e038a1cf1..16b9aeaae6 100644 --- a/plugins/SimulationView/SimulationViewMainComponent.qml +++ b/plugins/SimulationView/SimulationViewMainComponent.qml @@ -6,7 +6,7 @@ import QtQuick.Controls 1.2 import QtQuick.Layouts 1.1 import QtQuick.Controls.Styles 1.1 -import UM 1.0 as UM +import UM 1.4 as UM import Cura 1.0 as Cura Item @@ -55,11 +55,16 @@ Item } - Button + UM.SimpleButton { id: playButton iconSource: !is_simulation_playing ? "./resources/simulation_resume.svg": "./resources/simulation_pause.svg" - style: UM.Theme.styles.small_tool_button + width: UM.Theme.getSize("small_button").width + height: UM.Theme.getSize("small_button").height + hoverBackgroundColor: UM.Theme.getColor("small_button_hover") + hoverColor: UM.Theme.getColor("small_button_text_hover") + color: UM.Theme.getColor("small_button_text") + iconMargin: 0.5 * UM.Theme.getSize("wide_lining").width visible: !UM.SimulationView.compatibilityMode Connections diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index f4aeb95bb3..f00aab44c0 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -436,118 +436,6 @@ QtObject } } - property Component small_tool_button: Component - { - ButtonStyle - { - background: Item - { - implicitWidth: Theme.getSize("small_button").width; - implicitHeight: Theme.getSize("small_button").height; - - Rectangle - { - id: smallButtonFace; - - anchors.fill: parent; - property bool down: control.pressed || (control.checkable && control.checked); - - color: - { - if(control.customColor !== undefined && control.customColor !== null) - { - return control.customColor - } - else if(control.checkable && control.checked && control.hovered) - { - return Theme.getColor("small_button_active_hover"); - } - else if(control.pressed || (control.checkable && control.checked)) - { - return Theme.getColor("small_button_active"); - } - else if(control.hovered) - { - return Theme.getColor("small_button_hover"); - } - else - { - return Theme.getColor("small_button"); - } - } - Behavior on color { ColorAnimation { duration: 50; } } - - border.width: (control.hasOwnProperty("needBorder") && control.needBorder) ? 2 * screenScaleFactor : 0 - border.color: Theme.getColor("tool_button_border") - - UM.RecolorImage - { - id: smallToolButtonArrow - - width: 5 - height: 5 - sourceSize.width: 5 - sourceSize.height: 5 - visible: control.menu != null; - color: - { - if(control.checkable && control.checked && control.hovered) - { - return Theme.getColor("small_button_text_active_hover"); - } - else if(control.pressed || (control.checkable && control.checked)) - { - return Theme.getColor("small_button_text_active"); - } - else if(control.hovered) - { - return Theme.getColor("small_button_text_hover"); - } - else - { - return Theme.getColor("small_button_text"); - } - } - source: Theme.getIcon("arrow_bottom") - } - } - } - - label: Item - { - UM.RecolorImage - { - anchors.centerIn: parent - opacity: !control.enabled ? 0.2 : 1.0 - source: control.iconSource; - width: Theme.getSize("small_button_icon").width - height: Theme.getSize("small_button_icon").height - color: - { - if(control.checkable && control.checked && control.hovered) - { - return Theme.getColor("small_button_text_active_hover"); - } - else if(control.pressed || (control.checkable && control.checked)) - { - return Theme.getColor("small_button_text_active"); - } - else if(control.hovered) - { - return Theme.getColor("small_button_text_hover"); - } - else - { - return Theme.getColor("small_button_text"); - } - } - - sourceSize: Theme.getSize("small_button_icon") - } - } - } - } - property Component progressbar: Component { ProgressBarStyle From ad3fa9548a2c78f484fef42336670be822335e8f Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 26 Nov 2018 17:53:38 +0100 Subject: [PATCH 0447/1292] Add sourceSize to the open file button. Contributes to CURA-5942. --- plugins/PrepareStage/PrepareMenu.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index a953c2b5d1..81799206a0 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -101,7 +101,8 @@ Item height: UM.Theme.getSize("button_icon").height color: UM.Theme.getColor("toolbar_button_text") - sourceSize: UM.Theme.getSize("button_icon") + sourceSize.width: width + sourceSize.height: height } background: Rectangle From fcc6af68af76db114875479066a63c8660785670 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 26 Nov 2018 17:55:25 +0100 Subject: [PATCH 0448/1292] Don't show the current checked version of the firmware if the version number we gather is ZERO. That means that there was a problem getting the right value. Contributes to CURA-5980. --- plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py b/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py index 4c60b95824..9efd3e956a 100644 --- a/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py +++ b/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py @@ -93,6 +93,11 @@ class FirmwareUpdateCheckerJob(Job): current_version = self.getCurrentVersion() + # This case indicates that was an error checking the version. + # It happens for instance when not connected to internet. + if current_version == self.ZERO_VERSION: + return + # If it is the first time the version is checked, the checked_version is "" setting_key_str = getSettingsKeyForMachine(machine_id) checked_version = Version(Application.getInstance().getPreferences().getValue(setting_key_str)) From 519e2a3399b69e41af048212c45eda6492d7d773 Mon Sep 17 00:00:00 2001 From: pinchies Date: Tue, 27 Nov 2018 15:06:54 +1100 Subject: [PATCH 0449/1292] uploaded wrong file... oops --- .../extruders/alfawise_u20_extruder_0.def.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 resources/extruders/alfawise_u20_extruder_0.def.json diff --git a/resources/extruders/alfawise_u20_extruder_0.def.json b/resources/extruders/alfawise_u20_extruder_0.def.json new file mode 100644 index 0000000000..2fbe3f1772 --- /dev/null +++ b/resources/extruders/alfawise_u20_extruder_0.def.json @@ -0,0 +1,16 @@ +{ + "id": "alfawise_u20_extruder_0", + "version": 2, + "name": "Extruder 1", + "inherits": "fdmextruder", + "metadata": { + "machine": "alfawise_u20", + "position": "0" + }, + + "overrides": { + "extruder_nr": { "default_value": 0 }, + "machine_nozzle_size": { "default_value": 0.4 }, + "material_diameter": { "default_value": 1.75 } + } +} \ No newline at end of file From 47ed9e3f5db99114f30c884cea413dc4949544ec Mon Sep 17 00:00:00 2001 From: pinchies Date: Tue, 27 Nov 2018 15:09:36 +1100 Subject: [PATCH 0450/1292] deleting the old wrong file.... --- resources/extruders/alfawise_u20.def.json | 96 ----------------------- 1 file changed, 96 deletions(-) delete mode 100644 resources/extruders/alfawise_u20.def.json diff --git a/resources/extruders/alfawise_u20.def.json b/resources/extruders/alfawise_u20.def.json deleted file mode 100644 index f6dccce3ee..0000000000 --- a/resources/extruders/alfawise_u20.def.json +++ /dev/null @@ -1,96 +0,0 @@ -{ - "name": "Alfawise U20", - "version": 2, - "inherits": "fdmprinter", - "metadata": { - "visible": true, - "author": "Samuel Pinches", - "manufacturer": "Alfawise", - "file_formats": "text/x-gcode", - "preferred_quality_type": "fine", - "machine_extruder_trains": - { - "0": "alfawise_u20_extruder_0" - } - }, - "overrides": { - "machine_name": { - "default_value": "Alfawise U20" - }, - "machine_start_gcode": { - "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F6000 ;move Z to position 15.0 mm as fast as possible\nG92 E0 ;zero the extruded length\nG1 X0.0 Y0.0 F1000.0 ;go to edge of print area\nG1 X60.0 E9.0 F1000.0 ;intro line\nG1 X100.0 E21.5 F1000.0 ;intro line\nG92 E0 ;zero the extruded length again\n; -- end of START GCODE --" - }, - "machine_end_gcode": { - "default_value": "; -- END GCODE --\nM104 S0 ;turn off nozzle heater\nM140 S0 ;turn off bed heater\nG91 ;set to relative positioning\nG1 E-10 F300 ;retract the filament slightly\nG90 ;set to absolute positioning\nG28 X0 ;move to the X-axis origin (Home)\nG0 Y280 F600 ;bring the bed to the front for easy print removal\nM84 ;turn off stepper motors\n; -- end of END GCODE --" - }, - "machine_width": { - "default_value": 300 - }, - "machine_height": { - "default_value": 400 - }, - "machine_depth": { - "default_value": 300 - }, - "machine_heated_bed": { - "default_value": true - }, - "machine_center_is_zero": { - "default_value": false - }, - "gantry_height": { - "default_value": 10 - }, - "machine_gcode_flavor": { - "default_value": "RepRap (Marlin/Sprinter)" - }, - "material_diameter": { - "default_value": 1.75 - }, - "material_print_temperature": { - "default_value": 210 - }, - "material_bed_temperature": { - "default_value": 50 - }, - "layer_height": { - "default_value": 0.15 - }, - "layer_height_0": { - "default_value": 0.2 - }, - "wall_thickness": { - "default_value": 1.2 - }, - "speed_print": { - "default_value": 40 - }, - "speed_infill": { - "default_value": 40 - }, - "speed_wall": { - "default_value": 35 - }, - "speed_topbottom": { - "default_value": 35 - }, - "speed_travel": { - "default_value": 120 - }, - "speed_layer_0": { - "default_value": 20 - }, - "support_enable": { - "default_value": true - }, - "retraction_enable": { - "default_value": true - }, - "retraction_amount": { - "default_value": 5 - }, - "retraction_speed": { - "default_value": 45 - } - } -} \ No newline at end of file From 2e81b97623d542c23f7f0243871269e238e8fae9 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 27 Nov 2018 08:45:42 +0100 Subject: [PATCH 0451/1292] Use global_stack.extruders to find extruders CURA-5978 --- cura/Settings/MachineManager.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index f321ce94a6..f7ad108ad4 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -909,20 +909,14 @@ class MachineManager(QObject): # After CURA-4482 this should not be the case anymore, but we still want to support older project files. global_user_container = self._global_container_stack.userChanges - # Make sure extruder_stacks exists - extruder_stacks = [] #type: List[ExtruderStack] - - if previous_extruder_count == 1: - extruder_stacks = ExtruderManager.getInstance().getActiveExtruderStacks() - global_user_container = self._global_container_stack.userChanges - for setting_instance in global_user_container.findInstances(): setting_key = setting_instance.definition.key settable_per_extruder = self._global_container_stack.getProperty(setting_key, "settable_per_extruder") if settable_per_extruder: limit_to_extruder = int(self._global_container_stack.getProperty(setting_key, "limit_to_extruder")) - extruder_stack = extruder_stacks[max(0, limit_to_extruder)] + extruder_position = str(max(0, limit_to_extruder)) + extruder_stack = self._global_container_stack.extruders[extruder_position] extruder_stack.userChanges.setProperty(setting_key, "value", global_user_container.getProperty(setting_key, "value")) global_user_container.removeInstance(setting_key) From ec63e6c13066d307238a7e176f04adee8df1dbf3 Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Tue, 27 Nov 2018 09:27:25 +0100 Subject: [PATCH 0452/1292] Added icons CURA-5941 --- resources/qml/SidebarSimple.qml | 53 ++++++--------------------------- 1 file changed, 9 insertions(+), 44 deletions(-) diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index 52fc9320f2..2e0f0d6c4c 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -192,13 +192,15 @@ Item id: qualityRowTitle source: UM.Theme.getIcon("category_layer_height") text: catalog.i18nc("@label", "Layer Height") + anchors.bottom: speedSlider.bottom + } // Show titles for the each quality slider ticks Item { - y: -5; anchors.left: speedSlider.left + anchors.top: speedSlider.bottom Repeater { model: qualityModel @@ -206,8 +208,7 @@ Item Label { anchors.verticalCenter: parent.verticalCenter - anchors.top: parent.top - anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height / 2) + anchors.top: parent.bottom color: (Cura.MachineManager.activeMachine != null && Cura.QualityProfilesDropDownMenuModel.getItem(index).available) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") text: { @@ -258,7 +259,7 @@ Item } //Print speed slider - Item + Rectangle { id: speedSlider width: Math.round(base.width * 0.55) @@ -367,12 +368,12 @@ Item Rectangle { - anchors.verticalCenter: parent.verticalCenter color: Cura.QualityProfilesDropDownMenuModel.getItem(index).available ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") - width: 1 * screenScaleFactor - height: 6 * screenScaleFactor - y: 0 + implicitWidth: 5 * screenScaleFactor + implicitHeight: implicitWidth + anchors.verticalCenter: qualitySlider.verticalCenter x: Math.round(qualityModel.qualitySliderStepWidth * index) + radius: Math.round(implicitWidth / 2) } } @@ -453,42 +454,6 @@ Item } } - Label - { - id: speedLabel - anchors.top: speedSlider.bottom - - anchors.left: parent.left - - text: catalog.i18nc("@label", "Print Speed") - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - width: Math.round(UM.Theme.getSize("print_setup_widget").width * 0.35) - elide: Text.ElideRight - } - - Label - { - anchors.bottom: speedLabel.bottom - anchors.left: speedSlider.left - - text: catalog.i18nc("@label", "Slower") - font: UM.Theme.getFont("default") - color: (qualityModel.availableTotalTicks > 1) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") - horizontalAlignment: Text.AlignLeft - } - - Label - { - anchors.bottom: speedLabel.bottom - anchors.right: speedSlider.right - - text: catalog.i18nc("@label", "Faster") - font: UM.Theme.getFont("default") - color: (qualityModel.availableTotalTicks > 1) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") - horizontalAlignment: Text.AlignRight - } - UM.SimpleButton { id: customisedSettings From 4be8af7cb278fc8f1a7118d1cfbc9ba02d47cd80 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 27 Nov 2018 09:38:32 +0100 Subject: [PATCH 0453/1292] Restyle printer type headers It's now a grey box with the printer type name inside and some padding and such. Contributes to issue CURA-5876. --- .../ConfigurationListView.qml | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index 8a7094497e..2f5bf0b1a2 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -43,12 +43,24 @@ Column section.property: "modelData.printerType" section.criteria: ViewSection.FullString - section.delegate: Label + section.delegate: Item { - text: section - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("configuration_item_text") - bottomPadding: UM.Theme.getSize("default_margin").height + height: printerTypeLabelBox.height + UM.Theme.getSize("default_margin").height + Rectangle + { + id: printerTypeLabelBox + color: UM.Theme.getColor("text_detail") + width: childrenRect.width + height: childrenRect.height + + Label + { + text: section + font: UM.Theme.getFont("small") + color: UM.Theme.getColor("configuration_item_text") + padding: UM.Theme.getSize("narrow_margin").width + } + } } model: (outputDevice != null) ? outputDevice.uniqueConfigurations : [] From 8e7e8354e7196b1e449f43f89c7aa521b9d43931 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 27 Nov 2018 09:41:45 +0100 Subject: [PATCH 0454/1292] Set colors to the correct ones --- resources/themes/cura-light/theme.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 67e0c701c2..fdc5b2a2de 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -86,8 +86,8 @@ "primary_hover": [48, 182, 231, 255], "primary_text": [255, 255, 255, 255], "border": [127, 127, 127, 255], - "secondary": [245, 245, 245, 255], - "secondary_shadow": [228, 228, 228, 255], + "secondary": [240, 240, 240, 255], + "secondary_shadow": [216, 216, 216, 255], "primary_button": [38, 113, 231, 255], "primary_button_shadow": [27, 95, 202, 255], @@ -95,7 +95,7 @@ "primary_button_text": [255, 255, 255, 255], "secondary_button": [240, 240, 240, 255], - "secondary_button_shadow": [228, 228, 228, 255], + "secondary_button_shadow": [216, 216, 216, 255], "secondary_button_hover": [228, 228, 228, 255], "secondary_button_text": [30, 102, 215, 255], From bd42136712e63abc8043a41ce1004275f4f94d5f Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 27 Nov 2018 09:49:35 +0100 Subject: [PATCH 0455/1292] Fix GcodeStartEndFormatter to use fallback values CURA-5901 Use values from the global stack (if exist) as fallback values. --- plugins/CuraEngineBackend/StartSliceJob.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index 79b1e5249c..273dc0b6f6 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -66,11 +66,19 @@ class GcodeStartEndFormatter(Formatter): return "{" + key + "}" key = key_fragments[0] - try: - return kwargs[str(extruder_nr)][key] - except KeyError: + + default_value_str = "{" + key + "}" + value = default_value_str + # "-1" is global stack, and if the setting value exists in the global stack, use it as the fallback value. + if key in kwargs["-1"]: + value = kwargs["-1"] + if key in kwargs[str(extruder_nr)]: + value = kwargs[str(extruder_nr)][key] + + if value == default_value_str: Logger.log("w", "Unable to replace '%s' placeholder in start/end g-code", key) - return "{" + key + "}" + + return value ## Job class that builds up the message of scene data to send to CuraEngine. From 39e1cfd6bc080cb193191a1d8472a30b3fb21274 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 27 Nov 2018 09:50:01 +0100 Subject: [PATCH 0456/1292] Fix indentation. Contributes to CURA-5902. --- resources/definitions/alfawise_u20.def.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/definitions/alfawise_u20.def.json b/resources/definitions/alfawise_u20.def.json index abc206c4d2..87726fec3d 100644 --- a/resources/definitions/alfawise_u20.def.json +++ b/resources/definitions/alfawise_u20.def.json @@ -83,7 +83,7 @@ "support_enable": { "default_value": true }, - "retraction_enable": { + "retraction_enable": { "default_value": true }, "retraction_amount": { From edf8460619d9228a00154632abb76a88c2793ab3 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 27 Nov 2018 10:35:19 +0100 Subject: [PATCH 0457/1292] Return empty material model for empty material CURA-5982 --- plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index 8314b0f089..f8726a5441 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -593,6 +593,15 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): def _createMaterialOutputModel(self, material_data: Dict[str, Any]) -> "MaterialOutputModel": material_manager = CuraApplication.getInstance().getMaterialManager() material_group_list = material_manager.getMaterialGroupListByGUID(material_data["guid"]) + # This can happen if the connected machine has no material in one or more extruders, so we should return an + # "empty" material model. + if material_group_list is None: + return MaterialOutputModel(guid = material_data["guid"], + type = material_data.get("type", ""), + color = material_data.get("color", ""), + brand = material_data.get("brand", ""), + name = material_data.get("name", "Empty") + ) # Sort the material groups by "is_read_only = True" first, and then the name alphabetically. read_only_material_group_list = list(filter(lambda x: x.is_read_only, material_group_list)) From 0cd9c8e0870e1ace2bb6add479b5fb5f83863d37 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 27 Nov 2018 10:52:49 +0100 Subject: [PATCH 0458/1292] Add machine images Contributes to CL-1150 --- .../resources/png/ultimaker_3.png | Bin 0 -> 792765 bytes .../resources/png/ultimaker_3_ext.png | Bin 0 -> 1038742 bytes .../resources/png/ultimaker_s5.png | Bin 0 -> 1476464 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 plugins/UM3NetworkPrinting/resources/png/ultimaker_3.png create mode 100644 plugins/UM3NetworkPrinting/resources/png/ultimaker_3_ext.png create mode 100644 plugins/UM3NetworkPrinting/resources/png/ultimaker_s5.png diff --git a/plugins/UM3NetworkPrinting/resources/png/ultimaker_3.png b/plugins/UM3NetworkPrinting/resources/png/ultimaker_3.png new file mode 100644 index 0000000000000000000000000000000000000000..4639cb3fde2c32574ce6743fd3515a7c38aa1290 GIT binary patch literal 792765 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 z ziszhTc>LkVdFh|Lo;!Z}7?+%@S(sH^_7CsnJ(quqg$2#C&Pn<4jkoicfBq`=?OEoz z=Ooxc!OQ;YO?>VPH*)^Dnp3uDKJ>wBxb)I@Fr8?gcYe;%{fBwkOJB!LKiti;E=<_G zLGzZke2DkF`;*MiB|P{1lv{4RoxgqArR?3a#Pgn!qO9ldUU3jpxnCT{5a&gYCTkqlJ zFM9JTtQWS9J>1R;-oG*R-IAPkj0swrrc_^wVa!_L}Q>-RoY<;iChdamfOY?>WRPU->ew{qi?C z`@DI2-4-9X`~$rAeIEne=G^ntmdEL7Tx~mAAe5@4505pQqPL*}5&~ znyWv}JKp?u_8%N@&iOgJ?z)@TU;0;k?Hf0-bw@^$dOr4{xAB1we1u7o@bLKfI{newq`<<`h>d#(Br<<^_!Eo*8KE=D={zmp4SYzjzhI{Y4jkmwy zrF`?-KVi%El)R<+_?7SB10Q@pg*BXZM#lHQ|25wJmRE7dZF|^x`bG{NdW>6c{uZ5l zE6;k~FR=40_}phc&fDMeI(F?o%xPzJIdtF=uK4hqxc1tcSzd*eF5FgS+qK#vAYDOV@v%(TP1^9k=}SK0f`)8@d0sZ_@1~ z?Aw2oFI{^t*L~?zOp2pS%aU7eet;{k_y+ggc_TAj&7+SV;!~f!pKHJLX%wq0uk^X` zJCAb3M?cNJM|aWA;jZ0}a^)3E(@>TfBG1k^jaPv+3x$26`Sv zaX$Nr53siSApOA#`yU(g$&Y=QU3YvHS1fbl$O*o2!-HIR&BvII_p`dX%p(s^x$;Br zV$VZ2G9IrmT%L0M7k|VJ*I$Jn9%gmv1b5#x;FBMHCo9MAV>Ddm#6h^`Q(xew8^6GK zc$~GxgPb^Vga>xr!eIFrD9yn`YkcRMU*Y(XgA`s-mX14aTj2wjU&+eyJ!ERi%83*F z@H?O3_@Vo7E@L#Fuo&gj`Fmf-;Mfm%?8unI zOPl%NJKoCf+dsv_k3Yt!zkzRlRn`XE z_{0Z4!wuKHm&5yZabh*&CwGr{_d73Rao<-taI|E(e+nOd*Sq-94?fHz`wlVeZ{Zu? zxStPw=q)Vn`vFH!Bpf=vf%m-m^*p%yvplwcnbGu2zWDj?@R=*#&XIk0QMe5}_*lxD zU;hdY?fn7=4;x6I#Yf)%0lxFqxAEBHhse_l_}=&S^47P!hC_R9U@)9zWq3O8c*EJh}{zw4cNESH71M-+VobkM8B(_W6AM z$B*%Ycl|Bw|2lWC&G4<|Q~2tKFJp512YLL+gk7T@Ty@1K*n9muDfisY9=(}+_G`ZS z!Pijk{ydKyEh+U`eC4xW_Qh|Yz;DF=Jm%WlZ ze{uyAw~bRydmbNq-v_w%vzPM7p)qIg{AF(a!EL{Hoo)K z*YWsb!WpN(kQ=W59+$u4HSE6cZcg3uOpYEiyzR0}*>(HJSQ^c-VdHc7;#F62&8IHq z(S1wo*!nzf`|%^Z{mp;JgLi%f-8vn|d3^M}Z{enIy@kC;EjzY7pKpEnTfF}rui^fC zf6B&9&tU09kGH9_Nfo3G%pL(AmpHg5aLkNC`I-ocRryI38Sm?Y=UAANyGAN>(a{VB!J zvg@`x`O&R6abVwlfM+tA@}uuw!2@@FnL=I2kz+%?`Q;Duz`gfyeCY&BD=Qq@e}a4N z-Nn-KaZD>iwKntBFMNo*e{?wy?;p_V{Vd=5;>Y>&=U&gA2kypqc5>`+%6s1Q7d&v! zr#Nstq1SyLpZ(Zd_{Q~@a?b<%*|PNo+<*H6y#0-T#N!Wrov}Lwqt4^Q@BAP9;r$x19#oR+?I>zuXcI&TVKLGw|hglwWIOmL?=LcW^EZ1KB79M!?5a*urV*1Ap^O-B&$ZbFV z9!d9f&fa-Gw|whbzWk+k^XTDap8m97=g|H4@Uaj6J-6L{C)>6^kIkKpeCtc^=X>A! zILiaYd1w3rcisFAuKWCZ+5OO?oN?wal1$e4!l&NOkG}I|rh0*k&%K2EZ~8i){KOl1 z@X>voclHY?`^Wj}^;fZH{~qQxpT>?27jx^4*Yfo*U%|d3E1Yra&vE#{d-%l1-^@La zKElk*Gg&)o`TQr|!8gACHHz$97Us|3nooS0FMRU#Jb1j#bDr}8zW0sWdDCUD;`=w= z%IW9)0;6$5yn+>G*kq65!Ka@ zR7I?)np7m#fony?hY^bVilw5${EsRKTwzPyz?V|b(CnBNyI;kc6TBhTPAR3ufr%k} z7q1C6I7TWsEArol(m}76)6J8U(Dr)F8~;20dpsWRee;{&{1u);hT-Jzc``>Kp>Euf zg+KZ3-S_{+dFP-1-vuDAzqWfahXEPEaPZIy!_^hEa@eAzEDM}3ab=0~E)2E_pHQ~q zX~pTds!A34dLYe7o>VMmi5u8#pIN;Ek1W1njhT9=Me;vIYM*tGdH#@4at;40T&cPGosj-n_?^EU0)4AwjP!#;S+#toZrI%Cvd zr5vx4v^$vA4BlBrYpWzmF}JXQHZ7KxkJIlj(do^R=54fvwUtHkOtWF*CcM`iJ#m7i z)f3Fmw3(fqXHra9KCwocYc_4!O20qg*ntBm?bxzqJ89lwW#u@N!GO8BIa-|_!~QDA zj~ydP6Xq7?Fgj!L#4$$05xtG`w9=gZ(jqI%Ys}1a=xvxKH5tbbA7)xkn46tNCx+qb z3Tvxt^fqjuH!D2-LkAC{P0Ggk4Om;SxOAMNn6h!>W?J1IlhJ_1&>9;h%7TKY}!JSwCNX)M<06xYj-lY zu#JNU@1h(nfu54II-I)YR7~PIdi+qB$1$ZGO|YfMCMi31p3h9T%W%5J^5St?NyhBl zMyAfwUt2=ilG%;hFeYa-SYd5-iB_w{{D$pJtYvL!fLEU0#to!N#@ga>CKE@ioiW?% zF}0Rqe?YEbcCN?7d-^MDxYE(>b;+|1#dJu2G$qlBh4}@>u3%+x1&v~MVTM-TVlW&q z8cmsPb?EiltPBS%p6D|>(_&$vhjY;Hj~R^%I^B$RD`(OlF&=yJmZCR1!_>jr$^d5z zX6Jestyt}^QH&IwZbGluX4oIGwlW||A;~kWgYkGoF)r!O2C;a#D~c&}#QE2HIIknzh-mVTKJ0^Q??4&T2ZT zr#IJSFrKiyG@vLPtqi)o4hN1cb8u-y;->W4EtagKKQ8g*lvbY5GC9jr$FYfJA@^*} zQkJJ9mPu%5gu*p#1Mw9!3j!v21 za0;8|TFiGktV|2mR##YEJjl^fG0-XAgVl!lM6r;!SagmPV@GGa%tFh6&KNn3Njw`` z37w?H@zIcDg<^vnu%*+XZ`$;&rrdP=X?W;FJo<|w9%EX*1P;}MHXQ`B@qNy&-DHBKx|QEGw2tzwcX%R`UR z^C-7OJJ(p9Q^Xo9nS^4u{k3|=kZ{0U~-8N;a}Q5~kkC7ha|mB*FJa@&;EVly;Rg^-N8NG?^uto*>nVerdraOeZ6R`GPR6LpmjcTy^LghKUtoF zF}P`g!r@fHU_8Kjg)tp^d53Pd!-O197wuL_m80+_NjihFDTB!g+DU>nEwt(3#>dcD zCQg&KHsB@$oLwW)8lBFAP8bi5;+$jRa%MUkp*X>)7*Kl6OnVc~PZ_Kp5E^whPdi^= zIy{E66Q3yPMfC(_=b3!HKms3UanAY$NppmKF~)DoT2DTbb|m z7_A*+d2NMKx7gU5qh(4CFCC{pE!ezp3JWtG78eh(GFU}tJ^9GfPLbk@=kyU1 z4F8Nb$GHKKU!-+{xAnlY>ef{KkXpx9jNv`iFd1KQ&Eh?1)H-Ludr&6)EqtS@D^h&F zEK4J^;p?Z0^$)r#gsvaQhfG9tXno@|N?8a~gH9IYy09BYg9+VMm;d;mev?*Pp@n)% zQ6L?I3@9zdUCztzV)w_8wZbISH63C7T&B+FNM`nHtMJLKGjGgGaxwek$uYJ1QcbP{^5J9#$m zT5_C~`*9A&697w^XtarG$=X4T*C`55mdO6NGNc5Z{B0FD zSK!g4si|7hI$NKOvXpKiX-ktNnsyF@K795wUu5ynU7WVH!`6AjIp?0r_ES&8`kbYH z!Grq>{>}gSTvkUJmw)7bCetG@d6e1Nd4BGB&u6&uFo*X)icuL4+y`CPKR z%_YyckgcaIFqsS~iV|&7zy!r3PIr>!I1I&jDuu}l^JIB~a!^<>X{|S1=-`k98P&*I zXd?r_yptk$ymaRZo$cgvx_(bFm32+CKrsy6>P#3uU07N3ER$k>1x%+RE5?Wn+tBSJ zO=T}pFqw*swL@>tku<}S`&Du;lZkv+lE`}}V-db?%Sd>|ddg`DIw4IY-&D^Yf zZ>B_kA3SW?b#O}Q4Vf+IW`=gJMUq3}J-RHJA}#;A225F^4EQu*8hWE9#T1{W=#H+= zYLdwwI19yC6hW(_$Ww3yv~sv`yF{m`Ro1#Nlt1a;@ihXDoq)ajCyYmyZl{CSFrJi5 zCqvRSqn)?V3fB5-cp%L>_|j1nW2`U8TV3)rqby5?!#+kQBzcFjoH7{<@W_;PturRm z5tGpXok&qJ4*J7B%4j;B89-x;A)~<%owhMqhIb{lm|&8OJnNvmrQcs=JeiPX9r9KS z>q{o%0cp}AOWQbC(jP2SPA#qWEGjh=#f0f}OrGatNsDqaVlY?*rJ3n%z-i57xQ4e= zI-Oax(u~I=Cexu5%C={)-ZB}Fu%#5wYNIJ9BgVrKX=jE`OKMD3`^!v5Lt0saGK$G$ ziZ7?6Sqq&Qd^wdi(aw?QIcbuyfA8bmy?ZxlnlKse$EYFCe)>h6dB#qLw$18jE4STs zE9H0zlb?oZ&+{w4@LY}`KgeVE{fLblG+Gr5)|MEKhLqN@>z;d9UDI4}$uIG5e&aW3 zcXKA=K9lJPrE=0FLE#yV`cmxMp2HZ!bTVLCjLEYusmZZL!Rp`yS|`l(7EoR@9<5T? zF2%Dru(aAUc%><(BPN4Y>Asf;W5SjN)_d}-jW!8`;WESiA|}a5vKCm&a5%s#O{ddE z;~0#Fj8@l3)0`L1bg|Ac8V$k2&v$0<%F|!#GZ~HP&io2L-|AwEg7I*G*9p&Ux3T4v zwY62I(+L;+%&*aEwV6&QtgWqKS{YA!(G0dM81#?QGKTKLChorTW}bD?FLS}g&!w;> zFVY5>G9H&$53@6~>%V$$cp z-uwB-aLQv#g$Yw=vqbL8G}hI`E`d^?R?l1r!lDDXGK#9Dp0sC# zro-HH1c-tbey@<$sI6eBU2q({f+VdSk%Zc5@zjHp(j?rIhcb~Z^2q%-TlX#3IU&nK z<#2>n$d#}}3SoSH>*{+lCVbx4*`Rp;(ZNtrVMN-Yll!#scOGVYpcAw1i$V+U3S^=} zAyfdiaZO#*2Un^5JFI=)6GN)c;x&i z^WZI%Q~BE~PpQG;p)8q93#?M)d5cWTefV6X$Ovztl_j{&EQN)+mfYu@hHgu)X$vTf z)Gy6+4X15yGc5s^k%qlaG}7|4onj|IAwV6S;ENJBnF2lx^-`qX(+N(#Ej`A`425{+ zjS(kN&WfjJgz(vHsC%*viEI0We_Pl%551Y3rBzrPdYpycOhTH?k|q+c@W93`y($2s zv_Yvf*rO<$DM~F=atCcZ?MkS{)_1{lE4?Ryk@h+xuGAbb7wD-Xd$y@BNI|t~9ps~a znX7cPe6F`n=HprPQO=n|scmvR!!ugutD%uf)dCr7GkwtSvBRt*oKxgkN*iRZ+{j=k zLnECl@!kfV=&@n4z4D&2oT3v=EALQ_6$g$_(0Gon9wAE&vz-iAj_9;DuxaP{Jo@+^ zjvt3Dr#ypGc5dg_e{F_aZ`;7*kF;^q0ZAe{N_mSa3+#A8r+q4?pMEhr&se}aD2o=} zyU=;a;Jjy}TBwJh;lTIg*)-s!hVoRswE}_8fzlho;8BsRBr(-=<+`y6mAwqG18u}U z#x+zrv>6ZfrfLPQ>H=Tq8#S2`&ZrtI+MvgD6upQKJ=Ne^9ln41|MB+c(YIyWT_5(D zYwdl`uen`Sz5Yq4Z|FiN>Df95D8Pp~SH>oP-e*4`UDG;NSo; zp^FEdV*{Zxvavu&LJggeK;6rG61+~Ysj7Q_?Kx-fwPya9bFQ_{xwq=os}kBZZr$Jg zoqhIR&0KSSXYYo&DR)EFC`;FnT{PTlMwgK9fe9wNSA5JN@76s$y}IM!#RY%Nb1maL<4qahQL zTIqX@VmDE=COiZtD3U*410xK3WZP%|k5c_(pOx{llKc^tWJ%9dk5EZ=5bfQ;;Nsn& zMH_#4E4sjQVfk<4dPg3H=ahzSqCfui@I!!Ch)2xKH@!(mf@yu1Ac?|M+J4XWno`D%o2-7q=V> z>WSuk2Lo7pSBWO11P9Fyn9Mt2rRC!LHHuz^K&v$6Fs0-P@Xiq3L|eUtm~|)h6|T10 z(OfJ`uVY*_5`%2j)z?>R^{_BIu+^nvt=5dKI=W9z2ew_ooAXsFW3JEKsew zm+_;15WBU(erGklt$~pO%evwAK5>10#r@q4JP;($?AOA6Sva8F-Y+a^&-JcwzbJRt zud%!SEM+;cEIV#*Zdi+g%sjoi=Gpb@JUHKS^Ym4gD%|h(+~41GIP6g}1tohfQ1iZt zDG-VvOJdqUsatx}D@7)0v}XH~NYc+h4n^6|SgTF$)E*t9kIOEPIYUNR{c}6h)%z*b z(BMS96^b;F6YnqqXG(a~+3pEp+U^UvQJsiW>-5|AOfWuTeKm}RifhDnW}}$GYUKg9 znFr^Yv#hWvq7!+_s9N)}(<_cB(3<~+LF4|u@ab3YxY%wewOIM*?%1W9O_xr+ns2r9Rt%am3lR%!Vbm{)EvYj)# zyA3%f(rl$g$&;0HRVCHReh;th4%{CW)^)=dymDcltlAX=;{3(WI*6TEU$w5ZS}G4O z%NS{lxvznr+Q<}XcnrNvQlcC69WjX|9}o5tVtTZS>cYM)9zrI5jSF0*EpLr z5%Xq6kASGdXJaVFf1rEHt0F0RFOkUk%l*u_S3F{+)d4Wx_r*Z6m-H6%is7A{B?%=g zvf|lx)p)4-VC$;fANDLeD<54-b)HbI|BYJric*aR0LsO}?aeh;Pe03)mBV4rMHcRF z@5$4|w(dAQeU-A@vMzVr-+hMbr-@H~`TwC8-JWIHv7INbmpfj6 z`U$SDLAd5{SfDD!``*}@vblx#I-0MguuOpc+!{89@XRQ@kdgtrlhdECi4hMEOpJCF6?C!6ST=*0JpFhZ#e)$*ji+|yl z@a*P>vKoJ_V&#u(t(00#fflO(WlCrV7}GQ{rReKaS@wnR`R)(#t>64txxcyPmG?bj z)x@i>-|*0y#584V8u|zI4)DH@fz>2AelX4v`>Gr#BS(W$ZPu_sD8x$}g9+KLUGZ)o zgl6RXG|03g-ayAi?W#ssT|@Mt;B?!1iv-@|=z1%Pz&kCg`nDAYTjwD5&piO2_u!Us zKrLd~=WD=+>Jqtg6~YDQ`Z3-1Hm*(#mZ~B8RiXL zJmM{K27(hTH$i+B&Ej2yC>$I|ci0dSp_rhS%$-sL{gy57@2p}L-lW|cfNPfH;aYsoDksNZLLTqqE=3sJn%mWLmKH(RNlQF!A;Q*f$Nh9?`DE}2|;0I6!vb}(fg z!`T1S7E>DN^)+b?n0iwtyDl#({uf9?z^UfX-20Ug1VWq-%yp>*O+k4#8AhSSxQu>uTmqqTV(8XHfMGv)k8#Ff`z=nhqrH=9%IlATFRv#{ADwwpwv zl2qAlCbpZ5gpztxh^}*=F5v9XoZyqM?fAh@?1Ti*5ZIlCFIcS@ec3S?lFRIEF@pT-v` z3pn37OPP{|qRPc);+4k}`^EZY?DmyXqyc;!D2FXkogbLUFt74t!BkZ6CXSinW>P`C ztGV-8wNA<+Lec69h&028A{Op2ha9R6tfv&91J~l8sB}0kuFt&tcwuFTpaeijJSgUoUPBNiV%+TgwyB6!CVjb$O zp9@mBy}v=ooNdm4Oj%YAhXW5DJm%rUhio>pDVu=Q%64n;rqbOoD6yxE*9c65TOrLpNQFMJ&Z+*R&tT%&V# z0i?+(t?JJV5bNX?GS?r|-V?8{bOS{SI$sA%cp#lFqf+YS+dH2#epV~6?D4HOMTo?r zwEWJBn#JDbq6CIgCFjE7e$R3^aL7BJKKm?*l`neb36Cz%*zMr3Ke+Oos8y)0TUA$} ztN~rO=tmg2F01vTnS|NP)Bde*`K$a7-~8W@bmj8mlAK^Y9FT2l>qiut5!^y=D;xpm zI;`s$VjejJ;-yz>9gM>R4~cJ_Ryc~)_a6wGplY03SLToO4I%L6c!?N>3HcW|&^5(o z9LA?m)go_Xm|qx#f4r+9z0vh{6$Z&U&(IkbjDYEQ@JEa-mRk(8mQq|P=HFtTQX)a@bVqZZIsnS7!c45^Sk3>iY0rHeA44n)+ z2rN~so3pQ#x3xP8scL1&d?iZ*p6ag4bnI2Yx*4m-G>M<7P?T^FgU0;>01z=Ne|4py zC0IDy^(|}rY2Ah0?_Qm;)DBd2uwW-|juHkVQ|+bw-uRJtkbXQP4PXr#} zVpU@2qx70Ie~E)>>Fa%1SJw5wVL8}+wV2YJg#CVDe}Jb~m8Goisi@5YT8b48c+bnP z@YyG?uz2^=r5F&O^2B~!h*H5((%9BP9211_OKtIm=t|l)bD+Ukb64zTQ0iSERE@;{ z{v8o%G{2OU&0KlqVPd<)4=+yYG zS&&<}p2IkG<+#>6MvJ zeE(;7*Y+WBhN?AbT36v?uimivz$HKJOA-&~bH4L4@PGN8e-L!TOF!-BqCfaQ@ZR%B ze8I~PxtM3(^WXsw&(5gJ0m{Pp`36bCW_ymN%0K+U@8?H8`Dv~W3(pRf>zg}t`v5K; z@-zR%pTY0{t-qKput|N&Nm+8E#{#c!_j;dJ6|8JDJLd%zNgB(fd|_RG5~Hp z{%!+r&{FN zsVoIvd%AFczcNkRK(YkWw>44o@;Tp1Ib?!bF%p%Ct`0WV=G6=!ZY1dj5(Tf~k|g;U z&EsLGEy9s}?gHWpwpOJq2c)iKft%|qZg$UjTppoo#VOaTS&L-Zq$$F8H zJ3gm|Qj-^P>F+b+sKd_$DoUyl)p!zuCQIf`o-kQlfk>F*OM+S|PoKWdqX%Ea@BTmh zU->CN{at+g6HlQT&3yS?ZdaEPAzRE-76;1bk*yTza#$&4&oBS_Z(x7>D&PD!{}R)7 z!!*I&{mOKa{TvSY0)iXRYzGW;b;YXczR?)pU$^>BgYmVtfMj+a~rj49Pr}%X9_CS_Odo<+1;<< zF$gUz&X#H!D7!$)NYysJqw;AIE@7KnCYjaRw_T-e5BuGYTn@}rCQmcEDy0fV3ap8F zyJaoORFEmN*-kvTcwjE;VnXTW<{4+3iHDCKa@bdD**7JUWbd}-gcDUl*hmA*cALY9 z+U%^fFo&3DuqR&=N^3Yhg35eDMb^cr;u2_f(gO{vn_1;d=C2*2N%IaP@rz1P~MiXsaw7ovOC~bUd;y34vq^VhZ#Cci) zLP>6POOM%SSfAv;@;#4d-YYY^1!M#N^Pl~M!`FW~x4fI{wB_lCZmCzF;_kX|pmIHL z`1CaKA*m!54!e6^e|F7lS2sMpJ@E8)VYgIv6<*f^^`-a2?H-=VdM`k6u@cc6j9yF%93cQtG4H6@m1ge2j~gAG6QBR4GT z$~?u{PQ&~i3^n=>^jt^*azzHd79L!+@ZJDP&U+CO+~>b#HeV-mLF{ z8Kuk%-+5&Kc%6d?;~SE7@C?a_pqK& zjPZi`4L|x?I`e4Zh+v9a&Zt)3&ye{L1}w_0ef;-apHCNxhCT*!W9VB6~IsvQ^sCqj3k zHVbqxS6|%F0UU{pC0NaK+ZWjW?@2PXw&yp9pz;1;(_8)3;6N5neAq9{Ig_T;83tYZ zx1Yn>ZO^V%Syv?|h1p^blS>Qj18n2!Ji45D$XPSlZfQ(U`kF89WiI>Sf; zB}wxZjC&c$&BXMHHO`EKwPg0tinTMYSkhRJcA!${uyqWZ8OiKK!=~?%F%a+1A*FAd z#vVl6VrLAUHe(FKp*ylHr1q=sg@~Bb!Q-Q+W0f|x&a~`X#R2(Nh3(lHh-I-#w&dum z>wA=kJbHM^~<@M-2q{Ppqy_mJ>l0vjhe6tFoe6R zoslLdmskt)M)_Ilt{ewm+8A2w^>J)wr={_EA;40ueDJ;Jy!AAB5Hp%Al^FHtr|I+XH^#e`)d=9{&S{1eZUfJ&s+}+)ASPmQ( z3tbU~vK9`dQj4$@;h^y7z3=8OB|iQ1b$;p>m=f?(RpzZQz5iu$6;f8tU8paYnV

CR>N#?IyF`X67lk6IzNjTH0*R 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%0DMp8deP+WM}2{3AU5;g7JDLtc347PoHQ zV%csfOYxAL5mRySZqMnRm%I=sxM|N05rr9w$q7@b zZ?vipN7B@;jZe~Th3Ub(O7lwfiOB&ReI^0oz(0JI=Jhv_Ser2uKrv`BB4L($ANQPS z6Mt1q@b~~6E1pZEDKr=lqZwJaaQPzdd;f>HapO8)^R-{aC!YBPH*a2Nsg-%DoSkl2 zmW90w`^c2JeRRTVvtsYU0jJwDwq;?xx6gV#v0AS=J~?Hzp15@NfQy&*xp=s5d7YD` z2c4dru-$Gs+s>RGpYf6R{TyHX*`Lm5ea@HgUEll9xv;<2IyhXpa+&Y>r{BxNk37PE z_;tUQ55E5wxOL+;XJ-qiCo?BUXPlkR9IW>#vvPcN!tw26_Eu}wdE(aX6ZThoJaFGt zu3o-}Ix9!Fj<|4ef%~r9$Cbl-*kA8+c6!3mts_p3&p19l<>X}M*7ckG!h3#>-}vi) zC6B%SE&QYJ`X^jGyg;euWGKZ3sMS*2@9JPAhC$kU&9Zmi)uxQ<@VA(X-14WRh_3O6 zwzCWG*sc&XV z`bU1ATOa&!PG0yhdspwJ-hPF%SDs-;u9#Q>joPX(cp>K%nkGtGvwyJRY=-KM0k@@c&p~F7%E`$I(LJm6#c_{# zih43kmWA`KC2eTenZaWz-P!5Jo?7?u&wcnKtk#FT@hzXv?V~eZdhtbcsm!xQVWR;^Jdu+rE!s1z zNwmvzJ5Dt~Kh*UkFGj9zxFt6NcQRUhPs1oSe}KylD#V~&V>+yMGUi1&7S>`NzN90i zU4tTij`anu9zN40kezvH=(-KhHQnWUbt(2=f!DnDDVDOl>97CwzwsHvChcz6tNc8j z`@{Hw@dC!q)9S6C_trP_;Qg1me!Q^VE@Ur!tJNlOM$4@zDK(OboG`a4eG8H#7W_N0 zMGBfSt;>m+dS9>C-li?!U!qzx)&$lu{Z-o?t3i*xOBsbU?So4^puMShkW{{y^hs-#c?hCz`t7Y!H>L`H$MG1 zH*VkN@BM$jizh$rv-s?{eJLOQ#Se1(_APQ+p}<-;)|^$uJ;Giy;-_Zb{L$kuc%0}3 zUqSQ|(GhU3y6sG)^7Sq$qcZGd+X9k83wa{a?x(G=D->2lq8iyZQtMMLJ<{Wbkrnln z*zr;R5ot$#lK9YyQ@bb2yw)BzA1FV0x`g<;l?c0ckQqY2_Sd3KB9;!5By;QdjJ?B) zpj*yPPAomZX>7`gQf5B<&Uf|C`^uTL) ztFwweE1_D;9q|44{-l| z_wuICej67K@8zQ(`vso;*!y8Q;nAnwz!OitnH$$m%roq13MsGAvM@>IzK8GO#g|`T zwVKSclyX0x&T2-_o^IE?pc)6J?d)0 zCaZbKIl!#XJ`f-DHYJLP84k&(GzVxdm9&!PSk4Z%Q{%Ht!dhLbSeGPmqb^~cTU3-a ziA7+^>IygaS%KIQMpSNLWuiPKYOeN79tEu-Q^eC*Q?jz_Jon zl9>>u)ntXj_0BZ4MkiwFSk1sZ52|*&)V?`8QHS`GViu*ichZ_uHK)G6Kd}Ll<2p4|da%c8gwv7ybX#J;+T~+7Hzu)baWL zfnHM=MYT~x9$vY&M%BJ7zjX3R)Uk$?pvb4!>Ft1YaD3?`rMhIVgG*W>&7usV2R#E z$iVZ-=?NDuUf~PB8eM6r#{JM+chrwEifbGaDg4D_%+M6a7h@&>}Z4 zA|lb{$2-Ib*}Fmw0?!3X`>u1E>o9wc+6@Y{qGjRIT3Yz+SG?^rIsNTl&$W;K4BzwJ z-^q*D&)8hKpErHh8_5(dTsY*VliO_P*}8>@_@0>rjM);~`y3YppL&R0GCj%22{HjqtPTi6H`?Tz#t%r*;`l8L5}R5?7nz_shw_|t#(&+~hK-#78PH@=n4X2bvd z7ymTBVRiU0FTe65e8m@jg8#>V@q74-fBvuV+{d5gt)KliKKg%t zKfmcWdd1gqDI7wYq>%Zi9fd>^!T3h#_v!6=0X<$vbO=G7Xxy zd`^2WyD>5Hptf2mJQb=bYt9w6(|ZTR=aPR`Su9;fGLt6O3hR2peHX8=olmLdjP2Pm zI$1ZKyi~MqIXXMz{!jY??)|(k=k^Pq;1fUeT^z16X?=;;zxfMDulsafdDlCBqYpjA$DjWQ7cO1l%H_*^{2Afsj+E{@xykhllswarFJ)yS`qn=z08d)6})rqtjXs&$bKm94Sb& zlmSZxiCF?_`EnWe=(?i!b(6%3@WQL>IMqDayXVuo?+gZ)ZFX+TEChEKn4Tveh{1t; z6|+7g&(thpCx8ZagTri{A>dj{4;|>(vMd)-+>*5-oJc})mKh!fpey3T%Ay+sv2WUk z2NkU?9H;H}39r1g{g2f)Pm1SxVksW>8gdZZt9yAu8JUoZoOu79^zH<c!ox56IgSZoca$dHy3G;NZ#yRpcdQ!v*;QzLa(?QCU~ZLxqhP_yf;;Qz7E)}$7QSeAed!Go9rj&{e7hOP`_ z!M|r}v+K~&AW#NSHt2`GWzrmB&{MU_vSp()7gj57mr709q-(V~B6YQoE@uYR@tPTN zud{X;6SWv)uJ~vK>=**)4U?QBHfgQpsh^wet8?Isf|)l+3`_~>ZZ#a=Y0d)tZPJP`M& z^t56+cyE#zr-#b(&p*qYd8EmVqMs66G!{?RlFc1IGmAc#r_XA>6!J1y6rzV5A!-EyUYu00LxG|Ic%% z)z)aW0L6uYuRKEesz#h{c}p_S$MLpsY^|pFsUQDgUi{>KH!HUF_g@}tIg1JFR+e#zf0!rc$0ZAdWg=Au!t{C*&GuNKll@jx^kdiPZ%acxG22@p3*!Aod zU-+eO=lac=cm3qQ;>y)~__WXcGJfpGe~gd6_x(Kn+Sl;N6OXY<69=0ER%`eN-|^S^ zQ-90q5T(s7f+W8^sI`Dc6VX@+5@m&AlEREmCqA;9B7Y;Tn64s-> zB5d{!&~nC?{i@&0%jI5v*Khkee){|Vci#4eZ|3rq`&jgd@BiMv#y|Y4e}*6YzJI`5 zKkqBJde42#ZY*fj&A0#+QA)9?#H2hZ5}bw&ttL9HNXti!D3sDWhFGpVPMHx!s;a|1 z{Y-1TH{4RyB7f>>7zug~9*ztx4J1otnk-FXwaTnk!omI?^Y(<7Z@hpW?s5NX-oSb_ zSz&KD36dfyvy#mA=w&|n{PVnUyzt;>elgSGWe~V^{dwN|6W_zZr7Jx4mM>>1Th=r|0i*e+WhdgB*zc;6Ge@cy6T*2~YZ-rGmY%z8d$k_D-!tkpUyA!;3mRG5=> zVG<1JrZ9S{LKaFg5Nxgfq(ud!s?B3a+0wLtq-G9Th0G%1>4LaZy3 zR+lY_8Cq0yuF6&|@@x23SfykJfmBoyMUxMAOCZ@ItN1V{vDBG_GF4b1tdgH6HgK%< zsP}(UGB{B+ak3~=UR#S#*InJIWG_<#Y0wWHyxCm_urYj3y`Oe?X-yX8Ccl!)R3uYs zMmB3S!CYwC_rglKxPtBNBaUv}WINB?IzFZ-tn!`#HR(J)*2=}&%=Yc;>M0x}Se7PZ zP2xHD3`42u7Ej02G89_+^9A2P8-EgQj>8$(TCfhU0CwHXN^M3(DV4I!JaUj&BX~nL zw$)SX_70eJvN{(9o8IpF#P=elh{A+J^rc(1CZ+O{UvrKwfX@&6>%f6V<-{3UR538(y&&$XQXtSv1raxZ^za!je+YP zl{s%fhvC@XRzIr-@+>_z4z;JuxK5A7xlFlr`!-q^IJwD3-}g??#KRB1j!!;!oA3Jm zAK=B8USOUJr}Gh|ZmFe^b82T(s~ZAdKRR4~K*FvYpz983&pT2>tLJDB8&?>3y&C;n z6NqS=A^lke-%q2r>R?~ultme_kcozY9>m+xNEiWjuim7<5^9Zy!(g$2o~hbiROi!P z>sK4d-g@ivSFXMC41Jr%ZFp4!;;s>_ySx;Tr=R)QzuYdFXJ2@!72Sr1qj}TM3EOIT z7H=Bc0W?lPUjMLEuY;(?#ZsJnPn`&1*o(*dJ=#KD-#3p!@&$x1&x_Y*e)ioT;gc_2=f#(5_LS0}e_@Hub(EN+*Hzwl?j zh0l5G8~DxN_?!9rfBQRl$B+LAU-Bhi#_8!6t+Pi1W)9X@IKA*DPOrR?y$hE)Jvs8W zrJcvysHTls(eFW(-ak`(r{khiC-7uZ8tC1JgsQFY6` zZ~UcPzV{)@*$GQ2HtQe*qO4O!@R=%;=alPW;@6G0g~e!>+%#)dSgI*N^-Z(rqV0RB zg{5^7Dh?bf8Ql1=C_+ZCu0X}<%p^g-W z1*qOgW1TVum`kN7mM&I-V$sxz%392*S)7ihoXKuv)CyDf6vj%EA02pv2j2Lqgn>C2 zqiu5SK-j@sU9#*Vxo}=pXGY1HMKdW+oE4e@uoQUUV&)*h$>}LKkB+!~a>85{Nh|U+ z`J5xycQQW1n09#w!wn#rw)SQ-yPS-4tmt?rh&!r6RMtTO_mr3T-7aV{*djzU10(7N z#P_ZnR}u)5DX%#^yg(A=>QvbGp_LQT(ndCWnIaQKZLWznJvFW;bcpl#0Q&Ft62!4^ zZJ+B77k2T)c&1HW8PGE$Wh{Dk_nquUIYtAnuh#c&(3de=19}9$r(cif+KoVS+72mZ zB2F6uHFRhI%eGUyYjJuC$4yHMkMnAu9ds_Zr`sBhw3I$IBYw47ar5R)u3dYXi8eh$Gy;q>br zpB$sQ%&%c6F<{50Lut=Do{4HgYsOqML!!tBp zyk5QY*%xp5rq$k3E-onnV$_wi|6ZfebO?j$uu-uwp3YKRrMWAyNL6UUuoB+DD3ERd zJvvYf)>ZSEx2MtpSj8sOz($aoMG3t4OJdx%fnj3|k7jr`q(*e&q9G1n6$`hU!kqF% zUhnbl_kWNN{KC80Y*yU=*u%WxvprXlXrb^F1*?eDLjc`EiwT7h(7>dUs101k{qGQ>ghAl9jA)Ht z)4WDqK(?C`v^&zA)sZaT!J#W?qvdGfdHdvq*S_X)9(>{{{^oanACEr#7+?8oel0)v zlkeqc-uoWD^h>{#8#k_V>*$E1lPzbbm2ddQujfzvxBnUc}Sl%s`P#|tkUFC5Rp!D^p_ zx_}lcf-c@YZM8>UPC2Lxb$d*mPdT0!(!muTdgCwUrJL7y_FX^Dg~Q9d^2+nP@V@u* z(lbx<$q&DqiwB2jQFN(n=UW`U?lV~3_aM4#iJ9I<)g~mP)=D&EdEGUc;WBw7DrF%} zPQzNz;vT6(AV`|1$)--@Q>jM?*%fk+Y>nwQT_#0jc}xj%Anc;WqFDYOy@!s9rKw8J?5)>s zFxWFKOJOZa*`Baen`K}bB+1S(?m7VVFc$ECq&bkzML#s!p&Lhxse*(5ujy)l(UWFx z+xqX8-*0bNDsB{$$E(>WX&3mkzk5{g;^97*4mRws5-Ta}Pc{vF?R64Mg_;EQ&R+q| zQuFAB+z;{I@3Xrf!`d7irsVoAfF>QB>CPr-*Mlyz1jjt=KG#S;Z6n6p2d*I^r4gO- z6zjoDe}~Z%mmQoeT^IG6g%RIA=UEnZ50kw*?h(=&fQaLoHkoAGarB9CEoer4>Mi7kGi^t=WZxh?|X=4d&0@-F`Kt-ZKsiPVhN-jNN@Qs}xoFlGNIFiQ1QA+rH=vdGV!} zdDENT%--PzHY=qrl@CAj0dC&D#cQAXbR;EK(~6uYN(Gs`b>U9hhUG{CL|PJ~0FW+F z6w3n!A3=`IiID112lphT0NbgjeV8yYl~rm$w(|-DXRZ$RY7jrtTMm|DKZ_ErXzl!m zoJSX0c3E$~3q!QS=`3m%JW68!Zw2y}4q#{5!me6(gt!nEzSBk+A7MyHZ`+C{s8++1 zl7ZeHqE0OgESgx#LYA3FpL~iZKkc)5{inZ)%bPV1yy0_r>fwvrd*4-Vz2iNsFFnj^ za|!k@@#68!vmgIBFTL^-7w>tL)AdF2#Rr==&I%7FgrylT(E(#j-zh2C;I}5!x))B>Z{oqnpXBWLsCUa42JV$&Ve!ru z(t359LV_mfwJYwRgBsH;U9mM`Iq2Uc;tdOg)?&MwyfGP7hw~K0+*!n9`fhBuobwb|prPyZa!OV2SCxN-Z4^we9(^_05ar=H&8$|H}np4Ob+ zy3QWsr#HD!EBUEkf=p|s`OG|Ti&7|*WC}4cA(RfpDSj5#)kwsO^efft zK@wU_@vPlJUaA!_XGv(Pl%z}usa9sZ&1aLz3oGaEvq&BD)X4=!u*ug&ZMID{X|mL@ z@bE^;Z%iQ&FG8t_-mC$uVL@As!1>t=g7w3ZGC}D>osS^jI+HY0Ion$zZ@&fNsws`^F*y% ztC5NBFroiFz4d&geKZ)N{=*`nKAf`-av^k4d#h^hoQ zjnvAXA{^fHh=6CLwT7?F5fnIfw9|IMxekBp5vN{E>jp@xk#IESfV%ncG*W`2##Ft> zjkI%&&U_}uO|aUY#9&olXbgar#FZ;o_|S(w$h;)(f8c&ftz3QN_56mnyq(jn&7!(; z^#UJw-@90?*X$o0SQh1!iL@V)$-%RmD4zWi*$OtqF!r#UP%1&!$x|8ytp$sqTI*=r zCM%dW+sK?>$?H7F?pjT!FdBK%kAKiPps07wk}CZmiSOCjbmKNP2cM#jo6H#38fj)& zR(xDZqIf;6gY-Ioiak6LiQ6U)~rciVjHXpxTIa*&&P09DY-w@>+}ha%}`Kk+fX?3aB3Z~NT8OI}aB_^}W3Er0x*S*;Qu zdirVZzvmvl=@0xN9=QKre&>JwJGtkc3tYQ-3sg9}eS>fOhHv2F#XVkr`MMb+Vjgpi zh7GkBK{mro)Y35W#8`{(_7bHi*I#^=-|?HjmPa3bf_J?0-F)Vke-&T-Yrc$mdz-KS z55Jx#o_sSu^}cuU=;ytSule=Aj*ABq|Jm>R-F))JYdm+l<*UB&Kjl}x{R_}?o0F3* zdCG2-g-j4~T0uQFV_ke|v!)7N@%B0wE*`S}%(t>$39IcfH(&lF7w&%; z$dt2F_7hxq=rPU|^yHLDD)+wTDatYXi6mxEV-nBh%|NXSqE@G&A}pmaIq;q<9&5J9xN&ysGi^LNAg-{x zo|g{j2;k{}ln$Wnvou+<1DYKeQhTIXowif5G@86#F+0|@VpQSs-oz>u%515d$>)JY z3tSVg(mFTc?Y-ODhi8aa7z>Rh8mNglu$qDKYT#Nu>Qo^mg>c4b@Mr*D*V%)94d=m5 zRswlPPAF=|T~%)1wgT_7rBatuE?wH^);4ikl+~m#W5c{QYdD>#l2BP_oq8(X0jusj z%lV&2CtAE8w9wwOKltZUZyz4}+dRP#-uC3t^2(_1`W|(i60c5Y4O`d|cU|l8^{%%@ zJsPig-q1y68019gU^4h0f%bVZ)W-^JT%)I#WbNu25-p$RUnTH>Jf@v+D)|w1Y#yy*N zsI8j8dbM>oCnq~~7GT$mxem2jBM_BhPLp9D`W_C>tl`ybIflz)Zh{@>ZDesc-x<#j zxHFbL;74(bK)fb$q#XCPv>g|BZi)y|BwUJe>>hs?6OaAbAYWcT)-OXSaU}XDw z=e_Uz&hLEYxBkb!=Qt-h5Q%~?6E#(V6rL0h!FaLQGM{m_Jta?T)DI`;j20+mZsAUq zn5XM0Ga+!)HqJ1jc~aV-8ug-G7v|klBL4XRe1k9z;&R4pJ*Tzj^bIUa^G+rM9m&&g zn&(^XGu4fYurlLd!>YC-C`+-}Y&Jal_!GSF;)^`@;x&$skGcNJi{zBKefyN#$0uC5 z_aW|m;C}Y@4_M{38%P~U1(_JXxX^WCv*trXI#T@JNi7vGZ0Q>4FBzr+nzl0L`nu99! z|9Xm1lQH1?Fi7iWP|%d05{eO~X)>_lU_EK_S{F+aIXj)Xa`ME3a_06kh+> z10adpw{P;$J(qa$u>-DMyUs6p{i7ToA8~SW#FQsaPfqx>*FDHG&)hyb_KDy<)E{fu zEnqZ|adL9P(eZH;qLxnRGFIU1^pyJ2C-@b=>`i>-mwpy2QEuJ1!N;Gu!G#MK`1QZy zbNF>%`FZ3l+`4v+7oR)fOF#e3r9?7Qb{ z6uO;8!VBi-?#CpA$FFvg?R?(6VRWz(^d_S2m`LM|h)7i0=`Lf}l$0o?FfWUF+85=q zH+})EHx#YRMM;{Ol29mwGMP}Oa>VV^Q%H$g3N^WRw~7y;w4%+kx+N9Jc@3)E+Rh}D zO%n3SO_+tn!EY@y8MSzT7EZQjR7p%CY>RTXoRQR8q%P6!RD7_Zd!fuJXt~6aZ0Qbo*mQ)Gr(k8!_1_s0U?s>=-aSp@Wu%CIzX>~B;D^#b`X~=AG9e|}<77|lV zHndF4AykWUX-Cu}xToBZR(2k2Hkw6H$c`__s)d>%Z=-+XdCT`{3Vo zo>nZfAn~&&bp;d+9T>7xhwItDp0?8r6|t@`Vzqh4CnsjSNJ2ETSBn+ktFXZg!KyH= zgwtAWhKM(RP}d<6@>$P!hGO_xcK&XwPJ=uR5Jmu=o!9y3g@nPHmFY;|BA z&uWnH{F_cq9%Jp;)`$ zW^4%1bgVEwU~&h5szrgOJaOgn6{gjO8?U^~M?dmWu3mYCOy&0N6RzF74SCH&k3P!b z#Y50+0}j;&Xr?HNlhED6K1c`BmIduP*&U*>G6AB)9+H_>Q;S4&D>Cq*4)nT98|}{S z_zqPgz6fIlVPuKOk{G$SUFIBJG>0bQh1c3@@GP>JhP6l_La%$VD9LlrKlh8n?am9U z-5cKJ^{N>A=A{VKAN?pK$y3F$enxJn-NJF6_g}@hj-b4NhPAIP>kq z)ytPSxNt9r2Z!9ex#ITG35A&(H*eZ3i|j^@=iNth0Cf^XE%H{YaC&ye`trTpcW}Vz zJiAes5H||d74q3UGr#bh0SQmrm{$9ooNYOK{&@tU=tA-VO|QK0f_XcVHsUi7Qs{Lk zR+P3~&bWB>L8f#cXYogm!2UQoM?Okgp+rHTq zaD@9Kp3>;A~k)lE`U|))}QT?QO_KSlRRgCa?7>2uv$v zosnXWn<|;46B7oCb+UV>s?5c9Jm(DS%F4ZA#!Ho1i^<=`y5A%bAKGM!S*v^9JvDKy z1<4jyvee2<7L&V)%0@Hu3YO&zWzA;2*8tQwJ^2oqaF$o$*O&ey}yuNbhXT?5vhr!Y0N*El?VMuF5JAS@{ zcs;kiT|nxPuYG5%CmB!rZs@K(pD0lXu8td;9@bdnZo6Ac>GO5Q_hY-NKU?ySNZLDH zhF3faiW_hp&cQzCGnsNG<;>px9tV#-%DkO9Io(o9MWzef_rSd{2~$q&@2%OaR&I1m zoxWQe=D;Xs>~xy-HF;{e?P#nop5LA+5fLK6W=ln?*_hfz5P19bd^+MtYqs0T&z1h~ z(2=uUXP~3qYmZqL>QPCfyT;osojXtpv{@;5?b^<%x1aScKcD|y038Rnoqye7B*cG` zL^bjR{j5?lz#khDI10SYWv#5H%zCwAS(dgjQP`7kFPaFX94fm3^6+#U_*6fDI22(Q zl=>4&^o&mDKw2b|7PzOZ>xq6P$=f!Y4e^Bhz}mkLJE0H(bPXZLpJ?b9f zJlX)0fuyAYRsU2dt#&wS=hM0?D3EvhlGkQMNL#<)Mx&05PxG#X0VKmd7%=yBiUHWN z6jtj!9)I{=^z1qx{MjGmNB-5n;C;XFexCm1iyR-%9PF=n@czp@^_nO6;xGCV-uwlh z&wYR-=lwE?X>{_quU-9F{o z%_E8~z8~&|cbX;(4Bo#|A*Pi^Th>JK&lx}3aOF62;hrmp+;iyyRVQA!dCXUR)vw{g z!5%NX_+nQkK`X=Q1ZBiIv}v)Cx*&MIdqfgqpS96uRZBMHW6~R}9Do{&BilRxG zQicWlTuv0-k|i-CObM@-siYcdEta#t0_ql~ykaHR^-5}CQb^fmaHJ$mG9hO+SksIQ z%j>U8;o`K%JS$K*ATg^jrDCmQmjx+Gk`0;@QnswhWPDT>ayAesuC$blY=vn`%ynyk z1ffQ&;jMYmC-+{e2#Z>w^8}C+WwGeT8evA+WK&nUc%6c$d?v31)-+LcOVUDSvZ8x8 z9Fhi|RNE_`+K^nst;NO$VsRU0tS8tc<)jGY z%(Pk|wMWHCR&N-ok20R;IY8Gzyl+bEoCDkHM#1?O?mLFnAX{20UFfV~Kbu)_&XDOx zCiI+Pm&b#F(eD*0&*6;f*Af4$iXaWxYST+888!*fEQD6m=Ddq;MB-i0Y!04)&u`F3 zL35pKTT{CtB(?S1tSrZE#iA3@$YitLP?pL(Z^?P$!sR`3GOV?oXTS!HZ8jTLLkB)f zdT{v>)xHvi*p*T}LnT=?Vy%wfaBLV3rg5<4sK_zgY2zaEU`UGZOwcU^4zaKK6z82Y z88blGInSVh5pRxwJPb+o+C-`i-pt8sf7OTSwup-v<5j%tnPl%!rbsU^i)!qky7Pv@ z`Io}0M;PvQq0xY_gcC_f_K9;?xU4Q^r)#BIrvwEfm~mnA8@w%PPAqjXuqk3nv03B> z`ocQ{o>#8Y`fOV_pzt`m5Nqco{rxy3QK*XnKr_so5sF)yeF#xo<9UnHrVKR#?7+wC zItb5?6IT;h21FDkr^F-~^%RbI_7qO7zrV3V~~d8>ZGXp)N6_3^{imaduZU!))hVZ!`o8ZcG})` zJ0K@=G=s?vbZhHNUk3(OBCwIXUMsw6!3JJL zT+L`&uU2L_7ajc{gf^X*E%)4WFAv^($PfL~f5iXv7yl9;`0zC@KJ*4YmPqB_a6L@{GM<8kN9oB^Y?J=!u>q|+{@nOrcZc{BtB7P zYV`rO_S2JN?!R)0#~*!=cm3$U;wOIiU-9{$_h#PuMPJE_H*WUaXpEN;tf;;e6GT&{ zE!(Px9>ZFEVe> zTnR^UVW)$hh87BaSAKV6&73b?6xnAw8JstP#yh<7d>X5JM#2< zevtJie}Q^7lhVXIf!4~}9TJNOTV2RZ$b5=wBCR)w7K+Y3pCBWPr&NltNcEvfHm4v_ z4CK@VrC7nW_`WVyXqTN%7qwx1f<7JJEAvvAB#|YV2RbLOhqXOjRIR~Ms=kLNW2`38+M%M5lX)t^j05#) z%P}(o#S4;!lwqj`Ql>Ofbn#{qHpFjPEKM@!iqr)ulTSttfR+(aO5pQSkUX(CePpZ) z4=TL${3pnt@gE}Vm4p3|H(h45R^WF5d3ONN5lpJmx_h}S6o1z0&M#6XCt*rTS!{i) zY-topVVx)TE?s1vw;Y`uQL4+>;1_pvw1{^zNOsrP!K^#ITB8ax)GE940bcD{$Jh9o zj3VA}pr!c+r}@{aLbMlNJx>I*byK~Y6gB2R16vLa|*Sfvf9uomGUTWyLV$dJ=v zIC-sw2z`v%?(^&zdiGBHdwAU&W;tg_^(F}&@O4>M2*-*Qbeld42ZuoeY2WPzXspAc zv{vThYtk`Y%Jwy)u`K~*pv6G5-3jJ2knH-xa7GOWgx-)H89ZE$R;w9Ch4vMht>Y2u zv1k`@ryzv4Fbo+HVYAtQ7M4;di_vDJq)$^~J=yR~bC_BL0q3oT3EH8?bA&vI$a7aB zm2d|3LyL@Nd(OZY_B<$qPIYM8ZmGlP+z3lL4AiwVtd4V}X{%jYJTEs!nbI>KTsK9F z)dbALU|q*1$<(mvYB$(SRD@O6u>AP*dBfq3SI_C$H4M)GTl}*M)Fh%=1RL)pEhVYt z-1%XNnh>c;K_+|1K}k1883bFm?s0Hwj9;SIxpi4ldf0DVYBw~x2h$9LI&6FgAQ8Fn zHv}Ren13^1dJfQS?@isPr~clz_1CbDNodu?bEU>PzuwOm{u!R>ot)! z64QO{DHCKL;G(^#sD;B6T70HBddm*FAiWSv! zApJ<9!$Sb|lv)g_2|XoJxZ+E0xM?-z>77}$ose{6!GDcz0WB1&0sajfRE<6Apdc7D z{+3)=hdQ;A4WqX~oi@7A*av6Kv4wARNm3OqUAjs=zR4f?<9~?1{rCSdpZCkZhClwT zzn`~#>1Xrg{TtT9NzK5sx8WT>`%(VJ-}r0%p8x*a_?JKOQ~dY;-G9&3dtSq}o3~Bu zjPk~7fNE`VFH~*d*uD2$B2s&F!;OO07)U+Bz2Zf~LHp z))}Obr{wy01p+BsDfntyF|AjvRw>12a^}K4mwC_oevrTQo&S_;*Iwa2_?17xpZJzP z#cI9Jc6;hPuv=K^#Nfccd(u?>GzOUwpNaD`d0>2DbQ(1Uaou)gchJ5#4UR1)+m}*e zOW~6r|0Mb4W75?}kkePtn=e8ZRw-NOprTAF%sRuRhmqC2%&&ZiHD_e^bQUT}Ci959 zmyTi`tP~-6(*^UmtFxd<5bI!OU8WXqj}m(mAlFg6dDN3lKDO>S_PLyLQ}E^pusI6q zvSMkdt~Rf4aR)>=L9DR2c%HcfE8p9s1;wHW9%FF+H={*~B2XI?ha|*1#z+cpWqT-! zSg~{xAu{kxs!mp$MIlXsQqW>4PWF9!HdMVgzwf8m^zej5hf+3rI=gwDTxa(^C>?RT z#B=>{Hvm1RJ;WZhXw?Yh9Z=RzasHdhhKi+kR5x(f$>i`V3HzHB^XUnzR9UCQ(R>DE zkLsA5?9Q28T5qzH;k_n5?O9{4LVSKlHxGO^{{4>M#hh4;qrCP@!91H<&7i}EE!rid zeK&M-PT9A;c;KYA)F#1l@}|kuZcfVHB;1(2xk|Eue%fRO=X8wj$Q5zExK^I z=^jom7^3WH_Zp!~-Pwu%E{@$SYBt~nBmPzkDjL@q431cr*YOyx+8|3|TMC*@59K_u zTIIHXHvg*As~yBS;jU5RL(>&KwLCtPh)Lr8oEj49n8H&>gP&v1&qt^L$G`pf!pI9g zCyA$OjYr)++-Z!vT)X}36z1}>l(PF7$3EcoI|?-?1dASuq_|M!?#9A+qdQ)&mXdV0 zi?oZ2BsI@!rCX+c|7L;PWx}em!x=mc=N>ddHPNqGQl`P+_E(3V=7mlae->XQze z*u5YT_U`$1k!BP|STl;m+t4<_-3^2&5)2Qc4u=?_b358-VOSe8sLyX81Zt{-MZfF$ zX)mXP*vAmyZRUr2KAP?gLD!0@LyGKNi~tk07UpHP{Y*t z4}XyV_D}!s{H|~MEnE_K`MLM;qyOlKdCxoE&Gl=yI6T2G)~Z~bLoz;F1{U&dE{ z>7V2ueBIaaU;n}1$$$MP{~~|kfBMU8)*I&Swx5amAS#7YY2KV#3-{i0A0PY0kMPI7 z`A>26{zrM>zC-@n-~XrljlcJQv)QA~-2j>g-fEM=!)9R1IxQt~%4A@(w*1o~Hdt(v z)_{;ROcOkR^OPqa`3!XbLB8$peHU-|%s2C&{_a1_FCN_{+T3c@*5wAe$4`Tn2Rhw3 zN3?l_tb`-HNHo4o$qK3l`1(YS)qztiY?m&_g9;`N4NGAax@#SDi4p8vX(r1SswXa$(n8ysc^X>@BdqP262 zu0bvB5NSKD0$HNCeWor;)4#QvcFjpx3G8{}hb7Wu2GwupuU$+J>+XoqJ;zi(>;B9w zdK->~QI~`&^uM>rINcEzX||ni93zGP53#GRk(w9|@3ez!EQP1*#$C`FIH<49?HrLM$7>|T{_ow*8TF9{hOz#yjSqb{N|-3~WD~x*AcP zTZBK4!G%GN=!cPZd@euxYp9sl#(kNkwhso5mgWk z$ZiB>J)ZsHofzA!gviVHloX{xvBQs#M3*1?#lvW_Ags{;KX3mXY+rWW_ko|a_qq4J z_kOAS*8!c7Ln9Id0VXg9QzRu*q9j`KNR(`fw#U|tH1ZT{YCN9txU8D8Esp|iS+waI zmne;>KuKm4gGdn!AVC5o5($8401b3EI{o?=U%L06v)BBw*4lfY`(9IGqiRl}@q6#S zbI;jf?X|uuS1{Zdew}>rhKN0nB&Dc(+@$avylb~d6sN81HTl~r zRo++W2GOBg!V7%$H-0N$|A)SV zZ~B@qhFj0@Lx1-N_@969hj{*`GF-fmX>|Z)q#VA7gY-A~cfRvm_>ceMU*gaIkuTxl z`+k@kPkojGPAmImKp0%8Y_W4xL-W9ZBol>GLfVB}IzkGJae2%q6K~OH`M1C4`?w=Ze(R&3 zs%F^8Y$?E(|8qgf;U}1<^tQ>18uq~7EC0U~Di6Ld{ z1LIz9okq4(VWXLpgvF3Z6pAR@&B(S`gSSOal(MCa%JSd<71(SJDI{`QaWpzt(2&+HqWy;1<7{?9kZ6OUyN)i@%$)E+Dwrn&pxqw~?ES&!p zKkMN+7CL~S&FXHn=*A*#Ac^pNYSi*?>?xU_y*86e@eWClGNaR}Vixa3R#piQCxcsu z$1tuLwF?$raVGi%~U3S2Sn zzGuc1vCzh3K)Mi#(*e#MONe=Ze4)q;EQ_$6wv?1Xtij(>gh61HsW@Zdm>@uMWSdC^ z$!$EGnPYg8(rli+;y1^Ip%_H@?o#jAT^kn`CNop6ATsjXLZJ&Inxs%beEga!zz?w9 zjIwhjC=7Uzt1>1jSyF$@$3wUzWLY;q)7howzy)p9{d9T~q=r>R_>TDZB=AkFm>U=) z={R}=h=*g zDflz7vAWU~-w6+lm8kC`9aL@J$-|9w>J}_`Nzl=p?xJcG;7YN!gH)G%?%nJgwu+eC z*NQ_6lvJ%brZCtVmZ@;Cx9CB0uOPgbvM{@b?xy+a`F;MAC;&`jusYMu>OS~6b>+eZ zy>=6Ai*nxZ;$Zdd#^Xzt02zQlQZqNU7_qS47%&c|*odNwe-GNO;2ByUO-zx=o*c8o zSgOm(ZUmW#q--Ne4>O3RQFo1La$srQ1d}rp5m@Bx#0Tm?+E%b7WJRWa+hM7(qqZvU zjt>Uo45BIu$!i7ZPKbx2w@Tun-Sw=cYUpABH5iW?!!I6Z>#WNOI$~4}jMrGv==@v{ zh7-O*v-)%bi$<)mUnP>BFeZ^`Awu~6b~CbnL!0!R5c?U_lgZATe^1`=v3Nd>xd&ZD zsWV30l`e_X(_`N9ntQo&_uYKT2icw+lb1JHxF=>}VtDX%lt~z`e}*J`EFOF{+oL;-*PozVyoXB(l4CeE+MFyg)@6WWnvH9%mBe(!;MrC9~Kn zHy(dK<@hFhS0CWu)vsg97a2AuoIdq_7`Gg5w%q;D8_|4;>rZ`@p=?<`_(t+5tY7#9 zk_Qq7?$Hqi#_h;(@G_S7zLNFv(_Fmt8uEpUEEh{|KmS>tf8qn&|G=ww;Gws&mc-tW zxc2D}bNJk2T-v|HeXn~b$9q>Jr6~lZg<)CLfEk?%QLfy*fGIH*%h}0`fl$5<5!-*0a?8ihxyycK3^8wCn_14=b=M!z2kuarG|j^89;L3e%x zEtBI0SKu&=RdgbWc|jFrNCV?!I6|`29D<%$Mw6v_n%j$_ixg;%}&Lx!r+7uu29w1Fv{Yz9I{rR z>fpR9YiN}Rd=tASUzLbErV^bWrE2n8v+PrMpo2cc<56SYtU*LQup$@%)97rbu?HbK z`H-6{sN2rAM7ON7O7sY5T5wCM zhE`Q(G65L$1hjVTO@3$^Cdm)sYlD4A+RN&s` ztS)d{EU30q=vQ?j`N4@AFO_UiPzj>!rSTcEDqMHLOZqW0#=+GWnrz z7Cs!jBZdF8Lh%lz?75+*2l+Of9@G5?oSZm z;^hPO_ZCdsi7kTJLruvk2)Lk4QphqedB@m>*TdRmO}r#oIK`bCFTfETTwXHXd75(P zX%@?sRlo5sXMs@Yy2S-&+<~=%KIYu35ltcf*qCY+6@lfP`FpF!b1Ek33@A0F52k74 zc(Wxf4mdrz&cXg=uDts@dEv(AxcAa4xP5Yy{rwAEKYX5h7FW4*bd!tA%N`;#0){qUH@pWIxqi_9M*3Uc!D`Bxd;jtT^=gPbP7#AM6iah@m>&?V= zHE{EHewB;M!W+K)8`!(=9enn;{yCq1{Fl*_6ZRf?BagoOk8yNzo0IJ!r=R~MulvS7 z!<{ET!&5)^A!Pr+N>+Et|?dLzjpm4hSa*lLBZhwZ?yx|Qj-u{ie@af;?!yo=hUjC{t;Wgj# zUHsxd{%dTW`81Ed@k_Y)(3|+oZ~X|bc*T7@eD#%R+C#2?nmbQU-1X>}^760zMvlj8 zT-F1wT=*(J_o3h5zE`}3t8aRgV?APZ_scjr`C{(BdKYi{`tRUVkH42a3I`Y71nV^~ z|Dv~Y->bfur=I!%vVXwEyx_^tdm6U3(4z|2{4AXZlIvA*hYNoR-Wh@%YQcyAPH0X3 zH3iqI=}eBJhKx0i(g@u#e!^fOsz|e-S3X%;pYz5jP(ZH$_xwA#o-s8b)Pv-mYgR0v z`+EyvjDi~VfVv_8k}?|3V!|Tr%T|n!Co$fc)8Mk%z35oTY8n=lvE>*I+4u+IUC7l6 z0c4kfp_Cv}^XJapzW{C;v%pJ%Kzc+oKIpU< z*fDljds)}bduPqW-&=Di1+?xT<~5?jAWkQ7G&O~hG@h5veV6T-84Pl=Tm~kO@TfOB zUa1Dw<}r1)5dTFU1KnrmUG?)&7^M5d4EpXo#AL6P;ITu|^G*kI<1{vl?leL6iYQ`) zt>aWT!6r8mjofC9L~8O+=PrtPXTx7K9nIQ)M>1~lvRRZ2;%&q`kg8toLxOm9=Y1kn z>wyk+U0cFdbHf=E3`;T?ASocmjEhQiF$WP3Qwa-j5Vm+ZFt4%eO{T*2*1)w8U2p~K z$zW&4wyIgtZH!SBC_?C_63#ad2`WNu0F=TS-}RhOdtc4LsPTK!fNF#WRw@aPlCO=g zaWIgma8(auFaY8Jrk3cIu$Z^b%VMAJgayPp0{Hsc3?t^T9{Eb(#sIuT+?1VJ6i8NT zG(0>=d{gU0XD3UwK7Uv&t!+JxA;&Ya6pCbS-nhZbUUnbf|3Cf>?z(!3&;HJb_{Tr= zKk-vP_Ahwu_J)Ilfp7krckt)`{qN!HzUXUt^Z)!eIk|I-YcJd)WsBtv`lw9`DQuaL z9CNpqW*_!qF|d(|saTUJWu%nCdVS0^C724C>=sH3SUQ7rkgi$B5ct}J9A*k)0bX`LGr0)KT(#ny4W7UN^ z&_jrkU}Az)>uSq|=_$8&`=UV~%Cy}w$dWRxS&tj?{vKT1<6yjt)x{Odyy9TB$C}Gr zx^RW-M|ZfWL5Cwt5_erX;Lgh*;kkPs;I3D`h2g%38ME@*ulx?~y8mU|{@Bm($jjfw zI!`?R*^hGTfBS#)+Hd>!SzNlCU;pvH$#DB7FaPrI;A`H_>%Z>*#ACOwaqS~N&4W+;7R!6?1GhNv5spme!2mj&sbLrw`zUX`Z8vAL%lRy1_KJ&qU!JFUmc0T*@ z_i}pYCaa4Ju3X4mdc`|<;>ph-i-G0UOFZ$}&v5PIAK;yT_CIC4xSRL?)4$G@#YNuv zJ%5$YJ@yfP?Jqd&xWc#}W;UH>Vs{?f1K#_|?V-1r zQ?iC^0ocgGFbtG3)^`ud6oxQOHoWYh&etQ0Sfm4`$*u}w&!3}o%F%4D^}hBT^-$b1 zN@WMM{UvojdRj895q~xeC$gB0ORB;!16!^PI>?m*nmdqKSHnT+_D=729g zsfo-!M^DSgq83bHnuU4SHSs4_%pJHCI}Dn-`|Z2Y@Ku0lL{>{iORl*ju`g#hcYyqE z(zYy_h-$G!tGU6jjoc(qm{~1KXrPTVWJ-7DW9*$`(c>5;*J-EZeY2z~ptBjIpu>2s zROP6?Z-?g;FQ?rK2{oQ$VP}eZ-<=ssPBnwRcOm|M%EIhAFC=MKY1nn*vp~d^5$O(>bcF4pJdxl; zcPOfL+7$_?1Q%BDHkXK>%{758ghMMm>Iy;tU~Oe;YaAX5WGfSjJ=eSw+2`P~u#vwI zL>!6KUY$pK#$4Txp)B~1B{Xc0Zw->FjMbDA4GVCS@$Faw1D+J6WRas7hK4 zT-?9FW^>AVI}#SMln0WuG{L0Gl*EOKdCeyG-Z7fHc~}fCKwAP_sq=A~QSmuASQW2U z6^()#6(N!2<%xaPkf+^;TTF`x%4GDS*_S0OdM*Sy>oUPZ{6PupR9q-bMH$6%1@ih1 zX*^{y9g((o7={(g>69`ak-T6-bYw3{DR-`M?_Kw@`I4{WWmjL#_V@*^>|N%Ox4)a; zdhb8s&TsxCZ~2Ccyzv|U4DbJ;|AKP!DIPvq!#Hv4`fctyJwevD8SlN13vYQh_w8Ng zh2Q%KCwHDjjt)7v`}Lf@;aj-tRd1r)`3&1zPcV`gj|(ST`$U{ zz|~iOGnZe#;-1Cb-1+Q#nI3wC;bo6<*W3R%58Qh%S8qMZt98|7jriA8+?ddTWhAX`C%l{O@ige*_p8fdGArHKc%ddJpul_^d%jMNR&wcEd zxb?Z;v1tAXt5IlO>4S&PX(Fx`QrZ74ys9ChX);KqmU&G$sCBUxpeJGBNULN$8Mau? z+>izf9qgl7W`H*gL4k{XY?Z489}4*s$+yjd${9tdJ^ySTN8|sqc>N?*8B&$nP(sLv z6ypmLfXHR6hfjnz5FBvhP5<1OmQuD1Co%b-liO=0(IQSt2tUh*s6ZfJ8Uu?AH(c()~mnj7b_J?eW@n1>bQc zvC3ur=lz(BQp5Tk^wbp5$}3%ri|iuD8;9m>S&XnQ59-9emj>Y>vL+RVXgRo-cZm^zvsT1pr(GMk%9g` zzn{7OAf2A;&*CL*W=gk>vb)uFFK=Qc9y2Lo&4@&-gc?8;Olq#tcE}?^r!XQiAf8Ys ze!%MXM@+rSte!3om}^B9wEMY!;*W3uNwE5Gx0a@t1mabyOW6*Q6KnunVp8_3R?=1d z=Z@fj=(Y-T##QOmojR4_R|e$osM>4$R&Bxs)WqZ3%Dp9E7aGX6L~sEIn7*X-pvOM- zmz6wiV{4_uG{Vwp3DKAm7|(LX)Du)NGFls^$F7i-||QP6o2y1 z|3$v#>)yeI3~S)q|H!*};^QA#e)xGs!^C z1DRw6V2XN-wHW`^$&?*YL<^EkzziO%X@Vq?R{Pxg+^5(-I^@pn_p!Koz;b^@9*?>7 z`gbv0xR;BsdNXM}K`9JeV9M58U|1}X&4zK@a_?Oix$9N0=l)^EZ++?`+%6;A%`x}i z{|a9I$d_>V?1%X9&;K1ZH}8;^7XTPpFga%%rklv!7kK!qzl#OJ>h7y>{V~Rai$-JP zWCvOc)3_#Iyo#gpp(vPdC}$zsPo+TxkgT)#TVb+3;*=Qg11ygN)5$?1_z9 zS#YKMD4rp1R7=SeqeU`)y7FEOV~U1M&bxbnUd64{pL=Vh)brB#V&H}nVJAePiFVF* zt?ntM+2?1h@_vq5n1zQy3>vBXv;zTqDz|k|He5<8PrxT{wGG=*+HVbUa_A%`nzV*j4QP)#Bja*FFrF zZOJ@3rCa~sZ$CoW3j1*L(>Aay2zats%2&A%(?rO(iB?75Huv z9?el`5a}#Myy!K%?_Z}d^bc;Dfd6KPAnKhDh>j*mQ#32H16IVFx+Jq;YP5!TBjy8Em^joXT6c|uNuR&(Y*WA@I`?69QzUY&U{!gVHoz`B@C={7zV z$yYDPWF~wnJE;3SpZ5H*4K$gA@t>vrn}WFdXSEY5ekiM=rS@3}psHle;F(+3s_<;j zRabgU_LaJI;)7_GIVuJhED^e>x|e<)TN)2&!YCBY`PzthyrDCd*6W~G6llsytYr?5 z2CeB%6}+}t-D)}D^8@caCA20p1?_}e-+G0N(_~(S+&{XFE0hI`<5W&g5Ba(;e@A~@h;I;R^o!d8Vve`~`UnEAU5vLoLtNBA{@8YyMs1N^Ux+i_(}z}}oQM>ssfI)4p@nJ9 zm33R3%IdWde+xznF51F70yGe1NNF?@YeS`Dp}DI4;WBkJ9z+|$w0S`#2}81qNmo{T z=we{Gcad^*1M);#E!kUL;`rp2w~RNXA}2_T1IlLNbHDKu+;iW9yz;BQof|SSOj}-Y z_kH9cvA;avWIVE}CKO0Y9xTkDsE{sP<=M|a!AJk;4|3PSDmC4E^**M{7kT=9zrf4# z0r~O;PR7Ju-e;qyj3lP*NE#NvlI^(Vk-P7Lm)%DiH!SuN&zF(?y$hTy7u+89$$3R) zVs+^fZ~VGH!(x^B;7|Vm>su$J#R2)kWsb{+-};6B56j~drXnoT1@#t%+q}MpZs0!I=FzYR@{H(9&X>c?l`rHy0bE(JIgNu8l}$*oAGp$ z7eyx|4Na=KoJyF2Izg@elSJ9e!lbax+2Wy#bnj}`&1MV5B7tH3Y} zj<>|$>;DRMPYYTApg>>0t7CfDVgpw%;rciAFvJz8s+(K;C74dCCBPuO3hGP(gq%~= zlqL%53PvPQw?(!287}QC$i5*dwbEgJcO6H~g@^-L2~In}9q%wApb}&8xYKs8PL9aw zEaHlX-(W(Hmc2e#rA-*AHU``jls4|5l2(zLs&ELQ`Nue$cg2V%%Fy-|3!3Y%ZeYi> zOzE23C9ICmJc&LI%QEHh9@u`_K8|Y8njLFgZ%HxcUZ8jj zsg${O>pGV&UE!bp%zOE(|IH8br@sA@yyL6?Fvo{?n5Hd>p$@61_Yh$5o>Ht7?{c}A zG3kisz5nXnT-sl;9nC|KwXj$%*x%dZIQf3-&ePS$s*E>Dlu-d|m0 zoJO|eDHrz-c;w-SxP5%YGtXUTkp{M#Qwp#c1}yoo2D`^;-u6u;=<95#ge37UwC#!E@pG-XUcJ}QDyx`6F^RHRX2#8yTOa>zkYk>I z=1J1sS6N=V!pY|zVSMW)2n)d4pL;lky+`1pJN zF;Bhkr+CLV|GT{UYyS+3QrMuZhQxl(NSPqRC4_^k_jCA--^s9liHkaN^2v{q*{7V| z=E)EJ7?1v;@8wIr;os#G|MDMlVR=6fyzyNu9(sgVe9>3&}J}eH8uH?_#)gFRP>H(a(R5`>wo-5B=&7a`M70_AXuJczumM z5%x-EeJCu(#A30eP`J1_AeWKf{LWb=$@g;4>%S4U8&rgg3kzWxB{RyzQ}6$29=!kcT>R7j zNA9_Jg>?N{p8E9f^85!AU-Z_mMBny}T-h6V{QW=5-B(}916S_jXMgW8_Q#**E5GK? z^5HVFx%Dh>e8am~{yX2t!Qz0+S^3NdewL$Kzh#ZmG;--0JUB1TeXcb0AiDz)8k{Jo zE!E`aC=sc}J+NwAZJIz99z7spsdyy;KDz#vQycLfmV(HdXfY;6K)_ z4Kg9wc&V0jrZH=Oh5W5+TOw&!EA3XgjlGF;qs`kD{JY@;M+sFyXtdZXdex|0%QywL z@X)U)YSNkGMZE;KC+Ay;eakIr3Z%(*9|7WW&Zx~XoG4PPRJ<7>g;qJ!af~m#DNLne zr-pHr)vzGv#Kudkr&?&m)fDmnN^6iusbEIW`R`wQ{XrFm7_1kP37d>3j443&P_4;{ z(fzBgDMl@HQy$E{ucfd^$zshr_m8-y8kT6YP7GLFy@I%_wk9CQI>chPl_{>khug<$ zVS86zu|sPFI#u`79LO8fkM4|!qP0v}0~o;xjDVc0b%bO0$le(viLMtiQJ-9q|BAvut@@Mm)#IYfIslsx;La z_-zdYk{z%V^HfjPCSo+z8D^>$l--!m2I6u(bO9IrW%jgW^k}j#qm#Q^-4HG+*4S$I zd$G<{EGJ}AqHbY?Otn0g6e>nlJf^Zm1ai)dldVs3a4?HS^e{UKQ{b(;p7hNU*hobPjLL)H5LeExzBSSelM?h-5YuIu6;-&%W=(P z+e4oJr5|Is_6#@I$9(2Dew3HLS+=)svRdtv6D;?Z-2UwEz@1xM zNU&J$+gV;NdFI2v$Y#A}wY-*rDs$)BQ#|%7 zKZ2axWdGs=Jom|uar4>>tn$F}!d+bZ$S*OX?Cq^k5+C^0pX1RlO}zYdZ{qOAr}^-& z|0KuPu5s)3HQw}P2du6>#M6&|ijTeTS9t5|Z}a%==efFn7oYyjr`fys6YS>;Jo(Z0 zvK$Y&D=pAgi+s&4#L}#2)>RV-7>D0j4n&Eh>4ISEc1%Jg8?lQC+i~*TX2i3WRgtv{8SrBdoj&& z<6R63782Z7I2~bIU^^Ai$$)CH81$67lI$MNVsq<`e(YJyllip^wP%V`#R4taIM#Gl z3SK;FL4$HS1+2cu#$9P?_O4ddt&XEK!=Qa5o*(|2L?6KE4{GlWP}wPMjc7VL7pZU; zFr{E;oPx{inm!^kdI@hw&6(IyzO@o69SCoVgW-@g%W)w>pj0Zo1>Lt2^z(Pk)~{k9 z=lL~s*#Dhve3XShyGG*l9vH{MvRvVa3ZNMxBs<~~o97{LA{Cbz*mpVa;o@ez>YE)G zHrow*d4WiFWNKTSi$F>aX>EPys`*R5UXsEPTHn-bE-@GfQvztRPRGezC{rnnW3h%m zGMbjJN>;ojR3FOHHab9K$^jA$B$wj#W)p;~Mrsu!b@19bntSFTmdKhUVSR0a=%OBT z5J;R#^)2bZyMtDB)6(3+&=i?oE2KW%ELsIuiqtcIq@dnu)iJ6+bH35m@Z}u#CRHT) z`kKcgNrW9$31S3AX!f0Q6wm0+as9=oqZBIrrqT{de5Gn0&Qij)=yR-A`v@^3_C17A zoK0sNUZYqLS5(i&YSu88ShMIjNzC2<9F`v+XB^yM;U?@HT)MCoUrUXt#of|*LrP|m z5{n^mGFnxzA`?=?z0JW4TFrI53C;`8Kg*YW@oV_1|M~mT?I|~|Kkt1I+#)8fe7of* z_tr!|TcpIeJ+W}DWHC`?QWlGW3wPhc_y7H$;>OVlZ+XjGc=m;fgW*2Pq};xJllvdI z%G=-eP5jPdPjczv9dx;1(uo5Sd%(IBa#^!rU@O*8jJ=5iMs7@d{PG8{@wpc^94}sB zO%tb6;05-t+{F+5z~AG4{lOpR+y3YuW4Sya$qgo_7p;5UfJ#R-b?=pSzS`=?SqNs| zgz!w@G8bI4?>N&BuO&3Ar5U({sVGw!*Bmt9R;vR_nYg%rk*7ZWaX$OlM_4T`P%X@hJs$h;uaXn&UA%%$BOiU=PmvaT ztcDdI`PF~KG@hb)$*{P{^%tJynP(qov3G%V;WCeZ=J!aS`5pFFSIBwE=YIFMDQwx_ zy9gz*T3zC?-~I(Y`Tn0lNh}t7T)22Y<4NIz|LUKyWkk}FtCwHS6Hhz^PkfTg`&SwB zRX+W(-|-H^!skEr5tey@B5YMTxNsMH`v=CmWN^OdiYtvS>FCLRZu~ON;I21f4!T`- zY2%S*1TmnSDQu=Kn{mlzXna3mzqN^f!>|RW{f9lU?U$Upubo4DzMeY@RI@01vZ|xm z$W`q5Sltn!Vuk)WcE4ATs$jpx>owXiA%xa z$aQq!o`BIN87`rimo$%oS)a25EOSj&@`%MiW?<3&W|~%t*2gkmEvY;)Hq8Nkg!}Y| zM73&bwOUaTQjYl0u$afwA}L^gxa&%E-ULWqp$UkC5HnO~2myS;eV zEof2lu;O3=kALdpy!s7~G7L)t0SKjRk%I%23;fD^KFZg9!&QFpul;4-^)=tfb2sn6 z=9nyn#h`r2=8O1K-}CLT+9wSwtJtzw@Xy}+7#EhpH@@Rl9G(=mTRX8SXUeo;dveHB zgkxPW=7GF9pVLn(hItFmUe}lh}-8>DWe${hQ+|RIp&F9`Z1>Go<{cen1G9y?%}ha_%NFf ze}L6$#UxjF_IKY$8a`@q*h40f8Oz8Rp@wRJS4a$)#npl-GJ9!BRtvQp5i$!WkHWCn zLk2;o!k7e-m5Y6tOJHGj{|6IPS|)}? z!n$P(C0T;3g?(it50;yfgjA&3AM>zROMi-Fmcu1L*c64dBn?Xgqa#Sl4EezLPMTN@ zE0l#b1}ud42puA{k}Na=8RqFczzJl!rZ*3j?h~ zUXiheP%G!JrA!zfoGMr_+H#{-rI{8g+N|us$C~l14|kzTh4^l9*_o|jl&AyiLYk}y z!K6)=Ed+8F$|P)0PngCHg~+E0+!HxQjlSJ!Y(O+ot(|i#yM4#xcNFPxIZ%@^J$Ol~ zX~|ONvhhRnJG(*3E4Nv4EY5$NHbltT=qnn7X>eQ#Fl;ziQ1dLriS|?(NG0M*@hp7OVAwHCU<6J2E_T&b!hRy)P(%rlu# z54jPUm>CGgz2wlqXHb?n2kpmXOp$ZZVd^F5Ie?m8wwcVTk!qSeil_U&J*57eDt&cp z+k|NSOayB*=e%4y>_){szPf7RJ2jF+gc{l$xT|8dP8aacem_NizOOONHirQA(uktU zrQSe1$9J|L8v9lvgo^szh(Kw02_jHXHO_L_?1z&;$00)nit#aXoHbZVH+b<2X5Zi)tkeG(;?10$1YwK&J^b zH=>B}ABi3i3m;aHosF>`L}y%*e4L(q5+Od#U01sAw|{HAb+JOlL zN3~e4hq@~@xw53q8WHjC5k@0~JFcDX-Yp1Hb4h~HR_0Q9VyVoq#)nGH7XuZq0ZwI{ zO1!_Kb6;lZR!-}_hhR@KI55|4kNkcyup6C#Z{4}YJKy1;qUy9f1B_B+kcCc z@8k6F)Sjme#P${&>jUBp!WHku0$R5|-xog*0g#>OQB{VVdDSZ)ZG@AfBOZGA5nl7Qck}6wyoV?M=|6??6o;SxB@S<&FpeXW7kE+%DG!!_ zC<$fD!D_`*zk8k4u;jhJbCqcop^cdPYgM`IuqU z71;uslr&^ebqlz~r;8t9L?91U*h@BgoBVIZEsRV`9wK+fOKaxDgj$(lyqL8lQ@V6w zl&B8o=WMWQLn-)bN{k4Lq#iA6;jqQmy2cIHDlxnKifVvR4MR)Fke)~EhQMeAI~901 z7ZSC+rfpF+Dn?VlA_KFP`&8=JL{!U-aDhNbfvC;je(Lx_B^pt z)XPOi2nogmOY3HA;TI-Lnqkk+mx{|Rt#S7{jpSh<`cDT6PjD>o2Q^(r{dVA0r!9bVFc_^(T>J&X1wRk z0cuWW*Nm>MGvNF}OE!sx|U_!W*Qr$IHyT6s}lt?sEYB+@|wc!*JO`Z}-C-3;! zCjkc`HjqtEV}02!B2j23w8k&nt_WG7Zn6PfXQ&N0NT$dm|+~4$tr7k+#WRMZ(JeO zd6te5QhKQ0lZyAU_YfFU)+S4W)o35zgkgj>h5NHR(X?211C!c?ubrNra@VxxFaMRl z#9#T#{~`bT|KKn27yrVaWAE}Mwxa|06@5w`Rx~MT@EjKA%2Gke-t5R2 zj9As73I5)X|0Dj^-~M5~_doqU9)0xneC{)!CZz?X2zPGZ=G70~&;Rb<`*ZxmAGyf$ zPd&kp{=&2T!p}Wz3C`2RsD*?515P(v*4s6EDSN_iA*aOR(gn&0+tU-snVhVllw=1# zSq$6>5vGcFiYXw18v)A&915DCMpdk=kom9d^P@f@i#S-3`C4u~XDF>7>5c0N-!Pk@X{ zE*V)2C==79j3P+F8sKTRFg45uRFW&58oU%rHo!$OBTO>JS`h^AfMO zYu2N%++VQQA(lJqiKA^|9Ji!tOJbsV9$gXzpbh!&v{+%Vx(TrZ&MA3*T4%H{(v7Hr zohn4WWAzUr*3?=j}~Y1*lib)Jua~ZprSryLD413yH9{OvvuoyZUS}PX!R3 zHjPG!{aNtm*OH}B0ebXp5cj6kypDRl{ZVz#n=+<5xjlVomyo>JfS>(1Se0j(5(G-h zik80Nt10%Sma_N9dLnvq98jX%IxxAH)jT#MlbGTVr~Rzi^ACQ#w2&n6Dmhat$mple ztV^nOe@)0?hc0Dmtez^AmPngaye7PXg$TJR#gdmiq`$o@Tv!70(4A(*PAR!{#EovE zUVf{E&NTk+y&5E}@^Mc9RtSrITL&<&gjNt9;745G*G{zcn=Ncc>-Yo61X=mtVyi_h zb0#$4$X%#BCJ43DKs}?st&Pu3VO9p!_pCn41zWg{?WS)09di)GZ!Z<>S=a)u6vX02 zK8J%sx`P#0!n`Q~+zDorIz}8xepDu28F45!aX4#yXYvXMevg9nm{8|T4i<}p&JLi9 z(|RvBs*>om8xV7m7d-#W=Xu>L9_FwAkAIhc@OS?K|M}nid!UE*y;7ROCPFLX;f&k& zUDRmR+>6c(l385wY7%AzG^?bf%$?&6B_HsA{;&TA-}cS#=Bdwq(soCT_SUB-?B~oM z|Msupi@)fLc>38FxPJWwHm4iNOBRd7SSF+tD`U7ASS=IJ0;eZyB5$R1rWLBxGosaf>YynMA{956V~GplSdFy`Yj zgfv#JU4AdHGrqwVVTT_0SgmJMIE3DWAR?zp`5uwFgTA<2av|WqTfguYa-#VfmxYGKq!?DTGC%G zThL6F3~4gu0x_>k^i;_imExhK!lW7131LIgsr9aL-d~MO&aA@_L-6=ot)}rH6ZYtiZTmW9#f4gx`7bhm`@5X^ zdrGnY;vC0~tX=q*-OOy2ck>29!8mU&cAwI6$RY=zlMVeDas{V$^47L~{Tl9iiKITD zz7m9%kGO;V6zKCS`!(DB*}f1>UyI9?Q0P0X=U4*`FL)?N#n(2?=rQ;wqD-Y2$JEaA z6ujFbKz^DS4AN zvC@K7m_@jTgJC&;4R$qH)N%zPrp#nmssh2r=ZC7au$F2?5)=GQ16F7F0e-@AY@26H zI!Zxm$7JjPG&?dr7jf|%a2%f>ARf!+gp338nGi@`IU@!hV-JK>*I~}sVr|qxn=P5E za>bvMr4FW*ElaUL75v7!BbFaf%INblD?wODcNvk05~(J^|7;fatO)4|cP%?p5WM6W z#qAz(Lo1~l`y{@PzVVg8i36M{qls(hv3xS4GpRHkctR!f+~=R-RrlP-|Ls5fPk8*P zXF0ri#~5Btgcyt1VjD+6a;l6Rg~(s3K+@MNz(vj$Vls_p<=#73@yILgGVKMTSS6}3dUw02_F`ynslT$Wjy%f)3w9p-^WM<I=W8M?D097U~W*six6}yRpj`7F8etv4GoAVYo z8yl37)&!?=Wc*wQ8Se;^83$2=L=mC_4$7v9sR+Ye4>Fw|GOdpphb8IK%aP3u#?xDj z7cP?)SD7}~2w^G{j97sNgt~4KKDZdXLzj;+dxNBeFlFN*($(N^OQVQJAus!xB4~KWG5MQef=vi`ps%NoCVk(6!$qH5!yt$FBV-B94u(FwAG59Kl;vM9z3$LBC zOd@5ofH7h2biuqU#e4J&FqJOEMio+crJ1c=CNX63{vpPTGQkHyvhiM>EdD=9V$u&%CS{u{9wjjU9blqZ9CTirWAbCJWW%XNIH^r z%hBn`o#nvYMc7Nq-U3!dST7FHX#-`VNb^2c3#Z!pMc;*BAq_D)-wA3De6|C0`%za# zC`z(A{YYs!YpNj&9H^)(m@d1=QjqnUCE|XTa3YibPUL zK(+wEqTN^m9Qyl`V#d9KmfUd1&UmHH56%;gGd@?x*}#1KeSYbStcT$gl`>aQcN75W zXzL6Po4uy@@U(Lt@3DKzj6a8A2We*>m#&h5Tqu*w=G9kQY~$(jCeJwwg3EP!+|Xo4 zpI29(9dq*WwGh|{1q_+eh0}|1Fpt6X={FCQwigg_95p91B`8y!f2&TF>)Ig}vEkOf_9BP0q1qK?Dkhd>*V8@)G%7IAnnz7}TV7MA4eGBw75jI|`4b{c(CaErgst%X&K zb#@oa7;IV{u&C7fz|qXF-$%e>XJbtpfKOF<=*H76MSFsctHV*<4W;gL%q2<^+TWA! zf>IS4P3|Jp7yu27`bQSb=x4#6m2v^i+`4g%d>bCVctE~#pF6`0NJVHvPA1*0SU>_V z1VEgX+6YP9#cv10tlUl)zIW3!u|2xR^VipQ-jc_BSIdu$dm2Z|;Sn2-k?eFd70;7t zjM|JD+PYM$l|$}{C>e1y9wO|XjZ19VnWryZT~i#XR^ zP4l3@j#u=y2fL@yTXjFz5T#}TGCC=hlIkoyH0yA)VgKcCL5u0btCUO(oL*2kOXV`F* zGEPyVU3J9au`ZxKs$bi?g!sGl2a1e|n*+azl(1~$IVeyfzX=(dW z&k1$SYZJF95nU`FOmrlT8@74N;dbEGM%i20eq~h_%O&VOWqSk>H!lg&P~T!ZG1cGt zFpqG`dyt){a5$itGX zo(-2i-*dCLsH{Av=#g#l&7ll$E@L$MeB=-_*|m zm_v>^9-5DN$1~7f6-xv!l;qyEFzUD*&>)|=1%G!f8miVg&THbS!!tW`4Q0KXLoX9z z&K3e>o}eb*=|FjtId!Dni$igXGaKPpl@CgI2s)#2H^15ZeQt&(U0JBcs~L1dpc-Ln z$dmVis0w?XYvAg@RE3DZn!UVxNxVZ4a?1bzR~TY2b`T6;nZdyXw^=n^^Ydm&VWE_P@)|((HHHO~^&AF;4 z@U;Y66HKbsCR~zR<}?_O5Pbo{t7{cEAY#Zk!w}p`UlX@I{!Xo7QIuB;K^cmN(SR{* zTR+$IldnN7SGr4RQuhHSFFBe!#j3p{taepsxSJT)=G7U7s#~yoqHu*ptH&Zb`>L&- zn4l@z_68K4q$bKW3s_jgY;46XJIN1if9zDO!>5ouzS*oghDjPt*eE-}k{V-au6e0R z#-*pl7#2ZmsX|<#Kq}~zEs3(g(a{O2$JLb^fX?W__E>aqvhJ-tJ7-?im6B#TjJ39V zwJNb;6~zT;V}*@j778-@Nein<#6ni*{4LKYTyyQds5Wpv9oZc2w3n z8si>3$6>ohhb1XxC~&%6lZO>#7`FnOiJUS+Qgl0-_1`VLLlPJktjosC^ODJvRn|dZ zy)7*E7G!~OJY};@ESC!wB8=70Vdo@CW}>4rKj@R#+6)TfJUA?FzNH4ra9$_H!bn}A z&HJT9~o{p6r&xqNZgOr|A@Qn>s#57cvQEaYsQCS*^EB$<9Y7_dki9 zh^!tul`Ik6Lee}&P#O=^kXIO>n@Sj7n!?)y7NZ}ZtFss-6#qyZHa?%cL03EH6O@s~ zuwX13Hk*BJWZ}|6ImocgFsLw2D`Z@giy5~pbkzB3nd;L-ZB6hUjRA$+iO$v0qAbG>((Mn(_u+itg} z_ACzAu*W4~mcMXwT{zwfx;bX)inywkpp7t+Xb!23E%;8E{|>K;)q9-d=UAIvg<==0 z2R{$qz6b!-+zCT7eYmr1mo!WQnPmxpDfpc;OURKhfLhTA!vx~g5`m&I%dbXv!f@N zt+D4#(daMER4h#fG)e1g=HIvV@vtO+URHuByyWYp=P)2l#e`Wz(WtLa0HD4CP;6)! zCkN*kb5&1Xt3VUb;#y)b=2V+ChQ(1l{3NWq;vqv81_Mwk)2`ZPH-5#sMpoiUZtX|V z+8B;@2vLN|fVDc_jIS%TszGV==?vPetyP;3xgyz5XCLc22c^5(e}EoalaMw+cvcBR zYKgtf?$yG+k^xrj;^cIwOp}hGA#^}JHzqgdY;z_MKdV_JY;5A_!k??*GHl>G_Rvj& zHDUYAJfe|YT{92yaHK76S!&ssy|Ms^da`Rg2e%q{zKI5N2qv$Uk)?Vsl?lazwY2?n zZPb&RT4-Liq~SDSOWQnYE*ye+YB%s^HF0H=2w-d8lQ;tgCZbAJ*GNy=-b5MWs2nuAB)#OClBxcLm@{uQ|Q z?QE`ng1vF#!b5LE_x9P`xxwL6zso)MJizk)S8=#LWh#YBdsn!1{Yi9NxOm@#oN6Jl zWGEZfH=l&n-HgZ2G8{h3bme8NF1#GBf0Ai?0%XrIa7IL(RuWnZl&O=M$pmuoxP(A-b)+8A5TBO0Mp04Aj`6|1=kw`! zPzT@Z{qU8tZn3E5(Z4;IlZElqCY~&)0%w+QQRfo83k~t zSRge+Bx)7X!T=1^rgVMyVE>ORiP3etZI$B{>G#`cHBpQ=d|~>+OZPC$!We=kY9*T( zSMLrhjMK!nOe|dC7%{7UiV}kX80kY${18>});2duv1&n*E5NI+<8bvAYT{;xCafCL z>`m%`HZav_z_1=5BP7c^j+@#c>vVyt2{u5h^`1tc0jMj&q&>leV4tGZYqvd+x7X?3m)lcCQAQ?vPQR;AklXyaM$cveds_B@cK$I zyMU!C>(Z2~y8k^$thmtDDu?S=2d3?s8&7zI=8xzBux51pLy%17V88{YL5Jf9C3 z78lSPpXVdL_#@o=)<43f*S((23s15-xWJt!Kf~=O1|Ip6Kf!x{;(y@wQy<~cFZ-iB z@)K^UhfX%fzG>_L&X!`I$)WjBUQGF%l1xaW5YPT*f=+?rMu7^W3g+!i&f^sig$uxG zWM7IhmXXC`pJBNo)cATn5U&&8K-C}Q+6B?II8!J?mG=7cGr=^HQ)aV0=5$SVmu;Qb9E$rgRPir|fYsz@=q-=JUrRw@wAdBZgwtkpiR@ zg+UZ4#VUHyf%bocYnKn~er{l~qU-wEzb+)FdGcGhTg|~La}cjktLTBE9xfJ~IEQ#2srlysB~kl3U)lGmmbpLtPVfS@KKvO5a$w~I6f89W(_G`ET5w}AjTW{2J$X%SQXLg_f$iDtEe@jU z!Uhq8S;W1`SrtzKl4IlQNM@Yc7}*%divYXLc3@)<1wkE@x@c`r5$R$Td$75~EJVC~ zZB?V%Sb}M&>>PqXW_F;$;a@BDh!dV4s9J60fJ;YKY| zli2Oa9;$_VfE4#WQIn*tD2X&iK=hSp6-+A4bj&AW0*ML>{#F&s0kAX$bp~V>fa0Tx z`};7W;_fAJhEaif09&G(me6diL0}f96JvXS)^emIK9`;s*~&*)PxaLHtjL=u(w1~a zQ?b+)Yt)4Nc*8t&F5cISP!Of$!**WTzt8VnMW!>xNZlKkd5#lmR7XFaqmOB#+Yj@rD|<g9H^^#P=VaGl6P=!EVO zG5zg)nDgC$nAY#4n1dD%J{x?D+Hw!T1zsNt6Z4Ed5PmRb)dRHt6VvTo&fXA$8s-{c zU8EjjRZq`RNVEI~=_cw-Ga2zGlEvkBJ(ktrRs{{gfQoh=H5#MX73jVhzNTFRM8CUQvuyXN9u%*@VLF^w z^a>Rw5(tr5LRBeP%)2XSv8GAH!>Ih(HFmmr1jFs$FLw=RsvxRaWuk|y%{4o{xIlG< ztwc|k{;6&?(g?NNxn^$eE)-#I+0qIMg06Fh&34PtjXRu9!gIGyta(}h+hGr`KTWyz zI2W!wz~-~RL6$A##2|_N@g`5+d6tudhq(LF{e13s-ou@z9%H+HnulKf)m-|wzK4S= zS9$->{!Jc!y-(<6YKl$P-`0Nu;vVQIpoZfhWYtKxS(~)b>UFZ7eKF`DVy`1sr zl=XBGx%w9J!4*!P`dPMzM;uIBUh&#D^YFv3;*}4*icjBs9!(2Gw-)jt#rk?6WKptO zC|HE~=9DOt^;uYCsYU`p7_~5v7?Lm*dltzm7+EMDRS$IPaZ_HNh~^8k2^EP!6XZ#zd3PGg3#=#uQ3a4z2kF6vwZly2oz0nqi71xU?4FQYO&gXSr0m@=cl~SJ{9Avm_&&IV?;hB@d;i#0;I}Fo?L9Ef6OJMgL2mA{wzJ!1v zLW}zM$3%O@pvk--*>2z4hWBW{iZc5+A_l6!oxjhJaXlWpz#XryxMLzG2IOCN1HII9 zSwB+`0rIsrJRnsT_D`LAf#dInQ*5@`yM@QHHRVq|N5gcVRL^xN1yRhVs02`IrHkX8 zDvcs!q!xOSD4Np)^yW#9b+hqX50!Rb;K?~%w!#e|-(xde&bwRNrJpM%kszNtDc$af za}!2y4WL2H)4W|Z^vl<1o;T$YDD}I(&n|yUD89b&VT=fBFhi=)LZ}-}m>i!xT(Mio zmvDVS8PlPq5n!xNQYdM11_QXpU_Zx3#qNYfwqNbA#by#wZqdQ2mKN{r3WcO(F_)^% z_ZwjjHTR^&teG*pG~h27;F}t=sQFs~Tbv0KbI?X`)nYL-cQ$FMs&*(+fYwa)=|=&~&)9ea18dCDei0E$Ek`oV*4?%!$jckep+vK_)UQ`nyi9nq&VzC_69eljvcDKtT>R`f%4f zQPHj@6s7-L1q0&Vk9cP!l9m?s*02o`H&DqP3n@quQ&}yq5<{moIP^24p`P?}rCEe3 z2$@eI#@)O%?Oe@RorX}J3*BI-Gl{sf9{uy0g4YC4oT~^&QVK;ks0`%c0@Gq2*}Dk9 zIGTZBv0C!P$9|o=Kk^nXzUs^Py`4GG+9VH#o_2W-l@A6`D@sbrLMOJ{W5&GXxLn}&26Bdj zL0D$xXcCS~rWBagCm@hh3*`)8+ko#`pwPH+#eq9Kr;e~yJ<|UBGW)2qkSfYMP&j*r zRZ$9K)@pyB?KrVL-I#}9x!{-sBrUmnY4=XRlXnU)Y!hX?$#{613mFm<$wNW{B3iXJ z_gGuSly1#;r_sFqJqxlyccIaq(W=_-qy3*`p(!N3dK$ecLf)OTCRM|jTlgd7x*ux| zg^J(1XH}zM?3bU>`Nk zyNX7&FgId%7*FsbKVs$PX9|?W_#JTIm&WL-!Qa8+)GUWoO0eU*PqU6^4jI zj`(&w5w*jFRIR;}-;I%J?3EpcG%!wKF}Ea;L}>b+fF;QRcI%ic4vH(#^EC_5+dxD& zt{S@HKup_#FmPp~NN%mDi{4r3lPH1S6HT)XvWz6n28`_x*8`x*Oe; zmpBLkLgVP!m(6ogFq6B0m$(bL7tKRr-vm#*5voQTLN08}ZdYsZsr}v;k0s4gUOamxiQj=?mJz%YqhDbenFw)qeHo8QQIJ zsga{lE1)1ClY7z3(_>cE*nRuAHXoFNT5X$Zh6u2$m0@+vP%E3RxLOHs`CcSA8+69t4YDEt8#c<>Ukr;M4Lfn>y_C1eQ%)(bq(yLbzcmK z^iLCCzfSb;Jg2`RiEvjq_U|(qjy>_>3}o=G)RI7!0%=614a0DOyI%ep78kB?_v^ld z+wc2v4v&r*Peu-pw_F{p2E9t=o|nIw&p-JIKKkCDVE?Wwy!|`=a~_+PJoXD8W_`3_ zap{1YM<*;xX78cbaCGn>KmU(@fYaO0@z5Xp3%vQ;znc&Jo$q7PEolL15cAFgtE+eO z$&dUZANu(pWmsI~=krGo>ZC@_b%dD1x3vo5wuYCWVZJV_y5TZpjVFO4@u z$WTAVz151-@otx}?(s~q7 zsZkHAq*9vAK$REk)6@gv_EQY6d0(pWW;ZM-!aTL-A?-;~7Q2RF!fZX;{b!|Q&!2=j z|E;^z@z2U5MLZdH{>-{Ru_xVl&v>0`v5JmY0v+mTN`;75RP(^0CS0kKNq63152d}K zog1J=6}9y_fB$BCQRTrL>b1Z3Pw5qlCi9w=VJ;II{_wqS8ZlvzJTtbPcScG3z&M2t z+px1g@k!n5h^P^Y_eP44&fqm#XWxEqx{uUnexXXkOK#j21FHwh{EhWc0>*b}Yq8gA?%bAz8tmL6Si|}}qy4K<9G$KzO zcr>t9eC@07EfMQCCv;m9x8i6Ba|;=0yHxO)mP8UAR3huiBMkzF!V4i#JpdMB_&x3pE zb}gR$0OzBc&)2|J>nmbl*66l)yPH9ifz>jxr-kwOCilJOQC{)IU&HqD-Msm0zLQ`7 z?Vl&Y4fC)<*-)5Bz{?(aGj}ds;M(dU_ul_7oLuMhh0l`HlEvOW2WiQWGbiJQSKjpi z_q^(D+*s_frxP!`^Z++L^#MxRlJk-ad;9Dq7+7;r1x7wglk)g>q{xOp7b*UzlKhOqr|+s;G3v(~k0m2Jk~J zb!WnDQSFSV2Udk_?EdD5$G+p`2t!$)gXgw((X%Pm%{tKw>*EuqGEtH+<|QZT68l-X zdrugPa#9jc9ut`yiTF!fMqYL9#~&s6Qi~PsPG>h1NU${8 z(EMG6nGtn1XQlO^h<)s%Dg65}=UM4~VsXzv@9G6oi;$_^qG{7<3TDtFwEPLX-$Iop zYH<|}4XR->(XPi?Bcs`vsIucfVTQcOP3n<{_ zkm?~cLu3$4xQ5#r7uA|GF$+V{#=xvXudjEVay_Q>3V=$eGtoTHy(-0@FN&tg!!WE$ zRFt^$4Vep1>6)@h7cz&tmW|WT0JowJ^o?fBOJ!wlD*@1kujTxhd2y_DlSyzs$a zL~cIE!IgV>^0D6{$thp;mETHQ>~ZbG@8|O${8=tuSTRil*FXAxPM&*;VQ-(J%B>In zGOv5&VP5{mH?hCE!nMVcqtCsc>mT};r-_^rDLY6ip0Jk_lh~eHvr<2a zsw^x6!L~IeL`P7IVNW@ebYeg#wGp5zt7_pT~iEhz?PK7&1 zhvp4RedtDwPR2qtsXSX{^7HE|N=Lc|{8~6mrK`g1T(<7NIQR}Q@@cMe7 znm}Z(9PRR{7G`6dBSNWFmE+@MQn4(RlRR)ZTq0}co|RG1S`$wl7M?$ykm-o=@D`U6 zVgbcv4~(n%Lc6m5>S=rG`Y$6p7Bz)1 zrF$;j9(7E}zNV(!&K9#Z(5#m6m{S|D%hwhy;L!hUm7$$^s?rLpxKbM$S-dT*>VY?m z*B3-wet8ATzEp7=Kj&T&n6e}X-uC$}AD@3G6t9Nig2WMvj|j0j~1d8GfpjtC}@NBoD@|W#n#x4Sgy+x`C5i!+Zf_~{c=XmbCb^Y znf2p<*oAbClJf_>USiU743$dcl9PpAMEFLTf2Tz5fhTu0!=i0?3%ltxqYjjN7*BH0 zST*oUG*oMoqC}VB9tgzW6lbXF-Ux9W&l!+q@4JTQ07OfKeE^ItBq};8yOrHM2hO-+ zvw>#v0VH|#o&NNMHC|)d^|JYtj_?8y#*MjdOeD*S??t@cs$F2^6SKWfHIn%}QzDcM zA6vxF)v{s5G~y(oJ~S7;c!^Q*b(~uu8gr7+)?-tAjT)egHS64@Kc!#t41RD(%4cf9>ft?)SNf3nl~c z@%PqsmzZb2uJO0vlwBxT?+!=1Pz6_rr7e2>dVjt})D_moY>Y}mE}46^CR=wxECg&H z|5+`v5*Z!N8+=Sg>)i;d#is3FjIHi7L3i!Y>_C=|cIIIg?G+`K2-JKFMTLO{37Dh+ zBa30lm5UcyWH`D0Jmcp+#{G|eIUoAaFH_d1T)1>M7xz~TS|~{wr7$d(jMIkC{rZpb z)Cc|r(>Sp?J!ZAHkIKN!XP)G_XZ{x`!fJ1i?Ktt=Hmf8X3f#GhP+^Zv0}>b zq4)dQxRx3tq z4elmMmONiz!9bxfl~Uu-7s-_Ql%zIE$_~J?WF!@~SOuq?l}QDeVDL(LQ5y&6F+ySx z8`C&?5@D5F3iLD*ydysA^QMB|_cE!`X{%Ub=cXnw5;f_Y658IW;NF}S%JJcCQeJSU ztSBWh72#k3`$OSqn@P(Hto94j=?M~Dq`?{liZYGnm9FRF9KN)By_kWb{=IfqpFc-L zX5IuxI}VCM1{gtH0m-{c1{cTYDG-jjMEQBXvtm# zW4tU(J@a2S@x65nYS$^MxYqykY2vRXqmd;DHly1mPARXjqIvr(iZpp$>cRfpaS(XF}P+r_Q%LRa%kQ>(VW3 z0717^cF$;sL^}+xw!T3ZM3}+(0xzm@i1_+xYq>J>BKTEegUM94}tO{Q0c8x zwwuMj+gtywT2neju6a3>GqJt?S zW|ld#o=zwmOY}{Pi;xX$Puq#CnZ;o2W|y>F$?-q+CgJe#&Tcb_qCE-mJ6v?Jk7#|mq1=cOvth0ke0pfvW5+)tdWXiR$O3ssuGO%J55bfAEGohpcx)^pMTbg((_@IGH%Iv!BV$O$G73)Rqkv+m$sh! zS=c7!_IAPLbHq4~)+{YG-qwTb{_{WRwQH=Ioy97z zonvY7GLOQTgmqeQn@bek=fOSeH*qv3?yQw-Yh_qWoZfhryguZ@as^skqWO7t@924o zOU$eBx!9lpb){lrVZI(B;k^(1u=}@|*W6;ioBz_}$~j}SfjYnRb(F@ZY)l4PqtZ?o z<0?26s9x4kq#Se=G=zz>DTm@B2$izx+W@@S6Y`EJo~B@CFcxnaLPGcV#?$ZXx) z@4U!&nhc4EfF9&DMewYQtm{^zSh~Anv9yKp81#z=`@7Y{Qjv~ksOxi{7cCw*H+K16 z_nt)`M|7e#Q5=yEG4=>wY&aptHB-2Jypb03OiBNQhDZ-H~geby^ z`Vbi3AhIhL!Qk9_M`az=T43){)ZN_S3DHVCKKT>^qJ3odnJ`IYFH!5$>ekxUM(SD- z@9e?6?}HFv%>^*(u2U;_8HK@&hJ8I$DV^3G%+StdYU7DKj;>B{8>fYF#hNAmJ@`cL zevJc7jpdIc?cq{Yqi;=)lIJDFzSKio%cRW@#LR-c!&HP+<8BGCn{w?Ce!gX`y}^{0 zv-k84qdD^nMFWS}b~RVAe?$HKU~!YdJ?eaoWt( zE4n@G7jCtdb!!ufCgKeSQzhpH!emA}^Yw`HN~M$j*)}H+ zSLq#8-TL%GK)V}61f3>^Bs}n%H*kBaT+#(MUU-^kfA)vSL+0X@3q14W$9eMc-(e-f zaOG}3{ky-4juQu~p@zpyQz0WP^OBN1)Ugyql`NUG$RLH1CJI)`|YNTXhbxJ-pr%2wiMGI}*TdUB;Fn?*d5_<)oXWG}cN znML-p#nZ$hXG+S9)8t}yVu_NyYSSVKlO~oaagg9}p=@(vZ&;Faq!eFcNen4*baVts z_{y*P1{T9$3C9&bbbM82)a5klp(kqmxY6nSWaDQoc%cEl1if*|k7lqV0VG-QqLh(k z%AB4ak%t8PcXO(lG#R(ZSsBK{&Fzv)tGn1ww~@^$!!WQpJ+0lj$8q!qd7M$Oca?>I zt#{!ZW5dp&vbl;|=mR^I;NQwbVcOg0C|zOHJ?>w@auANTaJ+?^TSXRIPH#NNcf<}hCmS%X^Qf`)M(Z^fy3%XVwAMuH z8BIxe|9jBgXhVoI-x-W&XDv*15l$BdB1{>mB4~cjaGu_ewgT^+y{Nf=HITAbX8LjO z;LhEvGw{_pgi%cd?c|t6yk@82j!T3Bh}OJ`*u7o)iA9`q8O$K94P!)9I9{mY3so9k zV&gU+xGzLt9g*S|RGkrJyPCD%d-)JqmjQO`5@`XA(wBi-wSo+AjW^yGATXYxab)5U z+q=}087<7nm)i*^nuS;yQ1N#fkeM?It1e>a$u0DRf>Aurz(IQ@!V-B^-POT&(~7EK zQOBgM3PnSl#%zkOhXdaf?ly=I@OTS@+I6bNn$#j6M0{YkXU@SaU&ZrIs9Wol-o{x)v@6*0Ld&h0t%&Vkl&Xma zXX;OtW+dqwqxBYk)yO5H(itUkh#FYf^{^O|wfhT>9&V}tXae8>0KlF#cm7n`p@8d)7 z`IlT845$pr@=y}OG#2t=V4d!;-mFQQST6VKSPDW`WjSQFsE7CfrI1s$aGz;HhEQa; z=u{8}CK4%)c3$&f&DO?=EU--GLEU=zlTb)gft1M^v=qhyk~0hw(^MFMp%gT!`AtJH zO~p$DC(tcX4}F{(9ZyWCSpNl87$lPvwq*+`v0Sdujj~>^fo%L^nn)zJxPp|D)!i2_ zZ=9^GU@2z(9w!@s*>Pzb2C>3QT3yyE!W{||{(mkAx!lcSF!)g$wt#V_tpbQr|SY}SQ8^)7U zrijsY-fpE^+j;MmhdG!!YmJU840mZKET*noQSy*k?(d1tJ>l#5?1?bFWN?MF?+2XN?O#576dnf-e~tyub1p$5D!TT zp=*cJtKSsyIC-e6=9%7;Z?+NNWZ$6!OSPF+)A&+~P@2iRO{#(1I5>O!liaA9L-tC{_i!Rr9Ep{0>}*3`F_7M5j5%fvGWZjTyHO+`@`fV$zN{ z8~UX(x+HD9j)L)%;vY>^g{uQiaV3v|>q|`r=&w)hK)%*7*&}PqIB~`nb)T!kBUloY zG0d3)=bAME(uK-^dZwb*DXcNj$fcMi$4XOAX4VaVTdjuB3$+O1X-P&c3o1E{I1L5p z-T@B=v||rSosThsdHiJKMvbWjGpe!s8cf^f6zdyMwpRe`e)0FX(kL_5;B#p%dD|*~ zn%EhQB=DfAv*2I{j7L(Y4YA$P5ls*H>7UXG#_CAx2HS*c6Jq8WF&e3BAMcY&jqG0b z{Qz+D_}kf~btmRy_YsL?UU=a-Uh~MS`G5Xb|95`q@4bn`Yd1LF6w2t7?y0tHCaoWE{Soww(SsMNDEXau3kQ1aq(WBedbAq zX^W!-_1zIC+>u5*A`fekx)H6Ayg}#Wa&($RL@q6edRd&S*-&Vqw`3 zN@D9JWrk=5Si45SkOm}W*5kxDZdoJ?L7GH4*gv3@!lZ@0yoaiC>CypLFJ0mGog<#T zb`70I4h{~ub9_um$~)fiD1YWpeFuxQ;pX+*h-8Ytm)Us`r->GuZzR6soeG+ifGa_J z{soQhBoPAQo$R}_CEC8{5{Kj_nw2C@Z(gTN8&;R^W33D0oeIlbC?nk7u2>HXE=-3k z^OntK4GK9A4scpknO)1}?q_ogbo+Prp8oudlga7Ta)nGj{+yVOx5y$frGdkAiKBdx ztcm?x7*b+etdsSv^@uD+);F(leEoT@3{V1>w49vt zuLg!^&#$}OXrTX!_!;cI6EW|0U!3`FT|6?S$|*Jc5#E-jl(-@wft@<9k%n>F3^#V( zCzs)gSuRuHRaGytu;Y~y4S-%sQGFnTZA)o_y@gSa?-Pw!Zb}J87dHO6LDg8 zhDvCG8m`H?#uHT-Ca>-yzS!Zq3}!18RAmQ(_WUSE8Q|TMHY$skmr$To`WYN~j*Q31J+O`W>UY)*08x-GQsY`uX}xrNT~_^}vYQ z^rUIdO_{K#MiO9v5*(bjz7ATS*-E5}m_jtEcY5}CWTnN)3DhQat-^-wi7jpe`2paQ zgwS+42|{XHWTnJ3#-W{pBD1wNgOVp|#@exE#V9?dM z!<=acw#FTpz}ISa&h(t;)JN=!zxJL6SfnP|LlZo4Zt4U7HCOP6ru4=0oVL5=?cb45 zkjzvH&wu`Nyy3z7_^n) zvSrBT>6C2N_EN9}V})tlQj%EM5oT2?rI0b}eDpNPgIFS~s$1znJ=~@W5D|uyDu8n{ ziM2zUCUVM5UNTh`_7?*=WsXiy$znCcLMg2!{zTbJ2@-7F%A6%LNMiDwwjpObtB89o z%nO(XD^EO4%2d1y#8hAq7F~JgZJEr&nM|lAFLDv#SlL68HseT6nKBh7RrXeUpvtHd zLo&H^*M)(*4+aiTlo#$CK`EqR!SQCpa+$e$u;AqOv)p*$I+7MMK3RjO1H{aa;u%AP zfvD2`o$l}L9L4#w&piBf2k=-s2`j%{YRvV>Qp_WIdU%JeOsp>7%Z8P$@0iHRxWnm~ zI4zf1<;=l;W>L1}V%4T9KX8v_lEmKL9wNf&>FEsU&Ck+YnP{=^^ZQkml7#JcWZG`o zj$0^&GGtB`D~|IePNoa&A?yz(Pc{>5QEnV>NO_CizQOw13tSu)>@5cm-?P0*I#m!X zjtiRfX|g)xNL9XS*~J&(=k@0@o9E1MHeZnb7k}+pE4~>gwR)^}uU)SO(E8PQ#Dih_ zo_<1RxX~zNbr%-g&oh+T7xfzTEZMF?IgMr_nxaYvJn(t*%-`CiuI-VI7w#UX8 zx(}LsikG#0iinW7KX7)F$6D!P>rF0mcw;3L-mah77pN@2OYXx!CCbSKL%;XEdrUPB zd2!}%8(Z9(WWOra@<}2^;6`i?0wtl*br-SnaZ=Ga)wb$%;~dujrcfDqO5th9mG%Nl zHLw-q2%xQ$TJka@Ue6z|u3$rT3!XR_ww-K5>>;ZHM15jsNmka)nRf%tmT)cgnKaoY zK{!}=4T_Yo`UeQKN=Zh5tt_fPhT3|bc?nd9gAM?-1MMwbWGdq87+^75#T|Mk6!qR? zUanku?*tK>Uy1J8HJq#wS(F}&v4`bEJtQX%U#wpPoLWJU?Rm$jon8{H9=cV@GW%wz z6}@oZy^Ps3CT+b$y0D(^G?Ws+DODQm6_;k!@b8p3+%aAUD`g%sP~We~>BJeZ%!Ogk zaOUSkn~XbWjQ$*7z)FJLZ%qSkSRZ2o zhExSoaX>$n0_!aoR!da8e}P~IFYjYhC}z=~U_Uiaq2*t>Lci(u)4_$J=(a!+7Lr-w zz#wIGGkMsDjcFwbEhCA+N+9dVkQ0;B+*GW3(1nzscnMuq^u%t+>eXa`o3}SycLgNp zfiz^w8uk;&(ZsbI6Wd8iX+iVn1!s1k5sHAGrO)PV47%*XI@+Do(2tHjn`6n z^XnoN*c`^iU0ZbWZT*SX`%UFeonJ|p!k?0V*k zT3%9;p&Gz!OY$5G(w&u^arJ9B&qq9G9&H8c9)z?iv-4{7m3oY#o&1!pIbQ|)RAp+8 zi{@*NP|Gccq)swfL&@3qTEs*ZVLpsHXrzX)2M05|fYCy2`t}7}FF7PBi}gt`uqmjh zht(Uic0Hj2hDe5nVu@#Jb(BpAPK0H$5=1A0 z%0#%>J@}8N)sEfYBCN)&4MwOwSyvXq3Q_80-GUc!s>yR2x{RsjVw?jZ<7euiJyp;+ z^CSd0se!Y3BQv42WCx;yG$kx79i!_Av%=#(#!l_?@Pfpf64bWWO_DQk%Vn^?P8Ey= zo|Mj7(-=9>C0>WJ+gDFXV#y3T{;n4 z8I~L^Yohv?k!sLP@_p*SOtlg=VdI0YpLa2yE{R;hcak};n`}J+g7Min1v6s{&Og0b znkag*b~#%j1b07Ep@wg!#;Y2S;G)E z^OCk4k!D8qpW|Gp%{L~LR9X0YP7e<`oC>Q;SCG8}PPUnn7c5oSOGXzX1BYDZuxvR< z$6Q)WNLhnU=ypP8u zt0RXjIm#C~9WIg59z%hJ6c)aCqY4`)w$qvgYt}ceG2S`k;$p$xkV(;1I|WQjnQ$RcNbN%+MYJn(I1Ps%xcw&nB5oOY`nln;@|46 z=Z3E;hVgq%wT)0|FL~S_(_Uc}Q15IWb%oU8|XqNZPxk)ST5&SgH||`5s28c?%cu zaHCXrrEwa8LZ>WLr9U>$WscwP=0&@;R%Yt|Ep<(I*DGX8DZ%Y9x#5*Qb1|N)-dX@$ zh19kt5%uwfTrW*w2m#x6sa1$^W}P~U58@1qbV>q~RS$_oFepY~erPSOH;A@S!H5f> zf&)e|W?*NkXWTA)Bo@pne%ogD*7ji7(f~yeuQ)MAQj`Wb?3jyWpIgBaKtK_cbM`2WK&lYFYKa8XZTg zkJ42D5~5Rc9D!Y+HV13!;}d!dorNiA9Y-l3+19EQi!D48(&GY@5+O~_Jf+2K#vJi? z_6CMI(+kEDITD@qHxe!T5U~J|bw%vFN|8?B2LsZ|;QKRD!JpHxM*Gh`JcbCDvUO>V z0~@0PwQwCE;`;#ykKr;lMpqO2{d)n(;hb=*Wb}>aN3x_Bl7$mzs{%6IiKr2Qk_7q`>ALC7PByZ6W-tRubJV6*xEj~ z%4F0cnIY!n=#b;nHT(D6#bSBDwrm)6pQU8>66^^K0$W{hJYC_iY*?m&%SFiv9)GoI8yW*AOX3*)$Dnnt#3%d4SGD20>;k_aP(wIohia(mckJzONGeMBJ_ z^C|>ynM64nx8$^8I=;o}^&7BRb8)d?H6-&ahygbZ1=HnHikzH!1sIO?*N!Hdp-bp^ zNxw%xO|I=K6KN34&Yr42N8|g6xqR!uD6?_E=tqi4OfjaOAelBydmwR!t%GzV4QRT*>UT~g5KD&1zgU)(6|KQgbP*#;%wIYZkzylDgVAicpjf;vGwkXL# zb_fQoi_#P`Z3|vGh7#3nYME5YM9gVuQwFRYsB3^^?Ob2DeOj=}&T)Vp33E7?tmN_L7OWk!dRk?K~iIaB`gMN zv@uUQi-X&N5C6QBVxTwnP5V%qIaoG! z)IegLZe5?)w9XPK{WIpkBR&f&OUzhO@xL3$my`{lRyS;bzY4dyb+D^iQh?~GV&~K5 zI`t)tcfk8>Ufmqxzg{gpA3&Xdy_n$IEvJ0e`_z8#y$unzd{!_DNU{>AjWyGnHSRE0 zX|ut>%gnpcKU>wx;#DDg9tfwxWiTY5n{3nu6pJmBD?<2N&b-+#Xfblsu79l<(V z@3Zu_t7z8y;>`R$G&=VLoKKTyzaO%xzpq!I%DLYQ1-);CR*jKkVGuYNGN9y;u zu54NCUtq(;p)A<4$6ihhz(G>B2&ZYurYw1ODj=uqmo@u3l9Dh;V#sbPQmf)()$+`) zxj8*{52~^)N*NZ6B#w(Es~=0|c(_PfTw*EKKuU_T^s`kk`kR=boRX$B>B`3!Sjm;@*+GhE3Y|YE_)TDj7gH8&p0stKc}{ofZI_N`3aiV*lv3p( zbY~Hlf0nCxcE$Sf1+az4=WO@P=j08}W>toylew{eJN%;K0oB0O?Th{1$$gpQ6#&^? z&q{9*_0s+6jLb@%X!o&);vhzW!Dr@jB``>P-^}O;vpk%fx(107MwAvBT#ZG^C9*+< zFX(#73WHIf0XzsI@ZI+?o;qM0^!Vf_K-Charpa9T!K?$g1yM;Bt2wU4Eo06^QV&KH zW%6#MK0FP#b|;kR2}^2_M?k~&M7PMi1qj7K>Nu&-g+%Qh zFSaJu(O8^O3R+SNtD?eQ;s6Qu^q zUSESjs=(6Y6R7yczSnou>@6f6k}d_`ljPvs(kH zpPXHr-ijXpYE~;>8y{`+FXuk1u5-8l=K*_>j8qiqeQ z-U=|$=Xb?k?vBkq=!_|<9$Ouq-_0AC6!r&UTa?oqH^|4w>|MG@TI{hcYfiUI_J%!{ z$vS!O0i(c4PD~tdEC(E_GNvsHMwYr|$(8}doW2%*guu2~Sz1Nd6y-!R+q{pmWSPw~ zaFDRvv;s?)H4KT#a~9B3w(BFx$qD0~TWn8HImk;^i$qRlK1%AwNRrEP_ttA~l#HTTrQN5dB$T+3VOcL4j+k1b4Hh~=~wWyU7paFlWqGnr#Iy6xrl#Nl?cU&idyG# zY7I=&fqWb<*u&5J*11EpLV*ix(6g-b<($?z$4lDWMt{z3B6jnl^a_*iV5b&+(64W2fTP*UjtJ)>RX`>P=p;+!5 z-~a}7j5dGkUfVSO1{{36A&*sj2)4FSRi`E0OPpArcZ6E_{7lk2v$Tpd-JogKi6FwT z5E@9aswlAn_MI$7M3UGFTM-Omq zeS#pQ-Rrpsr5N4Ra(V1rp;-ENnsuk2PwYj%*VMBQ^91zN@r4SVw4IBXhwWXWx{>D^ z%j^o5Zxax0taFdWRApL}s5N0x>I%hE;wRa8PZ60}d?J=uqzCWaNGm-OV(<6>zXWVC_=eZAr0c52*?Q*2&?R!!`&g3RGHL3 zN*-)}8y#7&MYd};Cr50L?l2ymFqFdO#X!o53=D)vKx<(t-!V+N?}2;}dzYc_ITU=9eJ5JZpqckCNW({WNgSO^Km^A0#sk|LL+JP=N0A@LnCdlhpO?HMs z4kF$^lo*iO_|`1^(UT=nw>6eey0PN&kxstR3>;NU3wb7Iy_jw7Q+-}=!l=eK+d~mr z#mE?wpJlC)=G{Kd-(rfig--{C_c~f&qvUX-5IL!3{_vM@z2vg0sM%2aLm{EX%Ahd7PXPPi%T5%{XupIwA=Y#orr5<-kAP-+%?d#=>vRI7<><8tWK0YvqK5Y?sHA*y)yP0!`5l zmuoy@LK#h{dG(PLN7MI8WvYrF+Gf5hAW?OlBLG;eYpm1`#&3?EMhL`RwUr=Q~kO6|cq>F~T{@ z3C5Gelr8CKJMw{wsw-4NxFASBh7LF;Q*r|&WI%GJsIoac z;^g?0<-v;O!9LS)%9IwAw9i@>Op?h9AuBMN#OwbPAY~zUHSlw?K+Z_PTL=tOM?V=5 zQ@=(nsBXxtk#S^ua>VBF4%?FxvI+;of?>#Hp}ip#arf{?^QlI?vG5(QuQBw^Q}|-* z8ODS-TdlnI*)#6Lp@s_mKKs@9ju~gD*kgYGdGvV}d@A8}4gfvFFbd6MH6Lu5jm_Ux zlbr*Ib>pjeqJKj`3Nic~*U)C?65Y8GN7G@HnHiyaky?3wL{T&{InPsBe{X*X5!wTyj^Ffhs9}-a zur96dFy0gAua2n+;+li2xZ%~Y+wMNUl0De-9k%0u%R`Ks1kQ?w%cjOLm9SmSER1;M#5jJwfE> zh5e)oCVOJ5YD%&E3=@XF;TrBL8@E#o22OK(g4ZzKC1Q2pmo!(>SL}=8fY`s6lg!rQMJ*Zr|JB+c;mPQ|5m0+rNc(=QL)QP25Y5ea&&yhwtfoWlZoCC6!_x1yhcHX`J1Uu~?4NK^xfz7z9x0nq9hYxA9f z?~cZI*H^mm3E92Z&r!=E*u6Yl&F?jjaD*u&H&1v4C^{OhAllcj9mg)fvl}D6H!~$j z362;&AQW-sq}>RvvmpS%{FP!sga()<;L|t@c>#?ZMuLk{9H~fTks?OITQM zkYN`ymGJ2MTKnc@AZJ((mQ6Q~t{_axYS^+$TV%7LtT#;SQ#MCOoSvML6%G~ySs;lu z7mNVjFysgsTw&~eoijrgLUIp}S#gJM)GuPaufKQ3fV#v@fj_(A|7KSOl618GA_~Hb z8+PV=*#1`kVo!G_r#t5*em^_+hKbCur36@3Jhy2_A?U}nOP^<+-;H}V;O_Tbg($p0 zl5p@2wM==O{?dDK;>`Q`@~GE{Fz9n611Ci#qO<(py;tJiI(1{8cKe|7d4~KA-Z|T& z9iCs`*FfeBbIc4&9kI+KDLkpYeY>Lr>q!zJv9?C-LDsv)<(PPYygJ|ggAnvN*GmgY zB8YHqp$o!nix~@UKleZ*sy~?(Dx;Iu4XZW&YwYYm6~-DCBG;LcTgxi(qzbnC=1i&{ z%b0q1lq(n%v_zsxoUF4=R-}8D0r?nZER5fuvN2duD>X&{i_QWPWx<-{M(c*lJjqZa ztSVw_BUw>B{Js}JPIxKeT$S2Q)VY2Lm%h3W0+R#Bh?Nd-VFxU%%pszi*l!@KG2u`| zqFZDDE1REvcPef<&4TsC@Huqu*g1kSH)QKT#&k8PkNAW#$=FsHE`5=4#fVy@> zu7ZEwczXYg_^c^17U~wIImHtZF-DCGu-Nk#X;4(pqp!;x4$J|;S&x82%m^Rc!BRp0 z;ic)e^QBS3bw?QYYbX7? zT-a;(J39(jtf|J@cAuAS>~l~%2fTR9cg#A}f?0C7?ozCWC)Lumw(nhkA;CFsUDQ3v?x@+Ot)V!qwUyZ`#hAZ`8&|2OtswQ z;OAD#_3WA19qZJ7?*WiDKwkynBn&d3S;nZo0DTsPmalp1&ig9#cD}jF3@2~ z9#%-s)^S`CQ-M*F_Y1K(6sM6ILMR29whT!a(!{h~qnnY<$rd(ibhBZ5x?$X|NviA* zD~4=9ClPz3UW+gK;DBgBv!lX}C(h{~(8*;~D0~jDG}iC@P_OdWdlKX5=D%)=K-^-1B&r#^-!=#;u)K zb_H0NpN(C>T@hi26RnU;yu*muI#~D5aGX*1)gCgdRvD2ewZfHD9(kT2tgWxs^|W;l zY!TG0#*h$~C@?1U7E`rZ^r8+BAOd>w>oIOaH8t zkpFx^*GmgY@yVc5#AlbX-x)7;^K$Lf@Pqh`S z(IEobGwU7c@E z-s?k)TS+9&ifwQ(ARE7Fol(I;rL9L076HV>*TguxAJo)@y97zO7OPYs50Fz3sj>7b zl6%HcD_NAf4wW|0+G&{pE3pSY76Y1=jFwyxi0UoA8y$NHMi5$evnHe-uxO{1m$5RX z$`XQUR!|TOySHHX47(e77jxJ{q@Wog)oKVWvqSy6q5QUkES(i$_qo+#jVlu|4(-Ds z`tkQ(7VTEBj?$}j86D25vUEam#tbWX>XhutWCO(Q#Fn2Uyv|x;&sLh~@9mX_Dro9{ z*_pAk*m=LS(cam2&lRJ&kPc5o2hL&)agQqDRuU1fMm2S%@%;=$$e^kVQmuOtF{>I& z*X?0#d=%?m#|cs4O^bTl8DEnQ_$MN%87u^GayqG#ZhQLwYwx{-b<3{$z~9>YeD}Wh zI;evJ3Sb2!Bgv8l7=tka&y2H;VO+K`M&NAX09E5D&y<-OCKV2h%h*_8Tc%tE*uww< zBqTL?Kp<>_0+LYELZErIezq9w6KUUo5JNNbL+csmV&z4@_FP!h39oAm^w=#@s zV#GuiPcZt_`fC7fm^WP&=Qq9z{(7lVBv%6YEFWBF{TkNJ+yt3@-g11?IG#j@cJD#x zV;op4IKb;+bH|+Mv1So-H$4Y7dF{pkY*wB|27HKIfLSWn;y0%BvOS)xL}{Q)d_VsVYi!5kB`BnpqB}#QoWn2ByI3udy?}R zEM#`=IkD&T95Rr{$yL}EJKtYHr>6x?du4n^c2@;T)$`23huqr| zp)C6vDPyDW*A*0$uRH(tucR;XRahDxalVxI2oN{kl3a?0W^s!+xc@l+`L$Urn_6ay z2itQ`Jdup&7zNmQ&{XkDNgx@Y>vWR%l$~KAjJhj`%#V(F=)Y_RU#F~q8R&y5h}roo z+nLSgtS;lRm?yUwpo&1Qu{;>)prdt0(?ZCh2o;4FJJ0HhM@%`v0BDED(9Y&UR>sqpqgZL3CWtLL4dS5VyMs% z2Lc&=S*9!#v&`J1wpdW<%iH+%LUX1#vGW7|{0P$2OnzAGK?TDmAjExb{#BvG2@J)oJN?8K zWxsD0{vc0*VQJ5g@4!a(=T6-uYboeN5RBh3@2^U5Gd(QeqEzg5$8ZavrU>@4tP5aa zW^n6ht;_!4hDyLxDvl=c3aB7db=5RMi^zZ;yIsMOo%-3kvL5l;u*LY> zfw^IKDPedZuKvQlTONXOawjmNZY&|S!UJma0vdQ!IP146rKJ5&KoP5mxI^iIln*Tj zIsP!;c?D(?*TcS9R~2L=U>6$8aRcO2kCnng>p%J=0tg9r5aKG#1J*YH0g+;GWy2*< z2aO$|vUF=m8VSFTj?aLC72zvJ@EOP^Fa;Z109s#j&a76S>48u7e3@LyXcG(w{<|fU zF&Lvnlhz@(rGpJ=`d6u$!HfAYl8n^8>4#~|w%(`j@ihh*^OpP9AX-&pB3YYE!!?@-YGc&)yLD}G zeq_>w7Zu2%GfuP+t$jc$aI$KCLen0maRHcC**e%i{9v%X65sIRGkun_2-Bk;4uaEx z8NrTBK`(i(eUH*8T>3SZ;VB)usXK5>mjkb`%IQ@Hpv?9-fT)^lJX@6~w#Mw{8ikT9 zAX4rldg<1?-;;Qpl?>+cXPFXCvsm!r%25M~plt`_@|hJ?^h5qY04u}i25jA;lz6-q zq8fj1-!IqS)+l~sfW-2g4n{X_J>z_w{rz>w_C9WhgzN1DSl`UY+Wfi0@Nii&A%Jx z+2+$|Jkv2LJuboJVOuIXg4d0#I3L&Kih@HPe0ZNner|5vaSiEGakx1rJYjRP?7w$> zfj5x$-6P#2)4dcDHGn(*&gLa3U#Q3Uv@2V%;A76`0E+{|BK7vTmk-xIl!I%1l6l~s z`CLFzPJI@o;?i5d#uLqw6y-!3hQSOIc$cO2;VO5jY*{Z~Lz0oIwK6R4l`>l`&e;G-YjM{Yt+_ERewyws&MeAb)P7 zQ9z3n2cd!#9Tb6)z6GEUGgl7yv^@TUY(boIIEk;Qt0i79l4<#9|awFf<={0Pw@azm0Dth{3|@Oh<%T zIMB=YHh>@_3R81X!+3~fAT8GtxWyhAH>>?tQZWiYIs}(NE2nSt)3y0=zbu1@oI4&; z1A|Pj53CljX$e;hW4K0B7WmC*4rmXxIdUW02hM?Q-GPIC*=PEJ&YnWbBv{CRwcyVJ z1R4-%cLB6!ZZ0bp4-mjA;OV`_-}WBT%e6IO$)!AooAPfq)fV;`{Id<~qD{l-C}^8GX!%jem=#6^)d z80m0df&rU-A;lZFSR8DxG}*@M1|iG)oHUs+n**ShJ#6C**Csi`v2*y^`B(8=9n_VDdt_#RLWIhAZrp zF1(N{na!O6(v!xnalprbx-w@$;xvx7T=P6P17HG>;{}($I~8Ofd~fHP(bss7(|GS8 z@Rz%fnrw!};2p##9o$d)5^+N##uzPP%QITf%G6axcMBOT!&c&Zhx;+!yQA&m`+-O1 zy~1&>%26KTU|1OnZMNk1mED#NGG$oS{Y{M8)Fg*399+K8MBR&F4YEuB7 z<){}eVy2p?%nZ5>(zGfaVD%@>{>Mc(CX*70n)K}Z;P$$fq=!W_7BAy1W<3b)s2|ow zuoR3$ztDR|%?Lu(ARW~#>SpfDu7Qfo4C?;HVU;O*5cQBHkPD)@NfSl`O-P#vL5-3ykHwsp=dQsZ^BK0amob%8Z>ZRjhS;Msh%Ba|BGY{9oaV*mv-=tt z7&XpkD?*-z5-8l@@qH}(D)^99xhFTmP9ky0+~*87rAD#?7X}h|0>f+Z*yxgLo}8)j zT&wLM^lDcxX~#~LL*5|s6ZDb+v?(#<>l{~UJTC;SQAi1)exzS#cB}nZ6CT#A0*3;I z3V91R&!Jz&&uo(|ti#UBOo3{tLNzTgxT|Gh+>5YL2Z4L76F*Z|#@o^u1`ERC@Aw&% z?qpvL0*($V@Zm7CGD`~$zZaqGq;Z!W>;>+WFEhjqtB)r^DE*dg-I6mZyW*E25FuGA zfjrafze_5{L~r>duO%xbb-bMR03}?*^68{rE`pgj6M2k+GAs>1rV`IYhq}NhKqh5MwnPMg zdYVWB6WTvY#G?e`Xm91um?gI~?l*3f~5fyyO4I>90o&hv4ru2L5BNlvRO$e60M0#QC zU%u|NmhX|T%{;ca3uoL{;_kWw#H?h334(g1pSPa9s3Om^_irH(jo>)*mGu2$@2y!B z^6%GT-qz;nMg%O%{nAgEjox#T0O&eqOMO1WijIBO@5F26de0ud^O{$t6a%1MF!Dsj zeR{pcU1i!TB#LNeh9zpTafxEkzSDts+r!0iM{mt(q#BL{G`X1Ye^bbs0`&%t-0QZ- zREL2;8sEywrw-i@{2*l(4Os7pGS&<#gtk{xNg+^EvrF0#R(9N;t5O1}8gnnQgoclh zCMKI`lz_r83=}uTyHZ8>RxG$_ja&=W0Ydi_j@B_dAeLuUXpwCI@(>Sx%NOf)qfe_4 zl?fNwB_t$JbxY8B$k>3=_rWw1^YVTI2I2`oZx+zWPVmFPY&d>aNSfM$0Pcd}IWMPc zgsaM3y?1zBX;0Tl@Y10!+*zFi8^0CQ$v{E+=B4UEF8m0PB!pJ&bjFaiyMZU!$1rG9 zhTpM|(S#rC|G*H*1UNG)8dy3Mb^>ehDz?p@!C{sHvcjH$b8qGf+BkL&H@ z9tbs`ci|!y!jFH8k%sb~7w%-d3%;Hs!_F2Tq1W_#wtZ#uyrfs*26m4EfVG3%7} zla$uF@M9)9k1PwIi;Aj%@$h$>_XB$15C8^EKhk`S0+aJ`Ud+7__{uIB_!?U{C; zuqN2PTm!EoXg}2Y5APQnB^|dIslw*v@LuJ>#W?XLaL^wCrmP}$W9mH%7BZhBpPX$` zbP`5f7QZw4S%;H?4;UtUW&XN)9~-ZHaljkgI*_h^Bw=ugbmLmx18jR^A&4=YpNxGp zUKgBTZS2dwt?lar{5L}X!*gGGt;bpDo*7~clG~PHPWj3d-*R{RjU7|5@6;W=1df)P zmFt$eN7K$MFfiNZ2#IzbjOYS&fV$*^t);*Uu85{v5~^{Z;n@-ZWX+Om-u25qvs9s^ zDrV$BasUk6>+=~3&cuaC%G$_#^4X3|6Q-ebIm6HHY#6VR>sCLrRA9`EN-Wdsu1P@z z=z5YBy=T`$k|1>P3_$K+X7> z37Hwk=+uMboN$$Tdv*(omgh(2pg>Z{={n)iWvBPkTp=_!7)C^);|v|cv1Xb zf4mq=21}G)ceNyhV3OwnfX9Xrlz+g0$T)gCfX0K&fLT@kD%$q|R&mfeP#uPyT{CT# z%>~WIZ1*t5O8C?ITxwrjSppU2tltR`7%dWybDJJEj?eDT?B|O4gd1S9wIM>vKoa-N z{3S3<>JOp{Z3x+B=~K%zc=&ZR(*~QGqxfgz9uvCsU#kx~lW}Y1`UmuHdsgQot*MC-AqC*_kYJik)0+tA1RFrl9JnBkVl7Kvqi7R-g4*BgcIwBlqLNemh z{-{tA%Ext$_n|N$v@!}}gbYNDSe!yMSErZ43JdS z1jbl>JwM;qMlnfIeCYhkPz^)QVMUH%2{XO}=M77tK{~W%{R$qPd0Kdv$cW6trE5JQ za-^loNeUk8zj7K9#Xu=qD@6BSRw6qJp!n^`56|AtZeie#jt&EBd9%i3QCJIz)Q7g9 zx3Cz5nUhh5>=6L-tbX(qE+UpC-4bL`WzJY#OqhqjGRpIlnKgyEv9q~F84Y1*OD(khj#+8El%N@PpXnB8 z3TMIbJ~N~7g5mQF$Qe!P->e>q$-5cF=sbfsz2|UP0YHVh3zBw!lvfvU2zs`r!N(OwTh_XX0H0mpEZnTNE^LM7<_tCg;yZ|{i zrj&;Dv^LD2{&yYB;t$6q06eJ#tVWW~OcA9l`g)_PjJudSXa*GmpsX%L;Sn?gYpAFG5sI5KJs&7IZkkWsfqFwQTCp;h=&i12g zXBHTY2s<-~S+(=5vm&GH%%Ca@-8)dTltaP5MAF+EYt<(RgOxO_MSbGMR2nB8InZK) z6PJTg3U?blF{GNY<&{>=rK2or61TAMH`bvd9~{%(7N2wcCTH&OAi|hO1C{|%{Ndxn7Hv2b0JW0f;GTI-Z2+7; zW7|9=;M$oh8Z1y8dWi%wOYpYL&4SW7-!~58Y$Y+@=HW;Fa;dQqVa2qw@i{9n35(RS zK$*HRPKN`<@2$Wz79%=A~mz6FI$VlXO8zap;-#s1;DfU?asd`&&ROe<2T_G zY+sGfW;nyiQBeLo`3?KLt^>4jKAgt%R<74eeH=2ja0nkEgk&pT@B;%C@?AX7_@gu{ zzLdsm-!1^sz$ev89c+___p;U5Ut9mWFM;lVR=c7QVW`3^Kw3vfY}wG30LAu3MFjRs zCFVHCvPf#bi7ZiKJtkP8)@OoRa7%)w^rD>nKR5qq%? z)syNx$!8&5lFkb!c|e&`o=>NXIIxBdsR3zDpnU@M3ET~wbjJ>%1-AR?h6a1wh(FC9 zQM7OzOB&VA<}78i$>5@s(-)gvQ>ZeK{PV=5uhTuwoozn036I0uO?6~|N)P=EB0Iy& z!!N*vd@!cy1E5NBM$WgN!K05cp}?e{^Xydu{M-w8$QHqizKjQ&jV%Jy$*wi#y#RLk zGbZx>nTFG>Um`FtEZc%iadQA7*|)^1=)%c@4~5p=`Y-p3dmLV$-dT?i=H0ICox$9| zFc*jbBMJw!PQ-Y)M2bru)@uZTjNVNUY%rQ%11)ygmQ0ke!@$N3rBOJ)h`JT0X?+Cj zcaF?I&Sz2|4unSvjvAbL2_|fP;QQLMvh(X4&>X)V_mC(?EG=N-N=gir z<}det?DyeJ`TfjI(u(h~&_}*UKJ-r$cn-#=dt>c-8=D7355h{`cV^`gSFhfC%9^y? z3vxf-%eh|%ylEKR0?=4t)J3mY&XA}sWSamm&TFOt*dDv$S(EH2}mg;FZIE;PxB*79$z_k44Iw)0T_&ak~4e4o{; zW860#rXb07$XI^2P{)saE)V&yCfGiVwCph5~!HBe~-;3Ez~Gf9)w1nSyL?uG*(nl(W3?F*tY zVFU_FY#STn_GwoiL$e5s{=Z>LgQZ+zQc!NpODkQHz{w7%;Gp-`J{4uw;`NiBVS~Vu zzX+JM;#SakxB7jV#8}O(g7U+4 z!idz&Z1)0G;Id~V`s2_h8c0WHAL`N~k>~8-0N~~49A6mCl}!ES78nPH2nAjCJMvs) zei{}xR`8@>#F*09v3MP8n6LGL$$_Bj*SqXsIB6^oBp&A|f0M3t(5-wc4qDqI?ciSP z0$L8%w!OXX8Y5PotOc}w*}N@4M>oNJsm!5+adi$QknHPGsNx0v=uE*6P;?Z{mY09K zcHkch)*~0Cv>)sq`PplLCWNuzGAT586|}PRdIif%ATyX*cV%e+XY{SRwycBymRLLJ;Iz*@~-&n(MM>Cai~59t}s8XtuS zP97~pV;eFa~6SkBY0kIjx zcbjFMN?r^7+L-l_u2sjT=6gFJ&Amh}%b7aliA+uXVxg}146+ox)X_WXylVz1CpNtg zGuY-ofl%)g4h4x3n8g~HEnxt->0mM~AG`rE2rXd}m`CpQnvSt2B8JES^j6%Zl03Div4^AI| z5rS{Hh71-XL@;``Y6kNRkz2N%nb!N_y6keY*bixK*ZSUdtRX}gV>cxS`TgztA*N}$ zR*UBlMW!KE>dpX3T=?nWw;@2rT;%%(a6`IwnR3}`C~(>`i~W*c8&6CFW55+o~BIh_0K}-N`(mT2c|t>j>#v zS8H#gxe@c(JSy1M_}Hbe6=%21RZ~Wo=_T)H`<+?i3D8veYR0%&1A%Vcjr z47AoT&zgFZyAlzBOZ6Cq*fg58Me@7JQ%QoII~d&5q|fA$ajuc@KuC_m1Hm+85pB~@ z5RN)@iWXlr?-cP9PAGPWFi@y!pi6PfK?FO(!2~Naj^}rb)sT%y)x;z#?eoom_>Jmw z0!j$MWgx|Dg|jT%OvjKyTbU_SS4~m(`>76eec5e&x|rMCy@Meeoz10X4iJ^PDnMCw zT<={Du%gTdX<8Z3a&0h;i&PeG=xE~8>hrAhVHu$MsPST%9=p3U>#Ut+6>8iUl^Gd} z*qR+qM*>Dkt7`up1Ps5gi8?kh1Lw?JX6(0UY$5h@3|IOrF2lu4OEl z%-9F%A`SP9IkC@F$nXHJ73)Fj&q3dfC@fTQy0=NpTDIe>j$PjoIO0vie;8r>Bzh z$F=J@9k%jWXvLOm;Texe_O|@ge$NWRIx>v~otf*H{Z|z~%;~!E99Z%K{nYuTSV~m$ zono9!Gd)@-GC()W%r2Mxm;F zHjUhH8_7AwAZ4B@DAWao6g6Vjjm2E9(a!SyQVDa&Kl~RmKkhOm{fKjUY((sdQpAeD z7Gt{5^xJqWUMZg+F^Ab-4_Psg z#S$9NGUtgwSfFf$jIju5M_}#fI&SN-JPT729JTUyJy(KHvtq~a-tcKjAUx)O-Q~#E zz`*&kCX(G`$?vjgeK3cjl&e#%gOI)o?{Zw-j@x?GsWo&{1&OzLJewU`*BKCej6pW<;`MaqN-BX3fwBT+<v>mfTsuw zxvz#w0YoloT3#IYJIK^Bf|3|>943As*u;Z|YYqU8J~Q_52=emZ%*(X1egMGtWIk@v zz4Uq6x~0Hd`Jb>J~56smVD~R-AM;!cUo~kWBfze4ceJAP3Xzp2{>& z`FQ>F4Bm+>rp7*B_7@2E6-w)zKlknn9`HCqVEEGe6+Za65%G}8I%p~Ht>{PoJkwwB zJF_7O)f+A-lpR>cdj!TYmS`5ASYhXlY-^UzbO)abut9p3Q<`(zQ|WIyC#}wt@!F+e zYxmABXq@QY)(2d5%%*AAK9Dc?0slRXV)8yZ;L)d?PagZXa-NQBqF91Qn#k*!`#5gQ zh;L&qNpThhHmT?g7@jBua0xGESCn);KM}Zb;2q;R+TA@h&hhK8_ZwIN;hOuA=eqgFFJ^QU9*tsN4i1IobG3yZ@;I(>&RJ;+04z_x`ToniaUP3qvH&P5M05oM1dPGH zEAx2p5&L}PeRCQ;tqM#!UfWmW@5jR|#%3Byq%lcQYxglJy|`Gd)`D*QM0rk+`yKW< zCn^}Tu*5yq=87OW=i^$PVBf#)_n-HbCE~C#viTq%?!nMNC*WpF4LH3Tt&EK^CShRY zy!3J3>ho+Vpc}Ke-ZFH4vSnIEAz7dqWEOf9*U$$af@Bc$Jx}_)GK|&xLnCjoIdws5 zSht`b2bKnskm)Sb+6ojRGKz}(rGW0pR%Q1v0eXg88GWk#2^JwParhSAuK`wLxdh#lbB=K zd|gA5t?*fgRd)AcUKylN7+!1~Sx6{D-HQ;~%o{(

eS+UQq<;XpOwFGW10rl=Xs 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�D;Sj6wQ<8NnKz;?yZyt9m{SH!lOu!x$lBm= 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

  • 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%0APM<8$|%uEW& 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

    O(?^|d9>Hhj!TjE=&niL)kHD~}J>A6sh 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

    wtIQ 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

    S^ZE_;q_Nu;qA9BGhZy|W;0f+HQ)dK-?G1d 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 xi_seE(G%m;54WXd9Oso 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�-H8DkEOevpK@-KcPnKJ71P+HI=F3Y=^MWtk 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 literal 0 HcmV?d00001 diff --git a/plugins/UM3NetworkPrinting/resources/png/ultimaker_s5.png b/plugins/UM3NetworkPrinting/resources/png/ultimaker_s5.png new file mode 100644 index 0000000000000000000000000000000000000000..29ba428e38a90b74072823c941e10a173ae7171f GIT binary patch literal 1476464 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 N_a*4HE(SsGEo$F;M*APO*f5|nw( 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ⅆyW=&FjU1IDC-=Pv&(m{Uy@xHRq)jr`1cU{ckSk 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�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

    lDe^P-*N94 zV`o&Fu^Xe+g2OF=k^&)SLgPwx#@JAc*$l?&k?0%;g~vv_zXPuIAMq$0m3EB)!GWH+ z9CA5n?4VPM0Nf#x8jbX5-2CNTMy6=zWVk72Aw<7tkb3%5ug(p5lRZA}*;uOVE@cO7 zaVMr4Rr)Sdw7~urR2g|Yb8%(qI)dq*HNCSwU;U~6JH0n&xagZP1Z}PA2E|TI8=37N zJA1DD>x%4tMl9{mXI_1bc`(7BU0FsEH5%r3J$-+j(`k-;uLcoT>z?&Cv)I$3;|VLu zY~ImMMw`!p&FSOM9rNO|ALl#1{Z5Y8M||+ZkFY&X931YEM&aq^IWC;-__}w#j$iuF z^L+8~YrNsX%U-A2M~FzV)}ca_!YJ$%y!SQpni6xyXf9d^y#S3AWx}M{nt9PHGwiIP zJ*BAbjbg>3leMxnndDAg!Oxa0Uq)qo6gFwp&UL3|D5a5pEMCfigzDrD1+_QDHM|=p za~UHQAR6slM+-F6Ej)9C@@#Frdr&Dl4~^&EmwGyO_MSWP{@mGvGEBun{dKfjaqVW{ zgC8m!9XGu2(%Z>x$9jks2q}F2ONTu7eByS0FArVZvwc^sA7dV1b_bRc;LoApOP}EO zYE4D~^V&r(mns0~43{}OWzMW~ki)F2S_`Rhgo#}vzwYib-DAE>>v@&3yH*te@O3f0 zIkP*d&a3}xPG&I1ptw$+IU!Kbc@fjMGBuExgW%J6cE|1xgbS@#Fgfie6QJ)OFLjKk z?MkHwZxnQ7_>39vmjn-_y)xMQQ z2+j)9`VW2T*=&09D2zEGi#?iVK@)mX(H6plNFGPZnAFB;f(6mEW(P&Ig>e=Zu|v%9 z*Z~ktwl=ZVy_OYhL^7FJH;9!CL4a0#uUf|@)Y5ieL&dJwc=4hPy1x)#abxgEA?IL1 zzSx*Npk;y4;NT+FVa^7om?>HJpf0c3E7_!F@>*&_Nr|(U?&M2f`V{~4zyCk+^dq0= z(%Zg~fARzWi0^v;od6sN{Ouq7=iGSl7XQhA@|PHgH7{IyiRWH?nV?*@yvB#L6)gnq^17-CA9t!peY~C<@v(G16G7TM4=zAqU1`q_lw$BiUMPQ$&5P z9El~f-fU|9 zfP%}H-IvJ%m-WT%C6{GJXrRneKbg|aZSU6LlBX=0J+5|^{vL}=<8oV2+=iLtrt5Wa zeOJZqZYrk!8zb3R|tyx*2A8y-pS0lsSE8!ZmwpPDz-8iiLUIYd@p?pFB~crC8{c=u9A;Q zDQv<_UzwaLv&Eg1mFJ-D#tw?55JhDWh!@VxPy$D*HP^0P)#gCC;3=L}`R&JWKBOp$jZdj#>2sKlZPFl7I2DAED$m2m6Oe zzhT>t9PFQAZ*hqbp=p&wnu~!ECDAl37nV!5+m2xzShSt8A*8VBGsCv0wOmPwh1dj& z6)_X@1fwYv&*B;jG&#^nfjBZ`fe@7;la&^hNXDxQmhJ&1sUg$G2%#ub#T{fYX9UPu z3zbPEq4k6kAkBh)R3l@t=*ZF_BwB0j77$Hila8FVK1vL#ICD0tYJ|Om14`Bi&p2+# zIg_luiSHGEc9Eu9=x(fPZ57`~>HrH^o?~; zjlBBzk!lQ_j?^mXFv-{Hx-J8E?;|oBr%XyJ#8>9EBKl1=NSy{fce*NhnQDfM?8v$3 z1%J%Ra!_$TuKMX$I4RS0^x6*el$~*^5vXpxJBz1Z{#jT0T8z@-993~o>*ud|hp}DD z-U`}Qxo-fTf8tdvm1*xzPZb*lzHgnZIanT4UoxO}NS<)ooojeu#jiefjTevhdE`qM zc>0;1N56U}xhxr;fszNhuZ~>1-EjY1!n4oa<~Tpc8y>v;s`H<+cDQJwAaMc>e9XS{ zk_|-A==PXlJ7f~VvJpz0=)DChPgaUDzdZG1o3!<7*P4-QdbENB_M~peyJjDY>Uk+} z`(#aj;lS>d>%6RoM3XWj>Rt>lBx=Ig_07^F*(u zO!lJbxmmRCfE~(YfLB54TKbmq=NpR9r$Q{kBFqd}lRR4}t~ctXXCO=k zY-V7~d_{GM^A7N`%O;t?9KY^d{_Fit$&Y%e30&7}{Z6vQKR3x|2N<*t!gQheGrBw% zt2Z)@Td(W&RLUG2p6dWyzRa&XpO2ZWsLwuKe;W4$E={t`nG^QKy4CIdD$gz0SRD}C z5Ibwashe$#dwR?)ny;>}`D3hYtCqf8Q z8*8To7A@qFGkcM|g>i6O zZ)7amfMBs$vbkAEMIf}qGFm4`G%yuB#ayiRou-$2(*>QA22V%QS`?Ek78f4qJbPVD z?Z^^r4f3=)MQ!Oa>kzvGP!`eIuE4(qg9IoFECi_)&(PX{(HKOzmUx(aBD)9H%)%Br z=R#-#?V=^8fuH}ef69|ze1x-a{bqjPAO1tW>+A2VTj^(i>gRam3s3OTG2VmDG?j(YN{Pyp&v$?7>N=HZ9^%MVHkiy+qUEaDJA`P9B7*cWx5GP0wal# z3){ZemeC>5v@J0fW9%EjpbS7}x#()))-h?T@^k0T=vpSVqnCRNmU|t~yzmUa@Z&$i zr@r_&|J(oiqrC6^5A*l_`OmQ*mmD46=7S&nMPli=b#uk1Kl?e}_0G3(_q}&;>-I6@ zsJ7!~yQbf6wFXQYVX-$c3H$_GP`l&_ILBm4%Dcd<{vfmc=PZ?}&J#jqRk<(ZHHHGa zc9$OGsld7G8{Lw&Z-PS~9?&$cFJfa(lf5p2)Pjn---~6LIH0J{m+`&&=A!_n3twsX{cc`g3jkBJwea-DM6uqT*xl#=fHG8y9o~|a(U8R=rf!7k zm(`eyQz0E!wAr07yQZgTxFYpJr@MDn0q5hw6l1|R-DISTBRhH8Se256rIOg@D40`e z(LN2t$}EM+6ioK67;bF1vda__O|xJa661D6x{mADUuMw>?|H)mJaD$tw!I_PW5L=}5^V#K8)PbrlKEBop+G0P9*OiAtp` ziYiWp-;&Z}#nXsvexueTAs3?M%9fl74!9II@Ee=o5v0&a11t=n%cPQtA+lJslu{Uz z3f*xW5DD}d7E$+2(|}k$wRhC%`(ye6Z6{ZRF?77}@(ucaq-i>R&ZvlKv3rRbJ>GR7 zM%`l~ijeDhnf9cgAKkwW2AVS{8i6bRd$IYo8Yv;G(1{_UfflPyFRCyK9!)KlpB>3% z#3Lrjc$R+OK(=m9kV7JqDPz%MY9h+4iIIadhxEtCsAA52 zNtzxOG>xh5k0=I0Y7wnqf>)!b6Sz7zM1wp3GB;cbMRKL}Vhl88hXl{3m<&yucke1y zyX=?|8)j>OD3i)&(4217Jv!V;3004(%HdMwp~?lB32jp()u5lr(4CiC-?B3oRnE+u z$T>rUf_l+m+H5{bQ9kW>&72Q0Cwy10OlQ;Q$HBA-aB}d;)5InzUZXm%a=%=5=cE*^ z&6Lu}?UNHOo!zG~)|_6wSfZbICGqFAXc3vOf5!v7^-T|OeAM&sn;PEouE;0~b`uI| zGjg(Cvr0Yh__{Z7>D)n`$yv6G`6t3=$iy)bmJO+>bD#1Q=m2UuS`(nNl#lhOMtc(@ zX%yCj8EvIZ08G~TS++tGU^_xTXzprh6#Pk9W*~>kc~8ZQQCLRU42hAzvK3C&Th_*a zNm+}k4;ilCxJ`3-$SSEGKHetA5#m841=#e|NN2HiLa@jqbW!*CYEa!2T4lEM2?qZT zQtKnRW3&t~row7F5((rku-;?WAlIMoW5Nk{2iIh$9NND-+iST4t*SU0RPJ&*el^_eE;&lQ%N=Ke@- z&-)xJxG;5GO*xs(5$Y-{pg^@Hy}UqWM_JomDTT(;5hw{Mg<%}Yd4!y3V<455rdzOF zEIB&fF!ozY8W_`Pc7-~=xj>dcXd@+$#>jDJPlE`#sGrbAr5#8SLbT$$29^f1>)aI; z3mQf*7GKQ2vL++d-$89#ErMF=dQFRBQ*3sYGuOZZ+SwRLVyW!e*?*;OD)*&!!p>RC z5olwT#5j(`cERf81}{GQ0yJm&OMme{7U?3zxE3p zo;}CG+up*WiI9g1;OUV|=8vQbx{i4yl%VaPrJr>j?4dXyRYza-|q%VB@*M6B#{^sZT zYk%YK@E^YaVV+#WAAHZd$Z^Sy<6A8E7JTGaewn7*=l0QUo_Y3J4iA=GzI>j|c4XWR zY}YHcn-$}rL6*j96{%R!1|==F|HA}tc%4QE3LSi%Qo~)&Ol(FxmA~G2hzHx1O_DjTrq{vFCKTE0#eMCwsO` zL3R&1`0p+gD|Y=gy#9Y;z)XVF6?~cfK8q}hIWR)ar&S?0GnRc}LG#3dAz=1?sFPpR z@tP^zP=DVYCANLaY2#t$h$*$sjenVh|IC1QbT>r39%Y*JnnRXVDLa!v>V;AGX)whb{Q(zv0ya1nrEv*FhD=h#nMXahHIK1X6f9s{dqzQAVh zEO|Q+LgILJlf7l&%7x#@&>yosdYOZBm-$!!;z!u7SG@ZJ-$c_!N(`hTG$F7x)HiRm zVzwY09PZJMiS2enL(gKdu-wpqMuU}NR&t^gA+%9DuNW0Cl|smhE{;JcsUxIS5T`3|mW(GbzLxZIq(LT{D3~ql}J570g(YRc(hhYJp)a$6X^Fk+xY- zhQydMjpY}P+03FK^l4yGghh9#X)LtbKK8~3`E?KvhJ;h{OTh%6(P4{4 zY6^Omyigaj`KvF@KP5~pPCZQ{7Q?^IA&6xtJ{BxxxyFa@u)0!Alf}hTj8`5I_n?9h+xOvpNDpcQVGhnL< zD|M%===Mxj`!(v^$j;BF|L)9&xuaB-FbXnO1w5O>f<=(rus0_eGbro)qM+@(!^z|{ zOwT!~CzI7P=fR(&m3fP*P|Tv;`LpO9R^OeJ^PD=(QS1< z?RMS5oEUt=aHvi z+&J0r!p)HjdkyPt&&g(Be|d(!A9()dmCC)W$+8{^)I#8a!)42b!zH(mx5OxPXZE;$ zyya-!TQ0rUF3TkoMfFPz!ky<2SofLhM@KB$v-I1-^EZy!^y+AhiuwSk0Sr(w_g_7a zAlx`Q0hSyt78HRo3$0OylBFk2z~QuflLT-Tp*wi`Z{0z4FK2PP220I=ek`15>( z^-zJGb2PV|UhOr>%H6X(J6X7MKW7uW&MRfAeWfhA32^naOb=KD%yDLti@O0p|Jy5N z?IfLc|2Ee%?hs`B?9QIk^>Jk(x)VBkN(maoDBiusX=b3F#CjHmg9>~VJuI#}w zv5gcI30j-N*fLo9ff%h<=Vk);L{!HF@zda4AkFWHo)$apK^1*k-yuY8CtT1-cS(h| zYqeFcXgXd%>sv`0*{n}kZP%m>`|Tdbn=Px=np6_qq9Kiiq1T!tJEGk|Lx@a3rJZ&Q7J7{g*PN7zu~JZmZ(+(daMqJ9jW$$}f(7aF zd=nc>T}a95Z3LxB3bS=*_k5TWr7U*QIw-je5P~*i7&A@NB25ct@8Ij+wp--<-+b&# zgo}4`^^U7N_4LymoWH=c&pykq{@Ta+tAFvY@~6J*?Ew73Cmw^(y}+9vx}Pftk%#{9 zAKplKuL+VjV!u`aXYeJt@WIGieQGeZRpyT zwp(!H*(dq`)-aG%(h1`y_U!jteB{!O=!T=x*3V;y~z>UO$QZF(t}Ltj>SJ|B7nra1_Sg9Ood6j39Cltgj}*FHV_W%qI;^UI zU8sxY&?e0hM@X9eU6qk5PyNwK=@fT#G9{=Gieh z(Xh7B)qp=W0X`NHUtQZ`;gu7lJNM3KbcI|oYzOdli|Je8P z#b=-4nWsO*IBr?CdvsA5E=nED9NoUHj`f(7PB#whA084UFbso6BAbpOjf&2OKpTaT zqD6IymgA^VfozDdrj=wxe9d7J2}ssrxN4AOa)}etF2(9`LFIW91Zt#>3h+y=3Ur!#K~MX;0C(MJ2R?uKTk$&HU7-d z0(L-yYR%g3GP~|%;Ll~QKSQ1=yO|T@Od`8)w0vhZW@k=@8`Ac32(dbEbGNB#SJ;ua zVJ5rl{5aTXB2&j#X5V-BhUvVVqP0eebzGW?rGGCrPp6~r)u^0}qy8-Jpv`qdna1z6 zU*VQq0{k16S&}s@S5)QT9cj5-+@bi;HLXX%`(YzO3|R359JxsIg=YWC%@l zESlylw~p7Ww_DEaFFDx^+&nraMq$0(l5(Mmjn7KXT)EO-Ad|q?EK?T@+#-XryI34xDU9 z+8BB1)-BpLaL3t&1|?h{&Kw(04XXf0UE4X-B0Fbx+H*{XGRok|MblU_aI#6t-U-^y zco%4y9QQCgA0lGlY^cEoZwFj$9;mW^mpwPP_f7%0WqME*WAo^%RGr{#DJpnS43wRo z+4aCQKPES;W#)23Wo1o2WwK2tSxkL)=D$xT3};Vz;qofy3N_UP6xyy5L9CUwUDrDo z!i-sGl;E=PGmk=dy3oJLS}F z)XVCBlcnW^9f76kNfZsl6&<{dXRiOinT!?0sL$+cJd=Mm3ptxVB2)mYc#R3uiTyaz z=fYlyHK0*M8xxck?ED19(dw(dq-1c4TT_ zi}6AmJteTvHNMjJAuBd4=1c}@)V?kW-?dt|#W%j{uu#IRK8tNmQM<-%mEvu}1CVn~ zm(;l_M6=-AK&_o@8@%${v^k@ zUuL!0vTg#6Xn6%?XKGi|5F;TpYWGqMv=q8dYg4Y*Jq2NZv7qm@@x_p{)?Lh*lzPMp z_%`OGhqj@KkuoNTmg-d0p3$0&LX$F!u3->iGj19BOxrAIn}`rNf2Jb~Jn_VrDP@m8 z|NYt}@VGxj_Ahd9;R?eOPjj*vxpniH*FN|lSFc{=)1UbgXV0BA_GzcBrUSLuaFIZp zGLi~S+u9il6sw;XiWn2DP;%JuODG!jmRbe@Gco1AzerTCIj= z**>wYA&-WnvFfyk6$C-zJ}11H0AF_dQi~FKdRP`WM=5)sL6UX=69$iS@Wc^k6p~ z-v+QFmwqp=ueA#jULDydKu74m=U0Bo@-{Q0P2NNq_bb)zMQ+^7OgUQ%t0Hs7?)lf$ zafC205;vtU>EG3e*LlseMVR#*&*o?aUG%Dsi{^uY7oV+VFYs}XP>VE zQfiU34#}yo-kh)vEqnX>jN1V~(`ACN-EQfc zmXZggL}F}-C6UHN4w0Orfi0O<0Lct_q?ASt_7Xr^Yt1MOWgsL437_%aOF*fQ*8bqstArhp}1uYaj82g2yg|cE0R;wert|5koR0eVy zDHLMRGJ)e}OA~~~s-~wj(ln76Bg6KD#iFH&DrmK0{)mW1TJ$=R%3=|j($gG365FG7 z^SYVqb%WgSo(xk+RV0atonHQJ>en~G$Hq$y@uG-V*7 zRQztynK7-MiJH(5LS(ceYHf^4(=3Iy5sQq&GAc`^iRgS7t7#ZU;tqXJpFmK655e&4en{ao0%gtcyd9?v+y0BJ}+DJh|eO3c~m}oJ#9y zrWLrd8b_tBA(LV?-IC|v$o#vr=k+|CIUf)0$HzCRdQaYQ168A6TSS zYFz}sZszoQ%~y`;!#*WG^&ZG_(p^!9XR!=i-@?Z}`xx(j%L5Eqc=`Gb+NN-DaKQB& zw}_1vpmrUd(nuQvB3p)GBoF&sIDeLFw{Npvt-0^ci>xxx9mu!gZrdx&vtCt ztk&Fd@f@3B;JFuH;QqTWaOD{{BAO zZEuc+*%MJa9vpWqS1(`S=B*>56z;fsnHOKa!Kxo=8%-NSn2Hs~$acNu()mLm@bb-@ ztcE*Ttp^@|_Br-UPW)DT#o1^IV5t2uX1KN5Fs4k`HVU!>%5bIHXglZH?i)R=ucm*?d^^_j zJJr{-$1oWtvvcg%6k|d&JA)4B{#LTtrL#wLXO#@}uVt61R_CNlz{Y$G2^}rW&*G(cu?oTS)`Ngd>TBNgIUuvPI|>ISnoHtPfIai zzS`H*SazRpcU~$JR9vRHMsc}LT}ypw2S)7%TD0i6ovHc7OVPSW33aeMvYi~@1G3ES zQl|Cv@kQ4oD2QBv>-qeZL>mg3MmznO4-rvYvricbEz3oxKnW1rJyMB`n+-W=!vZ0i zEvRXcIqOo5OiY0wqTOAy+Ook?jWoqx-LYs2Q$Z1_waoPlP{*B1B8Uc7v>>rY?2S59 ziwv9U)bklMK&%u_LdC8z-GJQ(mhxC@ME|5$zS{ol1J{iu*X~Py2LY2 z!T`rWIKOXv`YXKe9q-}c2kztIrHiDL*jp$=)Y(?pGxepA2JN&u45R9+7;2e-)oRN) zjH{`Ln7=jy9aRxX-`*N+WQoV##=C!TqVgR@t7`@7ynp9YS%$6UC0fnl?O zEFA71vOc;=N(ygm`<{L?LJ>lntz?4vr%Y=(5uc@^{dM(4REJT`a6I_8BO65O?^t&PG*pb zEkrHm3Sji-#)`s?IT1przdJfLuNtrWYNnL14`L3G3qz(q?a-u(sq(@E?#v8?-Kfp% zIx>x?-fO18cNCo&K2EJvAs6Y_w;69dLmLZ+=dL1o&0`<_dtB)L5bt>BA7wixR=2Nn zrfi7af_}SZJnje~Fy4BJ0`z^)*bkgJe};SC{2reC@gHUnSf0B?CUbK8m@aKtbc5SM4iK!E%Gm;@|=nv z#!M(i{WE%`7J&utb*F`{Mq(2*(rU+(9O<1w;#DdmrUW!fpasvMSPP73dm`nmsC0&| z>sW8M+&((tV1M6?MiVMIYrb&MC{)+BY!Lchoro9%W7M{8O=EjU0%EPN#e{PV!Gy7{ zZ4{-HYPTn+_EuRnJ6Adfswm5}hjOWTm>P*!L6(afCdOjP*&=4jbO_=U(`hfdFwqvP znnIRDQ-1_ex+U77gb)c>%fv?Y`p^$FO(yl37z$l03_TW(?5*WGG;K#VN@GN(6s)LY z#pVSw;G9ShysMM1N%bNp!9H1P(|ZnoMi=J=16Pahpj~6tUco0`OzF(mq9WTeKjJ25 zNW_j(m~Y?50J47ozl`%fKM zCWh9l8Q`v9{Z$&kMqE*kc9bB0T0zs%RQuC>k$GJ#0B?5>MDK^_zIwG|)l?3y74`XO<=>DgN@t+Nu| zz{Id)--o~RYv*G#y^H90_8VaX{Fi_0f2Laq-}at|c>em9^=3^P&oCt6$>*Ns*6}TB zfTHADH%4M+v+jBQgAelHYaV2?-LToL$wY3gH+C{s{V{@4@ zGoukt&$I&(X23)>rlIPM8Ii5lY?@0?mud4cy1b8`I`8s-M;1)7Dy3otUZ*kDdWN&- z@TVvye|F>2r*bH&^&k&9CXpc?7GPHL_K4378ujMSEgU4y4|*qb^OUPFlNbq!=?1hwsgCPub>Pa|3qVN9?c z6!2fRot~=@$Y})2W{@BxQTBSunJ7Y#h9a7>r0bUH$3!8}v`tN)Lkc&Jj*zzF@|CMF zuKD~|ALa9({RH>lcai(9T;$=am-v(a{x|U(pKkc%7e3Fq3tz{$=~*3JC(tO67le}3 zmLIk~Y3Ly|Z2J+dd!vCW1=O?-N-oL}ahqF@j{Yyq1=+3uu*`;u_)w3e?Z9d`$xMG# z`Rn%LOrsTNGfuXTigTASxCu5X58rRD3&i~lKmWV(#aZBu1O-HAPT6T~>(4Y#;rC~s z;Eq??+P|Au_?Pj!sB4#ioZ=OxRE` zM{lB>PWLj0yi7`~n1hOmW=g5Xx8{0HPMYE(=C~KD?k%F>dht{bQO)rxuN`#E7vAnQ zj|w{q=f-Bg*>Gm>kn`uRaCCISjhokCyXE)4_Z#`fZ~ivM1R)DeY#GG_Vo+8{+N>E; zA_t+39nvm&{;4Op_Qj8J{@{>v7w(|x_84;J==KrEtBs}#4O@nBWVP9{*{nG^Ug=@$ zqHYZ<9NdpR(kxgk_6QOft(YrWffuCFIwv6l4H7zV_EE_Q38aTI(vc~lkc{?d_4+9# zF>W`IlIHBjx*}R%q-ZUX7zOQqqkAovKq`jdRKr1w&?Ynf+on|~BKIu11&eM^jcL1f zDG@THJkYk0Zn>mb?qo@Yrd6~hr;!jANN8~ioH9&;fp%g>nhAnr=cG^zfO$uR7^Bif z&CybTMK^blta~j?=ch*93}ttP?yfclb}&1G5onu03{%n25av-7qqm+XlP2BCmk9=VkQAY31-NPb|1-Ftheo21Gl_L+?4lUjLsOWYeBG@I60ZCSE9~` zNAIPvIZ%lgMcD#Uw6;skLL?ZgW-LBsIsVZ!Sd>-SG{R;xkc!ZD zt)^WNNLl|sju|A-wk@G)SZ_u(m_y`bwW5eJ5<_UL7<-^;S{AV(l38>uo9#f!BW)Kr zS+Ai)y2XN~Yw&1t78oRe1Qy+bu4_3u={2=fg!LxVwjFzWd!|RMX@CThM4G1IaQ}c@ z0^7}&Mc1%hZ^>ENL|xkfg8WU6_j8~zTh43t3B^(m0}^tz|K?*8v-9fyFVp!{H)%Sb0oTPAq*k46aJ7`0Mg2~Fd@4XITvck$@`)bCdtyu-Op5ihiGA1F!&eB1k z9}`lvhRV->;yM1^hd)KTIG|*$OVc%);&bJW`w3(|`k`Oq;@uDP*0+2e_rK;r`XTe? zd+*_)iw*tQ^TZR+aQ*q`dHA)jXVC`w&4w}-+IGoeu_QK)F_8ixs87*Gp=|;~N^FOL zMc2}{E#ojSZhI)uhJZJ!$VHhYq+It{u!2ghL?}W|u;@DW7E6|kmLQpw^*Li~X+l8A znx-q7613=Aq-0tt+;i{!v@!6dkNyhZ@@?PAL-*dzeiyiW;V!OUdx;ANdwlczzk%cH zFY%kd{;M=Wxc9yXXd5jcOi>0{&OKw=GL9Rqhgpi2ivWssIFcY*ZomQzdRE*fnu(N| zWZ5~Z4s6Vs_r-14T_#m2kdp#oC7Zu46Vrs5KVEHa(ecHQ5Q()0OiiiBzFPt$4GvZ^ zh-6QKnC$X#?uZjSdrXR#WDShSH+G^a49#5fKN!v={h5?e}2eJ zpx>-&E?*M@`^yE(y#;5^o~4N`UI8LVBuZo)N79(sYa6<#EsRG?JJA|lqHLw2iCtNQ zF>6PjCN#ArZ4Q|dl?|a0Cta_U3wbP%3j>j4har&}DP$`~sB7+PlQb%UcF@S#z_Abr zl93n*U8k;H9&62uf*K>^I6%piY+WjfDtttcoJr$AKMY1S_ngP5^zoVwV=c-`*226d zXf*1shdcm5eDAwqR_eJ`r_}(uqH_}>_1uIg#0E__s?iWCMb6`h0S9Na;F$v-I`zf6 zDP327>tHCh+ zHqWDXkVAap&FFNc;B2QFd33{eb}dt9c(J!2lZ;T~(__Kd{&jh3|0h?Eyxvo+Ev2Ve zG0C79CLm>c*%Md*YR67D=z>)?L6HzMejGYj#YZK?;W2jDcQge2k5Ad znR$Z>q?Wv+AF2_sGycHwX2W*y@1tpWrOX&wJASS0r!xC}(kCV!>hBa-*rxhx|HD7v zAN`}h%bj=M#s1ztBU&`PjSZy;CnqN?+lED>=eX|&hH+#Vwxn@n*pBQk7A)Gx>g1Rv z2HLLU_U$9~mrE|3Jqso)bR+2)q6F@|atBcYtJRvr{X>pUj@Vo7ao3%9(isTTwhbW$ zVyk-N{Mke9yXPLpq{jZ4!vlsv<@wozrKSahNQlbVEG4nmwcK^*U0V270%y;hXT4c- z@#1;zzVi;+rlV;iZQE+W!zf4$>>uoL$JHxr`z?!wzCR2-_uYFpXZ8=OtXy;ptxprQ zc>O(h-a*$iY_=N?4)*E$o}3bA&zw;fDb{7lQUyQ(@pEU-5k!>1(=-gj$dDj5f&Ik+ z|J{G}f90?L?SIS$?OqWArcbccshNzB35=Wnu4h!!8lwHI{}*GTY7L#CxHE;?3a6ue z6<8^HhF;AU1x{1a=Mm4H%i-rS)N`fAaH{8{GFxV8qpv21bpM-MZgRa;sXISw)UmnD za==(Mj0Jiy8Bpic(>-VBcy=w9Z(%+*12%Sm9wxhTJ~tI)n*D7GKh+!U=&$K-xysGp z=YKYzF$9%Q7)!R8=CNn@LdVQzX(!lYuXzAq_Zg<|xPE&j;x_L<^zb^O0uu zw@iOSl;IkRhBQM6R+|d@j%f@FlzNko5QFJ6Pj7U~eC9Y~>2#%3;A2S26bL~ZK4=|I z?d(|6z{%=_Mb{7+8OO|`UFaGIfs#pMqEqTGV@jl)G?ml3(4_49%v&O>T-fn(&{|WC z0ccSy(1h9r(^^e-lTZkzSM|&kOPwlA9bfRUu%4EpzpD+E)%gxV86u{S1&|`NF_;ZJ z$r_Kb6svLQR!PlD#_Z4{1RH;BT9%6i{R_|V^b0TY^fCOCpZEoO33S~8ubC)0(=3g)K=r;m>EWAVJZmN%-Um0q<%v)K5}*9w zzu_(K_y*qo?hmkO;GSjyb1VmS+5;&XEn9$OePipVg;`a6so~HD)D~D zF0SwYmJ0E=ef?fjkS6)=&s}z_gb0fMU&RL)+%`P)gB-!;$;YCB!azsSgG9h}) zs0lHjXl}E6i&NnYVwGGs+OBet>L~0`JVk}9xAF5@RRnirt=*z21$TlK({UpmFvrPh zR2Y4G_dSC*5igIHtZkllQsj}%~qXe zQ3o_irfJ7BYdLT2o1PYNnYC*be z+l~-gdh1%@MRt*7={Nz2$|lLh@^yoPhl+|D3X1|#k_*ykzHi<8R^SPD1l^zw&XCf* zTl1I&6=WqSL@CASvuZe(F;~UutO?K}iXJb~jwgCvV$fPI+7hzScH9(78dM?1NG@9M zAq4H#k!rD^_i6kO97sh@|SU@0YidiY-L6w@ct%8C;@l-9**m@~Jor7ow zXmG%V3C#u-md1}PrVx@F=WgtlQX@ek<_1(luO4i3On1~x6>4R6jd~%I4fFTo%wYDH z7ojXtYC7dSdN4QiD#&5!9g~0JSM=89&fH7Y$f1sPR(w%J(>j?M-zLYV2=&ZapEeh} zuUx;k`}?CHD><7kN!MA_ESH@yWjg>x`Xo!IrBmfn||PM z|3Hn-&4$b8&$GX`WOH^4BD8HsDcK5+2hJWIaQ4hT!?@*Of1l;vJ}GB9f&1>hlQa8! zGvH43xFB4;e1YwDMTmhjXV0?P_DI-r@!WX=u-zZ3LqgHD*jsii+m>rLZkk*U^n=#D zYMPewXAjt4G%WY_=m&W8@#kpHoMFFfxpnInLly`vw{D+scs6qJ{23@2Ie$TSlDAT& zXy>{ZI6Asb)3rzm+`M^{u4%b?@jPeG?9XRdS$ILXaPEwzaHWyM!$Y>?hLnUmFJI>T znM1}am$art(^^`V*3;Qr?h%VR0SEj0j4AWX^))ZwIOZ*HeG7}``}nzE`XE>Dy@x;X z2fvxi=k|1G+Ob*pg}%=fOu^>d$d=Wp&E{Z@DQjQ^p-+V&W!8P>=wwS1nwh+aSY^DK zBW$`#pp*&vp3bb#%A9dGJ2$o&=MhLfw|1Q{0hGIi%c=HRm396>T*l=IR0t{)ykKz+ zf}OHcr?a^$17tSlR{*$*vQ%BM+Yw{BRxV|>O@f`lS2BU-uN{!7co0#l6q@UsIq0n~ zpQpJzc%?1A1N6`Sw410)1*YoX=W~PscYc3S6U963`I+}XL@3sRor#&G*Ye;UHFcXB zrM5b1*)OJ_3+~K^DSgdTi5$2{{&2<87HaJwYyK;fZ9a7^)mIcnI7=>U$B|K^IE0)K zV}r*i8Ys-#>UpsgQcUc1k({*K*)S%GM4EP~XTA~0f}m}1OHOFeS!GY#1UFAGoJxT} z@w##zgeulCP@m7|P4}XoNBh6)Nwb-?ETA(1N_Bd{0Y^*OLkoo`OXIiPd_>fz$P`j> zu*l9pr77#86ca!(D$w9EA?1Vy;uWZo43bCM1^mP>{yIPXiy!8>XTHqh@C?gEM{HY~ zwnZe<2I0b)L*DtG_i*d>O@8kG^N*14{9`=yx;L;qe}NA_@)RHWwGZ+WKlzi~UKRe* z|NgIV@t|ScjD!&AEk$fhxeiqeqi4pH8FHaWrVS0TiJG?Bk4O;uQEl2{=~LPbRG(=~ zqxu6D;0R5mx8m*%p^1bx*8MW&f~vGH-nKrwUtui&JOwTl>^;SX+z~dDJaT*9d-bW`XEMz8 zsEC4w6bpDGQ(;}P^NQ5623j7p;HXHExgDq9ady^J(!jbOT3T2!nWG{`_o<$zRIRD{ zOg5kH4=89h$){J^(!aac*Hi=Mw|n^{%$0C~x{`V<|e5!Au&$nzEx@O60bIiWLez%7l9&p!XHBhC%{@#+qgF6_c<6y62 zZ`mmTA=(-)2SumHVMU4&$y!fgv1p+PcV4;7YhM2bR@;FRI#!!rhcb@jVcb!YN1K&W zs4c1yi!cBLh-QE!DORsR*CZIbqLjpd6`M;IF)QwzspIYx(Uer#Wug|MbcebYP*bLd zDxaw3VnQ-Q4zlIxMx)&k8_1CRttv3<_%Ifw-bsjBpqCK|4I#GH5vtG+BcbWoYzFrC z5{piY3AYk7-(Rr8o~=2+#RP-q6Y3#N%3SfHbYY4_G%=X5GDYsI5V8MMKd$a&!CgHE z^VF`8TA*|+1&U~W91)0mp1dfvDnxC!D5CQeqCj%PMA==bfJj4(uvjeUk54oL6m|Za zR)MQw=t+5_Eoj>X`+LxDk0~Y5wJisG2Sj;E$8Pzi6wPf8SV}~ztrsz*d#4eC2~s^z zDou?PU-US!hM`JQd@WS;Wx|`WcwxGHDJj=sl-197M-+8n{(qZ(y&; z>>6_k;h#1|76LWuTaCl{YjQs7{-{8Qk6o2O?ciaC@&sl$xzYhDf6oqcl}{ec5Ce=% zzGW)=YAUdPY98y{&mUk0LR1AjO@)|Zo#uBcvN?fG*jOF($g}rd-%Lt=zP>uYvl}u8 zW#rWN9o+Y4c$Fx-`13n3R;n{7uAu8!^*$O@ojYoE;PsjTL7Ik_Z{FtU_(*F7h|o6L zMlwWWFU;%Y`1r(tJfLla{pG?OMbl*&)_u=cpTEW7g)986zx(%DbRFCE8gk~VkG;&M zA85OU87+~6y?wg2rSBH3Hz$;FV+M@sf$eJGxtlLQ5e^Oyh)qMvBju&%2~9^Abv}k+ zw1TtBLVV`&Ydp5usIDkV;m)R`1sHNNof&9jWEguk>ouPnwXo&k!65@2j~Y)cYX2s=Xv(Yud>~)DMf3Xjl-5<*m7`iXempY;+WE)_J9Z}k32FC z1PX1}X#l1`*EB2^9g9v2I))%fgcuiu5IDK|6hyMfizxz+oZ#F#t{ImSVSFUl#xqXut zN`qf-wrsZ}UDp}#QfiT1LFGXftwSJYG%GdS^-(r3KGyUj2X;MGRJ-$lN7i2n0}5VO zVplF?Jk??@!@N_5+TEp|KRpYR{PN%D;ET(^os=YC4ujTnFS}!XH2`LAr|z&&W@#0Z zj5q~6)bY-LwyAQt|0-jhkK?y`ZvqI^gPLTNocgQ-VVSwy^v}NXRd%TK%04aCHmh1p zCKiT+Wwnc;OwT(Jrb2a09C(>@L;cE3hiR>`0vfP$#WqtPVyWF;&&0HOmH&#Z6jOcX zFW97Kj7b~KZnPRt60!jy-c>SJ`=~hk(d^#Mu`Y)?lQT zz71%*WB-EGg(=!zTdfg2x_tgpw1>wq^D5brzSd5~Aura$>vPu)o;n9dCF&dy54h{q^&F?AJcXr#|{2 zmhB$TJ@X{T$H%OjU^f=MLXtoO*AlOq?AIFmH91gFn>VnWfp-&w?`?7F>UGEj+{i9;zQ3c4s>0o zB@c$AHgF6q+6Cmo^&7WA;7JZ72EZSJPwQ{&_qphO5+BRh!oLA1(VQKKR9Qr>*^_r1tl<; zeJai{o9vbfz?_z2#aLjn8~juG8otDUeCIDt0nefSHhxNA{JGd0F%0)ru=2n39dM> zI$g<8TnC`lhZa>3o)+T<_++#A<;}5!sRTLI_e^6Zv_{Jck(35Do1WCK8TuX{UF-rW z2AXckqFr$2+&LDVA*rIst2!MmW4X+==bz@}_H_;}oFjA{UDMI8j~V+di{(DUFfa@~ zi{*lp6Wej5jg3(vwbHa0-EQ4)xp=W<*&Yz3QJPx`j3uan?dPmIZlNkdBw42(Z8NM4 z8EX?}byR{;I}=620Lcrg&K(UD>M(&y(Kv#HV(s!YDxqym10go_DdUthfF#;=DdemL zg$+p^$1OsrU_rFQ-jBjKYPI=*3iCEvG^}J|)b%U5CC5N4g*J$`wsYZ;rdxde;sO+wHDA9y#f%AnE2DvBAS1!1&ez9kgKVvZ3)h%LqP z2DAfFL_(xlE)Y?MN-CKap=}jVY!MC?Eo}=Yn_g9EiI%3PPKHJp5-A5-b8g)M2(g`v z#hJ4USm91}LQ@rd6MeP#nJp8vkVR?28YQwhG2uF$dDMuuIk!`euY`lRbJNw&bs;0t zOkZ?4HygKu2+V2|nAovV&Yv?gAx=h*E{Q4nYkQ)O%b&%K>`5-pK@gekE48bgqAqm| zwWa%f3l?hHk#EWxofdVVJuS!YQ_9Tn0+i9@&%&vf)NweRSX_D5?`Oc;e$M1^@gm;A z&pqU#xxg;>-C5psJWdZH+Wq`}XBK&`du9TznD$JyRm#p<&Yj1}D4xIaY##L4{QIFk zo5~51LWr%_@*0!2k7u;9Y3}?=b#y}X8fLa0MGFgt#tOSLt@tozVr+Tq8(**Wn8w6m z(=eow)q1Vn*-~!qZ>jt_xSV=YiL!(y>d&JLgy z>)cjYG?6q~>+4{F3K6hY*s*O`v@Kl|2xYX|3A#Vi*jw-?s_srB z*!BZ7Ep3dn-GXj;z~26$)ye8uwtM7Mw8LPqR?9(1n`0IsaNpf`uvu@oebP@(Qa0zR zZ5fM2ncWesMS%cgEFv0xZ`$a>#r7VE#CrbRdCxgnDx~RNbI2yyIyH+HAq(VVqJtWyVdb=g#YPL<2`sJ)5Rj?V094v)%HPkn-np zS?qNKU8dzSwJ`P+-#H+yb5rW?uY6gd)iQw&6YxHP%ZaXNuAJHk_Do$+QP+6iuC*F)~)C~#Q( zvF6_qsfA!N%6idAbT%8n+E?d7iGdPIeGX6BNo1?>gQY0xepPm`+AA>zVxxss2kXRE zLS)--NPSNh4F+wF*TjPZa_Q;QR_nwJiMDA;gVxI1_I(Wi7L5c$Y%DE(@--;bi2TG5 z^L;r3@v_ZNpr*)`s>^MC1hr)iI7*`L1uHh{rzrcL3$yE*w$YA|#h4nVcY?9a^;nRy z1G&Ks)Vg-re5F#Xp3n@4%tg~Ynzo}^?ms_!y?9`CvdSk+ zVJ6XLj3f8!C(-WuXXfMk+4Jv0q2s!}nd z)QVDNLuzXtzp3_8OgKpaE6l6PElhMGbNVUPQO1l5$y3kpQpA9@Ny$&NcKdq?<_uHw z`K3hMom6CAoiGtaSyL`rB^!+#Zu*{*6{!`_)S8qSw=#pgvJEnlwM?t z)}kr7xIqS9bV1u;w<#=EyiGsvA=fp6)6;J}GHC1v_dbt>l3 z;#2cwj*)HS`h0V_>_xeQJ6|EFj3m{$ETRsb13y#b*9tP@#-9P8Om%Fg;ERu6W^?B& zJ!fZTlg*YZpWW$W`W(}_Ul zMe{?9VDj$spZX1&vZf2_xC3lAy%rQ~J5JUcD`1;6@(9E{QbMF321?4v{yvL^8lGvh zW{{58zxln~_t2Zz+dE*J;Ftf||C@jPBR|Cd?vH;TZ+_3e$Mwg)Oe=xspTEiG7%tuS zHulaedHInq^V9$0f8yQm{d)eucm8n}T_kNc#GoDgMiNa3bg@xdav4ck0bDOy;D#pk zOkhqq2GVO}F-B`~p7niAQPoZv!*)y4E;w_3$ztyu=gwW?;9!4dUg~}r%qa*Gtu}Nb zjhS(PE$%Q0-NJyfD)&uhnBhE^GsTS3XzVC4N4<6=slSf~f`r+*nWsg13PGsg#;z=I z>h_#nXXm+;$sey^fy;-<`7aewnPg7|vuCe4i>4F@e;gc2W`j)(KuWgSf73Wi@n@RL zg~@iC(xPHzuld;*JVnIdPzxX;zHNN$E|=#pr~@q1bM8KuUDx%?%&9reX3_IG)h5u- zilqqnGfmGk|N6AP6RU9d<;pfe_YN}^K*)Q6PTABBSR?u#t zKpFrVLWqppwWcLSA(X&on;0x@rwPFr!)BM*z6>GK#%}5~Sf<(`5(|xpu^iFw8sky7 zn9rh^{Uab*?QIFBKFV9>NAiHvFF)~#D=H8+jcSt*&5)d_oh zOJWeVi!Be{|31#_@6$y%KDo{F&ppXzo7vktAO=gP7g(=1q^xQ6Ia|=z8gY2{pC(3z zVK84+*ba#%jvO4c93QViplvi&Gi6Of>c^g2M{Am9%if|>S-#d_Zpy`KnI*_VP96Q2 zN&jEc{x#ON>^cv`zA@)od!KV}-CJ)KSuDO^A|+82DeGxjZ%eXTajWeXWD7<+odoD0 z0b&FVBta1PXV3`{(7FkuSx{q_t z-fPV{@?(r|jJftXC5n|r6z@4_uf5iMj5)?P-red{)@g@hKj3)p6y8&5s)1or#enBV?x?DjLJqF4`?*w>D$%Lh=cINzT^YQ@?cdT*F&fi~cC zUw9eI+E7q%ST3+G4RyAnzdRW%)zGP{L1O$D^YB>Qnn;JfwPDlPkh&O{HQCNnnTQA!tiKU^YmvHsu_7) zC*SniM0 zT5x{%QLIZx=?%NH83zRp7gw+psR_&4P)ou2evj5{-HyuwsGZGu@Pbl?mvAS%BUvTJeLc=D{n{ zpirz@;}8_7CP&O%Z-7WUdTZG2Dr%v)??AU=Ylq`86p^_apjKV2*rQlp{<_}5*(0-i z*A>v_#hWJV_Gc!rTK5)pUTDtglFPp6f?=Fi*YRmJQo)&`Q~{Zm4 z;HaqkM{)1LJv_X;z~y1VR4VS=x`nA$yzD?EDZ9FM>5Sx7y@vu}JirmIW*tLOh2KL43d;0^D3A0BTni@ zAGC#%L&GgUk0SJLOw0pbjRP^dP8ktVoL^-sL(*RwF!}u9cp;U4Gcx3P+jd;Lo;s7! zB7A=GKpozHo!^8(G-j3&Huim<6aQ}4&3Elv&3O(540$`^Y>wl~sR+hso!}#`3>*LT zNTAMzqWs=I$9NbcziF_^^&R>6b}zWT$x}B=q#fJ1w|qw4mwUQZIr2Tm^BOb^^W*x^ zNI&e!i7?FHJ-RC1Eb)5}1(~8YOQ{tvy!ZlMd`Zk%tR3_2Huh)5(~i`iQ*b;k zkUF6)#slWboW_?|S7@F_|M2PpFWhYMn=4(>z76nJ znLVO2n7a&kky~@#nxobi-0ef7h_j)D(M%FhiveJ>hEtg`fg-NWskUf|rZ7)h(PE*F zQk+nL<#>s8S+UFwR~HX)el}y8CoIb`7`}QcN~yrwS1iloX&ZvwRPpQ^--@%H;PUE- ztBd=1{O%ph``N61YN3ZyH3o3?@DkI!!_pcq9zMYBThHJeg1G~&D-;#b0;vk<5wi=3 zW3vb#btTUExp$>-r0>O$%0z3v{Wn2E*{IdJ0BKQR1v(0*VpYf$<^d@kUg+9r!i;$q z=~ARXz3Tk3TJ0YNaDIMng_u|$1s&_!u&j%9(kKON8``>HU98yF*?w;kQ!=^m=$Ix0 zMIFTrQ3876%){T^x^9s_#jDFVPhT>9FFjpRL#OoUwi5-P!D{#(QRBi^)r2?t&~mrf zm_!t!4b?ri3X7I%01k^Q@(d%C21ZphRA}9MWRjvxyAUj`choxJ*4YlykAN!nJ7Atx zKos+|gZBG4E=QwBFBYsG!BLCRPl0$;he!5E_w)%`+^uMEDc)*wqunwBfl)+x8aJG3 zG>@ME&OEw#UL|;ygkg9T68XEF{C;|`fpP;BJm)8hgt7(<6%g2Y5li#R6v@rd?HBSu zpL!Otq*BwajcEkt0d)QErldJ&4%Vu;iKmYODI@L)#?uSERUXC(cw|h9VqD+56J;(8 z=&67d-9~|I!~gB%jGp4H0QJfd{Jsd%E1YRsd|sw742}n{Stc|zhryjnRT`m2#RHIx z&H~Rby+)d}Xp4H8Pw?#HchHsv&wt?yfCz5ix{c?a zdm~;q2@j4<0@+#b|A~y*tMb{>8t7tBVV~;f-%W zhvK9E`k&+Xe)FUF!WX}Y=ic}x9PdBC#n~6}`Zv8DU-##J81Mh)KaUT5@Xz7a*$(~D zr!e2TgTuuo?!WR9UjEW&p#1<@J9=NupyClFQ!!atCXX_aie+73PBg)~9x)e_Ci7HK zroE+%iKS!Se*77H)w{nQw;y=~YiriZbX`m?!{uGnLdi2TVk+Hg*Py2@JA(1dnEV>g zX-0un-}8)aqaoMs9U|kD1v-bfI={-HoZye;ssY3>D;NSi91G{ zqt0$dBXjV1yE_q=rCj5V>M~;;*ahqTXzQ3@5ht}yUXsE1m^w!9t>MnCTR7Y8aB=Yf zU9I@7c8eIa`Y;n(>rsMYVuYsad&{y|jmd6N8Fd1BFP0t#GotNxdo0U}R~}s8@_1p9 z;;0trp}=8Tur3R3o$sN2#j+f6T&+gfx?0+BohGc!A}e?EjA@#2I9?fE?h8~3uC9&% z6w}T-imGC+77K4RgBr@=fIb0TCls{~O6zJgqfTG@dBQy1#^u$5zIHskIAXV-ar^uh zt_~|+dHKFMf@MP2ic%Dh-#y3kFI#;zi{4+NX#=`OsRuY7>TVc|Xzkj8?mUx5IrzsE zA1;pyER~0~$WpfPVz~+DQE~p_m2jbYSokSUgj71h^a z`JLKnuf;~6qPR-0r~?4;bP7;FXG%k-;l|S~3QBB(xW`}J+t|B@V|f&Z)eEqqJzYmj z{fLGU`(t35Yh)j&3@zG1f-5>Ix;n@$-f5#)E6cWAp>}VFw;nT+!M{JYJ#DK(v|^Hq zS*mqFSR3v>`Z(%5L)!|0MSJY0*+cwR7it!kdA8f5lnM79Jiu`|LiC79uh4aI#%yzJ z5TI16?IFe6C<}T|h0ba=&gxM^daG;@L^$hmY9t8!Zc)F9X%~U-UUlr0c z_FUDK5)o)AI3ABU9*%CLQtWnf%&#?%{D3$UuWr<^Xph!bTwL74vRs)5qgLxQ1x4=` zCSJX*oGD6dH);&66bpGYJCufEUm=)FMb)Hl0V9BrpiL~)t#qSPOHs-^O-rdtug0lC zp!hQ~tk7tXMyJWL2rQIPIQHswCx9|lNHrR&s#uqUg@dAESuFBqHv^@tzQ+@mzM|=h zS}LY8qd1+kZmsc(SnF1SdTN&Q4QCS3Lb+)u_cVkQDG}W!gECSiq`>LXi;L&k|*ISS!+D*8Iy&v&@GrOnQ!B#_>y2L6sz*cpKmgGU-96p-RIg6!Q1 z*!fzrF0B?io^Bm;RsR#Y0s2Li#YANwm0U#b; zF5}-M)YWT9Q~W)V2w%4EV^m;X*XNOR$33m_c1EmZmnEidz-UD6`~~ooapZPojz1hN zr;^6Ci&miYz5uayw#BA($VM@A8q%$&o-#QnE(499ETNEYb3Ly|K;$|m=3xjiQ-Kv% zmsi-;g4_EYZp}N~*`J{t5BSdS{y}`tU;YpAh0lE&^VOH|ZGYyg@t1z+d$3zB@Jm1Y z&oDjq2K@QI_~Ur}Gq1;fcMG>}J%-!2AH{CoVLcwqdn*M+6s0!2_~MKB{HH&S=Rf&z z+<)auSRnZJzwqzkTfX!Av3ukxG(E$9D)`zDd(g_#G1kU8 zq46sfu=qaAF@=c4Gb6t6+zr@}A z_p1Pt6iZhqV%;2_`);C5Bv`Y_KN0lS<2hIxEb*_PHSzRrOC5S}-wXq7Rjg}sox&nl zN}aOyAAof|K>N`he-)Dy^wzvRJX85?eT_Z@y){#iS({Cg{s4F+fMKFZ1d}_pi&_P> z0*RU|4Lny#EYi<(A{z&Zpadt<5h^O{h*GH z0|16VdA|X>7*3|^_`Y3U9dZBR1=g;Z=baTYS1T{jn(1K$hJ}gm?K@_CX&q$}GrX%sE;15Bdq-cbTk14h48z(M zi;V0Y%W|*+%u7RSisP~QzFLjM4x9h%&hwXFxrb#{oSp4V59wC7tJZ4z%d%jachD|4 zUR`3I1a}@e$8Hjwo$c}P;tJ1y;RW1(@BlIkZr`4*i=y*N^afq5J{jpF&dLS{`gdGb zNKr`a;#lubLqBnw4Y~@}!O24-rqzu})Ej(B-QhGIXU8h6fhkarE``&+W7*Q9zAJ|F zkWqEU8>0kCCcgyVD$egb?*v7yFt||151w*@7vr2roXHV!eWllH?}9WaO+qF{R>{o+>P4hP-HMe^Ne3qpcpE>M90;^Po*j$8YX zUISZHbr3*^Vt~Om##lMSfGu*Rd%>attMcsC(>(&DKujpN0*IvvArvh|EwdSVx}`ak zIzd}QUngi=T~QU($yn=QZ8#hc*xfpJtGpfl3ISZ%?Nu-p0NSiSeG|O$(hHdS1?DoL z)IBba4Xr)ITr1AbcepyNW?e3pOW5>?M{eClTV`AySKL1=(CW2wN-^ud=hSO2XkbxX ziaT4|-W7E+rLH%NQ0d$WNY^} ziCRNYGY|Gg$mOXL(hOj90c3(QS5!KB1qv!w2c?rMv=rh3#eO%TuPfFG&{DB3ilqT{ z+T(Bl9^AWtsztYmch(RH*1lS}YHwIub7orYJgYJJ1oa*;>_@sH0YXMPxEvqS3c)o+ zDz`dt-ZC)FQv<=KrSm9`1lTAAN)AAtv*kYlFiR@%D%=usq#n_CW>IUy^G<=QZFCVY zr>w@sn2N&)E1;t*jl2ZGmV#!VJJ>BH3gRghDk>fdtHI(c?J7{rD~!A>i0NZw5opmt z^$DW`Hh7uJhJi5&o*Yq1Gz_VKSzUC~(BQnyHxvvl1p%YxdfGefEZcZ&zDzG8z@#xs z2pGc9#dULq$rx}L0BIait`BL1itk`(W0A-)g+Sc#&_X%g8t+Z%^*RE+JXF3$1)l$& z76Ub}SZlw7w0X*FLs1WWM_Pw6*zun83Zb{{ZK$<3IQx{B^wN z?Qg`#e(vw%gYSPo-u&jb;*)>yd${wCuf_lPfAgQ>k@Jc#eD;$;Tbz=01rbPB?9TSM z=!&2E$-jeN`e#3hx4-rEIGYQeeC929?v3w2d-)aY=LzSpyNmkBZT#-9{1QI;i$8J&K(af9-!}T;m(uKqN$?pZb9md$-}ze@Z8&QetwPz4;}z&9&+0iv8co_9&o4JMz z;uy7BRI5?BD-5F{DxCy&zzBr>j1AF0jEJ5@;fcYzA8IV4s_x2x;1mSRbvTf^1iA(rI`h^08zc|u=|POXlYjlH_DM{2PycK}M6d>rtiye6|} z=Z95D|6Z(H%rQlITq2CEI4#?|CO^6oY1OtUY*Y}~iiWY?A*G^A$5eo|t2a8RP-&iS zJET-IbHQo16?H?Ocj9cG)~S|eWQAIrMU`;aWP5#|34# z!@kZ~wRz;XSe?#ka_2+GvaBejV!z*^udAo0DyC^h@7)T^1J>2AuaE|;t7T;z*N&^h z0d=aV)tuy_4f8x>H&q<_YBf(MtBHAaIG7W-RUDQ}tbH-Z`m*9|K7&ffd{)u>f>Nr> zmx|eIEt=8HIyObuJ6Bo#FuLbo^hU^=a`0v|Xq4&kd{qS- zqcY-ugArl0Mv#$gg7}_1gR+s4kv<_%9@)Q^LRWxp=bsT}j0z-gv~)(8!-r8iFd4LQ zNRjunA)w^ONY5{Sy(R-psbvmt;BcKrz+49c77AvEir#N324+E&Qaysfgm_xsy*jZ_ zNN_>0`P~#73KvUvFlEh^bSh1razi;u;tIQx0NSidwXln>s>@UtW^Nl-ukDaE4ZvNo z2YK`kAU?KC58!?3gj%|VrioNcwO}b%XlliWkIMp?C+y~C)!d7RKgPxw2%zVrL9q74 zEbKCSb@x3E5AWmQ#X~%}xWw(pCR`j2xP3lBmx@(8ZcXQA7(M6+>>Lk8W(lG7JQr(?tcZy|gpy|=-hX^_WoGP?gV#!oplWkgUCevoq2d(ioaef(I6FVb<>3m;)nd$aX*j!ehP}6_ zQz_8Wu`CPD<{3M0>pV>b(_|juBG$306pP@o9Lwv6v#S;2WgB9PJW?;HCV75N&yq-Z zIH*7t5j2l}igVEkFuhO~#EoAT^>k>iFnQ{dK+UUQRfthb!K@DWYDHIL^lNW8n~a$? zU9om60=FE2)>oYGZ=)2&;rI}3J;K6$jh=xO5R1-&0@EZY1QeWOw{?L>1BvF`jaQJt z@_Zq{T95TnR}4=TDNg5*)>sykmx z8OPdXs^(>?Oj*lQFzl~^h2ERhb8@A-cQ=%2bJ;e?%Hb(|7tfMvdS4A#(h$ZdL;H5< zGM@fP#o?6)_i%N*!iT>3J8#zO|Jod(SVqX<6eEu`e8;X;Y z?K9V+sfEASQt-OhKZmEEeKVeV!<(?*pW*HAdIuhU@$>lkpZSM4d+c?1?zykV@eKIm zKm0hRdBTUj>j&`WcYKwdKXosDv5sDcgW{3Lp22*67p<#-RuN3|9?%2+=+}M@FMjgl zc=pY2!DCN6h8JJ>0>1dU&qL>1_`vu503Lnj&A7U{vV8hdVu!T@4<0-KlMLM6>w#PwU3xIQA@F-GN>JrL)4n764qp zwyI9uppk*$_v(g=(eR#pVH^exp?MF-l1>48hVkG6MzwK`?fx1+kC&|xjl~E)V@6p& zXwoB%B*xas&xxhCn7E92Jz(#-=D2~;6a|^CnnoD=Z!9JZzc1?}us$030(mFpA$g-I z-o)r`T+|#FFRuNoM$(T;&|m^(tJNJ+z`6=VcG&F;j+YlGMX;N97BR6l!<5aNA(Vn?w@10UviBS0iURO7s?u1- zxiUJ^jBOo7#T}QnhShhm*cZS!gHlu80NAGHsinl5%(k@=*Fi>u7o!_l6u2l*P_Pz- zHpN)8PeshJruHrtQr_SUz~!vZtpK%5n5P+-tUYoqKobp2+-d^$K@1_ug?_4jFw8MXeLcyu-cw_t3i42W`D$o;_jzoS2gxS$kJ7(pHojm_WK=cNOQXVw85z!gU?5E_WjFT3Uu0wcyi(vgg8ij?Eln8)nD5MpXYD<*5~8bH z7-CLQ)K_-B_6V3^LADlgy^(>ALKHA1z|OYiV$#|KR;N~M!;?Zl43}bbGHif<4_~zj z6?z9#ZY|{6I6O=cyVF^z)nPQg94~J6a-37eF`F9hn|}bH$PwymPIVz^Zvyp z9$Z`k?Fgtq_xPqcm;>U1*RgnJX~RFVl6@eC(Mc>dx%^@dqstH=2@3!t)yjf@9>JgnusrM zy{~n`y1MtKT5Xfw7eESX@j`|WXPC|Maj{z7sRGiCIV~MftT-zb-HXoFQd99!ao}1l z>cort7Bt+df-1oAaKOBqKqFbLCP1_oEX^WwN-aQZIG^{}R|`{I+YzlzxVX4N>x$jk zgmrCbhYO%Dkk>tp;@0x3DtM&sAjJeooob{cp#vSPIpg%@N}a;msB2fJg8|T<9HSz| z!e1T0TgbT4Cw3dGws5)OM*#UQtoQ5JwRa=wduuhRxx#InVC=dIaehxXId9SLiINr?-wSz{P_LoZr5S zr9OtA`PJXTU-|3bj`#lA@4*Y7`W#;R!l&Yy^ww)Pv@b9twV>ka>VUiZbNuL!{dJU5 z@c2{DLZ%&l`k($^@ms(2Gnk6tt&cv6cJDK|Un}1IwcmiN%LjP;>F4maw|x}^ie_y&w1PzkrLw5#RW|KZ+;b z@DAL&_a(sFBzFl51*mXRIget>T(Q<%Y;BFYq&ouRWmz5kn37aH9a>lNK{CnYo$-#1 zprg=*Td6xYICr2={NRB+%e#SNETt z@Jpj(|I>zsumgFb;Uf-fC`Sw5w%uSScLn!u2@z}|IyxXw%r z0JV0~rBo~QTMPOsSXRa1cnJY;_x2;Gy`g*Eo8~;kG7p=lw|30CIoGxWt4BO(v+jRI z1nTWbyDFxsVpk`0G~B*>j&)fv&)#LJSsU&O;A*jQ6Vp5cVvb9o;<#L4H(8|fVQH93 z#o4Z6)d`mmA6TS*Z$M|kW79pW(;NV=v8=8ekt+DHOLsqe7T{=Shy0r=MP6;|%Wp}2%r2(|V z$~|lh57e!KcMftp_}F#6{-?cOTNfm^&dHZ~Z-6Q?U;yjUt1ZLAi@X1im6Aba%WG)_ zpdX&I@d6+j(O7Jb-dA+D$Zi0w^94^8irii9m3t5I%JMl}eEtt{`K8a``Q;8&tPLsPkt)^a=3W!?EWj-IVTAIq{%VI+M1V45 z?G1_*yHZ?P7xYq4rV8!ARqv>ixbkNPx>_q#yseyAJ2MeMZ-R&S9^&PfU$Lsb2yrkG|w|yS6n^3!hScSPP3;dDGrAP*jFr<2fXs&A-?p|ODL~Az)PR`1oY|> zFTVUTYOQ$k>8GJ*^pCXe#U)XB&t=Y>c}aXP*X<5tNsK zQQOr4RQCp%(j8!{X@t15?Q6C)O+_b!AbE&K9zf}FKV{5mUjAUrx(TrLZxoAiw zBKf(!irsLW6(U;@!}o{#A}&zLkBm2^jPIPwU>Fhio9PZ6OZW1|QQlN|E1QTZIb!rY^L4uO!ud4+^Pk1tTQlafJGk@Ivv~H+Z^ON{;;HjzadmltpZ%%-2OfRo4!-+)zY84=>(LA* zP=&hJzqKp$rdIG>j3ZoJ-oxFyPvEP+8n4F9+GKx+y@QyLUBnIsY3=mEZ@9fF6O8a>*(hCABZVgw>-<5m` zUOK?a1g%ax{ygWiqtqea9gQNqtUFE*1HouWIW;QB^cdmDv={P8*?yOMuOLq{0Tsr4 zkc=!!rMZjV6n>Aw>;)*+A*J=zjmwM)FLCSeRzRXu{O<-?&LJy zt!Cgf?I81nr5&-WGwM{VD6N{2rFCnp(YpP9wm(Dh4pe7nJFH8COa;q&L~{e~RA+Qu ze7^ut=WHEq?U2dz(w((1f)>HW;Sv=Ex6W^2?U&}Ho^~j;V)cT+7nhef7ht#BJ2pc) z_e;TU-gz^S13EgU{SKnQ;c$i9xAu7Au}5)nd4a>>=!eAgsV>zz7O6$9_b%AYdmPsT z(1G)_Tev)0EwXu6twU~CoZr3+MZvnR0J4MFJnvDail!@o8Oyr5>`x~hjS7k$sla9+ zcPu8Zw|9%CsYSsWV06iB`72K`BbAVmyhERGD$6OSu5s0Uk6(+z?F`~>F=(no} zPl!7QoiA?;ID?JB_@v1v(kiIOYdYP=^RY3`dkK*fG4rRsUXuYPTNsYOHU;3A-x?lc zz`F#A8#WA#uHAr;l;TX@g)V$k8B;H0+{Sncy+W;qK+SMiCpq=HF#s%w+LWtWhR7Fa zc3z_3rqZWgSPeCpHid-Ue>*3ZDPei}?0$dM}>+zx#3}`TPuLbH#Fe3>~HS;fWq4)eUn{`IfN@#+G1o_qpteal<%hNqrHDT2Fq?&9|CTbQRA4<0;l z0WzaG1FRUsl^uiyIM)F0+;?%hp@I}p#A%euEQE%Kf>kYizlaqy7BN9s05q}MLTHxH zD@8C>TT44p)#}enx5Agx4*N$Q0h*-%N|~@Ms}%(<1xNRA6gR@H3arN!`^gILwzZ)t zEE0%Rq77?X%==MX;ZjAZwm-Gh$W-EYFfyfTqSu4J@5 z87-MP^`pUK$%5O6R<5IAVGD{kFjU||OFc}J&n9T)KnKC+d)l>GShV=~9N>um9)tvS zp(Yq#eX}Rg*HSgSfj~yB@X=gC3ZF5;f}T}=&QR@*VO!||&+n!2L-Svl(h2SE6|qI5 z@hNM9IN1b_*6}+2}#XS+@Mu38XY~7p6LWkKrn6h=vBhHi{U#w0V z+PuSoZ3nupph3@!P>go6J-0TQfJlYFqa$MP#1szAh$Q0)gF+HOBW14JF5EEdsYq4L z8R7E^<+2!$G0>idtW=AVCb;Hti9{q%7=Tpc9Cq!-SC0qWz4HjZ>07@A_g;PpSC<#2 z{47gEK-##66kcCL(T=GWTr3NI`k(yQ_{h)xzwyrZd=(zte+A$AZGQo8dHS#6w|@PX z@x<$%gwz$cZr{Q0|H9AX*MITDxckIYc;Uq_;J8}NF)IYxa!$UUbwbE`Tk?*3FTaf2 zw;#uwzVXka91nQQyY`swJcSpY|Gce&R0Hg#WD40}fD!TZve8h0L8*sDa1~cndI#3N zc>O3?N)(LuE=y0LA!1RDRxk`jiu3wGPMFr^^~o^sEb<*16$ofE)v~#qHNfk&<%ZfU z9Y#kbj2m{AM7q};6Q?f>N~s;gD$Qx$l%L|!qN6u*jFupeFx^*%S~hO{p_~Y!q469W z{=@YT5H1)};C0{yTr0#n3cTsTa3Vsn2l@YSW`lR86r&OlbJC;(-e75Bw23GbYv4xp zGuv7o4)R$hm~_WD#Uo}i9f!u1zByYl4j=Tk=rj358q}?*@EC&APuA8jH_w;J+R@;b zDU8UK*~pBb9!(h`js`L%*b{PlDqf@k%2)flr|f_cS>n{23ZKAqh_0sauf0LLVp797 zyEl9FGe06$h6EMOb3N_}Mf~n07nVA~-*sL25yB98pR^ z)R3>1I>hxC_1JyiPtju0V{W8iy|?I`8k||cR!6p$Ck|^r&!voV-QOuDqsT|3SaDw{ zP`n%Fu`RZyt>NLtg<*5GVzsrH1DH`m1$gtbgqm(?6lx-%JayhOivh-GRhb&qzu z0JPzFH~MK(Tt-P{rl(%2N7awSc;==3JgDE)EBjxk7Zs)#U?REel!~obAt`SPjMX zhO4UsLc zFje4ex5x3g;{L-6NG+J^4u{1uCAtC+9$sOpinRe3mk)6!=YS|)zIPv=d;WPyFL>Q^ zlfedJPB8<&Iu3?fDF_QTqvh9(El`QNn^wC{AzCp;TB#&91Nk-i1T3w%xC7njs>E3b zkm+#wc%5x~FrwLiiK-uDjt-^zx#Nxn{3gk8}!>)*O!2rsGZ%En^1`nhMbwUJQ zGiLk!((N8~1whOkY|K+UG`iR+Sl#kHm1@@iuIRM@>IFMhadliF+Hiih!+zdDQP3b* z4z>}Ot>Eg=u#*`NkBXz8>8{O;ZbHM7dgP2oNFhKb3O7>JAQ~E0!Y0o;F*11mb?6S@ zyG2tg{~@0UV5XzRyg>$|7(nAff}kYQ!5HHV*w~Ck?u~oOdjQVMfj9T|n_t`CAS#_Wa#W2>Rwq~JN>?-09(T_aMdOT!D_ zo!<2H#;TeDA{BUFhat3|U>OdiqXy8ZU^z>Tv<$FSpsfS>f9_3s`8FOzjx%g3YUz%{ zTw*Vf9_j5oV?{$ob`P2D>WZ)eOb5!8sfGqc@l?TavpWH@M=RLx1TGCxT-onxt^mZm zMWAgo_$7_PQ>41ZQwKGL(( zec$`=E5GuKDEr&^mhb)V;cGtl!B}IaHm8!OZk*RN08*Bq;o-$4=KUS4`#Wg0;PUI8Yf-5ASmS86d}zb_}wTU#c|CxT8nj2?C)B#%Uy&$tHSJb&R1zeCZzVgYJ4u= zFXR`DL{X3SGC|YSxd`PJ6l!b!KjB?u;H+1wx5QW7$}gJD)$Ef57uvFd9F&HA)M z5;f0!tw3*<%FYPyQU$w7Ak}I$iFWL#8B?h^tVcjtgUwRxwOD#atvl@YifKQibjK_n z@lWH3dPIRVpg6E>;`IQ18;QS#b&STd1j#O$05(xAqcR|)k$aF^V5BYr8}K+6NgYaR zML9F4+kQ8pPQb&57r3~%#MxxsPuHbmHw#L&uBglLh>m6{KF1Xomk+Ey&H~(j`5u;D zpy%g!>GPk(GA&qEp!6fo_Itei!t=QI@{1_CI>uMrI^ScOD!%mcJ)llzj8ersO}MvVoLV=4{n@rd`l z@9Xf?)6W4YIKQ=npkZB(z}dM)i*!I-n^Zp|s@3J1%SQ2fjm`(`2)Yb%oJB&*dj?~k z%MNyl>*!RC2kb{fE{(Q>W6ybDscF<5yCj?b=gz=xXPv}Nc`uTgG&~q0S?|a>LKd|i zWDNk&Jiru2iShP+|NgxNui<)a5imC}^%0nnPjA4QIFmrfszY}WFFXo%QcxozdV-j` zqOe2VRpT?jHp^0pJSeYZ=#jCiVxje7CJXacX?_<9OF>EoZ)r10P}bFG+_Yg=NF?z) zYZ(k_4c&zqLvDqgWjvf+8|Jy<>hcPU!o%$B-BYc&cd=rg3N9Z$z^BS14qBiQ@Zwf23ZuHE6Y%!Sz|~a+M7=wJ?;%0H11ClY(e}=@u``v* zRscX6T7B$6GvJ}I!n0u%s(@7ge%w!Go$}e+gRXmoBb`gpfl}sN7vVwMyP}czi&%|d z{~CHXuxdq-fjj3rEbEHTz3?R*merVIxA1F**)i;sVa+3;;hF$LB!W2IvG|oQSae`P zGL-B|?*?43TUY`%Mw5;0M5#b^|5r-E+5wb~xx(7@DWGCCXWF`0LF;M8)w*I?S5Ham zz)rBP9c#OSz*+>>xnP=#N6e@Pvso@Qi=bJtX+hSfQDQ=8gnmZ**jZ@wuqOZ`uuH*^ z0%G*=+J9b0!+FJ42_HeGQE_oa19gagfq=zAGlFGQLNGj&(K-a2$upI}p9;PYG16*W zcxy{Q-G_C`8Uqe6W1J=UwC#n5h=D1rrx85E1c&F2*JymA zvN*0U7j87%E$JmbcG_kEdpBax^w+$WPVn~t2!5slaB%;VCdog zuX{cI_J95l@dy9r7w|P-^LG5JU;Jf!@%cZ(eggi?w|*Ob?YDjlcOHELZ+Y`uQ44T5 zu6AC1@H*^YZw=Q@u2{rHJ6@sGg4H`UGKal5&1zRj^>c(l5tr>bA9pg0p+n?HP=RZX zV^@VR{$V(C+y_H|C={X_1zbWdV^BCpv@#lL6(gNXoHY*Lyr2j=wQdpsqalO>T&{!H zah{pezmAyH@-$xo>i+pw5M4+|9Xe>^97s&)@L* z@!SWEjnOR#xw&;F_4uxC=pnd^@4?6)WuON)S{WC2zUeeL&@hxWUYz!wrlS}v$ySLY zEh@aN9!czqWg!NJDQZ&0>jMg=x#H|>kGW2mcY8B1z$2H6c*jR;Ej;fk+Pwv(6wGJ0 zfMO}$Quo;H_BIZwSar1&OB7R{ORkX_)eTF}o_Z9+bNU*c5s7WK7*mFQ%>6{}9}pP; zG)}SWALU=I6|FThYMkwHcDBP*COli7#J!9As73I)#~$-Yd#lknRg2MzinIM5kKerus6BU@s-OOX<(a2! zeTq@?T&BR;$8|NG!5tHmV?~8ysOFIvMJzQ}9QSzR3ghdD`an_&s#Hj^T4%i%lw!IW zL_)@ORjloZS|*5CW=3yTWWV=x9`)YMDBCR!Zknp`QV&irMZ*-N;{? z?4E}J5S9~2o^D}r>aEEP&f^}61ozgA;93VpOdJ&rB|QXq0W>|X#X&#|rNBYIEy8B+ zx#l8C0|_)dFI$ZRi6bCY&*_89{XTlGO@I_yNHndY5DS+p9v<$FMZ4d>&ovJH$oDXn z5xc)a%%joO6d+e5mbKxy0$+ON0UkVj2$Tu6)L<;!PnH57*LwUnX@iVH;^ngWyXHE& z(!TkO)JRTNtlGF4e+s7B(K;C$6(#jhS+Ta`%+2nAqG6tP?y2lhLo5(CF70P;*;oYo z$%Ja@E413awBtgAiVk2m8Fg4Iz17c@pC2@M5g`|98eSQKGR`-_;OV*zhSw47``(*C zHF_+yy5Jn?b9^dIx(3{+?JD1=2pZ*A_yqgTKyXf6HyNh^*qVm2q~j3cy9$JW*or*F zSY#0J*A;9(O9UgsT8@S-qa))vHM|8J#&tu)SbTUB*>pnNxq7i{08%L%jgO2N$=WUn z)K85Eqze}JW0y5&dVo|$zv}WO+Y&-J!R0y#H(7k1GImcZQcg`$_!EkN*bF_d9&o_x*r*GrfQ@m1UcM zj}*QlV;Z6@T7^XgqFN1w8gk3ef(*x%G;}f#_3v1ya=Nb?$fr_)vNVztF(a`g7V5jaSkzbQ=9)JSfM7NR=u69OGw7xs%&E?CJJ-AvZD3FW0(^@7v5TjUwaw z((q3{!ntfEQewIiYsd8(Kj%ETPFcIg*0H*SLpO8V%25h7HYR95*1Yp|5z-{_s17{T z_uuq_Ecn@44;*W(K%uQ+C+Rp`)&;AlzM~h+WkPEW%j)TPozdjYQs`^3dNMADYk@}< zkU#Upusfs~kya>Xp&<$z48-3tY)8(Myd!x?U`Ea7Q050dcf&^NMt1MIta#WO4u=Ew z^Njsm@#Njxc;fCI%mo(hF*)wGnq{s+>x4-T@sI>vu<8i#&wE{Rcq*IpE=KHy- zH&BH~CAk4BRz@8)IH_$YRZP@H^gfS)00SG^{_O8)?u4y=)EiaBlJ|u=I`ZqR zz-viSSFpcl)HXa#*!OiXsBX^@B|=9*f$V`lc;q&U0B8Pb_c5Q}I*S3(&n85O-dJqNR;bITWME88@iTBu>%BoM z5CjJ+8HIMHyM!Z%d*IA_lv#FXhKJc&VZ*^_5oOU^$N-ppH*9$%y)iz9Q!P<8`=hgD0d)3bh$^oMvxgpb6F>O7}87VC?HECXr9~HQ_@`Sy$p0lA%Njj7`sr< zk@XjffCoCGBao=W!k)tR%jC!6-%0Rco*XDkJ!^n49x&=ugxT8D({KvxL*$Klsd|0iJ zS2K{3@1}Cc*3+X>MFqsxDB=z*=gvRp`VF!xy!2H1PUT*9v2a+0N|`{0AXL5?$z(=$e+lpV>aWMWOW@7#cqi7S<6nK`SMk`>PhnjyFa!A5Z~qSd z?XUl9JomP@;f0r8Liai{$HikktL=Pi#sdp#NEt>92-99%Nit=MhAP|ls_MALYomC2 z>sUB^^hDDr+&AZGYpffMq2NjhQ<`|5>*g~v7$k@VjS|C|9Y*B)MW%t2ovzrHpdCLS z02sMZqylJ3Z$n~p8j(4lOm|?{KDHYT4{Ef?wi|lcu#irZknOzrtM7+olu<2kNR_qfDl8h`oaV)`4zWGIAX}ms=B?z>Uhw3r)~_3)QeId=@7I?Atat|05b@xpflT`8a}V3c$R}Yj^I$7CY^7Y^T;~U76GJmG%eZ5)2inO ztdErr-37^Kcmrz@WdOLH#h&$|wuX5I2>{wl)RLvTNj}Rl*qEKGhJHotQGCyhrkWPd zbkI0+f-M$}Q4ntpiuMUq{8L|Fi2){FK|nyFxY^q|d{Iaw4BrKyib)DoI*tre?gl1{ z0xLSE>ZGR>egLblcLpQ*xua|uJxpBz7SI$)qYA+efX(-_SdR-P&`ac>dyXf=ERr5S>;tClIbjM5>^h_3@&*tub^R0k>4Xp2>BFI!=F)7c@w zDylh0O(PWl7RJK>LT02CAj08M1l2)R_cT53RV_6`{CfB3CO=1F#dAd_S6*f;i(*|B z>$>8&ENE&Tw5b-XC|K8m)(fV2##|>W&{`|z-5InOw6$TkE5Yzc1k8(8|GBUrQ7Kl7 zN4;_ZL4!~=Le%QXJ@qB=_5q{k(mcyU7a5jq!PD z{As}>Ijr=kUmuT+KRcm_Ob&#oEG9s(XQg*Hy+9?NLm)s7E0RtE&S=BmxvoMFwuFo- z%*VU|02P6SeK*#tkYP;8|5!IhU2zF+DI@Pp`XQjSxmzK3c*I!;(9{eRy%8Lfeh^Vc z)uWu`_r@BGuV89rmVgSSa zX<*5{|kl?B~1r;G;jjV#Aj9@tsdSg-L6kZv~|N@*_kr;#5M zy7diY^=IOCtAdY**3hb)!bi2v-L<>Z!;gy^+(x}f`j~eqI*NDbKn{AJc zF-%jVo-1%t96XkesV@WG*{n^37Py>qS-e5(#WEXI&^jA|xHIiEUgktDhoP6JQihPH zukb2g{+3t2w!rK(q>`5j9C%KBjc`&Pl%ahiKhg9Uau2uf0-zSooQGJTor+f~3RQ|l zmuS9Wv?PxIsvjKXGd!Q!0BMJm3~%aW*ul{Vphp1V1i(YlvwKU233LkqvzFUZlAvf* z5SU`kRG;iy9;`Oz6`H`qreMKag3`6Gn0061{+y2sH zWUH5ZXiPoxyh%qnCw0kS&(};J@%=Ufjcg1Q;ut~G z#=bR>6@E5Y+h2`-$QSHAgAf?LXt~0GF^L4v+^Y@!B=M!xNy&YUp1|Avw(*lw(65}M z=2UOA+aLeF zxJNN&h@i)Dt%8nAK39kL#F-}#<$G$`j0YgQP993&H8QM`Z{**K8?#KIx~Y~=&hd24 zROFnBxo&0q{e%bCJ>ba;1T^TM(l*DL^Ku|%Y63>GQ$NGj64dt+#)E1#+6d$J_uUIiTfAIp<_{=eaqKR`I2Yc-^2Om zW{3O^wiM^h{yXIX95=_a{r%)1z+?|)y`^jC@5XzQ66_2*mP3JR4I0k(`TF{z^x-od zKBN4L&te`Dd%iI?r~&#?CZlTgntzfs#P5%UYRaCqrR90qj(1o?PNh4}knP%?f^Wb1 zIxpOSb5EuBzvLMQ;^b|3m7cseX=Qr}Uw<>UiAPJULp;w@4&ogy00e?s6{U1Qy4MsM zj6|e^%{tJar4Uc`xyIWyK+qmB(G6?J^UuE(c5BKt&bo1q zJw0M1>w$0|wn}k0v|+fu3S4@@olh04!6O!?2qGssl45$|vQH+cM{R5TeFMvUFMSLu zur$M=0fUoMQ|sobF#Sx6q8EkunJ@#K8y`;itv$!jeqa#NY4VQ^U)!wvfMbSdj=0C; zD-p%Yfv6csoCd%gEf7f6;6EcQVj)~!RZ<7HqVE2=*Gy9>UYjOcLH7=b_LNUD)~`Ip z4a6E-Sz<==(EwY}F*>-gxk4NXP>StRM9K{7X&3}q{2R%?>>i5&wL7W zz`Pbi$fs@8karJzmJz7s@Aj@?RX6+E3ac$4Bi|1I6=RI<6TVbpA+EMngZHNZQ1>P< z$DW0}&=FNo$ROOysz}Dqa9-7hCPp02c4FP46NryT0q95+gGF!LAc4d*JJgDxo*epd zZ-jg4`><)n8$vWeJ+I#Bk>VI^{ZFq`1I+2)ZoHRA)yEJ_#BRFzJL1t3A}CrSjqB#| zTxWha(=5PYWWIEcko#)GOyCngD1{CUb)@Cdn`rls#b1+Q*+!TGAfR~6yQrw-yo@%0 zqE;B!Qr^^+E=vn(EF6alX$llt_7R24qS!Sol0wjMY>P$56yR{RVy-i$d56n~4>92p z^MV{3t}ZS^iM1{_4O3Nr$4Czaod!8YC}tGy0&FOpA-h~Qt67kI=q7L5sGtat1-arZ z+A~bB49XwDky5xdj1ge*3^yvoxf{Wq+9112KkA70FiM?PUPEY zgdm8vD*Pw+qM95T3TBR-PVx-P=Go)e#=qM*ZH&c%GYkFkJT(ap0cGSVSXja#XtUk z{XP8BPyc=3yMGt}aAy|0`>Q{QH^1i_@y<8B3E%S_--+IVwJrGM$9@f;{lnkHqfb7C zzwpEVuFa>piXcPra%ESkZq6E?b9WrVE?DRdC>2#L1*sLFs(?|FBaw5z$gfD$lotRT z1S^>LXEk#AaDI$NyL%laX!>UP#bd%ki6)yf!eo@SSrF2&3XK!lG0f;{!#hK~4Kk2S zDdtQ$=D-?lKqGbrNJ~l6TLVI#mF^3(_Xfg7GXZnMA9@*kcYM;}W-=3>0jivoZL&gJ@hc`?bcpE4p<_af4@!Uj&9L zx2cP#`0kV^+Zi9|XiU$6;rCIw>b)6F`R&#mL!+L@(mU2=wHC{5g`nfGUIFchNgLL~ z(You@imA@VhwIobdPbR6tXSM|P*F;EhmyoT6xS=H8q;L-?^H^ziLY-g-+-yoAW0+T zAUjTWEct*8XT#15vCdTMhUOdfHBcw$9>&b|e=NkiTP{TtV z@RU@?LxFcX)fDHqxfZ9`epEL`XHblo`SHS=1=b}nzi7*CO-T9)?}{2)F|B@W&21S^ zjOV`pW6Cw#9hxh89p1)WIm5PBh36arY`bTI2s-oqzvH*K3P_Ibo(`Y$J$G!-n0^)&+evPXrI~ zfqUkFjcqQe5K4($Zylevd8UK) z0uSl5b*ZjcgaRG+`@%a@EW>AiqVdIn$0^f{6%p&+l}dchk47q5^=<9A`Ihz*9w_oK z2Y%|+sS{A!XO-4#8NiU|e_C!VX<8wrL??hOPw4e&29uu^f-fjqcmhzW*=8AOu(pm; zCuo_lwg&Wu^W7QRvO>EtJUDktr8}KcQNQk<3AbJ z*63WpTyneI$Ktn)08QdO5|7*%36(1r1Z2!U4wK~gKu-?0V*sHvwD?|xtHd5;2idAn}gk?^nNOM1*O1J|C&x z=K1D}Jch~{u>wDf6i{4GN8qI#v(KM(U`&pXUUgVof{ksMe2!@v_K%8k^3N(Ms#Cu^4Ff;U5U*tRw;*A6->*?|1 z{5q&4uqGS8x^WVz$f1l0BNyC|;^)vJs9J(@@b8IznC1qaZO13%os75~(_lq}V==k?))5a@@pz9EPz^-~TPI;Cy(igrVf7=oSp$84#1eJC!i)M8>dM zNU582lt{4|aFDicGP94LDoQkF2kACVSjXpn3j>I6xK7{h10MX z3i1Cus!B2Jc`;tb&oFfA8}|{Jq8HeKbrMhNhpF1SYqhA93Sg3IO+Y~2N?b63Q4kPo zxX@O^D%~T%*4{Dic9^FbRRsHak0RFeplgRzt7BDbHQXd-Q?=XR9E_1ggAsqDS6S-$mS%f)Z1Yj%T4B%+;OCgMYY`-H ze&^~&a7Ao*y(B&Yu?nNcTpyq#)0wjd4Prwd9qzG4{fO%_8P zn2-%N*BVGcpHJG(VKjn>bCq$t)Exse@;+pw)po?&gLTuDjD&z8^WQ1ttJf+TjZz}j z($=K7w*}4+Zm_(&IbS4Oz{a_{CR{Yuo<({`Fes9W8bd;BsaCCj$XB;><_sqokz|^j zS|PP*wh-c}7VN5l^sWW9OlCk?S3m?;>k)@`!0l;5oo1M^$lg?|wFs1fr$h`aQ<(*Q_&IoXqZU~ z8q`AfN2kY-7BN0o1UMcKxOM&rzWaxN46i&m;7xCR8+H}={0lGO|M?St3%~r)U&UuW z`Eh*uQ=h_*{0Dytb+^ZxzUrIsq3{07_|P|fGtNrIs*J9)bqE@oB|0BiR7DRXr$?=0 z5{rWAF87O)E=F0IYwcTP&u4LZXvnv?Q^^X3R_LlhM|CW^FQyo>O}c3T8ghelvAswe z8U_nvc_;FR`|Ao|<^fn^d%+*+62aAXXd+hM2JU7mH1YCF$lrJ_MY>VoqE6V8J&AB%c zgUhL?B?FT^-3^(HAPgg`q*Ba+pH}OGe3#LgJ)wH6z46MCe-Vd<&M_KY24oJHgHzO< zold{w^NRpVWtMx?&GC!gG0hcas(`Y2L&1a@wNxx!v8>$-pcZpl0zgyjb``CaNX@OV zx-V4}YtvjGNel=#_8P`0fsLXjA=GMG0p1RqTf#!{3NxmTbgi+Uwsu(`1x|<7>bUs# z2fmqN=g220W&2h}C9gT< zjl(!p!2}d+W+(fzY-KTto-#vYfVcRXQ9-qN`Pt#+%n#|3! z=j-G`y_Pu~tjU8UI@C${E15=~Jc?s7rxN$s`G?aL9ZJ;OM}2nWW1>@Z#{vK;W2DJV zvJ8GETt16A-c8n8#){z%09xF^w;KJRZ0W^E6tZrNkSk`m;tNNf&&ZxoU-Y^@_my0) zDFVh8F$!oKl4reX)a}eM_VWi)vo zW56!QhTQT~slPR#goiHHWV=?|^|NRJQ{e3onet!^eIx8`c@mi4s9=m21x$x9)HmT6 zsLa{sZ$t5Jv>bc5L4g%WEJOaU5=VL2|R;bHAJ`;Vj(@|}5_qZUemM1+h*UK!KgPZNq- zcdn^U-kr?Y#PM(d+zYg5!{y-$r3&U*aCTNuCXH>abpoojeih%lTBq2CQVOd7TWW(JsMyy{QjICSnJM2p^=aUfr4I>|vd0#75QI}DucIJg5a-YipI>u*>w6y(q3!GWl zkEhTgstQUK1I&GEgdAx;#-+p0a+6>_IZvGi@Ga?3DW{*-hq)2@Hvhr68T5Hlr-C#W z7--lRxnXV8l|Qk2lNVYpF*zVxBhsFka6YzolWMb3L?nkK%Ftza8b{Is*OD|*w0Js| z#`A1V8rY&S6lxz8*A1$hs3(TmT8ivwOgQD$IhG9&=O<-cKN}lC#8xrPb02gb{0MQM z>hM0m(o>!H(dbEDOVoSE zJXbt==P}%R4M{1g1G|J#3o^ZgEwKK?Y`^$p(xQQ*Dr{W{!z`dPg4 z;umrIY(`sGbWdHjG4~uZX^}+|#k(Ad8J#QF$=9fgxFLCqc{Xf#bNI2@yLuAJQ@G+6Ae}5dx?*T3AS~5fb3F9yufo#83(xc za-{Linhl1bVQ5)zVpywzkK5E0+dJ|xf!zQzCTki`Se3R!MDOs_Slc{DK#?K zSdx)Fb0)`@fP=h zqFPgt-h5AdY_SWr-U^@>m=k~)ADa6)7@$J-_&V4#S-WYQ0y3U^@`jt}IPkt3>u5T{ zKnHxN2qKzFH#l{~0^=CQ&#zynf1{2DtMYJ=X2gE^9(7} zlL!-w^0;B# z96@|Txy8AvyJw4T_J9+a1g3R#{!J_^$J3OyvPw2%vS+bbPrpuBe~Rn1MZkcTZhEWI z19OegyO^b_R#)_B*H;wjSXaQpnpT4llE-M=aDX0g*&GyL>(L>Q1K^=Z*7=~rJ#GQS zlL^_)C2>g*p(gY3dNbxlaSyR?uth0QITrvn7j+5hvN>|XH?5HcP+hGhH%*T~2*?f4 zfJa%l*M^^l)xIQy<>3rMZOyFZa>}&+lzV>iJk^+4jFAe}hRJZZ$$%MdT4>~9I2b_X zkQ2VyvN#&WP65ev&|;T=qFitFJxwau82pCo+FGf?I(-NfEIMf?f^~pY>B$))wTf6M zp_+$DZgj$ym#)n`nrgtLPFB#Y zYo>5WncQlwm})_v3hI7`QYY+Z;7le|1+*Pe;h}79WMH1|@pv##6QgV#pqO*3I>7Xf zNRqp=4YPEn7nXMQ^I(j_LM_#A+|q#ib{y|IMBsVHHgcr<`bB3VCC@hQBoh9~T<;Lx z{NDhQVC%s+xxg`90hyv+Q+QL|6UE|joJ*wS0D)LWqf|~;U{QTmw*m^!>t_h2dl84{ z*b+O9NVlA0U#|jzmcc{i=ZOZ6m_OwJu%&hMh z)P`}(3%M~0id!aeB78ri#kSYjD8};zG-zz4L~uGEfAI%f)MiCm#O?2;z}t9_@{oKX zjUichGYfih&0;Ma&*?Ctl)1USCxHzCG7{Q0jNNv4u6pl?u1D(rbCImNpc)2((GV%( zwNxnT)fJ8+D4kIe)*b2Sdskg4EF$4_r))S?tnD7fet(Wv9$euc{>1+oAN{$1g4f;s zQ7C{Xo_Gcy{Qe)qbB~|l8$S3L{`~j-2$l}K{Nfkz2fzLcc=ny zN5#%YG{WdQoMI9c=NmFYJtC0B`BJ`y;phfYWd?LR*EMP>kgqw|MxLcHnu*b!G^*Gx zZX;zhes(WyA80Ri0H-q+7-c$jgLvUY?cL|gFXd$H`G(s_QllYhR6dgATsd$+AL)&9 zf)R%G5F?;4@B!F#Ut_cVw>&!VB;s`T*hr|jz%Xmoco@WU&5U@ zLDL?3!blooNjUG-{B9VLVu=}bKJ5P~j>?;r5*uSftkf~>O{04sHvyl8eK0=aY~6rU=tT1!lDg+1tG%nZ{aN z$J)6@dIR14X|LB50mCAlv`E{)>~ZOR85Z9OsC8px1&pmwmsw`q;C%oEPD`eZ0eA%R z9FNJ#L8h>j29;#o#stN{eqtf#7PLAmO2uHw>+yyZL_N}4Eog&YF{XLs*eDo`fZUQ? zNi57oo-p#TEG+38EN(G(!BC29nBE8s?fY9sGe#1eT4Tq9d)-pJ^?1d7uDlz2c2938 zFCFMDqd)kc4hJLzC_+FJEI`Kfixok91i&JiEDVie;1rmQiYYxY-14->>NQ}so&WXs z53A*CDg%?XeX3Q``vf@Q^+<;pbJN4ign|;qGIN}{^h2&SfrqNEyFZta0Rs0XyJuA~ zgj8k-Z?zstb~d2q{e?w~l`7CuotdtfYQ-diT{W6*tz&HfRIpqfaJ)L8)*Yt0gSLiJ z3g-P8s+i$&@(36aD&OL@Kzt?5Hs`c$5RwYww!;_!CFe?bo0}7bD?Os9axKO4l0kzQ zJlcYwBaJ3dME16T)(H7kF*w^M{DnB%0rEMPgAv8FzO(_Y(R~T zOkF;(;Ga5Zg8-`v4u=b@7x!^~`wm`t2>kfJ_wV6<_8|lCj|ifW3;uHvo)wqf zw%G9mPT#tWNc;^hLus%h&yVPWaM+WEk~gFRmg^d{2?^PpZKmzANX?wwDC>is_&lY@ zGRJ|<`vX*u|o|iGRoWc+qn~ML|vHggPygffh0$+dFYQQ;2GUxM>hV)b*nxMB^*# zn!$PhNSPx~%SHzI8PimWi6S~romYZ<*q6gqC3YfWlnGdT)%jy7Ruq)ADoYW&zbyb1 z%W=h2fT<{sOGAg6VYzkVb4>Y0gH*x16YM6h6*$kB_jAapI+>iU(*!9-gH{6um_;08 zdn80)&_T}l{@ zJj?@j)xdJ20e0lOV>ce2qpmdglP}mDj3!$A{ZDn>aGSz3w(i6tuFo`e=h6u;xyA#= z&w+@hW)%O1(`xdnQ+-OqSfX)nv^SRF+@Bb1#zQ@7puRkB?{Y0bz`m9s!8GF<1ZsnAq@d+1q~H9zB(QfSPdQ&dtWz$XlGbz zf$_RdUgET@$$QcW#zoJa81Yr_K#N1vT}OjQD5k-NGJ(7>)|>n$P{UV#y`~75@K_=R zq<@lw+jvaiAjBd7Ob{UQ*a1Ypa~7Xd7=!KV?*p6(XE=B7ZaFTjoIXUqAi+x7YcxQ! z5hL@d2g8pfi6qSvP$KSwkCT0Poi@nkC(l$;FdJFnNuLQmqYjL4o#; zsoELPUZ5+WYsXpz9TliMG^{ur8>Ce9*0COrsAWPaGayS)L05VmOL!U;in&w=qvP6> zd9qH(uo>gl=s*XKSd$40H!D+)VCRzBJcSdGiYLF51ZB0W?CsqJS*AY4J4h!ZjhzCh zF^AO!1-oTz3JLc5{q@RvgVHc z+fckqOcp&;u(OLriWNi{>bPA>BMNhcX{cpQ1&vd2OX~5#g;)g9&HOD_VYG?DDysUK^~Bi zeG%B|N>18z^BH+g9NL_upDCltHXA;I(4)oH@nDKC()g~_HFvV2xB+#`BWx{37^V@0!oA~jW4*ybqk-+5)=K=g-4~8`jBugRAzlOG0W+-e z{HHLncbwohVa$YvvI&>%q!lA4f(&t4(t_&7xzU5J0fKYRamI$ZsjAsH89C~A(^Jbc zDfyuMo8u>o*vh@*^L6+hKj*W=BeuA1ojA{VO6XE0*OkxZu^_fhkz>(B5DbQ13~TMi zMh}lk41_^>%e}m=L=^vAoUTYNW{eT7ftiapmW#sZ(Lv7nRyYllIyMqDXm-FH0N7@i zorDbAN)GXa9!5tL=c^(A87*@iZzT?u{O)kBvK}AtQAH^Qt&JGn+XoM0FuCl;CJR-> z!iY#HL>meeQw8cIn5JsjN(Ae2fHtdpS7t$-3)*GJt@B4vy}niTlxi!SDuF$ByB)N3 ztZfDM742wLUM7o9t175PJ@PB}S%AR)#GBPqMKkqij4a{5j_KG9DzL49k#!?oIw-t$ ze(dKgIT6sIo1vn?4J#4VZtJM8;@=-JHs`m&O7VO0z7zI2T*)i9vT(RV^%`w=K^W&~ z=H3XzVLaEKbu#|VP~fsY?it1{+vkiwvpXPpg^~f2rvO9xb4rYyAGc2c79ZELdF@FI zh^<49`1n|B8boXi&L0&}Y4P=Jd9K@il9AsTzapONG8l&)Co04vY%Q<=pv;`2Lh_~=)1y`~5l z+uY2H=Ril{$}105L8+G8AB8{7FP%&n2!KB-<7C>M3`vrq8j)-nI~TZXZbnK6)*wlS zzp=_nE_{bZib+;UM}RH@AS=}Al?sT@B7#L60GAUb#6rwP1naUuo8_HCw~Q$6E#>5I zc?saHuygF=znteyKgXJ1V_YM!BS65Gh(WJ?xaBsW^BQQu_}RE$+sSa9!aB}pfvH!% zqI~8+dz=01eOLoKw5P_E3~jz?4aRFU&d@TQ7XPt37T|5zoRP%Dd|br=+E`4QB%_i^ zdR$)&bz_Ddh&e001cOo|&d6Ht(Fuv~HeJVBOP65@)uYiA9lZeSx{1viy^wfK5f_jY$>@yXGkrJL_?aGg2psP5%3qYAwb z)`i4)s}T_?)##LGVtgz?FvJZRH>`6;4{>oEOv1rW8I?I5DaHO?#;6W2h+V|K$4DB` zyD9-P1F8|Eh1?-+`MVjt$pnLueGEW04b&3ky%F#?07n%>?HvM(;OiUu;4=b(*~$w% zO3}_>5s!QbTC;bK#cug5Mg&@ET8&iN&0fSh+nCm#oibDvtu?Iciq%8#p^Dy`8=vzz zj567(N3n1bts-b1?O5=oFMb}o3Hb0o{}=ezzxrX^I@{y+Q*XojKJ-1<3-HeOybpID zeHi$KWm5!LF*F5|8stf z?j-=tdE3(}#>iKmo9oyFo6m2$(x^n`>r}be{;cCU-NNJ;GsW2mVv9d|G%j;b`C0tu z`_20{3LtThBG#-x1|!#XzHF{m|p(s&2rD=tJKh^?%)~%nmJ9mx1vH9L;bII5=e7aF@p9tsclt z#)LAgqd2x|5Om5_?ps9H(vfB<3$>Urt2K)t>8;_|R!o!0~iswfpG;4khG9cELYcQ;3 zIxy|;y;~*&d1!0Kla*r^cJ9P5`W(|u`r%E6jx8ySvhw6J9Wm3ZKb!J%qZ9F8wI%{# zO!oonNP{;#cjPhg`*1AN@p?0l9^j|?&(^~XWCKpLbph)ymP`momd9HtEg6^(po zGylXp1K_gSMDgoQd&noJK1a+0L5sthLlDOe&h#sMkvuu5TiPKmHNp!>Tq5X*M_h{NcG zh(yq}K(uEVu-9p@P*u1`%jXFrD9fuhPq1jE#2o+x!pdh9$-ry@F-vILy{y48&65#wk6Y>nP!Zuj0}ZFI!o&i z2g!W^I(+)6bvpNV48^~J;Sc+NjTWwrxoj0d&?|Xr@g`8RQI5|~#W8^(-$6kQDnAZ* zLdB#IAA}m;O?l)(!ophnvKmM%o>o&7=nYe?SR9BH54KQIOm%hxhMj?Cq>Nf8 zw05-r3UGvCSsISVE1b<8^E^en#%Y?cYQtPCbqQ!_9_`ZyB~>KBL9Dz2Y3#@|YQ+a7 zJXUc#)9_phjv0yx;zuX$P3os_seWSyp%o5`8KI36UB zs7@!W55n~z!yf>QFv?Cq$i_4sR&o!3MlB#{ERmlH;1YC666HCA5NP|mY3T4asMhXM zpgIje*oB}+<5)Ky7w$!&?F1PDRuhbc?VN{`cN>s1$61f1EnE_N|x2YDFZ#4_qA=_h1f6M@VMf84hIf2YLJ{o6Wkhj;(jHF zYoZn|?{n#-snPim0N2hIIB#u(0+wqYO6!p76=x%ipPUqYEG|DsLJnS5tg}eZ=K(%6!JYnqE07w+()~-M`P_G@hed`RbJa~wo`n!J{ANlZ4;Z1LN5(|LG-|!B6 z?~nb*c`>%aEv&;h*k!WZ#J|MuTtx0~>hkGuzOdGlLPi{iNIW_&j}Dr~lP z-{Rr*lhW{F3QZmOcP?xi$hkb5br*@qK1+4(;A$5UkK!G0PV5EGnnydr1LB617~%uc z#HsNC%35Hyi|S}xXbf<;LB*PBI&Po71~QF}baTE~Dt_!JJHgn!j(f=GR5w7Db05hn z#4`hd{8)xE14ar9Sgs_T3ornk1xE!UE%2AfSZl!6iUt9zdF4D6^qw*rP$8P#X5y?D z${BU~_BG-n52m*JjBJN5<$rC8mgcz!yWSqqBa zRW-*hVKe2qh@v->RS20NV3A#5s4oM}=x_CBNYW+5Qjxmz;>|)C0}Nw6@jdxbcm8+c zb4a-irzKU$R8Qzgw(y7R*DXb<5VljkR0Y;L@Y}EKdQA~9BC_L%Z&W6SD}}dhP%Q-o zlM9e$mNqY)AbSiKk92{_e)Vs zBH@_~LGM856m({8{`hyjwr(n;M+$N8NXw(=G4lF-k6oX$Jtzd5e7~=)0FZud-$n(X z!+@Q@0~^FVR*73A_rHi2)H)GJ@JJ{MUl%x&GpxB*it_;|(lF{q)l#fYViyCh)$)l; zwYZVFPADQ+j|=v@8B!}+Um<-(>mAd?E?PVb9n)N(rJ%JH0x?k3J1StFBG~z4&h-Et zef>Qo_r`13CqFWz8BP&`P&yzjI-s*Y1%eJ`P+DDSN77M29Rv#;v<$|YB3=(lp=xy} zBH98#?`AaQ-%RLiX(7NUxHmjW3VNxty&n+980NqhEA+_oY*9BX>F8jU0E{83r0Hrc zG|@e@+am>|u9MU8DA{tXZb+fw1pFCcw9<$iF+<82Lah*MttpbxDUlm&ge zC9lv(Nka~t7dxo*v9qwSDxj^x3aTUP|M(hrhO>4D1U2Uv6|cGgT3wM*pm-5mdN`do zkS5hF#p3S+#O+_kd4iuHm)7`zL?K%H8@>D~{{Zm_j}|Q*jfS$@pV1z`h93kmO4mM> zQgNDf1&iMfmwi0|KacB z^5Ox$_Cw!>cfI>PX#I$_w~z^RcG!IQv#rA<1y$g{F>4ZZXBwg`%9#oakzGbmrA?QB z*q*~k9NozBQ;%wb`Y~E0@k*vvr{^B5?J$Bz$dE3UbWDy(k1c7-#>A*gIKR>CK0#q5 zF7vxu#}=bBRF5tsZ_OGtvBj1$&Ny{(8S0>yN&_P0hm>dkC1~6X>}K#Rk~||Z8#l%IsVbn= z$B)2!QFA053pzxqBli%-cStMze7vY!MTbfSqP7cv_A^YQco@6HYEp?uG0}KY#5!hH zQHZ94r1!pYJg9h=BsG3L)oKRjI-?Y8or|tGULLWo4acL&m0GRtRaeEj94)dP@cNEM zhfO=$x}ds4QKQZWWwC&%wv@}cA6ZvwG;&TwJe`i1y9fRo_j0VSa{aQsFQ*;e6mbq( z)FY!TtDZs&lbZrp*8PdY>(Umy-RYZj#=z9QIA2Ykl@bmZo$ja4KK(g)SDycLe%L%! zEs46*SyOI!#>u#If5ZW}#$<{Azg(10V89!GSHi9V7mRvC{1;eRoPNcN%@0vSLK@c$ zaB!Wdhb6=fmSA0~?cB3QYZ=a)!i+42)8kws%x43SbY3EZgYpDZ#^0+uw>{O+WTo9( zhOR~yMK{atjtlEL1UOn6*&uAn=0oD~*TE}fMWp-_VtPQsd zFzceQm*)*d_L6sd;4_MYCrs`g#)=|0vp0zm`*3t9Ebt{`Qm}}(g6=2#0 zsL+eyOrC-|0I-Cx3dTxc4{y&`6zJ|z4kg!T9BJ9W?IKJY-RtH{4qe%*omiHbzBHSYN` z5tz{=S&|u%jgJ?p28KCa!C;u-85K7^yI)*2^Rg8iHt6`oFbyQ`vpwJdWGEczK(a{O zY!O^sUf{9EpT@uc*ZxOXjticC z-LrV~4EXtv{yhHE|NY-YSs&ou=Rb`%KJ$7k0G@vCIlSkCe-4j5^?E$}`loSrc8>LM z8N8&rr@c*%AG$!?fszWWnJbw(62-Vlz(MMosY!)VXi0L{q|YF?<1+!oYt!U;lBDP0 zM>W5I?4(9T4FC!i-Vh}@f;@XJ9|Y;pAg!>#4CP4Z6Oz1-LyOkkG?tFakUexv%re?; zpkZ%>9YO0pUm9j;j1`fHPyz6&9%|MO0&INdoS~QB-%)%n9k2))KxFbde&i(y@Pcxbdrn56#9S%5LU7|PZvf6cpXan34Rz=AGxM7VR)YtP?eq4DoI zcz2_MLc)q$+f8525M%nQ-yi9yey)P%6DuZWB&{Y7WqJ9}y(d$coujEa4`~77 zdQj$pX&hzNkvymm%Uk0ogwB@a3cD>8U__#V=-gSD}H!F3Dluo^cW(Cc&9T6A&a zWkVqN_ciK0>jcE!Z{I(9*8pTa16R0=c5@Ef@pE3L6eg&<&QR;-0B`3eqxatb+d$hB zM!KQfljp^15KuW|RWHsKYs2d2YMyCsd4i3hHjVFnDn~;^!q)GXMuA};N=ar*`l;a_ zwFmL~zRzO0GzN0$Z7_U=_I0hN~n%6kr;8(nu3t>?PLQy$e?He@nv~ z*(GGM>LftJD@SEKz`XZn+#2L@><^;@HWW3`nR%Zwe4g|qg|ve~IhXW`#LLWjAHy!) z1Q#afQ9Wn^0uM>&Lmb45qD=YFpgG578CK~o=h=*9DOQyJO zuZ{2(iTVljzMmT96d8rHVN2q&2N?3ZH;ar@NtOlxZdBISvb8nEC5qs4eZv4}ijVO# zQ%rhSEN!(Gt*!ZJjbE(Y_(NCgE<&~(hH4R@AnIe$V~h^eGU0ew@X1gAF~0cxALBEh z`UFY=e&eIRf_tC(O+5XEH{iYB{C)V*zxv;Y0C@I|Z^ik3kKg&tkK$+l+n+`69dn%x z2+Kg21e~N1t~s2y4w0ba*)v->ErI#>ZDiP17Hte~o4py%AOT*`?TK84E0>J^isufp zcEAjfF`5PpyzyOsHQ9SAM*-2|9ZI}@9$zy$Q9NQUbev-# z>}S3i8=6x9eX{PGRo&P>c&|H$m(R}PWfJ^KLh%8@y+p4B2HqKl`tFam->sx-OJ@Ul z93-7xz=rojEYi}9_Z|i2od#JOEFxV7=HFe(wnDhvH+u)8F@&^nQlBlIHK)AI`9|P# z8oxEVJXzfr!%Ef>vZ6I327x&|YMmgpps4_LLY*em;`3?-9IloFWUAQh&!QxItsXsE z3QFA>4=Ejxh9V8rekeak2Lhnfg55NE7nl(%r#$3T8I>|XPfr)$o@+ZB>D;0u5%K6l zk_S@8Wg`H}UbX0+$=0%U#k%&;&2$jzEZ2~9pZw$|U1hw~X`-uFdn66P3|3$6dNn;K ze)o0Cq^cW6Fz~PIMwYA>dee8sW&SwNxc5((_f2CB1EY&6<0>b3VDmG0hhd`NKcmAr}el0R=44K@P(1X=eQKHcF10r#sTdaL_y{j=@GCM>tH_TJ3L)a(hGsu=+f@Q<5iaL#__o_$AXq*lw8)#@QR)fFe76RZ~}~;fVds5k?<9u zEuEe;=H2^|89?rKaY_-3gz?%WQVZabD18Lh01qTsi>NCwO^T@&tQ{z5uy%=iti5Ad z7VOW=V5&`Uc77YZuju^I~Hd%evT0YC&raHI#*7q1Vpndbi@Rqp>vCB!RGa z^pHir`QIhI``R@TW2|d22JV2&Kv*%Nl0NL2AVMmAo4afM0)h8_PGGkY0KV=#-vTfM zVk;y)VhQd+lzyTxb6gJMM@5ZCF9=ASw@3&=3T%RNEonrstOEa^kO1rhpvGv zQXRzce0L$&-9r+kFMYT@fdYIT21RBR&iOYkr3_QmjiKLu=$o}5IYsd{54n$Gx2|z* zl@0`b*q_ZWN#30@BS$&zfw4}b-OPq0?P&6oVaRb-{cMlh3b+@)lNQrh8iWWlQd%0V z8z04ES7Hs+6>J*VyuD*+N*VbC&?}tGhlyYj@#Wy6lmd2jka#9}oz-xI0~cZk{fUHJ(J10Wwq@ZJaBK_Jkb*NxvF zcpuC=t&~qrvtrCF&Rp>bjldy;;hzK1ICJ83rQ4cY92@5(8t2v`=!)Z;U?O1JPVWF? zc@sWJM&t-UFes=N0f?UO7K@aiDX3K6OD&GC@;*Cuo=7Ln*m5`eN`5S$@i9`3gwb*K zd^^7-YQhAcmKJiNjzrvXz(}kE8n0v`xe-9SGTL^Oypc5E}-cLp3-ft36+EWM*QkCC-^)Z*z>j*mwD#g00a z*nECCI{f|D^~G(vVswHO+<4t&jF6Ler4h>>q|W2QPD+{}t_zyMFrOUftLZGXL2dav z|3;bHH{ai^hjV9*fBlS&@Al6}r{%^l0I@UYol1M};pB<+7{&_#O))9m?=teYP2!`leMH)lNFzFN*8TNuiFD8Sfd*)1mqWM`V&fgi;2e6Kx z!uX$535-LY7e;ERrQ1^%ErwreDWRL?-XVR=P?1{RYv56N7-aGhk0ldZ)M;GyYUSZ8ds1}9T<5CN+-5CShp>jX;S zJkHnOqQ=}h!8!nR%Rf`;(CYU^C=~PVo!Hbq^wL6L?{alTXv1hIaFEBjN*1>|waDGH z_T#m&%DV8+zgZ=D`yN9&eV^gpD&FgRLl5otB}s^*<(t6m)Ea&|zWA(YTJs&$l;IwQ zRpYtNn9FA0*Z@{QslUC7Ufa|4OlJA&>v%fB{5}CT*(HDTkw|xdPexTDXPdM}@BxSe ze20M+mya+Ma0cPoLF`+0%@~XaFuJp+6;CNJa2YiLpdKM%@2XXTcnjITOB4lwbwytq zfZ{pL6OP9fttrqI=ldD^Y9hK!6>GP4j8icqnlUvAz$7r?oE^yE9@gB80I6^rxhnzG zaMe=@l5XxocmM1%KbC#KgF9DUMLXWn8 z*9@)`suWDsjTEIA4-w}TQlf3Dh}U3&fW<|l){z3mX~uxNjiIkA&gL2K`sxqj&NFYq zox68%I0E1Co!^J2-~Mj=+&}$q@c;P-{{{Zbzx!XB0p?SGh~v`m{y+2Q@J-+RO@LSg z4p*QTlOLR3bouflFal=V!xC#m;AKG4Kxz?zuo#LNU!C>};0Dn`;V4a$_zL+Xvc(QrrSJ?8loKc7r*w_*BcozHdtfx!?}CC+lKBzny{ zRW1uoVKQ+^rsvR@K@ahGzk(iHaYK-eSE6n~C?BPvw=w{F3F8g8XF}tO^L%!kQKyi= zR%t-Dc??l4FauWbXcpz|Te`9}1lY}lk%mFRQD?^YBG%2Fx3?rbud!8oj_OnF^!LVbs!G@eC z7C`KehErjTn8`~VH~8p!cdRx#dAI3ir;h*AsGaf2G%N`+aE&b6C7SWsle&1P5rLzT z=XCra@AWa#h)vZ^_AUxz!#V zB4w0w;a(ZNh2hoZl{oE+7q_A;el;CifQ_T(E4^M@1PsWyd~zq(c0tW5Rm250I%=(0 z=#dfgm?4PMJ@Fz~eIrWUT1Ghn3i|QA1X0Xk+gcw>5G318k@3a2J2zPefa}6lGW5vA zo!1SBC>Q!vROC8%b@QpTn9TPSqxkvE(`|NF=oZn|#^)IIlqEHdOEj!~@% zkZrt0Ige`_k!z=E0MlVye2YRi-yfBPO(YLNqPll_j7*3xBSMO|Yk?bRg~EU6e8FeQ z_4PYl*Uj@c>*0W|QC zOI24k4M0Zy6^uZn49_#b-Ft&-@jdZKl42{a^hiVET#v=P?NNgl%STV6ai_r;FyLQr zD1u28tkzcopg~cGbTk4Aqbkax05MdU{oYB$b74(LsspciS5ejq8W@7F@S9HK2FL_7 zFp1M%O1v!?DC_`L2w5$)j671fen=AUuKm%&+jVsesIk`RWifO#0(3=>dON<5wnn0m zUi|FP7)RrhxGJH5ENnmJv!^X{`jb#95TaT2227ys7CfqUw zW@z8s6)cp=h&&)=d<)d1U}wLoYHL!{YbheQy1c*>uX_vr?6-awKKARsj5~Lqz+-#h zAN=$`#!vj`{|R3I*e#TYFJn4Bz(WO|ee=8U-Vc2%o_X`z@UC~i8#}33P%Vs}wCoj& zo7b8lt!P&VUt6V{hCz3kB%KD0Qwcx0B!TGWk2FGr%w~7R5yBdH6@R}K_jl0By$*cf zl7LZT-1UGOcE;Gj&v-nYD^6Rm&}~N9h?)Z2RlrUdLK;?V?F=Z!@7$n)qFIb}h-OGy zWk)we9Vo&PMhFrw#CcCZWB`1CQcPLv+Q3?0fExsO{>2?KQ3uN(3oCxhcNKbl-2kC5 z#dD~yi8$p0Ad!&Etozmx5r*`{cB^F|4yZDo1Aw~HE?fr$uaPvBdXUG9QB=1cHC^N zNSR_6Ew_}*NKA6V4-tRcUZ;^Tucj-xCI?r$VJ3$}9SJS28(;YR)A!|^htoVB>)|_N zO6XSC@Uhe2#Pma7Z1+`x2lg~7XVg_F^VKnWoN<1RY{pW=qHhhhT0|9_-Kf`U%J+;k zCn!ihv(d%qU~xVZV{yJhYE%fKI)Z0^p{Gp7?7Z~1Z zUT?FA=~q$f%`tuPz>C0?8@bKJeQnokihzj?MJ~Wi7QG0Q@{KB1wG}G?os>*NK!OTd zqFMKa;n_Cn=0jk&l_YLa^%hjy1tDQ{?dWI*l;IH{_T|i-EDCI*Lr#EB2#>Uw1KkZw z8pwwu(D?sgm1Lo@`n_2$*Ofp%_ zaQ6uVh;cyT-t@?BFCM6yytm^QYz!Uf4g$%HhC_UMz3N<@p12DPCD$#gx;DQX8Tq&e z3}ddmo%gr3ip@dY|n1odvFm-tvV( zuLLEW7VF4ZB&%6^x+=6aV?ad3wW5>`=?$%|KyR2QYlGNYLtC2{=AC@9-J?KEVH6K@ zES~SJN(((gaH(b*gLzel^%e(aDi&2n5bXv7MKVW)c=sPoChS*N=BV;B?w2vsqQ%m8 zj4=ca7!T;-ag1}=Y1~TBf~bNxnl&%R0>VLq5X-oiG{m4#VCA_UiJiaqaSTAvcEw18 z_WNAD%Dr3{SP3+248k!4T_qoYKR0y&jk+xG@8f8+ww!W(lzYA^q@_+;zn4e9+}CSISC$&rkP%_5&js? zrk}^)jWj4nfl>0y4yzZy$QhEk@n*}7_jNvHa|0W*E<|;+ZpjxF8U2Ewvye?v%>x&l zUpEHGygxys{cLq#w0E?&TCEx{3d~w=B7m|M3;-#`I}&MxI(J67d1_woid(lI!KXj} zIehq^{(ap4%B%$^R76fhV7N1`qCi2|x2w z{}ukl&wd#5{tTrIs34Rw=W&eE^C&^`Qp&TKV`~uc2*Dw;k~?(G`62OtevR^(3RfD! zZ2b*SaD8d`A?PHp;tOaHVIl7-7ITn$-cie7*j4`)fGVDDzjA!3vcS$U1U3#oelJ?0|LdyNvo0Od!tjh?sk@pVD z;HzCd=Hhe~a%HRy2VZ|1o3+dK)KceTjKUGh^v$KdR@;b6!(bkX=1L}nkvV#Dp9Ut7 z;JH1{z$U7GI3F=~U~?X~`-{e#R)<#{h+fCRNa7%pNTlu10Wi{K&ckV9)Ul2X+}YuPo8%J_8y1) zs#t$`>J2!4!}olh@>Q??&e6zm{kg8IL~39f!EU0#@j1j_HyVxxEazYNax(^C#q3+p zHupA9PH&h;?@)vJO)kCg)_N06h@BiHG_7^Fh!}kD?tqRkz%#rB8AGqax-u1;7;v@k3FAiTQd) zaDWVllimvwpcUWsVHXIr2-dZO zdGy^|m|E&U@yHaT@luVEYuQ1iLea3>RkU7R`8K7c^=d|(TK&v*%+riK9}}dnjxXKI z=tC@}*cru`3Ik+5cMklOK}&!~J%bR%=o(2|k_(r$gvdjD z|AVm)9^okLYeq~9Bepr3y(pE=(V$^CRA_>W`HaQ}h1#5ve9ZL%^H#tj2IF1M_X-5) z=Cxq%esNypGu!~!jX?v+!!!I@gCC&)(#`0YEqXcT&|CaG8x6S6CDxfnbe<-Vu0yzJ z1X$(zO|4iK*Sun&EI~-u0jqy8W@Z4}pz5)JOkFnK4#U*)e3gto8F*3pLV9{DL zo*)f4VxQB9mWF%@Wk4i(ZP2%O5-L^DTN?hjbsJ?!hh+$*zeHLMfOHrjJybRifQ6=Q zyu}QJ1OFcRHjtpr>RL2tmq@{+BF$)y*h=M|n_Si+K|Cz34i!k9aC!AI{`ga$z#o6& z6Zrb$1zui(_kZXc@EzaqO?dvH;*UT5J9zQ_1H8EaAN#%E!0&wYm+|Jey%R6K_(eQ; z@X!pwZB3d6qH{vmjw)*2Xb8p>3V6Hpt{Q2umKJDAD5AJL;$NPuP&^_vRtH+t4IOWd zTBMaBJ&sDE(*{!%lr*f8XL|5DCL&ILX@85u32f@Y zkpD=Y=dLushU7p_#?MadD^hk)05PJVxS76{Fd&)I)1CKaLHgub1VV%HVn8CXEowYC z>SXH4IaROX!P;Ol7#)40RovX+kwVFihxJez9y7HuX+8YeW)L`0Dua##&)GAWS{eIK z%!_97N{bsP93OS277R2O8-gtODFEo+-HgRjvsdlbB~>J%iq-o$7X?Z;I<2Lktp}{j zCFW}BtMgn?rU|GsrsA~R8d_^8wHmGxpz935g0^(5>jH&Z8q=|Pk#q5yRLxShoQ~>L zLp}#z=UH&)LgC>O@%?bV?SGS~bHNtYhP8~8xMI}|xQvS0paab&1wm`%U4wImJS3sf zaBjKRHYV=CMjrs-hecr;g_$8?TccNYacnL+*F2KZqx3B5Z#2-c4DdVy}NmPzU=jy3@}s%HGL?aGNZD*CgpYlo(^`d09 z$BYcnac@uObEC23+D%rp%$c6yG0jT*U-nWy#?xaZsYuids&%!t3H#N|AYKoKZBVSI~2ob#OQ~Cse2ulyx;jU@2HzM_ZdI znBCI?P*7#UJe#82wLm>IQ5C53gjxz#KO?){Y>G{vQRf|6yMVh#&=xD)*4)!4IMT91oP0X%?}H zMgd)+Vv0!1n-O&mdPxFNH+IQzo(4Vyj9xHrv0OYaT@h`zX*i?cG{Is(kN**#eBw#;4t(_oz5!qO{oltg{G-2xU;J199X|eVKY{=3+rA#lc*&)IveS~X;4 zemNGgL-W0_a{_Ku7Pz9k`95grcpWM8h; zto#JPl2!+%{;YQC%jgsr^hWW+E|Jd%KaB`T33?{Z z;u8vY3bg6br2u55Nx0D_>vs)L?TsDH^Q=MjI* ziR`4Nev;1oL-gIUp4YEyh8F;sO)Q<4hDE{3i@je*{;Y?#xsTLo4qn=U>3yOS#=vWR z3%X_BXfJTNOAPal7kN%>HjQ;9!Y~dfXwr?x1A$u_kWNkjo&yRG&qBs`&#Zwpjflmu zwcSwme^WE;LEO0Kvd1)wXeR-w#Its?tjQwFMCzcyzmk1Y(n?vjo_T`koaP)S*Obnb z(mjh$gCeocB)rngy>?tBL(QQk`>w-~#j%9gvA8vsuAKO27c{4D)uN#&G!JR6f*XDt|`#JcgK5=};u?eITYw1h z_HryS+rHS%L94XpMWoY%9|l1+24O`%YoW0tLt$ToOD*6o3>0D>WUIB{pBIH*6u_{$ zD|?_s6QoLILEXFF6k`I4jxiLcn+}EI&WrGhh^HHz(Zo&&c=r4`=G@JYvYl{qI$2GU zF|j!VJnI0&6=(O@wg^w}z7#n>h}W)P)5b;eNP~ zZx(G=1#fdD4gLthxWn1#JNslpxvZkJ2zw{pnPMfdO7dP_bCymOaroK&HBv&p{W43rQ1Mz;Hv5&EFKx zjMJ}Lk#BmU)l=w*SGx^iQ?(ZSD*ufm<9G^uB2qM*LIdRFN*N$F3 zDikz=0g_?e<#(Ig%;lB_s~-Thg2^hF)0Eme&%pL*Ewv3ZSii}BvdtP$_t#x#DkLwrv9qTQVl54(u-b+D-!^ zpj|LAaWakCPc7Tfb)fH0(YxTKmmlE+H^86!k^eV-Uo@8QdGWl4=N5*3PG_P5V zB;-vZ5v_;GJqFO0okGvCOk=G#j;lmcKxVIXu1ATRc4J(9`$?DE2Y1^=^h+UsqlhC1UppJlfTH1lOr`^@9$a-ly-u zo-!=tluD$>K^d_~k3Y*glxR(Dfb@92iPwUe9!(LvPmsEahDNbq^4NP4az=9#EKwuJ z>ppC7-xc@!BZ27-_eJzz@DE~|Lc`pnl6{Q{gz2}=ihUm^uU}*}4LixwjZ*nxWnqW$ zQVs(W(PngFLT0A%mp-p5O$I$wT?#6p^>mpP;S<)J z8&9KOQr;U*J2M{gem`-;_KzFyZ60=u?DXh-Pd@+vKV-q^l{&;K%}cZxX6Toc2WIcq zg%)$Zb8X%O`CVM^OQQ|ot~d~sneV2o%rjobipP`Bc*w7Mk*BD=KrrHi^$%GS2Jlm1 zy^-PfuxhzWSy-(Audfn$)mdkPe}_Rs2BZ%!?wQ`K7K&;L%|a#sJr|nH(*|KTDs$?! z5Vc-+q!Jj{$ z9UOH)=5F;5{D|-KFf0E}12FEe^@itnw>Y2gaN16hQe?FstazOPR1;!z=JCsd%nh~r zPBlfshhFDKkK=Zs!t{;?AA@^vVEL;?&qdj3FrZ)B3U4D^F+wqzA^XB0hT|z~WY}=; zr~(DZlSFd=QE;gbR%&BqeOW)ImET3m{^h%15d+~T^7+bkQ3P_ntBxN)0nGLcISZPH zG1Fi|O4Qv^dS{B^{=F0wFkx8##}T!di)q)`|YpcNB_!yf^U5Bm+;lEd>I>nZ~W#L@ci};uYK}!_?Az9 z8sGkzPng-SP5i>o|3iG~7k?VR_H#dtr_Y|?;iDULa4r+%i|?1N>3~>xXz)t7r>j8+ zc~6G?6NqyjN`_Coi)0xF*rWU}^aa4vuQSpsBUpF?*N7NL0_@jzD^9Qvr>{@N4M6pp zGW0Hvy;k><`a3Py%GQ^W3!yyFXmsdHi<(E4f?+-79P`px*NE%HIWxSs z@)^nID=#EI63!u3`RKG!XC#c9ocqHHE0V9$U`54F{1m&;3t0b226XOFndn{7Wj7hv zJ9_VU{OA!HfE)3{4TgFYZ^t+f?B_GkI!@b7>`NNcpys$uxq=1bwq`Oa4h|8c#YV48 z&`7~{2W>8*Fi3Y?gF;Vp!KqG57=fp1(b&ot)#u6P)%T0S);`uMcWtA*j-@a1zK~e< zJ#kXyC)chcCVqDY8S+xCyXvAX0U?_vq1G0BIi?=xiRrg#%zjZ{a~^aVudVGmSI3Kb zZ^~svEu(65t_H8tf%u%K6B%E#fB;6mXVyiI89?yf=rb`p_qp>7PNsN&g61oulKL!l zllo2tb?O|GM^J-W)97v5uE5YDFJTzWAzPVVtg?`=*&0SvaKLSPw z&bTlhq*+ooiQ}4YhlWb5dmu#aN|!^?BZTWf15=xPFI{9 zL>Gpi_G3n(m{DY@nCuH~1kzz)QpAD^^U~W5>bYnFc<2_R0|2P!H8-(w8IBAutkr^P z7<0JN3seA6cxwoq*76U|eR{SvG^^amsg!Yi#*Z6N&WG3XeI{!cVv__i@5S0IpqE$e zBoLr@+Uzwf=1JntLx>M;-NSg^?L}imosc6)edjh%9?o?c4%S-hW@zv$PHwW;@i@UE zPr0#ziL+Ffuinrw=(Ls^zvpmM{#tG{>2X~bDnr5B#02~pX;_5VsS7%19Q&#m5EX2# zyK-W0?Azw|?wD%(?X1qAG4RljB|PtT>>{L@2S|W125!*MwwX-LQ&Q$M1*~-qK?5Mb z=rStFUkuFD!huu>&FF`ciq$;zfCeC&eHx%H4SQS*waYZFhd!Ja;3waM`mQOD{m0;6P`d5XM?hP7u}? z0A^6l`51737vC3&2^yq~-w{Oe`_P$~UjdJXQTt8!Rh^%@2$C;ZqgRsl$xE}u9F}z% zi*j@@aQfykrD0NL&lUemHL8dgqqnG*+yxRT$ZJu>f#JRN!lG(BNvC3r8SBi{ z08^su~m*nT-fRggr-{s(ew60}8FkgtDi8jp9 zyj~uK8lN|ZjbSpozX#@X`RAcj`o#@Cr7_bhZk6$oPAa~l z?9jNIdW<-2%xOFs&imOf^;B2Jb*OuXS+B}t9MIIF(afkaqkX=+s~O0(DwvuJ)t%2L zzx4hp`KpBSZ#>RusQD-|egeK;bgX*Jl)xhcHAF(B^(vJt%34i4=Uo)QL$l!W09P)` zKr?2tFu1~SZ_|mLx2Z-k+sz}HwRdcr8AEzIVIODQ?RR)^^9bYlTaNb?P)pUDXxR5X z`B5^lA=wT7tZ07h@=#;)O^7R z*O%#W*|!pm7JCxP=nnOECv-NW z4jR-<7jB+v<)?O%7r~uNG9imG&iCmI(guX-$dZOFms{(pjcS|5Q$y`}8nsaN4>836 zIlMX_rViCxOUw~QPUo6K(b{JGTuSx_@nD_SnTPXKUMU2c@8f#k1{iyBdVlPL5x^Bd zSgizb1B6GUw1$0G6X3qPS}ztf1<*b9NDa=}iSTx6h=Cwxr5zL`TF$&*Oe-{I&W&wh z&fsDzO*tkM)W;@*^nQ6>--H7ndcFYjZo-U8G!)tU;L@Z)b@+zu9xhmjt?uMyEcR2> zA!i1%GNn@dF$u#z(M&OE&P2ld$d{mO7Nk%Ifku(b$LpH6twuv}d=eY9v{xjhiZihb zMtA8cye}fBenvpYd8^;?{CX{)t;*6mHg0qg1??Qu3lyGO4;_*~2q2wx&xoWw7A4Ed zm=1HwA%e#6O*a;(3pO-yuj@)7aWv*Mx|;&@ZUuG$7tS7yLgkXkk8+TkeZHm)PbHj=P1DHM61kCg1?|_A7 zQy@_Rf-5`Cisnr>VzhQ-f;Kr+7-J3Gy>9b4GrXGbC=(j}@q73W*Nk-{6mCoj0brmr zPOtOGs7*@2$cY7104Bt^w}%v3R7Te{=QW-`PTuFwFzmPqEUz4DDv@s^_M2T*4qQsL z58qD>h$5(gZJAQ)N_)aPL?K^sFlL1WZC?p#&s6~U^IWZ*Piw4^mSH-R1ixl#mhG&~ z`9I1mE}l>OAnBo8lqLLb!1{bF63JDk=;bps;0xOh<=57lYrh!Gm`bbkh`|9%8sX?Y zq`}V$ZZ~v~o}JnP)L4YA_d=!_(xO-{%DQpQG-)XEM*Q&@p@r_7!IOYjP){XU6oI&p zauJ0d6QC&?bW_YJ(B0=^nt>q!pt$n@cCs6Jz52;S&byvHeS+6N@CyFa|Kfj*zuY%` z<)lCy}Kvf2AkyR~oQk8uR`{e7E#wI=w4m2r~ zT~T6P1knoWC5?gtFRNvA#QjZWFK863hvKz~H2I{s=akAmBX=hpU=ts}9aYgs#Qr*7 zl^)j}<+3S`#AQ2-DbZLDMMh_+0NY70_KC5Z1B3@J01hp>Buxo|PjTK^2dB3gbiukl z(3Iw#a)tD+UQx!|s`67neq`flY6=fiMQNlZ|1?Hz1TbI`II3131db(Jb0esTyD?1; zP64{}F{@87f!1Q(x<{!@n6mMeeYk%|)6rSw$8^%?33-;KV(Dm;g1Z+>HT@0UZ-lI_8)dcXtqUpxt0X@qFK7zbG2^0ZcS>F|&sH(Y`tr=esjRfVP=4 zY&xwmg_t~76`tZr-fodMa6HgmVKpVSgR3ckJ9hkYf%Q!t__>^c9|&QjH!V6!x%M<- zxzSaOpQnS6hBMcp1|XY2x}g~_n^o4h@PP}?;GefN8rHj3H}d6m%^-1M_&w+lfUPb4 znoG?np=|adyP!Oj<$aV>>BP$K!w~O#vtrEqbeF_2l)DHWg@QT$l2QP;w(I*?JsotP z0|R-Sw`gLFC{peFrcv1xahz=j2S5yWL&Q%F>flN>>V~a2mqd*_5GyP7VRhcj_&g+h z4nwZ*Q~!(x%ZQ9T%4+fxf%A2X%(t=HSfsg8MFpbWkC@KXqt;+p#|;HKvmPDiCo#|g zTZKM}`Q*tH);WGp*ZWFAQozGwW%-oHAoB`Ky^a7P@GaInf3OO==#*7=wAP(~hfedD zNU(K;qyXh>*$@I48>G@VGsjUfpBAj9E@~-I44a06NwKsGK@|-H&=F&Uzn6dW*tISa z(JyE`-kBg%J?z$joP(z0#l5S_P(W8CksvmV9%a@oKRt=I!Tn<*WgSuw)^^BDc%lby zd{G$SH3kJ(g>eH5Calxzb9f#=7N5IpyI%J(uxkub4|BA%bEUt>@zpjXl1kH)Y&1uj zr#Fo16^!niTeg996T`q!7ka5&$U48VoM`t%P>At}biXMWlr>tHHo=f5SH~$n1X&9M zw`VQi*^GsA-bJN+k!i(2RnfPTS(L{a4HMgT!glijI(G;rHbw#M6FMe(>jpN|K#XvP zI0qED0puE5+mPEk_p|X-17~JU=lqxg!M!5V4Wv&89nw&#D-DIYk79o-u)&VWYYOzK zm`#^rxOLvOS@AZ4s2&31mXvz*|~3<0lK5Djv-eMucN*EO=tjq$LGEc zpZ&J)gka!1zwMjx%EJecCfK%)t@r55=EZf<#MTgkjdKhM$Bb% zpD2;5s?K}47l~(*?5`PM_<4&|BSgB2K+J&Q5jV}F$_#>Ks&#K>;2ZG5k*(o$(>+?j z@sX!9H82qJ;IMICXUd3kPqptxqh}Wm*gdK{un_mSDI6TIij=4m8(xP%+z`P+|8-h; z#IT5%%y1SsJqpN4$oZ@(@Xhh;1dT61N|EIEKG@jPBHfpK1n;nD+Kj5?deTT4Jcc-e z{EK{C6W3HM6%G`kT(mlHP2C{@I>2P1m*4}){joSE=^f|Ehc3TKqEiIoC!@~E{?z$S zJQQihm1jfDAmTF0oEg5>-D>vS-R`*CckHT=W_+agiSs@&2KTw`<8eNt^^UFGKvXcX zLv=SARx_v#H_EW?6jOJ4qk%(^r>^>Hbx-l}8dSO50*i>WxuqjaKx4MADff9RuDB+avG19#$MnV*Ve9*@lr1De($)RX+{bUOw+{^Dsi3ugp<61F z)=}}lE;QaGY1J@+8Qw*aMdk~yzAp+V6#P1&y3#QDbnyLa7-ObRpa3v=n$(JU1*~;O zY{D2dpNk1VyO*LMAL5(M6$m%z8O>zb5$+$`=iYCRpyBr_X*lH=t>3-OcNse}2qF8N zYY|3T?g6!Z)ZCyOi^53Y>4uir6zY+KlO*T7MZ6Z$I_FbojL~I>K7aP?YTVsBUGFOb z#sKU!qEBK2kP1Xp#is>cGekAAod2`Nt*(>pGaFda6`Rq(X)I0U*nvv)Def_Q- z+NxGd_MsixtoIx(=URRV#>Er@4%z`;YlwAbQNM+Gl3q0f6h{*Xb8;ORnN=B3j}T*# z_y{?5pfy#1IWVVsG|F%*x6wdv4f}AAI4yNTWkSa)@EC?KYGAB)Q=ZP}GhW#mZnlo+ z&!6J<_9@0tj3JOVao*3+F`)7g1B!i4+&$lofi=N)v!M;6ON-nwV@!ZrP36*#CFNW? z7}XT~whd{)_jzPnzVpnJ>tKTo_?_bSkzk4A7zf8_rg|i{HQ|OdO%e|f*xbVa13pwB zA~5nu*J^^1p7<^q-Q!tnw$9$~E;Q<~-gW+R13XQK}!J8 zydIi6bd+=(ORi=4Q}z&G82>;-ZP;xcR(AlgMlrs_m{OKfJ|DnOSyvu4ZNNuzB2)tq zO3=3Fna=@*8=B^feQ(N;L?7toe*EY$o;<(BfA$~$U-9FA<45r6kADyyz_YsseB^iH zqaVJ*XTI(C;*b8z|GGuWO2;q%($Askj?aGkx8sNZ*q_49gGV^u-9n}n1&6@XkWFcT zh=-B8jFOmb()19?q7jj&-nK)~y5hm(>fT6&L)nd#4FsBvAX<@iG~5tEr zMgpmN1Odt=X{2ey#+=KFrtQj05M)?j2g>B;LTyOpx3B|<`^qjL<77rBRZ?N5v-c!9(WMXG(7KZCd{ zXQFJba>ZX1?*uY3TnUoOdT`Nsz`~s7OtBs^2~_;}?Bplv2TnjtUZk_lTHH>j7p%PFyVSVz0(t9$-uQ^-*0I2))il$J#9@7cC3ey8%zZ9duz{&FFgkE@sr9ng~o9IPMt-d<}bAt{O+sz9zS{S#3y=DqsFP_6{ zKs+=aee7sp4!40+4O)T%`=m%U71j0?PxJ7(+%@)!!kDH^Ke0qg$`b&vj*&F9q6#roD_od9N4;`^$q9Q@ch{suf6sVLnqGX9kMx!fk0%le!5G|PTcUY zS}y_$NYsMax{WRh%@W8GgNcI5x6Mfl2FQIRAc(X5te!Vbk13G*h4r0ci%A|eXU9By zzi09?H0H!l%AgQQ>fI1DOx>{_yD0IVCF;hnhKzhjej^EoxyGayS5_H$Bjvt{Lx{Yj zmyd8$rtu`ej5|9NyG}Rs7-%2rMSX=dZor#L{Gh-!aqpbdM5%aWg`0yd!oX7z2gtuD z8(i5}APS|4DIpVxv{Ui-(V#iJzs&){F6trrS&NB=^{F=Ut!2#=3!8O*p|O}|z)%V0 zHGoKfe1{-j=#I*xo$h60V#J@)2*Xf#$+}A9&tgOYz&((%gCxx(?a5oL9|C1EmH?}# z7>IZWfrWM}+jnr8323<=#ErxZ#Vr(C&6?noJ|R5feX2y!*f9!_SGDkch1Fc~$ec~g zXiOkHeBZZjJdiS7F|j>(fH&TJ8(;dhU&Y(}^RebC-pT!&Bc#7w@x7c(6iQN;cG?kxp)R4(~dRc30a zy#m3Xw54~ldUM6o22|{b@eaWTM3f37P4zS#^1t0T6mdVJM+qVu6ivD%n~O$?8B;v7 zh^yH>&EONti_43QGI1jpG!6vK5_}rOaC8Qllg9Y)NcichLopEX-@u2-!!5;ijVfTe zQH|V;nGwVuiA)ytd%5T(nk{L-_S7I&hXU@fQY)ZlyhTk7=`yhk9YmC?;z3G|4SE`O zoAkixrtDWw{sH3(BCUoPbxyBhBx!JE`tYRV7J~CWA+llHPS80p?(T4E8*Uyx#MBO` z;O_RRDPmhkzd1n#IFAvLsEQl3c7y53TU!&%;l?VTLOPukK=0l5daRk_Ss{6NdN-df z3c4AkW@-U~NLdu$6C>zDL$3vl507csifCb#1}U?M>y5uySA*AiXO4Qti=3!oz^9xs z0T?ng(|L4h<3)y@kipJJjn0KH1UZ%JsxKrLzSKSV{leSI1Vw>!1+()G9Cop^T)7r7VxMmtyJor+viE)k@p{rpyi5vW# zslTv+iq}cO=4{Kg0oh^cLPjhVdQ$3>MYj{`!zBvd^@!T{YD8ot4CktTR~-&q+WV>R zov-(0fYDggE8iWIdZT-SwcQxE*`RGA`sQgn<+wzrq{un+NjXKaI%hQ8ie__l zYs?wOxlFl002%_IRHSVTyGNo}an)*Isu3hUMo8pz3e0mbCjC3)CJO1m+>Hr}s3}hF z2;NTJJT@?eW6X*30B*K!O3GA-SN6Z@4UZq4Y@}|?(Yc#pXDa&5=7oO;_A$`iVlgp8 zaKq;(8E3HjSSM5ec-jTPqmTVuBmWE~dd>FkL<*8d;VmV7udP6Jc)Cq@V<{E;<|hY` zE8BhI$5u-4sNu@ZCIF;Ip>TnLdDf6I#jP(iwhHsi;@EE+wIQtFxgud;q(|0$xCqY!_wZb!(HcR5_tgwD z7H%khjQA+?9sE*FnHtg}Ud4Ft#B2^4Rl?|Cc0Yw^4|*b?Fpy|GeR$t#c!KX;&a-G5 z+kh6e4^lA{oZK^L*wqWTXpJ3lzJ|=$pS}PRg&E){FR|FWD=7rm1V+Ahgpq|#985!^ z2i#->YabvGLliY--3`*0(+qeDfcGh*Gz5%>P!&(37`b01J>NhY7^bJ}Hs4o9bCxhC zvU#Y#9|I{~NS{W}20VH4Ha_^u2k^)L%>N3v&u{Vi>mNo3u-`q!&;7l>jyIn?L4W#n zeDa$<2A#m&vnTk>=e`sF{15#x{Lb(CgLt@|@ch}cAV-m03p2uLC=}wdd@7A=G%Tvi zH#1a8Ta9WtiMc+p<^kH2ZeerEAOW1jGbIuR)8v+NZf&2_sK~JxpifyXa46Dj&xW^- z?~^os(1>FEp7gBPVM_ky6g;7T8yMmDM$zdq4idag)e&RRaFyZuP=fn{DE-$4@zOA! zqTArd!`n2T+>5#Uyo&(ZSU1ZtfYUztp&1v=`6o?+2Sp?`;Mm-89mgmP+ZR`cTeQ#m zE=dM9rXg-vpNgTtY!a!M1oh30kULCq=}s3k;8yyOcoy!|Q%ehWheVGlWb#Sk8xcgP zJ|}s4)Mk}0tWU^?n4u5wB*9!e*6kua0E~#^Tunfy%Mo*2`jVT0r8ytjoa!bl?Mv8U zuLTp9De?8E94**AVokvr1EcaJaQCoz(Ug_V$6|h~5}`8(q<5e-JAQiW=ukYo+3?`h zp>trr8_6GAH)GRo^<;(-l_QiL=Hxp00R{uoZ!pgTI|jDXmi&hXQBouKw@9SZahG!J zbad3}N|w=La;w95zMV#B(`op~bd}~O&P{iQHVb(1`C)Vz^@{>B;57)rb)^B?6@RI9 zdx+BxG7&Dvod=`?+yR{sQJB0&$nWH>7fyeycq-lvH!%AUhBj;l;`}7t>bichZd8qU z$9gP`9#>z#V}EKJSHB~F=5!x)YW6KZPA*I_O=lg-EptvgeNF_BE#_a)!1{g3Ig2a= z0Bk^$zrfRrAobX56moDW=}{s+`tttiJfJxbn;rr#71)9ic-E%6VcPd(;Goz6psm2t zXH(zTxFcQGW&!8(?nICd)ox5*j0aC<$<*m9;wf5|mJz&oe^-0wTQ08<^jF@xLCn0~?SmUKE5M#7ZMoUN5qaU+<%Ho8@^&3?X7 zB=*q&nV{r=z0bykJ3%f%q^AR_Obk!UyXl)nyhuZ99bHXypT~|}1=1Vt#=t%sw(iQ` zG}@k`7`rjl%>^>O8grP%yNT_o=6Ry@qS2rO-;c&u8&tD$%4CfL1!QXQ6qN6nln@rGWFQTMMnrpXY<=^#m%&=Bids+7XSzAVY9!WE7HS& zd8pd-HUNy4?f4T&=wd+LYFJnw5UHJJrV`lqJ!%iMWek{}FD|aENP-umiBv?Ui04rI zPF9u{xB3_oGXhg$mwo0@AjVv6?!6xj>!02M0zL_P=Q|yIh`3S9a{rslei{L~bc=@J zx<{`xfJ(GV-mC5-)T?`sgk9*HHJG`g4h;a_o#;8e$&&ra&7S{Db~m+rmfQ zWIUfI)4=z<)$4M@jlv^{N{zFaGeEky{W%q9&9AMmUWAmOCwVUCB6(=!LW@MvTvIf9 ztb6Yr{bVPkZGL>KDMV(PRQ380e&jaPjKh(8tpd!6mmYR}o>T2`WDcDpZG^V zfnWQ@pT(y?@o_xUj``B3AOd{bcYY^+_xJoE^f~e254?m&4{xj=TMypbd&kzAAK}^2 zdNH1J&*}znPCDy+B~-vACR$v`=t5O1672S`pWE2sRBfMGTi* zSk;UsO|7mAcOp}3IT2F&&v#1PZ?Q>TJeon(3k1_3?!2TZXsV;|eVeIPj4xa}^>&OV zCu9yZFlw8TizW3R$aGS2Ca2#W0`+=N6ItXoF-gj6h1#i3&hr;A>-2238F_-Leb200 zamQNFzhl9yXQW`EBFZtESB24BK7S30Qy278b6tc-r7Kh>`pJ0Tn{U4bh)2C_n<@BS zf37K`{Cs_7V2<7BtaWo|bc^`ox+s+*m<%)Lk4K@RW#RC^$;hLI%W=a@PYG;!bN_a%qvj&XoB{zP`Va04WZh1;PCr6vust)qcqP4`!ZR$Sbd2 z(+;gMV9>r-;+&BADxdjfVH)V)C*$|N~Qy`u)t+RVARgDRax-jAi ze`FBWtk)auU^a6&6Qbk9Q}!k2gb`ygcL#YZAdYDZUoe_>!>n+OS(}Nx_PBn>cWCYK z`@G&?1dN{zF6DHDqtV3g1S^h*R}^l^@?y1q`Yj^2**&{+nnx@I*dmCyNGa&W7ntVT zoMef6l_^G&)=+B{Fl#vlsYGfM4vVT<`v7fmKvjYjtw zgc#A_TBDD@GF38kf`nQN!-Z7{e*r2TykMT9fBt?0M~WrFr+~|$6Jtz2l1~t7Q=zHW zT2xvma0z9yIEHqNifTL{U%=ws95z#yVpm~ap)kae1kbq)hn6nCf8b~(Mcd!}Zrx^{v*=e3b zZs5$Lf5@xB+CKv_y(p{8sWdX#eZ#*qJ;4NaclsF3PcQQM+ffwSvgfH-0=AFqQRL=P zBd_w1@yd(1pwpt?g7VnKXsgm~(#q7re`yzYmKC>D!O#4I|1Y+2i`QOzh=1-g-;A5>gy(l>uZt!z zx1q%7EU7OVG@_UmYbebNW}1-}a$Qc5M^`Yu%ITEn^$K|@2)PBxxwro_GQn4+oP;Ed zW;6kTE)DwuCxq;ow(scoTIBCR_7DfPCfJ=iCp6elvL-alNWpRV zY9n_?g<*Gvc!Zuf?m*lxTn6j{kFK#3LTz@Or!lGtG$nb>8;JMcWm8EfAnE2wJX{sW zK`>ctk?=My8ew=+9BVN3CO8i-NQ~x&f*Jc@0%q`;YCH*+vUoo4I1j~nR{$HD+`uA_ z1iR;h^{u1JhORKYvI$Ni80WM1yF0HmgNntvWTe^zAUfTkZS&V`qK)_eY#zqtsba^`2IM3&OsTHHJ+JYcV*@7G89w_v!uJ~svILcl$ z!}P*e{h7KCp^0FCx;I{Y(NGfah5ErKoO4ArARVv8nSam^LZ++cetn0&u+94WQb#84 zO&*`}Twd5uLV+Xn3I{{%4ZCUTMCa+hNQ`NyFiqO4xO zvaFkZM#pPJMvDfXZDq`IWzf`VQb%3o*(haA==2DTr#?}E1F=hM4IlmeEDo7aVb!Yp=h&zYZ+z;^s88}MYbNCF#$ z5r-Xx3wvh;3ILeSa3SR4Ywr^hETqy6D7u4KDhGMdlB?6a^zpff)xHrs?vUwE{zel3 z(=7U|mcKU4_7NbNN7Pz8qaO!0y{{3mOckrFg@?<%=(=jDmEhw`r-VCQ)^+NzeCk$y zM3Y9so386~{5PtzAFgD8wI35&i#Iz7!qNQKM;kqS4)eDGroio>I7i+#AqacrjV*6Y$e;d^`}V z&$7>fIfi*jqyw|z(Kewv&}Boz#2CA!+I8#n*mtx(EiGz#!8X`A4tXM(wa=4^L>x$I zjuk)%OKA*+wlPlt+5|(U7oxQZCvOD}7HTOyLrggyqHaXBzZJ-Wq5{kid}WTsy^zG5 z4rs+`PyzG!6~sF0roA|p* zHwK#6DNVMYX08d6kFdZZC(@2owe^i76utLR(*rZsI0Sd)e*#eXHP-0$n!rMd)@Y`4 z!XD4HK2o(I`V@xb=?P^NzRQeu_C2 zH!r=6eFy&dAO55G_y2?cBR>1B--)k${-59{{@!21)`4IC*`LN2{@FjpqgOr%h2r*n z#@!%)8sN!w5w7g}CX~u9kY--x)_i|Y7*&$7G*VX@xqs-Nf zuEbRlg+Y&O%RNy0=ASk4gVw;4ha@1HxZ$?0hhrvB{hFKybz=_kX%mlXb|-;K>ATT- zHI{NOa*)P98qPEnOSf#jNh7nV8g_~kFyYahBJKonKICJo5#;rqbCm9&kV8gYrn-v4p99^seCMbc0jhAm~u( z7??PnPS7FPx}_u;f7_vRHy$I+qJPGWg1PF((FQxdd=eMHj2Sd=8-C!rGnzySHg@N& z(_I?1Q}$G-Thr-O8Tld+34^JYmdE>@FN!ogeDnx^`|tc+{K7B&GG2Q83W#k0k8YSK z{0@{V%Y8v(*8r_|vIM6uxO?GhLdV3~?gdUiw(j)5;*o+cfrttWzV!}m@*b1NuHV$* z3HMR`_j;dGrWWi#>{{-(e{u0y9jCNr^jq``E%z?b&mbRmOo9fB4{w-5oI1PjHP|ev z1p?U7_V#1G)(L68w_H~SOrBfKDcjcqiBkdXzY`O~BjCiLgdMj?2B);#d!Kxs zLQ0lC+|K}CeASRYwj(N*27*HDaM4XACj<(7{y7&CHFgO2j=7XC=nazIZ>kn*CqvMit6-Frjg65{BEYG6Z3|GI76m6jO#*m&xGpU0>UsG7Q7wvQ zR^J53?&pGtAE!B6?5PQ0oE?m{i8if%$Sz`$FgajAfYvtiCXYMZ+&n~Ug4x|Ts)F-4 zKpJGSis9^IVq*6`!n-6Q?5!HRCP=aPHXKn2Y6(>quokcx@`W-RFj zn%cA!w+Ns0d7Zxe;ShC$s(I3;*ZN2WV6QIteFp!mb<3ysoMzJG5KF1)DxNCAaU`%4PDscq zo15MFUpel1b1ywKbsu~Iioi1ZeoVFJ2lefP8_FMSSYp>%^|9k%d zUV8i(pZ?6Zq6_e~ulxr7tH1D{V1N2GeC_kUfJYBDDEcuNcP}{iDc1>h`5px0|_LKIu&=PBdY?21~4M}`T1)2q{9hNs_x{mQv zL_}mxM7}qo)P(y3ac`c?QstpXr)j=(VSi2^Rfft`T1>3AMSybqAIB9~%5Mq8zl-k3)?EJ>8fzueFb2?0 zPTdjxV#iNw6Z8h0wvHx(Z@m2ka|dotC*1ABs@8A7^tge24z$sMX2lW7gC3s8lZE{Cfs5{I?>JX8ih#$bI1ceL zhyd;+g+(1A_YJoIz^FKmSCFTbO_xC(Jo;Tw^mj1b(fX6+G>E(0btvXinmWB8G{@+t zkwIXEeV5H4t7?y&0mTXPAq1C>tMQsUs1O&2mC%FHzbq5gkX)QRV9sw|OOM)S#tyx}t zNq@|tapWzHURsDEtp4m5yQT+E&_ykV>udEQ266Gcsww%}V?;S41ZV7%kM|v}cQ(LK zs2V+8ewROWEiRrfpTCpkeC?CbKx_0C5D+^p5l}nYmg}7eAd|{~ji(+n8utcZv9;}* z4AUY^8~}ph)EZOGB8$S`twCdq#(p0RDlTP$*-kb-UVv`-) z=>b$W>~nak3P9uO7`yMe?4?3I6c@?l*^k*vj(PQjh!?oCJ<56|O-y01<3zLYGl1ok ztv1at(GPPN`^Jq3P~aHuC%hXB!+R6Po}fl%xM!=iDpTDf?tD(b6vMKrV$rKz1l!ipI_s=#=-Ua>HZQiD5e=4t zLhotehYprR%u(~|2R?{bUU?N?|LT{a9r%eK|55z%&-`ud5cJnSjnDn=-wy%s?ceqL z@X=3w8o%(5e+*CGdJ``_er){!qj18h_2#l2R6hN?>VWcDPXZD8 z`pT911;ThPq)DfMVi-!CleM!@Xo1+Ob^9!rLF|+uK}IH!w#quyW5Uy0Te|DCs7)Zf z8?cSB`i^pCT~x9AVC~=~MaN7U_mfqi;zpi~hUS2|KZBESFK8As=haos!9o7$^(~Cw zB8&khhNl~GX!y51!veZPfIMNv$L_{~PI=&KCF+ruu=8v*fE91Fuv*O~Zh#G-QhcwZX6HU{a2W z{K+xC4}wNFvvW%AS*#yVsS~cX)V^09l=Q-gq)3a6C<6&O4j`iTrp8WKl>ga)eVT)2 zIyQn>6lfR4zFQii{eL>X>9{#Pz?3tdJbfGIyE~jtG)~z5Q&`b>J9NZoY}*><*e&8h zj3-&Wo+<^*D91jFIR3`~<8@8GmB^}=3Uc8lp@1GSuEO@|28r4*4hW$-y+)rIdFB}S z#HT)kS6_S09BoY_qD*{!OFUgD_s46Ak}M@F(uip?DfdamIXMpEB9!mnDN+R}wBs{C z*;^6KwRUnJuVbkFioFX&8ep__O?Nu9UzPhg?IfyeeK}&QW4j7ON+PliUp~=K&v6$UwG19PNP2YRAy10vI3Zc3RldOSW0~2^jsOFumV#9H{?hwC&MJ zZNpKdk%p1z&L5l?@npM7TV{}>OFd&j;D4lmfd-q-M%K%fA1(I(y4pkzh zC6r9I_h#i#++3UafFsVH=Vlxu851K^SWhB1tzAL^j_emLUiLY2J~`py!rB&OmVRej zdCjR7hV8}MSdoqvQ~P&^U^m9(o@;Rc8O2;EbA9tz*zvY3?y(lHj}T@N)Btv2fn8#N z$S`tkIQNT6b)jI&#eDL&Sk8+X5Q&Yp9A6#c zrq0%juXnR&>L$PZJ(-#KBC8CiZD1dSky@B*-51W_N<;y_yBIU_G=~~3LB>N6&FF@N zWn`Wbijisj21*9Z3r$_a#vs0#)fJH~(hpPz_I*cd8*WY;rcOM+yTzkN4_+?h zoai?vpf?Qc*t)?Ci*!lrJ3`qVIj>F|BlfqfbPGU59gs5}!q+1aX6~;dv=0;zb9PKg zAhW*ofaHGQefCHSsY)l+up&Yr7%O}DU2xokD>O)fTRoU*9CZV+8;%#bEJ;gCJFq=! zwOmM(GyYxYs)E}D;tXfCxj1?#I)q*!%w-)UXc^`6?#5^hC1M#wD2akRMJkPEF;xO& z*uXmW7{Bk$=8-lgci{6_CvSmgWnO2{L%h~&=-A(GdU09S!~%Qi`8OE7?)lBvaDpeR zl*K#nI4itshK}U*W@O=sfC0jNKhSVu3YGJVpjj=njZgx?^>LZYBGne@bfR~oD{-ONBx}i31LMPokMZWyr}&Hi`Tq@n^S}Jh@RcwA z3I>2zzv;91?(hHC@TqV4ZhY?_`BV7*Kk_HB0r={dzKEax@gK$Kf9_}SlYi&G!;|OF zadSGsoE@@&O%XFLaADJI;)FCR9k6bldk>XHM3VtLs+T0gBC(bt>^y+vG-3O$gpP6@ z`0j@8HF>5V^Qv}YOvOK9y{_Ka1kz=UFvYe*&?Zvh0xs4(c~F(nGr%c#4{21q-KF=z zmy_Sv{JAki3%}F!kc!JFnynQ)`HB0%*1_tjraTP=J&erUD~w`J%ybbBu;4z@K?b!) z+J`quLwC>&nL=@d*+-OfM_yg#s9>waO+fPDBUWh_%spj7S#MUS1)VB~{S9DhiwyFV zExy))-Dn)=xX7~rCXtf1m>#mo4p&Z3Q(zFXs*=|Vn z^+>#sv<`K=5>7F5CeN`$MDWRP{w!X4`6Wa|H4E}ZnrdBhy!Y#{N7J~S4K5C(Ag}vh zcGNMJJGE*}!1Aq@XNoRseOQeiA*Tut27D`ILl7w2t%0|<{*}VhOVg|JVArnm`s^wz{Egc=+aBJuUbiok!x9= zVwtysp{1+yf@T2%)B0i&d*tzqhDn3J6}x8NxJOp`xc1Zc5cRPXfA9KwUj~@gTCoTM zfGnOeUeWQz+R4JZJ-$2jj_!sPYqo^-BE3|AosMAPo9jD*0fRi>2#k5MBo7{yF#>QK zShX(p6fl5Wrn8PhUcO~jJ?yXLIs}OFUnP}co+w~Uzk+WyP)cQ!V>`UjK9hxT$XtPt z|3zge-Z@>{JI>v;&o3;EI9O$y08L>>k&*|eV%%LIADQ2M?|l(7Ju1^vtDqNTc~k*~ z{JXvGvrgyx^2a`xP}pp2!%3ipwUqTdxHY~~p3GOb9jnx|@xj@xmA+tG~<`gCy7 zFn05b_Qtg~fV1oFN|$FoM7?{pBQV^R0nkNNSW5!CC)sSO2MBno zjP1wjfhe=74DZ$8=|;P&@TnIKhN&>F_pORWe!tG~I7v8c{@}?VyQ#rjf7z!kmt<3wbJT>Q9p^Xte5{i2g2+a86 zX}fcpA!hh7_Lh1C=y1vBuTmBCcFIs~@0Zm!0)UQo^D-dL%_pjkE{iVN%0pN?j_N#d7>u=x#ANnZtwBgy^j_Lgw&bW0>U``AjIM3aR&AJlA z)Z^f%TBA-|(5{F@GPIWGYl-uHK2Lc~u0mqfmr#AeV4TYZ12*PGlK^a({0isx`qc@=3IC@L12=?Q=C^vZQdWYXl(^67lE_gS=4<@Xtn!}*gqYJ5P$16{tp?wbJ+Td{f@YaV>`}gHNw}D z4wPTVUQr(h${G!q|3chi^cM4AGX-c5yIV6w0^tN=Jy*c@R9Pp~NSB-k1>z*hr4EcF z1d1rTIgzzgm7*(cA&$LWVulP3nGE0}3Tw`y?>L=YS*x|ry3qD}z218b7$0N>aI12f zx9S4wOi1exsCFp!SYQmdOffWBld(LY7Z zQxM!?j`HziIMqRsBK-yaFd>gw%VQ>i$F1RcJ#4VUyZO!(;`bBqk=bNxvD@mDP-^8| z0EfC1SH}AepQHBC6{X18b|CH~2MlLy(%dVqz(JW$=2#2l5ioL08t>~sC~Qna+QrGj z0a#OD%$ysMhSn#>KBFL3(uJB=7J}9r#y(=(Otp~Qri#`q$M|keywpx;tz(~iD2rV> zp5Hyk^JmWiH0X=jf;}leAK!@G8vaJ`Y*#^J2QQ)0&f>LcM4r95`jt3F3CHukVcLRzXX#S5fG% z)YXXbuniY5%6HT>O|HKK3RMTA$?s%+S+twHvWN7rUBKspZzqtTVzFDSic4o2^;Dfi7O>r*{8Aj03B8f z#^>Dtfww_nu4-yQl|KSVoRVkJXKvFrFe0RJH)JCffi5eUsw5RfiM5;R=Q7L9B{q+d zI+y&@QlDD3s&oi&OdW(AqRoNIMB4;9Oi_2Xh@m!@>Pmi70GmL)sKe~Q9OA|)gs@3( zxObxgx3|ym;SYWo|K`8*XK`vLeEd_N#nyoT@h5)*fAPQgzu=|uHh%jzehnXZ^>rwK z2M-?L^$&j-ANbIR@B=^iLwM=&Lp=G~laRv#D^ROY$e2-3T2-S6u2EZ$$Ui|}Xpcrq zczqZpPVnNeP*{2&1}0Nw;B?pkOB+PeN=JI`3%&p&X^T9+ych)lM;Q`D2-TyMwnG1t zbtYomW(*|nlO}$G3Zqwjt0?Q{wMbpiX7n)B3??UGdg<G2bt(b^pu_ICElaz~e^`t?0iFY}oPe)X?Q2zWiHv*!LX| zAKn1sr>~3&>3vzB)*0o;d6==!roxSwj*~dAYPHI`aFe<`S5L`J3og2tYkR^Rb&T-o zLF>dKj3kwu6C^yO)10zI05hk>Ovu}mIpwh;%+&EfFCQ9h zSu^#s6|>tqr{UqMo+ARZf|WIT0kq-ZGBF(6t8E>1mcVHQhST`WlvUBcuir5jzOI&n zO;%$eGAq;PC4At>-DSXjbaO&)ysX1v~ zui;lLcItxKNs6zU>Y+^xodY7$B!z;8h>PE3qIHeXJkvoK3d^}`0e})5mhqv4;PV~~ zKv?j}tL}%;T&=Onuw>*p^+3U1v9FA=ig>Pnxq)^OE;aX{(cH?Ij%!qz%3|Gh0^_Y( z+pb6-c{{|S570E3P&_9^@?D{m1CzXVB||mg9#;4ZP|7)t2c!L?5_!#{dGBW8`^%pR zhMJ|ziG{Ik1YHgkkI@IU?<-vxpdv^OP$?2M3pVw#!@-=aIBlNy;%!iAqF|T|{m!vd zxT>1KXhM+M>|~=R7!DFo{RTSRo8NmBd}}g**75B5Gsu{DaC2k()%Wk%r=7;ps8Fjh z@JKc2Zn%ip15^c=DTkJut)W1f?@JtT9E3Trta$?SS=Nm6m(RHk9Kc3#I>lo zaD6Y;ejf~CC2foRoVmJE85-)`l|3BMMJt%26sG|Tpn;~I2xSzc3$>=uf?|7#x>sbK1kN*~06i~R=yi9#>%~oDFP0HiSu3%gPH%8o7qy+HMZ0(uY4emD z%0p2BCeV1?$P}}LFoakszq}nEOB0&dJvUq%;Km6~hqPwOj2D*dy<^*qhxDzZ_lB*X z(0jM2oN4sd&>%B+Jol@OO92c|odn)^T9k^*5PFu&;d(M{_Z$9;oo4x@MucHIA2u+V*(`jM< z7qm?pvNdYW<_R7(BCNYpF_<=FVMSdciGhjMeca?mn)}-xsm9eyo&_#R)3=e)0{Y*_d>%CklGhLg#@ zUm|pLm@&Xz8)6LlQc`hjm{E#oY=x{M$Efw6Yh*Sd!PNwZXB`MF_MEk+gNar?ew3`H2_ zVFtvEh)6O!?((2Q&rlc>OPK{45rV!^=V8SVFVYjP=@CcTMcKQ{v*ocog(&Cl8os$2 zfx|I0!LAegzAw)ojW*YQ2j`>k>+9q7XX`y>4LWfJ;5yi`1%-~pM8PW?08Fn7N#`gH z<;g>BW3B~gBWk$NvMQj{Bi^0PL*HGQm-V%=Zmf-@s=R!TB}2j(44&@D=s@zbjLM@? zk?&IHQ*#U-il-KEY^ZaSvVl51=i~y~zlZC68DOe%&JNa&`a1gLI>Ey{Nf4`&-I|zE z2w0_W=t5A@W=Di)+B?Xc)_20&$u1fQRvImqes<_=S(`&7yy0M%k&KC!M6^5`B?Lxj zECX1Wqn5R_&t~q==#S;+rv;niw;Re7vK^u5Tou);m+v`_<3*O^`geHIgiMGVxEs+m zg|ty$W1FY+Kcd%5KdxQ(GNCd@TIemU_s6s_AE&=C1!;bFAM@ki_gSjzIGNuVUMsgw zr^OgipCRFuIn)I#)jY)vrcj=TLC_BpZdz_vZYX>$*`DsFF|Vw|6&VWKx+Ye4V9 zY(1X`dSxYlFG4KW#^!)U2b=d3Ksour=D%Sz%7|;NY4oaIJFW$l=3MAj<~^=fYE}un zaQG#yToblef1hb+&ONv8#mmb1Koq4#9h*nh;cz0E(@as_vi_l??+wTqF_BN2wK}s!YG1@SHJmlIN!Vi065=1!<*mu zI==ShFW|@i*5AO>r_Zt7+(1OkC{)snMXVoYsB-VUnscaej)D)e_DfY_ngdGX;k`*5 zXK8luW**FDW4AeQY~t%O!9XbqnoQaRYFE^N6vwlyjn}K%h8ba3z18ChJtD!o~GKxBg33CS)q8gQOD%(M=8cD5)?Kh zYh=~_rqfk2g`gZfL3&}`D$ehmmNwmsBBg3IVIDnxXol!H0JUSKrEj=>_7wXV7;=MW zw>$3c?jZYaX+P=;UGq5-bv;Kg#(<7dFuje9N2hPww(@yF@M_`ItC%wDV>V~Kf(m=3 zk}E#)n6OM?!$P-!@dw&`X+G>U+6nvs21S!@_vz7qckgS#JzuZvhr;xz)bHx|tNdGa z7k>6m&RxpaNyX+$KPo-uzpEkgnvPKQEXs?0-=o{_j7iG4T3h&^;@Vn6#JH6mV0o*%yz-F@Y`Jgu(Q>by_47SP~>3S6(=`);oHWq?Ub;`L4%)6keq z3k_6=hx3Wp;*PUQ$3m>l*zTDws=i?6!+z6Ji;g=2ZOe5 z?q4st#tH?~M|f(0^}(nqL(;ADoR$fzKSM=52s{8AEsaSQl|YtZM40G{H)L4nI7uK6 zzqHm~T~iQ{Ue2X$7yxnFhJ`vdEs7fi;^zV%3klz+jK2HNYX7UiC>zgjyU$YoBI`Nc zMgOR%X_J6-(w`4lQ@l{pZZC!diOWIw=QiMkn03H!D zNw=ha5daf&42&_XzQNXT9(G#Hqnne>#Zobg`+4gAWlgU}Lsh53^1~)M|!vnkUnj_4AzDD$rM2F$1!P*m&m1~j#&v0U0|e(p8&9Of~vxjbj{l41T}dZivs zY}aUJmcDYY9@o#e1AxX;U?h(qU6$AXHBw#2YQV^7H2No|;9y!R5Z%1$ktH7AV$XY} zMj3v3k)L*CwNBF5222MgWiKhcM3&+pYGKRjOh~6yyfB)W8D0!KNn^}`p_ZCLSvcn) z+KTZ@05O}FF?O`3`0yt`i&tO&Bwl^Z3@so1=5NR24}Ai^`71wzpZZ5Xfq(J~pGO1m z)i3=fpc6NbKZrYN7&0skGHTI`Akr}g_A!!R9WwwnCj`<|GA{SGuZlJ|uqe=LT3pL^ zGtdYOagX&8JF+x=LM4JjDNh)6Q7DrAfu(&-0#QwjK+s6%0n_zuxg{`JoMItr(aYX) zC?JLAOyt&+cp5CF<>(w)_hlLuk`rAjA&8S!3~PFeWlyBxfDxnRv^k%v>ZB{J7a3Wv z)d*ztG2Cma%b3#WTT>!DrAXNC)%XLCjAp^hh;&j@Y(*^1rgF;4yAmUCd@BaZzmu2D z0AZB_)OjYaI?jX~?oXvM-hq|pGY!VlHFA!xuC3FK_tG)8(^zq?6hljmpL z4#Djln4X3!4QL&>xjEtH<{_puoX-Od4L7F-G{vqOk&hgEp57?1s3$9q#bU#DtIMeA zY3b^xN5S#5xaay>a z@nW}(mlsbhUOWMMS3j9Sqy6wMWY6qhF=NM6KlO#*`-JCFUH)I|v`uu;X4txT$Rqf@ zf5yIv!P96v6P^K7RtL# zjTsgbZaH`~f{4BgOkvYz9JHQ>#9BzrnbH)&l#bpz&;)n;00emH@dH2<=iLl74{sWp zGz=B=?S$SoOxTgtItRvpDHkGubO(o=k8;$aB=c|0IH5Go9s!rLlaNZ8(>&ooHm10G z@yJ+77d+~&02DC#RzYR3@`aUlNq6OQfrDzkFFl3yCP{8D^H|gP!W`TSfNc%iajp&@ z_+1Et;mUFIBQSjqAsKC=01c=#hTDMs{S^lVkFb{pZRZU>#uYReA8ClRsCg949L;qf z!wR5s{wnC8cjkCMB~FcS%65fTyk)%x%0w2cCs3tQE^wu?Q5qol6CE2yi=200pNP*1dc@lfAO^+Lr*Gp^pZqxf z)j#p4@u5$C3toBkF-`#f(Lef0{FT4_U*qQG*YNtwk8r-*@f^U1Kk`X@@>_lnKK9Aa z;D`T}KZaKxKf=@JPXkO5Crm$;fl(+xuD1fqdUE~NLegIAWcq%Z4%ot4AQrts7@@X~ z5orT>!A}FA=Dcv(DzNoZLMM$msbCeJ#zbJ<(GUlg!P8qjm}!G4uBPK^p>N|)RsA>F zm3))$i){wMroE(pIvx4RXX(Rnr5Zf#PQi!?NJn@_LzeShWowBk3Qed~Y=~3exYxDF zZ2>X@zQ6g}ThKL|g`*%!xhDzRSu+!X>hLMKT z)^T_H45vr0;KAcp@$lvb4O9ngfxwqpXO#&u7$yA${|B zcV-jR$Tr7p&SOw8F zZ?4W$egCSYH$Zx%|I&!8erUse4&tS4O$WVgDbjG^!vzy4!JIn%!=s-yxr4Jt4`em| zIlZ>g3h+W&7qX<0gnS{vhe9LjlYs_uWsa6e7B`%0Q!|{fpJHj+)X5bC@YH^tDR(;~ z>6Ln@nqI2S*O10sI8GsED{Jj@1ohLIIk!NeW1APAWLVRf(oy@q;#h$9{bYdOY^H`= zCi4ckvgTbhBI$i|Fe7N)7EcGt;OrTO2?;Fh4I-FI3tfwoW{wO;ilDK)!y-(a5CT-j zZWBPegU(aC!P^LfGx(S+Bfwng6-%%EqIr%!xTHb0`qDKx)eJ()4 z9=4&AunHTq(3|*vtW3^e)Ve;`Pek?z>257lvowL-a%^zmb@C@retgNu?J8 z5=D5q3c^_b3z}|!U;6-l|9AXz*Z_R!qaVZA zpW%%!{|dhP#Vw%)LHHzp(LwzZVwIqod@Uk!Jart+tV9F+it+=x{0k2I;X z6;SEG-6!}`k@me2bt{s%rq7odSU4{6dM&QxNzxSQJPg=@jofgjtXoFnbrYb>s09;s zX>c^0r;M%!ko-)_?}|Ksq}EB}n8{bTKRHoshsGUO0{HB~jTHlrcdAD>1-C&e7Tw1x znR_z^BHsbrTl{Wc~X(tc1Qy`XzK;*v%yhi5)d7{oDgWyhzvPQXP6IRG{ zt%1^(@f`6Nhp-6G!yNdU6p$S3RI2g3%3NK{bv$9}Qug zu@VL?kDcZERlWrv>p@5;wXJ3USx1rvsOidblMQnM=jYF{-#$S*J;I|`J`9NB)F&Qp z4KmKy_uW#mC!o?X$HeXV7U#QLwBFE8kFfh0Umb`r@epSUt9QZu1P<78l=D_>I&x=Wts>$;BR zI-bAAo9lR%&lRA3WkP{AAc$id;{J^AV_M-V2kMo<2IK>rgz0E;T3C{-xc^0ZPwLM6 z8?GO-!9 zz=~kQc}=bvox3jrt1rIZy8%Yb01?`N5AeRwtN{3&_Y%%)3+~4Q0%0tfUXq_jU^TDE zBd*XM!xZ^>3j$-;sH8|3a_oDXU`7L^S1gt~Qk6KqXtyYPwN1d46beWZd;vZI6-wWE zDu$&|CG}Un!Dj=QbB_hHusg_1?4A`wFGrFU23CdTwaA#`HEjq+2k}OY<1VA`_t4}u zrg;RLwI8c6FY{C8!M>zs;8N@zt{08*MOQGou<+Sh&*+eCOdc&bb%$VRQ8 z+{dnf#2Q@9kI(M}83w&x&V(IEFzs24{Mh2y_5=*+$ z4h}TDKc=d4V_d-u13NY{&0{?}wL+6BreIVf7{?syRskAC+~r)gTnoh|4-K%3mG6g9 zT{UX7QG!Jqfrc_s^)zxwm-v&wig+s5&4uf?$O@x(E3L7x$@OiLfBhf*3$mbi)V5zl21Y; zimnT?u1Y%GR{m9;acob0@&xcm_+u2|CHAcSVYlrWM#EV&PiqPY6)LAG`v~E*QASjj z{aMyoNOMsTU&>~s|PI}7GqWfq+|OAjNvp~|W>Y)+s=MlSm0 z0Z$z-jt5$!TM>XH#&C4huM@b;QM6nBrNOA`KEXRRpUD){^?8mb|6ciU?+a}^djA>Pe4cwYQZm=|@!9kVL^SK_!#cG7zLQN2G(rhjy zmNuC^0B3AbELWI%l){#A-4;AfMm>{}D4ckCB&8F1VFKzWCsw=B^{Q>W$nyMdt^gA{mw7cH?*#$d42Gi4p{|LD_5JKSLv#szk_mQg z;iXBDWRoI(qJjx_Q;;U|h)OaR8hms{Ooh4gb}PCIG3)b51RLxqOO@%4=^b+n+}+)| zC0OzF_7)$0>18~;*-WTT#U_ezcZWH4bU(>Nngc0MYa3Gm6>Qx-g|37&7!b1Io0lBw z{!QtybUY~_+xkHTC4UDPiQ!XJK0gRR&4Oo1zy1&@JeVy7gc(H8%ormFp#`{533@H> zRgJWSpdZk~3y(lRD7*z)F2X!o_IKMp@X*ah7OL4sj4AhaM1K@gWZTW@OeNEZ)D5{b zrY-w(YVu;X<)ke_?-RYACKFgmCO{@aXjB<{STBC<9B<+A>-`sohXOR|=`uK?xk@3& zqzDoCJRg)At{LB}8sY7!*l0EZ@+pnFEB3AdhT0GSP0GPCZmwhZUxtsJe4u)Fs@w^v z;Oo@@%+faNwJ`iYAX%)fuTN(YNqW|t4>nhd6@VYJ8ipL*F<>rYIy~4& znRqD|8L=a9_6GA@H>fgYh{lckF5|m)%1VC5`W0C$H~BM(n@*_9BHg(kZRsrSmqrl7 ze_A34i1iBhR753!G|rF?m^PU_oARO>DC{}n-d5Vk2$l(+bi}?py;1N&ktt2YJH>f; zL~*e}lHVT{HyV0ZHke`cY0OO-m~SdHQ9i4*%7>%0f*g2LX|3L$>s#fkEO$WQ1_pn- zF5ebe-vUQqTB=Oti_3m0J+b#Xwwlu%O-?)JfCA3DImMcoQFM+S7&}fk9ownlMtnwO z!`yGN&pY%}!?R~^ZFG+IKfVE0tBJx5B5m_ehJXb8%9{ zP3ou4Q3qQ3Rc>4M!#b|ZJ#hW1#vqH)PScLH(fp*HgH_j$!B$j0bPSt|bl85FrvesA?hZd9{3I(B1B$L~Rm))&9QFOj`>z^P90(ZOXiEw}THJl^u@=Rv zG$p0YcYP5+NK#WA6Ig%)nb5ItqsUrEAm5$oD(jFv;>!1%h*2kttf|u`572GR6$qc7 zFkXtQnK}%R*HCsRegd2>VqTi_o$vI`z`qFEX0&@g?|5+Y5HCG?#fov=Y`D33gxzbx z?E4vg+wkDDL3cZ@a1L9Kp)R5r`6C9b?PU&3+jK9MrzUyGctg+dM8Axdjuz>5_$k1g zz`@6EA;6w*?M$9IpH1CZpguoTX1#V3SKHH0m#gY1g4imiSW#xjzBNF9;gxhSgUP6t zQb#7nE)jK5fp(B95XKxw&(SZ-m?-nfel^N#J;O&n^a1?vzw)o+10Vi4M1T{3AN%`1fgkw`e-2;zjbFi=PoLup-?+sYz(>F7 zllbhneJ4Kff!Fab{DJSq;|C9McXxI<>5)C^R92iuQNZ45I5=~�MU=&1+&9XO05` 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

    ZE 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�rPoBcO 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%0D7pp! zR_d@Ikt&zr=Pj{(by=S`^d*_>YkU29Ua!vpld{?wCoM+l0WbrJ5rP>8#DQEEz_t8M z4@Gi;Y6^mf4yh>$t!2899YPONl6r8pC@2$IaeEh8QGnHEAw!~ia2gevopMiO3#<6^ zpeAVGtHm`_*~f)MYUvYmm{MyYx)X~uS3VaA6ziBc0Cqs;3e15nfT~5OSPMNtYl;OX z2-gW;GdDO4pwDScN6heN6V1 zhsAOfQTEF3<=@>KbpqfOpjy{It~sMT(X$!~pX~QX3XS-FM066v`s-dx&{q<^?{FA5 zrtdd%dYyH+@j#SnTY^~D-YHGf{fuaq#ZZKR%M(^#DJ-cpbn)VI4scnZu!{h#VI3ow zQJQ-umTsv6V<;3IqT*m+fv8|Pbf>3*z8nl}OyIN*00%$^*3&hvE-!&6PLK{@iW_j8 zY56RAGvi)#GgGewKiz^aa3crjXR~E_?#^@*(vNXLr>GIMZ2u-`dz=?$|4M*bi~znb z;@wC{pId3g4U!wrs0IKQerB2h`BE@_zfWrpu$htI@`$>Nuo^wzD`1~vBh^^@Q!OSvn)@F#*PUHO;!FofAE{(>%v^pXUj}j?)o)-)brR>Zc}kFZ*;=fndBq!41~SA| z^D{V5(dv=V65h}2C0Kjw4ix>GOpU1C`~;z90xQv%RJ3NUhsNYRRe^D?5%%fJ!ou1L zq5xYTqE|ojpbUsHNGOEeoeoi}#c6|{cT0ycda{wIea?coA+MDrfM}*rX|(XQ|71Sz;va|c|Om&f_h9j+eQG! zPQ3{LWgC)D*LBQSp2yb2fO)8@5_>`_=eb~w3=82VK+Ph|fC2u%D+*vt%;I6^{ktpS z%=tg(P+?l5)hv{t+s$P`%TA@u3V=>e$1!LA1Sa3(9C?Ns(6;^UvWbC4ofaAw6&cNC zkLS6c!LwSoXVla`X)wPQJaW(L-$dCw$_F=I5^vbO4JSmts7$o3Aty!1Lj=l(44J2g zh~}o^p=O9MqlH+?qKDWwX>m?7wM1gB8U=4P&a8SmgGI)1CAqIAEU0jpQCFRZ89fQV zTX3+|x8aTqL|rjaFEUPEZt3$q6dDAaklA7n;q|a;cS)2rCQZMVVx9Csp6K=BkXRn7 zCRx-wfHw6mM*%z`5#s`nXwgvmlo3~|km&`@+hUoQ-7K|JC!||LvZ>ZkWUkj1vF9~E zX6qg)2(+bRC>x~MJ`Y#E8_$^USZDW@X|?sL@ujKNy+dml@JMAiFK1+^AZpi5?*c(y zR#OvGW+BcR)O9owFj(Ig9Dvp6XiIY}+5FrH`oeSRP1-z~N_9mcBEQwvxX67bzODxT zbH*9lv-6JFN;g}l-VS>eUB^B*ewn+#>&f$L)NR3e^`7M!>T9o#+s)WMtU1ageY!Ea ziPwTz0a*P=*3-1#P47FQStMg?8Kn&1nz9LsQn?v(%;-!NX>NWvr%tr>gg4!}hd00J z4S4q1XYuHfpWR~65HIA$;Dm7gN@5@-PehN;iNooz+LnM|u!h81VYi0l62$rBOJ;nU z6p4QC)I$TWP)7^COS)@dM^B$&Mj4}|3{GATzyl?cnImX*3}V=T*{}Qcx(qO!bPLOE z2BC3+_F_@NjQ9|N*Ql6&@Jhr(0XeEk@b)~w80EpQUIAqxpUvnBfV>HYLN>w}x|A^) z*e(|0S-#^!E`&fKPVqyt$6Fik!HysRwpO%F?vY}o-mcT;Y*&} z^QajsG|rSY0=$z-KBq%4C=`IOE>}P=4m>B{D1!(u6-<#erZx=->k`G>NYg`SMq+q+ zn}tU=jA=Azz|a})Gy!rr90KQv7yVkV9~liT2h8;v>zKHE_bzVTzKx-ZV?W?}UP7D) zT(2h_yts7bSm{L&zzcIln6^}*P4y+a-B6(n1sU}4G|vQZVHgTz!#2M+c~dp$1$|W7 zolNa<&{IE8OuJEZxkmvmcErQ&jPx2u*34_S+5_~IPV1KB0&GG(rNciDxf>4mQ zfC=LVyE7SsCm1iaFv5Z$6IMk^ic+-Y0ft#zc@@b$N@LmDwB;0)ejq?#Uo8%D}5Gkm6;-n56+;;{!p ziQe!#ZxxQ|h0s}_#@pCa!L48fKq_c%9NRh)2<#=Y&qN6{Q_0~T=up7x2JCsu7R>7A z8Q7f>9TPg{t_u(#tWD;IW}|1DOTex@c4xV}HNj!D`X*_xVKJMJP1we6qeaeUpJMa$C zkR2H~^{V6(RF-qUrLV2`E-(?ux3;gn62UV@uNV1Do>3b~435|Fn3Im!m1_dc6#;&G zTNpgYLDsOH4>6zQe5Yc{@X7Ts2otErcgq~TO#o=XNL=MzYs8FClt<z>M8z zkUUdBLNTcOP5cSJUvnN_??c75+gkf~Gu>sz9wp6jC@t2~IMR4PLVwao+Y7d#{N_&zr*U3SukkLd$76LyUUiscp?_BPLItVI&eD z&m70q8gu~bY2fnFt2i`88xwP^xVTu*TQj^3V5l`-5Vh|KCKd>;FfqpJvcb=mYGB1U zZ|W)G9TpwYJ<8&S!fG#emJ*+S6M+sEWp?ME2y}-(bDhgQLl(M)(&?Z_CnUIu@O{i$M9XZQ+^4{^excUqa{D$AvN@sZ=zt{{A{`V{-!t+mudg?62IgONuwUcca zz*{DDj$u;21899gZ_Hq@&PA;00uc)^?oONTgpg+SQ`8HWO~+9*E?fOQ9txM^Zv1S1 zPN(mQ4m&4HYt|mUHGKK&FXPi+cpi@)U13?4jC2;$O@n<9SNLNXqEOc?jV)p{;gR-i zypp?S{E6RbvNgH^j^4?43eKA0RQFp=H~xF$1@5-U2uzA9TNM!AGxWVQ@<2_dHR=9) zp`9JBDu02RU7h8h_x1l%8)^!k8~~LC``xbbjS`6!tjZBzp|sP$(6Fg(kcJFPw;^R1 zSOp4?_v=guRs}AF;?2VwEvYGN{OU$mSV9ME6GiIy_AiE&=66%cbE5b6$DFtxCqRIe z9bx<)Qzy_H`m$gO(8RpM6IP>Tt`qH+sT^)ZxmV6)LlQSW#dR zJG|@agEr7(=Q7B zkY?k4X9Si3SyMK8hqogG(!FM$3-yIaM&;ftA1{HheOk@gn--=R%I^fm3cKKn}lXtOOIx03R7NyNLwmPz?RB@ z;B>l%YQxf(tepdZF?!O7m_pr(HG<971K27UxlhfDzSZ-fn1u&y<%1%Px1^6r z`e4M1o2CsfXeb9fvq1+yQD}BFu>mdqcLk=KYk5!7nS|mSyupVj^}hZ+Q48hW1K<7p zlR`)XWo-ax>$tqW#Cp0yzjJ{T61Z&Ur}XqUObjeb!_qJC(#x;lt6%*bo`3E+Joo$y zc=+f9g8$YUaJ}NgKl;|ZiGoZgWZ0Fh5E*&ER=(Ss$zwJVasIhx6&L0{2-sC9(#)ql4>F;X z^}}w~a3RkT;r*wdSMqm<3IZ_I$oP@J>7U2Frg%h)(?v5m508kp_sP%7ez~FEw&Dw&|{--s+wJ z6E;lBG=R7kY4isoQV^hbJdKAHOW7JVbBKx=|4!GdN9PZ#VJDWhuU#O^g7M%QOFKdp zSl1Ph4(SWVI018FS%A~!HHJq%Wh9rKwGFS}d55>qb{Wn{!tTvJhAXiav2M``Vt)i* zVHa5%Va^#|_&!rqC z#;4~-R`qsDM``-0-eC*{f;laa) zI2>-r`q#an&c`*d^VDJu`Pp8#4qdu9@>uUuiq2b&>uF3Uy?G2TqmW3S@GfVe-};!H z7unj|8mZ&fsjH2_jrYMn*jz@{&$S>hq?yH5VQ`Ib} zy<_%{CfOlpor84+7I3}ei!Kq3yZS_6g{_*x)1I3pfn zDK$Lgk1J}LN{I$=KpccTU}p_DdquEbw_^w!65OC0zQoF`!v-aXitLZa0)nH;y&9W4u{}3=g|bMbj4bI|PEEDFE0uQ&llV z%xj_}a!%)L0p84t?@U<$MS2E?dro?{Xq2Tl54CR?s|f%RK$?Z+%3RTx1Flb3xVpT= zx@v@aw`O^&1MsL8Ypoazdbjr#5VGBL@EL7ZWXzd1nv^;hj21|Nzr8o}4@gl(>SM3mXbn^N3Q)4QtuRlH~#ZX&eo}pB|G|HlixVB)IT9%mfi8 zz~ffX{3z%mH;w>g@iG178;20kT%NnWh&5`=}{(#@;TGJ#uEYBsVJR$5twde ztSbvTfb{`-d!x}#1-?vnaS#S+7-I#{@bZIeeBq0q!n4mli|fmQMaQF5dtg860|DXRi{FDFgzrsVggJrqEFaP3ykGFjLcjAYC@&owZ zANnEOfBG(-dip-D*A?qLK}4_|4!*vQCz|4=2Pb^>`Oo3=U-%+E@PQw}(@#E)xt?%w z>xk2EL$uR#fJ8s{hh_2fXxnI+BWuCnrqWT@vCka3-j6{nnE<`9G)qn4WgKMG5z^)Hr)4mB@U2 zMmvbl)p*&ARjBJ^w9fs|&3&q)jcc^$B1{psj|GgP;1Ux@*&DK1dZwB1Kr?Ore1r-I z5(nPz&1a_Z$Bb5*B*65>md1tL*JL_|i5RYFL?H2C@+{{uG$KdJ0Wn}Tknwui)DKGI zpff$+({RlBeYkhQZEx_NS)QkHKBAKXWXxe4(9n;*GSTn^93|?XcX4YbH)y{64+qn8BxVL1`cqUE_s&rMg)fglv;)-)D+Lw z%{f7NXi=Ni=2)n|sBWDx}sSReXone=$Dt@ahGO^(_!g^nP@9P}W=0K-ie(j+UvzsQj<$ zS;Y0uZvy;m_doP;-xmnej=V9CZudcaZN~&!H^-X679TUmJ6rvRYaRlD8>m?yhhKxG zfJ&tN>84X7&l8=gG;DI-{Qn$tYoYmbyxKRu4kEd*@!47)Hhrs0%dFPfDr5{XymXi4O9|?SQr{kOerhP483;891rs_OYOxwfcf7H?fZmA>o`4n+XDN%q< zVvPYe+1Xygg^&ySSP${GcCL_*Ve4ZlMjh*EY-%@IWWFW1&1psL##k|7t2X($+D$NiDl zlCr3mzAPTpHE`?BEqv|kFW?XU@YA@yp15=GJ`T6f#3e^-^8!| z@-O1z)@@u}3;x-!{Vu-r(ly@l9q-2bfBY}v!+-g2;Cp`X!#FfR=L3A|WB&rrKmR-) zouwO--*7hgbM7W8ESn$>Ix`gWRMy5M*? zI8UHV3ud2tgFLr;9+12$*L$OEAZ4Xt3pGz3whoODPfjD0yGEC(SQ}F^9#v~9m>1ly zADT)%0M_Rr5Jf0qW~?+(Bv7zEpBpj73c-W;V57?jTmX4WM#lV#V;gh)h~qwwd{o4l zGtlklzBnV|{?o_f5pwD`ntnf%-*!V&*5KD=bhf}{k}@5~*K@**&wLhhx81;Esl3K( zq#Sg%s*jfSOiglZz?v)MkHSz?9NS`1=#wcwjw#IRgn@~53R>$pEMDJk zy0e1RfzN`O~8~k>NJ56Mbbfy=6pG28N{%}p)WWr3(_*uuvPh3G}bzPnWMop zV6$17A!rWAS7K+Wd%Hey1wC7xJGRvc;_ZxV*waqk*JPQG(+AGUrusR6Osy{Oo1p^1 zqnW12RCpF`sJzznMULs_GtZ4f{eDaL1}4*f7btocpmmGXf)(69iePDi(0{Ffm5FhI zVOlXP-kolza@-zC2S#gluNfm~{`~2}zKKO}G?{39;?~82uRQx@{Lb%w91kxCmgNZJ zQi?Fp`6EKcDDjA$JMr_~yjClm25s@wfB6(Q+st*-eP~Zs8y)$Jc>vY=ikLS zt(2Aa)7ms$%<*5+x%2zb@vO_8t*fnF?>uKYzE*0OIt9Q|M{O;}SpWZPfZ>EaI~o;O z=V8(?&VbC-4`cT*^SZg>yWT|6TMuIZg=2t5Upy;DR8YRVkVTt&336OC1XM=LIY`_y zU-Z^Z?Rjvu&KvREs9!-*T+Su|UnPRA^%e-XXcNp;Ayc3XXI&>`3WkSr^}d8bh;=el z1gqLs3Jwky?4S%D6lpFTI@IGsn~#l(1r0D09V-F1no*&-7bq3wEiI5b3DUNUnX9u0 zquX`L-{WsBxrF8Ysxa&3GmX974?;EfzA}5#M)r(1rUPZlt|m;xB59x<8AwjRoe@qJ z*)k!Wamo$?39Tf@slI>C4b136gFs!^jX-zis%{8m+8Almh#WD>og$UiaBjOPt`*pY z!sO?(N#Q%af%P_`Sf_9ZQ8H~aW=ZnOaRS@;)!?BWEFP`_;^2x$QS6c{gD^f+iI#$= z*bO3;Aq-%R%J}xM(NjV}4jBK+n~2i~ylp4PgxF_x%3*-WP!+{0)>?y4^ zKlcq67e}n?ia+_&FJP=E91ll`0Jm@5#;seo0VqyaCy#ibA<{zjFRurlfAv*7`;}+$ z@bU_6toW(F^zYzr{ICCa_=$h*r|`Bn-UF^*M4OjT0Y3LfpTQSD_c?s!*)N&GMx&b7 zw3<4xPHU-c#$iG4w*a+*ld8ZUfBMt-?B_m*(^zpl9?)7hns3?mnaYQ8qnb8X>FVa| z{QD%_8y6=(aLrO@QC9t{o4kGB)l&ZfG%*SUs9g1AH7Xgqz*B)-qJt&Tgx$kj+T(H1KX6fZP(N_;gK z0GL1*u`&dE#hvR+Z0CHFY*S-T>d+nMxXiLhbb&1HFq4Lf6$dD!Ex0;aN76+aS~J~c z9g5RbQ-oKxz}8rIJq=4ELalXY(~DHmVPH?a242+Ui`rj_b&XC8tqxI3UxA<(60F!e z(}cF?p9bc9G4hGEX9PN2F>cdRR}01EhPR-nN)YFbCzY3Mas9d1H_{)@{hM>o#hB&H z+e}??7p7|QEap`=)S4Z=8Edfj<^*~thA=)cXT!7@rf^U;2Ps2=$smL=A!Aa5FgfFf z80`(L=^11IfF0Z>;AdxI2;8}6_}FlPIihagdJ=b^coRex>jI{_*)!+rxkt`#&6(u& zunJa6COy$Q(3(YM(b6r%zaYl*010+I#nv1HX;xEJ1;PkPuN4NZdP~^{tvHNlpAk6T z5mrr`fXl8bTyi~)p9l%T$4uw1y-j&CX|-0$5DW7g*Pts$m9 zYs)wltoW^fGe-)x+!LElGHwNdu?u&x+8UGNMx`lR3&0iE92Mr~{x`=L;i$;e1AAX$ z%&F`a5I32Bs!@}o{^ugcQU`sV?K$qfz(lwX=Cl^szIW488+5K%uP)KXu$01e#RA2# znW4v`1YmVN)VuGQ z2+vV`Lj;i`l;7p6=K9%*TEOfBdn3j$i+!pU1~O@%zq$8@}_sAI6)$^&L2N zV64`OWX@^cTvY?QaO0^=04r3l0VsMuVm>>`(p#pZWBs@%(eof$*aVAlydHiu|n)?`AG-DxvPy|(!izxW~!6I{+V$mVlZ&~hbv2a%<~wGB8Xgi_48K9cBgDB zkG6d#NqZ_lO~;F_74TGrrV)TiVXK**~8xBl)yp4%wX3nAW7+ z<9%~U>x)60i4!!gFhSc$8Y;mf00n6e4%i6yM zTeltOVc6GW%(eIaZ|4Ra00a&|5_f~O)fpza@t0z zIj0<~d$M^T%23OHX#4x|-Ypy=5?Jge?-7?)n;I$K8^VdJ(Li}a1ONJ-PXNo{^6t7_ z`JcJo-Z9idW*yk102!56K+d96CA`}MWL(XMiK(Xn!5N*=X-~&%prGh!zRidNiOq;k zodq+3C@ z&n1N~pAT`PVYr0p-H&K=@ZlW9%}*oG0jr`14-+~Lo0$s}{Oy1Z`F*e8;_o7HoNWmB zO~{{g$;MdIfG}oittW^q39y&8p!?a<@FUUPOMiV590tK+i(Vg*0=snR7=U?3jp;Ke zR)`!5_soox)?1|4&*OF>jIss=xqr>6IeK(%2YXE*_uKwTSw*K-Al6jSFt2yE+!ndE z8*fRjg1Y0PD81?iwvgN#o1)O4$8Yo961I=QEUaW)PiVPpef1IM{L2rA(+R_F-K+>ZoI{*4h)2MK46 zppe$D2EgV4rxqZjUczHnOZFinVzXRw%J1B73E>b95Yq7sU-A85>C;SEHH%|qixy`u zCJ=PRxIDr-4Kg-Vt|Jpe$YOXonYa$%+JQi}>c$|Q#s(oB(qSKLq^ScZkYz^7-eF{L zC)9Gdz?WZr6@T#6ui@Q4_HQQjq&Z)YG4Qo-d;k)Diay7n8$o?>EWtDrtyOnH z%lOJQPZo8$*2@fmivhth^-C+56+E@bDQMA;4S<(Cfie-UHw5qqF=l|y;EtI_nI-vt z3Cv=FJuQM76B}2}?i7?Rz=*zJh|SMHSB`t~e9Gg30g0uJiq@%>CCyW>#ayEt)cMud zL6syGG`m^ao>>H@xVX5)vRq(U76{xKqhm#H4HtJV(cswx>j1`BaVdv1W_yp4{?Iwn z8muvx33%y)f+v6RL?i`mfaDmkv_s%H9wFN`XwAJ~KnB_bfJ*R|0lj3iBz`EMWGk8H)~OG#hK6d&OQ-A)v>-7QZT(F zMx#y#f*;JYhPHJOq|KDw+n>3SCpYE?PC?g!5ieKsoh*0r-rfb9gx9O88C46 zbC2<)IU`klFE-KaHRksR)zJ+G4ZI+pI_(m*eH~W zfyAE81bJ0^J}O(mcaqFo(gQW6lIOgeKRDpF1zMvPOGV zw`b_Hk@U^--W1kvl|fTKI_HR?5mvpnzUBkd*hE_Wtb25^C*ZM^2!%Pq+2N_2H2U~1 zrxC}dg*RJq;B-=s7{%cA!toGJNdVaJ2w3ctd_H@-5cM&OVy25reD21AgV&M#f)HYD zamQ$D9U=>!9gjGkuF(M;4uamyBg@UOTpX~-z&ZxT7!X-u0LJP<`n0a@JZu0un@&58 zGOE$TFlr&3#SiG#;k*|+9*h7v9f77yH=pUFPUpI=JB3}q*W^75L0kAF3>Yt4*~*G6 zfef%He0RK-Wkv*LlLHE$#(P~lNUpsg^iddk%z`mTXKvqzA(0X^0ILUQDF=PcEuO_A zqLVa%gAoQ%mLCm^aS+VLnuK40M$;Z7NzmP$ei4}o07q(sCs6|;c$WD>4dL-<;!^Wt6#%GIv(7+ z=SNkqC!dc-Pq8SvAG$^c+>8vXDwckUU;UL|#((z@{;tcD(eW?8@*Own&rSo<7U*dWJYs1;f^>l&bZ}e?UJ>9l z272^SI9@-)qla(e;hS%IFPq+Rd36a9_Rn&fZ}x*sp4+T{0K9X56N$cZ+<&_f_&vm72DeRa%#Sr~YjPi?uE#yXKr7;biy37Jo)$*HgGo;c})mmRhyk z8{B>FFv`Wtb(;2@CNS2i%$YR^NR+1_N^R-_M>_&* z)6tT&i6CN;|Nee2-C~qG`>t{BDqz1KFR5%%t`V4t$7_q1DCDkkt34b|fu#kdbjtvp zCw^wetIj}1?k8iPi8x^=$TQO93K16UM|y6Kcm}antO+p>DC1psNjSo-P3&mV^Tfm( z+ja=Bdih4{j-fQ1V=yo2QCRe8bhEFAT~RSc#I0f-eC=Gkw$up>Xp-I812EN1;6%>P zlS)};NGwz{-U?m}=Nskv6bp`TI-A1Az(@-ZxP_z&%;;;1#FJaOR@RcEu)TwAi^-~8 zu>aot*{8#-nabKtX7I@aC&rH^lMA z3g=-P=;E2-)zRR4L(tK%G&%#3<=!TO=_?j!I(s7+A9Gz~0T1TsO)#SDmO5Acf9#Ny8IvCy&gyRd9svwrw;MH~-}m*l95B<4 z*(s<5X-pMk1dASW&F<=XB~g$9#+z?TG~%J+%-bEro1dhRrA~3vKKr49QW{JQ`4Q;x z{_rV=jpHZ9Ot8IM&HPSXpen#7!&tz2sl*Eq=0|Z29F`?E7&UJLhI^S?M0%OYlKqUE zq1nJiBLlg^WF77~?aiY@%hJQk8FN%GF$xPNgq4rU>qk98fCMCrPL)NdYskNsg)-21 z!Tf*nzB@6tg7oIkZ{=V)chv?%6Vtwc(KCMb>6MuOFyn!Ey^-77+(e@fP&$mmc0%9&jV%y ztslIWxpnkDqr`x?({CuSEVx(}jO%M0*Asg0=>6bLdR5_0!vj_wIE|BMR9QskMPSio z|7`R^N&lF60Nu0)S{My%%%yR%(^Q9;r4z1Pcwz}@I8$100SARIlI5eBVA|sam(#eb z>F2jSQ^cDH3T7j3zo|GT_l&3Jr4vTrFrOu*4%Oz0qudlm%{*ZVyJ1d%7Z8okumERX zGGJisE;A^$z=`j-RNe+Uw*n0E1#`ezgOI?V-?iJOS+3YKZRbMMp?M$W9M(`vWwpF?CA+#f9)Bbd*PjU?jEr8hP(If;ni<` z9l!s(pNEZsJ9q9tdc*N_#PN6y9p=4b!s*8TJ#@g$lx^|-U;~%;U&0$t2Htr16jwIz z-}|%wWBj?l@*m-k{i#2NcfWKOpa1n=!0&$kp92Q`!54lXU;ElO@a3<69is;TH^4*z zU7_oWF*NjhI40x0RCCAU2|5hN(}3x~#l-?u!|(jg@8IiS`#SF5zrdSsKEzkQ`V|}w zhg_SzaWLKXl5@=cT6EKm0K{fJrxSUuLvg0=!~{!8SY}zBm*Lac{!PO%SJ))WQ6#x; zS{)l!ivCdv(xZ)i@FflJ+yRD7b6v{O{CxwEL#{MB6;VE?uZBs~r;2O!vJu)+5&S zg!OoG`Ys(Nf-xG7!?RoNTpZB5xGXVogIW#iSfiytG_ltKs9|Y5p;V&D^p@|Y3}9A~ zWZ=gnngi$FE&LF3s-<+kwI;qfcWncelmD#PMU-iw(PJ!eyh9lWPl=oFBLC32GT&L> zf9~h+b?xznv`L4}Qw;g}21^k{A|=emu)pa%IwNFnqO-huLmUG>0z>)QXp{h%N|eko zV+epaZ-Cft3@kQrR90fd9#V}1Hd5xmlNUmdolG&9Q451f&ptm-uiwP=(?=MmXL-sI zfNZ(oeopSlPy)g%l&Q0}L4`>VAr^yd8hbk;n$I;LolgFiKG%^rLneki=MbSdrE-zL z6)dZ38{Sj!6gtabj|BvZOdn=_Vam>PyeY{S0B*ti-_P~-j-k$%+nK?gV^;FJoD~Kh z;SFNy1g-p=FID#xD_gUv&phY83a*>ap3D+($e3=n1wJT$tDZHVr{AB-7ubw*J5SPq z&-7mj#oU2Z=_eREo074P&6v8b?kqa#z-0h_Gld2a_H6GMqX4Z776^`GIJh0YA(rMe zTOknfhMgKt8x&@0k;BWQ2h#%!>{4du9LWz{lXF=om6k5FOL}0rcfZm0PL$h(bxpaa z;GzMyTP0B8%rzFU=K_RHhg+=MyvHn3N^PF#WMKA4q`9J=0<(3>@$?kOC~+)#f^Ju? z%^Xk;na>x@iTJ(qGyw1H-r(6gQ}NM*p2kf`yn0d@q(#Yyf0r~KtEcaIX@jEmhUM}S z3PTTr<#4!wo{rF~6^G0FxVUY*b;Swp<7ZcN4jgB?IQa+J_JA2>)hS`+`IJK& zQ7OU0lB~laIFC&sa?>Hb|$9B8=Bo9yqkT%9OwkVeUd&Lr=gM*Z#IZT*19PhJQ5g73WcExh{8H}US5pTlo`?)UL4|KykPp7*>D z&p-bH9zS`EF$PvuJUyOpGEFDXW={^c#zg=fBh%m?KYoZ${rIQxu6Ml?W{S%T!KXj@ zas0i%^MAwVKlf{R{q;BSrLVn;=U({){;UE0a2Fr{>3;+7|L~`9I4oGNk0o;GC_q<5 zYl`LI3HoX*+4YQ;)9HkzH=NcJu1|u~X~nV#)^)`fzxV~14ZQk|Z{o@IGaw9*8dRWO zclsA#Pu}Dn;ZmN_b$gw7L;uC^+=Ddi1OX^5xGeeIHvE)4ROAeVyh*%O{?5H>misrj zAvR8#ztEsni1m$_v;5Bv=jA>=PZt`;FnCr5b+gRPP#q4r*@4mrP4a&{7CQaGQ3swS zV*X*-Pb{&L5F!FUA8b&}JeH^HGV!0Ck3^^=en zOEl~~2CuOHW%HAi%+L{u5AN){+Z-6)7evYPvT1UF3U1MOendO}cZ*IAG%2h3YVSNDEns$OJaD9Cp4c^@$4U3A0$Q*RXFCgm2Q8QZy@SZO$ zJj?QB%<<9TN}gvzpSC#7O4ppf#_6N37d$9x;~J;+8qba=EOOz#)a;>0+F)YWR27yP z*^U{eZiCS|H1|2B2lY^6FPHd3_9HbUe;~04Gf>7xZY7o!w}I0J0%gUtTR8x7a+O^S zSc-VV?dB<*=*tY!*6W5nTmEc#3&!~#*V}f$xKf#Ej&p-W$~z{Qa)9Wmm-H-o^kJ4h z_)%`Y!Tlr_10xKnND@2DBc(*xgQjnQ%J$z-r~<%RHu)5(8*74mHDt|QGL+Of$QHc& zhNQ(^1;O+%TWDh!l9CMMwaX3b=>!ax0y!hCa3f#f$4LvK=STA{{yHSG6IO^S+Tu02 zFyLg-dD{#yKif#k#%LkPEu0SAOeUVzxk!ib#3d>|?1kd|IUQUn)TH!MO9@p~{S=qB z-OREPj5pWxoa1X=bh>PX@%Fmq^UZfc(Eu>hjGotVrNJZuUxSPLRnfjVWgEtXe#2^@0 z+67j4SsHU@Tkik{TED>3fZklFjR59L_a?nMRxDzEoGaE$H%`N_8enGV1R-2wVLYtO zI^%GF$=rmo9>XUk5}9^7OH9D%pFg+u6?!Xvs((`|aRd(sA{TR^ktKkEcR|P<`zoL5 z4}-=j6OCXeF_VQtZsiM@y=8$}PhWV6X|zlaPX!(Cn~oJaHl}0Cb5c<)l~Ay6g*Z?@8=S7Vc$ZNXwMzmKit* zh0jG`q?2Q5X><{ki9ev&Jp`qaI?W30;}vyxbV4p1p?q_aET( zM@Rg<|M&kHk6!yWzVfYSxIV7AEBu%5i+(n~T8U;M%sVG7)T{yv^vA8|Mwyxdo| z;7vk?r(8f;JM8Y2?ceHZy_GRS86z@71zE-EJzd(sEGkvVR3XyS)- zuNZJk-A^wow|Np5V98E{%kf!mvBk5Y8U4RukR`6qAYI^EZ9tS1xHGBH^%iwn*W7?? z4!z$C#Kwgaf)*>fF@IS7^WAuiGawN9-ClnlhQpzbEDy=t+RReI5D1ft*D_K=T?`{Zs zWWA%6Ik_{VVU|6Gst({>H+iVajWOMdCoHoN$hhfSr{jDoEN2Rxo4BBe>GWYl*&8EG zLz(}EQZ``e-5WuL=Y2--{e+}-HCWUVimhmei=f*H;SYBK41=_eaq`B1XaNo)J=k07 z`rL9O2v4YSg{tUa_j9jZR-lZ1dM9l+=gK3S?HbgR(vxH>fNPZSoI$+*d@sn)-S79^ z_|xukUUQ!IGC6vFBcv0291;6;cpw$24Fj5HQ_m(Hjg1*0Xf`4R(Vt7FTK2fZ1SbTm zK+Ap&mV%`s<>2NDIIOu3LcDW-)^$U+yIS@p@p>TdH`F47 z##@FfuI}7LTkfFu1*;jJT^}K0Sg)UAs6cUo=x~P~6ec6nR}Jn2M9{ubNjCs8yzYNm zF2RD{xHFro%Jvis5pN0y!1>*z@Y&?qo6#Twph#P+y2#ZgdS=cU@jG#G$_5$${+-BC z3x!nQYi$P@f)35%6f`O!P#Mf|3;Bhg(;3p}Fsx&lHRm%0J78-XDE`1{(1f!E5d{_t zStkx6sR&^JS}MlgomCtgX-4%}_T=BIMo2iXjH5-4oAeE0`ufPci~5JnH+`?hKF+l5 zpm*HEedp+yXdogfARkVN&*q#n`WWk_@%JpTAa4deJ+u`LZOS)}n-fEhkrUUA%;XId zSWp|$m{!uK%$d;{RuK?~q}<5C^6^ENZr+Fay!ji*`_6j<*H0ef-rWcIz$>rd(VK7J zyWjpcuCDIk>R!Y3(**BDC|yquRp@DCFD)KFt#KUZ<;7k6!+-D( z@#+_T6Myl4^p|nehS#4w!9_EC;wSz!{LlwKf)^ef@R5&v5HR4)*S?M4_=kTBAN%Ns z@Y8?t&th2)_*TqS)qr)tx&bnv2K2T#f9r@-ko_px!*Kuyg^dBV5p1Tg)^Ip1Fg2Xk z6-RZ$unW6*6}rWKb(|6$@D?=QVubz0`=+kke4qPduNUhY??9v>fasVqLqJTIOaU5x zbIh9o$FsI_lsLhgMWf&@L)q*(t|@b;^EjVQLltZsUn91X0AC}W#eL9{d)`D`CvWya z&*r)8d*g{B0u(Gj49iF|#Pw$Bi@ZbNMP?h|hfVJ8i21684m1g?Hk{)bG$c)9*dpGK zuhJ4>VheGnc!^SAY5%N;HgfsnDm^G&G6l(_fIE^}+>_bL){;ksWeUC!fpvK6QuIa!ceKn3} zZ-NL2!h0}^Mfi4r>j=0I}I9R%F2lTU+A53o}Q%Rc5!= zX7&pl^A9x)bX;5>@Re_V8}iQ;Po7-kaB%?fpjCQX;H7XZJDnzY2nm_k#G8sw8pM%0 z(G1$@;Qo8ZjAA^26`<`7%67AK_9N`$JkBAO()*ls#7>U|@n_eyAoiK87Itvyd&*;{ zEqEfaePN|@yb7?He=)-TkXQTOx170*ih+|hkcc!s_Ty32C@&&-P;W%ER0GK!2vh`9 zFaX{$f2Jj|(I|y=B{0B+u5{VtrWS(I(?3d$@l+(fM)c;j=wrZTjrndo(PS#VQ}VN$ zp0pUFD5QJx1UmUVqRXv$Enj4NngG%r2OGV4f8ELG^1t2Rr6ibXpb9@eLhPWVC z0eUudYu>C1UV37t382z`cY)WIN{;4 z$xpe>OT*uyRBt%&1d)R1ZC%WYToaE%jRP|$-o?Jd8BG8@tmhK6CqBNH3T0} zCZR+@G5?)M_f6hmEw1-On36hWnpL@(_&;m(XI8O4q)$+wAv zg_&Kz44o3){s@IdC}5PwN^u23eYOdUlO*8d#P?IF^fyF8o(^UjB`Ix#QaHnrw97?SE(Rh|Rx+ za-_&VW`=1v4x1IHUKmsavW&um`e!HaT9fc$lIw4dX^73|2IlgH#gwgxy%@Yk;KwnM zMqIc24O4ig@mtB~I>3!?PCbHw=um4O>7>jNVD_}&9+M)!-GE4Eh6!wN?y)|J^ThFj zpwLVvov4dr&@A8dhOLenMIr=tL&waSn(cU~vX@YYQx;LShO->zb~##RDo$MP1R*T| z;<7*iTJ(>3^ImC&)@?IiFDIV5kTT2rEzEUhKe2Mq-xliyM&fb0HY8$zbb#6yObnHAoAcSUOlw04PgDAv;nA{|`^#1un$I?;&z5mHz>h61_{ zT(l(uNC2} zA+^!r*pl>u;gt))i!FNqmHl1z2%l50+wlATP8g@R07KF_ ztYH6{1EgIbx^%&C!s&F42QR%JANET4Rr$Lya3*6A>;yIE^a3{ma>_l6@PR6G41huX7G?E z{0sTGfu>u2NC$CzXI)P#Z^a+-dfO#P)0oB-*6|;f7Vv5kM^M{T=ze_i$&cg8zAusH zqylSk)Rs&mp|$WBqd`?tX{e4!fuo>~RH#xrN*3UM%S2-16aXRsJ?@##Z_JdKHGuwm zC5iw%P7GCm1gHst#MjJdjNtls#1Mn$jK>(dV2$(24jIjG<*ph{R?)C3aM3yrt@|@z zkS;i`UK7}*L7`a3G3e}diA@cMCNNvk&|qx|LqQ?3L@l8K%Tg5bT-!Ye*n6KRAlQS< zn}YaUCd>YPe9vw7zt!jG{zi}e)}t3eg&*9<# z>D@(Z)YW!Xtk-Ygw65sgGk*jPST4}*gl-GeI-q_kDXfL@9?Cp{2=_x6+*TDQ_m07W z|2t`54$(Sk4(DHfr^!?n?F?V+BhmW^ay6h0mQB$7J(6t(=FzZR4Mu?_zf0#6m&>2) zMhaSePhC+e5%R|bv~~Q_<1>rz*knIa#hXI$wX~N@NU_wd#4x-2|$x>)ka%G{Z0Lp+vVJJtTX9L&Q z-Zz1Acnkwm-_1re+8$VsC;aRm`{Q`|eeVK>;vj~rgWy*_^N;c6FZ?#zdcuc3_(2@r z^&$N6AN&~J^RD+nf9g-*!=L;#UU>d_y!qNU(VF88KxbbxF)Z-(@S_@z#}%jJ2_cj` zU8$fz^c-kYJ`@GJ8Am$qTD-?@a_^B>#?|8<#OHbZDqMEe zmyjL>M~QVvV_8i1J<}}XdMM<{=R`PL!~fhcNof~}LkbNlW@S#jgJ(o|}|00>Wozj-i%DtpF=8WJQ33&}eW`NT8S|yz0D03|O z8=!-fS&*J#FEEU8!mtr#w+cE-h~aw+Osyw8d-epESBI2+J(@0$49uEm&~>+OBzeUN zv8r>6VH-m@rpg-S+7Y);dGEYAPnyygN|t_;2QV>O z)gR{^wz+CH|Gsxt@9|e1>p7XapG$r(o>B1|4}W0eTgUA+SkCXC9d^7c-{ilCe4fFb z`V0q#tguB};La}MLeFqng7LM~fSZ+cQk$nCxJNaJ6^lv%M1|qsccRWd zEL3zHf;&tk7K`sxgmA1+{eVb%fPqzYVkNiOERkEv#L6UTE+AZS?n z1sL^oAU?qcBgkP+t9!+fxI@TC#1Ek~G@rWnaCpOj>>Aww z=>pjB^xegsEII~8G+MO;_fby7tfL~F#gmXGD52tv(U174oB!V2=cj*8 z0O`Ox*Gnj0rlU8+XRHab1dy|LCETJ6(!bd+Zj+;@;?( zkz*v4YxC>9!Na>+*#}!^WijnyUjQgPBUuhN3vy)cE1A!*J>SH}w-AVFH|MLj*)p39 zoS+r|-qQKbeTR)K*ckhqw9UVX$n5bU)A?;c8uXs!R!Twk-k`c- zX@?|=Y@)}cBubU<47j6aKYvQc_%#ac!RHSthm1D2$J z#j^h0Q81&Jp)tcRR>jCqX@GM63{*($QRdgo(~e-k?0FQnM##-{^1cPGB5(8B%Zfdo z-#cT@>AC$g0oPfc@msR+69~qC%6F3|Z?PrL%wpp2-Pm|{6GTdvVQC#54bYik*Tk*K z9#tV4K~TiLg$~!L7RQ1#=iGx!lECRSOEZPi2sF5ESP*pJ}8?PrC1&8dcsn9Xh-Od}f1Ziwbzs z0X0-zBNc;UWNCPwX_EoAdCDO_?+s})Fsqx&vj(Sb>hmdoH%jmidA+?17~?_F0!HRc z$}mKbN61z!EzDY}MlamBY9yGVH985L7~YNF6}~cKFpM6g;+agzMv(N3`+MDi0>Cpu z3Nn~L#x?wgF{o^sqZy_oGV(o163?P=+?Xj_VUy42RLoOOUB>#U3_a$u(9xoR$b!?V zSb9e@XUZ0xn?)kfBjH$4j}#8@=stsJhuQGvs_HK=_|ew{fx}i%8TUqjtVvfy`9xXj z_>~JoITs)=EtLsJl4hIVNDJF2(A^9BxO;AF**|GP%C#2pUP$vKrN0V4g0(iB7C4Pnzd zCEA(BackblZA9h{!jn4<)fT})gGJ*>b`Dn^5OjRf!@r zP&Hyq;DyDWO{l>S-h-fl?Ka&AXlTisVbsa&sUR^Q*4fu%Ni*UIfmz>da&O+~!(s%J z15D*jc{fMyMuN;7C*Nz_=iD!xt|Xv@Ac8nsfRW%UK_0&w21$TuzTfMrHFzR;OfVZ- z$E0LFDETEm;U{~3TX=-Jh+1&c;yH2!Vi29pZw&<@y?fD#!r0uN3mW5 zU;N$Q#20?!pWqKZ_6fZ4_~&r<;^0QcP{;wexV+;{3Kwt4+aS2Sx{KC3)D){K*7byr z=}>Yo=5_2n7Ns?JR-cYX;OEzZjVAdhagd3r}CuQ2Vr+G%wxG4E{a)VSATkHp@y zXspPQIns)Kim6?r00Z;TgR(a{g~(WTd1I3%$Ss+&2O%d-Q!1hEohgc>+*2`x#d87^ ztIwB>;`1n9HiC?jcYxU_>hiXhM!E0~CpGy5$bce=EHiNAkSqpE;GRcI%Z==w>~jL z_M$@r`8kh~cI0rv7^je53zj8oHGgd-CiVE-$Zeak#)bR*3i!!wNx< zjAAuJkELoAFsK&Ups|Ncco@M}P9ShmGuN;h^Xz%3NMr#Ua<7cwhsNdQ{to;{2ai#n z6ep0sa-dmDHy7mtc_>#R<-(McIp)+Klb3*sueUOCo7Fu>W0MiiIty;t2|(&qBc9`+ z71@8q%Cx`N*lJb{os#=^Gd{*LV_OFr7IZK5h|*W**G91tL0K0t&mS3E#(k+;T1a6irJ( zB9TSte4{D&{8YXMG=pHktocE(%qG*BrRdve2JdS*aSdh*wtVu3x!#ro#!OdV(c)a8 zfVI458ZqX>^l0}?7wX{^o(-3LRYX{NFy++^C?DWtru`6h;5pZV-JcSQ=*)u+CAZGa%+92CQSv=%2I@jw1=_-ctY;jR2{` z1?C%$f}U1QQ;ZQ__;!M*gB}f9@rb@5?mle_z!bd+R65jv3jneRMu6gB?ogN@ZMzQJ z&x!|hN~yf>Mz#QH2xLt(X;tZan_#T8z3tjNZf4}|yaL$1!`$asPTF#@?hcYJF3i0F zpl|Xfk;!5MjOy}P8v&N{gEy>70~e6eB+Vvrn#Ugtfz9l@;U}%Q05lqY0Hpj(eJ_F( zhKP4~G`nGpfdv8^D@?neVr1?Rl%?U>vw?N2c(8bywwd8@_dcX8(AAHQYoRFI5jvn_ z%{euZbm$;QCDRxv{6hdnC7%wfjUnA!)Ju=<|0w^NPK?Qy6ROvXcW<+sd_0*EpgJSa z1d$^7e2Qrv144T zasC#3v~z^yrb2n9_z49w-al`$1gvu%*ce>_H!29IElL;2XYnYFk^@G&MbeZE;52Ew zQEo|=IpBs_r<`-h?^!mEW(3{GTiex7*~dBUL6^(9da?jh|7$NDH?Dg3o+#JXM>mwm zfXTp23092Na9mFg2xGr3P2zZZH{31{mpJsr*S32Zl1K-Rf>jOcP{=y)V}Io5Fs_ey z`uH*KyyFUg@vr_heD1Tqil^5r7JZBd_ByWQgx4PeU;FAeaPPTy;^iNB1$Qp*U|c^# zUmC{RfaVzj-Mau|X&r6xRcYcUGoFqoJbnBacQ5aROm-7w4E6Hp#1sY{C+IkVa4{)) zgSO|_0K4z-p8e;Q7cwiO+{LTIk^0_x&Her<>rX@w#lJx zU>F2Fn?FNFgY*XIibYn)p`)z_EDLQG zL2nn~-|~QGhhkvh;&6f97O1*mP1{Him>&wS3h+#<*5>5gV2_hq1<7|NQ||QOJuSQt zk~~W{h8V#UoQ_Yhu8$BY3RrHL z%lz5%#vJ|{Y9FA<6Db}y`q7Csajf6C#dxhTL#Kq8nQ3K)RWq{0Fqf< zRi?VGaXF~)qz;&c<5C01_WAz80yk~TX}eT;U#`mfw_b140pkqZdh?XKp!(JTsLl-^ zaBD3Z$NI6;#%8+oL_$lQVRTWpU`Uh&PazW72hws;Gz}C0paRTfaYmvX*!suM;jI`Q$?b<%4egNi~G=(1#qh4=Gl7;0F} z=i6k#s;j4Yo4R0Xaayu^uN-th%p0b*$RSW0Q77N9w3#lv6;3vB3@S}0pYXoiFgw9G z#otVM=a2 zArRlUL*b{0Eim=HE4@eEzGAt$gd7&w@P06=t82UA0OW9R!^dErq2mPbZ6M;jj~SU4 zSe$5}=y593W|I|W6AP&z7E$U6e4RceU0vi1FK_uO0k;oi!#6W)gMXjK!p6~u2}~-Z zQ$MlPFjjl^lfiT>bAM%K4t(EwRx95{Lj#aF9m=BimnT%*yxNwp0k-v-YAph>t|fh7 ztx=9hf`7jy=qe#6)!f((IvG*#BtterSQeZj{*^a(t;7iGY$;Y+{!TllTd{I@u*im!gp7aA+7aW#D$QX~twbmeqj@~6piu^cA zgmDCz4VPsy(4zdRbqSd{Hb#rcj(-ZRfpFj!U3Vk0$~7!2LWc*jObC|XhnvoqO*Ht7 z?xWraW-4;3@Jh(!;D&;$w)%2|fxvwRkcF}N_P+J=^#R5hCKwP=f6Uq#MECbrF#l%Y-L)oR+ zUXiilNAhg-Qtr(-kw{}bBrrJNR|1e`mRU&&Lj<#=3gKX8mQ8$Y6gnUtvgjLv?LFi~ zG0+hf3+_W{q4%}$#Tm6UBkFaj$h*|xk?|c3OKWspIMUSrzE>4IO{UF~51%d&c$c(k zO+52J<5>FEvJ`ZT6|Hw%94@=_%`~ZVyuwl4rj^U5%Jj5X} zB*MTI1pR0W0YeA6g?v)SFeCW3H$NqlC*hgdEI|sIvF9DLEP$HvD8-(try)&UW@=D6 zSyHymea2vrnPq=8WRY$I#nfhfZ_!2jYa_417T7;$;}F5t*<1rSh>V7$NBB3m6{nl< z=DWXFGvNJL=#W~6VVsVT-nej>5MhF!ugRW-EUVdxlf40M+$u@`}<^FfoI zS(%`1WpVaq=wEM$53h0%;NsBn?Qg$|-)qlcW?1@ii<92@MWXaO16`>iiVcgou7;^M zGssC|7a1LwvJR0Z5ZI6`2 z5kL-YfwjdAe2eB^rU>g7qaARqF=q=UB@MkV{%&T{G%K}{4I&*Kh9%Ov&|EMDdc+7% zu8u+}L3&j4=vK~W`@@-wpx~`JmbA{zR6e@_Qul8-^Xv+O>N=kL8{o=z-pkAqGFnNA z4eP-Wf>aQ~D%Ktn2Yz$P^?5FYIg-YYj84qhPtvf8@SrspLN=6O>Heps{(56*oMT zz;nw#1W`P3A$hjuZWo^AI}Mn0(y-^ce zPaE3o9rurevX?Y5^XPYP9mjRx z^*0~kaJUGboW`AM7%S$H*}gRN#rb4i2YNGHTpiFlTv7@kalG^0t1H~Sa|c&P~i_~+JGr;VD zz#eK4YEzB&L*cwJz~lNJ!A+wvUoZJ0&sHo(K%3cW)4_mnFr!G-?ikgm!f!hIbE*ws zX%Wyi^tg#X=e*5A&JRQhQVVQ{C|3fqS5d5+nMG!b0OCOvKkSBBo!A?j_xtjzXUlNy zH#K7@h7=-@!-4yI_N+xUny0%}8N9!YGUt{*CXE3|+uoO{ub6UK0UBPeoOG*0gnTQJ zVG>y+I->tYlsBkBYwsO#`^qn+A zl$N^fiO8yQHP*aTdCW2Ry%S&O7{XS~OnC?d9is#U!L^r}WI?>@Y#W-(h>u*4@O09B zAa6sPy^h^y@ckjLx7!28h1AqKMR7Abr4HEphzQ_)AWq&;);)s++yU~`Ad5do&9F4@ zQQ+nB1jpP2#Y1Oq`0krj(lBb_TyUn_3GTQiabqJ`FC|Ef@^GH<{P?XmmNYp7Hl~WI zD?l;;0mHPNBh#P*%c0{m6c?8UXp5+49N(?ZyiFR`*Z>WFL?-M2M5f9KHp>e{u%=q} z2uXuyA1Mrr%ntojW&?4KJ;9EI+aa-4*=SNqSV*}IU2hVZn_&vRn`=Ot)-|d8wD&x} zm2>9%^|GJaY_tBc{_LJqGjGtw`&BHul20S1+g4GGpuh9G*KN`huM!QnNFM+z2uyun zu;7nRY=vLlQ{O!!jmURQ468GvUfwp=*s75NVq!6A;zDL+!TF}8dLNT zB`Q(V>`tC;j4)G-%%Kg!T6NyZe+NeFyC{V=s1<63sUL_f>8;OD2)b*gGa!PGj0!mP&_+I zHz~6%^p;RRHHULSfH{s*$~8^lpp}rok%PrDS8zHKx>Hh*&$$52TJ-9PXE;HSRvGCY z&8_FF{clEwDVO8&|^~x*n z$Fp}lz{fuI6L{|rya%l}{Ll}-A2xt5{r>OaU;ffR!iRtKXYk{n{%Kq+OQ1(h8A7`F z$uz#c<8;IqfB$!I=jsYwfVF#{D=+u#7&(Bcs76^e*R_X>YDau^qx`Y zd93hWht+>K>r?r?t{EY6@CtK{&#iNH25t19TAUl)uXJ3UA029}xYy})pvkXJcWvEDK&?##sKbN1WW7C-tr)wdcQZ~P2 zg{}yrO)~wA5md*h@sH~+act${tr2B;Z?1^4CcPMO=V>Qg8|7(GR5zC2tsRtw|7MT^ zF@HDQP{aZacE@{&aY`xg1z=H#E&~ux$8XVl!uuyU{iaaXl({^XJ>9k;!Y$T$W4zEn zAM>=u=^Qza56@lOU|FoGuq{B0BQktk?>a$-O~f?gl)5W@@$3za9jvBUPb*dc(hu=I z&-e$_d%bu%FZyzUcDV8~232Ux({w;a@Sk*`36>sV;4$&95?jO^TW5<=iM4GWe3e=9 zm6VSy==zCi9TNvlwL38p;Pdqp-X!+)m^=+S|ATHuC+u_zDk4jWsU*!Cu(!ZV&ESCs z%8Vj|Nb~)5F6dqFtr$O<&Mff_C5==$M_PoStWEm)y{Z1BJeGQ|(7_)#u_LhQbwimH zP(8X1G^|foTwDm2)}c0HZwfkif+vF(vA*i`^tmuIr9maSgBs8l?<=Vmy*5EzXjpl$UB<#!eN+chlf5+E~M=LSxM zS!S_mI5Yg94e!Ip|7kk4rwtw}l;a_8N+f2kvyoYn6+cqfD0(}%y{3Ljng4AUge!LD zmS0N)<+pjgJqHX0t3>)OH*zrSR^f*rXuRLhdjMx~Cxe$G(b#Or6L6A{p7~J?h#BFW z#1!U1gBbwatS%tJi<6sdF9@bL&{8R4CkWz!U^YYxM^Uyj*a#5uj(x#z5M~&JV)tJl z-D$U~d(pdi_C&NH_Q-y3=&fU24d@*U238$7EDZ;yNSmQ!nNALb;xf5k@>UF1ZLh$j(ZMl z=tq!CzJxmpRUFDfk%rb6jMg!R;^J_Li~BEOJbZ?Z zHN->nBU_ul|D^C^@61BD&a_)sSkWcId_F=Uy{E6u6Oag)X;4{aG!*3kuMJZ(FYS_> zd|3I&m72fb1C86Lup7&Crda$eDToStqKwgsyUJQ?4{PyNilj(5HE0v^5b2HyG3 zcj15jzxa>wx!?R1eEIi&2fy|6{~x^a!H>cI$RER_$G~@Ae-rQcz(?`i3-7{{$8X~C zdPM7j$oZrqOhc7tRJO3NPeyjB=&i zKbdImV}zV2xYkk*#oq&9XG6ny%r=@iu^5F|L(8VU`86q$zMdGgJH>05A1f{qA+@Cc z#0!#+Y{`8zAKHs6oMJl z@}pEq5D$_m9j+04oXuDa>B4V@*$`Yj`vpKYNe;tqiX};2m8h$vL795gyC~=1Q`hh) z=WG?Q)m5N8YDEr3518a5^3-nKw}yKwKYM;)J|7VfPW?YiQVbG-smgzn{}=H-l%@h* zH84i-fx3Otn)8>mj@B2ni#u3Ea6An^RV~iq7R+YdsvU>!M&KI#8=*nhCTZtz9IerT z(8BL%0MuJOAbK}SR!yPnEVcG_0_+pUUM{hk77oGSMc1iq;yFX?2PeJvL?Rif*CTk) zBpodpr*1mg3-8rEwKH1lbu-|({kif$E#=?cP_Q+hX-HcypBw+eHch52b!$i%%0SAo zV5y2Bs`GH#nDJVhG_}=bmGa~~qr<`dgF^(;&C9i|dvLRXs1ZC&hAY~dU@^g}D-N>Y zAjC3sj;%0LEWP2-0TJgN5rOpXC;rHS)dYvdZ9xk<6}Sz^)F=EPopZ%jnzjZvEagRD z>5yx4e|+-vDG|! zI=2#9o6S(k7<(g$o2d*tK>`=_wzMMuwcWZ5JoY+I=E%L-HqX3i^sv#DB@R?%R!c z3SldE_;=h`nDwPo$a<7CA#CB#e6M*g9`*X32{J*z$9%FWXcm4ogi(q}K{VgZgpA~6 zi+yDQRQM%kk-(4u|Fn94ZHaqZcW?V53&0E%82m8h3y2)hFE6mZ_9liQ8g3faVK}XZ zG2$rM);!HSfS+MzYd9(5I7uLQm_QLgljJ`h|LlM_aYZapUA(f2#;hg(yt0UcECNqV zP*~P!es8XEeMpU_(fP^9E77)L%Wn;lp^yq=W>D1h;VU;wq#(fN-83NUsYxj7h$!=n zcJjg7Gm7cM=DxR?3U8VxtdSom2hxb#$-5hup`_~uX-i#uI&pUZmvWnH?qwIj*KlLz z>C-28`MLY}V?X;dc=+(CH|hq<54|j7UDvSlBvR4^>+y&ukKceS3ob71Lg3|t=+QSI zoa{^Q&@phhxWMI|=kff#3tS#L&{q7jU;I1xmB0UY@y*v>$D40F#OHtOU*g60{vbZ` zQ=i5UfAmLi|HT*ap$~rq&p-D9uAe=|{reB_j+ck0sE?6-luQ+-aU3;xGSdYtGWc3+ z7#jCWPX~GLz`gtTaj^(a&z_-0`3^zjloiu4dt+&C!A$#$pS!&tM*aq9-gL6uaK!E2 zO9%K~c0u+TLQ^V;Ss0LW4-h=3Q4$-}Ii0e`pTY41h+t6s9+saazae?Eg$!T=a2i4z zoE64AqoZ*HSfb?Pb$Q5B+$fjG_wHCXFj!@=4=L}wUxP$uW?(b%^{wUhIdJOW&63^> zE=el6BIh&vCbC(<09utjGL;|a0YIAO{3Z(;XzV})Ug|K{m(J#!xGEeg25-oV!V5cj zp;Gisk&Bg0nQ4`JV*@1TJ=7a!E_cKv^n`6sHp;vMA2-*QYfWc+U1yG+J*`w}aJlqt z%^hM(>*$R%1D4*PYs0#F_W0?^6I|bUip$FjFHQ2+^w170hv;`BJnll#`T=7-`Uz?> zaWU0)3qGb(GP5b%zC1}E;3;<-lVz28dl|I;gstlUgFUr zfZNQE(FV&*0JPm6z+A&~PT@Td)qnT+{~W*NcbtK@-^*FiSf^|&jD{UO%f0oQ@13?L zZ=?R*>;q!%F`!T^ZkXXT)K9LBXRKjA_SpN1a18YZgZCMen434b2Uaz-rRQl^6c?kr zKJTW{?@<9=okw(Lp{odv;~FnNcn&}G%KPy6;p=$%^cu^8Y)L@7mm7DVh(MY+p@Z&0 zLwEYs`}Xv7dGc2M&vG3-jX7-qO}QxXY|m({xK$|k`EpJqu`y-T#7_jOv!5d6fu?M{ zjrTk-&~Usyp71uWx7mc(lKGtwV>3V+HH_|2p=~n`y@7AmbD}v!OC4jOWa1>GAoR3> z#*I3_>GW`50F*2kAfA1Gqs`A^DXGYJz$V@v^Nxl|jnA$9Lw4YxdF@$Yp)_h#4NE&< zX&po19(D4P`H|VCp5okKXlZzRGu4AMES=GjXyI<&IlDLCxL*J3{b3x$Ip{TxISMs+ z1m4M3KdT;|YG|m!mCh~6pGlfMv+f1zjn8cw6}8;!t)6vmL!5hG{p_}T`JQ^o?w3O%|gnbl;Z2L@0|yg6* z1y9$ARQVx)bpTAqk_I4+7&TuRKU8OtMVdb}4AC|L>JG8-MfJ@IRxl`aM&r5t(~-08hUeI^vXpJFpjD@YDa)ODH_^Ze(T$_g?P}&%N*x{?6b2+xU%t z{;T-8Klw9w_*C)#`mg_6y!n;i!^`jeL45Q_{sdlr`8|05$A1!cu7InHhOd17vv~be zpN9R=`|!f^_i?;Ff=wv>6cb;|7LH*ao9SubhTa$Sa)LVfw27bo0WplzHBL`?0#)Fl zpr_9vT-9<@CjnFMoC_fA*NYK$B=1-n0aeuP*Y>O~Gyq}+bf(mtI(Djx35y~uE`fJ^ zud`Ip?^E$i5Ha&RC@-fdn(qvLqE@7AW$*!r{u|{P*v*~eJ9eXAyHGr9=i3Lz}di*E%vI}$wT9kZP@EXTMr?21J8s%gyHwio%*~o76 z1+TFGi_Cs})rc|5;mjFI>W7T23(Q3{nuB1^4}j5fOu<#3mZ$X)#{>pIN(-kMoo=oy zGUI~5g3N5%j&!bx6nquqO1{C&k`R#$a>AIc5J6qIJY=2Lq(DOxZ`NzgGfM>StnR(L zuGJMVh020{c^9oO&@u4z(PJFmaf!h`ju0%;@f2$~)Zrz6tG7Zh7;G5&GSLzFh<|rI z6IsCu@BbI&{!K!X$#f{X1IhyjB2hM|@Ur+8JucM1l1T2Mij%nd8{HnCH$!GYt0~aM z+e0*eH(i}{hP)MqPkty@#rC=Obv^fv;`znx_l(@)nM{(rQdIZOMw_$WU%@v!mfv8S zYWK$Y1n^U?U=SHt#Ie=T70n_`h{FvBRueA?RWmC!?!8b~HC(iYlfW}( zrWl2_3+GQgqKksg$&P@J(y;V_uYL0y_|4yLxV~P|mu1SJ*uV{LS0ZtVB`r3j!3-KR z%aAq>@AliWXmo?~Zg;L3gaM5zqSW=Eml6g)Y($uqQA(_{+rnltdlv>TG|>n!hm*AR z$k@b;ESc9pWcyEF32iToXM;CPJM!3WZ2v%oQTLHWDH#9)d(G*@n zga*h7=;6&*^IBE$z8DKuH0fUQWCn>8xfUDV<#7@*Q#tFkaZq3iwYEv23k7Oa7O`1c zL$h*p@9v>h2=Be5`;Gfn#^qaGX*ie2Fu`28%lX1wK&|j-^%5zWBX~kXfi)H!OPp|3 zdUnvW?O96OC;yB&uAk!B)2Fz*yodqC(_(yaM2dX0Ur5LK~qIvIu;3G z96-#K)l9j~*r_)6{6_;ohc?q0#v>%%z!7vo99Kuh8qp_Xc9H{DMqpb3aO`7bX21vo zBYDX{Z#Y7Yh(#7d$fhPOGdD8(B1BD9AT6TH7ChuM?*WG9G4}xS*{Yb%7Z7l5)uJWR zhzyL>GHD9oNz5bp-zG%esM`3&=MsRQd<>VXoRitECO`h}AVI;S)MJIA%8aMd z0F61M!KcC=QyLjV(R+vBU05QiQ^96RH3al-8Ucb#@^GoiWS8c(Me(I+&KJ}CM)F(fR2X`)UIvw%;cfS*-XTTr) z?&t8^pZz6#>_>hQKl0;$1otit>w1Jo93wb5qSP!Jayo~2nQs%rdb&nyZR&FnbO~UJ zMR=s8z*<8~quPz^5o_sA)JoTF3ir9-ME*T=P&ymy->3_5-nsLZmxOZ+lONLIS0B|G z{mhq6=Mr}@F@c4J{e?+4rc7J1LCBH4{44wFLzAN8JM~HDx1)s4jjR$kYGQd zk7y>^dNfwG3n&a1mkS;|cz|)d_RQnnq3aPapveM}XBeXBaE#k}$I9~ShFF{Ii~*LM zm<$LObTrs7PsBuINHjk-J7&FsoDEeIU|MqZoxfjY_A(8EI-&vtfd z(6HU4%>xqXIE<8?EuV2UWta85!|wZQZ=-E8B;q^uTfW?$xo>7z+A>8;3s+w3CE1P9 zY&t;sY%6?7+u+7t&3gl5ne$R#4n7tWj6r$Sl5aiTAf6|VF`Bf{d;p+O^FTbC-MW-( zI7Pb+f1Y|95cA$b0K8N(gi((SswUojvgrXYz4%T%_ux4kpS+O)u9R6ez~;-4vd+MzeCL}yB4F=Fb($}dR2 z0?UgWXSsjDRMC5bg2@ss>6|t}Sz|uaKeK|p-`@2$d%%z(0Ge{Sp)s>Zs&1WaZAfa~ z$EQRFNeBTQemYQV-ZXYuS{xIl@&8(SL}Kw+Is{ni$ojGnP&k|>)-g@8p0Vo7%jnk3eVUkrxh`V<2LOKa|YY2ByTx&vKRud7#J?S=&*SfgA0 z7>0i708f=k-2-DC-iR!VfWyH8GCIH`x|#sJ8N?I~3#@evbKtyb9KR7x(;#EU0%@4( zzDXg84U8x+y9si5+#EO3Ij{J3oo-vdx4yoY^JbInTlW~}9s+knW`x4fEi|4T+Nu!!IbNznW6Rxo%oym>(a_M^ z0#!FQmcBrxLD4)((hgV^7`?;V9hfYDDlYmR=s3cL_m3g)^L|l^-UVX~(JDf?=8A&W zu24}r<%W6`pmDrxiVEs`Dgg38iB1GAbF4w&MW+}+o8Q~}_6SkZnoB1Hnu2Ya4f8Nl zBE})eQkz}IQy5*45fN5^O=6QDVyUG`g~n-!c*2v+<;46f9ftuz2~0eTA^nQj6F?A@jo4hy-j=|TfPcTv zIh+>GkLWeyju^5RH#ik47qmulWb-qPaF+CBc~_C=)mW?GCEp3oVfM1{2EV&2oj3&$ z$NchmM)EYLU%&##qGr>uh;<=@updT1N6wbSLk*&ssRMqY9&6q!AhROo+$%_-z!wup zk1_#sLxv9j=5Ak`al0A z{K0ShDt_hjzk!!t`C+{B{*U3^ANvFzKUwjv4}28w`@o0rju&3U^^-S)E)LZQI_sKs zG_<9sjGo!Gz8R-OkMPXbNMY!dt)zir-jmC3Y3!EAmgT;ww=A4F28+zUvLC+>gXJy% z7W$k6Rhzv%lB;79~JnI*GSDSKPR-p$OH9gs@;8elzSED8vz zc(f2aGLopNM5yz7I%2${s)e&;uBksS!>43+s(WB`=0`L((#JWB|tPA7lAiV zuWLxY8KCg0vekBTOoOSpfh6qX669*08WJL2^8GodR-PenM@lGD@4MIltXwLWWj19T z%&;B@a4BxUYln&-Yi-K`?Qj7x;IJG3#ECNlcs2}2HP2d5jXt#t^tfUS5A-=Olf>Vq z02bmfvZHwqpyvF-l@>VM8HN8dpb0u4so#hbroNopY%Al;)*WAXiOgyvk~bX(^2ECg z+{olR+I~R60+{@EE^x~CRVPQiZ~ybTi@HL@@orX@2{PzX^)h9s57%-(ox|0@EY&>w z?xN>u8?C1m5VxN^du(`+9ge|z#%da@c{WQIr?jws~51v(g7GRDNA)I!y4;AGq+^mMC8X%0}*n?y6-5K7EAu?9cR zC7dTHeIPbKV7^8|SO5d`IwpB(Kz|RqZRsz&-+9ku&?+eEB5wa)$1s(IcgydQwx;L- zK)Vc2g_H)x0ySU}#lp-IF{mv#*@7;L1tYRq)EhggAA{GF>4_ui>pKqcjd_yp&Ff@D z50S-mw>&h)8u1Ojw=eM#a_Z5u;emNd0oJ)Mi3}K`=ofU{CxKppuL1D#-<7_;g zNO9;u5W;dEnf-t`jmroiCI=wjK?j!4Lz4(e$hcR7{##j=L*vhFIz8ABwIl@Od+T?m z(bDGcq@CGp{D(+Qug@YakW)x~ODAxr5d$}_pd;qfb3I@#BZev#7+!jC7w>p*i91)9 zIEmrE`Y---{K_x=eLQ});&gqDi*I}fAN{f4z|a1fpTh?}_6fA6c<=jPfvwjVW1qDt zL7KKXHOy>8G%(#QTUy3^I47^!kMChdH|K!>+`D5MxWNl-$ci>)d5x}$Os5wAud*FW zy{hq0pRxaWLxq^fY*vc7M+52kN5o{)Vb_AM`8RNX#G>e z$hgBOxmNW{Ax|!I7BIhJFu}R1f zi?S6e5fuIs(kx_O^d+oDErSvwEqad3EDD9?m`I;FcFvVcDkaOtH!yipL@-v*oG=a9 zWQHys(!4a^k6ul}|Nupkk}NOsb#XcC`?`=kA&6F?y)AIj@PS=DlKtZ}|89GjDm<{z_RwIVkYp zo=~=jj9}@!F-RBvn$X;VsBnsg?dv#;0bG<84VZgEz45s3KVO>>b6bZ1SYXo8;Mp|& z(DC(GzlwVoN382W?}t2z2%xMhf;Q)uL;=7`4$@U3>t^a2i{uA#Yx3cIL}J>UQ%S5K za;!QLqzdswj*ol5Ftd!10V4+br|lXJSuwB5F^MxIW)el}o#27J++|6om9f2@>unxG zP2CtCDM$)oph{qq-gzI>-BaQKz)TI@ z0L4jA7eZ z5q%3}HCVS)2npO8V5@r-HBukDh}RISWR$(ZLXilpH>}6i(;eX+<;rLojT6#lGA#eC z+j!C-1eAuSI)qUR8s=unCZFd$(sg5=6X>^t&MnxjpPzfjj9MdfRdx2sbOywRhJ}h! zWT)*tu+DcHpXtKKMRM5-wi{P~7z*Dh&}JkFBCb2lJk35!FRXNbw|owrGtRF5x$1Cd zXk^hW4LFSxPS+jFbB4YEk4+(mj(hj+3IGf!77AF46MneY>7a^CFW-~JaY1j-s z0Pm4PdtsfqCWOlRn#skXkykm2WnA5&-*f zaP5`#_(9C%Z;m_p0Reh6qlY9rqjhsI*cdeg5Jd`1g(XObj^!ORedF$C*)OI#x%dT* zsB7EMxaEAZnMIMsiV^C-GDnI@d70MxwKK{f$30yB4(INiKA8P&U{vAS8J ze1DgSR7d$Mt0DZ9k#P8g^ds15=DP9jgZua!f8+m(-};ST!=L&ye+F;9dBQ*X>~G-l zqbGRby&u7+KK@7Wp7*>PpZdu^iaQ73!J*;Hzw_(()^~mm4<9|k)#W9|x*}Y5u_Ts} zFu<}*hCSOTIoS|6Im1Fyw}z(t9j<@FPlb>r(~(7>FH{@hkSBjseN<${&M0B|%1u3m zd`}I0?HzJ+KTf$uUYqz!HqUk0$rTN35CA{vNH(qe0?4ND#ERbhRf61YI#edQPa5Ro zHnJ%P>2k{EI}?S6~bX?wBbmh*?p6gnKrUYKGx~KvYi;Qyydf1~+(^jp!#72?XH*mN4S1``;q9-c@Ch#l)L_{7AtkmhWZeBIQOp zlXMzvY+PxKTATP75ONtVi&N56zAn6;Yit`71eiq`1Ird7qF=IL>vLENo4OhuW&SbXfh?4=`3GFwq>^TnQ5XbDTILW3_YuP(XNy}ViV#(N3nNfgbN?)N_ z{6hQ5Le6EzB;1kKSp`5nn|qMY4E}lx%%0;r<9Mmg#@fJ_>&$mD`{0}ik-+6=jpNi& zlmGJLjUBg@!~2W-rR{7LfYr;fFI$6H$2vv?R2sxq%x2i$o72nlJUOBF4raths0C^~ zR5$c*jM*YfvS~O&)S^d_hZ$iDAPr5N&hL5GyYcc%@4`2}`88~ss24lKX))V+Y#N=1 zzNCfQB2&j8=+g4uNxMo*R$n;%Ek3MH8DER(X56fGk>?WS`?6d7;GS6DhIy>JKaakG z7W$ty_c@-;C-3-za+133?Ot#D7-~0Q;6{W2i1b8&sj~E70e+*`3$AfwoqJo?jJi@# zr$?=9O#Yo-O3Uu{0Sd?<#fT)4C78~S$g54oCh!F4VMHiKI#vAd`?|&b&k0R->mV`> z9Ul3mTB1oHGZ}O}!6P2NB)xkFYgv}i1t%CZ>N^z>Z=Pf}a1g_?INdxGz`gY>S1@a6 zvO4$?-`EzLeld$ItGuxR-=9r7o#qxLMFDzk z#wzwQ(Nex~DJ7oEbzn4H(mC$$VL8^MFVlzlC^1PRz>N+>buR3kle7#8(wGmN%sx zm{C1{Wf*rjFOLlt1_oe}zAGZ=08TpMsA<8StGhTH4p5k9stj+Ie0{o(M&ND$(SJch zyS`uH4m&#ih6df5X3&IkXYOMHDC%V6uEPl(-+g$*<0sd+ItYIBXZ{V`IW&Ci6Q97H z!vW*bxADS*J9zXI_}$O{OMLxHzmM;J`&;PCWi;CDrIDlM`=?`I${=E!DhH}z>Utb` z52AM8`-}K}y|;+inm0EWVCfwfhf6>N&z?TT>2wM)Rx&6wG83@vIk4AFw*?qj2F&l| z9F1!+dBTq%m&{VRscFmejr*g1+%~+PNH%1Hv<9Jfy;-!$3U`IUBf)LbbQ_##nQbO0 z0KPb}<|Zt2OMKzu@(t4SSsNf<=91jU0KYe7m?cHUF~4!}1Zb&_03#Mm4|CzCcow>O zX|7dSkL+`}?bkwF5vYNf2Lga?`=if+@;StpGGDOQDJ=|sw7EB!Ik3av8CavL5;}@w z9!Up_iX_(+TGvI2J%A#Yb_O^?ACu?&9xs^(+~8e<;w|v2B;OgdWcn$cuEfSM6cx*U zYE2qOlueQ2D5e#f>)l#I>kaFA4e1?EA3wr#_wQ!Ielx)$2MihL01n*%9pTs!*oXr% zhVx5nlyPv`+Yr4~NHf<%tvNp{)EzLGYaxYhoBeI>Bqdy@LB1(F@xuT$u{c^7}1$&Vw5z=o7pZ z$ineMZoVl_-pVGZW63cGjfKuK0MOMTSBuQ19+{r1(Z>^5ta~3+WhRUVeOg<*D#0Zd z7@X~amz|@dpOScno0y`B>)9?qhoZ|sgGP^0$8XC;$CKkV-hBKhH7xCubSjim?9?G` zOQ*~Lhvt$CF;C$y3OEU@#yE`yE}x4>aZP()Q`k%=)YQ#x!^R^ln*XPrWLeZwVy{3@n=b88n}@QGU4%wluBTEH^x|0C*yK0`*j? zEX4|kQ8HywJn_B{s_{GLA?Sw#27pzM5bJ2F5HlzRfwX$u5fFlzXLQ6Vn+?<&>K?>CwV*Q02h9Eiao2a(*`Xmwd|9 z{1mjZ1^b+ivf12DQFGt1Ofdq=oA+{f{&zazu^mhNo6W*Gy)uTnFZ^^202%S6(`WAE ztz4R*;@o8*h{06&p|8jbTPNi1`)XyWtU>!V+?e@gzP52M<(6Wf9`fB40bw2>5(v^ z#M+1zV{Lfy=0p6YKmV8Tfmc3=hp)Yc_rK>o_;Y{e-^S;D{TK0@KmWJzjjw(Y?|JVJ z;=xPr!879<8Wx6M zgG2*fIwlR57YB$b9zT8q-aALo7C(me@x#|}d2xaFzV8Qdd2xkDkDmsuLjE;}WVKm; z<*9Ry7oqIg@WxiA`JR`_l%xfDyF7an*##Z^Qye(7u}#TM8X`_n=WX3`ES*aJ3*Bqe zc;0Q{3Z$}u`NRhtNm-i|cLsOPW*!s3>BoLf`jj`OuR?;T+=G+I`5hi5Pq`!EkT3)v zPi8A+QhtM1*~n(DDf>jSX@0(cGtHn?$O|{B`&_@EGs2KEoAN_2vA49j)*(zoFVSVn zfWg#}^M2B(j0r$G`2o~pt*2bSxu2Z0TiHK(R*TN#SRzZcPovJvgDwqT6mHjx6$viSRkugMYt zs19dBRUT8^C;oBe19!SGU_5}3k4b9o!}u_dJ}y(OCEB!JB>utxwm+Xi47atM{s=y3 zWDR$)L{H9*ZN+_c29ZpezrAkNhr7?ymW=TyZxvD`e{hZwaF2~x@Jey2P&aK}7X>^! z9e&%jk*jeH^WKThRdG~}I=||Ossj-qf)`@&F1f*jCcq+|jplAu*VRjFS&3jGI0 z))rNCcNK=5Z&)E{qFDNXbU(#ZqNT@i7}g@Yws=yoVY2-ig$&;4iwabYd3gdRKx7Fd z?UvlqZjd9a;9M#E`(r5%_R#lmOq6!AI0 z!rD^at;V`HerF1@Er_N9+Rv}v$L;SzQ^?d(pC@pyFqO!h>&D14p!LX}2>-p;jCPov zoFNe>=vaeE2b$nG!oY75b+UzKHbNFf!&vEQhR{p6B97GVJ@JPIXmz1W%1xT@Qv^2= z=v##BT$i9*F)Hg-KdTLU>pS)y^Sw~KJxaK}&fRmv$%7C+a6#6jI1(vnKx5N|uJr(c zo`1R#HfFxzn+VuSs?pmmhS^s@(s(qZqT|U*PDn=Vl}D8~ci1@}l#GhN7$zD@Rm&Xx zxoV2j@!HGYq@yiMB=-n96b*)94oogCt{@OdZ@7DP7jKw*l2w3JBMWE@sExSylm_KU z-kKfC8BGEAc7$HY%fNKTLL}=!sSpzA?$$5?R<8F>`4)b)*(yq_IGDAO*qW z1&oOEk`Xk5vPb6MSu%gd5J>!6UZD|*sLq^;kEcT?jpJfC)nIGxr_G5F!FPsStE!}L zI2};-E*Oa|cu2528hMs}Re2vpW;w1oH*SVWyLil8FY~u!+A*oDdGC#Vzf~i%pN~XB zD^vLa&?mo9%!L4k;^4eZ2J!QXC{1!|H)N=6fo>XM)d0e7OuKidkr(@7nBmSr@B`0X z;Lg(Vore$crQiQNzVzj<;4^1j^SIY(wjoN3 zUH^F`-sO`w1EhYhDfWgqipl4nc|i>-4bm2z9)AnV({JMW2S1Bvrz8H>-~3PUYrpgl z@#x{3cW@ijbp<2%sP2|O(#No>BB8pmIY^eB}s z23ee#W&m2JanggAERA^yndljdf_8a+J$rwDE_}B7pTmGEScH9z~ z7|H+C-;-lAJ9DSE2a2QJZ1%zt26pLunAiYNFX@V2REI;ya#*}iPG{DEL}VUNX*gV5 zU}+ueY2a|U^rqr4$O5#J;B-=4uZD}ZfMs_k&9PoH^iEzy*g^nf_33a|iv&(OWdgIc zeug(gXHZ92oT3Mi8NnW!d89bGDmI7nt%P#h1;xP!1!f?xByVjQwDyhSI-kSrjTs_4 zn_+W5Zog8WB`<{|OE8Nvcwf%pj12XO0hK>D5N^tu8~mG3_0Jt9^f*D!PcF*}4FP&I zop+<(X1Nmll+kA94m-G0XDHAuN{9rI)^HHP3E|9beqwE7S)O@*n8<=*ZbK;ibS%AI z@q-`uAb#iv-h zoz9c6qrw)LB8xm30ng0b+k&~-bu?@r^S$ML;22m#B!k45Z*a+$pF^SCj_uqPi z_!V_ltpQ_Z!6c(n+nR;2x0!`v!0Dt}|J{UUWuzRb=H?WUH~|SB^-QS(>``-d3IN;9 zA`$URBMC)u@lnM(^Y2AUILE-YiQ=U2Mvu|3NkcoS0Ef0jiHMJP=}~hSU`gX-B~x{;ym+&%rF#~QD?57VyZ29M z-Al!S|8LTBDpk^=ZqjpWP-)#Xz+0i+d@gQ&e{YcN_-+54+pgR0-x`uzFdBCOhV(Q$ z5c3+yq48X!N7#)MW_!TQONeBufM&>gO#xs7-rzP6X^qy2G|Yx~Izb==7PX(vI!p#; z^J$&@EaAk8=$l1*FPmcN2e5}ikA}^s^@!7Yz&*K(N6(%> zkJnh9yYvho1y1V-Q)*kctfA-=Xv98f#`oC=mxy={sDIu0oD}{-+YMc z*!$2*36D&*8MLc=@A0jUV~Z zAHzGIzlR_Hu^&Tgz-!<73V!$3egPl(@W=7+>9aVddM$LKsweLlab14y_l6;;A;SXb z3v?cBYzC8tRm{t~#=uv<^hG>=;}P!O_x@OBim@tw2dY+8Twk9677ZeGT{^3ZtQU1- zRuNb{@YZy!xjc=~ZhV(stQipQi_1|RCrIWNX>*hE%|m9?(#-iDikp9#x0 zGBIw5)5@T>!$W8Ec9}==y&AeWPoGwvwl}bJKj~;#LQR?Nz*R=Ky4;)sD`xoiCjY zbc2ZB=k>N6FeFM2f~QwttKj3@8~E{$9{o}^^v(>D z7Il6GU0vxp_+~v9iXid#cGl1^ZTS|%dH*{N_*~2aaQDWQ{|s>HeH^v6x^DkM2b-VI zBdJ5-7RF)L%NT14*xtQPlpBSS&_Sb8Bh{NHEQByUEK4ZffhJ4Tb%$ZCiq#AUb>VPS zKZT>WpfN&mB>?cu3v0gVZ9RDntD}=m=~$%`=Xj1D>5(oRlWWun0=ac$^Y{cFLPazG zShEbOAl&oAIq)glt$relV^I(7oVh?IdyNR*q(O^{_g(gZpjWcVvtOy}NncZqnXey5T5K4_8t zJJ#XNd7nP=aa}CXaRj~lrivwwc3sDc-V7_uPvD}U%Qa*gu0-~=%ZNt0oA0TniqRx` zfq0Y-Y7i^Vmk{~^Nx|dkt@fFT=0jVaz*fueE;`Z>JgsKYaL+c891bJMJ)hMi_h&}q zQo$h8QZ3eKmVyU2nPt`#q=Ms!SX#a@r*H#baSUqEa00c|MU0I3{T?N-!WV?tvEOad zO@j9u`(tCawU-`lx;PuyE!@aA!_;dgMe~9(j6FmQpm+|P^ zU&4!rf%m+44{yE!eBrl$2Tz|Iap%DUTwPsY9ihXdO($H^Si#;kUAmwC1_Ll0oaUaE zU@;BawFxc-fHW*^!LuiiupUo%@WMM>zlp(C#c8bgqd)R-yzhBG_;vvJ&g&&Xg8&CHeVz9k%bHDJNWgGx%?#mwtE*F;ijX=T4a+`7f$i*LmgoASq3u#%+2R#`51+m02Yl< z!wBa1ngq|&36&*AQt`ZFIBOB~Y7r=7zl^CLD6S=(B2hn%dRm!qD^b>_tYoBrVoKZW zAz(&*-N~&SFY#0~fuDU}S{n9j(3{RBBvI4g<=#zMrRJHwT=xx_+upnBx8w+agXbyp zi66Dd8dVLrViEDDa&xrhmPcR=IDT~A^=xoK=$hpF29x3aa}?0kvvE7KyH#=0f!+*D zUp$$~0O=iz0PE=pxpV2*c_?}phz%@}0ZnYv;HO5yn7JTXl9aq-?$B+JSQlhTv!VIv zm<@UI4L4i3n9xixqP$G#tQ1LE>J*B@kcENIAPCA@#IBI$je>jhhIE?wX{&zFhay_O zZuYA`SIaYRUUV4mKTDP=-^|kn`FY@hD(!AKNd&pSn~7(1g$$yu+{#QkCg+3qfw)`k ziTDq@x;61WU{6oLK{~|zU<&UIxkBNATI)P^oWd*QhOFqaV1;1mfFE=Ys5plYQ%LV= zXM4D{dqz#{OEpCkuexZmU>MLYuJE02zlJNjMpH#!7Ub5=Ia9`ZQbnUvYC~(JbRofv z@)MYJ3}SoxK!vKL44);bQsjT^+=|J46v68JTgXaj;Axcz8qU*A$NVlNZB)ZZr@fg* z5I5GD`n9NudQo2aVQXHJr>X-tDD?eZZ_fb}15vBcGz7^Rpy)upL1BoIkz^dI!3C3V7Sh$>&oeyUD;ir`Bzk1l?iV@0^Pgr+B=@S+=M5 zZ4SBp&-M4cCwMy3Y{y@Wq4+aen`_@qFzAS~opT3?LHGiHZ-6p3l@o#qoj?*I;Q*(y z+R{K;?7Kj8YRDx1Jv|vMVrGTLz9leS!uhwFMtv&KWPuKYt;6?R91q(=fxE$=z+u7B zqWnMymfk|BdxRXOdHRRTfl>x&@Zg*nL^`1C#6A_mRLS9}3B{3gW)F#+yFXasL9-;J zu5^_ZH|cc)5P~4MI2krP!|70kPMd3>MW<5^fNN~?bM8~8 zT|B$i2MC={oL59rO5^akCWV-!LAeY9Q8Fi^=aOHxGB!Q};;HL%Gmhi9dS+3F|Z>E!aZe2;!!;AH+x-GIYPNWXPn72f@R9*+r~RtVB!Nln(qs75aWyw1X0!* zSst+;8>kz?X>aO1_sD0QTMIVDHfl~fX=GXWm`e?iOuS%*$S@AtgH{yRh&Ki+fZJgVdKN1V&o(mZlv?iv>zG;C6v}tDC zw8*+h`GRxTEuWUXUibUCLew~a7~Af!nom4|F~ zIEW6G&;*8)hAs+;>=|nfr*Xs&zV{V;_y=CVm%j1^JUboH+Jc&)A`)vnxWx!$ z79@bW#VHV4GXUEpIla0-M9|^Cw?p^;cfn!lSTzi_=IMjZ)XgK}_Q4r@GC2d3Fw|2hN z2;RASzLx=W{yFEIas+F>ruzsHg~Lpzi|6{Ey(wC3Zi4t`MOfwimd_FXE(MTG?1e<0 zh4g0f5sw7xN-;n!GKjNy?Xv_nQ51b{Tba=5_N)ji0?6;8u&I-Peyy~i3%8%N+m%PB@7Au;I~_lm z;CE>q_wU@ru!d*WG2{w&?>xYJ-}xfm{n8cQ`_2PiymtqBI-!Z+aB;xl>Jsbfr#Uc! zT!=IK=J+52s7xLanM;#pEEc76n0nZm!_Zs9pg1JscpC^yY`N;sdHQIXWH?V|M^Ve zy|y)2>hl}KQ}wf1=Ino$xG27_XZYoN^7roVjYhZa@Y(JWRT}288@sV5O(dK{%-BlW zIC1>AQYrehI94*E>c$pNu*tvY{f^Px0-0GwfmT6{AmV$1kgN%FIATl!V8myE~TIir0oN)JR+0;12L&h%tM$#&Kk{2 zpEd#J{d#PcBIsvR0>GkVFmMNPlSm7D*bL9rkhBwKMJwe&%0}Fafnyr`)%HbLFCJ-!< znHa^SLcSF+D^jB}q~g@=wbh|pr{xS}-Of?p`+8d$Fk_5UT2nL+S>v69cA*!s(Yg6k z7Dk^J635uBQJm`{fXGPDo^@|3u%?hmDOBlML)V+2t%fzq zkaP?jB;E~$#)eY}IvESoko8j=PLNgI<1g4T8Wmr|zTr`>Kk00CqcLga6y8rBs!@LH9_Z^WUg84o-JT7@rJpr&8AdNyVd88#hoCc z7&b6$Mel;%uJG(|@;cOY-~fZQj*$r&9BXkpLHZK=x z3+}w|e*BAn_Bnj_yRYFV{^Y-dlN#CyI9@-)SO>CH)fm6_2eKi)<>@S2JvOgdJ_#@r z_@*v9XViG2LFIj78Lk59uu&%Q?Xn>YRcN|eB@9p+Fnh)u4cxsB|6Y1{z6WW1Q3RSH zGizW7r(T{f7az~HOBs>6fwHjWxLCkKFSWppmjMqTG6T=?eS%2OpedOYeqTJR32X>l zunl;I9ZT>Of}ZzkDfQf7M-CctW~`v_V+&`M8JxGIqi}t(Q?S{)q1i(p3Op5J z%R49zBI2YfDfY7998c0FIG6oW?-!AI5JzBN3hs)%=0P2kSGFv&v+CM&_iyBu zO`O4N9m6fv%S#Bvv#0E19G-e9)@ktyHe1U>U+^H$y=NUX02hb-LE%Y+mYu#JO6 z*1DJjCjp?t%bw60TJPw6as1UT(5~*{^!QD*(l@b^ra`hMiQ7<9&{nlDg8_R?KV`h{ zc@4cMu?G#&4>B|LW*K6eFNihr-ZCaS*Vh0hV6f*>gG7+c^_QD%bc8Zkz%jdwqN-~p zxJtZxn-j6xD*r0i+ib!se)1%|ahB@r9L&K@U=xBqK(i{HGEP)43yO&kgY=e-7ujGF znAswJZ*`{7VG`LPvViH1Qy9>3LMIU;@@{xl!;nP3>6M${qox2e&58F-B|=8^)zwf& zo^{iZ&W09XOBG9NSeC^Fle9R}tU+|eVgsuQ%zA7(g%_^)p`I{c8ByEjxo@5#87M_s z!y3x3nZ_oTpu6}CoWY?e^5dDTYIxG@E7US+bhh~{~(AoeQ~0+H^5vjMoeT(BNb&@RBT zc@%Z_fgW)L=&f|GkuHg%R02Jt5RWoOF$b|4%1R*U=22;5e;1hmI{!=1 zB{L(3s+7WaMqbV+5>S?$;ZGKnmG4+ODq;w!z~?ypQ3Rdtbc?e5aC~6{wsU-jT>r|u zmOAB>Fo@0&a=9yC|4IbIJw)=n-kLvu!&z zdIU_Xk1U(AX4A0b?|Sw*=bS-FazPwdNwkbjpO*Z7YtZ8fCjy|L6NW-toX}^^S5KZk zf{0=0z=d33X$`|hU=KR>VmulUXt@aW+ixVpT=|LlMDzrmx2Z$Q^;oZkEzKK#lL<6SR3hd15?zV@Xr|G z&%J=t=@@p2%{WcaE&~I(zQ{3%%o1TI5!a|ilx+rA9PkdT>xx%?_#^nyANvWs@y1u7 zy1Fbx!}awk4LeiyG69+Nck$4m7*Jin;7xUuoCAb3U^thJ{MqTa>C~n1?a!X2pqBb1 z-qlmLi0ZXK@V)8Qa=x>$#wtVOzV z{Ys`*j3prLTqEvxVv}tepwGKiKCz@<+71m-resI~O6V1Dz9FB$aS*>r+}}`7OY-pz zZm7+AS3V(6opr*wM1PaLGKM?Jpse8^oAoWf^!NJ;H2)@UV6i|4Olc4 zZBZ^}fi*oW>*JzhFi%SiJVBjCCzprEB4`I%IK=G}Z_cpQr2X96Eo1?O4I8Hu+j8+5 z&<3JYP4HWEh|8)7!MP=^*SX-rIo+1*Q21hlVY&A=SbpnJu=@S-#A#;S)W`d=QXZ#s zQh*i#F7}scy@AQqD-1_9+>r)}Of)ga022lc&xlvgDC&S`%=8wArg$fS9szb|Z#v;T zqdv}Af{3E?&=i^&7-G0qz?i9*7I24-OHVVAItAaLF+kCzU zo40w<&t138WAE|iNT`6OAf{6gyM7bu&8EyFSu|eBl2v)oIIK>uiH=-&N*PlX1eqVpc zh9gEI^N)%I6pImk4;k!aRlxcjL+;ClvEe_Lzac$JWE;t=vau?sp#z}wy{O=igq)uk zkPe}}F_}>}+}!V(#bncB5x9=9O5b9TfcwcTlxcw7=uyPJOgZ9e8KO+J1pp}HWLC{y ziEp11zcUN!oD7@HcSG*+S(MY2thYOuC&1D{aKlmt_pA*Cj;Ckd8=@VsEC)0Q)@&p_ zjdc-6qoycx4+Av76HiK_R5kHz*Jv=2^3TDX@A>t#;`H=Q{P+L#pTqm#^L`w!kGOa5 zE-vgbUj5uZ!FRs%I==R$-@`Xvc{j%B_?h>A5HG&?5buI9W;T0OfR5xwa&CL3#bYwtC+Nqr9ydr@=AdS9sT!PZuGuV=D{*Y%Gzfsjqseib z#+cQn3`t!L%u|hQViYKV-q2c{S_lNMyWyQXp~yJ;h*r*GzC#h;3dQ_0emEZGfy*cvn2OQiJ5NX-JU zm;{7KHpd`rze_`nYs+j&Gk61D%j^;VnEcVmP=E-=x_V!j(3>jo66@{S z6j%6Ju^CW3{1Ub^~8rz#jtGby2g&N~6397xUknf1d3S_>zP2>R0S>NmfEdl$e( zLk8EK4k73ov7{eD;)w%Aco)K1?xT@--JcFv%sW-PN>#e?o$yj3EpRD(JnM}hz;0!F7)>OU2ofWv)>L? z(fc5`H%V>^9=~QGhzqc71V9mCPCciw!2AH9A?vRRgCdyLGjh%W-O5CjX0fT_d)tjj z6|-eP2OFM=GQGb0=kooYX_F1kwtq$M9mnGd$LkXghYK8*hO5JZL-S*z6%DHb+RVFJ ztHTN%3Q@tKcPv4&CSFqHBj=g`HatT}O`%Oa(k}3<7zKJ{Gc^IgRJNc+>#gd+^TP1v ztn=MBX)lKP<;S+1?{v z&B7bIH-yT+tYzH_3)w}KZW>&ZX7MD6l!OFg+wX6lVFK0gBqN$ib_yK>>&l0t3TWvc z(n2_0pFA?O^k^1_Q2ZY3j?z!2*)C$=X2k&v9X!brJcQw2wP2h#weSS z7TY~d$BbdsQRgsag- zomAI^4jBNm;L4Bg_TCz6ViPX`HjFsc?(R$P#8DTlt9m)`;^xviypj2=hMs&t`2@7o zSJUC&k~gbfle(98>&tt#pWWo$bNpv!*#}{BiKNk9kx_LPRehU!Zs$ar@A3cS$gJ>7 z_}yWi5!hPbf#8+$aI{u}X6EuwVc96a0-JGP(_p)a^+G04rtA!`$-O?#`E~Y=!hD|; z`CfspRWWAy*t!Re9||+1nP&xf37N)N=`5V%o5wl1p&^j{|y{-3!hQf>@z$k9-edb|DS)~UY?$NXMA|;c=>mJ+TghBuq^OoUBl8E zx~XSw3$h200g%Ag5)~4P;n>*JTLHkEO*eFiDy#u2ji=Zno5PzsB!(FvGmE1y-Uo)+ zBJX|A`|tzrem7u-F($@T)08(XH%isGTQ}M(W%@9~#77#GknX%-I1 zn@6(p9{vy;LYXvW63xZ{_woZ?D<-*6K4;A%lKt#(j@}IdCtQy*7R0m5CN%?-^6IF0 zv>gR~1&-4&;&(Kk?I#`t$AL}DDBW)g5us85V?dn0E}OV6W?vRhlQPA{#U=XT0=6{t z!@(mf&EUr(0l?~sFKB2c5aYS$Qn0=sS)FB0fTx|C0d0Xs?coCVqDt$CMj>7*C4y{3 zxm)L(fMxstt&?JY+rOrpdmHJ3u(OM>-UvFOg1spK>s1A5rS(lCu(H4QV2I+?Ybb#8x>9peFa6n%Up-?)8bsSaD+Tw>Djsci@)4FBBSl0sVT9%8j z6y$~iR0?8`^qEmSd*2=Myh8odCP5hRBi6tTBd3E$$TY!1I7*~Mhc-rNji~JT!3sb6 z=QOC8Vp^|;c?_gL{B&3D%QIkvV6nCBbI$IKFj8hG{=zdO6i&0mM`||dt#R}`(@Dd@ z5*A82H8>}MXGAd_&O$B=2zp|FGgB>WDK-pDqer91K~Aq^*`={m=8clIVC8Go*l+@& zN-UFb2nC^-c_Z+-TcMwwS?yx-06NQ?DiG!X(q`luVH!W1G1m1d@^Wi{aXPV?%bfR) zSboO)_l{ZW&;8$qDiFN}NXi+=aJ^=#SWhQ30E+-a2To&V5=pM}bX;*9IZhMsxXD`P zirACWc{sJ#Je|+HC)#p}fA9-GkAM94|2|}C=mI>rx`+Gk`5=Dw&;GmkYyZpt82`>+ z{PXzuhdzLH0Iz=YRs8m6{|VlB{WZM#c*SzKi2XOS;%*v#^)#j$RB=bPldgy1$BacD zK^@#60;u8H)2Ddw!i%tF@o2a-EIme$m;+JjmWv28jlK|)w2IZ6r|V$?(eI_hY_v^T5O*(GYc$3wD__n8&v4eneQ?eui=BQ#11HTRi{#(s9* z8_K<1oo4{k$_4O%#+hT{_XLxskT#n_yF=EW-Gv4Dj2mG1nlQ4O8Y4OYSh({$e(WCXNz7BdRZ+I52?p(^;&A0ny$d& zgd#eqJ0*3BnI`R=Cs!OoQUzKbFf*>XMxvxaBaN4H;E z^W%7}WA+Y_BTvN? zJ>g9b*{;{l|L6F}ep-#1Bhx*`(eY!Yl%C?sWH-B~F*s4B8r)Tji+D zdCW7{6@9q?d%)1C(fR_2Vp%$xEVy@d2k(60K6#P9~s+HZaFpk-tz)2~hnoO)M!o%ek&YZ2D)3gq^bPnBMqF82-Qq`$|2HuG z%+zpL7PO_oMu*6PZUQ@a?EW+i-RK1sz%)Po8nVrMYBL$yEW1)}#NLtF=jMy5FmUIZ^k{G2tFIUZ<#r`TS-nBgfZ13cm z*SV&dyv}{+w&!e>N9l1Svp;@<6LDdz(X5z}F*U(xQ6{GbYsj7w4vyS?5E~`Rkz$WT z`fFGBL#WU%EK@lXXT;bv>%{zD9>;r@4uWj@g)lG}#i4P~q`7l&RnLxDuHwWdAM(1c zFbrH?-9dZv32Z%~U0u1rlMcfvkM2CJt4D+~yTy;SrJP9mi{yBWDVyAj?9Bmj0cew_ zSQ>z&>6juodrS;(b|&yBwzQC5UMjW+CY}a-GjqzpRW&+OeI+QY-(mVXVRTJS;xXh2 zn5$PuA`8k4JbkHN1iPUo{VO)JI;?r00RnOFTd`M&&Q;MeAo#Xq)TnqJy|58q$HaTH zgpi+QUmCU9^MIfZg;wDJ;MFYd5EMs?L?)0koWVAy*bq%y-j4vzNF}{d_3`=&(1rUc zo|&>7JfUo6^yKpr)JYoZux*CITyFvtU(aeA*6UnE-nj0&`|@vvXUuLkIzI=1fiTDc zc;in75WM#b+phI4IIf<4y9mp=)KlKgBgQCeQ8lWk@JcvPqwkp!5(&)Kq+@0_OL0cH zzy#p^qmIXC_}M@4r}5JLcjD3Ouj8^W_^W^IKf;qIZ{W3WeI1|u`M-x(-unS8pZaM$ zd(GhKT{JMcJJJCJu(#+EUEW z;Tfs-@87}I-Mbhza4FtTOCk9G@%E>|wq?h8Aok^2`lQZE86XLx5D9YDB9g(DeFU_z)pFu%lFgqYVsnU;``lcRDiCQy&Gxr{JzGkT%WjnF=66tCu4t- zCLwD8oo#JPu{H9)#Q$3QgBvXH7cmjlJj!N!LE^Nwg%tPqn!NFx&R*PkED0;y|ElY0 zusq9+qj6NTe^%_N@b3v&0%)9Or}0?1yS*=nH1rRw9k8lpeE@*e5^^2_%Ul()-d?IB zYtUN=EH&1+N~tERQ}%@BIdI0}vsXpw8f9j|ThSv0qlClfp|E`&*j3@YD+q9`qoh^} zy#HNs9cY0mbohY<=y_xlWS{nylKTqfJcI(zWYc&i9ypk<2;r|W3stZo-u5U-J0 zQOX4EdkCyo8|9m-@e;}=^vY&a@wIP$1slB!g`iBuj98c3z0+Y&N#~z415_!W%YrUO zXP3QU`^PS}ed+>`Wy|&qmqFP9yuwFZS965>A6>Zj1nDlEW0SB|DMlHNZ}x z140nJa5Rpxv^_)ogm}gPrOm-$+}FFM8EOa6B03}@(ALlo?kJQQ71c9N6k1sxSRr+b zt_2tO@8j;pE10h?P_J$L*iJisx>WDoQw38gmV$}R5$)9hk`#$LO>^!#_^PJvRJ~E2 zN@P%RKayY8PD0h$Pm{8AL~B&+3Oy8e-uuUjxzrlR(`tIpLiu2M;=|EiN#CP-ZRs8Z zk`hW^$tyCPRD3=aQtTeCpCXi|0bvEIBxlGdZ3qR1LRZc>}s?YTBV0tinpwqW=u1Nu^2@PTIh9 z0{bv9%rW#$2RRR#Xvc8@4xYUPBA&UXpUbAyC})w~Kps_KWAjH3QDP{wW4dsb~9nB6^D7q={W8c$#ExUj&`5#*puEvLkg85O3`p!^Pa4m zdsFCqg-?9+hjD9XKy!Qj5xn}XFXF%X`+pao`}#L3W z6K}$PzsJoRf~gkF02Ce5RB-5|g#{a0?-t&t@xB88O4Pbq^L#l@MK~CJr<~S*2|%lc zmhwj&Kij|G$4ihgj=g`3QAt-#vWuukePoG;IqT#1vavbe;P<%Utgib2F>noptTO>O zbfKld`@H*@Q_KxIXz#--6&~@2?_+l&dmERdR(No3J2z#M6GM8!l; z?zyq&v(tF2o3RERpZ*-5Lk(H)$52y3OTmnR3+-=2TxRatmUS$jnt!W1LQvHDn?O+u zAZq7=Ml;+x8LRCd0CEHBh0bQ17*Co^V@aB=39$xr1d54IOddDXT0A>OVeK5rgtq?b zyi!Vmkmc3*eFRg++5~P0%JQT<*T+g{2%RWxU1P*(JvbzqN z?_0x}78IQ^qqtKQfLbGWlWqovn!>U%D)WuKOPer(!E8>e8Zo`x)JiRj6vJS?8+!Ls zz67X6G1UpIV|(hcM{(MIP8~MD8Gm64VEC$eK2~a46o>Na1_WTr`v*n)m1WufFSxFgdtNDK=WQ4+yrAB zc}(M4XXPw=yO{TsUM=2r>|`L(OW|i@6Iv{AJd;Mx5H1)@Ku{;1&EplNL-q*vmk+F$ zhNq0x?G|-2g_Ej7FazLu>XGa~;3^GvB9(@qg3?f@;_9ekUiBj8_-gT&4LU5Mr)tK& zHAi))S1PSJrnmFN3h=M_fpg`5*~dLp#SrP^k4y0Qu>LQ6cV4?SZ>|M?RszQ!-PIg? zjIo*3jl)usAQ-~SfGvNOXxe4XCmBy0JZPt1jm^%e4&eDxipZvjC{NUC@?V%Rb?p&U zR~+#tl#SB>c>Sor(*7Z0Ui%JA#d-vFFF)uo<6~P2q%~Y!9kgEy5#HlZclt!lG6Y%rAEgT;J|T|ckqAd(89o&i{_q2 zFR_TG4F1S8rA)ImsaUIv!Mhp;N~YmBJxs^Ft~XKrbggU|P;RA}2t1WL(KUXSv_8b2 zdm_e=ECw!0lhP-o~EAXqj4V@|JE^0j}XxEwJc z&*-#<>~Bz9&3jzCc80gT{hfHnbI)N@#2s42qRy&lb9X1Y0Xi$ywC5c5bCfA$-F1q8 zP8l$vyT}!*?~OG=?5k+ILL9nU*9FEC8p5l{x{m#=4#1VYo1lTgu=>v0=n2CoO1x7E zfe!g4A?s;CmcTi-H*K6!#Eo^=10Lj9mltGbw((*9*|C<=!D|5k9zkx;R`A3g8Um$w zP$uR*1famjr7nBb4fX|&7*3R6!qp{^Xl4)b;DvOG{wt>siOyZmk!`Ti?zO$)jgR}?57HAHY@47l*wx+mxK{z&tUeGNPKBH zS%n#)9=z=8K`K9S)r~Kej?J_|>kY5ozd#c;e57{&JS$Wz>$KKl!4EHcvtEid_GZTK zB{xGY1Ixwq)g7|nK1XES6;=l%IxOs+04Ij)c^VCS@R^RKj`6+Z398)d7F4s>6!AvE zY5(Scz{4Cb>(3V@M_A+2q{k#VhaYNJkW?nWN#lHL;E~XhAgCNouf+ENkCXFpITjHao6)eAVrf zS^%xs$QEatifL0ZZ6-7oJbv>Qo_qT<(M;JKGd0#E_AAA1#v=<_WZDmT%)gnPy#!Yh z&l$X*Y0FIZqjg7if)6RRwDI^P>IE72!z41J-6p5R9ImRKl}20)?u#)locNivDW#qU z^54bvMvtK$0)GVn^1m+629dDZWWAvlE3Z(6cQkguQmj6*cP~YWltpe_Bkb^GDl}42 zkrpWf-If-q#NS+hxG_3@XRnDdwkZL!l>vysu!uRc9rFB?tnpDC|dcM0;Sv0?RlKq zQM|W;MZ{d7gqJ!-1F7mw%slE64GV2ER5u#B1Ceu_gH32_Ezs7W{a`0`X~TB6wIhOQ zmn221DyVhx)4j5xJ-CH}FMyy3Jx)OzKrOR|!i8�U%TvjZe|T5 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�? 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�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%0AC&4LrD+4A0q>Q?55JQ)hvf^~r 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∾lkZE)zY(1oY;2!! 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␢RJF8qeZkNI8f|_Z((|r&l%){P7gyDsYRnC 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�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 ZWju75pp0D0O9h+_Jso3h>^;Yb{{Vm%*lhp+ literal 0 HcmV?d00001 From 7340b6dbc49d3bf8da73b87d121e0f3c367d8ccb Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 27 Nov 2018 10:53:00 +0100 Subject: [PATCH 0459/1292] Update CameraButton.qml Contributes to CL-1150 --- plugins/UM3NetworkPrinting/resources/qml/CameraButton.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/CameraButton.qml b/plugins/UM3NetworkPrinting/resources/qml/CameraButton.qml index 7e5c254e5c..618dbed81c 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/CameraButton.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/CameraButton.qml @@ -9,10 +9,10 @@ import Cura 1.0 as Cura Rectangle { property var iconSource: null; - color: clickArea.containsMouse ? UM.Theme.getColor("primary_hover") : UM.Theme.getColor("primary"); // "Cura Blue" + color: "#0a0850" // TODO: Theme! height: width; radius: Math.round(0.5 * width); - width: 36 * screenScaleFactor; + width: 24 * screenScaleFactor; UM.RecolorImage { id: icon; From 616ec13457f12fc3b0396f3872ec29024bd4ed9f Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 27 Nov 2018 10:54:26 +0100 Subject: [PATCH 0460/1292] Change context menu button size Contributes to CL-1150 --- .../UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml b/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml index 11bc913d06..02a8e7ae69 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml @@ -25,7 +25,7 @@ Item { } contentItem: Label { color: UM.Theme.getColor("monitor_context_menu_dots"); - font.pixelSize: 25 * screenScaleFactor; + font.pixelSize: 32 * screenScaleFactor; horizontalAlignment: Text.AlignHCenter; text: button.text; verticalAlignment: Text.AlignVCenter; @@ -41,7 +41,7 @@ Item { var states = ["queued", "sent_to_printer", "pre_print", "printing", "pausing", "paused", "resuming"]; return states.indexOf(printJob.state) !== -1; } - width: 35 * screenScaleFactor; // TODO: Theme! + width: 36 * screenScaleFactor; // TODO: Theme! } Popup { From 8965695a59916b6895d90468257007a5dd29a403 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 27 Nov 2018 10:54:46 +0100 Subject: [PATCH 0461/1292] Update MonitorPrintJobProgressBar.qml Contributes to CL-1150 --- .../qml/MonitorPrintJobProgressBar.qml | 202 ++++++++++-------- 1 file changed, 112 insertions(+), 90 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml index e7f9799310..6e16d026a1 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml @@ -6,107 +6,129 @@ import QtQuick.Controls.Styles 1.3 import QtQuick.Controls 1.4 import UM 1.3 as UM -ProgressBar +/** + * NOTE: For most labels, a fixed height with vertical alignment is used to make + * layouts more deterministic (like the fixed-size textboxes used in original + * mock-ups). This is also a stand-in for CSS's 'line-height' property. Denoted + * with '// FIXED-LINE-HEIGHT:'. + */ +Item { + id: base property var printJob: null - property var progress: { - if (!printJob) { - return 0; + property var progress: + { + if (!printJob) + { + return 0 } - var result = printJob.timeElapsed / printJob.timeTotal; - if (result > 1.0) { - result = 1.0; + var result = printJob.timeElapsed / printJob.timeTotal + if (result > 1.0) + { + result = 1.0 } - return result; + return result } - width: 180 * screenScaleFactor // TODO: Theme! - value: progress; - style: ProgressBarStyle { - property var remainingTime: { - if (!printJob) { - return 0; - } - /* Sometimes total minus elapsed is less than 0. Use Math.max() to prevent remaining - time from ever being less than 0. Negative durations cause strange behavior such - as displaying "-1h -1m". */ - return Math.max(printer.activePrintJob.timeTotal - printer.activePrintJob.timeElapsed, 0); + property var remainingTime: + { + if (!printJob) { + return 0 } - property var progressText: { - if (!printJob) { - return ""; - } - switch (printJob.state) { - case "wait_cleanup": - if (printJob.timeTotal > printJob.timeElapsed) { - return catalog.i18nc("@label:status", "Aborted"); - } - return catalog.i18nc("@label:status", "Finished"); - case "pre_print": - case "sent_to_printer": - return catalog.i18nc("@label:status", "Preparing"); - case "aborted": - return catalog.i18nc("@label:status", "Aborted"); - case "wait_user_action": - return catalog.i18nc("@label:status", "Aborted"); - case "pausing": - return catalog.i18nc("@label:status", "Pausing"); - case "paused": - return OutputDevice.formatDuration( remainingTime ); - case "resuming": - return catalog.i18nc("@label:status", "Resuming"); - case "queued": - return catalog.i18nc("@label:status", "Action required"); - default: - return OutputDevice.formatDuration( remainingTime ); - } + /* Sometimes total minus elapsed is less than 0. Use Math.max() to prevent remaining + time from ever being less than 0. Negative durations cause strange behavior such + as displaying "-1h -1m". */ + return Math.max(printer.activePrintJob.timeTotal - printer.activePrintJob.timeElapsed, 0) + } + property var progressText: + { + if (!printJob) + { + return ""; } - background: Rectangle { - color: "#e4e4f2" // TODO: Theme! - implicitHeight: visible ? 8 : 0; - implicitWidth: 180; - radius: 4 - } - progress: Rectangle { - id: progressItem; - color: { - if (!printJob) { - return "black"; + switch (printJob.state) + { + case "wait_cleanup": + if (printJob.timeTotal > printJob.timeElapsed) + { + return catalog.i18nc("@label:status", "Aborted") } - var state = printJob.state - var inactiveStates = [ - "pausing", - "paused", - "resuming", - "wait_cleanup" - ]; - if (inactiveStates.indexOf(state) > -1 && remainingTime > 0) { - return UM.Theme.getColor("monitor_progress_fill_inactive"); - } else { + return catalog.i18nc("@label:status", "Finished") + case "pre_print": + case "sent_to_printer": + return catalog.i18nc("@label:status", "Preparing") + case "aborted": + return catalog.i18nc("@label:status", "Aborted") + case "wait_user_action": + return catalog.i18nc("@label:status", "Aborted") + case "pausing": + return catalog.i18nc("@label:status", "Pausing") + case "paused": + return OutputDevice.formatDuration( remainingTime ) + case "resuming": + return catalog.i18nc("@label:status", "Resuming") + case "queued": + return catalog.i18nc("@label:status", "Action required") + default: + return OutputDevice.formatDuration( remainingTime ) + } + } + width: childrenRect.width + height: 18 * screenScaleFactor // TODO: Theme! + + ProgressBar + { + id: progressBar + anchors + { + verticalCenter: parent.verticalCenter + } + value: progress; + style: ProgressBarStyle + { + background: Rectangle + { + color: "#e4e4f2" // TODO: Theme! + implicitHeight: visible ? 8 * screenScaleFactor : 0 // TODO: Theme! + implicitWidth: 180 * screenScaleFactor // TODO: Theme! + radius: 4 * screenScaleFactor // TODO: Theme! + } + progress: Rectangle + { + id: progressItem; + color: + { + var state = printJob.state + var inactiveStates = [ + "pausing", + "paused", + "resuming", + "wait_cleanup" + ] + if (inactiveStates.indexOf(state) > -1 && remainingTime > 0) + { + return UM.Theme.getColor("monitor_progress_fill_inactive") + } return "#0a0850" // TODO: Theme! } - } - radius: 4 - - Label { - id: progressLabel; - anchors { - left: parent.left; - leftMargin: getTextOffset(); - } - text: progressText; - anchors.verticalCenter: parent.verticalCenter; - color: progressItem.width + progressLabel.width < control.width ? UM.Theme.getColor("text") : UM.Theme.getColor("monitor_progress_fill_text"); - width: contentWidth; - font: UM.Theme.getFont("default"); - } - - function getTextOffset() { - if (progressItem.width + progressLabel.width + 16 < control.width) { - return progressItem.width + UM.Theme.getSize("default_margin").width; - } else { - return progressItem.width - progressLabel.width - UM.Theme.getSize("default_margin").width; - } + radius: 4 * screenScaleFactor // TODO: Theme! } } } + Label + { + id: progressLabel + anchors + { + left: progressBar.right + leftMargin: 18 * screenScaleFactor // TODO: Theme! + } + text: progressText + color: "#374355" // TODO: Theme! + width: contentWidth + font: UM.Theme.getFont("medium") // 14pt, regular + + // FIXED-LINE-HEIGHT: + height: 18 * screenScaleFactor // TODO: Theme! + verticalAlignment: Text.AlignVCenter + } } \ No newline at end of file From 475a94d10d4e7fadb7fc43978c59349cda6bb000 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 27 Nov 2018 10:55:08 +0100 Subject: [PATCH 0462/1292] Add printer images Commit to CL-1150 --- .../resources/qml/MonitorPrinterCard.qml | 48 +++++++++++++------ 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml index 2fd3f2ead2..8089ea2d30 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml @@ -1,7 +1,7 @@ // Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.2 +import QtQuick 2.3 import QtQuick.Controls 2.0 import UM 1.3 as UM @@ -50,12 +50,18 @@ Item } spacing: 18 * screenScaleFactor // TODO: Theme! - Rectangle + Image { id: printerImage - color: "#eeeeee" - width: 108 - height: 108 + width: 108 * screenScaleFactor // TODO: Theme! + height: 108 * screenScaleFactor // TODO: Theme! + fillMode: Image.PreserveAspectFit + source: + { + console.log(printer) + return "../png/ultimaker_s5.png" + } + mipmap: true } Item @@ -111,16 +117,28 @@ Item PrintJobContextMenu { id: contextButton - // anchors - // { - // right: parent.right - // rightMargin: 8 * screenScaleFactor // TODO: Theme! - // top: parent.top - // topMargin: 8 * screenScaleFactor // TODO: Theme! - // } - printJob: base.printJob - width: 32 * screenScaleFactor // TODO: Theme! - height: 32 * screenScaleFactor // TODO: Theme! + anchors + { + right: parent.right + rightMargin: 12 * screenScaleFactor // TODO: Theme! + top: parent.top + topMargin: 12 * screenScaleFactor // TODO: Theme! + } + printJob: printer.activePrintJob + width: 36 * screenScaleFactor // TODO: Theme! + height: 36 * screenScaleFactor // TODO: Theme! + } + CameraButton + { + id: cameraButton; + anchors + { + right: parent.right + rightMargin: 20 * screenScaleFactor // TODO: Theme! + bottom: parent.bottom + bottomMargin: 20 * screenScaleFactor // TODO: Theme! + } + iconSource: "../svg/camera-icon.svg" } } From c489f911fb2b16bef7dfa5a4bac76ee83620d13b Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 27 Nov 2018 11:04:41 +0100 Subject: [PATCH 0463/1292] Use QtQuick 2.0 and simplify ConfigurationItem It now uses a ButtonGroup (from QtQuick2). Also, all the mess with when the border and background colours are updated and force-updated and such is now cleaned up. Contributes to issue CURA-5876. --- .../ConfigurationMenu/ConfigurationItem.qml | 189 +++++++----------- .../ConfigurationListView.qml | 10 +- 2 files changed, 83 insertions(+), 116 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 7427b5ddff..d825a8cc6e 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -7,143 +7,108 @@ import QtQuick.Controls 2.0 import UM 1.2 as UM import Cura 1.0 as Cura -Rectangle +Button { id: configurationItem property var configuration: null - property var selected: false signal activateConfiguration() height: childrenRect.height - border.width: UM.Theme.getSize("default_lining").width - border.color: updateBorderColor() - color: selected ? UM.Theme.getColor("configuration_item_active") : UM.Theme.getColor("configuration_item") - property var textColor: selected ? UM.Theme.getColor("configuration_item_text_active") : UM.Theme.getColor("configuration_item_text") - function updateBorderColor() + property var textColor: checked ? UM.Theme.getColor("configuration_item_text_active") : UM.Theme.getColor("configuration_item_text") + + contentItem: Rectangle { - border.color = selected ? UM.Theme.getColor("configuration_item_border_active") : UM.Theme.getColor("configuration_item_border") - } + height: childrenRect.height + color: parent.checked ? UM.Theme.getColor("configuration_item_active") : UM.Theme.getColor("configuration_item") + border.color: (parent.checked || parent.hovered) ? UM.Theme.getColor("primary") : UM.Theme.getColor("lining") + border.width: UM.Theme.getSize("default_lining").width - Column - { - id: contentColumn - width: parent.width - padding: UM.Theme.getSize("default_margin").width - spacing: Math.round(UM.Theme.getSize("default_margin").height / 2) - - Row + Column { - id: extruderRow + id: contentColumn + width: parent.width + padding: UM.Theme.getSize("default_margin").width + spacing: Math.round(UM.Theme.getSize("default_margin").height / 2) - width: parent.width - 2 * parent.padding - height: childrenRect.height - - spacing: UM.Theme.getSize("default_margin").width - - Repeater + Row { - id: repeater + id: extruderRow + + width: parent.width - 2 * parent.padding height: childrenRect.height - model: configuration.extruderConfigurations - delegate: PrintCoreConfiguration + + spacing: UM.Theme.getSize("default_margin").width + + Repeater { - width: Math.round(parent.width / 2) - printCoreConfiguration: modelData - mainColor: textColor + id: repeater + height: childrenRect.height + model: configuration.extruderConfigurations + delegate: PrintCoreConfiguration + { + width: Math.round(parent.width / 2) + printCoreConfiguration: modelData + mainColor: textColor + } + } + } + + //Buildplate row separator + Rectangle + { + id: separator + + visible: buildplateInformation.visible + width: parent.width - 2 * parent.padding + height: visible ? Math.round(UM.Theme.getSize("thick_lining").height / 2) : 0 + color: textColor + } + + Item + { + id: buildplateInformation + width: parent.width - 2 * parent.padding + height: childrenRect.height + visible: configuration.buildplateConfiguration != "" + + UM.RecolorImage { + id: buildplateIcon + anchors.left: parent.left + width: UM.Theme.getSize("main_window_header_button_icon").width + height: UM.Theme.getSize("main_window_header_button_icon").height + sourceSize.width: width + sourceSize.height: height + source: UM.Theme.getIcon("buildplate") + color: textColor + } + + Label + { + id: buildplateLabel + anchors.left: buildplateIcon.right + anchors.verticalCenter: buildplateIcon.verticalCenter + anchors.leftMargin: Math.round(UM.Theme.getSize("default_margin").height / 2) + text: configuration.buildplateConfiguration + renderType: Text.NativeRendering + color: textColor } } } - //Buildplate row separator - Rectangle + Connections { - id: separator - - visible: buildplateInformation.visible - width: parent.width - 2 * parent.padding - height: visible ? Math.round(UM.Theme.getSize("thick_lining").height / 2) : 0 - color: textColor - } - - Item - { - id: buildplateInformation - width: parent.width - 2 * parent.padding - height: childrenRect.height - visible: configuration.buildplateConfiguration != "" - - UM.RecolorImage { - id: buildplateIcon - anchors.left: parent.left - width: UM.Theme.getSize("main_window_header_button_icon").width - height: UM.Theme.getSize("main_window_header_button_icon").height - sourceSize.width: width - sourceSize.height: height - source: UM.Theme.getIcon("buildplate") - color: textColor - } - - Label + target: Cura.MachineManager + onCurrentConfigurationChanged: { - id: buildplateLabel - anchors.left: buildplateIcon.right - anchors.verticalCenter: buildplateIcon.verticalCenter - anchors.leftMargin: Math.round(UM.Theme.getSize("default_margin").height / 2) - text: configuration.buildplateConfiguration - renderType: Text.NativeRendering - color: textColor + configurationItem.checked = Cura.MachineManager.matchesConfiguration(configuration) } } - } - MouseArea - { - id: mouse - anchors.fill: parent - onClicked: activateConfiguration() - cursorShape: Qt.PointingHandCursor - hoverEnabled: true - onEntered: + Component.onCompleted: { - parent.border.color = UM.Theme.getColor("configuration_item_border_hover") - if (configurationItem.selected == false) - { - configurationItem.color = UM.Theme.getColor("wide_lining") - } - } - onExited: - { - updateBorderColor() - if (configurationItem.selected == false) - { - configurationItem.color = UM.Theme.getColor("configuration_item") - } - } - } - - Connections - { - target: Cura.MachineManager - onCurrentConfigurationChanged: { - configurationItem.selected = Cura.MachineManager.matchesConfiguration(configuration) - updateBorderColor() - } - } - - Component.onCompleted: - { - configurationItem.selected = Cura.MachineManager.matchesConfiguration(configuration) - updateBorderColor() - } - - onVisibleChanged: - { - if(visible) - { - // I cannot trigger function updateBorderColor() after visibility change - color = selected ? UM.Theme.getColor("configuration_item_active") : UM.Theme.getColor("configuration_item") + configurationItem.checked = Cura.MachineManager.matchesConfiguration(configuration) } } } \ No newline at end of file diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index 2f5bf0b1a2..7df93b9cbe 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -2,8 +2,7 @@ // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 +import QtQuick.Controls 2.4 import UM 1.2 as UM import Cura 1.0 as Cura @@ -31,8 +30,10 @@ Column width: parent.width - parent.padding height: Math.min(configurationList.contentHeight, 350 * screenScaleFactor) - style: UM.Theme.styles.scrollview - __wheelAreaScrollSpeed: 75 // Scroll three lines in one scroll event + ButtonGroup + { + buttons: configurationList.children + } ListView { @@ -64,6 +65,7 @@ Column } model: (outputDevice != null) ? outputDevice.uniqueConfigurations : [] + delegate: ConfigurationItem { width: parent.width - UM.Theme.getSize("default_margin").width From e05566865a9d5333d1dbf444b62a3ecbd4a29445 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 27 Nov 2018 11:19:03 +0100 Subject: [PATCH 0464/1292] Use ExtruderIcon component to display extruder icon Since we already have that component pre-designed, let's use it. Contributes to issue CURA-5876. --- .../PrintCoreConfiguration.qml | 34 +++---------------- 1 file changed, 5 insertions(+), 29 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml index 97b5bee745..e8cadda05e 100644 --- a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml @@ -5,7 +5,7 @@ import QtQuick 2.7 import QtQuick.Controls 2.0 import UM 1.2 as UM - +import Cura 1.0 as Cura Column { @@ -33,37 +33,13 @@ Column color: mainColor } - // Rounded item to show the extruder number - Item + Cura.ExtruderIcon { - id: extruderIconItem - anchors.verticalCenter: extruderLabel.verticalCenter - anchors.left: extruderLabel.right - anchors.leftMargin: Math.round(UM.Theme.getSize("default_margin").width / 2) - width: UM.Theme.getSize("section_icon").width height: UM.Theme.getSize("section_icon").height - - UM.RecolorImage { - id: mainCircle - anchors.fill: parent - - anchors.centerIn: parent - sourceSize.width: parent.width - sourceSize.height: parent.height - source: UM.Theme.getIcon("extruder_button") - color: mainColor - } - - Label - { - id: extruderNumberText - anchors.centerIn: parent - text: printCoreConfiguration.position + 1 - renderType: Text.NativeRendering - font: UM.Theme.getFont("default") - color: mainColor - } + materialColor: mainColor + anchors.left: extruderLabel.right + anchors.leftMargin: UM.Theme.getSize("narrow_margin").width } } From a3f0630ee9a1ba106969dada676c1d045cd5e762 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 27 Nov 2018 11:19:30 +0100 Subject: [PATCH 0465/1292] Rename printer images Contributes to CL-1150 --- ...ultimaker_3_ext.png => Ultimaker 3 Extended.png} | Bin .../png/{ultimaker_3.png => Ultimaker 3.png} | Bin .../png/{ultimaker_s5.png => Ultimaker S5.png} | Bin .../resources/qml/MonitorPrinterCard.qml | 4 ++-- 4 files changed, 2 insertions(+), 2 deletions(-) rename plugins/UM3NetworkPrinting/resources/png/{ultimaker_3_ext.png => Ultimaker 3 Extended.png} (100%) rename plugins/UM3NetworkPrinting/resources/png/{ultimaker_3.png => Ultimaker 3.png} (100%) rename plugins/UM3NetworkPrinting/resources/png/{ultimaker_s5.png => Ultimaker S5.png} (100%) diff --git a/plugins/UM3NetworkPrinting/resources/png/ultimaker_3_ext.png b/plugins/UM3NetworkPrinting/resources/png/Ultimaker 3 Extended.png similarity index 100% rename from plugins/UM3NetworkPrinting/resources/png/ultimaker_3_ext.png rename to plugins/UM3NetworkPrinting/resources/png/Ultimaker 3 Extended.png diff --git a/plugins/UM3NetworkPrinting/resources/png/ultimaker_3.png b/plugins/UM3NetworkPrinting/resources/png/Ultimaker 3.png similarity index 100% rename from plugins/UM3NetworkPrinting/resources/png/ultimaker_3.png rename to plugins/UM3NetworkPrinting/resources/png/Ultimaker 3.png diff --git a/plugins/UM3NetworkPrinting/resources/png/ultimaker_s5.png b/plugins/UM3NetworkPrinting/resources/png/Ultimaker S5.png similarity index 100% rename from plugins/UM3NetworkPrinting/resources/png/ultimaker_s5.png rename to plugins/UM3NetworkPrinting/resources/png/Ultimaker S5.png diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml index 8089ea2d30..bc8144bcd6 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml @@ -58,8 +58,8 @@ Item fillMode: Image.PreserveAspectFit source: { - console.log(printer) - return "../png/ultimaker_s5.png" + console.log(printer.type) + return "../png/"+printer.type+".png" } mipmap: true } From fd723e10842f2fe4d77d9c010495c72aea8dfd20 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 27 Nov 2018 11:19:45 +0100 Subject: [PATCH 0466/1292] Improve camera icon Contributes to CL-1150 --- .../UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml | 2 +- plugins/UM3NetworkPrinting/resources/svg/icons/camera.svg | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 plugins/UM3NetworkPrinting/resources/svg/icons/camera.svg diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml index bc8144bcd6..d1d9bec351 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml @@ -138,7 +138,7 @@ Item bottom: parent.bottom bottomMargin: 20 * screenScaleFactor // TODO: Theme! } - iconSource: "../svg/camera-icon.svg" + iconSource: "../svg/icons/camera.svg" } } diff --git a/plugins/UM3NetworkPrinting/resources/svg/icons/camera.svg b/plugins/UM3NetworkPrinting/resources/svg/icons/camera.svg new file mode 100644 index 0000000000..2eaebb812d --- /dev/null +++ b/plugins/UM3NetworkPrinting/resources/svg/icons/camera.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file From e6c2238fd51a5eec44a645ad4a1e798120bf58a5 Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Tue, 27 Nov 2018 11:24:09 +0100 Subject: [PATCH 0467/1292] Added popup spacing by Y coordinate CURA-5941 --- resources/qml/ExpandableComponent.qml | 5 ++++- resources/qml/PrintSetupSelector.qml | 12 ++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index 262c6bfd3f..3b1105ddd6 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -24,6 +24,9 @@ Item // How much spacing is needed around the popupItem property alias popupPadding: popup.padding + // How much spacing is needed for the popupItem by Y coordinate + property var popupSpacingY: 0 + // How much padding is needed around the header & button property alias headerPadding: background.padding @@ -143,7 +146,7 @@ Item id: popup // Ensure that the popup is located directly below the headerItem - y: headerItemLoader.height + 2 * background.padding + y: headerItemLoader.height + 2 * background.padding + popupSpacingY // Make the popup right aligned with the rest. The 3x padding is due to left, right and padding between // the button & text. diff --git a/resources/qml/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector.qml index 8271484e6a..5f593f9ba2 100644 --- a/resources/qml/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector.qml @@ -29,6 +29,7 @@ Cura.ExpandableComponent iconSource: UM.Theme.getIcon("pencil") popupPadding : 0 + popupSpacingY: 10 onCurrentModeIndexChanged: UM.Preferences.setValue("cura/active_mode", currentModeIndex) @@ -150,10 +151,13 @@ Cura.ExpandableComponent verticalAlignment: Text.AlignVCenter color: UM.Theme.getColor("text") height: parent.height - anchors.topMargin: UM.Theme.getSize("sidebar_margin").height -// anchors.bottomMargin: UM.Theme.getSize("sidebar_margin").height - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("print_setup_selector_margin").height + + anchors + { + topMargin: UM.Theme.getSize("sidebar_margin").height + left: parent.left + leftMargin: UM.Theme.getSize("print_setup_selector_margin").height + } } Rectangle From e2f85fcdc4922fada1ec7d259cab11a9c452df87 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 27 Nov 2018 11:25:43 +0100 Subject: [PATCH 0468/1292] Add extra space to printer button. Contributes to CURA-5942. --- resources/qml/PrinterSelector/MachineSelector.qml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index 93e5103aa8..15cd773c90 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -90,11 +90,13 @@ Cura.ExpandableComponent id: scroll width: parent.width clip: true + leftPadding: UM.Theme.getSize("default_lining").width + rightPadding: UM.Theme.getSize("default_lining").width MachineSelectorList { // Can't use parent.width since the parent is the flickable component and not the ScrollView - width: scroll.width + width: scroll.width - scroll.leftPadding - scroll.rightPadding property real maximumHeight: UM.Theme.getSize("machine_selector_widget_content").height - buttonRow.height onHeightChanged: From 75b827d3732f128bd3eacb14d8803d90fa057a4c Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 27 Nov 2018 11:26:20 +0100 Subject: [PATCH 0469/1292] Modify the hover behavior by removing the mouse area. Contributes to CURA-5942. --- resources/qml/PrinterSelector/MachineSelectorButton.qml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/resources/qml/PrinterSelector/MachineSelectorButton.qml b/resources/qml/PrinterSelector/MachineSelectorButton.qml index 992ea55b1d..369e75cede 100644 --- a/resources/qml/PrinterSelector/MachineSelectorButton.qml +++ b/resources/qml/PrinterSelector/MachineSelectorButton.qml @@ -16,6 +16,7 @@ Button leftPadding: UM.Theme.getSize("thick_margin").width rightPadding: UM.Theme.getSize("thick_margin").width checkable: true + hoverEnabled: true property var outputDevice: null property var printerTypesList: [] @@ -86,14 +87,6 @@ Button Cura.MachineManager.setActiveMachine(model.id) } - MouseArea - { - id: mouseArea - anchors.fill: parent - onPressed: mouse.accepted = false - hoverEnabled: true - } - Connections { target: outputDevice From 6876c12106e32d74a1d492eac6d95fc9130a8474 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 27 Nov 2018 11:43:32 +0100 Subject: [PATCH 0470/1292] Remove weird padding from button I don't know why the default Button has padding everywhere, but I don't want it. Contributes to issue CURA-5876. --- resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index d825a8cc6e..a6778702d1 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -15,6 +15,9 @@ Button signal activateConfiguration() height: childrenRect.height + padding: 0 //Stupid QML button has spacing by default. + rightPadding: 0 + leftPadding: 0 property var textColor: checked ? UM.Theme.getColor("configuration_item_text_active") : UM.Theme.getColor("configuration_item_text") @@ -73,7 +76,8 @@ Button height: childrenRect.height visible: configuration.buildplateConfiguration != "" - UM.RecolorImage { + UM.RecolorImage + { id: buildplateIcon anchors.left: parent.left width: UM.Theme.getSize("main_window_header_button_icon").width From a2b1f5397962d5e4da7511e54eef4e7a1ad235a0 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 27 Nov 2018 11:53:17 +0100 Subject: [PATCH 0471/1292] Use normal text colour instead of specialised configuration item text They were the same anyway, and they should always be the same. Contributes to issue CURA-5876. --- .../qml/Menus/ConfigurationMenu/ConfigurationItem.qml | 10 ++++------ .../Menus/ConfigurationMenu/ConfigurationListView.qml | 2 +- resources/themes/cura-light/theme.json | 2 -- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index a6778702d1..6a6f0ea834 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -19,8 +19,6 @@ Button rightPadding: 0 leftPadding: 0 - property var textColor: checked ? UM.Theme.getColor("configuration_item_text_active") : UM.Theme.getColor("configuration_item_text") - contentItem: Rectangle { height: childrenRect.height @@ -53,7 +51,7 @@ Button { width: Math.round(parent.width / 2) printCoreConfiguration: modelData - mainColor: textColor + mainColor: UM.Theme.getColor("text") } } } @@ -66,7 +64,7 @@ Button visible: buildplateInformation.visible width: parent.width - 2 * parent.padding height: visible ? Math.round(UM.Theme.getSize("thick_lining").height / 2) : 0 - color: textColor + color: UM.Theme.getColor("text") } Item @@ -85,7 +83,7 @@ Button sourceSize.width: width sourceSize.height: height source: UM.Theme.getIcon("buildplate") - color: textColor + color: UM.Theme.getColor("text") } Label @@ -96,7 +94,7 @@ Button anchors.leftMargin: Math.round(UM.Theme.getSize("default_margin").height / 2) text: configuration.buildplateConfiguration renderType: Text.NativeRendering - color: textColor + color: UM.Theme.getColor("text") } } } diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index 7df93b9cbe..2b7444be01 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -58,7 +58,7 @@ Column { text: section font: UM.Theme.getFont("small") - color: UM.Theme.getColor("configuration_item_text") + color: UM.Theme.getColor("text") padding: UM.Theme.getSize("narrow_margin").width } } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index a51b397262..383159fd91 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -319,8 +319,6 @@ "configuration_item": [255, 255, 255, 0], "configuration_item_active": [12, 169, 227, 32], - "configuration_item_text": [0, 0, 0, 255], - "configuration_item_text_active": [0, 0, 0, 255], "configuration_item_border": [127, 127, 127, 255], "configuration_item_border_active": [12, 169, 227, 32], "configuration_item_border_hover": [50, 130, 255, 255], From 44c415ff78fbc085a81e2fc6da08e91c44c0ea8e Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 27 Nov 2018 11:58:32 +0100 Subject: [PATCH 0472/1292] Add shadow to ExpandableComponent --- resources/qml/ExpandableComponent.qml | 23 ++++++++++++++++++++++- resources/themes/cura-light/theme.json | 2 +- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index 9b2826daed..b438f0398c 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -4,6 +4,8 @@ import QtQuick.Controls 2.3 import UM 1.2 as UM import Cura 1.0 as Cura +import QtGraphicalEffects 1.0 // For the dropshadow + // The expandable component has 3 major sub components: // * The headerItem; Always visible and should hold some info about what happens if the component is expanded // * The popupItem; The content that needs to be shown if the component is expanded. @@ -58,6 +60,12 @@ Item // On what side should the header corners be shown? 1 is down, 2 is left, 3 is up and 4 is right. property alias headerCornerSide: background.cornerSide + property alias headerShadowColor: shadow.color + + property alias enableHeaderShadow: shadow.visible + + property int shadowOffset: 2 + function togglePopup() { if(popup.visible) @@ -149,13 +157,26 @@ Item onExited: background.color = headerBackgroundColor } } + DropShadow + { + id: shadow + // Don't blur the shadow + radius: 0 + anchors.fill: background + source: background + verticalOffset: base.shadowOffset + visible: true + color: UM.Theme.getColor("action_button_shadow") + // Should always be drawn behind the background. + z: background.z - 1 + } Popup { id: popup // Ensure that the popup is located directly below the headerItem - y: headerItemLoader.height + 2 * background.padding + y: headerItemLoader.height + 2 * background.padding + base.shadowOffset // Make the popup aligned with the rest, using the property popupAlignment to decide whether is right or left. // In case of right alignment, the 3x padding is due to left, right and padding between the button & text. diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 0cfa36fd2e..cc33d82b7d 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -178,7 +178,7 @@ "action_button_disabled": [245, 245, 245, 255], "action_button_disabled_text": [127, 127, 127, 255], "action_button_disabled_border": [245, 245, 245, 255], - "action_button_shadow": [64, 47, 205, 255], + "action_button_shadow": [223, 223, 223, 255], "action_button_disabled_shadow": [228, 228, 228, 255], "scrollbar_background": [255, 255, 255, 255], From e04f14b50c8967d063c90731b6e367ba5c996a9e Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 27 Nov 2018 12:01:05 +0100 Subject: [PATCH 0473/1292] Also add shadow to openFile button --- plugins/PrepareStage/PrepareMenu.qml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index 81799206a0..31a78ed290 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -8,6 +8,7 @@ import QtQuick.Controls 2.3 import UM 1.3 as UM import Cura 1.1 as Cura +import QtGraphicalEffects 1.0 // For the dropshadow Item { @@ -107,12 +108,26 @@ Item background: Rectangle { + id: background height: UM.Theme.getSize("stage_menu").height width: UM.Theme.getSize("stage_menu").height radius: UM.Theme.getSize("default_radius").width color: openFileButton.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") } + DropShadow + { + id: shadow + // Don't blur the shadow + radius: 0 + anchors.fill: background + source: background + verticalOffset: 2 + visible: true + color: UM.Theme.getColor("action_button_shadow") + // Should always be drawn behind the background. + z: background.z - 1 + } } } } From 1a6822436ddd22d53553c0d2ddcf549084bf763c Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 27 Nov 2018 12:01:43 +0100 Subject: [PATCH 0474/1292] Add missing HoverEnabled property Some systems, like mine, don't have the hoverEnabled default set to true. --- plugins/PrepareStage/PrepareMenu.qml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index 31a78ed290..4212911011 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -93,6 +93,7 @@ Item height: UM.Theme.getSize("stage_menu").height width: UM.Theme.getSize("stage_menu").height onClicked: Cura.Actions.open.trigger() + hoverEnabled: true contentItem: UM.RecolorImage { @@ -115,6 +116,7 @@ Item radius: UM.Theme.getSize("default_radius").width color: openFileButton.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") } + DropShadow { id: shadow From e58409b1ef07885a7e7d1807cbf243fc15deaf47 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 27 Nov 2018 12:51:52 +0100 Subject: [PATCH 0475/1292] Correct colours for the selected configuration This should always be the same as the ExpandableComponent's background, so white when it's not active and light blue when it's active, regardless of theme. The naming of this theme entry is a bit weird because the ActionButton theme is used for ExpandableComponent and now for ConfigurationItem as well, but that's why we should NEVER name these theme entries to something specific to one item. Oh well, I'm not about to refactor that now with all the branches going on everywhere. Contributes to issue CURA-5876. --- resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 6a6f0ea834..98f777d3f3 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -22,7 +22,7 @@ Button contentItem: Rectangle { height: childrenRect.height - color: parent.checked ? UM.Theme.getColor("configuration_item_active") : UM.Theme.getColor("configuration_item") + color: parent.checked ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") border.color: (parent.checked || parent.hovered) ? UM.Theme.getColor("primary") : UM.Theme.getColor("lining") border.width: UM.Theme.getSize("default_lining").width From 0be2453daf29080111f622e371708fd970946336 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 27 Nov 2018 12:55:07 +0100 Subject: [PATCH 0476/1292] Update style of border of configuration items Contributes to issue CURA-5876. --- resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 98f777d3f3..278381dc5a 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -23,8 +23,8 @@ Button { height: childrenRect.height color: parent.checked ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") - border.color: (parent.checked || parent.hovered) ? UM.Theme.getColor("primary") : UM.Theme.getColor("lining") - border.width: UM.Theme.getSize("default_lining").width + border.color: parent.hovered ? UM.Theme.getColor("primary") : UM.Theme.getColor("lining") + border.width: parent.hovered ? UM.Theme.getSize("thick_lining").width : UM.Theme.getSize("default_lining").width Column { From e751b59b1cd13855b413d79ef8a950bb53b7287b Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 27 Nov 2018 12:55:58 +0100 Subject: [PATCH 0477/1292] Remove unused configuration item theme entries The theme of configuration items is now in sync with the rest of the interface. Contributes to issue CURA-5876. --- resources/themes/cura-dark/theme.json | 8 -------- resources/themes/cura-light/theme.json | 6 ------ 2 files changed, 14 deletions(-) diff --git a/resources/themes/cura-dark/theme.json b/resources/themes/cura-dark/theme.json index 62b1dbfa0f..40016c5a94 100644 --- a/resources/themes/cura-dark/theme.json +++ b/resources/themes/cura-dark/theme.json @@ -197,14 +197,6 @@ "layerview_support_interface": [64, 192, 255, 255], "layerview_nozzle": [181, 166, 66, 120], - "configuration_item": [0, 0, 0, 0], - "configuration_item_active": [12, 169, 227, 179], - "configuration_item_text": [255, 255, 255, 255], - "configuration_item_text_active": [255, 255, 255, 255], - "configuration_item_border": [255, 255, 255, 255], - "configuration_item_border_active": [12, 169, 227, 179], - "configuration_item_border_hover": [12, 169, 227, 179], - "material_compatibility_warning": [255, 255, 255, 255], "quality_slider_unavailable": [179, 179, 179, 255], diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 383159fd91..de9b48c7f0 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -317,12 +317,6 @@ "layerview_support_interface": [64, 192, 255, 255], "layerview_nozzle": [181, 166, 66, 50], - "configuration_item": [255, 255, 255, 0], - "configuration_item_active": [12, 169, 227, 32], - "configuration_item_border": [127, 127, 127, 255], - "configuration_item_border_active": [12, 169, 227, 32], - "configuration_item_border_hover": [50, 130, 255, 255], - "tab_status_connected": [50, 130, 255, 255], "tab_status_disconnected": [200, 200, 200, 255], From fb84b344ecac3683848dbdd71d20e5079bd11818 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 27 Nov 2018 12:58:06 +0100 Subject: [PATCH 0478/1292] Add gradient to header bar --- resources/qml/Cura.qml | 27 ++++++++++++++++++- resources/qml/MainWindow/MainWindowHeader.qml | 27 ++++++++++++++++++- resources/themes/cura-light/theme.json | 1 + 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 2814bb9eb2..63888a4ee4 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -6,6 +6,7 @@ import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import QtQuick.Layouts 1.1 import QtQuick.Dialogs 1.2 +import QtGraphicalEffects 1.0 import UM 1.3 as UM import Cura 1.1 as Cura @@ -153,7 +154,31 @@ UM.MainWindow } visible: stageMenu.source != "" height: Math.round(UM.Theme.getSize("stage_menu").height / 2) - color: UM.Theme.getColor("main_window_header_background") + + LinearGradient + { + anchors.fill: parent + start: Qt.point(0, 0) + end: Qt.point(parent.width, 0) + gradient: Gradient + { + GradientStop + { + position: 0.0 + color: UM.Theme.getColor("main_window_header_background") + } + GradientStop + { + position: 0.5 + color: UM.Theme.getColor("main_window_header_background_gradient") + } + GradientStop + { + position: 1.0 + color: UM.Theme.getColor("main_window_header_background") + } + } + } } Connections diff --git a/resources/qml/MainWindow/MainWindowHeader.qml b/resources/qml/MainWindow/MainWindowHeader.qml index a24af7ee45..2942a9feb3 100644 --- a/resources/qml/MainWindow/MainWindowHeader.qml +++ b/resources/qml/MainWindow/MainWindowHeader.qml @@ -8,6 +8,7 @@ import QtQuick.Controls.Styles 1.1 import UM 1.4 as UM import Cura 1.0 as Cura +import QtGraphicalEffects 1.0 import "../Account" @@ -17,7 +18,31 @@ Rectangle implicitHeight: UM.Theme.getSize("main_window_header").height implicitWidth: UM.Theme.getSize("main_window_header").width - color: UM.Theme.getColor("main_window_header_background") + + LinearGradient + { + anchors.fill: parent + start: Qt.point(0, 0) + end: Qt.point(parent.width, 0) + gradient: Gradient + { + GradientStop + { + position: 0.0 + color: UM.Theme.getColor("main_window_header_background") + } + GradientStop + { + position: 0.5 + color: UM.Theme.getColor("main_window_header_background_gradient") + } + GradientStop + { + position: 1.0 + color: UM.Theme.getColor("main_window_header_background") + } + } + } Image { diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index cc33d82b7d..157adcf6a5 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -100,6 +100,7 @@ "secondary_button_text": [30, 102, 215, 255], "main_window_header_background": [10, 8, 80, 255], + "main_window_header_background_gradient": [25, 23, 91, 255], "main_window_header_button_text_active": [10, 8, 80, 255], "main_window_header_button_text_inactive": [255, 255, 255, 255], "main_window_header_button_text_hovered": [255, 255, 255, 255], From 81cadf702cedea664c1071d46e5261c1dc592b93 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 27 Nov 2018 13:00:51 +0100 Subject: [PATCH 0479/1292] Give configuration items a rounded radius Contributes to issue CURA-5876. --- resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 278381dc5a..f04e856705 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -25,6 +25,7 @@ Button color: parent.checked ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") border.color: parent.hovered ? UM.Theme.getColor("primary") : UM.Theme.getColor("lining") border.width: parent.hovered ? UM.Theme.getSize("thick_lining").width : UM.Theme.getSize("default_lining").width + radius: UM.Theme.getSize("default_radius").width Column { From 0794a2c8c9197c536ffcba090df72edd7d6e7fc6 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 27 Nov 2018 13:03:36 +0100 Subject: [PATCH 0480/1292] Remove not needed printer and extruder definitions. Contributes to CURA-5902. --- .../bibo2_single_extruder_0.def.json | 98 ------------------- .../bibo2_single_extruder_1.def.json | 98 ------------------- .../bibo2_single_extruder_0_0.def.json | 40 -------- .../bibo2_single_extruder_0_1.def.json | 40 -------- .../bibo2_single_extruder_1_0.def.json | 40 -------- .../bibo2_single_extruder_1_1.def.json | 40 -------- 6 files changed, 356 deletions(-) delete mode 100644 resources/definitions/bibo2_single_extruder_0.def.json delete mode 100644 resources/definitions/bibo2_single_extruder_1.def.json delete mode 100644 resources/extruders/bibo2_single_extruder_0_0.def.json delete mode 100644 resources/extruders/bibo2_single_extruder_0_1.def.json delete mode 100644 resources/extruders/bibo2_single_extruder_1_0.def.json delete mode 100644 resources/extruders/bibo2_single_extruder_1_1.def.json diff --git a/resources/definitions/bibo2_single_extruder_0.def.json b/resources/definitions/bibo2_single_extruder_0.def.json deleted file mode 100644 index 93c7a4e5ae..0000000000 --- a/resources/definitions/bibo2_single_extruder_0.def.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "id": "BIBO2 single E1", - "version": 2, - "name": "BIBO2 single E1", - "inherits": "fdmprinter", - "metadata": { - "visible": true, - "author": "na", - "manufacturer": "BIBO", - "category": "Other", - "file_formats": "text/x-gcode", - "has_materials": true, - "machine_extruder_trains": { - "0": "bibo2_single_extruder_0_0", - "1": "bibo2_single_extruder_0_1" - }, - "first_start_actions": [ - "MachineSettingsAction" - ] - }, - "overrides": { - "machine_name": { - "default_value": "BIBO2 single Extruder 1 (right)" - }, - "machine_width": { - "default_value": 214 - }, - "machine_height": { - "default_value": 160 - }, - "machine_depth": { - "default_value": 186 - }, - "machine_center_is_zero": { - "default_value": true - }, - "machine_heated_bed": { - "default_value": true - }, - "machine_nozzle_size": { - "default_value": 0.4 - }, - "machine_nozzle_heat_up_speed": { - "default_value": 2 - }, - "machine_nozzle_cool_down_speed": { - "default_value": 2 - }, - "machine_head_with_fans_polygon": { - "default_value": [ - [ - -68.18, - 64.63 - ], - [ - -68.18, - -47.38 - ], - [ - 35.18, - 64.63 - ], - [ - 35.18, - -47.38 - ] - ] - }, - "material_diameter": { - "default_value": 1.75 - }, - "gantry_height": { - "default_value": 12 - }, - "machine_use_extruder_offset_to_offset_coords": { - "default_value": true - }, - "machine_gcode_flavor": { - "default_value": "RepRap (Marlin/Sprinter)" - }, - "machine_start_gcode": { - "default_value": ";Startcode BIBO printers\nM109 T1 S170 ;preheat the other extruder, so it will not knock or ruin the print\nG90 ; absolute mode\nG21 ; metric values\nM82 ; Extruder in absolute mode\nM107\nG28\nG1 Z2 F400\nT0\nG90\nG92 E0\nG28\nG1 Y0 F1200 E0\nG92 E0\nG1 X-15.0 Y-92.9 Z0.3 F2400.0\t\t; move to start-line position\nG1 X15.0 Y-92.9 Z0.3 F1000.0 E2\t\t; draw 1st line\nG1 X15.0 Y-92.6 Z0.3 F3000.0\t\t; move to side a little\nG1 X-15.0 Y-92.6 Z0.3 F1000.0 E4\t\t; draw 2nd line\nG1 X-15.0 Y-92.3 Z0.3 F3000.0\t\t; move to side a little\nG1 X15.0 Y-92.3 Z0.3 F1000.0 E6\t\t; draw 3rd line\nG1 X15.0 Y-92 Z0.3 F3000.0\t\t; move to side a little\nG1 X-15.0 Y-92 Z0.3 F1000.0 E8\t\t; draw 4th line\nG1 X-16.0 Y-91.7 Z0.3 F3000.0\t\t; move to side a little\nG1 X16.0 Y-91.7 Z0.3 F1000.0 E10\t\t; draw 5th line\nG1 X16.0 Y-91.4 Z0.3 F3000.0\t\t; move to side a little\nG1 X-16.0 Y-91.4 Z0.3 F1000.0 E12\t\t; draw 5th line\nG1 E11.5 F2400\t\t\t\t; retract filament 0.5mm\nG92 E0\nM117 BIBO Printing..." - }, - "machine_end_gcode": { - "default_value": ";BIBO End GCode\nM107\nG91 ; Relative positioning\nG1 Z1 F100\nM104 T0 S0\nM104 T1 S0\nG1 X-20 Y-20 F3000\nG28 X0 Y0\nG90 ; Absolute positioning\nG92 E0 ; Reset extruder position\nM140 S0 ; Disable heated bed\nM84 ; Turn steppers off\nM117 BIBO Print complete\n " - }, - "machine_extruder_count": { - "default_value": 2 - }, - "prime_tower_position_x": { - "default_value": 50 - }, - "prime_tower_position_y": { - "default_value": 50 - } - } -} - diff --git a/resources/definitions/bibo2_single_extruder_1.def.json b/resources/definitions/bibo2_single_extruder_1.def.json deleted file mode 100644 index 246add09ab..0000000000 --- a/resources/definitions/bibo2_single_extruder_1.def.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "id": "BIBO2 single E2", - "version": 2, - "name": "BIBO2 single E2", - "inherits": "fdmprinter", - "metadata": { - "visible": true, - "author": "na", - "manufacturer": "BIBO", - "category": "Other", - "file_formats": "text/x-gcode", - "has_materials": true, - "machine_extruder_trains": { - "0": "bibo2_single_extruder_1_0", - "1": "bibo2_single_extruder_1_1" - }, - "first_start_actions": [ - "MachineSettingsAction" - ] - }, - "overrides": { - "machine_name": { - "default_value": "BIBO2 single Extruder 2 (left)" - }, - "machine_width": { - "default_value": 214 - }, - "machine_height": { - "default_value": 160 - }, - "machine_depth": { - "default_value": 186 - }, - "machine_center_is_zero": { - "default_value": true - }, - "machine_heated_bed": { - "default_value": true - }, - "machine_nozzle_size": { - "default_value": 0.4 - }, - "machine_nozzle_heat_up_speed": { - "default_value": 2 - }, - "machine_nozzle_cool_down_speed": { - "default_value": 2 - }, - "machine_head_with_fans_polygon": { - "default_value": [ - [ - -68.18, - 64.63 - ], - [ - -68.18, - -47.38 - ], - [ - 35.18, - 64.63 - ], - [ - 35.18, - -47.38 - ] - ] - }, - "material_diameter": { - "default_value": 1.75 - }, - "gantry_height": { - "default_value": 12 - }, - "machine_use_extruder_offset_to_offset_coords": { - "default_value": true - }, - "machine_gcode_flavor": { - "default_value": "RepRap (Marlin/Sprinter)" - }, - "machine_start_gcode": { - "default_value": ";Startcode BIBO printers\nM109 T0 S170 ;preheat the other extruder, so it will not knock or ruin the print\nG90 ; absolute mode\nG21 ; metric values\nM82 ; Extruder in absolute mode\nM107\nG28\nG1 Z2 F400\nT0\nG90\nG92 E0\nG28\nG1 Y0 F1200 E0\nG92 E0\nT1\nG92 E0\nG1 X-15.0 Y-92.9 Z0.3 F2400.0\t\t; move to start-line position\nG1 X15.0 Y-92.9 Z0.3 F1000.0 E2\t\t; draw 1st line\nG1 X15.0 Y-92.6 Z0.3 F3000.0\t\t; move to side a little\nG1 X-15.0 Y-92.6 Z0.3 F1000.0 E4\t\t; draw 2nd line\nG1 X-15.0 Y-92.3 Z0.3 F3000.0\t\t; move to side a little\nG1 X15.0 Y-92.3 Z0.3 F1000.0 E6\t\t; draw 3rd line\nG1 X15.0 Y-92 Z0.3 F3000.0\t\t; move to side a little\nG1 X-15.0 Y-92 Z0.3 F1000.0 E8\t\t; draw 4th line\nG1 X-16.0 Y-91.7 Z0.3 F3000.0\t\t; move to side a little\nG1 X16.0 Y-91.7 Z0.3 F1000.0 E10\t\t; draw 5th line\nG1 X16.0 Y-91.4 Z0.3 F3000.0\t\t; move to side a little\nG1 X-16.0 Y-91.4 Z0.3 F1000.0 E12\t\t; draw 5th line\nG1 E11.5 F2400\t\t\t\t; retract filament 0.5mm\nG92 E0\nM117 BIBO Printing..." - }, - "machine_end_gcode": { - "default_value": ";BIBO End GCode\nM107\nG91 ; Relative positioning\nG1 Z1 F100\nM104 T0 S0\nM104 T1 S0\nG1 X-20 Y-20 F3000\nG28 X0 Y0\nG90 ; Absolute positioning\nG92 E0 ; Reset extruder position\nM140 S0 ; Disable heated bed\nM84 ; Turn steppers off\nM117 BIBO Print complete\n " - }, - "machine_extruder_count": { - "default_value": 2 - }, - "prime_tower_position_x": { - "default_value": 50 - }, - "prime_tower_position_y": { - "default_value": 50 - } - } -} - diff --git a/resources/extruders/bibo2_single_extruder_0_0.def.json b/resources/extruders/bibo2_single_extruder_0_0.def.json deleted file mode 100644 index 7d0b246131..0000000000 --- a/resources/extruders/bibo2_single_extruder_0_0.def.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "id": "BIBO2 E1a", - "version": 2, - "name": "BIBO2 E1", - "inherits": "fdmextruder", - "metadata": { - "machine": "BIBO2 single E1", - "position": "0" - }, - "overrides": { - "extruder_nr": { - "default_value": 0, - "maximum_value": "1" - }, - "machine_nozzle_offset_x": { - "default_value": 0.0 - }, - "machine_nozzle_offset_y": { - "default_value": 0.0 - }, - "machine_extruder_start_pos_abs": { - "default_value": true - }, - "machine_extruder_start_pos_x": { - "value": "prime_tower_position_x" - }, - "machine_extruder_start_pos_y": { - "value": "prime_tower_position_y" - }, - "machine_extruder_end_pos_abs": { - "default_value": true - }, - "machine_extruder_end_pos_x": { - "value": "prime_tower_position_x" - }, - "machine_extruder_end_pos_y": { - "value": "prime_tower_position_y" - } - } -} diff --git a/resources/extruders/bibo2_single_extruder_0_1.def.json b/resources/extruders/bibo2_single_extruder_0_1.def.json deleted file mode 100644 index 76187696fc..0000000000 --- a/resources/extruders/bibo2_single_extruder_0_1.def.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "id": "BIBO2 E1b", - "version": 2, - "name": "E2 not used", - "inherits": "fdmextruder", - "metadata": { - "machine": "BIBO2 single E1", - "position": "1" - }, - "overrides": { - "extruder_nr": { - "default_value": 1, - "maximum_value": "1" - }, - "machine_nozzle_offset_x": { - "default_value": 0.0 - }, - "machine_nozzle_offset_y": { - "default_value": 0.0 - }, - "machine_extruder_start_pos_abs": { - "default_value": true - }, - "machine_extruder_start_pos_x": { - "value": "prime_tower_position_x" - }, - "machine_extruder_start_pos_y": { - "value": "prime_tower_position_y" - }, - "machine_extruder_end_pos_abs": { - "default_value": true - }, - "machine_extruder_end_pos_x": { - "value": "prime_tower_position_x" - }, - "machine_extruder_end_pos_y": { - "value": "prime_tower_position_y" - } - } -} diff --git a/resources/extruders/bibo2_single_extruder_1_0.def.json b/resources/extruders/bibo2_single_extruder_1_0.def.json deleted file mode 100644 index 3cf667de82..0000000000 --- a/resources/extruders/bibo2_single_extruder_1_0.def.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "id": "BIBO2 E2a", - "version": 2, - "name": "E1 not used", - "inherits": "fdmextruder", - "metadata": { - "machine": "BIBO2 single E2", - "position": "0" - }, - "overrides": { - "extruder_nr": { - "default_value": 0, - "maximum_value": "1" - }, - "machine_nozzle_offset_x": { - "default_value": 0 - }, - "machine_nozzle_offset_y": { - "default_value": 0 - }, - "machine_extruder_start_pos_abs": { - "default_value": true - }, - "machine_extruder_start_pos_x": { - "value": "prime_tower_position_x" - }, - "machine_extruder_start_pos_y": { - "value": "prime_tower_position_y" - }, - "machine_extruder_end_pos_abs": { - "default_value": true - }, - "machine_extruder_end_pos_x": { - "value": "prime_tower_position_x" - }, - "machine_extruder_end_pos_y": { - "value": "prime_tower_position_y" - } - } -} diff --git a/resources/extruders/bibo2_single_extruder_1_1.def.json b/resources/extruders/bibo2_single_extruder_1_1.def.json deleted file mode 100644 index e8f3ec7054..0000000000 --- a/resources/extruders/bibo2_single_extruder_1_1.def.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "id": "BIBO2 E2b", - "version": 2, - "name": "BIBO2 E2", - "inherits": "fdmextruder", - "metadata": { - "machine": "BIBO2 single E2", - "position": "1" - }, - "overrides": { - "extruder_nr": { - "default_value": 1, - "maximum_value": "1" - }, - "machine_nozzle_offset_x": { - "default_value": 0 - }, - "machine_nozzle_offset_y": { - "default_value": 0 - }, - "machine_extruder_start_pos_abs": { - "default_value": true - }, - "machine_extruder_start_pos_x": { - "value": "prime_tower_position_x" - }, - "machine_extruder_start_pos_y": { - "value": "prime_tower_position_y" - }, - "machine_extruder_end_pos_abs": { - "default_value": true - }, - "machine_extruder_end_pos_x": { - "value": "prime_tower_position_x" - }, - "machine_extruder_end_pos_y": { - "value": "prime_tower_position_y" - } - } -} From c6a9aca34602c0e5a32c7f308055fcd9815a2bbb Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 27 Nov 2018 13:05:32 +0100 Subject: [PATCH 0481/1292] Switch checked and hovered themes I misunderstood the theme as it was in the screenshots. Contributes to issue CURA-5876. --- resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index f04e856705..2988ab9eec 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -22,9 +22,9 @@ Button contentItem: Rectangle { height: childrenRect.height - color: parent.checked ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") - border.color: parent.hovered ? UM.Theme.getColor("primary") : UM.Theme.getColor("lining") - border.width: parent.hovered ? UM.Theme.getSize("thick_lining").width : UM.Theme.getSize("default_lining").width + color: parent.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") + border.color: parent.checked ? UM.Theme.getColor("primary") : UM.Theme.getColor("lining") + border.width: parent.checked ? UM.Theme.getSize("thick_lining").width : UM.Theme.getSize("default_lining").width radius: UM.Theme.getSize("default_radius").width Column From 89126c7323a6764cbe3c961953e3361f4581b641 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 27 Nov 2018 13:08:41 +0100 Subject: [PATCH 0482/1292] Use background instead of contentItem This way the padding and such doesn't matter any more. And the original background disappears, which was unthemed and still behind the original contentItem. Contributes to issue CURA-5876. --- resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 2988ab9eec..297c95d1d1 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -15,11 +15,8 @@ Button signal activateConfiguration() height: childrenRect.height - padding: 0 //Stupid QML button has spacing by default. - rightPadding: 0 - leftPadding: 0 - contentItem: Rectangle + background: Rectangle { height: childrenRect.height color: parent.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") From a6a364c337efb4f732247f30e60d14884aabdadc Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 27 Nov 2018 13:12:47 +0100 Subject: [PATCH 0483/1292] Move material diameter and machine nozzle size to the extruder definition. Contributes to CURA-5902. --- resources/definitions/bibo2_dual.def.json | 6 ------ resources/extruders/bibo2_dual_extruder_0.def.json | 6 ++++++ resources/extruders/bibo2_dual_extruder_1.def.json | 10 ++++++++-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/resources/definitions/bibo2_dual.def.json b/resources/definitions/bibo2_dual.def.json index e57fb64ec0..2036290ebd 100644 --- a/resources/definitions/bibo2_dual.def.json +++ b/resources/definitions/bibo2_dual.def.json @@ -37,9 +37,6 @@ "machine_heated_bed": { "default_value": true }, - "machine_nozzle_size": { - "default_value": 0.4 - }, "machine_nozzle_heat_up_speed": { "default_value": 2 }, @@ -66,9 +63,6 @@ ] ] }, - "material_diameter": { - "default_value": 1.75 - }, "gantry_height": { "default_value": 12 }, diff --git a/resources/extruders/bibo2_dual_extruder_0.def.json b/resources/extruders/bibo2_dual_extruder_0.def.json index 7cdc03d504..f83801fa0c 100644 --- a/resources/extruders/bibo2_dual_extruder_0.def.json +++ b/resources/extruders/bibo2_dual_extruder_0.def.json @@ -12,6 +12,12 @@ "default_value": 0, "maximum_value": "1" }, + "material_diameter": { + "default_value": 1.75 + }, + "machine_nozzle_size": { + "default_value": 0.4 + }, "machine_nozzle_offset_x": { "default_value": 0.0 }, diff --git a/resources/extruders/bibo2_dual_extruder_1.def.json b/resources/extruders/bibo2_dual_extruder_1.def.json index daa1504220..5f479ba54b 100644 --- a/resources/extruders/bibo2_dual_extruder_1.def.json +++ b/resources/extruders/bibo2_dual_extruder_1.def.json @@ -12,11 +12,17 @@ "default_value": 1, "maximum_value": "1" }, + "material_diameter": { + "default_value": 1.75 + }, + "machine_nozzle_size": { + "default_value": 0.4 + }, "machine_nozzle_offset_x": { - "default_value": 0 + "default_value": 0.0 }, "machine_nozzle_offset_y": { - "default_value": 0 + "default_value": 0.0 }, "machine_extruder_start_pos_abs": { "default_value": true From b15c272d235c36edc5056aace5293f287d430144 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 27 Nov 2018 13:24:13 +0100 Subject: [PATCH 0484/1292] Fix applying configuration when clicking Also no longer use that signal for it. It was completely unnecessary. Contributes to issue CURA-5876. --- resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml | 6 +++++- .../qml/Menus/ConfigurationMenu/ConfigurationListView.qml | 5 ----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 297c95d1d1..69c0b11882 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -12,7 +12,6 @@ Button id: configurationItem property var configuration: null - signal activateConfiguration() height: childrenRect.height @@ -111,4 +110,9 @@ Button configurationItem.checked = Cura.MachineManager.matchesConfiguration(configuration) } } + + onClicked: + { + Cura.MachineManager.applyRemoteConfiguration(configuration) + } } \ No newline at end of file diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index 2b7444be01..86deae9c4e 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -70,11 +70,6 @@ Column { width: parent.width - UM.Theme.getSize("default_margin").width configuration: modelData - onActivateConfiguration: - { - switchPopupState() - Cura.MachineManager.applyRemoteConfiguration(configuration) - } } } } From fcde6e3a34d7b8f51da08473fedf7aac98b6565f Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 27 Nov 2018 13:28:28 +0100 Subject: [PATCH 0485/1292] Fix the open file button Now it has the correct size and it doesn't look blurry. Contributes to CURA-5942. --- plugins/PrepareStage/PrepareMenu.qml | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index 4212911011..10b4262f01 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -95,16 +95,21 @@ Item onClicked: Cura.Actions.open.trigger() hoverEnabled: true - contentItem: UM.RecolorImage + contentItem: Item { - id: buttonIcon - source: UM.Theme.getIcon("load") - width: UM.Theme.getSize("button_icon").width - height: UM.Theme.getSize("button_icon").height - color: UM.Theme.getColor("toolbar_button_text") + anchors.fill: parent + UM.RecolorImage + { + id: buttonIcon + anchors.centerIn: parent + source: UM.Theme.getIcon("load") + width: UM.Theme.getSize("button_icon").width + height: UM.Theme.getSize("button_icon").height + color: UM.Theme.getColor("toolbar_button_text") - sourceSize.width: width - sourceSize.height: height + sourceSize.width: width + sourceSize.height: height + } } background: Rectangle From cf8d88054d8ded00237ee95587b5e0366060794e Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 27 Nov 2018 13:29:57 +0100 Subject: [PATCH 0486/1292] Use proper colour for material in configuration item No idea this would be so easy. Contributes to issue CURA-5876. --- .../qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml index e8cadda05e..ae21a19f5e 100644 --- a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml @@ -37,7 +37,7 @@ Column { width: UM.Theme.getSize("section_icon").width height: UM.Theme.getSize("section_icon").height - materialColor: mainColor + materialColor: printCoreConfiguration.material.color anchors.left: extruderLabel.right anchors.leftMargin: UM.Theme.getSize("narrow_margin").width } From e863c34f68b3fbe69218d76b3e6b549362468bf1 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 27 Nov 2018 13:33:35 +0100 Subject: [PATCH 0487/1292] Align the text to the center of the button Contributes to CURA-5942. --- resources/qml/MainWindow/MainWindowHeader.qml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/resources/qml/MainWindow/MainWindowHeader.qml b/resources/qml/MainWindow/MainWindowHeader.qml index 2942a9feb3..34936e9b5a 100644 --- a/resources/qml/MainWindow/MainWindowHeader.qml +++ b/resources/qml/MainWindow/MainWindowHeader.qml @@ -122,6 +122,8 @@ Rectangle text: marketplaceButton.text color: marketplaceButton.hovered ? UM.Theme.getColor("main_window_header_background") : UM.Theme.getColor("primary_text") width: contentWidth + verticalAlignment: Text.AlignVCenter + renderType: Text.NativeRendering } anchors From 6956a732a0453f6f51dea1f381451346fe241009 Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Tue, 27 Nov 2018 13:49:04 +0100 Subject: [PATCH 0488/1292] Use tapbar component from UM, change the print_setup_widget width --- resources/qml/PrintSetupSelector.qml | 17 +++++------------ resources/themes/cura-light/theme.json | 2 +- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/resources/qml/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector.qml index 5f593f9ba2..279254ec64 100644 --- a/resources/qml/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector.qml @@ -5,7 +5,7 @@ import QtQuick 2.7 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.3 -import UM 1.2 as UM +import UM 1.3 as UM import Cura 1.0 as Cura import "Menus" import "Menus/ConfigurationMenu" @@ -217,25 +217,18 @@ Cura.ExpandableComponent rightMargin: 5 } - - TabBar + UM.TabRow { id: tabBar + anchors.top: popupItemHeader.bottom + anchors.topMargin: UM.Theme.getSize("default_margin").height onCurrentIndexChanged: Cura.ExtruderManager.setActiveExtruderIndex(currentIndex) - width: parent.width - height: UM.Theme.getSize("print_setup_tap_bar").width z: 1 Repeater { - id: extruder_model_repeater model: extrudersModel - - delegate: TabButton + delegate: UM.TabRowButton { - z: 2 - width: ListView.view != null ? Math.round(ListView.view.width / extrudersModel.rowCount()): 0 - implicitHeight: parent.height - contentItem: Rectangle { z: 2 diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 029da9c14b..e6889b50c0 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -381,7 +381,7 @@ "account_button": [12, 3], - "print_setup_widget": [30.0, 42.0], + "print_setup_widget": [38.0, 42.0], "print_setup_mode_toggle": [0.0, 2.0], "print_setup_item": [0.0, 2.0], "print_setup_extruder_box": [0.0, 6.0], From bb9598afd1c2162d461ea8c456da6f0b54e228e9 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 27 Nov 2018 13:55:54 +0100 Subject: [PATCH 0489/1292] Redesign layout of configuration item contents This is the new design. Contributes to issue CURA-5876. --- .../ConfigurationMenu/ConfigurationItem.qml | 1 - .../PrintCoreConfiguration.qml | 73 ++++++++----------- resources/themes/cura-light/theme.json | 2 +- 3 files changed, 33 insertions(+), 43 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 69c0b11882..ffe3b32926 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -48,7 +48,6 @@ Button { width: Math.round(parent.width / 2) printCoreConfiguration: modelData - mainColor: UM.Theme.getColor("text") } } } diff --git a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml index ae21a19f5e..dc908fdb0b 100644 --- a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml @@ -7,61 +7,52 @@ import QtQuick.Controls 2.0 import UM 1.2 as UM import Cura 1.0 as Cura -Column +Row { id: extruderInfo property var printCoreConfiguration - property var mainColor: "black" - spacing: Math.round(UM.Theme.getSize("default_margin").height / 2) height: childrenRect.height + spacing: UM.Theme.getSize("default_margin").width + //Extruder icon. Item { - id: extruder - width: parent.width - height: childrenRect.height - - Label - { - id: extruderLabel - text: catalog.i18nc("@label:extruder label", "Extruder") - renderType: Text.NativeRendering - elide: Text.ElideRight - anchors.left: parent.left - font: UM.Theme.getFont("default") - color: mainColor - } - + width: childrenRect.width + height: information.height Cura.ExtruderIcon { - width: UM.Theme.getSize("section_icon").width - height: UM.Theme.getSize("section_icon").height materialColor: printCoreConfiguration.material.color - anchors.left: extruderLabel.right - anchors.leftMargin: UM.Theme.getSize("narrow_margin").width + anchors.verticalCenter: parent.verticalCenter } } - Label + Column { - id: materialLabel - text: printCoreConfiguration.material.name - renderType: Text.NativeRendering - elide: Text.ElideRight - width: parent.width - font: UM.Theme.getFont("default_bold") - color: mainColor - } - - Label - { - id: printCoreTypeLabel - text: printCoreConfiguration.hotendID - renderType: Text.NativeRendering - elide: Text.ElideRight - width: parent.width - font: UM.Theme.getFont("default") - color: mainColor + id: information + Label + { + text: printCoreConfiguration.material.brand + renderType: Text.NativeRendering + elide: Text.ElideRight + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + } + Label + { + text: printCoreConfiguration.material.name + renderType: Text.NativeRendering + elide: Text.ElideRight + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + } + Label + { + text: printCoreConfiguration.hotendID + renderType: Text.NativeRendering + elide: Text.ElideRight + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + } } } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index de9b48c7f0..824d4cf3ee 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -397,7 +397,7 @@ "thin_margin": [0.71, 0.71], "narrow_margin": [0.5, 0.5], - "extruder_icon": [1.8, 1.8], + "extruder_icon": [2.5, 2.5], "simple_mode_infill_caption": [0.0, 5.0], "simple_mode_infill_height": [0.0, 8.0], From 1555a1ab1787def2427449b1fbcde94d41893bbe Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 27 Nov 2018 14:03:05 +0100 Subject: [PATCH 0490/1292] Make manufacturer and extruder labels lighter The proper colour would've been 'detail' but that seems to not be used much at all, and it's too light. In other places, 'inactive' is used in this place more often. Contributes to issue CURA-5876. --- resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml | 2 +- .../qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index 4aa8d66caa..202bc22ce0 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -64,7 +64,7 @@ Cura.ExpandableComponent text: model.material_brand elide: Text.ElideRight font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") + color: UM.Theme.getColor("text_inactive") anchors { diff --git a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml index dc908fdb0b..5709cc948c 100644 --- a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml @@ -36,7 +36,7 @@ Row renderType: Text.NativeRendering elide: Text.ElideRight font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") + color: UM.Theme.getColor("text_inactive") } Label { @@ -52,7 +52,7 @@ Row renderType: Text.NativeRendering elide: Text.ElideRight font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") + color: UM.Theme.getColor("text_inactive") } } } From b0e9f23eee3c053c6179beeabbd1687a4dba0543 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 27 Nov 2018 14:06:07 +0100 Subject: [PATCH 0491/1292] Correct line colour when hovered A detail that I almost missed in the design examples. Contributes to issue CURA-5876. --- resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index ffe3b32926..2fbbef7130 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -19,7 +19,7 @@ Button { height: childrenRect.height color: parent.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") - border.color: parent.checked ? UM.Theme.getColor("primary") : UM.Theme.getColor("lining") + border.color: (parent.checked || parent.hovered) ? UM.Theme.getColor("primary") : UM.Theme.getColor("lining") border.width: parent.checked ? UM.Theme.getSize("thick_lining").width : UM.Theme.getSize("default_lining").width radius: UM.Theme.getSize("default_radius").width From 8784ecd49acad58d0cbbebb8b06bebfe520145e1 Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Tue, 27 Nov 2018 14:09:47 +0100 Subject: [PATCH 0492/1292] Change native rendering CURA-5941 --- resources/qml/PrintSetupSelector.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/qml/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector.qml index 279254ec64..371232372d 100644 --- a/resources/qml/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector.qml @@ -148,6 +148,7 @@ Cura.ExpandableComponent id: popupItemHeaderText text: catalog.i18nc("@label", "Print settings"); font: UM.Theme.getFont("default") + renderType: Text.NativeRendering verticalAlignment: Text.AlignVCenter color: UM.Theme.getColor("text") height: parent.height From 609f07399e7735801f728826990e53a390a5f206 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 27 Nov 2018 14:20:47 +0100 Subject: [PATCH 0493/1292] Show extruder as disabled if either material or core is missing It basically just means you can't print with it. Contributes to issue CURA-5876. --- resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml index 5709cc948c..cc6461ebc4 100644 --- a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml @@ -24,6 +24,7 @@ Row { materialColor: printCoreConfiguration.material.color anchors.verticalCenter: parent.verticalCenter + extruderEnabled: printCoreConfiguration.material.name !== "" && printCoreConfiguration.hotendID !== "" } } From 3ad1802ab68021d4672c874dfaa7481f79212bb3 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 27 Nov 2018 14:34:29 +0100 Subject: [PATCH 0494/1292] Prevent a KeyError from messing CURA-5978 --- cura/Settings/MachineManager.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index f7ad108ad4..03afc7edd0 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -915,9 +915,12 @@ class MachineManager(QObject): if settable_per_extruder: limit_to_extruder = int(self._global_container_stack.getProperty(setting_key, "limit_to_extruder")) - extruder_position = str(max(0, limit_to_extruder)) - extruder_stack = self._global_container_stack.extruders[extruder_position] - extruder_stack.userChanges.setProperty(setting_key, "value", global_user_container.getProperty(setting_key, "value")) + extruder_position = max(0, limit_to_extruder) + extruder_stack = self.getExtruder(extruder_position) + if extruder_stack: + extruder_stack.userChanges.setProperty(setting_key, "value", global_user_container.getProperty(setting_key, "value")) + else: + Logger.log("e", "Unable to find extruder on position %s", extruder_position) global_user_container.removeInstance(setting_key) # Signal that the global stack has changed @@ -926,10 +929,9 @@ class MachineManager(QObject): @pyqtSlot(int, result = QObject) def getExtruder(self, position: int) -> Optional[ExtruderStack]: - extruder = None if self._global_container_stack: - extruder = self._global_container_stack.extruders.get(str(position)) - return extruder + return self._global_container_stack.extruders.get(str(position)) + return None def updateDefaultExtruder(self) -> None: if self._global_container_stack is None: From 854755277c705d3eb7e01e21525b2fe5be570426 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 27 Nov 2018 14:37:01 +0100 Subject: [PATCH 0495/1292] Fix styling of comments Because sentences should start with capitals --- cura/Settings/MachineManager.py | 43 ++++++++++++++++----------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 03afc7edd0..f22029e083 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -64,7 +64,7 @@ class MachineManager(QObject): self.machine_extruder_material_update_dict = collections.defaultdict(list) #type: Dict[str, List[Callable[[], None]]] - self._instance_container_timer = QTimer() #type: QTimer + self._instance_container_timer = QTimer() # type: QTimer self._instance_container_timer.setInterval(250) self._instance_container_timer.setSingleShot(True) self._instance_container_timer.timeout.connect(self.__emitChangedSignals) @@ -74,7 +74,7 @@ class MachineManager(QObject): self._application.globalContainerStackChanged.connect(self._onGlobalContainerChanged) self._container_registry.containerLoadComplete.connect(self._onContainersChanged) - ## When the global container is changed, active material probably needs to be updated. + # When the global container is changed, active material probably needs to be updated. self.globalContainerChanged.connect(self.activeMaterialChanged) self.globalContainerChanged.connect(self.activeVariantChanged) self.globalContainerChanged.connect(self.activeQualityChanged) @@ -115,15 +115,15 @@ class MachineManager(QObject): self._material_incompatible_message = Message(catalog.i18nc("@info:status", "The selected material is incompatible with the selected machine or configuration."), - title = catalog.i18nc("@info:title", "Incompatible Material")) #type: Message + title = catalog.i18nc("@info:title", "Incompatible Material")) # type: Message - containers = CuraContainerRegistry.getInstance().findInstanceContainers(id = self.activeMaterialId) #type: List[InstanceContainer] + containers = CuraContainerRegistry.getInstance().findInstanceContainers(id = self.activeMaterialId) # type: List[InstanceContainer] if containers: containers[0].nameChanged.connect(self._onMaterialNameChanged) - self._material_manager = self._application.getMaterialManager() #type: MaterialManager - self._variant_manager = self._application.getVariantManager() #type: VariantManager - self._quality_manager = self._application.getQualityManager() #type: QualityManager + self._material_manager = self._application.getMaterialManager() # type: MaterialManager + self._variant_manager = self._application.getVariantManager() # type: VariantManager + self._quality_manager = self._application.getQualityManager() # type: QualityManager # When the materials lookup table gets updated, it can mean that a material has its name changed, which should # be reflected on the GUI. This signal emission makes sure that it happens. @@ -156,7 +156,7 @@ class MachineManager(QObject): blurSettings = pyqtSignal() # Emitted to force fields in the advanced sidebar to un-focus, so they update properly outputDevicesChanged = pyqtSignal() - currentConfigurationChanged = pyqtSignal() # Emitted every time the current configurations of the machine changes + currentConfigurationChanged = pyqtSignal() # Emitted every time the current configurations of the machine changes printerConnectedStatusChanged = pyqtSignal() # Emitted every time the active machine change or the outputdevices change rootMaterialChanged = pyqtSignal() @@ -201,7 +201,7 @@ class MachineManager(QObject): extruder_configuration.hotendID = extruder.variant.getName() if extruder.variant != empty_variant_container else None self._current_printer_configuration.extruderConfigurations.append(extruder_configuration) - # an empty build plate configuration from the network printer is presented as an empty string, so use "" for an + # An empty build plate configuration from the network printer is presented as an empty string, so use "" for an # empty build plate. self._current_printer_configuration.buildplateConfiguration = self._global_container_stack.getProperty("machine_buildplate_type", "value") if self._global_container_stack.variant != empty_variant_container else "" self.currentConfigurationChanged.emit() @@ -247,7 +247,7 @@ class MachineManager(QObject): self.updateNumberExtrudersEnabled() self.globalContainerChanged.emit() - # after switching the global stack we reconnect all the signals and set the variant and material references + # After switching the global stack we reconnect all the signals and set the variant and material references if self._global_container_stack: self._application.getPreferences().setValue("cura/active_machine", self._global_container_stack.getId()) @@ -261,7 +261,7 @@ class MachineManager(QObject): if global_variant.getMetaDataEntry("hardware_type") != "buildplate": self._global_container_stack.setVariant(empty_variant_container) - # set the global material to empty as we now use the extruder stack at all times - CURA-4482 + # Set the global material to empty as we now use the extruder stack at all times - CURA-4482 global_material = self._global_container_stack.material if global_material != empty_material_container: self._global_container_stack.setMaterial(empty_material_container) @@ -419,7 +419,7 @@ class MachineManager(QObject): # Not a very pretty solution, but the extruder manager doesn't really know how many extruders there are machine_extruder_count = self._global_container_stack.getProperty("machine_extruder_count", "value") extruder_stacks = ExtruderManager.getInstance().getActiveExtruderStacks() - count = 1 # we start with the global stack + count = 1 # We start with the global stack for stack in extruder_stacks: md = stack.getMetaData() if "position" in md and int(md["position"]) >= machine_extruder_count: @@ -646,7 +646,7 @@ class MachineManager(QObject): new_value = self._active_container_stack.getProperty(key, "value") extruder_stacks = [stack for stack in ExtruderManager.getInstance().getActiveExtruderStacks()] - # check in which stack the value has to be replaced + # Check in which stack the value has to be replaced for extruder_stack in extruder_stacks: if extruder_stack != self._active_container_stack and extruder_stack.getProperty(key, "value") != new_value: extruder_stack.userChanges.setProperty(key, "value", new_value) # TODO: nested property access, should be improved @@ -662,7 +662,7 @@ class MachineManager(QObject): for key in self._active_container_stack.userChanges.getAllKeys(): new_value = self._active_container_stack.getProperty(key, "value") - # check if the value has to be replaced + # Check if the value has to be replaced extruder_stack.userChanges.setProperty(key, "value", new_value) @pyqtProperty(str, notify = activeVariantChanged) @@ -731,7 +731,7 @@ class MachineManager(QObject): # If the machine that is being removed is the currently active machine, set another machine as the active machine. activate_new_machine = (self._global_container_stack and self._global_container_stack.getId() == machine_id) - # activate a new machine before removing a machine because this is safer + # Activate a new machine before removing a machine because this is safer if activate_new_machine: machine_stacks = CuraContainerRegistry.getInstance().findContainerStacksMetadata(type = "machine") other_machine_stacks = [s for s in machine_stacks if s["id"] != machine_id] @@ -997,12 +997,12 @@ class MachineManager(QObject): if not enabled and position == ExtruderManager.getInstance().activeExtruderIndex: ExtruderManager.getInstance().setActiveExtruderIndex(int(self._default_extruder_position)) - # ensure that the quality profile is compatible with current combination, or choose a compatible one if available + # Ensure that the quality profile is compatible with current combination, or choose a compatible one if available self._updateQualityWithMaterial() self.extruderChanged.emit() - # update material compatibility color + # Update material compatibility color self.activeQualityGroupChanged.emit() - # update items in SettingExtruder + # Update items in SettingExtruder ExtruderManager.getInstance().extrudersChanged.emit(self._global_container_stack.getId()) # Make sure the front end reflects changes self.forceUpdateAllSettings() @@ -1076,7 +1076,6 @@ class MachineManager(QObject): return result - # # Sets all quality and quality_changes containers to empty_quality and empty_quality_changes containers # for all stacks in the currently active machine. # @@ -1135,7 +1134,7 @@ class MachineManager(QObject): def _setQualityChangesGroup(self, quality_changes_group: "QualityChangesGroup") -> None: if self._global_container_stack is None: - return #Can't change that. + return # Can't change that. quality_type = quality_changes_group.quality_type # A custom quality can be created based on "not supported". # In that case, do not set quality containers to empty. @@ -1205,7 +1204,7 @@ class MachineManager(QObject): self.rootMaterialChanged.emit() def activeMaterialsCompatible(self) -> bool: - # check material - variant compatibility + # Check material - variant compatibility if self._global_container_stack is not None: if Util.parseBool(self._global_container_stack.getMetaDataEntry("has_materials", False)): for position, extruder in self._global_container_stack.extruders.items(): @@ -1415,7 +1414,7 @@ class MachineManager(QObject): material_diameter, root_material_id) self.setMaterial(position, material_node) - ## global_stack: if you want to provide your own global_stack instead of the current active one + ## Global_stack: if you want to provide your own global_stack instead of the current active one # if you update an active machine, special measures have to be taken. @pyqtSlot(str, "QVariant") def setMaterial(self, position: str, container_node, global_stack: Optional["GlobalStack"] = None) -> None: From 956741922d561e2e7405554cf68b6c634c00f616 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 27 Nov 2018 14:41:48 +0100 Subject: [PATCH 0496/1292] Make elements retain their position if hotend or material is missing Just a space makes it keep the correct height. Contributes to issue CURA-5876. --- .../qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml index cc6461ebc4..8d2f0c0f7c 100644 --- a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml @@ -33,7 +33,7 @@ Row id: information Label { - text: printCoreConfiguration.material.brand + text: printCoreConfiguration.material.brand ? printCoreConfiguration.material.brand : " " //Use space so that the height is still correct. renderType: Text.NativeRendering elide: Text.ElideRight font: UM.Theme.getFont("default") @@ -41,7 +41,7 @@ Row } Label { - text: printCoreConfiguration.material.name + text: printCoreConfiguration.material.name ? printCoreConfiguration.material.name : " " //Use space so that the height is still correct. renderType: Text.NativeRendering elide: Text.ElideRight font: UM.Theme.getFont("default") @@ -49,7 +49,7 @@ Row } Label { - text: printCoreConfiguration.hotendID + text: printCoreConfiguration.hotendID ? printCoreConfiguration.hotendID : " " //Use space so that the height is still correct. renderType: Text.NativeRendering elide: Text.ElideRight font: UM.Theme.getFont("default") From 0a71a9dd3ecd5c16fa82a498698f3e937619b842 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 27 Nov 2018 14:47:18 +0100 Subject: [PATCH 0497/1292] Increase margins around configuration item As per the design. Contributes to issue CURA-5876. --- resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 2fbbef7130..3ea220c91e 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -27,7 +27,7 @@ Button { id: contentColumn width: parent.width - padding: UM.Theme.getSize("default_margin").width + padding: UM.Theme.getSize("wide_margin").width spacing: Math.round(UM.Theme.getSize("default_margin").height / 2) Row From fb019ba987fc3542a178c6ff926d4fc11a115043 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Tue, 27 Nov 2018 14:48:47 +0100 Subject: [PATCH 0498/1292] In CloudOutputDeviceManager start a thread to periodically check for changes in the connected clusters --- .../src/Cloud/CloudOutputDevice.py | 1 + .../src/Cloud/CloudOutputDeviceManager.py | 51 ++++++++++++++----- 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index accc8429b1..79a3d46949 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -30,6 +30,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): I18N_CATALOG = i18nCatalog("cura") # The cloud URL to use for this remote cluster. + # TODO: Make sure that this url goes to the live api before release API_ROOT_PATH_FORMAT = "https://api-staging.ultimaker.com/connect/v1/clusters/{cluster_id}" # Signal triggered when the printers in the remote cluster were changed. diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index a252f9e4d3..546b9b270f 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -1,6 +1,8 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import json +from time import sleep +from threading import Thread from typing import Dict, Optional, List from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply @@ -24,6 +26,9 @@ class CloudOutputDeviceManager(NetworkClient): # The cloud URL to use for remote clusters. API_ROOT_PATH = "https://api.ultimaker.com/connect/v1" + + # The interval with wich the remote clusters are checked + CHECK_CLUSTER_INTERVAL = 5 # seconds def __init__(self): super().__init__() @@ -42,6 +47,11 @@ class CloudOutputDeviceManager(NetworkClient): # TODO: update remote clusters periodically self._account.loginStateChanged.connect(self._getRemoteClusters) + # Periodically check the cloud for an update on the clusters connected to the user's account + self._update_clusters_thread = Thread(target=self._updateClusters, daemon=True) + self._update_clusters_thread.start() + + ## Override _createEmptyRequest to add the needed authentication header for talking to the Ultimaker Cloud API. def _createEmptyRequest(self, path: str, content_type: Optional[str] = "application/json") -> QNetworkRequest: request = super()._createEmptyRequest(self.API_ROOT_PATH + path, content_type = content_type) @@ -50,6 +60,12 @@ class CloudOutputDeviceManager(NetworkClient): # TODO: don't create the client when not signed in? request.setRawHeader(b"Authorization", "Bearer {}".format(self._account.accessToken).encode()) return request + + ## Update the clusters + def _updateClusters(self) -> None: + while True: + self._getRemoteClusters() + sleep(self.CHECK_CLUSTER_INTERVAL) ## Gets all remote clusters from the API. def _getRemoteClusters(self) -> None: @@ -64,36 +80,47 @@ class CloudOutputDeviceManager(NetworkClient): return # Parse the response (returns the "data" field from the body). - clusters = self._parseStatusResponse(reply) - if not clusters: + found_clusters = self._parseStatusResponse(reply) + if not found_clusters: return - - # Add an output device for each remote cluster. - # The clusters are an array of objects in a field called "data". - for cluster in clusters: - self._addCloudOutputDevice(cluster) - + + known_cluster_ids = set(self._remote_clusters.keys()) + found_clusters_ids = set(found_clusters.keys()) + + # Add an output device for each new remote cluster. + for cluster_id in found_clusters_ids.difference(known_cluster_ids): + self._addCloudOutputDevice(found_clusters[cluster_id]) + + # Remove output devices that are gone + for cluster_id in known_cluster_ids.difference(found_clusters_ids): + self._removeCloudOutputDevice(found_clusters[cluster_id]) + # For testing we add a dummy device: # self._addCloudOutputDevice(CloudCluster(cluster_id = "LJ0tciiuZZjarrXAvFLEZ6ox4Cvx8FvtXUlQv4vIhV6w")) @staticmethod - def _parseStatusResponse(reply: QNetworkReply) -> List[CloudCluster]: + def _parseStatusResponse(reply: QNetworkReply) -> Dict[str, CloudCluster]: try: - return [CloudCluster(**c) for c in json.loads(reply.readAll().data().decode("utf-8"))] + return {c["guid"]: CloudCluster(**c) for c in json.loads(reply.readAll().data().decode("utf-8"))} except UnicodeDecodeError: Logger.log("w", "Unable to read server response") except json.decoder.JSONDecodeError: Logger.logException("w", "Unable to decode JSON from reply.") except ValueError: Logger.logException("w", "Response was missing values.") - return [] + return {} ## Adds a CloudOutputDevice for each entry in the remote cluster list from the API. def _addCloudOutputDevice(self, cluster: CloudCluster): device = CloudOutputDevice(cluster.cluster_id) self._output_device_manager.addOutputDevice(device) self._remote_clusters[cluster.cluster_id] = device - + + ## Remove a CloudOutputDevice + def _removeCloudOutputDevice(self, cluster: CloudCluster): + self._output_device_manager.removeOutputDevice(cluster.cluster_id) + del self._remote_clusters[cluster.cluster_id] + ## Callback for when the active machine was changed by the user. def _activeMachineChanged(self): active_machine = CuraApplication.getInstance().getGlobalContainerStack() From 077b34b4336fee026ee37f43a27e7bb13c9b9b4a Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 27 Nov 2018 14:49:01 +0100 Subject: [PATCH 0499/1292] Fix size of the extruder icon Now it should look the same in all places. --- resources/qml/ExtruderButton.qml | 14 +++++++++----- resources/qml/ExtruderIcon.qml | 2 -- resources/themes/cura-light/theme.json | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/resources/qml/ExtruderButton.qml b/resources/qml/ExtruderButton.qml index 8a1f0af44a..d7cbdc52bc 100644 --- a/resources/qml/ExtruderButton.qml +++ b/resources/qml/ExtruderButton.qml @@ -19,12 +19,16 @@ Button enabled: UM.Selection.hasSelection && extruder.stack.isEnabled background: Item {} - contentItem: ExtruderIcon + contentItem: Item { - width: UM.Theme.getSize("button_icon").width - materialColor: model.color - extruderEnabled: extruder.stack.isEnabled - property int index: extruder.index + // For some reason if the extruder icon is not enclosed to the item, the size changes to fill the size of the button + ExtruderIcon + { + anchors.centerIn: parent + materialColor: model.color + extruderEnabled: extruder.stack.isEnabled + property int index: extruder.index + } } onClicked: diff --git a/resources/qml/ExtruderIcon.qml b/resources/qml/ExtruderIcon.qml index 8f312adb85..c1a202050b 100644 --- a/resources/qml/ExtruderIcon.qml +++ b/resources/qml/ExtruderIcon.qml @@ -51,8 +51,6 @@ Item anchors.centerIn: parent text: index + 1 font: UM.Theme.getFont("extruder_icon") - width: contentWidth - height: contentHeight visible: extruderEnabled renderType: Text.NativeRendering horizontalAlignment: Text.AlignHCenter diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 157adcf6a5..d2358e36ff 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -402,7 +402,7 @@ "thin_margin": [0.71, 0.71], "narrow_margin": [0.5, 0.5], - "extruder_icon": [1.8, 1.8], + "extruder_icon": [2.33, 2.33], "section": [0.0, 2.2], "section_icon": [1.6, 1.6], From 172e003e1b65650d7f8150f5c6077f97f0c46685 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Tue, 27 Nov 2018 14:53:23 +0100 Subject: [PATCH 0500/1292] Removed the inital call to clusters --- .../src/Cloud/CloudOutputDeviceManager.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 546b9b270f..3ebaeea9a4 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -43,11 +43,7 @@ class CloudOutputDeviceManager(NetworkClient): # When switching machines we check if we have to activate a remote cluster. application.globalContainerStackChanged.connect(self._activeMachineChanged) - # Fetch all remote clusters for the authenticated user. - # TODO: update remote clusters periodically - self._account.loginStateChanged.connect(self._getRemoteClusters) - - # Periodically check the cloud for an update on the clusters connected to the user's account + # Periodically check all remote clusters for the authenticated user. self._update_clusters_thread = Thread(target=self._updateClusters, daemon=True) self._update_clusters_thread.start() From 82ea562dc389b6e3f8872b24c84e4a70f382ffe3 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 27 Nov 2018 14:54:49 +0100 Subject: [PATCH 0501/1292] Add missing hoverEnabled property --- resources/qml/Settings/SettingCategory.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/qml/Settings/SettingCategory.qml b/resources/qml/Settings/SettingCategory.qml index 7995619af0..00d23580b2 100644 --- a/resources/qml/Settings/SettingCategory.qml +++ b/resources/qml/Settings/SettingCategory.qml @@ -14,6 +14,7 @@ Button anchors.right: parent.right anchors.leftMargin: UM.Theme.getSize("thick_margin").width anchors.rightMargin: UM.Theme.getSize("thick_margin").width + hoverEnabled: true background: Rectangle { id: backgroundRectangle From c7fd147f59e1d6bf3fb71930ef6c3346c3373b4f Mon Sep 17 00:00:00 2001 From: Mark Date: Tue, 27 Nov 2018 14:55:06 +0100 Subject: [PATCH 0502/1292] Show website for support --- plugins/Toolbox/resources/qml/ToolboxDetailPage.qml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 437a2ef351..7b48aaebef 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -144,10 +144,6 @@ Item { return "" } - if (details.author_email) - { - return "" + details.author_name + "" - } else { return "" + details.author_name + "" From 92d07170964a8a4906ca2742eeb3675e4619487b Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 27 Nov 2018 15:00:50 +0100 Subject: [PATCH 0503/1292] Hide the toolbar and don't show time and material information when loading a gcode Contributes to CURA-5979. --- resources/qml/ActionPanel/OutputProcessWidget.qml | 8 +++++++- resources/qml/Cura.qml | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/resources/qml/ActionPanel/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml index ddbe709a84..45cb1fdb41 100644 --- a/resources/qml/ActionPanel/OutputProcessWidget.qml +++ b/resources/qml/ActionPanel/OutputProcessWidget.qml @@ -18,6 +18,7 @@ Column id: widget spacing: UM.Theme.getSize("thin_margin").height + property bool preSlicedData: PrintInformation.preSliced UM.I18nCatalog { @@ -48,7 +49,7 @@ Column id: estimatedTime width: parent.width - text: PrintInformation.currentPrintTime.getDisplayString(UM.DurationFormat.Long) + text: preSlicedData ? catalog.i18nc("@label", "No time estimation available") : PrintInformation.currentPrintTime.getDisplayString(UM.DurationFormat.Long) source: UM.Theme.getIcon("clock") font: UM.Theme.getFont("small") } @@ -63,6 +64,10 @@ Column text: { + if (preSlicedData) + { + return catalog.i18nc("@label", "No cost estimation available") + } var totalLengths = 0 var totalWeights = 0 if (printMaterialLengths) @@ -86,6 +91,7 @@ Column PrintInformationWidget { id: printInformationPanel + visible: !preSlicedData anchors { diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 63888a4ee4..36f5758fa3 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -212,7 +212,7 @@ UM.MainWindow verticalCenter: parent.verticalCenter left: parent.left } - visible: CuraApplication.platformActivity + visible: CuraApplication.platformActivity && !PrintInformation.preSliced } ObjectsList From 4fab546425450142f17a3aaf05511fe1de98b019 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 27 Nov 2018 15:00:57 +0100 Subject: [PATCH 0504/1292] Fix codestyle issues Boyscouting --- resources/qml/Settings/SettingCategory.qml | 199 +++++++++++---------- 1 file changed, 109 insertions(+), 90 deletions(-) diff --git a/resources/qml/Settings/SettingCategory.qml b/resources/qml/Settings/SettingCategory.qml index 00d23580b2..aafe36c546 100644 --- a/resources/qml/Settings/SettingCategory.qml +++ b/resources/qml/Settings/SettingCategory.qml @@ -15,23 +15,31 @@ Button anchors.leftMargin: UM.Theme.getSize("thick_margin").width anchors.rightMargin: UM.Theme.getSize("thick_margin").width hoverEnabled: true + background: Rectangle { id: backgroundRectangle implicitHeight: UM.Theme.getSize("section").height - color: { - if (base.color) { - return base.color; - } else if (!base.enabled) { - return UM.Theme.getColor("setting_category_disabled"); - } else if (base.hovered && base.checkable && base.checked) { - return UM.Theme.getColor("setting_category_active_hover"); - } else if (base.pressed || (base.checkable && base.checked)) { - return UM.Theme.getColor("setting_category_active"); - } else if (base.hovered) { - return UM.Theme.getColor("setting_category_hover"); - } else { - return UM.Theme.getColor("setting_category"); + color: + { + if (base.color) + { + return base.color + } else if (!base.enabled) + { + return UM.Theme.getColor("setting_category_disabled") + } else if (base.hovered && base.checkable && base.checked) + { + return UM.Theme.getColor("setting_category_active_hover") + } else if (base.pressed || (base.checkable && base.checked)) + { + return UM.Theme.getColor("setting_category_active") + } else if (base.hovered) + { + return UM.Theme.getColor("setting_category_hover") + } else + { + return UM.Theme.getColor("setting_category") } } Behavior on color { ColorAnimation { duration: 50; } } @@ -41,17 +49,23 @@ Button height: UM.Theme.getSize("default_lining").height width: parent.width anchors.bottom: parent.bottom - color: { - if (!base.enabled) { - return UM.Theme.getColor("setting_category_disabled_border"); - } else if ((base.hovered || base.activeFocus) && base.checkable && base.checked) { - return UM.Theme.getColor("setting_category_active_hover_border"); - } else if (base.pressed || (base.checkable && base.checked)) { - return UM.Theme.getColor("setting_category_active_border"); - } else if (base.hovered || base.activeFocus) { - return UM.Theme.getColor("setting_category_hover_border"); - } else { - return UM.Theme.getColor("setting_category_border"); + color: + { + if (!base.enabled) + { + return UM.Theme.getColor("setting_category_disabled_border") + } else if ((base.hovered || base.activeFocus) && base.checkable && base.checked) + { + return UM.Theme.getColor("setting_category_active_hover_border") + } else if (base.pressed || (base.checkable && base.checked)) + { + return UM.Theme.getColor("setting_category_active_border") + } else if (base.hovered || base.activeFocus) + { + return UM.Theme.getColor("setting_category_hover_border") + } else + { + return UM.Theme.getColor("setting_category_border") } } } @@ -66,18 +80,19 @@ Button property var focusItem: base - contentItem: Item { + contentItem: Item + { anchors.fill: parent - anchors.left: parent.left - Label { + Label + { id: settingNameLabel anchors { left: parent.left leftMargin: 2 * UM.Theme.getSize("default_margin").width + UM.Theme.getSize("section_icon").width - right: parent.right; - verticalCenter: parent.verticalCenter; + right: parent.right + verticalCenter: parent.verticalCenter } text: definition.label textFormat: Text.PlainText @@ -85,21 +100,27 @@ Button font: UM.Theme.getFont("setting_category") color: { - if (!base.enabled) { - return UM.Theme.getColor("setting_category_disabled_text"); - } else if ((base.hovered || base.activeFocus) && base.checkable && base.checked) { - return UM.Theme.getColor("setting_category_active_hover_text"); - } else if (base.pressed || (base.checkable && base.checked)) { - return UM.Theme.getColor("setting_category_active_text"); - } else if (base.hovered || base.activeFocus) { - return UM.Theme.getColor("setting_category_hover_text"); - } else { - return UM.Theme.getColor("setting_category_text"); + if (!base.enabled) + { + return UM.Theme.getColor("setting_category_disabled_text") + } else if ((base.hovered || base.activeFocus) && base.checkable && base.checked) + { + return UM.Theme.getColor("setting_category_active_hover_text") + } else if (base.pressed || (base.checkable && base.checked)) + { + return UM.Theme.getColor("setting_category_active_text") + } else if (base.hovered || base.activeFocus) + { + return UM.Theme.getColor("setting_category_hover_text") + } else + { + return UM.Theme.getColor("setting_category_text") } } fontSizeMode: Text.HorizontalFit minimumPointSize: 8 } + UM.RecolorImage { id: category_arrow @@ -112,16 +133,21 @@ Button sourceSize.height: width color: { - if (!base.enabled) { - return UM.Theme.getColor("setting_category_disabled_text"); - } else if ((base.hovered || base.activeFocus) && base.checkable && base.checked) { - return UM.Theme.getColor("setting_category_active_hover_text"); - } else if (base.pressed || (base.checkable && base.checked)) { - return UM.Theme.getColor("setting_category_active_text"); - } else if (base.hovered || base.activeFocus) { - return UM.Theme.getColor("setting_category_hover_text"); - } else { - return UM.Theme.getColor("setting_category_text"); + if (!base.enabled) + { + return UM.Theme.getColor("setting_category_disabled_text") + } else if ((base.hovered || base.activeFocus) && base.checkable && base.checked) + { + return UM.Theme.getColor("setting_category_active_hover_text") + } else if (base.pressed || (base.checkable && base.checked)) + { + return UM.Theme.getColor("setting_category_active_text") + } else if (base.hovered || base.activeFocus) + { + return UM.Theme.getColor("setting_category_hover_text") + } else + { + return UM.Theme.getColor("setting_category_text") } } source: base.checked ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") @@ -136,21 +162,26 @@ Button anchors.leftMargin: UM.Theme.getSize("default_margin").width color: { - if (!base.enabled) { - return UM.Theme.getColor("setting_category_disabled_text"); - } else if((base.hovered || base.activeFocus) && base.checkable && base.checked) { - return UM.Theme.getColor("setting_category_active_hover_text"); - } else if(base.pressed || (base.checkable && base.checked)) { - return UM.Theme.getColor("setting_category_active_text"); - } else if(base.hovered || base.activeFocus) { - return UM.Theme.getColor("setting_category_hover_text"); - } else { - return UM.Theme.getColor("setting_category_text"); + if (!base.enabled) + { + return UM.Theme.getColor("setting_category_disabled_text") + } else if((base.hovered || base.activeFocus) && base.checkable && base.checked) + { + return UM.Theme.getColor("setting_category_active_hover_text") + } else if(base.pressed || (base.checkable && base.checked)) + { + return UM.Theme.getColor("setting_category_active_text") + } else if(base.hovered || base.activeFocus) + { + return UM.Theme.getColor("setting_category_hover_text") + } else + { + return UM.Theme.getColor("setting_category_text") } } source: UM.Theme.getIcon(definition.icon) - width: UM.Theme.getSize("section_icon").width; - height: UM.Theme.getSize("section_icon").height; + width: UM.Theme.getSize("section_icon").width + height: UM.Theme.getSize("section_icon").height sourceSize.width: width + 15 * screenScaleFactor sourceSize.height: width + 15 * screenScaleFactor } @@ -160,31 +191,26 @@ Button onClicked: { - if (definition.expanded) { - settingDefinitionsModel.collapse(definition.key); + if (definition.expanded) + { + settingDefinitionsModel.collapse(definition.key) } else { - settingDefinitionsModel.expandRecursive(definition.key); + settingDefinitionsModel.expandRecursive(definition.key) } //Set focus so that tab navigation continues from this point on. //NB: This must be set AFTER collapsing/expanding the category so that the scroll position is correct. - forceActiveFocus(); + forceActiveFocus() } onActiveFocusChanged: { if(activeFocus) { - base.focusReceived(); + base.focusReceived() } } - Keys.onTabPressed: - { - base.setActiveFocusToNextSetting(true) - } - Keys.onBacktabPressed: - { - base.setActiveFocusToNextSetting(false) - } + Keys.onTabPressed: base.setActiveFocusToNextSetting(true) + Keys.onBacktabPressed: base.setActiveFocusToNextSetting(false) UM.SimpleButton { @@ -194,9 +220,10 @@ Button height: Math.round(base.height * 0.6) width: Math.round(base.height * 0.6) - anchors { + anchors + { right: inheritButton.visible ? inheritButton.left : parent.right - // use 1.9 as the factor because there is a 0.1 difference between the settings and inheritance warning icons + // Use 1.9 as the factor because there is a 0.1 difference between the settings and inheritance warning icons rightMargin: inheritButton.visible ? Math.round(UM.Theme.getSize("default_margin").width / 2) : category_arrow.width + Math.round(UM.Theme.getSize("default_margin").width * 1.9) verticalCenter: parent.verticalCenter } @@ -205,9 +232,7 @@ Button hoverColor: UM.Theme.getColor("setting_control_button_hover") iconSource: UM.Theme.getIcon("settings") - onClicked: { - Cura.Actions.configureSettingVisibility.trigger(definition) - } + onClicked: Cura.Actions.configureSettingVisibility.trigger(definition) } UM.SimpleButton @@ -240,24 +265,18 @@ Button onClicked: { - settingDefinitionsModel.expandRecursive(definition.key); - base.checked = true; - base.showAllHiddenInheritedSettings(definition.key); + settingDefinitionsModel.expandRecursive(definition.key) + base.checked = true + base.showAllHiddenInheritedSettings(definition.key) } color: UM.Theme.getColor("setting_control_button") hoverColor: UM.Theme.getColor("setting_control_button_hover") iconSource: UM.Theme.getIcon("notice") - onEntered: - { - base.showTooltip(catalog.i18nc("@label","Some hidden settings use values different from their normal calculated value.\n\nClick to make these settings visible.")) - } + onEntered: base.showTooltip(catalog.i18nc("@label","Some hidden settings use values different from their normal calculated value.\n\nClick to make these settings visible.")) - onExited: - { - base.hideTooltip(); - } + onExited: base.hideTooltip() UM.I18nCatalog { id: catalog; name: "cura" } } From d47806de509d9aeeeebff5c5c410fb17ab35f26d Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Tue, 27 Nov 2018 15:05:35 +0100 Subject: [PATCH 0505/1292] Change style, added close popitem close behaviour CURA-5941 --- resources/qml/ExpandableComponent.qml | 3 +++ resources/qml/PrintSetupSelector.qml | 37 ++++++++++++-------------- resources/themes/cura-light/theme.json | 2 -- 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index 3b1105ddd6..707b947c7f 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -49,6 +49,9 @@ Item // On what side should the header corners be shown? 1 is down, 2 is left, 3 is up and 4 is right. property alias headerCornerSide: background.cornerSide + // Change the popupItem close behaviour + property alias popupClosePolicy : popup.closePolicy + function togglePopup() { if(popup.visible) diff --git a/resources/qml/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector.qml index 371232372d..b20d8e116b 100644 --- a/resources/qml/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector.qml @@ -29,7 +29,9 @@ Cura.ExpandableComponent iconSource: UM.Theme.getIcon("pencil") popupPadding : 0 - popupSpacingY: 10 + popupSpacingY: UM.Theme.getSize("narrow_margin").width + + popupClosePolicy: Popup.CloseOnEscape onCurrentModeIndexChanged: UM.Preferences.setValue("cura/active_mode", currentModeIndex) @@ -124,7 +126,7 @@ Cura.ExpandableComponent popupItem: Rectangle { - property var total_height: popupItemHeader.height + popupItemContent.height + footerControll.height + UM.Theme.getSize("print_setup_selector_margin").height * 2 + property var total_height: popupItemHeader.height + popupItemContent.height + footerControll.height + UM.Theme.getSize("narrow_margin").height * 2 id: popupItemWrapper height: total_height @@ -157,7 +159,7 @@ Cura.ExpandableComponent { topMargin: UM.Theme.getSize("sidebar_margin").height left: parent.left - leftMargin: UM.Theme.getSize("print_setup_selector_margin").height + leftMargin: UM.Theme.getSize("narrow_margin").height } } @@ -194,7 +196,7 @@ Cura.ExpandableComponent source: UM.Theme.getIcon("cross1") } - onClicked: base.model.hideMessage(model.id) + onClicked: base.togglePopup() // Will hide the popup item background: Rectangle { @@ -211,17 +213,16 @@ Cura.ExpandableComponent anchors { top: popupItemHeader.bottom - topMargin: UM.Theme.getSize("print_setup_selector_margin").height + topMargin: UM.Theme.getSize("narrow_margin").height right: parent.right left: parent.left - leftMargin: 5 - rightMargin: 5 + leftMargin: UM.Theme.getSize("thick_margin").width / 1.5 + rightMargin: UM.Theme.getSize("thick_margin").width / 1.5 } UM.TabRow { id: tabBar - anchors.top: popupItemHeader.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height onCurrentIndexChanged: Cura.ExtruderManager.setActiveExtruderIndex(currentIndex) z: 1 @@ -309,7 +310,7 @@ Cura.ExpandableComponent { id: footerControll anchors.top: popupItemContent.bottom - anchors.topMargin: UM.Theme.getSize("print_setup_selector_margin").height * 2 + anchors.topMargin: UM.Theme.getSize("narrow_margin").height * 2 width: parent.width height: settingControlButton.height + UM.Theme.getSize("default_lining").height * 4 Rectangle @@ -337,10 +338,10 @@ Cura.ExpandableComponent anchors { top: parent.top - topMargin: UM.Theme.getSize("print_setup_selector_margin").height * 2 - bottomMargin: UM.Theme.getSize("print_setup_selector_margin").height * 2 + topMargin: UM.Theme.getSize("narrow_margin").height * 2 + bottomMargin: UM.Theme.getSize("narrow_margin").height * 2 right: parent.right - rightMargin: UM.Theme.getSize("print_setup_selector_margin").height + rightMargin: UM.Theme.getSize("narrow_margin").height } onClicked: currentModeIndex = 1 @@ -361,19 +362,15 @@ Cura.ExpandableComponent anchors { top: parent.top - topMargin: UM.Theme.getSize("print_setup_selector_margin").height * 2 - bottomMargin: UM.Theme.getSize("print_setup_selector_margin").height * 2 + topMargin: UM.Theme.getSize("narrow_margin").height * 2 + bottomMargin: UM.Theme.getSize("narrow_margin").height * 2 left: parent.left - leftMargin: UM.Theme.getSize("print_setup_selector_margin").height + leftMargin: UM.Theme.getSize("narrow_margin").height } -// onClicked: currentModeIndex = 0 MouseArea { anchors.fill: parent - onClicked: { - currentModeIndex = 0 - - } + onClicked: currentModeIndex = 0 } } } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index e6889b50c0..1228e52b9d 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -535,9 +535,7 @@ "monitor_shadow_radius": [0.4, 0.4], "monitor_shadow_offset": [0.15, 0.15], - "print_setup_selector_margin": [0.5, 0.5], "print_setup_action_button": [13, 5], - "print_setup_tap_bar": [4, 4], "print_setup_content_top_margin": [3, 3] } } From 55dd9be0629b5ac091628ea9184416da7edae972 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 27 Nov 2018 15:11:13 +0100 Subject: [PATCH 0506/1292] Move PrinterTypeLabel to a more central location So that we can re-use it in other places too. Contributes to issue CURA-5876. --- resources/qml/{PrinterSelector => }/PrinterTypeLabel.qml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename resources/qml/{PrinterSelector => }/PrinterTypeLabel.qml (100%) diff --git a/resources/qml/PrinterSelector/PrinterTypeLabel.qml b/resources/qml/PrinterTypeLabel.qml similarity index 100% rename from resources/qml/PrinterSelector/PrinterTypeLabel.qml rename to resources/qml/PrinterTypeLabel.qml From c1bb1a9b982d7e44b9dd0bc68b9b7e993dfc3712 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 27 Nov 2018 15:12:44 +0100 Subject: [PATCH 0507/1292] Use normal font size for shorthand label This element had been designed when very_small was in the theme equal to default. I changed the entire application to use default instead of very_small and made very_small a smaller font, but didn't change that on the branch that this element was designed on. So now also change it here. Contributes to issue CURA-5876. --- resources/qml/PrinterTypeLabel.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/PrinterTypeLabel.qml b/resources/qml/PrinterTypeLabel.qml index cd9f3b9743..7feae32e16 100644 --- a/resources/qml/PrinterTypeLabel.qml +++ b/resources/qml/PrinterTypeLabel.qml @@ -28,7 +28,7 @@ Item anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter renderType: Text.NativeRendering - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") } } \ No newline at end of file From 3ad2e4f62a5a7612ecf2372e0230a2362d7f3f66 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 27 Nov 2018 15:24:58 +0100 Subject: [PATCH 0508/1292] Re-use PrinterTypeLabel component and use abbreviated name Contributes to issue CURA-5876. --- .../ConfigurationListView.qml | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index 393c2715b2..c40eb5b9e9 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -46,21 +46,11 @@ Column section.criteria: ViewSection.FullString section.delegate: Item { - height: printerTypeLabelBox.height + UM.Theme.getSize("default_margin").height - Rectangle + height: printerTypeLabel.height + UM.Theme.getSize("default_margin").height + Cura.PrinterTypeLabel { - id: printerTypeLabelBox - color: UM.Theme.getColor("text_detail") - width: childrenRect.width - height: childrenRect.height - - Label - { - text: section - font: UM.Theme.getFont("small") - color: UM.Theme.getColor("text") - padding: UM.Theme.getSize("narrow_margin").width - } + id: printerTypeLabel + text: Cura.MachineManager.getAbbreviatedMachineName(section) } } From fd4d1113b9c45d697d817c53d64aab9be6c19a3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Tue, 27 Nov 2018 15:42:26 +0100 Subject: [PATCH 0509/1292] use right plural in variable name --- .../src/Cloud/CloudOutputDeviceManager.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 3ebaeea9a4..97b0787c73 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -81,14 +81,14 @@ class CloudOutputDeviceManager(NetworkClient): return known_cluster_ids = set(self._remote_clusters.keys()) - found_clusters_ids = set(found_clusters.keys()) + found_cluster_ids = set(found_clusters.keys()) # Add an output device for each new remote cluster. - for cluster_id in found_clusters_ids.difference(known_cluster_ids): + for cluster_id in found_cluster_ids.difference(known_cluster_ids): self._addCloudOutputDevice(found_clusters[cluster_id]) # Remove output devices that are gone - for cluster_id in known_cluster_ids.difference(found_clusters_ids): + for cluster_id in known_cluster_ids.difference(found_cluster_ids): self._removeCloudOutputDevice(found_clusters[cluster_id]) # For testing we add a dummy device: @@ -122,6 +122,11 @@ class CloudOutputDeviceManager(NetworkClient): active_machine = CuraApplication.getInstance().getGlobalContainerStack() if not active_machine: return + + local_device_id = active_machine.getMetaDataEntry("um_network_key") + if local_device_id: + active_output_device = CuraApplication.getInstance().getOutputDeviceManager().getActiveDevice() + active_output_device.id stored_cluster_id = active_machine.getMetaDataEntry("um_cloud_cluster_id") if stored_cluster_id not in self._remote_clusters.keys(): From f8f498b90cd584a98943d1735dc519d94b228870 Mon Sep 17 00:00:00 2001 From: Mark Date: Tue, 27 Nov 2018 15:45:58 +0100 Subject: [PATCH 0510/1292] Increase the lines that are shown to 12 --- plugins/Toolbox/resources/qml/ToolboxDetailTile.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml index 9061a8e06b..7425ab2ba7 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml @@ -37,7 +37,7 @@ Item anchors.top: packageName.bottom width: parent.width text: model.description - maximumLineCount: 6 + maximumLineCount: 12 elide: Text.ElideRight wrapMode: Text.WordWrap color: UM.Theme.getColor("text") From b98df0f22f04b04cc2c9f324d47611bb07d22a4e Mon Sep 17 00:00:00 2001 From: Mark Date: Tue, 27 Nov 2018 15:46:23 +0100 Subject: [PATCH 0511/1292] Show one website link where to get the material --- .../qml/ToolboxCompatibilityChart.qml | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml b/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml index a48cb2ee3f..9121b97eca 100644 --- a/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml +++ b/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml @@ -36,12 +36,19 @@ Item var pg_name = "printingGuidelines" return (pg_name in packageData.links) ? packageData.links[pg_name] : undefined } + + property var materialWebsiteUrl: + { + var pg_name = "website" + return (pg_name in packageData.links) ? packageData.links[pg_name] : undefined + } anchors.topMargin: UM.Theme.getSize("default_margin").height height: visible ? childrenRect.height : 0 visible: packageData.type == "material" && (packageData.has_configs || technicalDataSheetUrl !== undefined || - safetyDataSheetUrl !== undefined || printingGuidelinesUrl !== undefined) + safetyDataSheetUrl !== undefined || printingGuidelinesUrl !== undefined || + materialWebsiteUrl !== undefined) Item { @@ -180,7 +187,8 @@ Item anchors.top: combatibilityItem.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height / 2 visible: base.technicalDataSheetUrl !== undefined || - base.safetyDataSheetUrl !== undefined || base.printingGuidelinesUrl !== undefined + base.safetyDataSheetUrl !== undefined || base.printingGuidelinesUrl !== undefined || + base.materialWebsiteUrl !== undefined height: visible ? contentHeight : 0 text: { @@ -208,6 +216,16 @@ Item var pg_name = catalog.i18nc("@action:label", "Printing Guidelines") result += "%2".arg(base.printingGuidelinesUrl).arg(pg_name) } + if (base.materialWebsiteUrl !== undefined) + { + if (result.length > 0) + { + result += "
    " + } + var pg_name = catalog.i18nc("@action:label", "Website") + result += "%2".arg(base.materialWebsiteUrl).arg(pg_name) + } + return result } font: UM.Theme.getFont("very_small") From c9c7ef7d67f693da7dea77cf0d699dd76a7e8d43 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 26 Nov 2018 13:32:01 +0100 Subject: [PATCH 0512/1292] Add "is_experimental" for experimental qualities CURA-5879 --- .../quality/ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg | 1 + .../quality/ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg | 1 + resources/quality/ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg | 1 + .../quality/ultimaker3/um3_aa0.8_CPEP_Superdraft_Print.inst.cfg | 1 + .../quality/ultimaker3/um3_aa0.8_CPEP_Verydraft_Print.inst.cfg | 1 + resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg | 1 + .../quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg | 1 + .../quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg | 1 + .../quality/ultimaker_s5/um_s5_aa0.25_PC_Normal_Quality.inst.cfg | 1 + .../quality/ultimaker_s5/um_s5_aa0.25_PP_Normal_Quality.inst.cfg | 1 + .../quality/ultimaker_s5/um_s5_aa0.8_CPEP_Fast_Print.inst.cfg | 1 + .../ultimaker_s5/um_s5_aa0.8_CPEP_Superdraft_Print.inst.cfg | 1 + .../ultimaker_s5/um_s5_aa0.8_CPEP_Verydraft_Print.inst.cfg | 1 + .../quality/ultimaker_s5/um_s5_aa0.8_PC_Fast_Print.inst.cfg | 1 + .../ultimaker_s5/um_s5_aa0.8_PC_Superdraft_Print.inst.cfg | 1 + .../quality/ultimaker_s5/um_s5_aa0.8_PC_Verydraft_Print.inst.cfg | 1 + .../ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Fast_Print.inst.cfg | 1 + .../ultimaker_s5/um_s5_aa0.8_aluminum_PC_Fast_Print.inst.cfg | 1 + 18 files changed, 18 insertions(+) diff --git a/resources/quality/ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg index e08fa27dc9..4d585b54c1 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg @@ -10,6 +10,7 @@ quality_type = normal weight = 0 material = generic_pc variant = AA 0.25 +is_experimental = True [values] acceleration_enabled = True diff --git a/resources/quality/ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg index 6e9bbdce27..bee345e302 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg @@ -10,6 +10,7 @@ quality_type = normal weight = 0 material = generic_pp variant = AA 0.25 +is_experimental = True [values] acceleration_enabled = True diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg index 73df9637f7..fc4acf3cb0 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg @@ -10,6 +10,7 @@ quality_type = draft weight = -2 material = generic_cpe_plus variant = AA 0.8 +is_experimental = True [values] brim_width = 14 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Superdraft_Print.inst.cfg index d59bfe7cea..36b3ef603f 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Superdraft_Print.inst.cfg @@ -10,6 +10,7 @@ quality_type = superdraft weight = -4 material = generic_cpe_plus variant = AA 0.8 +is_experimental = True [values] brim_width = 14 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Verydraft_Print.inst.cfg index 368317019f..14e08cb14d 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Verydraft_Print.inst.cfg @@ -10,6 +10,7 @@ quality_type = verydraft weight = -3 material = generic_cpe_plus variant = AA 0.8 +is_experimental = True [values] brim_width = 14 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg index 5b81532977..c2bb6d4988 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg @@ -10,6 +10,7 @@ quality_type = draft weight = 0 material = generic_pc variant = AA 0.8 +is_experimental = True [values] brim_width = 14 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg index 317b89ea85..e815b673d1 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg @@ -10,6 +10,7 @@ quality_type = superdraft weight = -2 material = generic_pc variant = AA 0.8 +is_experimental = True [values] brim_width = 14 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg index 2fd6bd7609..c50cee576d 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg @@ -10,6 +10,7 @@ quality_type = verydraft weight = -1 material = generic_pc variant = AA 0.8 +is_experimental = True [values] brim_width = 14 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.25_PC_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.25_PC_Normal_Quality.inst.cfg index 55d53c6c71..53c319d6e6 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.25_PC_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.25_PC_Normal_Quality.inst.cfg @@ -10,6 +10,7 @@ quality_type = normal weight = 0 material = generic_pc variant = AA 0.25 +is_experimental = True [values] acceleration_enabled = True diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.25_PP_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.25_PP_Normal_Quality.inst.cfg index c925845dc1..b4d34cc392 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.25_PP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.25_PP_Normal_Quality.inst.cfg @@ -10,6 +10,7 @@ quality_type = normal weight = 0 material = generic_pp variant = AA 0.25 +is_experimental = True [values] acceleration_enabled = True diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Fast_Print.inst.cfg index e78006689b..4bdd09e9b3 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Fast_Print.inst.cfg @@ -10,6 +10,7 @@ quality_type = draft weight = -2 material = generic_cpe_plus variant = AA 0.8 +is_experimental = True [values] brim_width = 14 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Superdraft_Print.inst.cfg index c6d0962157..f9b6b0c7a6 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Superdraft_Print.inst.cfg @@ -10,6 +10,7 @@ quality_type = superdraft weight = -4 material = generic_cpe_plus variant = AA 0.8 +is_experimental = True [values] brim_width = 14 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Verydraft_Print.inst.cfg index b80f773594..9c6c7de7f0 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Verydraft_Print.inst.cfg @@ -10,6 +10,7 @@ quality_type = verydraft weight = -3 material = generic_cpe_plus variant = AA 0.8 +is_experimental = True [values] brim_width = 14 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Fast_Print.inst.cfg index 0ed4e3d994..c24aa9a98d 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Fast_Print.inst.cfg @@ -10,6 +10,7 @@ quality_type = draft weight = 0 material = generic_pc variant = AA 0.8 +is_experimental = True [values] brim_width = 14 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Superdraft_Print.inst.cfg index 53bf1d3107..5fc306b1f1 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Superdraft_Print.inst.cfg @@ -10,6 +10,7 @@ quality_type = superdraft weight = -2 material = generic_pc variant = AA 0.8 +is_experimental = True [values] brim_width = 14 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Verydraft_Print.inst.cfg index d9c45c2634..996adf5be7 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Verydraft_Print.inst.cfg @@ -10,6 +10,7 @@ quality_type = verydraft weight = -1 material = generic_pc variant = AA 0.8 +is_experimental = True [values] brim_width = 14 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Fast_Print.inst.cfg index 3e74390840..4098c86ad9 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Fast_Print.inst.cfg @@ -11,6 +11,7 @@ weight = -2 material = generic_cpe_plus variant = AA 0.8 buildplate = Aluminum +is_experimental = True [values] brim_width = 14 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Fast_Print.inst.cfg index 747e2fe8a5..6fdd22c6b0 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Fast_Print.inst.cfg @@ -11,6 +11,7 @@ weight = 0 material = generic_pc variant = AA 0.8 buildplate = Aluminum +is_experimental = True [values] brim_width = 10 From 2c8ed992813f2ae56f988bc16b97e87e94bcc529 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 26 Nov 2018 14:48:05 +0100 Subject: [PATCH 0513/1292] Add is_experimental to Qt models and QMLs CURA-5879 --- .../Models/QualityProfilesDropDownMenuModel.py | 5 ++++- cura/Machines/QualityGroup.py | 18 ++++++++++++++++++ cura/Machines/QualityManager.py | 6 +++--- cura/Settings/MachineManager.py | 8 ++++++++ resources/qml/Menus/ProfileMenu.qml | 6 +++++- resources/qml/Settings/SettingView.qml | 3 +++ 6 files changed, 41 insertions(+), 5 deletions(-) diff --git a/cura/Machines/Models/QualityProfilesDropDownMenuModel.py b/cura/Machines/Models/QualityProfilesDropDownMenuModel.py index a01cc1194f..747882b041 100644 --- a/cura/Machines/Models/QualityProfilesDropDownMenuModel.py +++ b/cura/Machines/Models/QualityProfilesDropDownMenuModel.py @@ -21,6 +21,7 @@ class QualityProfilesDropDownMenuModel(ListModel): AvailableRole = Qt.UserRole + 5 QualityGroupRole = Qt.UserRole + 6 QualityChangesGroupRole = Qt.UserRole + 7 + IsExperimentalRole = Qt.UserRole + 8 def __init__(self, parent = None): super().__init__(parent) @@ -32,6 +33,7 @@ class QualityProfilesDropDownMenuModel(ListModel): self.addRoleName(self.AvailableRole, "available") #Whether the quality profile is available in our current nozzle + material. self.addRoleName(self.QualityGroupRole, "quality_group") self.addRoleName(self.QualityChangesGroupRole, "quality_changes_group") + self.addRoleName(self.IsExperimentalRole, "is_experimental") self._application = Application.getInstance() self._machine_manager = self._application.getMachineManager() @@ -74,7 +76,8 @@ class QualityProfilesDropDownMenuModel(ListModel): "layer_height": layer_height, "layer_height_unit": self._layer_height_unit, "available": quality_group.is_available, - "quality_group": quality_group} + "quality_group": quality_group, + "is_experimental": quality_group.is_experimental} item_list.append(item) diff --git a/cura/Machines/QualityGroup.py b/cura/Machines/QualityGroup.py index 535ba453f8..f5bcbb0de8 100644 --- a/cura/Machines/QualityGroup.py +++ b/cura/Machines/QualityGroup.py @@ -4,6 +4,9 @@ from typing import Dict, Optional, List, Set from PyQt5.QtCore import QObject, pyqtSlot + +from UM.Util import parseBool + from cura.Machines.ContainerNode import ContainerNode @@ -29,6 +32,7 @@ class QualityGroup(QObject): self.nodes_for_extruders = {} # type: Dict[int, ContainerNode] self.quality_type = quality_type self.is_available = False + self.is_experimental = False @pyqtSlot(result = str) def getName(self) -> str: @@ -51,3 +55,17 @@ class QualityGroup(QObject): for extruder_node in self.nodes_for_extruders.values(): result.append(extruder_node) return result + + def setGlobalNode(self, node: "ContainerNode") -> None: + self.node_for_global = node + + # Update is_experimental flag + is_experimental = parseBool(node.getMetaDataEntry("is_experimental", False)) + self.is_experimental |= is_experimental + + def setExtruderNode(self, position: int, node: "ContainerNode") -> None: + self.nodes_for_extruders[position] = node + + # Update is_experimental flag + is_experimental = parseBool(node.getMetaDataEntry("is_experimental", False)) + self.is_experimental |= is_experimental diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index a784d17f0b..34cc9ce4b2 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -235,7 +235,7 @@ class QualityManager(QObject): for quality_type, quality_node in node.quality_type_map.items(): quality_group = QualityGroup(quality_node.getMetaDataEntry("name", ""), quality_type) - quality_group.node_for_global = quality_node + quality_group.setGlobalNode(quality_node) quality_group_dict[quality_type] = quality_group break @@ -337,7 +337,7 @@ class QualityManager(QObject): quality_group = quality_group_dict[quality_type] if position not in quality_group.nodes_for_extruders: - quality_group.nodes_for_extruders[position] = quality_node + quality_group.setExtruderNode(position, quality_node) # If the machine has its own specific qualities, for extruders, it should skip the global qualities # and use the material/variant specific qualities. @@ -367,7 +367,7 @@ class QualityManager(QObject): if node and node.quality_type_map: for quality_type, quality_node in node.quality_type_map.items(): quality_group = QualityGroup(quality_node.getMetaDataEntry("name", ""), quality_type) - quality_group.node_for_global = quality_node + quality_group.setGlobalNode(quality_node) quality_group_dict[quality_type] = quality_group break diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index f7ad108ad4..527d5d2679 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -616,6 +616,14 @@ class MachineManager(QObject): is_supported = self._current_quality_group.is_available return is_supported + @pyqtProperty(bool, notify = activeQualityGroupChanged) + def isActiveQualityExperimental(self) -> bool: + is_experimental = False + if self._global_container_stack: + if self._current_quality_group: + is_experimental = self._current_quality_group.is_experimental + return is_experimental + ## Returns whether there is anything unsupported in the current set-up. # # The current set-up signifies the global stack and all extruder stacks, diff --git a/resources/qml/Menus/ProfileMenu.qml b/resources/qml/Menus/ProfileMenu.qml index ffd3c556b6..b503b7de85 100644 --- a/resources/qml/Menus/ProfileMenu.qml +++ b/resources/qml/Menus/ProfileMenu.qml @@ -17,7 +17,11 @@ Menu MenuItem { - text: (model.layer_height != "") ? model.name + " - " + model.layer_height + model.layer_height_unit : model.name + text: { + var full_text = (model.layer_height != "") ? model.name + " - " + model.layer_height + model.layer_height_unit : model.name; + full_text += model.is_experimental ? " - Experimental" : ""; + return full_text; + } checkable: true checked: Cura.MachineManager.activeQualityOrQualityChangesName == model.name exclusiveGroup: group diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index da50b430ac..5d916aed7c 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -66,6 +66,9 @@ Item function generateActiveQualityText () { var result = Cura.MachineManager.activeQualityOrQualityChangesName; + if (Cura.MachineManager.isActiveQualityExperimental) { + result += " (Experimental)"; + } if (Cura.MachineManager.isActiveQualitySupported) { if (Cura.MachineManager.activeQualityLayerHeight > 0) { From 41a5f05391dbc06dc4afde0321364e596ab8452b Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 27 Nov 2018 15:57:26 +0100 Subject: [PATCH 0514/1292] Remove SyncButton It hasn't been used now for a while. Contributes to issue CURA-5876. --- .../Menus/ConfigurationMenu/SyncButton.qml | 102 ------------------ 1 file changed, 102 deletions(-) delete mode 100644 resources/qml/Menus/ConfigurationMenu/SyncButton.qml diff --git a/resources/qml/Menus/ConfigurationMenu/SyncButton.qml b/resources/qml/Menus/ConfigurationMenu/SyncButton.qml deleted file mode 100644 index 558ae1e477..0000000000 --- a/resources/qml/Menus/ConfigurationMenu/SyncButton.qml +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.7 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 - -import UM 1.2 as UM -import Cura 1.0 as Cura - -Button -{ - id: base - property var outputDevice: null - property var matched: updateOnSync() - text: matched == true ? catalog.i18nc("@label:extruder label", "Yes") : catalog.i18nc("@label:extruder label", "No") - width: parent.width - height: parent.height - - function updateOnSync() - { - if (outputDevice != undefined) - { - for (var index in outputDevice.uniqueConfigurations) - { - var configuration = outputDevice.uniqueConfigurations[index] - if (Cura.MachineManager.matchesConfiguration(configuration)) - { - base.matched = true; - return; - } - } - } - base.matched = false; - } - - style: ButtonStyle - { - background: Rectangle - { - color: - { - if(control.pressed) - { - return UM.Theme.getColor("machine_selector_active"); - } - else if(control.hovered) - { - return UM.Theme.getColor("machine_selector_hover"); - } - else - { - return UM.Theme.getColor("machine_selector_bar"); - } - } - Behavior on color { ColorAnimation { duration: 50; } } - - UM.RecolorImage - { - id: downArrow - anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - anchors.rightMargin: UM.Theme.getSize("default_margin").width - width: UM.Theme.getSize("standard_arrow").width - height: UM.Theme.getSize("standard_arrow").height - sourceSize.width: width - sourceSize.height: height - color: UM.Theme.getColor("text_emphasis") - source: UM.Theme.getIcon("arrow_bottom") - } - UM.RecolorImage - { - id: sidebarComboBoxLabel - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("default_margin").width - anchors.verticalCenter: parent.verticalCenter; - - width: UM.Theme.getSize("printer_sync_icon").width - height: UM.Theme.getSize("printer_sync_icon").height - - color: control.matched ? UM.Theme.getColor("printer_config_matched") : UM.Theme.getColor("printer_config_mismatch") - source: UM.Theme.getIcon("tab_status_connected") - sourceSize.width: width - sourceSize.height: height - } - } - label: Label {} - } - - Connections - { - target: outputDevice - onUniqueConfigurationsChanged: updateOnSync() - } - - Connections - { - target: Cura.MachineManager - onCurrentConfigurationChanged: updateOnSync() - onOutputDevicesChanged: updateOnSync() - } -} \ No newline at end of file From dad2031e4b5b8750a6721e6fdb3a24620eaf3cc7 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 27 Nov 2018 16:06:37 +0100 Subject: [PATCH 0515/1292] Switch to the preview stage before to switch to simulation view ... since now the list of views are in a different stage. Contributes to CURA-5979. --- cura/CuraApplication.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 6e52a97518..b43e4d5e0e 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -1663,7 +1663,9 @@ class CuraApplication(QtApplication): is_non_sliceable = "." + file_extension in self._non_sliceable_extensions if is_non_sliceable: - self.callLater(lambda: self.getController().setActiveView("SimulationView")) + # Need to switch first to the preview stage and then to layer view + self.callLater(lambda: (self.getController().setActiveStage("PreviewStage"), + self.getController().setActiveView("SimulationView"))) block_slicing_decorator = BlockSlicingDecorator() node.addDecorator(block_slicing_decorator) From ff851b0382b688b6c190d48127be3e0a369a2960 Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Tue, 27 Nov 2018 16:36:27 +0100 Subject: [PATCH 0516/1292] Added margins CURA-5941 --- resources/qml/PrintSetupSelector.qml | 4 ++-- resources/qml/SidebarSimple.qml | 10 ++-------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/resources/qml/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector.qml index b20d8e116b..6edb297721 100644 --- a/resources/qml/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector.qml @@ -216,8 +216,8 @@ Cura.ExpandableComponent topMargin: UM.Theme.getSize("narrow_margin").height right: parent.right left: parent.left - leftMargin: UM.Theme.getSize("thick_margin").width / 1.5 - rightMargin: UM.Theme.getSize("thick_margin").width / 1.5 + leftMargin: UM.Theme.getSize("default_margin").width + rightMargin: UM.Theme.getSize("default_margin").width } UM.TabRow diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index 2e0f0d6c4c..f2e998f526 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -38,6 +38,8 @@ Item width: childrenRect.width height: childrenRect.height + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("default_margin").width // // Quality profile // @@ -48,7 +50,6 @@ Item height: UM.Theme.getSize("thick_margin").height anchors.topMargin: UM.Theme.getSize("thick_margin").height anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("thick_margin").width anchors.right: parent.right Timer @@ -193,7 +194,6 @@ Item source: UM.Theme.getIcon("category_layer_height") text: catalog.i18nc("@label", "Layer Height") anchors.bottom: speedSlider.bottom - } // Show titles for the each quality slider ticks @@ -507,7 +507,6 @@ Item top: parent.top topMargin: Math.round(UM.Theme.getSize("thick_margin").height * 1.7) left: parent.left - leftMargin: UM.Theme.getSize("thick_margin").width } } } @@ -526,9 +525,7 @@ Item Label { id: selectedInfillRateText - //anchors.top: parent.top anchors.left: infillSlider.left - anchors.leftMargin: Math.round((infillSlider.value / infillSlider.stepSize) * (infillSlider.width / (infillSlider.maximumValue / infillSlider.stepSize)) - 10 * screenScaleFactor) anchors.right: parent.right text: parseInt(infillDensity.properties.value) + "%" @@ -833,7 +830,6 @@ Item top: infillCellRight.bottom topMargin: Math.round(UM.Theme.getSize("thick_margin").height * 1.5) left: parent.left - leftMargin: UM.Theme.getSize("thick_margin").width right: infillCellLeft.right rightMargin: UM.Theme.getSize("thick_margin").width verticalCenter: enableSupportCheckBox.verticalCenter @@ -956,7 +952,6 @@ Item anchors { left: parent.left - leftMargin: UM.Theme.getSize("thick_margin").width right: infillCellLeft.right rightMargin: UM.Theme.getSize("thick_margin").width verticalCenter: adhesionCheckBox.verticalCenter @@ -1037,7 +1032,6 @@ Item { id: tipsText anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("thick_margin").width anchors.right: parent.right anchors.rightMargin: UM.Theme.getSize("thick_margin").width anchors.top: parent.top From 26c7558a53b571deaea91d8d2acd39ee9f5a005d Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 27 Nov 2018 16:44:16 +0100 Subject: [PATCH 0517/1292] Don't show labels if controls themselves are not shown The height of the popup is luckily automatically adjusted now. Contributes to issue CURA-5876. --- resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index 78448d5be5..87096c3a14 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -136,6 +136,7 @@ Item color: UM.Theme.getColor("text") height: parent.height width: selectors.textWidth + visible: materialSelection.visible } OldControls.ToolButton @@ -178,6 +179,7 @@ Item color: UM.Theme.getColor("text") height: parent.height width: selectors.textWidth + visible: variantSelection.visible } OldControls.ToolButton From 26f107d1763387848e4faf9b7b9726ac9cee90f9 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 27 Nov 2018 17:03:19 +0100 Subject: [PATCH 0518/1292] Use cluster_id as dict key, remove unneeded white space --- .../src/Cloud/CloudOutputDeviceManager.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 3ebaeea9a4..e20a658994 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -47,7 +47,6 @@ class CloudOutputDeviceManager(NetworkClient): self._update_clusters_thread = Thread(target=self._updateClusters, daemon=True) self._update_clusters_thread.start() - ## Override _createEmptyRequest to add the needed authentication header for talking to the Ultimaker Cloud API. def _createEmptyRequest(self, path: str, content_type: Optional[str] = "application/json") -> QNetworkRequest: request = super()._createEmptyRequest(self.API_ROOT_PATH + path, content_type = content_type) @@ -81,14 +80,14 @@ class CloudOutputDeviceManager(NetworkClient): return known_cluster_ids = set(self._remote_clusters.keys()) - found_clusters_ids = set(found_clusters.keys()) + found_cluster_ids = set(found_clusters.keys()) # Add an output device for each new remote cluster. - for cluster_id in found_clusters_ids.difference(known_cluster_ids): + for cluster_id in found_cluster_ids.difference(known_cluster_ids): self._addCloudOutputDevice(found_clusters[cluster_id]) # Remove output devices that are gone - for cluster_id in known_cluster_ids.difference(found_clusters_ids): + for cluster_id in known_cluster_ids.difference(found_cluster_ids): self._removeCloudOutputDevice(found_clusters[cluster_id]) # For testing we add a dummy device: @@ -97,7 +96,7 @@ class CloudOutputDeviceManager(NetworkClient): @staticmethod def _parseStatusResponse(reply: QNetworkReply) -> Dict[str, CloudCluster]: try: - return {c["guid"]: CloudCluster(**c) for c in json.loads(reply.readAll().data().decode("utf-8"))} + return {c["cluster_id"]: CloudCluster(**c) for c in json.loads(reply.readAll().data().decode("utf-8"))} except UnicodeDecodeError: Logger.log("w", "Unable to read server response") except json.decoder.JSONDecodeError: From 0b8a56458d5d6bea6dc88c8674c3459fa5eee402 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 27 Nov 2018 17:11:32 +0100 Subject: [PATCH 0519/1292] Remove unused CustomConfigurationSelector I checked. It is no longer used. Contributes to issue CURA-5876. --- resources/qml/CustomConfigurationSelector.qml | 357 ------------------ 1 file changed, 357 deletions(-) delete mode 100644 resources/qml/CustomConfigurationSelector.qml diff --git a/resources/qml/CustomConfigurationSelector.qml b/resources/qml/CustomConfigurationSelector.qml deleted file mode 100644 index c78ca700da..0000000000 --- a/resources/qml/CustomConfigurationSelector.qml +++ /dev/null @@ -1,357 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.7 -import QtQuick.Controls 1.1 -import QtQuick.Controls.Styles 1.1 - -import UM 1.2 as UM -import Cura 1.0 as Cura - -Rectangle -{ - implicitWidth: parent.width - implicitHeight: parent.height - - id: base - color: UM.Theme.getColor("main_background") - - // Height has an extra 2x margin for the top & bottom margin. - height: childrenRect.height + 2 * UM.Theme.getSize("default_margin").width - - Cura.ExtrudersModel { id: extrudersModel } - - ListView - { - // Horizontal list that shows the extruders - id: extrudersList - visible: extrudersModel.items.length > 1 - property var index: 0 - - height: UM.Theme.getSize("configuration_selector_mode_tabs").height - boundsBehavior: Flickable.StopAtBounds - - anchors - { - left: parent.left - right: parent.right - top: parent.top - margins: UM.Theme.getSize("thick_margin").width - } - - ExclusiveGroup { id: extruderMenuGroup } - - orientation: ListView.Horizontal - - model: extrudersModel - - Connections - { - target: Cura.MachineManager - onGlobalContainerChanged: forceActiveFocus() // Changing focus applies the currently-being-typed values so it can change the displayed setting values. - } - - delegate: Button - { - height: parent.height - width: Math.round(ListView.view.width / extrudersModel.rowCount()) - - text: model.name - tooltip: model.name - exclusiveGroup: extruderMenuGroup - checked: Cura.ExtruderManager.activeExtruderIndex == index - - property bool extruder_enabled: true - - MouseArea // TODO; This really should be fixed. It makes absolutely no sense to have a button AND a mouse area. - { - anchors.fill: parent - acceptedButtons: Qt.LeftButton | Qt.RightButton - onClicked: - { - switch (mouse.button) - { - case Qt.LeftButton: - extruder_enabled = Cura.MachineManager.getExtruder(model.index).isEnabled - if (extruder_enabled) - { - forceActiveFocus() // Changing focus applies the currently-being-typed values so it can change the displayed setting values. - Cura.ExtruderManager.setActiveExtruderIndex(index) - } - break - case Qt.RightButton: - extruder_enabled = Cura.MachineManager.getExtruder(model.index).isEnabled - extruderMenu.popup() - break - } - } - } - - Menu - { - id: extruderMenu - - MenuItem - { - text: catalog.i18nc("@action:inmenu", "Enable Extruder") - onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, true) - visible: !extruder_enabled // using an intermediate variable prevents an empty popup that occured now and then - } - - MenuItem - { - text: catalog.i18nc("@action:inmenu", "Disable Extruder") - onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, false) - visible: extruder_enabled - enabled: Cura.MachineManager.numberExtrudersEnabled > 1 - } - } - - style: ButtonStyle - { - background: Rectangle - { - anchors.fill: parent - border.width: control.checked ? UM.Theme.getSize("default_lining").width * 2 : UM.Theme.getSize("default_lining").width - border.color: - { - if (Cura.MachineManager.getExtruder(index).isEnabled) - { - if(control.checked || control.pressed) - { - return UM.Theme.getColor("action_button_active_border") - } - else if (control.hovered) - { - return UM.Theme.getColor("action_button_hovered_border") - } - return UM.Theme.getColor("action_button_border") - } - return UM.Theme.getColor("action_button_disabled_border") - } - color: - { - if (Cura.MachineManager.getExtruder(index).isEnabled) - { - if(control.checked || control.pressed) - { - return UM.Theme.getColor("action_button_active"); - } - else if (control.hovered) - { - return UM.Theme.getColor("action_button_hovered") - } - return UM.Theme.getColor("action_button") - } - return UM.Theme.getColor("action_button_disabled") - } - Behavior on color { ColorAnimation { duration: 50; } } - - Item - { - id: extruderButtonFace - anchors.centerIn: parent - width: childrenRect.width - - Label - { - // Static text that holds the "Extruder" label - id: extruderStaticText - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - - color: - { - if (Cura.MachineManager.getExtruder(index).isEnabled) - { - if(control.checked || control.pressed) - { - return UM.Theme.getColor("action_button_active_text"); - } - else if (control.hovered) - { - return UM.Theme.getColor("action_button_hovered_text") - } - return UM.Theme.getColor("action_button_text") - } - return UM.Theme.getColor("action_button_disabled_text") - } - - font: UM.Theme.getFont("large_nonbold") - text: catalog.i18nc("@label", "Extruder") - visible: width < (control.width - extruderIcon.width - UM.Theme.getSize("default_margin").width) - elide: Text.ElideRight - } - - ExtruderIcon - { - // Round icon with the extruder number and material color indicator. - id: extruderIcon - - anchors.verticalCenter: parent.verticalCenter - anchors.left: extruderStaticText.right - anchors.leftMargin: UM.Theme.getSize("default_margin").width - width: control.height - Math.round(UM.Theme.getSize("default_margin").width / 2) - height: width - - checked: control.checked - materialColor: model.color - textColor: extruderStaticText.color - } - } - } - - label: Item {} - } - } - } - - Item - { - id: materialRow - height: UM.Theme.getSize("print_setup_item").height - visible: Cura.MachineManager.hasMaterials - - anchors - { - left: parent.left - right: parent.right - top: extrudersList.bottom - margins: UM.Theme.getSize("thick_margin").width - } - - Label - { - id: materialLabel - text: catalog.i18nc("@label", "Material"); - width: Math.round(parent.width * 0.45 - UM.Theme.getSize("default_margin").width) - height: parent.height - verticalAlignment: Text.AlignVCenter - font: UM.Theme.getFont("default"); - color: UM.Theme.getColor("text"); - } - - ToolButton - { - id: materialSelection - - property var activeExtruder: Cura.MachineManager.activeStack - property var hasActiveExtruder: activeExtruder != null - property var currentRootMaterialName: hasActiveExtruder ? activeExtruder.material.name : "" - - text: currentRootMaterialName - tooltip: currentRootMaterialName - visible: Cura.MachineManager.hasMaterials - - enabled: !extrudersList.visible || Cura.ExtruderManager.activeExtruderIndex > -1 - - height: UM.Theme.getSize("setting_control").height - width: Math.round(parent.width * 0.7) + UM.Theme.getSize("thick_margin").width - anchors.right: parent.right - style: UM.Theme.styles.sidebar_header_button - activeFocusOnPress: true; - menu: Cura.MaterialMenu - { - extruderIndex: Cura.ExtruderManager.activeExtruderIndex - } - - property var valueError: hasActiveExtruder ? Cura.ContainerManager.getContainerMetaDataEntry(activeExtruder.material.id, "compatible", "") != "True" : true - property var valueWarning: ! Cura.MachineManager.isActiveQualitySupported - } - } - - Item - { - id: variantRow - height: UM.Theme.getSize("print_setup_item").height - visible: Cura.MachineManager.hasVariants - - anchors - { - left: parent.left - right: parent.right - top: materialRow.bottom - margins: UM.Theme.getSize("thick_margin").width - } - - Label - { - id: variantLabel - text: Cura.MachineManager.activeDefinitionVariantsName; - width: Math.round(parent.width * 0.45 - UM.Theme.getSize("default_margin").width) - height: parent.height - verticalAlignment: Text.AlignVCenter - font: UM.Theme.getFont("default"); - color: UM.Theme.getColor("text"); - } - - ToolButton - { - id: variantSelection - text: Cura.MachineManager.activeVariantName - tooltip: Cura.MachineManager.activeVariantName; - visible: Cura.MachineManager.hasVariants - - height: UM.Theme.getSize("setting_control").height - width: Math.round(parent.width * 0.7 + UM.Theme.getSize("thick_margin").width) - anchors.right: parent.right - style: UM.Theme.styles.sidebar_header_button - activeFocusOnPress: true; - - menu: Cura.NozzleMenu { extruderIndex: Cura.ExtruderManager.activeExtruderIndex } - } - } - - Item - { - id: materialCompatibilityLink - height: UM.Theme.getSize("print_setup_item").height - - anchors.right: parent.right - anchors.top: variantRow.bottom - anchors.margins: UM.Theme.getSize("thick_margin").width - UM.RecolorImage - { - id: warningImage - - anchors.right: materialInfoLabel.left - anchors.rightMargin: UM.Theme.getSize("default_margin").width - - source: UM.Theme.getIcon("warning") - width: UM.Theme.getSize("section_icon").width - height: UM.Theme.getSize("section_icon").height - - sourceSize.width: width - sourceSize.height: height - - color: UM.Theme.getColor("material_compatibility_warning") - - visible: !Cura.MachineManager.isCurrentSetupSupported - } - - Label - { - id: materialInfoLabel - wrapMode: Text.WordWrap - text: "" + catalog.i18nc("@label", "Check compatibility") + "" - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - linkColor: UM.Theme.getColor("text_link") - - verticalAlignment: Text.AlignTop - - anchors.right: parent.right - - MouseArea - { - anchors.fill: parent - - onClicked: - { - // open the material URL with web browser - Qt.openUrlExternally("https://ultimaker.com/incoming-links/cura/material-compatibilty"); - } - } - } - } -} From 309061ce3113df6dd7f7c9e9762526b1ce0973c5 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 27 Nov 2018 17:16:52 +0100 Subject: [PATCH 0520/1292] Add a new ToolbarButton Now also the Extruder button is a toolbar button since it will show in the toolbar. --- resources/qml/ExtruderButton.qml | 18 +++---- resources/qml/Toolbar.qml | 25 ++++++--- resources/qml/ToolbarButton.qml | 92 ++++++++++++++++++++++++++++++++ resources/qml/qmldir | 3 +- 4 files changed, 117 insertions(+), 21 deletions(-) create mode 100644 resources/qml/ToolbarButton.qml diff --git a/resources/qml/ExtruderButton.qml b/resources/qml/ExtruderButton.qml index d7cbdc52bc..feb399d528 100644 --- a/resources/qml/ExtruderButton.qml +++ b/resources/qml/ExtruderButton.qml @@ -7,7 +7,7 @@ import QtQuick.Controls 2.0 import UM 1.2 as UM import Cura 1.0 as Cura -Button +Cura.ToolbarButton { id: base @@ -18,22 +18,16 @@ Button checked: Cura.ExtruderManager.selectedObjectExtruders.indexOf(extruder.id) != -1 enabled: UM.Selection.hasSelection && extruder.stack.isEnabled - background: Item {} - contentItem: Item + toolItem: ExtruderIcon { - // For some reason if the extruder icon is not enclosed to the item, the size changes to fill the size of the button - ExtruderIcon - { - anchors.centerIn: parent - materialColor: model.color - extruderEnabled: extruder.stack.isEnabled - property int index: extruder.index - } + materialColor: extruder.color + extruderEnabled: extruder.stack.isEnabled + property int index: extruder.index } onClicked: { forceActiveFocus() //First grab focus, so all the text fields are updated - CuraActions.setExtruderForSelection(extruder.id); + CuraActions.setExtruderForSelection(extruder.id) } } diff --git a/resources/qml/Toolbar.qml b/resources/qml/Toolbar.qml index 0240aaab26..3a4e7704c0 100644 --- a/resources/qml/Toolbar.qml +++ b/resources/qml/Toolbar.qml @@ -55,17 +55,25 @@ Item model: UM.ToolModel { id: toolsModel } width: childrenRect.width height: childrenRect.height - Button + + delegate: ToolbarButton { text: model.name + (model.shortcut ? (" (" + model.shortcut + ")") : "") - iconSource: (UM.Theme.getIcon(model.icon) != "") ? UM.Theme.getIcon(model.icon) : "file:///" + model.location + "/" + model.icon checkable: true checked: model.active enabled: model.enabled && UM.Selection.hasSelection && UM.Controller.toolsEnabled - style: UM.Theme.styles.toolbar_button - property bool isFirstElement: toolsModel.getItem(0).id == model.id - property bool isLastElement: toolsModel.getItem(toolsModel.rowCount() - 1).id == model.id + topElement: toolsModel.getItem(0).id == model.id + bottomElement: toolsModel.getItem(toolsModel.rowCount() - 1).id == model.id + + toolItem: UM.RecolorImage + { + opacity: parent.enabled ? 1.0 : 0.2 + source: (UM.Theme.getIcon(model.icon) != "") ? UM.Theme.getIcon(model.icon) : "file:///" + model.location + "/" + model.icon + color: UM.Theme.getColor("toolbar_button_text") + + sourceSize: UM.Theme.getSize("button_icon") + } onCheckedChanged: { @@ -128,11 +136,12 @@ Item height: childrenRect.height property var _model: Cura.ExtrudersModel { id: extrudersModel } model: _model.items.length > 1 ? _model : 0 - ExtruderButton + + delegate: ExtruderButton { extruder: model - height: UM.Theme.getSize("button").width - width: UM.Theme.getSize("button").width + topElement: extrudersModel.getItem(0).id == model.id + bottomElement: extrudersModel.getItem(extrudersModel.rowCount() - 1).id == model.id } } } diff --git a/resources/qml/ToolbarButton.qml b/resources/qml/ToolbarButton.qml new file mode 100644 index 0000000000..7241b489b6 --- /dev/null +++ b/resources/qml/ToolbarButton.qml @@ -0,0 +1,92 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.3 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +Button +{ + id: base + + property alias toolItem: contentItemLoader.sourceComponent + property bool topElement: false + property bool bottomElement: false + + hoverEnabled: true + + background: Rectangle + { + implicitWidth: UM.Theme.getSize("button").width + implicitHeight: UM.Theme.getSize("button").height + color: + { + if (base.checked && base.hovered) + { + return UM.Theme.getColor("toolbar_button_active_hover") + } + else if (base.checked) + { + return "red" //UM.Theme.getColor("toolbar_button_active") + } + else if(base.hovered) + { + return UM.Theme.getColor("toolbar_button_hover") + } + return UM.Theme.getColor("toolbar_background") + } + radius: UM.Theme.getSize("default_radius").width + + Rectangle + { + id: topSquare + anchors + { + left: parent.left + right: parent.right + top: parent.top + } + height: parent.radius + color: base.topElement ? "transparent" : parent.color + } + + Rectangle + { + id: bottomSquare + anchors + { + left: parent.left + right: parent.right + bottom: parent.bottom + } + height: parent.radius + color: base.bottomElement ? "transparent" : parent.color + } + + Rectangle + { + id: leftSquare + anchors + { + left: parent.left + top: parent.top + bottom: parent.bottom + } + width: parent.radius + color: parent.color + } + } + + contentItem: Item + { + Loader + { + id: contentItemLoader + anchors.centerIn: parent + width: UM.Theme.getSize("button_icon").width + height: UM.Theme.getSize("button_icon").height + } + } +} diff --git a/resources/qml/qmldir b/resources/qml/qmldir index 43ae4411af..2475f398f8 100644 --- a/resources/qml/qmldir +++ b/resources/qml/qmldir @@ -12,4 +12,5 @@ IconLabel 1.0 IconLabel.qml OutputDevicesActionButton 1.0 OutputDevicesActionButton.qml ExpandableComponent 1.0 ExpandableComponent.qml PrinterTypeLabel 1.0 PrinterTypeLabel.qml -ViewsSelector 1.0 ViewsSelector.qml \ No newline at end of file +ViewsSelector 1.0 ViewsSelector.qml +ToolbarButton 1.0 ToolbarButton.qml \ No newline at end of file From 14b460a626bfbb58b0bc8eff6621f46e8d400ecb Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 27 Nov 2018 17:25:10 +0100 Subject: [PATCH 0521/1292] Remove unused styles --- resources/qml/Toolbar.qml | 5 +- resources/qml/ToolbarButton.qml | 3 +- resources/themes/cura-light/styles.qml | 117 ------------------------- 3 files changed, 3 insertions(+), 122 deletions(-) diff --git a/resources/qml/Toolbar.qml b/resources/qml/Toolbar.qml index 3a4e7704c0..0207c8ec49 100644 --- a/resources/qml/Toolbar.qml +++ b/resources/qml/Toolbar.qml @@ -2,9 +2,7 @@ // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 -import QtQuick.Controls 1.1 -import QtQuick.Controls.Styles 1.1 -import QtQuick.Layouts 1.1 +import QtQuick.Controls 2.3 import UM 1.2 as UM import Cura 1.0 as Cura @@ -68,7 +66,6 @@ Item toolItem: UM.RecolorImage { - opacity: parent.enabled ? 1.0 : 0.2 source: (UM.Theme.getIcon(model.icon) != "") ? UM.Theme.getIcon(model.icon) : "file:///" + model.location + "/" + model.icon color: UM.Theme.getColor("toolbar_button_text") diff --git a/resources/qml/ToolbarButton.qml b/resources/qml/ToolbarButton.qml index 7241b489b6..b5e5aab475 100644 --- a/resources/qml/ToolbarButton.qml +++ b/resources/qml/ToolbarButton.qml @@ -29,7 +29,7 @@ Button } else if (base.checked) { - return "red" //UM.Theme.getColor("toolbar_button_active") + return UM.Theme.getColor("toolbar_button_active") } else if(base.hovered) { @@ -81,6 +81,7 @@ Button contentItem: Item { + opacity: parent.enabled ? 1.0 : 0.2 Loader { id: contentItemLoader diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index f00aab44c0..e040d91df9 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -171,123 +171,6 @@ QtObject } } - property Component toolbar_button: Component - { - ButtonStyle - { - background: Rectangle - { - implicitWidth: Theme.getSize("button").width - implicitHeight: Theme.getSize("button").height - color: - { - if (control.checked && control.hovered) - { - return Theme.getColor("toolbar_button_active_hover") - } - else if (control.checked) - { - return Theme.getColor("toolbar_button_active") - } - else if(control.hovered) - { - return Theme.getColor("toolbar_button_hover") - } - return Theme.getColor("toolbar_background") - } - radius: UM.Theme.getSize("default_radius").width - - Rectangle - { - id: topSquare - anchors - { - left: parent.left - right: parent.right - top: parent.top - } - height: parent.radius - color: control.isFirstElement ? "transparent" : parent.color - } - - Rectangle - { - id: bottomSquare - anchors - { - left: parent.left - right: parent.right - bottom: parent.bottom - } - height: parent.radius - color: control.isLastElement ? "transparent" : parent.color - } - - Rectangle - { - id: leftSquare - anchors - { - left: parent.left - top: parent.top - bottom: parent.bottom - } - width: parent.radius - color: parent.color - } - - // This is the tooltip - UM.PointingRectangle - { - id: button_tooltip - - anchors.left: parent.right - anchors.leftMargin: Theme.getSize("button_tooltip_arrow").width * 2 - anchors.verticalCenter: parent.verticalCenter - - target: Qt.point(parent.x, y + Math.round(height/2)) - arrowSize: Theme.getSize("button_tooltip_arrow").width - color: Theme.getColor("button_tooltip") - opacity: control.hovered ? 1.0 : 0.0; - visible: control.text != "" - - width: control.hovered ? button_tip.width + Theme.getSize("button_tooltip").width : 0 - height: Theme.getSize("button_tooltip").height - - Behavior on width { NumberAnimation { duration: 100; } } - Behavior on opacity { NumberAnimation { duration: 100; } } - - Label - { - id: button_tip - - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter; - - text: control.text; - font: Theme.getFont("button_tooltip"); - color: Theme.getColor("tooltip_text"); - } - } - } - - label: Item - { - UM.RecolorImage - { - anchors.centerIn: parent; - opacity: !control.enabled ? 0.2 : 1.0 - source: control.iconSource; - width: Theme.getSize("button_icon").width; - height: Theme.getSize("button_icon").height; - color: Theme.getColor("toolbar_button_text"); - - sourceSize: Theme.getSize("button_icon") - } - } - } - } - property Component tool_button: Component { ButtonStyle From 6f5dfc46773da8eacc5e32b6563ef5c5b3ba983e Mon Sep 17 00:00:00 2001 From: Artem Leshchev Date: Tue, 27 Nov 2018 19:46:49 +0300 Subject: [PATCH 0522/1292] Added definitions for Wanhao Duplicator 9 --- resources/definitions/wanhao_d9.def.json | 41 + .../extruders/wanhao_d9_extruder_0.def.json | 16 + resources/meshes/wanhao_300_300_platform.obj | 40925 ++++++++++++++++ 3 files changed, 40982 insertions(+) create mode 100644 resources/definitions/wanhao_d9.def.json create mode 100644 resources/extruders/wanhao_d9_extruder_0.def.json create mode 100644 resources/meshes/wanhao_300_300_platform.obj diff --git a/resources/definitions/wanhao_d9.def.json b/resources/definitions/wanhao_d9.def.json new file mode 100644 index 0000000000..4e368f970f --- /dev/null +++ b/resources/definitions/wanhao_d9.def.json @@ -0,0 +1,41 @@ +{ + "version": 2, + "name": "Wanhao Duplicator 9", + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "manufacturer": "Wanhao", + "file_formats": "text/x-gcode", + "has_materials": true, + "platform": "wanhao_300_300_platform.obj", + "platform_texture": "Wanhaobackplate.png", + "machine_extruder_trains": { + "0": "wanhao_d9_extruder_0" + }, + "platform_offset": [ 0, -55, 0] + }, + + "overrides": { + "machine_name": { "default_value": "Wanhao Duplicator 9" }, + "machine_width": { "default_value": 300 }, + "machine_height": { "default_value": 400 }, + "machine_depth": { "default_value": 300 }, + "machine_heated_bed": { "default_value": true }, + "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" }, + "machine_start_gcode": { + "default_value": "G21 ;metric values\n G90 ;absolute positioning\n M82 ;set extruder to absolute mode\n M107 ;start with the fan off\n G28 X0 Y0 ;move X/Y to min endstops\n G28 Z0 ;move Z to min endstops\n G1 Z15.0 F{travel_speed} ;move the platform down 15mm\n G92 E0 ;zero the extruded length\n G1 F200 E6 ;extrude 6 mm of feed stock\n G92 E0 ;zero the extruded length again\n G1 F{travel_speed} \n ;Put printing message on LCD screen\n M117 Printing..." + }, + "machine_end_gcode": { + "default_value": "M104 S0 ;extruder heater off \n G91 ;relative positioning\n G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\n G1 Z+0.5 E-5 X-20 Y-20 F{travel_speed} ;move Z up a bit and retract filament even more\n G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\n M84 ;steppers off\n G90 ;absolute positioning" + }, + "support_angle": { "default_value": 60 }, + "support_enable": { "default_value": true }, + "layer_height_0": { "default_value": 0.15 }, + "top_thickness": { "default_value": 0.6 }, + "material_print_temperature": { "default_value": 190 }, + "layer_height": { "default_value": 0.2 }, + "speed_print": { "default_value": 30 }, + "adhesion_type": { "default_value": "raft" }, + "support_z_distance": { "default_value": 0.22 } + } +} diff --git a/resources/extruders/wanhao_d9_extruder_0.def.json b/resources/extruders/wanhao_d9_extruder_0.def.json new file mode 100644 index 0000000000..00ae0e3b2a --- /dev/null +++ b/resources/extruders/wanhao_d9_extruder_0.def.json @@ -0,0 +1,16 @@ +{ + "id": "wanhao_d9_extruder_0", + "version": 2, + "name": "Extruder 1", + "inherits": "fdmextruder", + "metadata": { + "machine": "wanhao_d9", + "position": "0" + }, + + "overrides": { + "extruder_nr": { "default_value": 0 }, + "machine_nozzle_size": { "default_value": 0.4 }, + "material_diameter": { "default_value": 1.75 } + } +} diff --git a/resources/meshes/wanhao_300_300_platform.obj b/resources/meshes/wanhao_300_300_platform.obj new file mode 100644 index 0000000000..d36fa4027d --- /dev/null +++ b/resources/meshes/wanhao_300_300_platform.obj @@ -0,0 +1,40925 @@ +#### +# +# OBJ File Generated by Meshlab +# +#### +# Object Wanhao_300_300.obj +# +# Vertices: 10222 +# Faces: 20456 +# +#### +mtllib ./Wanhao_300_300.obj.mtl + +vn -0.393291 -0.630494 -0.669178 +v -130.035583 215.793518 15.199996 0.749020 0.749020 0.749020 +vn -0.051719 -0.728959 -0.682601 +v -129.391830 215.606537 15.199996 0.749020 0.749020 0.749020 +vn -0.207049 -0.715068 -0.667689 +v -129.725296 215.653976 15.199996 0.749020 0.749020 0.749020 +vn -0.544071 -0.503412 -0.671240 +v -130.302078 216.015366 15.199996 0.749020 0.749020 0.749020 +vn -0.580426 0.569359 -0.582183 +v -130.679321 218.494888 15.199996 0.749020 0.749020 0.749020 +vn 0.053255 -0.729269 -0.682151 +v 129.391830 215.606537 15.199996 0.749020 0.749020 0.749020 +vn -0.729738 -0.090231 -0.677747 +v -130.679321 217.003281 15.199996 0.749020 0.749020 0.749020 +vn -0.680964 -0.312870 -0.662118 +v -130.506790 216.305603 15.199996 0.749020 0.749020 0.749020 +vn 0.580429 0.569355 -0.582183 +v 130.679321 218.494888 15.199996 0.749020 0.749020 0.749020 +vn 0.680964 -0.312870 -0.662118 +v 130.506790 216.305603 15.199996 0.749020 0.749020 0.749020 +vn 0.544071 -0.503412 -0.671240 +v 130.302078 216.015366 15.199996 0.749020 0.749020 0.749020 +vn -0.726515 0.683644 -0.069329 +v -130.126984 220.890671 113.548996 0.749020 0.749020 0.749020 +vn 0.726471 0.683697 -0.069274 +v 130.126984 220.892075 113.548996 0.749020 0.749020 0.749020 +vn 0.729739 -0.090229 -0.677746 +v 130.679321 217.003281 15.199996 0.749020 0.749020 0.749020 +vn 0.992475 -0.122036 0.010024 +v 130.125702 219.401840 113.636200 0.749020 0.749020 0.749020 +vn 0.649937 0.730775 -0.208683 +v 130.081924 223.917160 121.446198 0.749020 0.749020 0.749020 +vn 0.748066 0.661094 0.057892 +v 130.069046 223.917160 123.872597 0.749020 0.749020 0.749020 +vn 0.751737 0.614921 -0.238251 +v 130.101242 221.748810 118.013794 0.749020 0.749020 0.749020 +vn 0.788179 0.584583 0.192449 +v 130.005966 223.917160 124.540398 0.749020 0.749020 0.749020 +vn 0.882308 -0.417950 0.216448 +v 129.913269 220.543243 121.067398 0.749020 0.749020 0.749020 +vn 0.991714 -0.114562 0.058125 +v 130.088364 221.097168 120.467400 0.749020 0.749020 0.749020 +vn 0.991549 -0.126987 0.026564 +v 130.120560 219.461838 114.714798 0.749020 0.749020 0.749020 +vn -0.751844 0.614714 -0.238449 +v -130.101242 221.748810 118.013794 0.749020 0.749020 0.749020 +vn -0.649959 0.730757 -0.208681 +v -130.081924 223.917160 121.446198 0.749020 0.749020 0.749020 +vn -0.043265 0.347512 0.936677 +v -128.778992 223.917160 126.066002 0.749020 0.749020 0.749020 +vn -0.152839 -0.739284 0.655819 +v -128.794449 221.041367 122.842796 0.749020 0.749020 0.749020 +vn 0.116109 0.334526 0.935206 +v 128.778992 223.917160 126.066002 0.749020 0.749020 0.749020 +vn 0.160321 -0.736734 0.656902 +v 128.794449 221.041367 122.842796 0.749020 0.749020 0.749020 +vn 0.152749 -0.862867 0.481796 +v 128.800888 219.985092 121.658401 0.749020 0.749020 0.749020 +vn -0.240252 0.330881 0.912577 +v -128.924484 223.917160 126.052200 0.749020 0.749020 0.749020 +vn -0.152750 -0.862868 0.481796 +v -128.800888 219.985092 121.658401 0.749020 0.749020 0.749020 +vn 0.141015 -0.952070 0.271437 +v 128.815048 219.122787 118.625000 0.749020 0.749020 0.749020 +vn -0.140808 -0.952119 0.271372 +v -128.815048 219.122787 118.625000 0.749020 0.749020 0.749020 +vn 0.139042 -0.976592 0.164119 +v 128.833069 218.077667 114.946999 0.749020 0.749020 0.749020 +vn 0.139953 -0.989294 0.041351 +v 128.839508 218.006516 113.688599 0.749020 0.749020 0.749020 +vn -0.140384 -0.976322 0.164586 +v -128.833069 218.076279 114.946999 0.749020 0.749020 0.749020 +vn -0.140747 -0.989226 0.040289 +v -128.839508 218.006516 113.688599 0.749020 0.749020 0.749020 +vn 0.519482 -0.842140 0.144702 +v 129.475525 218.263260 114.922195 0.749020 0.749020 0.749020 +vn 0.542742 -0.735115 0.406248 +v 129.442047 220.135788 121.502998 0.749020 0.749020 0.749020 +vn 0.525233 -0.850133 0.037484 +v 129.481964 218.193497 113.688004 0.749020 0.749020 0.749020 +vn 0.873925 -0.478520 0.085282 +v 129.946747 218.769760 114.837204 0.749020 0.749020 0.749020 +vn 0.879593 -0.475122 0.024002 +v 129.953171 218.704178 113.668800 0.749020 0.749020 0.749020 +vn 0.665525 0.408507 0.624659 +v 129.533463 223.917160 125.652802 0.749020 0.749020 0.749020 +vn 0.587814 0.409034 0.697973 +v 129.413727 223.917160 125.755798 0.749020 0.749020 0.749020 +vn 0.783587 0.572843 0.240504 +v 129.878494 223.917160 124.967400 0.749020 0.749020 0.749020 +vn 0.780364 0.490775 0.387521 +v 129.816711 223.917160 125.175201 0.749020 0.749020 0.749020 +vn 0.413693 0.336027 0.846135 +v 129.179398 223.917160 125.958397 0.749020 0.749020 0.749020 +vn 0.392286 -0.631539 -0.668783 +v 130.035583 215.793518 15.199996 0.749020 0.749020 0.749020 +vn 0.206974 -0.714327 -0.668505 +v 129.725296 215.655380 15.199996 0.749020 0.749020 0.749020 +vn -0.749441 0.658736 0.066375 +v -130.069046 223.917160 123.872597 0.749020 0.749020 0.749020 +vn -0.991794 -0.114456 0.056967 +v -130.088364 221.097168 120.467400 0.749020 0.749020 0.749020 +vn -0.991550 -0.126993 0.026486 +v -130.120560 219.461838 114.714798 0.749020 0.749020 0.749020 +vn -0.793714 0.558733 0.240491 +v -129.978928 223.917160 124.673798 0.749020 0.749020 0.749020 +vn -0.881932 -0.419880 0.214236 +v -129.913269 220.541840 121.067398 0.749020 0.749020 0.749020 +vn -0.992431 -0.122381 0.010204 +v -130.125702 219.400467 113.636200 0.749020 0.749020 0.749020 +vn -0.873962 -0.478489 0.085077 +v -129.946747 218.769760 114.837204 0.749020 0.749020 0.749020 +vn -0.879536 -0.475220 0.024147 +v -129.953171 218.704178 113.668800 0.749020 0.749020 0.749020 +vn -0.520263 -0.841666 0.144654 +v -129.475525 218.263260 114.922195 0.749020 0.749020 0.749020 +vn -0.525377 -0.850052 0.037302 +v -129.481964 218.193497 113.688004 0.749020 0.749020 0.749020 +vn -0.540978 -0.737047 0.405098 +v -129.442047 220.135788 121.502998 0.749020 0.749020 0.749020 +vn -0.744458 0.452776 0.490689 +v -129.716278 223.917160 125.380196 0.749020 0.749020 0.749020 +vn -0.774052 0.563892 0.287871 +v -129.873352 223.917160 124.958000 0.749020 0.749020 0.749020 +vn -0.690487 0.461347 0.557124 +v -129.412430 223.917160 125.758202 0.749020 0.749020 0.749020 +vn -0.535741 0.359825 0.763877 +v -129.339050 223.917160 125.848999 0.749020 0.749020 0.749020 +vn -0.317177 0.586780 0.745043 +v -1.949426 168.818207 18.567398 1.000000 1.000000 1.000000 +vn -0.481548 0.703595 0.522557 +v -2.745052 168.705185 18.162399 1.000000 1.000000 1.000000 +vn -0.515217 0.361340 0.777164 +v -3.835522 167.520538 18.371597 1.000000 1.000000 1.000000 +vn -0.193702 0.239788 0.951305 +v -1.870144 168.592148 18.707798 1.000000 1.000000 1.000000 +vn -0.132051 0.611438 0.780197 +v -0.458452 169.186569 18.709599 1.000000 1.000000 1.000000 +vn -0.306161 0.284964 0.908329 +v -3.128578 167.852631 18.575798 1.000000 1.000000 1.000000 +vn -0.250685 0.831658 0.495482 +v -1.277980 169.306564 18.299000 1.000000 1.000000 1.000000 +vn -0.371458 0.803421 0.465332 +v -2.033358 169.058197 18.229597 1.000000 1.000000 1.000000 +vn -0.550038 0.650807 0.523362 +v -3.401654 168.254486 18.097397 1.000000 1.000000 1.000000 +vn -0.679893 0.576501 0.453202 +v -4.000666 167.704727 18.033798 1.000000 1.000000 1.000000 +vn -0.652215 0.228506 0.722773 +v -4.930602 165.889404 18.222397 1.000000 1.000000 1.000000 +vn -0.511068 0.845446 0.155019 +v -2.817562 168.848907 17.694199 1.000000 1.000000 1.000000 +vn -0.621257 0.767112 0.159932 +v -3.491532 168.385651 17.629200 1.000000 1.000000 1.000000 +vn -0.725101 0.440044 0.529707 +v -4.751256 166.732178 17.942799 1.000000 1.000000 1.000000 +vn -0.766304 0.611678 0.196540 +v -4.383680 167.509384 17.534599 1.000000 1.000000 1.000000 +vn -0.601353 0.775598 -0.191892 +v -3.483910 168.374481 16.813599 1.000000 1.000000 1.000000 +vn -0.722364 0.691498 -0.004449 +v -4.130548 167.848450 17.155399 1.000000 1.000000 1.000000 +vn -0.838124 0.507294 0.200499 +v -4.876798 166.824265 17.474598 1.000000 1.000000 1.000000 +vn -0.843550 0.530938 -0.080796 +v -4.905496 166.845200 17.064598 1.000000 1.000000 1.000000 +vn -0.830792 0.314286 0.459357 +v -5.142908 166.002426 17.884598 1.000000 1.000000 1.000000 +vn -0.903895 0.400742 0.149600 +v -5.278788 166.074982 17.416397 1.000000 1.000000 1.000000 +vn -0.695815 0.674249 -0.247447 +v -4.097420 167.812164 16.750000 1.000000 1.000000 1.000000 +vn -0.634381 0.277877 -0.721349 +v -5.325858 165.833588 16.327400 1.000000 1.000000 1.000000 +vn -0.486937 0.392306 -0.780377 +v -4.275068 167.403336 16.326797 1.000000 1.000000 1.000000 +vn -0.328254 0.504471 -0.798598 +v -3.104632 168.441467 16.326797 1.000000 1.000000 1.000000 +vn -0.459126 0.866936 -0.193972 +v -2.811420 168.837738 16.878597 1.000000 1.000000 1.000000 +vn -0.177473 0.573042 -0.800079 +v -1.746108 169.060989 16.330997 1.000000 1.000000 1.000000 +vn -0.386429 0.911794 0.138941 +v -2.087058 169.211685 17.761398 1.000000 1.000000 1.000000 +vn -0.234592 0.950266 -0.204843 +v -1.308866 169.453079 17.015198 1.000000 1.000000 1.000000 +vn -0.042781 0.863410 -0.502686 +v -0.478650 169.448898 16.695000 1.000000 1.000000 1.000000 +vn 0.033255 0.419414 -0.907186 +v -0.029486 169.132156 16.326797 1.000000 1.000000 1.000000 +vn -0.075452 0.980416 -0.181910 +v -0.489720 169.592621 17.087997 1.000000 1.000000 1.000000 +vn -0.250643 0.955283 0.156883 +v -1.311724 169.465637 17.830597 1.000000 1.000000 1.000000 +vn 0.116437 0.867663 -0.483325 +v 0.308926 169.462845 16.767998 1.000000 1.000000 1.000000 +vn 0.100318 0.976827 -0.189067 +v 0.316086 169.606567 17.161198 1.000000 1.000000 1.000000 +vn 0.042064 0.986439 0.158650 +v 0.316784 169.620514 17.976597 1.000000 1.000000 1.000000 +vn -0.105670 0.981706 0.158390 +v -0.490790 169.606567 17.903599 1.000000 1.000000 1.000000 +vn -0.123464 0.874056 0.469875 +v -0.478168 169.441910 18.371799 1.000000 1.000000 1.000000 +vn 0.015800 0.845241 0.534152 +v 0.308612 169.455872 18.445000 1.000000 1.000000 1.000000 +vn 0.188353 0.971973 0.140681 +v 1.105114 169.515869 18.050598 1.000000 1.000000 1.000000 +vn 0.107402 0.839901 0.532006 +v 1.076648 169.354019 18.518997 1.000000 1.000000 1.000000 +vn 0.331975 0.924163 -0.188983 +v 1.876916 169.280060 17.312000 1.000000 1.000000 1.000000 +vn 0.327167 0.931847 0.156917 +v 1.881022 169.292618 18.127399 1.000000 1.000000 1.000000 +vn 0.133052 0.610384 0.780851 +v 1.756896 168.893555 18.933399 1.000000 1.000000 1.000000 +vn 0.262205 0.843801 0.468240 +v 1.832574 169.137741 18.595798 1.000000 1.000000 1.000000 +vn -0.048745 0.407678 0.911824 +v 0.283790 168.957733 18.923199 1.000000 1.000000 1.000000 +vn 0.128764 0.397690 0.908440 +v 2.370858 168.353561 19.154999 1.000000 1.000000 1.000000 +vn 0.194000 0.283968 0.939003 +v 4.064848 166.891251 19.404400 1.000000 1.000000 1.000000 +vn 0.373988 0.511537 0.773604 +v 3.720394 167.636353 19.179199 1.000000 1.000000 1.000000 +vn -0.257852 -0.062115 0.964186 +v 3.880918 166.726593 19.407997 1.000000 1.000000 1.000000 +vn -0.207463 -0.146310 0.967240 +v 2.263558 168.121933 19.158798 1.000000 1.000000 1.000000 +vn 0.451769 0.719611 0.527318 +v 3.260366 168.360535 18.758198 1.000000 1.000000 1.000000 +vn 0.536646 0.395121 0.745581 +v 4.673594 166.386139 19.349998 1.000000 1.000000 1.000000 +vn 0.665670 0.568889 0.482958 +v 4.419754 167.209381 18.925999 1.000000 1.000000 1.000000 +vn 0.592077 0.662217 0.459254 +v 3.880636 167.826126 18.841400 1.000000 1.000000 1.000000 +vn 0.237716 0.217631 0.946640 +v 4.822388 165.561493 19.579597 1.000000 1.000000 1.000000 +vn 0.609308 0.280344 0.741722 +v 5.167368 165.282425 19.483797 1.000000 1.000000 1.000000 +vn 0.294572 0.132647 0.946379 +v 5.261394 163.652679 19.811199 1.000000 1.000000 1.000000 +vn -0.253228 0.103357 0.961869 +v 5.023300 163.634537 19.814999 1.000000 1.000000 1.000000 +vn -0.275747 0.019058 0.961041 +v 4.604174 165.456848 19.583397 1.000000 1.000000 1.000000 +vn 0.676737 0.127106 0.725169 +v 5.484528 163.669418 19.670597 1.000000 1.000000 1.000000 +vn 0.852887 0.218907 0.473987 +v 5.611048 164.534531 19.238998 1.000000 1.000000 1.000000 +vn -0.214046 0.172974 0.961387 +v 4.930486 162.142929 20.007797 1.000000 1.000000 1.000000 +vn -0.698655 0.040713 0.714299 +v 4.777442 163.615005 19.660397 1.000000 1.000000 1.000000 +vn -0.658679 0.228392 0.716923 +v 4.689160 162.197342 19.853201 1.000000 1.000000 1.000000 +vn -0.141620 0.231524 0.962466 +v 4.457826 160.709915 20.211998 1.000000 1.000000 1.000000 +vn 0.323453 0.058858 0.944412 +v 5.164164 162.089905 20.003998 1.000000 1.000000 1.000000 +vn -0.909714 0.125339 0.395868 +v 4.542980 162.922913 19.407799 1.000000 1.000000 1.000000 +vn -0.914010 -0.018316 0.405277 +v 4.542156 163.596863 19.312798 1.000000 1.000000 1.000000 +vn -0.887700 0.221701 0.403531 +v 4.458224 162.248978 19.505600 1.000000 1.000000 1.000000 +vn -0.567676 0.403002 0.717867 +v 4.239636 160.834106 20.057400 1.000000 1.000000 1.000000 +vn -0.844463 0.355960 0.400219 +v 4.284582 161.577805 19.607597 1.000000 1.000000 1.000000 +vn -0.041728 0.196538 0.979608 +v 3.137128 158.979706 20.529198 1.000000 1.000000 1.000000 +vn 0.332181 -0.021430 0.942972 +v 4.669102 160.589920 20.208199 1.000000 1.000000 1.000000 +vn -0.572654 0.569500 0.589692 +v 3.473624 159.675980 20.266197 1.000000 1.000000 1.000000 +vn -0.718940 0.561436 0.409775 +v 3.702912 160.377838 19.812798 1.000000 1.000000 1.000000 +vn -0.774477 0.457569 0.436825 +v 4.030832 160.952698 19.709797 1.000000 1.000000 1.000000 +vn -0.180530 0.632799 0.752977 +v 2.228346 158.653198 20.524799 1.000000 1.000000 1.000000 +vn -0.527741 0.742417 0.412682 +v 2.836630 159.388535 20.026997 1.000000 1.000000 1.000000 +vn -0.576211 0.636796 0.512319 +v 3.302544 159.851776 19.918598 1.000000 1.000000 1.000000 +vn -0.897119 0.434727 0.078680 +v 3.874262 161.042007 18.885399 1.000000 1.000000 1.000000 +vn -0.952431 0.304687 -0.006353 +v 4.118150 161.643402 18.783199 1.000000 1.000000 1.000000 +vn -0.344814 0.813093 0.469024 +v 2.118588 158.879242 20.177200 1.000000 1.000000 1.000000 +vn -0.547195 0.801518 0.241137 +v 2.755016 159.498764 19.633198 1.000000 1.000000 1.000000 +vn -0.784392 0.619209 -0.036182 +v 3.174258 159.984344 19.094398 1.000000 1.000000 1.000000 +vn -0.454697 0.872550 0.178628 +v 2.057640 159.004822 19.783398 1.000000 1.000000 1.000000 +vn -0.095418 0.878101 0.468865 +v 0.930262 158.417374 20.403999 1.000000 1.000000 1.000000 +vn -0.017281 0.662290 0.749049 +v 0.978472 158.166214 20.751598 1.000000 1.000000 1.000000 +vn -0.651527 0.758624 -0.001641 +v 2.726434 159.537842 19.202599 1.000000 1.000000 1.000000 +vn -0.333700 0.942193 0.030276 +v 1.482006 158.784348 19.465199 1.000000 1.000000 1.000000 +vn -0.504657 0.841482 -0.192948 +v 2.060136 159.000626 18.897999 1.000000 1.000000 1.000000 +vn 0.123251 0.881452 0.455908 +v -0.291722 158.323898 20.625198 1.000000 1.000000 1.000000 +vn 0.168921 0.648260 0.742446 +v -0.306798 158.068542 20.972797 1.000000 1.000000 1.000000 +vn 0.105997 0.253898 0.961405 +v 1.028852 157.905304 20.906197 1.000000 1.000000 1.000000 +vn 0.175164 0.217975 0.960106 +v -0.322564 157.802048 21.127399 1.000000 1.000000 1.000000 +vn 0.279419 0.861366 0.424232 +v -0.926454 158.417374 20.740597 1.000000 1.000000 1.000000 +vn 0.361103 0.578066 0.731741 +v -1.629050 158.367157 21.204597 1.000000 1.000000 1.000000 +vn 0.231976 0.163609 0.958863 +v -1.712852 158.115997 21.359200 1.000000 1.000000 1.000000 +vn -0.123491 0.992334 0.004830 +v 0.340036 158.519241 19.684599 1.000000 1.000000 1.000000 +vn 0.092286 0.995607 0.015821 +v -0.280416 158.515060 19.800800 1.000000 1.000000 1.000000 +vn 0.391255 0.817163 0.423277 +v -1.548866 158.607147 20.856998 1.000000 1.000000 1.000000 +vn -0.255271 0.935065 -0.245949 +v 0.904586 158.549942 19.124798 1.000000 1.000000 1.000000 +vn 0.039166 0.971820 -0.232447 +v -0.283696 158.459244 19.345997 1.000000 1.000000 1.000000 +vn 0.344229 0.937542 0.050208 +v -1.488728 158.787140 20.032597 1.000000 1.000000 1.000000 +vn 0.527719 0.741742 0.413922 +v -2.138494 158.890411 20.973198 1.000000 1.000000 1.000000 +vn 0.650761 0.613409 0.447480 +v -2.680330 159.258774 21.088398 1.000000 1.000000 1.000000 +vn 0.511005 0.858908 0.033932 +v -2.055464 159.060638 20.148800 1.000000 1.000000 1.000000 +vn 0.305821 0.923563 -0.231313 +v -1.506160 158.735519 19.577797 1.000000 1.000000 1.000000 +vn 0.533863 0.430592 0.727723 +v -2.819120 159.052261 21.435999 1.000000 1.000000 1.000000 +vn 0.764870 0.564480 0.310381 +v -3.550808 160.157364 21.305199 1.000000 1.000000 1.000000 +vn 0.664160 0.231693 0.710782 +v -4.120144 160.599686 21.768799 1.000000 1.000000 1.000000 +vn 0.283875 -0.016840 0.958713 +v -4.332130 160.464340 21.923397 1.000000 1.000000 1.000000 +vn 0.274203 0.088989 0.957546 +v -2.964154 158.835983 21.590599 1.000000 1.000000 1.000000 +vn 0.828829 0.383818 0.407096 +v -3.917290 160.730850 21.421200 1.000000 1.000000 1.000000 +vn 0.904822 0.248492 0.345758 +v -4.203650 161.350372 21.536400 1.000000 1.000000 1.000000 +vn 0.680222 0.731875 -0.040706 +v -2.989300 159.783417 20.364397 1.000000 1.000000 1.000000 +vn 0.887260 0.459898 0.035550 +v -3.765174 160.828522 20.596798 1.000000 1.000000 1.000000 +vn 0.926600 0.195071 0.321496 +v -4.409300 162.013168 21.652599 1.000000 1.000000 1.000000 +vn 0.964196 0.261356 0.044927 +v -4.238090 162.060593 20.828197 1.000000 1.000000 1.000000 +vn 0.880803 0.424414 -0.209900 +v -3.809270 160.800613 20.141998 1.000000 1.000000 1.000000 +vn 0.680619 0.610710 -0.404712 +v -3.561288 160.149002 19.628799 1.000000 1.000000 1.000000 +vn 0.558493 0.794785 -0.237491 +v -2.606416 159.369003 19.809200 1.000000 1.000000 1.000000 +vn 0.472238 0.743187 -0.473988 +v -2.688234 159.247604 19.411797 1.000000 1.000000 1.000000 +vn 0.203788 0.803051 -0.559981 +v -1.553436 158.593185 19.180399 1.000000 1.000000 1.000000 +vn -0.024675 0.374040 -0.927084 +v -1.708834 158.127151 18.709797 1.000000 1.000000 1.000000 +vn 0.448197 0.572690 -0.686401 +v -3.281802 159.444351 19.177399 1.000000 1.000000 1.000000 +vn -0.027597 0.880999 -0.472312 +v -0.292586 158.308548 18.948595 1.000000 1.000000 1.000000 +vn -0.222662 0.602170 -0.766690 +v 0.373374 158.056000 18.497597 1.000000 1.000000 1.000000 +vn -0.298727 0.850798 -0.432326 +v 0.933012 158.403442 18.727398 1.000000 1.000000 1.000000 +vn -0.488484 0.725988 -0.484072 +v 2.124846 158.866684 18.500599 1.000000 1.000000 1.000000 +vn -0.387262 0.419062 -0.821228 +v 2.235634 158.637848 18.165798 1.000000 1.000000 1.000000 +vn -0.612955 0.746919 -0.257678 +v 2.758376 159.494583 18.747799 1.000000 1.000000 1.000000 +vn -0.634339 0.648626 -0.420592 +v 2.845010 159.377380 18.350401 1.000000 1.000000 1.000000 +vn -0.715324 0.493296 -0.494945 +v 3.484980 159.664810 17.907200 1.000000 1.000000 1.000000 +vn -0.831960 0.507839 -0.223478 +v 3.600750 160.455978 18.533798 1.000000 1.000000 1.000000 +vn -0.685001 0.497325 -0.532393 +v 3.312302 159.842026 18.241997 1.000000 1.000000 1.000000 +vn -0.984478 0.169180 0.046709 +v 4.285058 162.288040 18.681400 1.000000 1.000000 1.000000 +vn -0.967373 0.135091 -0.214334 +v 4.335244 162.276886 18.226597 1.000000 1.000000 1.000000 +vn -0.806286 0.345209 -0.480347 +v 4.042742 160.945724 18.033199 1.000000 1.000000 1.000000 +vn -0.842273 0.012762 -0.538899 +v 4.471396 162.246185 17.828999 1.000000 1.000000 1.000000 +vn -0.968676 -0.075383 -0.236611 +v 4.416858 163.587097 18.033600 1.000000 1.000000 1.000000 +vn -0.996617 -0.061199 0.054856 +v 4.365732 163.582916 18.488400 1.000000 1.000000 1.000000 +vn -0.882851 -0.091202 -0.460713 +v 4.555584 163.598267 17.636200 1.000000 1.000000 1.000000 +vn -0.553718 -0.617100 -0.559092 +v 4.704506 162.193161 17.494198 1.000000 1.000000 1.000000 +vn -0.670334 -0.135479 -0.729588 +v 4.793072 163.616409 17.301399 1.000000 1.000000 1.000000 +vn -0.672583 0.366675 -0.642792 +v 3.907454 160.218750 17.801598 1.000000 1.000000 1.000000 +vn 0.064210 -0.185756 -0.980496 +v 5.147336 162.094086 17.353397 1.000000 1.000000 1.000000 +vn -0.293523 0.009908 -0.955901 +v 4.447346 160.715500 17.562599 1.000000 1.000000 1.000000 +vn 0.188918 -0.240646 -0.952050 +v 4.653896 160.598297 17.557400 1.000000 1.000000 1.000000 +vn -0.022482 -0.252477 -0.967342 +v 2.446110 158.203888 18.024799 1.000000 1.000000 1.000000 +vn 0.093668 -0.286432 -0.953511 +v 3.275120 158.791336 17.874599 1.000000 1.000000 1.000000 +vn -0.102140 -0.227132 -0.968493 +v 1.074124 157.670883 18.251598 1.000000 1.000000 1.000000 +vn 0.749113 0.466257 -0.470568 +v -3.928852 160.723862 19.744598 1.000000 1.000000 1.000000 +vn 0.529094 0.419344 -0.737706 +v -4.133626 160.591324 19.409798 1.000000 1.000000 1.000000 +vn 0.722739 0.277869 -0.632802 +v -4.422330 162.008972 19.975998 1.000000 1.000000 1.000000 +vn 0.706158 0.300263 -0.641236 +v -4.652814 161.944778 19.641197 1.000000 1.000000 1.000000 +vn 0.917922 0.128133 -0.375500 +v -4.539722 162.695480 20.091599 1.000000 1.000000 1.000000 +vn 0.195102 0.162752 -0.967185 +v -4.993932 162.639664 19.620998 1.000000 1.000000 1.000000 +vn 0.143683 0.253390 -0.956634 +v -4.321944 160.469925 19.273998 1.000000 1.000000 1.000000 +vn 0.279207 0.073643 -0.957403 +v -4.783160 164.918243 19.967999 1.000000 1.000000 1.000000 +vn 0.773657 0.012960 -0.633473 +v -4.736758 164.127090 19.987400 1.000000 1.000000 1.000000 +vn -0.021392 0.245635 -0.969126 +v -2.957190 158.847153 18.941200 1.000000 1.000000 1.000000 +vn -0.326958 -0.000835 -0.945039 +v -4.522624 160.341553 19.268997 1.000000 1.000000 1.000000 +vn -0.298863 -0.129521 -0.945466 +v -3.094474 158.642029 18.935999 1.000000 1.000000 1.000000 +vn -0.548263 -0.311556 -0.776106 +v -4.291560 159.512726 19.303999 1.000000 1.000000 1.000000 +vn -0.509861 -0.452172 -0.731835 +v -3.239456 158.425766 19.086998 1.000000 1.000000 1.000000 +vn -0.297504 0.122331 -0.946851 +v -5.225808 162.611755 19.615799 1.000000 1.000000 1.000000 +vn -0.652401 -0.220895 -0.724968 +v -4.734518 160.204819 19.419998 1.000000 1.000000 1.000000 +vn -0.689764 0.046529 -0.722537 +v -5.470662 162.582458 19.766800 1.000000 1.000000 1.000000 +vn -0.218661 0.213430 -0.952174 +v -5.005250 164.996384 19.962997 1.000000 1.000000 1.000000 +vn -0.626314 -0.064027 -0.776937 +v -5.329180 161.755020 19.651199 1.000000 1.000000 1.000000 +vn -0.600826 0.179131 -0.779051 +v -5.425342 164.255463 19.997597 1.000000 1.000000 1.000000 +vn -0.153348 0.269514 -0.950708 +v -4.357660 166.437759 20.194395 1.000000 1.000000 1.000000 +vn -0.620021 0.300498 -0.724758 +v -5.239752 165.077316 20.113998 1.000000 1.000000 1.000000 +vn -0.875872 0.085277 -0.474949 +v -5.739280 163.428024 20.226801 1.000000 1.000000 1.000000 +vn -0.895097 -0.035006 -0.444496 +v -5.706282 162.553162 20.111397 1.000000 1.000000 1.000000 +vn -0.872759 0.197656 -0.446345 +v -5.659032 164.298721 20.341999 1.000000 1.000000 1.000000 +vn -0.838260 0.310134 -0.448484 +v -5.465446 165.156845 20.458599 1.000000 1.000000 1.000000 +vn -0.771242 0.415981 -0.481815 +v -5.162078 165.974503 20.574799 1.000000 1.000000 1.000000 +vn -0.504606 0.455666 -0.733308 +v -4.561816 166.587067 20.345398 1.000000 1.000000 1.000000 +vn -0.884439 0.434708 -0.169696 +v -5.281570 166.037308 20.967800 1.000000 1.000000 1.000000 +vn -0.726812 0.541864 -0.422052 +v -4.758310 166.730774 20.689800 1.000000 1.000000 1.000000 +vn -0.938002 0.301675 -0.170720 +v -5.591968 165.201492 20.851597 1.000000 1.000000 1.000000 +vn -0.363330 0.501937 -0.784889 +v -3.588094 167.773102 20.564198 1.000000 1.000000 1.000000 +vn -0.017462 0.306129 -0.951830 +v -2.831146 168.050766 20.528999 1.000000 1.000000 1.000000 +vn -0.564855 0.678829 -0.469181 +v -3.742616 167.968445 20.908600 1.000000 1.000000 1.000000 +vn -0.267375 0.612258 -0.744077 +v -2.963782 168.275421 20.680000 1.000000 1.000000 1.000000 +vn 0.120483 0.285844 -0.950672 +v -0.766560 168.886581 20.875000 1.000000 1.000000 1.000000 +vn 0.254974 -0.079436 -0.963679 +v -2.705538 167.837280 20.533997 1.000000 1.000000 1.000000 +vn 0.291393 -0.007035 -0.956577 +v -4.164292 166.295441 20.199398 1.000000 1.000000 1.000000 +vn 0.620139 -0.396088 -0.677157 +v -3.617384 166.677765 20.437399 1.000000 1.000000 1.000000 +vn 0.676571 -0.178134 -0.714507 +v -4.320812 165.530792 20.220200 1.000000 1.000000 1.000000 +vn 0.197498 -0.218224 -0.955705 +v -0.732564 168.636810 20.880199 1.000000 1.000000 1.000000 +vn -0.096558 0.599682 -0.794391 +v -1.554080 168.971695 20.911400 1.000000 1.000000 1.000000 +vn 0.026722 0.663957 -0.747293 +v -0.802452 169.151688 21.025997 1.000000 1.000000 1.000000 +vn -0.321027 0.805724 -0.497746 +v -2.382972 168.908905 21.139797 1.000000 1.000000 1.000000 +vn -0.205242 0.857579 -0.471630 +v -1.621002 169.217270 21.255798 1.000000 1.000000 1.000000 +vn 0.065670 0.863306 -0.500390 +v -0.031842 169.471222 21.486000 1.000000 1.000000 1.000000 +vn 0.179059 0.580962 -0.793990 +v 0.741950 169.158676 21.256798 1.000000 1.000000 1.000000 +vn -0.073179 0.878830 -0.471490 +v -0.836988 169.405640 21.370598 1.000000 1.000000 1.000000 +vn -0.276039 0.943783 -0.181868 +v -1.658520 169.356796 21.648998 1.000000 1.000000 1.000000 +vn -0.412511 0.892959 -0.180162 +v -2.438128 169.040070 21.532799 1.000000 1.000000 1.000000 +vn -0.129360 0.974846 -0.181496 +v -0.856360 169.547958 21.763599 1.000000 1.000000 1.000000 +vn 0.020016 0.983211 -0.181374 +v -0.032570 169.614944 21.878998 1.000000 1.000000 1.000000 +vn 0.194676 0.860388 -0.470992 +v 0.773934 169.414017 21.601200 1.000000 1.000000 1.000000 +vn -0.026944 0.986979 0.158576 +v -0.032638 169.628891 22.694599 1.000000 1.000000 1.000000 +vn -0.176409 0.971519 0.158211 +v -0.858226 169.561905 22.579197 1.000000 1.000000 1.000000 +vn 0.168278 0.968967 -0.181067 +v 0.791870 169.556335 21.994400 1.000000 1.000000 1.000000 +vn 0.122572 0.979701 0.158624 +v 0.793598 169.570297 22.809799 1.000000 1.000000 1.000000 +vn 0.321379 0.822728 -0.468866 +v 1.572066 169.232620 21.717800 1.000000 1.000000 1.000000 +vn 0.310861 0.597804 -0.738915 +v 1.507112 168.985641 21.373199 1.000000 1.000000 1.000000 +vn 0.225323 0.212583 -0.950809 +v 1.439636 168.728897 21.222198 1.000000 1.000000 1.000000 +vn 0.438353 0.750665 -0.494317 +v 2.336560 168.932617 21.834000 1.000000 1.000000 1.000000 +vn 0.475996 0.484625 -0.733871 +v 2.921796 168.303314 21.604597 1.000000 1.000000 1.000000 +vn 0.289271 0.149450 -0.945509 +v 2.790988 168.077286 21.453598 1.000000 1.000000 1.000000 +vn 0.312523 0.932545 -0.180802 +v 1.608476 169.372162 22.110798 1.000000 1.000000 1.000000 +vn 0.409402 0.898857 0.156349 +v 2.395900 169.076340 23.042599 1.000000 1.000000 1.000000 +vn 0.459913 0.870337 -0.176053 +v 2.390660 169.063782 22.226997 1.000000 1.000000 1.000000 +vn 0.269523 0.949942 0.158009 +v 1.611990 169.384705 22.926399 1.000000 1.000000 1.000000 +vn 0.569034 0.702157 -0.427991 +v 3.047686 168.520996 21.948997 1.000000 1.000000 1.000000 +vn 0.658624 0.721552 -0.213490 +v 3.713288 168.180527 22.444395 1.000000 1.000000 1.000000 +vn 0.530331 0.830666 0.169536 +v 3.125076 168.654953 23.157799 1.000000 1.000000 1.000000 +vn 0.337964 0.813823 0.472729 +v 2.334190 168.927048 23.510799 1.000000 1.000000 1.000000 +vn 0.188174 0.846550 0.497939 +v 1.570470 169.227036 23.394600 1.000000 1.000000 1.000000 +vn 0.063572 0.880714 0.469362 +v 0.773158 169.407028 23.278198 1.000000 1.000000 1.000000 +vn 0.193096 0.625539 0.755920 +v 2.237810 168.692627 23.848598 1.000000 1.000000 1.000000 +vn -0.032566 0.624453 0.780383 +v 0.741214 169.153076 23.615999 1.000000 1.000000 1.000000 +vn 0.521430 0.713723 0.467665 +v 3.625572 168.064728 23.728201 1.000000 1.000000 1.000000 +vn 0.641356 0.751690 0.153704 +v 3.721400 168.191696 23.259998 1.000000 1.000000 1.000000 +vn 0.739240 0.655931 0.152576 +v 4.331008 167.570786 23.376400 1.000000 1.000000 1.000000 +vn 0.342486 0.540841 0.768241 +v 3.475864 167.865189 24.065998 1.000000 1.000000 1.000000 +vn 0.611862 0.589490 0.527377 +v 4.219500 167.459152 23.844801 1.000000 1.000000 1.000000 +vn 0.764337 0.620914 -0.173942 +v 4.321558 167.561005 22.560999 1.000000 1.000000 1.000000 +vn 0.823534 0.546839 0.150860 +v 4.849554 166.864731 23.492397 1.000000 1.000000 1.000000 +vn 0.670770 0.527285 0.521573 +v 4.724682 166.772644 23.960598 1.000000 1.000000 1.000000 +vn 0.890029 0.430579 0.149833 +v 5.268514 166.093109 23.607599 1.000000 1.000000 1.000000 +vn 0.843245 0.509156 -0.172330 +v 4.838958 166.857758 22.676800 1.000000 1.000000 1.000000 +vn 0.704532 0.538090 -0.462703 +v 4.223762 167.463333 22.167797 1.000000 1.000000 1.000000 +vn 0.784001 0.426686 -0.450867 +v 4.729458 166.775436 22.283798 1.000000 1.000000 1.000000 +vn 0.636152 0.261593 -0.725865 +v 4.534122 166.630325 21.939198 1.000000 1.000000 1.000000 +vn 0.525460 0.346096 -0.777245 +v 4.049294 167.288910 21.823399 1.000000 1.000000 1.000000 +vn 0.822739 0.308396 -0.477485 +v 5.138040 166.021957 22.398998 1.000000 1.000000 1.000000 +vn 0.904283 0.391188 -0.171010 +v 5.257016 166.086136 22.792000 1.000000 1.000000 1.000000 +vn 0.870847 0.206334 -0.446152 +v 5.448516 165.208481 22.515198 1.000000 1.000000 1.000000 +vn 0.948107 0.268901 -0.169661 +v 5.574664 165.253128 22.908199 1.000000 1.000000 1.000000 +vn 0.891056 0.091272 -0.444622 +v 5.647986 164.365692 22.629799 1.000000 1.000000 1.000000 +vn 0.975303 0.142102 -0.169087 +v 5.778756 164.390808 23.022999 1.000000 1.000000 1.000000 +vn 0.971984 0.182910 0.147619 +v 5.791398 164.393600 23.838398 1.000000 1.000000 1.000000 +vn 0.939331 0.309150 0.148605 +v 5.586856 165.257309 23.723799 1.000000 1.000000 1.000000 +vn 0.879673 -0.029907 -0.474637 +v 5.735946 163.494995 22.745197 1.000000 1.000000 1.000000 +vn 0.985509 0.013830 -0.169060 +v 5.868762 163.500595 23.138199 1.000000 1.000000 1.000000 +vn 0.987595 0.054471 0.147272 +v 5.881598 163.501984 23.953798 1.000000 1.000000 1.000000 +vn 0.876012 0.092834 0.473270 +v 5.730152 163.494995 24.421997 1.000000 1.000000 1.000000 +vn 0.872122 0.205456 0.444062 +v 5.642282 164.364288 24.306799 1.000000 1.000000 1.000000 +vn 0.654855 0.210456 0.725860 +v 5.409312 164.318253 24.644398 1.000000 1.000000 1.000000 +vn 0.819816 0.317137 0.476787 +v 5.443006 165.205688 24.191998 1.000000 1.000000 1.000000 +vn 0.533075 0.357750 0.766711 +v 4.920920 165.904755 24.413601 1.000000 1.000000 1.000000 +vn 0.785357 0.425796 0.449345 +v 5.132864 166.019165 24.075798 1.000000 1.000000 1.000000 +vn 0.271789 0.357472 0.893502 +v 4.345300 166.489395 24.438999 1.000000 1.000000 1.000000 +vn 0.059235 0.339575 0.938712 +v 2.800104 168.092636 24.104198 1.000000 1.000000 1.000000 +vn -0.045572 0.352322 0.934769 +v 1.444334 168.747040 23.872999 1.000000 1.000000 1.000000 +vn -0.189850 0.263695 0.945739 +v -0.769066 168.904724 23.525799 1.000000 1.000000 1.000000 +vn -0.074309 0.863614 0.498647 +v -0.031814 169.464233 23.162800 1.000000 1.000000 1.000000 +vn -0.210833 0.631946 0.745784 +v -0.801648 169.144714 23.385197 1.000000 1.000000 1.000000 +vn -0.369781 0.514741 0.773501 +v -2.282292 168.670288 23.154400 1.000000 1.000000 1.000000 +vn -0.309889 0.198997 0.929715 +v -2.840390 168.066116 23.179798 1.000000 1.000000 1.000000 +vn -0.203177 0.859721 0.468615 +v -0.836144 169.398666 23.047600 1.000000 1.000000 1.000000 +vn -0.329817 0.803963 0.494837 +v -1.619368 169.211685 22.932800 1.000000 1.000000 1.000000 +vn -0.448391 0.765049 0.462218 +v -2.380566 168.903320 22.816595 1.000000 1.000000 1.000000 +vn -0.549760 0.677698 0.488353 +v -3.088306 168.487503 22.701397 1.000000 1.000000 1.000000 +vn -0.514861 0.388822 0.764026 +v -3.584502 167.768906 22.923397 1.000000 1.000000 1.000000 +vn -0.572469 0.318311 0.755617 +v -4.139084 167.171707 22.806799 1.000000 1.000000 1.000000 +vn -0.650823 0.607417 0.455493 +v -3.738844 167.964264 22.585598 1.000000 1.000000 1.000000 +vn -0.455514 0.876513 0.155669 +v -2.443446 169.052612 22.348400 1.000000 1.000000 1.000000 +vn -0.578130 0.801270 0.154055 +v -3.169906 168.625641 22.233200 1.000000 1.000000 1.000000 +vn -0.321444 0.933771 0.157304 +v -1.662138 169.369370 22.464600 1.000000 1.000000 1.000000 +vn -0.539066 0.823187 -0.178245 +v -3.162980 168.614487 21.417599 1.000000 1.000000 1.000000 +vn -0.687960 0.709645 0.152035 +v -3.837634 168.088440 22.117199 1.000000 1.000000 1.000000 +vn -0.653207 0.736318 -0.176510 +v -3.829252 168.077286 21.301800 1.000000 1.000000 1.000000 +vn -0.448797 0.762449 -0.466104 +v -3.091434 168.493088 21.024597 1.000000 1.000000 1.000000 +vn -0.778756 0.608847 0.151143 +v -4.431380 167.449371 22.000797 1.000000 1.000000 1.000000 +vn -0.749574 0.626658 -0.213161 +v -4.421712 167.439621 21.185200 1.000000 1.000000 1.000000 +vn -0.738027 0.496082 0.457405 +v -4.317310 167.340546 22.468998 1.000000 1.000000 1.000000 +vn -0.850359 0.500106 0.163659 +v -4.879090 166.818695 21.898598 1.000000 1.000000 1.000000 +vn -0.909248 0.388798 0.148673 +v -5.293118 166.044281 21.783398 1.000000 1.000000 1.000000 +vn -0.829859 0.325411 0.453257 +v -5.156864 165.971725 22.251598 1.000000 1.000000 1.000000 +vn -0.953257 0.263430 0.148003 +v -5.604198 165.205688 21.667198 1.000000 1.000000 1.000000 +vn -0.859360 0.190168 0.474697 +v -5.459936 165.154053 22.135399 1.000000 1.000000 1.000000 +vn -0.969777 0.175528 -0.169476 +v -5.790034 164.322433 20.735197 1.000000 1.000000 1.000000 +vn -0.979716 0.135989 0.147188 +v -5.802690 164.325226 21.550598 1.000000 1.000000 1.000000 +vn -0.892930 0.082980 0.442483 +v -5.653316 164.297318 22.018997 1.000000 1.000000 1.000000 +vn -0.648702 0.190563 0.736799 +v -4.943978 165.858704 22.589397 1.000000 1.000000 1.000000 +vn -0.984407 0.048408 -0.169113 +v -5.872136 163.432220 20.619797 1.000000 1.000000 1.000000 +vn -0.989076 0.007994 0.147190 +v -5.884986 163.432220 21.435398 1.000000 1.000000 1.000000 +vn 0.272637 0.182316 0.944685 +v 5.189218 164.274994 24.784998 1.000000 1.000000 1.000000 +vn 0.621363 0.103194 -0.776697 +v 5.223478 165.127548 22.170597 1.000000 1.000000 1.000000 +vn 0.305731 -0.103550 -0.946470 +v 5.172312 164.270813 22.134197 1.000000 1.000000 1.000000 +vn 0.325998 0.021026 -0.945137 +v 4.331138 166.478226 21.788200 1.000000 1.000000 1.000000 +vn 0.691472 -0.003085 -0.722397 +v 5.414708 164.318253 22.285198 1.000000 1.000000 1.000000 +vn -0.230087 -0.190547 -0.954333 +v 4.942756 164.226166 22.139397 1.000000 1.000000 1.000000 +vn -0.076939 -0.239289 -0.967895 +v 4.138904 166.335907 21.793400 1.000000 1.000000 1.000000 +vn 0.002214 -0.271473 -0.962444 +v 2.667106 167.862396 21.458599 1.000000 1.000000 1.000000 +vn 0.089522 -0.257918 -0.962011 +v 1.375712 168.486115 21.227200 1.000000 1.000000 1.000000 +vn -0.237586 -0.203635 -0.949782 +v -1.788144 157.889954 18.704800 1.000000 1.000000 1.000000 +vn -0.070805 0.148284 -0.986407 +v -0.321808 157.814590 18.477997 1.000000 1.000000 1.000000 +vn -0.146965 -0.237599 -0.960181 +v -0.336718 157.562042 18.473000 1.000000 1.000000 1.000000 +vn 0.904388 0.009911 0.426595 +v -4.526358 162.696869 21.768200 1.000000 1.000000 1.000000 +vn 0.930899 -0.111678 0.347787 +v -4.552520 163.390350 21.883400 1.000000 1.000000 1.000000 +vn 0.996252 0.085288 0.014399 +v -4.350592 162.717804 20.943798 1.000000 1.000000 1.000000 +vn 0.967414 0.063608 -0.245081 +v -4.401524 162.712219 20.488998 1.000000 1.000000 1.000000 +vn 0.990483 -0.137342 0.008950 +v -4.314554 164.048950 21.174599 1.000000 1.000000 1.000000 +vn 0.905401 -0.042662 -0.422409 +v -4.502114 164.083832 20.322195 1.000000 1.000000 1.000000 +vn 0.875571 -0.201557 -0.439034 +v -4.348120 164.766159 20.438795 1.000000 1.000000 1.000000 +vn 0.706146 -0.041120 0.706871 +v -4.760756 162.668976 22.115799 1.000000 1.000000 1.000000 +vn 0.306107 -0.189601 0.932926 +v 3.285832 158.777374 20.525398 1.000000 1.000000 1.000000 +vn 0.776584 0.611428 0.151898 +v 4.536568 167.314026 18.457798 1.000000 1.000000 1.000000 +vn 0.685149 0.712090 0.153290 +v 3.983208 167.947510 18.373199 1.000000 1.000000 1.000000 +vn 0.859399 0.498291 0.114627 +v 5.003730 166.606598 18.543999 1.000000 1.000000 1.000000 +vn 0.804912 0.568494 -0.170091 +v 4.526654 167.305664 17.642197 1.000000 1.000000 1.000000 +vn 0.705723 0.686392 -0.175560 +v 3.974518 167.936356 17.557598 1.000000 1.000000 1.000000 +vn 0.577897 0.801271 0.154919 +v 3.346536 168.495880 18.289799 1.000000 1.000000 1.000000 +vn 0.601807 0.778778 -0.177009 +v 3.339236 168.484726 17.474400 1.000000 1.000000 1.000000 +vn 0.374319 0.759957 0.531366 +v 2.577872 168.798676 18.676800 1.000000 1.000000 1.000000 +vn 0.458568 0.874898 0.155787 +v 2.646006 168.945175 18.208599 1.000000 1.000000 1.000000 +vn 0.485120 0.856076 -0.178306 +v 2.640224 168.932617 17.392998 1.000000 1.000000 1.000000 +vn 0.658652 0.597297 -0.457618 +v 3.884574 167.830307 17.164600 1.000000 1.000000 1.000000 +vn 0.559756 0.668430 -0.489770 +v 3.263662 168.366119 17.081200 1.000000 1.000000 1.000000 +vn 0.462662 0.755013 -0.464650 +v 2.580486 168.804245 16.999798 1.000000 1.000000 1.000000 +vn 0.323618 0.809821 -0.489348 +v 1.834442 169.143311 16.918800 1.000000 1.000000 1.000000 +vn 0.389400 0.540270 -0.745973 +v 2.473882 168.575424 16.655399 1.000000 1.000000 1.000000 +vn 0.221652 0.661668 -0.716286 +v 1.033202 169.108429 16.497597 1.000000 1.000000 1.000000 +vn 0.237448 0.191796 -0.952278 +v 2.363120 168.336807 16.504398 1.000000 1.000000 1.000000 +vn 0.137683 0.227346 -0.964032 +v 0.986928 168.846115 16.346600 1.000000 1.000000 1.000000 +vn 0.475909 0.394828 -0.785890 +v 3.724116 167.641937 16.820000 1.000000 1.000000 1.000000 +vn 0.290798 0.078990 -0.953518 +v 4.051600 166.880081 16.753597 1.000000 1.000000 1.000000 +vn -0.017231 -0.265940 -0.963836 +v 2.258228 168.110779 16.509399 1.000000 1.000000 1.000000 +vn 0.029533 -0.239926 -0.970342 +v 0.943100 168.597748 16.351597 1.000000 1.000000 1.000000 +vn -0.112412 -0.231354 -0.966353 +v 3.871778 166.718231 16.758598 1.000000 1.000000 1.000000 +vn 0.595388 0.340432 -0.727749 +v 4.241490 167.050323 16.904598 1.000000 1.000000 1.000000 +vn 0.314471 0.002798 -0.949263 +v 4.806682 165.553131 16.928799 1.000000 1.000000 1.000000 +vn 0.664180 0.178088 -0.726051 +v 5.031926 165.661957 17.079800 1.000000 1.000000 1.000000 +vn 0.735616 0.502825 -0.453912 +v 4.424236 167.213562 17.249199 1.000000 1.000000 1.000000 +vn 0.821095 0.404618 -0.402601 +v 4.879810 166.524277 17.335400 1.000000 1.000000 1.000000 +vn 0.272374 -0.091776 -0.957805 +v 5.244244 163.651276 17.160397 1.000000 1.000000 1.000000 +vn 0.636207 0.060210 -0.769166 +v 5.384734 164.482895 17.217598 1.000000 1.000000 1.000000 +vn -0.243491 -0.115623 -0.962987 +v 5.011494 163.633148 17.165600 1.000000 1.000000 1.000000 +vn -0.720414 -0.355654 -0.595410 +v 4.515892 165.025681 17.114597 1.000000 1.000000 1.000000 +vn 0.690837 -0.049798 -0.721294 +v 5.490012 163.669418 17.311398 1.000000 1.000000 1.000000 +vn 0.853650 0.306710 -0.420964 +v 5.248712 165.765213 17.424400 1.000000 1.000000 1.000000 +vn 0.883268 0.132347 -0.449801 +v 5.616726 164.535919 17.562199 1.000000 1.000000 1.000000 +vn 0.921649 0.317475 -0.223097 +v 5.520294 165.420563 17.862198 1.000000 1.000000 1.000000 +vn 0.895545 0.009540 -0.444869 +v 5.726534 163.687561 17.655998 1.000000 1.000000 1.000000 +vn 0.942191 0.334799 -0.013652 +v 5.564944 165.438705 18.267799 1.000000 1.000000 1.000000 +vn 0.970781 0.162447 -0.176624 +v 5.746762 164.566620 17.955200 1.000000 1.000000 1.000000 +vn 0.966907 0.203291 0.154151 +v 5.759340 164.569412 18.770798 1.000000 1.000000 1.000000 +vn 0.897890 0.402658 0.177930 +v 5.382006 165.829407 18.632999 1.000000 1.000000 1.000000 +vn 0.753683 0.474852 0.454397 +v 4.874880 166.521484 19.012398 1.000000 1.000000 1.000000 +vn 0.834132 0.335484 0.437806 +v 5.389924 165.368942 19.146000 1.000000 1.000000 1.000000 +vn 0.985870 0.080011 0.147170 +v 5.871930 163.698730 18.864597 1.000000 1.000000 1.000000 +vn 0.890102 0.106536 0.443134 +v 5.720742 163.687561 19.333000 1.000000 1.000000 1.000000 +vn 0.985748 0.028183 -0.165854 +v 5.859120 163.698730 18.049198 1.000000 1.000000 1.000000 +vn -0.952898 0.297756 -0.057686 +v -5.615360 165.289398 16.950199 1.000000 1.000000 1.000000 +vn -0.702814 0.002025 -0.711371 +v -5.872432 163.388962 16.326797 1.000000 1.000000 1.000000 +vn -0.978329 0.185786 -0.091416 +v -5.818152 164.449417 16.896000 1.000000 1.000000 1.000000 +vn -0.933967 0.274802 0.228451 +v -5.582504 165.278244 17.360197 1.000000 1.000000 1.000000 +vn -0.830103 0.148289 0.537531 +v -5.635202 164.411743 17.774399 1.000000 1.000000 1.000000 +vn -0.968693 0.151444 0.196719 +v -5.784112 164.442429 17.306000 1.000000 1.000000 1.000000 +vn -0.999296 0.036580 0.008296 +v -5.914894 163.580124 16.843399 1.000000 1.000000 1.000000 +vn -0.630848 -0.049880 0.774302 +v -5.492394 163.556396 18.059399 1.000000 1.000000 1.000000 +vn -0.307964 0.077118 0.948268 +v -4.730038 165.781952 18.362997 1.000000 1.000000 1.000000 +vn -0.420786 0.026360 0.906777 +v -5.182806 164.318253 18.252598 1.000000 1.000000 1.000000 +vn 0.630173 0.261474 -0.731105 +v -4.658672 161.967117 24.793598 1.000000 1.000000 1.000000 +vn 0.814808 0.396415 -0.423017 +v -4.227354 161.374100 25.013599 1.000000 1.000000 1.000000 +vn 0.605822 0.435415 -0.665879 +v -4.145482 160.615036 24.562798 1.000000 1.000000 1.000000 +vn 0.765682 0.107373 -0.634194 +v -4.803026 163.419647 25.024199 1.000000 1.000000 1.000000 +vn 0.849984 0.248707 -0.464405 +v -4.427904 162.031296 25.128399 1.000000 1.000000 1.000000 +vn 0.695692 0.600929 -0.393569 +v -3.578102 160.171326 24.782398 1.000000 1.000000 1.000000 +vn 0.368213 0.622140 -0.690913 +v -2.777676 158.999237 24.214998 1.000000 1.000000 1.000000 +vn 0.215776 0.204872 -0.954708 +v -4.870926 161.908508 24.657799 1.000000 1.000000 1.000000 +vn 0.059137 0.243609 -0.968069 +v -3.936100 159.862946 24.311798 1.000000 1.000000 1.000000 +vn -0.022170 0.270678 -0.962415 +v -2.371552 158.448090 23.976999 1.000000 1.000000 1.000000 +vn 0.126031 0.661686 -0.739113 +v -1.652700 158.357376 23.997799 1.000000 1.000000 1.000000 +vn -0.108523 0.251541 -0.961743 +v -1.043924 157.922043 23.745598 1.000000 1.000000 1.000000 +vn -0.324165 -0.041811 -0.945076 +v -4.118844 159.706680 24.306599 1.000000 1.000000 1.000000 +vn -0.277508 -0.167307 -0.946043 +v -2.481646 158.226227 23.971998 1.000000 1.000000 1.000000 +vn -0.094103 0.740043 -0.665943 +v -0.322476 158.053207 23.764999 1.000000 1.000000 1.000000 +vn -0.209124 -0.226898 -0.951202 +v -1.092380 157.675064 23.740599 1.000000 1.000000 1.000000 +vn -0.212778 0.205070 -0.955339 +v 1.068920 157.927628 23.398598 1.000000 1.000000 1.000000 +vn -0.098915 -0.293460 -0.950840 +v 1.118582 157.680649 23.393398 1.000000 1.000000 1.000000 +vn -0.135538 -0.592051 -0.794421 +v -0.369272 157.298325 23.775198 1.000000 1.000000 1.000000 +vn 0.022017 -0.664441 -0.747016 +v 1.171026 157.419724 23.544399 1.000000 1.000000 1.000000 +vn -0.268616 0.605837 -0.748870 +v 1.022310 158.159241 23.534397 1.000000 1.000000 1.000000 +vn -0.455402 0.580288 -0.675185 +v 2.287146 158.669937 23.303600 1.000000 1.000000 1.000000 +vn -0.260243 0.063151 -0.963476 +v 2.986982 158.870865 23.052599 1.000000 1.000000 1.000000 +vn -0.253239 0.834428 -0.489490 +v 0.971624 158.411804 23.869198 1.000000 1.000000 1.000000 +vn -0.417955 0.794095 -0.441278 +v 1.584490 158.607147 23.754398 1.000000 1.000000 1.000000 +vn -0.629057 0.667877 -0.397778 +v 2.715220 159.268539 23.523197 1.000000 1.000000 1.000000 +vn -0.646144 0.354692 -0.675790 +v 3.823626 160.095978 22.955799 1.000000 1.000000 1.000000 +vn -0.290902 -0.011596 -0.956682 +v 4.345286 160.517365 22.717800 1.000000 1.000000 1.000000 +vn -0.820718 0.345484 -0.455042 +v 3.949966 160.765732 23.188400 1.000000 1.000000 1.000000 +vn -0.687218 0.134847 -0.713827 +v 4.453204 161.293167 22.738598 1.000000 1.000000 1.000000 +vn -0.644439 0.517507 -0.562925 +v 3.205802 159.723419 23.407200 1.000000 1.000000 1.000000 +vn -0.873741 0.426475 -0.233870 +v 3.829690 160.841080 23.585999 1.000000 1.000000 1.000000 +vn -0.951542 0.216701 -0.218195 +v 4.297406 162.092697 23.354597 1.000000 1.000000 1.000000 +vn -0.887028 0.145758 -0.438105 +v 4.432372 162.056412 22.957199 1.000000 1.000000 1.000000 +vn -0.771332 -0.058646 -0.633725 +v 4.779850 162.723389 22.505798 1.000000 1.000000 1.000000 +vn -0.906298 -0.014444 -0.422392 +v 4.543018 162.748505 22.840599 1.000000 1.000000 1.000000 +vn -0.931921 0.361198 0.032552 +v 4.056158 161.467590 23.925598 1.000000 1.000000 1.000000 +vn -0.976274 0.216468 0.005543 +v 4.247658 162.106644 23.809399 1.000000 1.000000 1.000000 +vn -0.997169 0.074662 0.008924 +v 4.353694 162.769424 23.692999 1.000000 1.000000 1.000000 +vn -0.864687 -0.194038 -0.463320 +v 4.493102 164.136856 22.609997 1.000000 1.000000 1.000000 +vn -0.959457 -0.171356 -0.223786 +v 4.356282 164.110352 23.007397 1.000000 1.000000 1.000000 +vn -0.647020 -0.220621 -0.729857 +v 4.727334 164.182907 22.275200 1.000000 1.000000 1.000000 +vn -0.272757 -0.091120 -0.957758 +v 4.875960 161.936417 22.486397 1.000000 1.000000 1.000000 +vn -0.987241 -0.152168 0.046903 +v 4.305850 164.099182 23.462200 1.000000 1.000000 1.000000 +vn -0.940400 0.114429 0.320240 +v 4.529642 162.749893 24.517199 1.000000 1.000000 1.000000 +vn -0.827088 0.390217 0.404544 +v 4.220092 161.395020 24.749798 1.000000 1.000000 1.000000 +vn -0.721806 0.529739 0.445390 +v 3.938340 160.772705 24.864998 1.000000 1.000000 1.000000 +vn -0.838157 0.545391 0.006467 +v 3.482714 160.376434 24.142998 1.000000 1.000000 1.000000 +vn -0.690909 0.652000 0.312316 +v 3.196364 159.733185 25.083799 1.000000 1.000000 1.000000 +vn -0.857464 0.282696 0.429929 +v 4.419316 162.059204 24.633598 1.000000 1.000000 1.000000 +vn -0.518597 0.446987 0.728876 +v 4.142342 160.644333 25.212599 1.000000 1.000000 1.000000 +vn -0.651487 0.252066 0.715561 +v 4.648232 161.997803 24.981398 1.000000 1.000000 1.000000 +vn -0.937266 0.057581 0.343827 +v 4.549636 163.444778 24.401798 1.000000 1.000000 1.000000 +vn -0.707381 -0.003500 0.706824 +v 4.711922 164.180115 24.634199 1.000000 1.000000 1.000000 +vn -0.198142 0.191759 0.961233 +v 4.887444 161.933624 25.135998 1.000000 1.000000 1.000000 +vn -0.124777 0.247623 0.960788 +v 4.355536 160.510376 25.367199 1.000000 1.000000 1.000000 +vn -0.260268 0.107566 0.959526 +v 4.954406 164.227554 24.788799 1.000000 1.000000 1.000000 +vn -0.007053 0.265995 0.963949 +v 2.994024 158.859711 25.701998 1.000000 1.000000 1.000000 +vn 0.363757 -0.040586 0.930609 +v 4.561956 160.380615 25.363598 1.000000 1.000000 1.000000 +vn -0.325790 0.601876 0.729113 +v 2.847458 159.074585 25.547398 1.000000 1.000000 1.000000 +vn 0.110325 0.243089 0.963710 +v 1.071436 157.915054 26.047998 1.000000 1.000000 1.000000 +vn -0.407693 0.847192 0.340664 +v 2.167396 158.908539 25.314798 1.000000 1.000000 1.000000 +vn -0.029675 0.679615 0.732968 +v 1.018970 158.175995 25.893398 1.000000 1.000000 1.000000 +vn -0.489022 0.747052 0.450300 +v 2.707224 159.281097 25.199799 1.000000 1.000000 1.000000 +vn -0.726881 0.686712 -0.008417 +v 3.072200 159.869919 24.259598 1.000000 1.000000 1.000000 +vn -0.524021 0.850123 0.051887 +v 2.083196 159.077377 24.490599 1.000000 1.000000 1.000000 +vn -0.290966 0.881378 0.372173 +v 1.579816 158.621109 25.430998 1.000000 1.000000 1.000000 +vn -0.140573 0.892564 0.428450 +v 0.968766 158.425766 25.545799 1.000000 1.000000 1.000000 +vn -0.213643 0.975605 0.050508 +v 0.931116 158.614136 24.721399 1.000000 1.000000 1.000000 +vn -0.350266 0.890227 -0.291220 +v 1.536222 158.748077 24.151999 1.000000 1.000000 1.000000 +vn -0.234108 0.942028 -0.240369 +v 0.942030 158.559708 24.266598 1.000000 1.000000 1.000000 +vn 0.031914 0.928138 0.370865 +v 0.334888 158.326691 25.660999 1.000000 1.000000 1.000000 +vn 0.100917 0.932555 0.346636 +v -0.305630 158.325302 25.776398 1.000000 1.000000 1.000000 +vn 0.050394 0.998680 0.009953 +v -0.293784 158.516449 24.952198 1.000000 1.000000 1.000000 +vn 0.257551 0.627756 0.734568 +v -0.995204 158.170410 26.240599 1.000000 1.000000 1.000000 +vn 0.290755 0.843396 0.451825 +v -0.946228 158.421570 25.892799 1.000000 1.000000 1.000000 +vn 0.409403 0.809019 0.421754 +v -1.566220 158.614136 26.008999 1.000000 1.000000 1.000000 +vn 0.467536 0.496615 0.731289 +v -2.260830 158.672729 26.471798 1.000000 1.000000 1.000000 +vn 0.258875 0.122812 0.958071 +v -2.377140 158.436920 26.626398 1.000000 1.000000 1.000000 +vn 0.198899 0.187582 0.961900 +v -1.046390 157.909485 26.395199 1.000000 1.000000 1.000000 +vn 0.216847 0.976188 0.005832 +v -0.909502 158.608536 25.068598 1.000000 1.000000 1.000000 +vn 0.558359 0.696109 0.451296 +v -2.149540 158.897385 26.124199 1.000000 1.000000 1.000000 +vn 0.626633 0.313853 0.713322 +v -3.752312 160.022018 26.806599 1.000000 1.000000 1.000000 +vn 0.283156 0.018798 0.958890 +v -3.945370 159.855972 26.961199 1.000000 1.000000 1.000000 +vn 0.381379 0.923817 0.033354 +v -1.505426 158.794128 25.184799 1.000000 1.000000 1.000000 +vn 0.681637 0.661761 0.312161 +v -3.133060 159.666214 26.342999 1.000000 1.000000 1.000000 +vn 0.217667 0.947503 -0.234220 +v -0.920148 158.554123 24.613798 1.000000 1.000000 1.000000 +vn 0.578674 0.815537 0.005998 +v -2.530118 159.377380 25.402199 1.000000 1.000000 1.000000 +vn 0.452024 0.858089 -0.243635 +v -2.090264 159.017380 24.845198 1.000000 1.000000 1.000000 +vn 0.771144 0.462615 0.437406 +v -3.567584 160.181076 26.458998 1.000000 1.000000 1.000000 +vn 0.719689 0.694242 -0.008668 +v -3.011392 159.805740 25.518799 1.000000 1.000000 1.000000 +vn 0.544895 0.618046 -0.566665 +v -3.142304 159.655045 24.666401 1.000000 1.000000 1.000000 +vn 0.358627 0.803000 -0.476002 +v -2.155874 158.884811 24.447599 1.000000 1.000000 1.000000 +vn 0.862666 0.388412 0.323951 +v -3.928530 160.753174 26.573999 1.000000 1.000000 1.000000 +vn 0.867692 0.494570 0.050118 +v -3.775976 160.849457 25.749798 1.000000 1.000000 1.000000 +vn 0.705686 0.048021 0.706895 +v -4.643494 161.971298 27.152599 1.000000 1.000000 1.000000 +vn 0.892861 0.283361 0.350007 +v -4.214916 161.379669 26.690199 1.000000 1.000000 1.000000 +vn 0.902904 0.150373 0.402681 +v -4.414862 162.034088 26.804998 1.000000 1.000000 1.000000 +vn 0.975565 0.214593 0.047143 +v -4.243422 162.081528 25.980598 1.000000 1.000000 1.000000 +vn 0.939087 0.001516 0.343676 +v -4.527916 162.717804 26.920198 1.000000 1.000000 1.000000 +vn 0.945779 -0.054909 0.320136 +v -4.551644 163.411285 27.035599 1.000000 1.000000 1.000000 +vn 0.999894 -0.011535 0.008887 +v -4.374898 163.404312 26.211399 1.000000 1.000000 1.000000 +vn 0.903523 0.071709 -0.422497 +v -4.565098 163.411285 25.358999 1.000000 1.000000 1.000000 +vn 0.946546 0.232113 -0.223997 +v -4.293118 162.067581 25.525799 1.000000 1.000000 1.000000 +vn 0.894791 -0.089230 -0.437478 +v -4.498316 164.110352 25.475599 1.000000 1.000000 1.000000 +vn 0.963511 -0.155893 -0.217589 +v -4.361380 164.085236 25.872999 1.000000 1.000000 1.000000 +vn 0.900916 0.335406 -0.275416 +v -4.098670 161.431305 25.411198 1.000000 1.000000 1.000000 +vn 0.695057 -0.091101 -0.713159 +v -4.567210 164.870804 25.256998 1.000000 1.000000 1.000000 +vn 0.841945 -0.292159 -0.453621 +v -4.098322 165.434509 25.706799 1.000000 1.000000 1.000000 +vn 0.265992 0.108094 -0.957896 +v -4.948382 164.196869 25.004799 1.000000 1.000000 1.000000 +vn 0.289170 0.029973 -0.956809 +v -4.508372 165.653595 25.236198 1.000000 1.000000 1.000000 +vn 0.133941 0.873704 -0.467655 +v -0.949018 158.406219 24.216398 1.000000 1.000000 1.000000 +vn -0.050552 0.891332 -0.450524 +v -0.306524 158.309952 24.099798 1.000000 1.000000 1.000000 +vn 0.039530 -0.303313 -0.952071 +v 3.125720 158.667145 23.047398 1.000000 1.000000 1.000000 +vn 0.172374 -0.258972 -0.950379 +v 4.547086 160.390381 22.712799 1.000000 1.000000 1.000000 +vn 0.140427 -0.591890 -0.793692 +v 1.909578 157.654144 23.429798 1.000000 1.000000 1.000000 +vn 0.311719 -0.592936 -0.742467 +v 3.272210 158.452271 23.198399 1.000000 1.000000 1.000000 +vn -0.312713 0.084197 -0.946109 +v -5.097086 161.847107 24.652599 1.000000 1.000000 1.000000 +vn -0.616486 -0.301616 -0.727306 +v -4.311826 159.540619 24.457598 1.000000 1.000000 1.000000 +vn -0.500526 -0.379850 -0.777938 +v -3.786648 158.918304 24.341799 1.000000 1.000000 1.000000 +vn -0.439740 -0.514380 -0.736235 +v -2.597904 157.990402 24.122999 1.000000 1.000000 1.000000 +vn -0.247102 0.183925 -0.951374 +v -5.178146 164.241516 24.999798 1.000000 1.000000 1.000000 +vn -0.656030 0.218792 -0.722326 +v -5.420758 164.287552 25.150799 1.000000 1.000000 1.000000 +vn -0.620272 0.101843 -0.777748 +v -5.501226 163.444778 25.034401 1.000000 1.000000 1.000000 +vn -0.190843 0.247580 -0.949886 +v -4.717704 165.765213 25.231199 1.000000 1.000000 1.000000 +vn -0.690257 -0.040673 -0.722420 +v -5.335900 161.781540 24.803598 1.000000 1.000000 1.000000 +vn -0.061439 0.299660 -0.952066 +v -3.408104 167.588913 25.565798 1.000000 1.000000 1.000000 +vn -0.564317 0.386070 -0.729723 +v -4.938726 165.882431 25.382198 1.000000 1.000000 1.000000 +vn 0.668973 -0.312080 -0.674597 +v -4.014442 166.111252 25.474199 1.000000 1.000000 1.000000 +vn 0.264234 -0.046461 -0.963339 +v -3.256902 167.396362 25.570999 1.000000 1.000000 1.000000 +vn -0.353667 0.570674 -0.741115 +v -3.567778 167.792633 25.716799 1.000000 1.000000 1.000000 +vn 0.076620 0.299819 -0.950914 +v -1.467768 168.721924 25.911798 1.000000 1.000000 1.000000 +vn -0.431497 0.448877 -0.782508 +v -4.123120 167.202408 25.600998 1.000000 1.000000 1.000000 +vn -0.793371 0.441548 -0.419044 +v -5.151444 165.995438 25.726599 1.000000 1.000000 1.000000 +vn -0.820002 0.313313 -0.478990 +v -5.456460 165.187546 25.611597 1.000000 1.000000 1.000000 +vn -0.654209 0.596517 -0.464949 +v -4.300702 167.372635 25.945398 1.000000 1.000000 1.000000 +vn -0.933438 0.316743 -0.168425 +v -5.582762 165.232193 26.004599 1.000000 1.000000 1.000000 +vn -0.826607 0.521517 -0.211523 +v -4.907080 166.748917 26.221998 1.000000 1.000000 1.000000 +vn -0.747582 0.640817 -0.174570 +v -4.400262 167.467514 26.338598 1.000000 1.000000 1.000000 +vn -0.553395 0.693686 -0.461035 +v -3.721438 167.987976 26.061398 1.000000 1.000000 1.000000 +vn -0.648865 0.740201 -0.176286 +v -3.807584 168.096817 26.454399 1.000000 1.000000 1.000000 +vn -0.433885 0.752885 -0.494882 +v -3.071942 168.505646 26.176598 1.000000 1.000000 1.000000 +vn -0.183262 0.580479 -0.793384 +v -2.258564 168.688431 25.948198 1.000000 1.000000 1.000000 +vn -0.535641 0.825485 -0.177943 +v -3.143050 168.627045 26.569599 1.000000 1.000000 1.000000 +vn -0.327325 0.820374 -0.468876 +v -2.355846 168.922852 26.292797 1.000000 1.000000 1.000000 +vn -0.575292 0.803365 0.153768 +v -3.149924 168.638214 27.385199 1.000000 1.000000 1.000000 +vn -0.683582 0.713739 0.152621 +v -3.815914 168.107971 27.269999 1.000000 1.000000 1.000000 +vn -0.409115 0.894531 -0.180109 +v -2.410370 169.054016 26.685799 1.000000 1.000000 1.000000 +vn -0.201483 0.859055 -0.470563 +v -1.602682 169.224243 26.407398 1.000000 1.000000 1.000000 +vn -0.071172 0.661463 -0.746594 +v -1.536518 168.977264 26.062798 1.000000 1.000000 1.000000 +vn 0.227245 -0.191470 -0.954829 +v -1.402660 168.477737 25.916998 1.000000 1.000000 1.000000 +vn 0.191799 0.240129 -0.951604 +v 0.737648 168.890762 26.258999 1.000000 1.000000 1.000000 +vn 0.091437 0.599099 -0.795437 +v -0.007522 169.213074 26.293598 1.000000 1.000000 1.000000 +vn -0.062791 0.863212 -0.500922 +v -0.813288 169.408432 26.522799 1.000000 1.000000 1.000000 +vn -0.271086 0.945377 -0.181037 +v -1.639774 169.362381 26.800598 1.000000 1.000000 1.000000 +vn -0.125371 0.975379 -0.181433 +v -0.832098 169.550751 26.915798 1.000000 1.000000 1.000000 +vn 0.065833 0.878745 -0.472729 +v -0.007816 169.471222 26.637999 1.000000 1.000000 1.000000 +vn 0.220826 0.633448 -0.741606 +v 0.772234 169.154480 26.409998 1.000000 1.000000 1.000000 +vn 0.023865 0.983139 -0.181297 +v -0.007984 169.614944 27.031199 1.000000 1.000000 1.000000 +vn 0.198614 0.859600 -0.470786 +v 0.805534 169.409836 26.754599 1.000000 1.000000 1.000000 +vn -0.023093 0.987083 0.158539 +v -0.008002 169.628891 27.846798 1.000000 1.000000 1.000000 +vn -0.171783 0.972376 0.158036 +v -0.833914 169.564713 27.731398 1.000000 1.000000 1.000000 +vn -0.316237 0.935692 0.156444 +v -1.643366 169.376343 27.615999 1.000000 1.000000 1.000000 +vn -0.200466 0.843967 0.497527 +v -0.812462 169.401459 28.199598 1.000000 1.000000 1.000000 +vn -0.326448 0.822234 0.466223 +v -1.601060 169.218674 28.084398 1.000000 1.000000 1.000000 +vn -0.442228 0.749526 0.492590 +v -2.353464 168.917267 27.969599 1.000000 1.000000 1.000000 +vn -0.452070 0.878337 0.155426 +v -2.415636 169.067963 27.501398 1.000000 1.000000 1.000000 +vn -0.552762 0.695304 0.459355 +v -3.068852 168.500076 27.853399 1.000000 1.000000 1.000000 +vn -0.300804 0.597157 0.743586 +v -1.534986 168.971695 28.421997 1.000000 1.000000 1.000000 +vn -0.439931 0.460434 0.771013 +v -2.942164 168.282394 28.191198 1.000000 1.000000 1.000000 +vn -0.227012 0.236477 0.944746 +v -1.472570 168.738663 28.562599 1.000000 1.000000 1.000000 +vn -0.124308 0.613906 0.779530 +v -0.007512 169.207504 28.652798 1.000000 1.000000 1.000000 +vn -0.335940 0.158127 0.928515 +v -3.419240 167.602859 28.216599 1.000000 1.000000 1.000000 +vn -0.639119 0.596823 0.485107 +v -3.717678 167.982407 27.738199 1.000000 1.000000 1.000000 +vn -0.564856 0.318656 0.761181 +v -4.119000 167.198212 27.960199 1.000000 1.000000 1.000000 +vn -0.728042 0.515456 0.451951 +v -4.296362 167.368454 27.622398 1.000000 1.000000 1.000000 +vn -0.611318 0.242461 0.753328 +v -4.593422 166.524277 27.843599 1.000000 1.000000 1.000000 +vn -0.798317 0.395607 0.454076 +v -4.791206 166.665207 27.505798 1.000000 1.000000 1.000000 +vn -0.777992 0.609891 0.150866 +v -4.409880 167.477295 27.154198 1.000000 1.000000 1.000000 +vn -0.852845 0.500175 0.149936 +v -4.917804 166.755905 27.037598 1.000000 1.000000 1.000000 +vn -0.669040 0.107068 0.735474 +v -5.225912 165.105209 27.626198 1.000000 1.000000 1.000000 +vn -0.865897 0.216803 0.450799 +v -5.450950 165.184753 27.288399 1.000000 1.000000 1.000000 +vn -0.908431 0.385026 0.162810 +v -5.282226 166.065216 26.935398 1.000000 1.000000 1.000000 +vn -0.951797 0.268718 0.147898 +v -5.594968 165.236374 26.820198 1.000000 1.000000 1.000000 +vn -0.877071 0.080220 0.473614 +v -5.648540 164.330811 27.172199 1.000000 1.000000 1.000000 +vn -0.968953 0.179874 -0.169633 +v -5.785128 164.357315 25.888399 1.000000 1.000000 1.000000 +vn -0.979074 0.140441 0.147277 +v -5.797798 164.360107 26.703999 1.000000 1.000000 1.000000 +vn -0.872212 0.200772 -0.446024 +v -5.654242 164.332214 25.495398 1.000000 1.000000 1.000000 +vn -0.984233 0.051832 -0.169111 +v -5.871016 163.458725 25.771999 1.000000 1.000000 1.000000 +vn -0.891307 0.085614 -0.445245 +v -5.738174 163.453140 25.378798 1.000000 1.000000 1.000000 +vn -0.989048 0.011387 0.147156 +v -5.883852 163.458725 26.587599 1.000000 1.000000 1.000000 +vn -0.982648 -0.076158 -0.169124 +v -5.840400 162.562912 25.656601 1.000000 1.000000 1.000000 +vn -0.879825 -0.025474 -0.474614 +v -5.708252 162.579666 25.263599 1.000000 1.000000 1.000000 +vn -0.096975 0.343375 0.934179 +v 0.740054 168.908905 28.909798 1.000000 1.000000 1.000000 +vn 0.008857 0.344683 0.938677 +v 2.165428 168.460999 29.141199 1.000000 1.000000 1.000000 +vn 0.099285 0.645968 0.756880 +v 1.533030 168.971695 28.885399 1.000000 1.000000 1.000000 +vn 0.061796 0.864044 0.499609 +v 0.804718 169.402847 28.431398 1.000000 1.000000 1.000000 +vn -0.067019 0.880294 0.469671 +v -0.007816 169.464233 28.314999 1.000000 1.000000 1.000000 +vn 0.414767 0.778916 0.470382 +v 2.986802 168.554474 28.764999 1.000000 1.000000 1.000000 +vn 0.216081 0.852641 0.475723 +v 1.599078 169.218674 28.547598 1.000000 1.000000 1.000000 +vn 0.261271 0.582217 0.769909 +v 2.863460 168.335419 29.102798 1.000000 1.000000 1.000000 +vn 0.217815 0.389618 0.894849 +v 3.897694 167.100540 29.475798 1.000000 1.000000 1.000000 +vn 0.477849 0.423605 0.769558 +v 4.541318 166.606598 29.450399 1.000000 1.000000 1.000000 +vn 0.591903 0.611561 0.525018 +v 4.238000 167.436829 28.997398 1.000000 1.000000 1.000000 +vn 0.523569 0.666610 0.530571 +v 3.651232 168.042404 28.881599 1.000000 1.000000 1.000000 +vn 0.720756 0.525082 0.452548 +v 4.736900 166.751709 29.112598 1.000000 1.000000 1.000000 +vn 0.770484 0.419738 0.479765 +v 5.146434 165.991257 29.228798 1.000000 1.000000 1.000000 +vn 0.620094 0.291983 0.728168 +v 5.224610 165.106613 29.681198 1.000000 1.000000 1.000000 +vn 0.244291 0.214963 0.945575 +v 5.012034 165.031265 29.821798 1.000000 1.000000 1.000000 +vn 0.891490 0.427678 0.149460 +v 5.282444 166.063812 28.760599 1.000000 1.000000 1.000000 +vn 0.825694 0.543542 0.150971 +v 4.862108 166.843811 28.644398 1.000000 1.000000 1.000000 +vn 0.940693 0.305000 0.148563 +v 5.593666 165.237778 28.875198 1.000000 1.000000 1.000000 +vn 0.837851 0.314526 0.446183 +v 5.449636 165.186157 29.343599 1.000000 1.000000 1.000000 +vn 0.856653 0.202541 0.474472 +v 5.645874 164.337784 29.458799 1.000000 1.000000 1.000000 +vn 0.634429 0.133252 0.761410 +v 5.494080 163.460129 29.911999 1.000000 1.000000 1.000000 +vn 0.972758 0.178624 0.147771 +v 5.795094 164.367081 28.990599 1.000000 1.000000 1.000000 +vn 0.949186 0.264866 -0.169977 +v 5.581448 165.233597 28.059799 1.000000 1.000000 1.000000 +vn 0.905680 0.388091 -0.170671 +v 5.270922 166.056839 27.944998 1.000000 1.000000 1.000000 +vn 0.836559 0.315359 -0.448015 +v 5.151636 165.994049 27.551998 1.000000 1.000000 1.000000 +vn 0.845310 0.505711 -0.172362 +v 4.851486 166.836838 27.828798 1.000000 1.000000 1.000000 +vn 0.871772 0.202959 -0.445895 +v 5.455146 165.187546 27.666599 1.000000 1.000000 1.000000 +vn 0.602105 0.180839 -0.777668 +v 4.938854 165.881027 27.207399 1.000000 1.000000 1.000000 +vn 0.774449 0.411505 -0.480512 +v 4.741702 166.754517 27.435799 1.000000 1.000000 1.000000 +vn 0.767638 0.616850 -0.173863 +v 4.340524 167.538681 27.713598 1.000000 1.000000 1.000000 +vn 0.594346 0.340664 -0.728492 +v 4.067062 167.267990 26.975998 1.000000 1.000000 1.000000 +vn 0.719372 0.525452 -0.454316 +v 4.242288 167.441010 27.320599 1.000000 1.000000 1.000000 +vn 0.686146 0.084371 -0.722554 +v 5.229838 165.108017 27.321999 1.000000 1.000000 1.000000 +vn 0.318372 -0.064474 -0.945771 +v 4.995710 165.024292 27.170998 1.000000 1.000000 1.000000 +vn 0.259670 -0.167899 -0.950990 +v 5.227378 162.642456 27.518198 1.000000 1.000000 1.000000 +vn -0.200277 -0.218250 -0.955121 +v 4.773992 164.946152 27.176197 1.000000 1.000000 1.000000 +vn -0.041007 -0.246831 -0.968190 +v 3.712568 166.917755 26.830198 1.000000 1.000000 1.000000 +vn 0.320823 0.062548 -0.945072 +v 3.884986 167.087997 26.824999 1.000000 1.000000 1.000000 +vn 0.625804 -0.062572 -0.777467 +v 5.499566 163.460129 27.552799 1.000000 1.000000 1.000000 +vn 0.207393 -0.234431 -0.949753 +v 4.863922 161.088058 27.749598 1.000000 1.000000 1.000000 +vn -0.257183 -0.124662 -0.958288 +v 4.995374 162.668976 27.523199 1.000000 1.000000 1.000000 +vn 0.669414 -0.176786 -0.721549 +v 5.472334 162.613159 27.669197 1.000000 1.000000 1.000000 +vn 0.895083 -0.029324 -0.444934 +v 5.736500 163.468491 27.897198 1.000000 1.000000 1.000000 +vn 0.876430 0.080925 -0.474680 +v 5.651590 164.339188 27.781998 1.000000 1.000000 1.000000 +vn -0.699894 0.047064 -0.712694 +v 4.657540 161.968506 27.775398 1.000000 1.000000 1.000000 +vn -0.756685 -0.155750 -0.634956 +v 4.801416 163.433609 27.542599 1.000000 1.000000 1.000000 +vn -0.286734 -0.048094 -0.956802 +v 4.648064 161.184326 27.754599 1.000000 1.000000 1.000000 +vn -0.689689 0.269310 -0.672162 +v 4.184172 160.688995 27.992798 1.000000 1.000000 1.000000 +vn -0.267210 0.029872 -0.963175 +v 3.509248 159.352264 28.089399 1.000000 1.000000 1.000000 +vn -0.859475 0.237717 -0.452542 +v 4.225204 161.371307 28.225199 1.000000 1.000000 1.000000 +vn -0.898734 0.032523 -0.437287 +v 4.540920 162.721985 27.993998 1.000000 1.000000 1.000000 +vn -0.709226 0.428288 -0.559971 +v 3.618890 160.229919 28.443998 1.000000 1.000000 1.000000 +vn -0.921690 0.310577 -0.232444 +v 4.096546 161.428513 28.622799 1.000000 1.000000 1.000000 +vn -0.971484 0.094673 -0.217382 +v 4.402644 162.737335 28.391399 1.000000 1.000000 1.000000 +vn -0.896957 -0.128544 -0.423018 +v 4.563502 163.423843 27.877398 1.000000 1.000000 1.000000 +vn -0.998644 -0.051306 0.008867 +v 4.373328 163.416855 28.729799 1.000000 1.000000 1.000000 +vn -0.970408 0.239259 0.032611 +v 4.242288 162.081528 28.962399 1.000000 1.000000 1.000000 +vn -0.995806 0.091329 0.005469 +v 4.351672 162.742920 28.846201 1.000000 1.000000 1.000000 +vn -0.871802 0.280667 0.401481 +v 4.413716 162.035492 29.786598 1.000000 1.000000 1.000000 +vn -0.787194 0.430872 0.441220 +v 4.212754 161.376892 29.901798 1.000000 1.000000 1.000000 +vn -0.902231 0.431203 0.006586 +v 3.811110 160.917816 29.179798 1.000000 1.000000 1.000000 +vn -0.773036 0.553670 0.309621 +v 3.608242 160.238297 30.120598 1.000000 1.000000 1.000000 +vn -0.715049 0.577147 -0.394470 +v 3.189978 159.706680 28.559998 1.000000 1.000000 1.000000 +vn -0.812892 0.582356 -0.008258 +v 3.468088 160.355499 29.296398 1.000000 1.000000 1.000000 +vn -0.589016 0.673122 0.447177 +v 3.180594 159.717834 30.236597 1.000000 1.000000 1.000000 +vn -0.526050 0.728903 -0.438145 +v 2.152978 158.883423 28.791199 1.000000 1.000000 1.000000 +vn -0.638374 0.768043 0.050882 +v 2.587862 159.424805 29.527399 1.000000 1.000000 1.000000 +vn -0.533633 0.515361 -0.670551 +v 2.841188 159.049469 28.340399 1.000000 1.000000 1.000000 +vn -0.371681 0.790868 -0.486190 +v 1.570302 158.600174 28.905998 1.000000 1.000000 1.000000 +vn -0.474590 0.831065 -0.289991 +v 2.087418 159.017380 29.188799 1.000000 1.000000 1.000000 +vn -0.353904 0.564628 -0.745619 +v 1.652186 158.358780 28.571199 1.000000 1.000000 1.000000 +vn -0.240298 0.176049 -0.954601 +v 1.727490 158.135529 28.435398 1.000000 1.000000 1.000000 +vn -0.201688 0.718990 -0.665114 +v 0.333338 158.054596 28.801798 1.000000 1.000000 1.000000 +vn -0.144584 0.235066 -0.961166 +v -0.364940 157.817383 28.782598 1.000000 1.000000 1.000000 +vn 0.003742 0.883696 -0.468047 +v -0.331796 158.311340 29.253199 1.000000 1.000000 1.000000 +vn -0.181138 0.874947 -0.449061 +v 0.316796 158.311340 29.136599 1.000000 1.000000 1.000000 +vn 0.027683 0.672217 -0.739836 +v -1.022814 158.159241 29.034599 1.000000 1.000000 1.000000 +vn -0.061566 0.265490 -0.962146 +v -1.746326 158.143890 29.013798 1.000000 1.000000 1.000000 +vn -0.250381 -0.201755 -0.946892 +v -1.827400 157.906693 29.008799 1.000000 1.000000 1.000000 +vn -0.173543 -0.250883 -0.952334 +v -0.381862 157.566223 28.777399 1.000000 1.000000 1.000000 +vn 0.274776 0.666055 -0.693447 +v -2.217866 158.629471 29.251799 1.000000 1.000000 1.000000 +vn 0.238333 0.844561 -0.479494 +v -1.587528 158.607147 29.484398 1.000000 1.000000 1.000000 +vn 0.605677 0.689505 -0.397162 +v -3.158126 159.671783 29.819199 1.000000 1.000000 1.000000 +vn 0.451278 0.686129 -0.570592 +v -2.661570 159.225281 29.703199 1.000000 1.000000 1.000000 +vn 0.022815 0.248970 -0.968242 +v -3.474100 159.314590 29.348598 1.000000 1.000000 1.000000 +vn 0.539595 0.511112 -0.669031 +v -3.775898 160.027588 29.599598 1.000000 1.000000 1.000000 +vn 0.323884 0.913448 -0.246396 +v -1.539210 158.749481 29.881998 1.000000 1.000000 1.000000 +vn 0.076423 0.969009 -0.234906 +v -0.321718 158.462036 29.650599 1.000000 1.000000 1.000000 +vn 0.457076 0.889407 0.006059 +v -2.020200 159.041107 30.438999 1.000000 1.000000 1.000000 +vn 0.243866 0.969225 0.033645 +v -0.931688 158.614136 30.221598 1.000000 1.000000 1.000000 +vn -0.096994 0.995228 0.010633 +v 0.303576 158.516449 29.988998 1.000000 1.000000 1.000000 +vn 0.072395 0.997356 0.006402 +v -0.317996 158.517853 30.105398 1.000000 1.000000 1.000000 +vn 0.454228 0.765471 0.455775 +v -1.582854 158.621109 31.160999 1.000000 1.000000 1.000000 +vn 0.583127 0.747936 0.317104 +v -2.653730 159.237839 31.379799 1.000000 1.000000 1.000000 +vn 0.288352 0.858074 0.424927 +v -0.969310 158.425766 31.045998 1.000000 1.000000 1.000000 +vn 0.577050 0.391646 0.716678 +v -3.311878 159.497375 31.843399 1.000000 1.000000 1.000000 +vn 0.391677 0.553528 0.734980 +v -1.664802 158.381104 31.508799 1.000000 1.000000 1.000000 +vn 0.701200 0.560052 0.441203 +v -3.148830 159.682953 31.495798 1.000000 1.000000 1.000000 +vn 0.693343 0.136340 0.707592 +v -4.439724 161.298752 32.189400 1.000000 1.000000 1.000000 +vn 0.277476 -0.055856 0.959108 +v -4.668162 161.198288 32.343998 1.000000 1.000000 1.000000 +vn 0.277392 0.053941 0.959241 +v -3.482276 159.304810 31.997999 1.000000 1.000000 1.000000 +vn 0.803710 0.497156 0.326935 +v -3.578296 160.196426 31.610798 1.000000 1.000000 1.000000 +vn 0.616367 0.787409 -0.008879 +v -2.550694 159.392731 30.555599 1.000000 1.000000 1.000000 +vn 0.848318 0.396035 0.351443 +v -3.940734 160.774109 31.726999 1.000000 1.000000 1.000000 +vn 0.794879 0.604697 0.050091 +v -3.439338 160.315033 30.786598 1.000000 1.000000 1.000000 +vn 0.931297 0.119762 0.344011 +v -4.418982 162.055023 31.957199 1.000000 1.000000 1.000000 +vn 0.690408 -0.124071 0.712702 +v -4.786970 163.448959 32.536598 1.000000 1.000000 1.000000 +vn 0.876011 0.263348 0.404046 +v -4.221136 161.393631 31.841799 1.000000 1.000000 1.000000 +vn 0.945151 0.064591 0.320183 +v -4.529654 162.738724 32.072399 1.000000 1.000000 1.000000 +vn 0.940284 0.337074 0.047411 +v -4.057226 161.466187 31.017399 1.000000 1.000000 1.000000 +vn 0.754382 0.499496 -0.425925 +v -3.952360 160.767136 30.050398 1.000000 1.000000 1.000000 +vn 0.849183 0.449088 -0.277864 +v -3.832058 160.842484 30.447998 1.000000 1.000000 1.000000 +vn 0.908923 0.350596 -0.225700 +v -4.104734 161.445267 30.562599 1.000000 1.000000 1.000000 +vn 0.809830 0.355316 -0.466825 +v -4.233610 161.388062 30.165199 1.000000 1.000000 1.000000 +vn 0.993431 0.114096 0.008788 +v -4.353746 162.758270 31.248198 1.000000 1.000000 1.000000 +vn 0.886724 0.185124 -0.423615 +v -4.543018 162.735947 30.395798 1.000000 1.000000 1.000000 +vn 0.588539 0.339735 -0.733622 +v -4.454260 161.291779 29.830399 1.000000 1.000000 1.000000 +vn 0.744605 0.203448 -0.635745 +v -4.779798 162.709427 30.060999 1.000000 1.000000 1.000000 +vn 0.975525 -0.033265 -0.217360 +v -4.425768 163.433609 30.909798 1.000000 1.000000 1.000000 +vn 0.898997 0.024172 -0.437287 +v -4.564724 163.439194 30.512398 1.000000 1.000000 1.000000 +vn 0.999584 -0.028307 0.005488 +v -4.374538 163.430817 31.364599 1.000000 1.000000 1.000000 +vn 0.888251 -0.224726 0.400634 +v -4.481064 164.134064 32.305199 1.000000 1.000000 1.000000 +vn 0.873371 -0.182519 -0.451565 +v -4.334742 164.809402 30.743599 1.000000 1.000000 1.000000 +vn 0.939784 -0.250961 -0.232001 +v -4.202788 164.761963 31.141199 1.000000 1.000000 1.000000 +vn 0.701467 -0.002874 -0.712697 +v -4.728518 164.182907 30.293798 1.000000 1.000000 1.000000 +vn 0.183502 0.230538 -0.955604 +v -4.657192 161.202469 29.694599 1.000000 1.000000 1.000000 +vn 0.247902 0.140621 -0.958525 +v -5.021432 163.458725 30.041798 1.000000 1.000000 1.000000 +vn -0.224227 0.221151 -0.949112 +v -4.989852 165.045212 30.267998 1.000000 1.000000 1.000000 +vn 0.282315 0.066128 -0.957040 +v -4.768444 164.965683 30.272999 1.000000 1.000000 1.000000 +vn -0.271102 0.151435 -0.950564 +v -5.254582 163.468491 30.036598 1.000000 1.000000 1.000000 +vn 0.706453 -0.224569 -0.671188 +v -4.336750 165.493118 30.511198 1.000000 1.000000 1.000000 +vn 0.268369 -0.012630 -0.963234 +v -3.747612 166.877289 30.607798 1.000000 1.000000 1.000000 +vn 0.568488 -0.478526 -0.669205 +v -3.100176 167.227524 30.858797 1.000000 1.000000 1.000000 +vn -0.680324 0.133879 -0.720580 +v -5.500788 163.478271 30.187599 1.000000 1.000000 1.000000 +vn -0.628911 0.023078 -0.777135 +v -5.474640 162.631302 30.071199 1.000000 1.000000 1.000000 +vn -0.679023 -0.127671 -0.722930 +v -5.101758 161.007126 29.840599 1.000000 1.000000 1.000000 +vn -0.322962 0.044156 -0.945381 +v -4.873424 161.107590 29.689398 1.000000 1.000000 1.000000 +vn -0.895201 -0.027242 -0.444830 +v -5.710454 162.604782 30.415798 1.000000 1.000000 1.000000 +vn -0.869329 -0.136125 -0.475118 +v -5.570930 161.742462 30.300398 1.000000 1.000000 1.000000 +vn -0.588488 -0.218672 -0.778373 +v -4.762830 160.257828 29.725798 1.000000 1.000000 1.000000 +vn -0.568772 -0.378164 -0.730404 +v -3.805704 158.939240 29.494398 1.000000 1.000000 1.000000 +vn -0.315971 -0.083167 -0.945117 +v -3.635396 159.131790 29.343399 1.000000 1.000000 1.000000 +vn -0.442043 -0.441849 -0.780620 +v -3.207308 158.400650 29.378599 1.000000 1.000000 1.000000 +vn -0.362183 -0.568563 -0.738621 +v -1.912990 157.655533 29.159798 1.000000 1.000000 1.000000 +vn -0.891217 0.088932 -0.444773 +v -5.737724 163.488022 30.532198 1.000000 1.000000 1.000000 +vn -0.854434 0.206483 -0.476767 +v -5.649184 164.364288 30.648399 1.000000 1.000000 1.000000 +vn -0.612889 0.310053 -0.726797 +v -5.223646 165.128937 30.418999 1.000000 1.000000 1.000000 +vn -0.982924 -0.072678 -0.169050 +v -5.842628 162.589432 30.808798 1.000000 1.000000 1.000000 +vn -0.983996 0.056109 -0.169125 +v -5.870540 163.493607 30.925198 1.000000 1.000000 1.000000 +vn -0.104294 0.288382 -0.951819 +v -3.921616 167.044739 30.602598 1.000000 1.000000 1.000000 +vn -0.431898 0.517890 -0.738413 +v -4.105352 167.223343 30.753599 1.000000 1.000000 1.000000 +vn 0.031883 0.305420 -0.951684 +v -2.141660 168.454025 30.948599 1.000000 1.000000 1.000000 +vn -0.490699 0.388496 -0.779927 +v -4.581386 166.556366 30.637798 1.000000 1.000000 1.000000 +vn 0.252839 -0.160996 -0.954019 +v -2.046658 168.222397 30.953798 1.000000 1.000000 1.000000 +vn 0.154259 0.260945 -0.952949 +v 0.021918 168.946579 31.295799 1.000000 1.000000 1.000000 +vn -0.266123 0.549513 -0.791968 +v -2.921024 168.304718 30.984999 1.000000 1.000000 1.000000 +vn -0.167383 0.644768 -0.745827 +v -2.241980 168.698212 31.099798 1.000000 1.000000 1.000000 +vn 0.161491 -0.225887 -0.960675 +v 0.020916 168.694016 31.300999 1.000000 1.000000 1.000000 +vn 0.125249 0.657054 -0.743366 +v 0.022968 169.214478 31.446798 1.000000 1.000000 1.000000 +vn 0.002002 0.606168 -0.795334 +v -0.756864 169.157272 31.330399 1.000000 1.000000 1.000000 +vn 0.235320 0.218701 -0.946992 +v 1.485534 168.714951 31.527199 1.000000 1.000000 1.000000 +vn 0.081244 -0.260896 -0.961942 +v 1.419590 168.472153 31.532198 1.000000 1.000000 1.000000 +vn 0.320108 0.591279 -0.740216 +v 1.555160 168.970291 31.678198 1.000000 1.000000 1.000000 +vn 0.309259 0.103144 -0.945368 +v 3.366466 167.625198 31.861799 1.000000 1.000000 1.000000 +vn -0.004683 -0.249944 -0.968249 +v 3.217054 167.431229 31.866999 1.000000 1.000000 1.000000 +vn 0.540811 0.414417 -0.731971 +v 3.524248 167.830307 32.012798 1.000000 1.000000 1.000000 +vn 0.325630 -0.023740 -0.945199 +v 4.726046 165.745682 32.207798 1.000000 1.000000 1.000000 +vn 0.409390 0.470037 -0.781963 +v 2.893342 168.322861 31.896999 1.000000 1.000000 1.000000 +vn 0.348764 0.830382 -0.434546 +v 1.622188 169.217270 32.022797 1.000000 1.000000 1.000000 +vn 0.204697 0.841755 -0.499548 +v 0.834982 169.405640 31.907598 1.000000 1.000000 1.000000 +vn 0.529860 0.705551 -0.470581 +v 3.017998 168.541931 32.241600 1.000000 1.000000 1.000000 +vn 0.431530 0.875705 -0.216616 +v 2.347838 169.083313 32.517998 1.000000 1.000000 1.000000 +vn 0.191122 0.965211 -0.178439 +v 0.854322 169.547958 32.300598 1.000000 1.000000 1.000000 +vn 0.028480 0.982991 -0.181430 +v 0.024550 169.614944 32.184399 1.000000 1.000000 1.000000 +vn 0.069193 0.879341 -0.471138 +v 0.023980 169.471222 31.791401 1.000000 1.000000 1.000000 +vn 0.272783 0.946634 0.171679 +v 1.663386 169.367966 33.231400 1.000000 1.000000 1.000000 +vn 0.133727 0.978236 0.158653 +v 0.856198 169.561905 33.116196 1.000000 1.000000 1.000000 +vn 0.088842 0.874303 0.477181 +v 0.834138 169.398666 33.584396 1.000000 1.000000 1.000000 +vn 0.298469 0.828906 0.473108 +v 2.292386 168.946579 33.801796 1.000000 1.000000 1.000000 +vn 0.406152 0.900429 0.155781 +v 2.352974 169.095871 33.333599 1.000000 1.000000 1.000000 +vn -0.066042 0.864038 0.499075 +v 0.023960 169.464233 33.468201 1.000000 1.000000 1.000000 +vn -0.018159 0.987222 0.158315 +v 0.024608 169.628891 33.000000 1.000000 1.000000 1.000000 +vn 0.003123 0.653595 0.756838 +v 0.799668 169.144714 33.922199 1.000000 1.000000 1.000000 +vn -0.195738 0.862159 0.467299 +v -0.788642 169.405640 33.351799 1.000000 1.000000 1.000000 +vn -0.213385 0.591485 0.777568 +v -0.756110 169.151688 33.689598 1.000000 1.000000 1.000000 +vn -0.167792 0.973208 0.157203 +v -0.809466 169.567505 32.883598 1.000000 1.000000 1.000000 +vn -0.321431 0.807205 0.495079 +v -1.577976 169.224243 33.236397 1.000000 1.000000 1.000000 +vn -0.384326 0.551546 0.740331 +v -2.239740 168.692627 33.458801 1.000000 1.000000 1.000000 +vn -0.146480 0.327834 0.933311 +v 0.021986 168.966110 33.946598 1.000000 1.000000 1.000000 +vn -0.259454 0.204569 0.943841 +v -2.148664 168.470764 33.599396 1.000000 1.000000 1.000000 +vn -0.442034 0.768569 0.462502 +v -2.336172 168.927048 33.121201 1.000000 1.000000 1.000000 +vn -0.311255 0.937212 0.157336 +v -1.619664 169.383316 32.768196 1.000000 1.000000 1.000000 +vn -0.544798 0.681864 0.488116 +v -3.043760 168.516815 33.006401 1.000000 1.000000 1.000000 +vn -0.505666 0.394567 0.767215 +v -3.547268 167.802399 33.227997 1.000000 1.000000 1.000000 +vn -0.448336 0.880274 0.155279 +v -2.397894 169.076340 32.652798 1.000000 1.000000 1.000000 +vn -0.265962 0.946840 -0.180994 +v -1.616136 169.369370 31.952599 1.000000 1.000000 1.000000 +vn -0.404835 0.896592 -0.179531 +v -2.392668 169.063782 31.837399 1.000000 1.000000 1.000000 +vn -0.532371 0.827425 -0.178740 +v -3.117352 168.645187 31.722601 1.000000 1.000000 1.000000 +vn -0.571934 0.805578 0.154713 +v -3.124176 168.656342 32.538200 1.000000 1.000000 1.000000 +vn -0.644218 0.614726 0.455077 +v -3.700014 167.997757 32.890198 1.000000 1.000000 1.000000 +vn -0.680882 0.716265 0.152856 +v -3.797760 168.123322 32.421997 1.000000 1.000000 1.000000 +vn -0.442282 0.765981 -0.466540 +v -3.046824 168.522400 31.329599 1.000000 1.000000 1.000000 +vn -0.645881 0.742712 -0.176685 +v -3.789482 168.113556 31.606398 1.000000 1.000000 1.000000 +vn -0.324516 0.821892 -0.468169 +v -2.338542 168.932617 31.444199 1.000000 1.000000 1.000000 +vn -0.188748 0.845576 -0.499375 +v -1.579584 169.231216 31.559599 1.000000 1.000000 1.000000 +vn -0.536475 0.685658 -0.492003 +v -3.703748 168.003326 31.213398 1.000000 1.000000 1.000000 +vn -0.743975 0.645052 -0.174383 +v -4.381284 167.489853 31.491398 1.000000 1.000000 1.000000 +vn -0.644624 0.612244 -0.457839 +v -4.282174 167.394974 31.098198 1.000000 1.000000 1.000000 +vn -0.774452 0.614434 0.150650 +v -4.390876 167.499619 32.306801 1.000000 1.000000 1.000000 +vn -0.826691 0.535164 -0.173726 +v -4.889324 166.779617 31.375399 1.000000 1.000000 1.000000 +vn -0.729808 0.503925 -0.461995 +v -4.778704 166.698700 30.982397 1.000000 1.000000 1.000000 +vn -0.845390 0.335273 -0.415823 +v -5.448632 165.209869 30.763599 1.000000 1.000000 1.000000 +vn -0.887971 0.409048 -0.210205 +v -5.301074 165.991257 31.258799 1.000000 1.000000 1.000000 +vn -0.910850 0.385084 0.148533 +v -5.312662 165.998245 32.074398 1.000000 1.000000 1.000000 +vn -0.852181 0.501333 0.149844 +v -4.900024 166.786591 32.190998 1.000000 1.000000 1.000000 +vn -0.950470 0.265441 0.161701 +v -5.586958 165.260101 31.972198 1.000000 1.000000 1.000000 +vn -0.966351 0.195183 -0.167542 +v -5.779952 164.389420 31.041401 1.000000 1.000000 1.000000 +vn -0.843937 0.289847 0.451396 +v -5.175892 165.927078 32.542599 1.000000 1.000000 1.000000 +vn -0.753771 0.401992 0.519839 +v -4.773876 166.695908 32.659199 1.000000 1.000000 1.000000 +vn -0.887044 0.105377 0.449497 +v -5.643480 164.362900 32.325199 1.000000 1.000000 1.000000 +vn -0.634757 0.172665 0.753174 +v -4.962222 165.816833 32.880398 1.000000 1.000000 1.000000 +vn -0.978319 0.145649 0.147239 +v -5.792596 164.392212 31.856998 1.000000 1.000000 1.000000 +vn -0.988988 0.015702 0.147164 +v -5.883376 163.493607 31.740799 1.000000 1.000000 1.000000 +vn -0.711768 0.475860 0.516666 +v -4.277848 167.390778 32.775200 1.000000 1.000000 1.000000 +vn -0.434465 0.155854 0.887102 +v -3.934426 167.057297 33.253399 1.000000 1.000000 1.000000 +vn -0.064289 0.879550 -0.471443 +v -0.789438 169.411224 31.674999 1.000000 1.000000 1.000000 +vn -0.120861 0.975958 -0.181380 +v -0.807708 169.553543 32.068001 1.000000 1.000000 1.000000 +vn -0.042060 0.342407 0.938610 +v 1.490388 168.731689 34.177998 1.000000 1.000000 1.000000 +vn 0.162527 0.616454 0.770434 +v 2.197704 168.710770 34.139599 1.000000 1.000000 1.000000 +vn 0.113160 0.335339 0.935277 +v 3.377474 167.639145 34.512596 1.000000 1.000000 1.000000 +vn 0.437556 0.770497 0.463550 +v 3.014958 168.536346 33.918396 1.000000 1.000000 1.000000 +vn 0.251169 0.579066 0.775626 +v 2.890460 168.318665 34.256199 1.000000 1.000000 1.000000 +vn 0.211424 0.243973 0.946455 +v 4.741484 165.754044 34.858597 1.000000 1.000000 1.000000 +vn 0.417265 0.477464 0.773252 +v 4.077104 167.245667 34.487198 1.000000 1.000000 1.000000 +vn 0.533446 0.688986 0.490647 +v 3.672372 168.022858 34.034401 1.000000 1.000000 1.000000 +vn 0.646224 0.747368 0.154386 +v 3.769422 168.149841 33.565998 1.000000 1.000000 1.000000 +vn 0.530666 0.833179 0.155583 +v 3.094654 168.675888 33.450199 1.000000 1.000000 1.000000 +vn 0.565916 0.805180 -0.177267 +v 3.087894 168.664719 32.634598 1.000000 1.000000 1.000000 +vn 0.745357 0.648998 0.152459 +v 4.365102 167.528915 33.681198 1.000000 1.000000 1.000000 +vn 0.676818 0.714969 -0.175317 +v 3.761196 168.138672 32.750599 1.000000 1.000000 1.000000 +vn 0.640340 0.616637 -0.457955 +v 3.676080 168.028442 32.357399 1.000000 1.000000 1.000000 +vn 0.770438 0.613384 -0.173738 +v 4.355574 167.519150 32.865601 1.000000 1.000000 1.000000 +vn 0.712193 0.509048 -0.483375 +v 4.257004 167.422867 32.472599 1.000000 1.000000 1.000000 +vn 0.787218 0.420314 -0.451248 +v 4.758788 166.727997 32.588799 1.000000 1.000000 1.000000 +vn 0.572114 0.255742 -0.779283 +v 4.562240 166.584274 32.244198 1.000000 1.000000 1.000000 +vn 0.847044 0.502786 -0.172401 +v 4.868970 166.808914 32.981796 1.000000 1.000000 1.000000 +vn 0.837683 0.312499 -0.447919 +v 5.160674 165.975906 32.703400 1.000000 1.000000 1.000000 +vn 0.668684 0.170535 -0.723727 +v 4.947518 165.862885 32.359001 1.000000 1.000000 1.000000 +vn 0.281390 -0.133988 -0.950193 +v 5.254944 163.419647 32.555000 1.000000 1.000000 1.000000 +vn 0.629132 0.016436 -0.777124 +v 5.421814 164.269409 32.589600 1.000000 1.000000 1.000000 +vn 0.858746 0.190864 -0.475528 +v 5.461920 165.163818 32.818798 1.000000 1.000000 1.000000 +vn 0.907300 0.384373 -0.170483 +v 5.280166 166.038696 33.096596 1.000000 1.000000 1.000000 +vn 0.950470 0.260393 -0.169712 +v 5.588388 165.207077 33.211800 1.000000 1.000000 1.000000 +vn 0.891634 0.083794 -0.444935 +v 5.655402 164.314072 32.934196 1.000000 1.000000 1.000000 +vn 0.976362 0.134626 -0.169096 +v 5.786338 164.337784 33.327198 1.000000 1.000000 1.000000 +vn 0.895213 -0.032502 -0.444451 +v 5.738212 163.434998 33.050598 1.000000 1.000000 1.000000 +vn 0.687864 -0.090706 -0.720150 +v 5.501214 163.426636 32.706001 1.000000 1.000000 1.000000 +vn 0.632866 -0.269997 -0.725660 +v 5.328678 161.759216 32.937401 1.000000 1.000000 1.000000 +vn 0.239264 -0.206332 -0.948778 +v 5.090146 161.826187 32.786400 1.000000 1.000000 1.000000 +vn 0.516740 -0.356103 -0.778569 +v 4.777802 160.287140 33.156197 1.000000 1.000000 1.000000 +vn 0.125311 -0.281590 -0.951317 +v 4.150336 159.751328 33.120998 1.000000 1.000000 1.000000 +vn -0.009354 -0.306646 -0.951778 +v 2.463222 158.215057 33.466999 1.000000 1.000000 1.000000 +vn -0.268850 -0.004290 -0.963173 +v 3.966136 159.906204 33.126198 1.000000 1.000000 1.000000 +vn -0.276771 -0.083805 -0.957274 +v 4.864232 161.888977 32.791397 1.000000 1.000000 1.000000 +vn -0.236858 -0.155961 -0.958945 +v 5.021716 163.411285 32.560196 1.000000 1.000000 1.000000 +vn -0.165850 -0.241763 -0.956057 +v 4.516290 165.635452 32.212997 1.000000 1.000000 1.000000 +vn -0.263837 0.144592 -0.953668 +v 2.353876 158.438309 33.472198 1.000000 1.000000 1.000000 +vn -0.134543 -0.270913 -0.953155 +v 0.335754 157.562042 33.814198 1.000000 1.000000 1.000000 +vn -0.177663 0.214653 -0.960396 +v 0.320824 157.814590 33.819397 1.000000 1.000000 1.000000 +vn -0.218359 -0.232787 -0.947697 +v -1.139114 157.686234 34.045601 1.000000 1.000000 1.000000 +vn -0.071740 0.668581 -0.740171 +v -0.373888 158.056000 34.071396 1.000000 1.000000 1.000000 +vn -0.304270 0.684876 -0.662091 +v 0.982932 158.152267 33.838799 1.000000 1.000000 1.000000 +vn -0.100226 0.254958 -0.961744 +v -1.088588 157.933197 34.050598 1.000000 1.000000 1.000000 +vn -0.301306 -0.122898 -0.945574 +v -3.084224 158.633667 34.380196 1.000000 1.000000 1.000000 +vn -0.013783 0.249728 -0.968218 +v -2.947378 158.838776 34.385399 1.000000 1.000000 1.000000 +vn 0.174184 0.696049 -0.696545 +v -1.616728 158.344833 34.288799 1.000000 1.000000 1.000000 +vn -0.326997 0.003032 -0.945020 +v -4.558996 160.408524 34.726196 1.000000 1.000000 1.000000 +vn -0.374656 -0.496526 -0.783004 +v -2.568242 157.972275 34.415398 1.000000 1.000000 1.000000 +vn -0.276231 -0.611954 -0.741086 +v -1.192462 157.425293 34.196598 1.000000 1.000000 1.000000 +vn 0.147777 0.251948 -0.956391 +v -4.356706 160.534103 34.731400 1.000000 1.000000 1.000000 +vn -0.655597 -0.212520 -0.724588 +v -4.772602 160.275970 34.877396 1.000000 1.000000 1.000000 +vn -0.290447 0.116095 -0.949822 +v -5.233160 162.689896 35.073399 1.000000 1.000000 1.000000 +vn -0.552919 -0.291737 -0.780493 +v -4.342738 159.583893 34.762596 1.000000 1.000000 1.000000 +vn -0.510588 -0.449066 -0.733239 +v -3.228718 158.417374 34.531197 1.000000 1.000000 1.000000 +vn 0.225213 0.170620 -0.959254 +v -5.000950 162.715012 35.078598 1.000000 1.000000 1.000000 +vn -0.626830 -0.056053 -0.777137 +v -5.346072 161.828964 35.107998 1.000000 1.000000 1.000000 +vn -0.692611 0.047067 -0.719774 +v -5.478348 162.664780 35.224396 1.000000 1.000000 1.000000 +vn -0.253543 0.190943 -0.948292 +v -5.169068 164.291733 35.304798 1.000000 1.000000 1.000000 +vn 0.270056 0.101090 -0.957523 +v -4.939716 164.245697 35.309799 1.000000 1.000000 1.000000 +vn -0.650175 0.228996 -0.724454 +v -5.411256 164.340576 35.455799 1.000000 1.000000 1.000000 +vn -0.145137 0.272472 -0.951154 +v -4.362088 166.430786 35.639397 1.000000 1.000000 1.000000 +vn -0.540142 0.321890 -0.777582 +v -4.954304 165.850327 35.674599 1.000000 1.000000 1.000000 +vn -0.882302 0.224406 -0.413744 +v -5.644330 164.388016 35.800400 1.000000 1.000000 1.000000 +vn -0.874337 0.096829 -0.475561 +v -5.736694 163.520126 35.685196 1.000000 1.000000 1.000000 +vn -0.013472 0.306695 -0.951712 +v -2.775668 168.089828 35.985397 1.000000 1.000000 1.000000 +vn 0.268013 0.021244 -0.963181 +v -4.168528 166.289856 35.644600 1.000000 1.000000 1.000000 +vn -0.501663 0.456888 -0.734566 +v -4.566462 166.580093 35.790596 1.000000 1.000000 1.000000 +vn -0.791439 0.404833 -0.457968 +v -5.167692 165.961960 36.019199 1.000000 1.000000 1.000000 +vn -0.933496 0.291679 -0.208587 +v -5.596320 165.183365 36.295601 1.000000 1.000000 1.000000 +vn -0.983324 0.071509 -0.167215 +v -5.869484 163.527100 36.078201 1.000000 1.000000 1.000000 +vn -0.889975 0.422414 -0.171789 +v -5.287324 166.024750 36.412201 1.000000 1.000000 1.000000 +vn -0.722285 0.520920 -0.454914 +v -4.763138 166.723801 36.134998 1.000000 1.000000 1.000000 +vn -0.342870 0.508510 -0.789847 +v -3.529076 167.827515 36.021797 1.000000 1.000000 1.000000 +vn -0.627495 0.606628 -0.488112 +v -4.266558 167.411697 36.250198 1.000000 1.000000 1.000000 +vn -0.823689 0.539879 -0.173398 +v -4.873398 166.804733 36.528198 1.000000 1.000000 1.000000 +vn -0.741256 0.647954 -0.175198 +v -4.365334 167.507980 36.643196 1.000000 1.000000 1.000000 +vn -0.547066 0.697878 -0.462262 +v -3.681076 168.024261 36.366398 1.000000 1.000000 1.000000 +vn -0.259387 0.615946 -0.743861 +v -2.905690 168.315887 36.136597 1.000000 1.000000 1.000000 +vn -0.643118 0.745085 -0.176771 +v -3.766280 168.134491 36.759399 1.000000 1.000000 1.000000 +vn -0.439296 0.768290 -0.465564 +v -3.030846 168.534943 36.480999 1.000000 1.000000 1.000000 +vn -0.772017 0.617369 0.151148 +v -4.374874 167.517746 37.458801 1.000000 1.000000 1.000000 +vn -0.849570 0.505839 0.149526 +v -4.884058 166.811722 37.343597 1.000000 1.000000 1.000000 +vn -0.722544 0.523114 0.451976 +v -4.262258 167.407516 37.926998 1.000000 1.000000 1.000000 +vn -0.769741 0.378783 0.513831 +v -4.758324 166.721024 37.811996 1.000000 1.000000 1.000000 +vn -0.678346 0.718634 0.153009 +v -3.774508 168.145645 37.574997 1.000000 1.000000 1.000000 +vn -0.800861 0.301667 0.517318 +v -5.162476 165.959167 37.695999 1.000000 1.000000 1.000000 +vn -0.910360 0.386209 0.148618 +v -5.298884 166.030319 37.227798 1.000000 1.000000 1.000000 +vn -0.952814 0.265244 0.147619 +v -5.608562 165.188950 37.111198 1.000000 1.000000 1.000000 +vn -0.874870 0.180154 0.449608 +v -5.464172 165.138702 37.579399 1.000000 1.000000 1.000000 +vn -0.976512 0.142853 0.161302 +v -5.787626 164.417328 37.008999 1.000000 1.000000 1.000000 +vn -0.988890 0.021065 0.147148 +v -5.882334 163.527100 36.893799 1.000000 1.000000 1.000000 +vn -0.556121 0.325349 0.764773 +v -4.086310 167.235886 38.264801 1.000000 1.000000 1.000000 +vn -0.286522 0.168784 0.943089 +v -2.784732 168.105179 38.636200 1.000000 1.000000 1.000000 +vn -0.459690 0.495240 0.737172 +v -2.902794 168.311691 38.495796 1.000000 1.000000 1.000000 +vn -0.634888 0.601393 0.485020 +v -3.677354 168.018677 38.043198 1.000000 1.000000 1.000000 +vn -0.452936 0.099657 0.885956 +v -4.376328 166.441940 38.290199 1.000000 1.000000 1.000000 +vn -0.652534 0.091019 0.752273 +v -5.238606 165.060562 37.917198 1.000000 1.000000 1.000000 +vn -0.546854 0.700267 0.458886 +v -3.027782 168.529373 38.157997 1.000000 1.000000 1.000000 +vn -0.567771 0.808662 0.153952 +v -3.107774 168.668900 37.689598 1.000000 1.000000 1.000000 +vn -0.444012 0.882516 0.154983 +v -2.375260 169.086105 37.805000 1.000000 1.000000 1.000000 +vn -0.528382 0.830153 -0.177925 +v -3.101002 168.656342 36.874199 1.000000 1.000000 1.000000 +vn -0.435040 0.754385 0.491572 +v -2.314118 168.936798 38.273399 1.000000 1.000000 1.000000 +vn -0.307787 0.938369 0.157259 +v -1.595872 169.390289 37.920399 1.000000 1.000000 1.000000 +vn -0.400938 0.898363 -0.179421 +v -2.370072 169.073547 36.989399 1.000000 1.000000 1.000000 +vn -0.310263 0.809843 -0.497886 +v -2.316462 168.942383 36.596397 1.000000 1.000000 1.000000 +vn -0.192968 0.860644 -0.471228 +v -1.556372 169.238205 36.711800 1.000000 1.000000 1.000000 +vn -0.262476 0.947837 -0.180863 +v -1.592382 169.376343 37.104797 1.000000 1.000000 1.000000 +vn -0.087786 0.599210 -0.795765 +v -1.492126 168.989838 36.367199 1.000000 1.000000 1.000000 +vn -0.060528 0.880264 -0.470607 +v -0.758024 169.416809 36.828201 1.000000 1.000000 1.000000 +vn 0.027327 0.667790 -0.743848 +v -0.726740 169.162857 36.483597 1.000000 1.000000 1.000000 +vn -0.115701 0.976610 -0.181232 +v -0.775558 169.559128 37.221397 1.000000 1.000000 1.000000 +vn 0.078710 0.862075 -0.500630 +v 0.053714 169.471222 36.944397 1.000000 1.000000 1.000000 +vn 0.200670 0.246778 -0.948068 +v 0.785004 168.882385 36.563980 1.000000 1.000000 1.000000 +vn 0.113922 0.278642 -0.953615 +v -0.694236 168.897736 36.332596 1.000000 1.000000 1.000000 +vn 0.230593 0.627789 -0.743443 +v 0.821820 169.146103 36.714996 1.000000 1.000000 1.000000 +vn 0.192891 -0.202973 -0.959997 +v -0.663452 168.646576 36.337799 1.000000 1.000000 1.000000 +vn 0.273425 -0.127206 -0.953445 +v -2.652520 167.874954 35.990601 1.000000 1.000000 1.000000 +vn 0.292180 0.142353 -0.945709 +v 2.785220 168.081467 36.898579 1.000000 1.000000 1.000000 +vn 0.118854 -0.248042 -0.961431 +v 0.750144 168.632614 36.569000 1.000000 1.000000 1.000000 +vn 0.223945 0.870956 -0.437361 +v 0.857240 169.401459 37.059601 1.000000 1.000000 1.000000 +vn 0.338195 0.520475 -0.784047 +v 2.228822 168.703781 36.933777 1.000000 1.000000 1.000000 +vn 0.477567 0.481133 -0.735147 +v 2.915758 168.307510 37.049797 1.000000 1.000000 1.000000 +vn 0.326770 0.017683 -0.944939 +v 4.368320 166.419617 37.244797 1.000000 1.000000 1.000000 +vn 0.032043 -0.248456 -0.968113 +v 2.661596 167.866592 36.903801 1.000000 1.000000 1.000000 +vn 0.424812 0.771838 -0.473076 +v 2.324856 168.938202 37.278397 1.000000 1.000000 1.000000 +vn 0.300754 0.928466 -0.217941 +v 1.592872 169.376343 37.554798 1.000000 1.000000 1.000000 +vn 0.047151 0.982776 -0.178683 +v 0.054972 169.614944 37.337399 1.000000 1.000000 1.000000 +vn 0.548253 0.697328 -0.461684 +v 3.041390 168.526581 37.394180 1.000000 1.000000 1.000000 +vn 0.446545 0.876748 -0.178636 +v 2.378686 169.069366 37.671398 1.000000 1.000000 1.000000 +vn 0.271074 0.949604 0.157391 +v 1.596348 169.388901 38.370377 1.000000 1.000000 1.000000 +vn 0.130849 0.976263 0.172595 +v 0.879026 169.556335 38.268196 1.000000 1.000000 1.000000 +vn -0.011257 0.987330 0.158281 +v 0.055088 169.628891 38.153000 1.000000 1.000000 1.000000 +vn 0.174005 0.862593 0.475033 +v 1.555238 169.231216 38.838600 1.000000 1.000000 1.000000 +vn -0.039639 0.878468 0.476154 +v 0.053654 169.464233 38.621201 1.000000 1.000000 1.000000 +vn 0.406600 0.900124 0.156378 +v 2.383886 169.083313 38.486977 1.000000 1.000000 1.000000 +vn 0.070072 0.632933 0.771029 +v 1.491006 168.984253 39.176376 1.000000 1.000000 1.000000 +vn -0.093134 0.647896 0.756014 +v 0.051416 169.208893 38.959000 1.000000 1.000000 1.000000 +vn 0.321765 0.823700 0.466890 +v 2.322500 168.932617 38.955200 1.000000 1.000000 1.000000 +vn -0.193069 0.845859 0.497239 +v -0.757258 169.411224 38.505196 1.000000 1.000000 1.000000 +vn -0.297972 0.556609 0.775499 +v -1.490632 168.984253 38.726398 1.000000 1.000000 1.000000 +vn -0.092000 0.333439 0.938272 +v 0.787568 168.900528 39.214779 1.000000 1.000000 1.000000 +vn -0.193536 0.305221 0.932407 +v -0.696506 168.915878 38.983398 1.000000 1.000000 1.000000 +vn -0.162649 0.974107 0.157041 +v -0.777248 169.573074 38.036797 1.000000 1.000000 1.000000 +vn -0.319019 0.825065 0.466364 +v -1.554800 169.231216 38.388599 1.000000 1.000000 1.000000 +vn 0.062700 0.346793 0.935844 +v 2.794322 168.096817 39.549400 1.000000 1.000000 1.000000 +vn 0.164100 0.607285 0.777352 +v 2.226582 168.698212 39.292976 1.000000 1.000000 1.000000 +vn 0.345278 0.528315 0.775672 +v 3.536928 167.810776 39.523998 1.000000 1.000000 1.000000 +vn 0.174671 0.268892 0.947200 +v 4.382586 166.430786 39.895397 1.000000 1.000000 1.000000 +vn 0.516615 0.439943 0.734547 +v 4.568472 166.564743 39.754978 1.000000 1.000000 1.000000 +vn 0.629921 0.605415 0.486489 +v 4.272970 167.393570 39.302399 1.000000 1.000000 1.000000 +vn 0.550383 0.696787 0.459963 +v 3.689276 168.007507 39.186180 1.000000 1.000000 1.000000 +vn 0.430480 0.755687 0.493582 +v 3.038314 168.520996 39.071178 1.000000 1.000000 1.000000 +vn 0.724827 0.519601 0.452373 +v 4.765250 166.708450 39.417198 1.000000 1.000000 1.000000 +vn 0.774382 0.412838 0.479477 +v 5.165284 165.949402 39.532600 1.000000 1.000000 1.000000 +vn 0.829903 0.537140 0.150805 +v 4.891178 166.799164 38.948776 1.000000 1.000000 1.000000 +vn 0.747976 0.645940 0.152624 +v 4.385906 167.503799 38.834179 1.000000 1.000000 1.000000 +vn 0.649798 0.744398 0.153735 +v 3.786790 168.133102 38.717999 1.000000 1.000000 1.000000 +vn 0.772565 0.610627 -0.174006 +v 4.376328 167.494034 38.018600 1.000000 1.000000 1.000000 +vn 0.895271 0.419680 0.149528 +v 5.301796 166.020569 39.064178 1.000000 1.000000 1.000000 +vn 0.849058 0.499460 -0.172166 +v 4.880506 166.792191 38.133400 1.000000 1.000000 1.000000 +vn 0.943074 0.297551 0.148576 +v 5.607790 165.186157 39.179581 1.000000 1.000000 1.000000 +vn 0.908976 0.380292 -0.170706 +v 5.290220 166.014969 38.248596 1.000000 1.000000 1.000000 +vn 0.788869 0.417783 -0.450714 +v 4.770052 166.711243 37.740196 1.000000 1.000000 1.000000 +vn 0.723792 0.519631 -0.453992 +v 4.277282 167.397751 37.625599 1.000000 1.000000 1.000000 +vn 0.679860 0.711990 -0.175674 +v 3.778524 168.121933 37.902397 1.000000 1.000000 1.000000 +vn 0.826361 0.298418 -0.477571 +v 5.170498 165.952179 37.855598 1.000000 1.000000 1.000000 +vn 0.639347 0.254160 -0.725699 +v 4.573042 166.568924 37.395779 1.000000 1.000000 1.000000 +vn 0.531656 0.327101 -0.781247 +v 4.100626 167.227524 37.280998 1.000000 1.000000 1.000000 +vn 0.635705 0.599114 -0.486767 +v 3.693010 168.011688 37.509377 1.000000 1.000000 1.000000 +vn 0.570918 0.801721 -0.176907 +v 3.111802 168.647964 37.787376 1.000000 1.000000 1.000000 +vn 0.298388 -0.097791 -0.949422 +v 5.184608 164.192673 37.591797 1.000000 1.000000 1.000000 +vn -0.128968 -0.260751 -0.956753 +v 4.174438 166.278702 37.249779 1.000000 1.000000 1.000000 +vn -0.212388 -0.184612 -0.959588 +v 4.954510 164.150803 37.597000 1.000000 1.000000 1.000000 +vn 0.266623 -0.174627 -0.947849 +v 5.221534 162.590836 37.823196 1.000000 1.000000 1.000000 +vn 0.694475 -0.003163 -0.719510 +v 5.427582 164.237320 37.742779 1.000000 1.000000 1.000000 +vn 0.621767 0.095416 -0.777369 +v 5.243048 165.060562 37.626396 1.000000 1.000000 1.000000 +vn -0.262054 -0.117941 -0.957819 +v 4.989786 162.620132 37.828178 1.000000 1.000000 1.000000 +vn 0.166306 -0.252003 -0.953330 +v 4.551116 160.395966 38.157799 1.000000 1.000000 1.000000 +vn 0.664562 -0.187068 -0.723438 +v 5.466218 162.560135 37.974178 1.000000 1.000000 1.000000 +vn -0.307177 -0.006875 -0.951627 +v 4.349124 160.522949 38.162998 1.000000 1.000000 1.000000 +vn 0.561474 -0.286472 -0.776325 +v 5.105350 161.021088 38.193001 1.000000 1.000000 1.000000 +vn 0.088935 -0.295017 -0.951344 +v 3.637456 159.135971 38.389198 1.000000 1.000000 1.000000 +vn 0.895136 -0.167864 -0.412981 +v 5.701726 162.529434 38.318798 1.000000 1.000000 1.000000 +vn 0.878914 -0.041487 -0.475174 +v 5.739216 163.402924 38.203598 1.000000 1.000000 1.000000 +vn 0.985897 -0.009282 -0.167098 +v 5.872086 163.405701 38.596581 1.000000 1.000000 1.000000 +vn 0.976947 0.130409 -0.169019 +v 5.792492 164.304291 38.480598 1.000000 1.000000 1.000000 +vn 0.892123 0.080526 -0.444559 +v 5.661414 164.280579 38.087399 1.000000 1.000000 1.000000 +vn 0.951340 0.257245 -0.169639 +v 5.595560 165.181961 38.363998 1.000000 1.000000 1.000000 +vn 0.873372 0.195639 -0.446035 +v 5.468922 165.138702 37.971001 1.000000 1.000000 1.000000 +vn -0.294713 0.074478 -0.952679 +v 3.476006 159.317383 38.394180 1.000000 1.000000 1.000000 +vn -0.059423 -0.307107 -0.949818 +v 1.761338 157.878784 38.735378 1.000000 1.000000 1.000000 +vn -0.170684 0.267563 -0.948302 +v 0.280884 157.811813 38.970177 1.000000 1.000000 1.000000 +vn -0.297227 0.195092 -0.934663 +v 2.336172 158.427155 38.624378 1.000000 1.000000 1.000000 +vn -0.229867 -0.233884 -0.944701 +v -2.198026 158.071350 39.337601 1.000000 1.000000 1.000000 +vn -0.094212 0.669544 -0.736774 +v -0.001254 158.040649 39.150177 1.000000 1.000000 1.000000 +vn -0.302606 0.691975 -0.655439 +v 0.951244 158.143890 38.991798 1.000000 1.000000 1.000000 +vn -0.180592 -0.255157 -0.949885 +v -0.750136 157.609497 39.119999 1.000000 1.000000 1.000000 +vn -0.432239 0.502861 -0.748532 +v 2.234346 158.637848 38.760201 1.000000 1.000000 1.000000 +vn -0.288648 0.840463 -0.458590 +v 0.904086 158.396454 39.326576 1.000000 1.000000 1.000000 +vn -0.504990 0.716042 -0.481944 +v 2.123610 158.866684 39.094978 1.000000 1.000000 1.000000 +vn -0.121285 0.872735 -0.472888 +v 0.255276 158.305756 39.440781 1.000000 1.000000 1.000000 +vn -0.688722 0.548316 -0.474354 +v 3.159762 159.675980 38.864979 1.000000 1.000000 1.000000 +vn -0.561613 0.368693 -0.740714 +v 3.324494 159.488998 38.530197 1.000000 1.000000 1.000000 +vn -0.801704 0.372680 -0.467312 +v 3.953454 160.771317 38.633598 1.000000 1.000000 1.000000 +vn -0.647844 0.218778 -0.729681 +v 4.159568 160.641541 38.298779 1.000000 1.000000 1.000000 +vn -0.728932 0.644302 -0.231372 +v 3.063548 159.784805 39.262379 1.000000 1.000000 1.000000 +vn -0.839638 0.500792 -0.210275 +v 3.833076 160.846664 39.030998 1.000000 1.000000 1.000000 +vn -0.885917 0.244186 -0.394366 +v 4.236380 161.399216 38.517601 1.000000 1.000000 1.000000 +vn -0.740599 0.082423 -0.666873 +v 4.666114 162.007584 38.066399 1.000000 1.000000 1.000000 +vn -0.892934 0.014179 -0.449964 +v 4.535848 162.677338 38.298779 1.000000 1.000000 1.000000 +vn -0.688469 -0.129342 -0.713639 +v 4.803682 163.377792 37.848999 1.000000 1.000000 1.000000 +vn -0.877600 -0.193308 -0.438691 +v 4.503776 164.068481 38.067596 1.000000 1.000000 1.000000 +vn -0.688172 -0.341634 -0.640082 +v 4.577458 164.830338 37.616379 1.000000 1.000000 1.000000 +vn -0.972038 0.056066 -0.228033 +v 4.397726 162.694077 38.696381 1.000000 1.000000 1.000000 +vn -0.964257 -0.150969 -0.217755 +v 4.366632 164.044769 38.464996 1.000000 1.000000 1.000000 +vn -0.982753 0.180792 -0.038874 +v 4.250090 162.119202 39.253399 1.000000 1.000000 1.000000 +vn -0.999403 -0.011427 0.032605 +v 4.375402 163.366638 39.035980 1.000000 1.000000 1.000000 +vn -0.892103 0.334607 0.303629 +v 4.223904 161.404800 40.194199 1.000000 1.000000 1.000000 +vn -0.870763 0.490452 0.035047 +v 3.788696 160.874573 39.485779 1.000000 1.000000 1.000000 +vn -0.714747 0.696975 0.057992 +v 3.028078 159.823883 39.717178 1.000000 1.000000 1.000000 +vn -0.773600 0.482886 0.410322 +v 3.941816 160.778290 40.310181 1.000000 1.000000 1.000000 +vn -0.687674 0.600730 0.407711 +v 3.583226 160.204819 40.425377 1.000000 1.000000 1.000000 +vn -0.609855 0.674110 0.416717 +v 3.150466 159.685745 40.541580 1.000000 1.000000 1.000000 +vn -0.554529 0.411719 0.723177 +v 4.145998 160.649918 40.657799 1.000000 1.000000 1.000000 +vn -0.391179 0.566069 0.725635 +v 3.313654 159.501556 40.889198 1.000000 1.000000 1.000000 +vn -0.490491 0.792257 0.362970 +v 2.661390 159.243423 40.656197 1.000000 1.000000 1.000000 +vn 0.077700 0.243587 0.966762 +v 1.687128 158.104828 41.389977 1.000000 1.000000 1.000000 +vn -0.043831 0.269974 0.961869 +v 3.484206 159.309006 41.043800 1.000000 1.000000 1.000000 +vn -0.126801 0.671221 0.730332 +v 1.604524 158.357376 41.235378 1.000000 1.000000 1.000000 +vn -0.438132 0.832413 0.339307 +v 2.117366 158.879242 40.771599 1.000000 1.000000 1.000000 +vn -0.231539 0.861399 0.452086 +v 1.525484 158.597382 40.887798 1.000000 1.000000 1.000000 +vn -0.110316 0.897570 0.426848 +v 0.901424 158.410400 41.003197 1.000000 1.000000 1.000000 +vn -0.070382 0.935129 0.347246 +v 0.267732 158.065765 41.464996 1.000000 1.000000 1.000000 +vn -0.512389 0.857345 0.049171 +v 2.035108 159.048080 39.947197 1.000000 1.000000 1.000000 +vn -0.369970 0.928972 -0.011499 +v 1.466210 158.778778 40.063400 1.000000 1.000000 1.000000 +vn -0.533392 0.815711 -0.223848 +v 2.058940 158.999237 39.492378 1.000000 1.000000 1.000000 +vn 0.044142 0.880359 0.472250 +v 0.254520 158.321106 41.117378 1.000000 1.000000 1.000000 +vn 0.227638 0.633306 0.739665 +v -0.683430 158.111816 41.619980 1.000000 1.000000 1.000000 +vn 0.182644 0.206661 0.961214 +v -0.718564 157.846695 41.774597 1.000000 1.000000 1.000000 +vn 0.230213 0.784077 0.576390 +v -0.649808 158.364365 41.272377 1.000000 1.000000 1.000000 +vn -0.008631 0.972162 0.234151 +v 0.247182 158.463440 40.723598 1.000000 1.000000 1.000000 +vn 0.325741 0.858335 0.396426 +v -1.290352 158.515060 41.382198 1.000000 1.000000 1.000000 +vn 0.404533 0.550974 0.729919 +v -2.002458 158.533188 41.837379 1.000000 1.000000 1.000000 +vn 0.473784 0.758622 0.447237 +v -1.903876 158.764816 41.489777 1.000000 1.000000 1.000000 +vn 0.013130 0.999485 -0.029298 +v -0.001194 158.505295 40.337196 1.000000 1.000000 1.000000 +vn 0.284191 0.957204 0.054741 +v -1.240268 158.699249 40.557800 1.000000 1.000000 1.000000 +vn 0.579964 0.721847 0.377596 +v -2.474950 159.105286 41.594597 1.000000 1.000000 1.000000 +vn 0.557260 0.828634 0.053169 +v -2.378852 159.267136 40.770397 1.000000 1.000000 1.000000 +vn 0.518514 0.818347 -0.247896 +v -2.406714 159.219711 40.315578 1.000000 1.000000 1.000000 +vn 0.322530 0.839073 -0.438099 +v -1.909502 158.750870 39.813198 1.000000 1.000000 1.000000 +vn 0.707689 0.577408 0.407158 +v -3.106834 159.641098 41.720779 1.000000 1.000000 1.000000 +vn 0.557135 0.397855 0.728911 +v -3.267716 159.454117 42.068398 1.000000 1.000000 1.000000 +vn 0.734798 0.676278 0.052164 +v -2.986196 159.780624 40.896400 1.000000 1.000000 1.000000 +vn 0.685354 0.689963 -0.232897 +v -3.021164 159.740158 40.441597 1.000000 1.000000 1.000000 +vn 0.590765 0.649107 -0.479224 +v -3.116012 159.629929 40.044197 1.000000 1.000000 1.000000 +vn 0.446584 0.753227 -0.482920 +v -2.482264 159.094116 39.917976 1.000000 1.000000 1.000000 +vn 0.723656 0.504460 -0.471000 +v -3.937966 160.739212 40.243980 1.000000 1.000000 1.000000 +vn 0.834650 0.496729 -0.237949 +v -3.818102 160.815964 40.641579 1.000000 1.000000 1.000000 +vn 0.879327 0.472765 0.057250 +v -3.773916 160.843872 41.096378 1.000000 1.000000 1.000000 +vn 0.816774 0.413553 0.402310 +v -3.926380 160.746201 41.920597 1.000000 1.000000 1.000000 +vn 0.879799 0.259767 0.398089 +v -4.215046 161.379669 42.016598 1.000000 1.000000 1.000000 +vn 0.900530 0.161776 0.403577 +v -4.416588 162.048050 42.109779 1.000000 1.000000 1.000000 +vn 0.965641 0.255580 0.047089 +v -4.245082 162.094086 41.285400 1.000000 1.000000 1.000000 +vn 0.650712 0.242447 0.719579 +v -4.129698 160.617828 42.268379 1.000000 1.000000 1.000000 +vn 0.848068 0.186284 0.496064 +v -4.645308 161.985245 42.457397 1.000000 1.000000 1.000000 +vn 0.918081 0.022504 0.395754 +v -4.530710 162.749893 42.202579 1.000000 1.000000 1.000000 +vn -0.237104 -0.119448 0.964113 +v -5.270908 163.494995 42.791580 1.000000 1.000000 1.000000 +vn 0.264584 0.081183 0.960939 +v -3.435836 159.258774 42.222977 1.000000 1.000000 1.000000 +vn 0.227071 0.134542 0.964540 +v -2.105468 158.290405 41.991997 1.000000 1.000000 1.000000 +vn 0.994856 0.101186 0.004705 +v -4.354776 162.769424 41.378197 1.000000 1.000000 1.000000 +vn 0.896458 -0.096730 0.432442 +v -4.550550 163.461517 42.293198 1.000000 1.000000 1.000000 +vn 0.966675 0.074621 -0.244890 +v -4.405760 162.763855 40.923397 1.000000 1.000000 1.000000 +vn 0.894843 0.164471 -0.414976 +v -4.544086 162.748505 40.525997 1.000000 1.000000 1.000000 +vn 0.956253 0.002318 -0.292531 +v -4.425046 163.455933 41.014000 1.000000 1.000000 1.000000 +vn 0.999246 -0.038821 0.000874 +v -4.373830 163.453140 41.468800 1.000000 1.000000 1.000000 +vn 0.982725 -0.152728 -0.104523 +v -4.301242 164.131271 41.556999 1.000000 1.000000 1.000000 +vn 0.536348 0.699099 -0.472855 +v -4.801854 163.474075 40.281799 1.000000 1.000000 1.000000 +vn 0.873935 -0.238612 0.423440 +v -4.475014 164.167557 42.381180 1.000000 1.000000 1.000000 +vn 0.722681 0.229613 -0.651928 +v -4.660488 161.981064 40.098396 1.000000 1.000000 1.000000 +vn 0.338774 0.137815 -0.930720 +v -5.020622 163.483841 40.145996 1.000000 1.000000 1.000000 +vn 0.778834 0.323467 -0.537389 +v -4.227482 161.375488 40.339996 1.000000 1.000000 1.000000 +vn 0.450247 0.363787 -0.815437 +v -4.143204 160.608047 39.909199 1.000000 1.000000 1.000000 +vn 0.184162 0.183158 -0.965680 +v -4.650458 161.187119 39.869400 1.000000 1.000000 1.000000 +vn 0.483442 0.636516 -0.600941 +v -3.278402 159.441559 39.709396 1.000000 1.000000 1.000000 +vn 0.251782 0.616951 -0.745639 +v -2.611630 158.876450 39.583397 1.000000 1.000000 1.000000 +vn -0.238543 -0.002968 -0.971127 +v -4.533104 160.359695 39.768398 1.000000 1.000000 1.000000 +vn -0.339590 0.031965 -0.940030 +v -5.099082 161.862457 39.957581 1.000000 1.000000 1.000000 +vn -0.654101 -0.158492 -0.739617 +v -5.094394 160.990372 40.015396 1.000000 1.000000 1.000000 +vn -0.581629 -0.342153 -0.737997 +v -4.295384 159.518295 39.820599 1.000000 1.000000 1.000000 +vn -0.259926 -0.097367 -0.960707 +v -3.586896 159.082962 39.568581 1.000000 1.000000 1.000000 +vn -0.672985 0.009419 -0.739596 +v -5.475926 162.645248 40.201401 1.000000 1.000000 1.000000 +vn -0.272080 0.121413 -0.954584 +v -5.253746 163.494995 40.140999 1.000000 1.000000 1.000000 +vn -0.866510 -0.149718 -0.476178 +v -5.567918 161.734100 40.452980 1.000000 1.000000 1.000000 +vn -0.894594 -0.039284 -0.445149 +v -5.711780 162.620132 40.545799 1.000000 1.000000 1.000000 +vn -0.682346 0.113035 -0.722237 +v -5.499900 163.506165 40.292000 1.000000 1.000000 1.000000 +vn -0.250318 0.180274 -0.951232 +v -4.973088 165.095459 40.313999 1.000000 1.000000 1.000000 +vn -0.104002 0.177904 -0.978537 +v -4.308620 166.514511 40.475197 1.000000 1.000000 1.000000 +vn -0.625510 0.273704 -0.730632 +v -5.206096 165.181961 40.464996 1.000000 1.000000 1.000000 +vn -0.891974 0.078907 -0.445146 +v -5.736796 163.517334 40.636398 1.000000 1.000000 1.000000 +vn -0.856169 0.196462 -0.477888 +v -5.641562 164.406158 40.724400 1.000000 1.000000 1.000000 +vn -0.982659 -0.076456 -0.168925 +v -5.844006 162.604782 40.938999 1.000000 1.000000 1.000000 +vn -0.984068 0.055285 -0.168981 +v -5.869586 163.524307 41.029598 1.000000 1.000000 1.000000 +vn -0.967705 0.186526 -0.169574 +v -5.772150 164.434067 41.117599 1.000000 1.000000 1.000000 +vn -0.838683 0.309092 -0.448412 +v -5.430338 165.265686 40.809601 1.000000 1.000000 1.000000 +vn -0.934714 0.311926 -0.170331 +v -5.556034 165.311722 41.202797 1.000000 1.000000 1.000000 +vn -0.775165 0.410262 -0.480421 +v -5.129762 166.040100 40.888199 1.000000 1.000000 1.000000 +vn -0.886130 0.430492 -0.171610 +v -5.248506 166.104279 41.281399 1.000000 1.000000 1.000000 +vn -0.725219 0.516839 -0.454900 +v -4.704764 166.814514 40.970798 1.000000 1.000000 1.000000 +vn -0.526468 0.425077 -0.736303 +v -4.510484 166.666595 40.626198 1.000000 1.000000 1.000000 +vn -0.901810 0.405682 0.148869 +v -5.259990 166.111252 42.096798 1.000000 1.000000 1.000000 +vn -0.819209 0.546683 -0.173303 +v -4.813672 166.896835 41.363800 1.000000 1.000000 1.000000 +vn -0.947032 0.284955 0.148092 +v -5.568188 165.317307 42.018196 1.000000 1.000000 1.000000 +vn -0.889112 0.112805 0.443571 +v -5.635870 164.406158 42.401398 1.000000 1.000000 1.000000 +vn -0.851845 0.221522 0.474645 +v -5.424840 165.262894 42.486580 1.000000 1.000000 1.000000 +vn -0.976465 0.157399 0.147451 +v -5.784794 164.435455 41.933197 1.000000 1.000000 1.000000 +vn -0.988797 0.024804 0.147194 +v -5.882424 163.524307 41.844997 1.000000 1.000000 1.000000 +vn -0.827271 0.339990 0.447246 +v -5.124586 166.037308 42.565201 1.000000 1.000000 1.000000 +vn -0.838053 0.524450 0.150399 +v -4.824204 166.905197 42.179398 1.000000 1.000000 1.000000 +vn -0.597078 0.204406 0.775704 +v -4.913028 165.921494 42.902977 1.000000 1.000000 1.000000 +vn -0.772227 0.448204 0.450311 +v -4.700014 166.810318 42.647579 1.000000 1.000000 1.000000 +vn -0.754728 0.638218 0.151865 +v -4.288560 167.621002 42.259598 1.000000 1.000000 1.000000 +vn -0.545023 0.255171 0.798648 +v -4.505990 166.663803 42.985397 1.000000 1.000000 1.000000 +vn -0.686625 0.542425 0.484067 +v -4.178158 167.507980 42.727997 1.000000 1.000000 1.000000 +vn -0.653668 0.741136 0.153090 +v -3.663630 168.243317 42.337379 1.000000 1.000000 1.000000 +vn -0.733021 0.657278 -0.175117 +v -4.279188 167.611237 41.444199 1.000000 1.000000 1.000000 +vn -0.629088 0.603045 -0.490496 +v -4.182382 167.512177 41.050999 1.000000 1.000000 1.000000 +vn -0.629301 0.756951 -0.176083 +v -3.655634 168.232162 41.521999 1.000000 1.000000 1.000000 +vn -0.545895 0.698572 -0.462597 +v -3.572926 168.120529 41.128799 1.000000 1.000000 1.000000 +vn -0.380732 0.549481 -0.743716 +v -3.425394 167.918213 40.784397 1.000000 1.000000 1.000000 +vn -0.426602 0.756376 -0.495889 +v -2.898944 168.617279 41.202999 1.000000 1.000000 1.000000 +vn -0.511410 0.840549 -0.178708 +v -2.966048 168.741455 41.596199 1.000000 1.000000 1.000000 +vn -0.537296 0.829024 0.155024 +v -2.972524 168.754013 42.411579 1.000000 1.000000 1.000000 +vn -0.193279 0.629400 -0.752661 +v -2.064348 168.776352 40.931999 1.000000 1.000000 1.000000 +vn -0.317901 0.824138 -0.468760 +v -2.153234 169.013550 41.276600 1.000000 1.000000 1.000000 +vn -0.380742 0.906928 -0.180327 +v -2.203074 169.147507 41.669598 1.000000 1.000000 1.000000 +vn -0.587186 0.628245 0.510413 +v -3.569322 168.114960 42.805798 1.000000 1.000000 1.000000 +vn -0.513557 0.702759 0.492330 +v -2.896022 168.611694 42.879997 1.000000 1.000000 1.000000 +vn -0.403782 0.898500 0.172216 +v -2.207888 169.160065 42.485180 1.000000 1.000000 1.000000 +vn -0.261777 0.520676 0.812631 +v -2.163818 168.879593 43.186779 1.000000 1.000000 1.000000 +vn -0.335683 0.270200 0.902391 +v -3.702628 167.477295 43.189796 1.000000 1.000000 1.000000 +vn -0.269063 0.945717 0.182275 +v -1.393634 169.446106 42.557198 1.000000 1.000000 1.000000 +vn -0.146779 0.555955 0.818150 +v -1.099018 169.260529 43.189796 1.000000 1.000000 1.000000 +vn -0.124859 0.977512 0.169943 +v -0.552534 169.600983 42.627197 1.000000 1.000000 1.000000 +vn -0.017173 0.609916 0.792280 +v 0.000000 169.464233 43.189796 1.000000 1.000000 1.000000 +vn 0.052525 0.986283 0.156480 +v 0.297612 169.621918 42.694798 1.000000 1.000000 1.000000 +vn -0.087181 0.979467 -0.181780 +v -0.551326 169.587036 41.811577 1.000000 1.000000 1.000000 +vn -0.237801 0.954317 -0.180912 +v -1.390582 169.432159 41.741600 1.000000 1.000000 1.000000 +vn -0.052428 0.879710 -0.472612 +v -0.538860 169.443314 41.418400 1.000000 1.000000 1.000000 +vn -0.181897 0.845832 -0.501480 +v -1.359142 169.292618 41.348598 1.000000 1.000000 1.000000 +vn 0.066484 0.981179 -0.181293 +v 0.296952 169.607971 41.879196 1.000000 1.000000 1.000000 +vn 0.083892 0.877453 -0.472270 +v 0.290224 169.464233 41.486000 1.000000 1.000000 1.000000 +vn 0.192779 0.962717 0.189767 +v 1.120400 169.513077 42.758198 1.000000 1.000000 1.000000 +vn 0.243845 0.647408 0.722082 +v 1.942976 169.189362 43.187981 1.000000 1.000000 1.000000 +vn 0.355205 0.920052 -0.165328 +v 1.939680 169.257736 42.005997 1.000000 1.000000 1.000000 +vn 0.216730 0.959402 -0.180488 +v 1.117954 169.499130 41.942780 1.000000 1.000000 1.000000 +vn 0.216389 0.838517 -0.500066 +v 1.092642 169.358200 41.549599 1.000000 1.000000 1.000000 +vn 0.110088 0.655622 -0.747022 +v 0.278212 169.207504 41.141598 1.000000 1.000000 1.000000 +vn 0.345026 0.813590 -0.468005 +v 1.895764 169.122391 41.612801 1.000000 1.000000 1.000000 +vn 0.293470 0.592089 -0.750537 +v 1.817446 168.879593 41.268196 1.000000 1.000000 1.000000 +vn 0.457698 0.737656 -0.496363 +v 2.660656 168.762390 41.673981 1.000000 1.000000 1.000000 +vn 0.404030 0.462239 -0.789364 +v 3.230444 168.078674 41.388580 1.000000 1.000000 1.000000 +vn 0.252013 0.136887 -0.957993 +v 3.671406 167.327988 41.294579 1.000000 1.000000 1.000000 +vn 0.183502 0.229541 -0.955844 +v 1.736066 168.627045 41.117199 1.000000 1.000000 1.000000 +vn 0.571370 0.678219 -0.462120 +v 3.369634 168.286591 41.733200 1.000000 1.000000 1.000000 +vn 0.492533 0.838798 -0.232013 +v 2.722262 168.890762 42.067177 1.000000 1.000000 1.000000 +vn 0.533366 0.421967 -0.733120 +v 3.843478 167.519150 41.445599 1.000000 1.000000 1.000000 +vn 0.664295 0.590754 -0.457954 +v 4.009060 167.703339 41.790176 1.000000 1.000000 1.000000 +vn 0.612542 0.756467 -0.229238 +v 3.447656 168.403793 42.126198 1.000000 1.000000 1.000000 +vn 0.605559 0.795766 0.007454 +v 3.475542 168.445648 42.531776 1.000000 1.000000 1.000000 +vn 0.481206 0.875369 0.046581 +v 2.744278 168.936798 42.472580 1.000000 1.000000 1.000000 +vn 0.716003 0.660470 -0.226094 +v 4.101888 167.806595 42.183197 1.000000 1.000000 1.000000 +vn 0.734459 0.678653 -0.000517 +v 4.135066 167.842865 42.588779 1.000000 1.000000 1.000000 +vn 0.730141 0.481996 -0.484329 +v 4.547202 167.047531 41.843201 1.000000 1.000000 1.000000 +vn 0.802179 0.553315 -0.224394 +v 4.652480 167.135422 42.236397 1.000000 1.000000 1.000000 +vn 0.814988 0.577758 0.044625 +v 4.690112 167.167526 42.641800 1.000000 1.000000 1.000000 +vn 0.464070 0.518641 0.718089 +v 3.805704 168.095428 43.189796 1.000000 1.000000 1.000000 +vn 0.626455 0.333371 0.704569 +v 5.085614 166.422409 43.189796 1.000000 1.000000 1.000000 +vn 0.879076 0.442884 -0.176294 +v 5.123556 166.362411 42.289177 1.000000 1.000000 1.000000 +vn 0.804390 0.387506 -0.450328 +v 5.007606 166.292648 41.895981 1.000000 1.000000 1.000000 +vn 0.923560 0.313909 -0.220224 +v 5.486716 165.522430 42.339996 1.000000 1.000000 1.000000 +vn 0.835649 0.267134 -0.479927 +v 5.362552 165.470795 41.946800 1.000000 1.000000 1.000000 +vn 0.624277 0.273803 -0.731649 +v 4.800786 166.167068 41.551579 1.000000 1.000000 1.000000 +vn 0.880281 0.160889 -0.446341 +v 5.606092 164.594528 41.995598 1.000000 1.000000 1.000000 +vn 0.677707 0.101041 -0.728357 +v 5.374538 164.538712 41.650997 1.000000 1.000000 1.000000 +vn 0.963736 0.192649 -0.184660 +v 5.735882 164.625229 42.388580 1.000000 1.000000 1.000000 +vn 0.879046 0.043764 -0.474723 +v 5.721758 163.783829 42.037376 1.000000 1.000000 1.000000 +vn 0.681991 -0.075004 -0.727505 +v 5.496062 162.893616 41.737396 1.000000 1.000000 1.000000 +vn 0.259608 -0.042439 -0.964781 +v 5.250038 162.908966 41.586197 1.000000 1.000000 1.000000 +vn 0.195363 -0.011804 -0.980660 +v 5.133934 164.481506 41.500000 1.000000 1.000000 1.000000 +vn 0.892406 -0.070937 -0.445623 +v 5.732844 162.878265 42.081779 1.000000 1.000000 1.000000 +vn 0.978521 0.064168 -0.195906 +v 5.854228 163.796402 42.430580 1.000000 1.000000 1.000000 +vn 0.858099 -0.187028 -0.478211 +v 5.620910 161.979675 42.124001 1.000000 1.000000 1.000000 +vn 0.978135 -0.065583 -0.197362 +v 5.865582 162.869888 42.474979 1.000000 1.000000 1.000000 +vn 0.630959 -0.279869 -0.723577 +v 5.171670 161.206650 41.819000 1.000000 1.000000 1.000000 +vn 0.252106 -0.140205 -0.957489 +v 4.940142 161.298752 41.667976 1.000000 1.000000 1.000000 +vn 0.481247 -0.465272 -0.742915 +v 3.991436 159.141571 41.919979 1.000000 1.000000 1.000000 +vn 0.192065 -0.218528 -0.956743 +v 3.812758 159.324356 41.768997 1.000000 1.000000 1.000000 +vn 0.336945 -0.509647 -0.791661 +v 2.887098 158.166214 41.974979 1.000000 1.000000 1.000000 +vn -0.549887 -0.304588 -0.777721 +v 1.798108 157.938782 41.830997 1.000000 1.000000 1.000000 +vn -0.180951 0.114469 -0.976808 +v 3.643532 159.498764 41.773979 1.000000 1.000000 1.000000 +vn -0.828860 0.239700 -0.505505 +v 1.616110 158.464828 42.119797 1.000000 1.000000 1.000000 +vn -0.436442 0.538488 -0.720797 +v 2.520566 158.812271 41.964798 1.000000 1.000000 1.000000 +vn -0.266795 0.039712 -0.962935 +v 4.720896 161.385269 41.673180 1.000000 1.000000 1.000000 +vn -0.662637 0.372454 -0.649762 +v 3.933782 160.257828 41.875580 1.000000 1.000000 1.000000 +vn -0.182278 0.022462 -0.982990 +v 5.017030 162.924316 41.591400 1.000000 1.000000 1.000000 +vn -0.612222 -0.107378 -0.783361 +v 4.789068 163.697327 41.682800 1.000000 1.000000 1.000000 +vn -0.553551 -0.277417 -0.785252 +v 4.488416 165.109406 41.592178 1.000000 1.000000 1.000000 +vn 0.292268 0.082679 -0.952756 +v 4.585866 166.035904 41.400597 1.000000 1.000000 1.000000 +vn -0.084433 -0.193809 -0.977399 +v 3.508462 167.146591 41.299599 1.000000 1.000000 1.000000 +vn -0.003665 -0.236511 -0.971622 +v 1.658996 168.388443 41.122398 1.000000 1.000000 1.000000 +vn 0.081477 -0.229556 -0.969879 +v 0.253920 168.687042 40.995598 1.000000 1.000000 1.000000 +vn 0.103096 0.258889 -0.960390 +v 0.265736 168.939590 40.990601 1.000000 1.000000 1.000000 +vn 0.187239 -0.193748 -0.963018 +v -1.884474 168.293564 40.785999 1.000000 1.000000 1.000000 +vn -0.018855 0.604034 -0.796736 +v -0.516632 169.187958 41.073997 1.000000 1.000000 1.000000 +vn -0.017261 0.288792 -0.957236 +v -1.971958 168.527969 40.780998 1.000000 1.000000 1.000000 +vn -0.109412 0.236637 -0.965418 +v -3.272094 167.710312 40.633400 1.000000 1.000000 1.000000 +vn 0.137348 -0.114883 -0.983838 +v -3.126918 167.512177 40.638397 1.000000 1.000000 1.000000 +vn 0.528264 -0.326600 -0.783753 +v -3.500790 166.817291 40.696400 1.000000 1.000000 1.000000 +vn 0.643359 -0.159718 -0.748718 +v -4.293762 165.585205 40.533600 1.000000 1.000000 1.000000 +vn -0.672418 0.631844 -0.385522 +v 3.312044 159.840622 42.244579 1.000000 1.000000 1.000000 +vn -0.795364 0.449405 -0.406734 +v 3.738858 160.405731 42.210381 1.000000 1.000000 1.000000 +vn -0.792169 0.264907 -0.549811 +v 4.291418 161.554092 42.143780 1.000000 1.000000 1.000000 +vn -0.652375 0.170543 -0.738459 +v 4.515144 161.466187 41.808998 1.000000 1.000000 1.000000 +vn -0.510667 0.712342 -0.481444 +v 2.395654 159.031326 42.299580 1.000000 1.000000 1.000000 +vn -0.901940 0.379820 -0.205528 +v 1.534780 158.706223 42.600380 1.000000 1.000000 1.000000 +vn -0.549129 0.789964 -0.272791 +v 2.322706 159.159698 42.696980 1.000000 1.000000 1.000000 +vn -0.684597 0.686927 -0.243841 +v 3.211196 159.943878 42.642197 1.000000 1.000000 1.000000 +vn -0.770014 0.317716 0.553295 +v 1.510808 158.777374 43.189598 1.000000 1.000000 1.000000 +vn -0.491841 0.507917 0.707186 +v 2.987986 159.770859 43.189377 1.000000 1.000000 1.000000 +vn -0.638972 0.373594 0.672416 +v 3.666012 160.647125 43.189796 1.000000 1.000000 1.000000 +vn -0.676591 0.190570 0.711272 +v 4.198616 161.877808 43.188580 1.000000 1.000000 1.000000 +vn -0.965643 0.190549 -0.176706 +v 4.335400 162.269897 42.501801 1.000000 1.000000 1.000000 +vn -0.690259 -0.005299 0.723543 +v 4.399812 163.260590 43.189796 1.000000 1.000000 1.000000 +vn -0.924260 0.039596 -0.379704 +v 4.560606 162.953613 42.061996 1.000000 1.000000 1.000000 +vn -0.980682 0.013486 -0.195141 +v 4.421738 162.963379 42.459396 1.000000 1.000000 1.000000 +vn -0.877629 -0.197154 -0.436918 +v 4.459756 164.319641 41.975777 1.000000 1.000000 1.000000 +vn -0.941286 -0.336795 -0.023464 +v 4.088228 164.943359 42.779198 1.000000 1.000000 1.000000 +vn -0.593182 -0.462299 -0.659101 +v 3.805962 166.429398 41.488579 1.000000 1.000000 1.000000 +vn 0.941403 0.328387 0.076955 +v 5.531096 165.540558 42.745377 1.000000 1.000000 1.000000 +vn 0.738868 0.095558 0.667040 +v 5.885874 164.023834 43.188198 1.000000 1.000000 1.000000 +vn 0.035930 0.605411 -0.795102 +v -1.361588 158.254135 39.370796 1.000000 1.000000 1.000000 +vn 0.085596 0.882369 -0.462707 +v -0.651722 158.350403 39.595798 1.000000 1.000000 1.000000 +vn -0.060004 0.963100 -0.262371 +v 0.247488 158.456451 39.838181 1.000000 1.000000 1.000000 +vn -0.253492 0.960682 -0.113275 +v 0.866386 158.598785 40.178799 1.000000 1.000000 1.000000 +vn -0.463864 -0.476587 -0.746790 +v -2.991230 158.241562 39.593376 1.000000 1.000000 1.000000 +vn -0.873328 0.216676 0.436291 +v 4.522482 162.678726 39.975399 1.000000 1.000000 1.000000 +vn -0.660085 0.216256 0.719389 +v 4.756740 162.649429 40.323196 1.000000 1.000000 1.000000 +vn -0.132511 0.236681 0.962509 +v 4.359384 160.515976 40.812401 1.000000 1.000000 1.000000 +vn -0.915469 0.052797 0.398911 +v 4.552224 163.370819 39.860378 1.000000 1.000000 1.000000 +vn -0.987065 -0.160230 0.005407 +v 4.316086 164.035004 38.919777 1.000000 1.000000 1.000000 +vn -0.220178 0.179537 0.958795 +v 5.001554 162.618729 40.477798 1.000000 1.000000 1.000000 +vn -0.064627 -0.585162 -0.808337 +v 0.307750 157.292740 39.115978 1.000000 1.000000 1.000000 +vn 0.109748 -0.654777 -0.747812 +v 1.843904 157.627625 38.886597 1.000000 1.000000 1.000000 +vn 0.535836 0.829927 0.155244 +v 3.118626 168.660538 38.602798 1.000000 1.000000 1.000000 +vn 0.840601 0.307964 0.445588 +v 5.463400 165.135910 39.647797 1.000000 1.000000 1.000000 +vn 0.974145 0.171077 0.147558 +v 5.805174 164.305695 39.295979 1.000000 1.000000 1.000000 +vn 0.575931 0.287676 0.765210 +v 5.237808 165.059174 39.985580 1.000000 1.000000 1.000000 +vn 0.857844 0.196022 0.475058 +v 5.655698 164.279190 39.764397 1.000000 1.000000 1.000000 +vn 0.988237 0.041401 0.147222 +v 5.884934 163.407104 39.412201 1.000000 1.000000 1.000000 +vn -0.983254 -0.068280 -0.168968 +v -5.846606 162.625717 35.962196 1.000000 1.000000 1.000000 +vn -0.895516 -0.023938 -0.444386 +v -5.714318 162.639664 35.569000 1.000000 1.000000 1.000000 +vn -0.884371 -0.139943 -0.445314 +v -5.576350 161.767578 35.452599 1.000000 1.000000 1.000000 +vn 0.731057 -0.133248 -0.669179 +v -4.578296 164.831726 35.547997 1.000000 1.000000 1.000000 +vn 0.695858 0.085485 -0.713074 +v -4.801776 163.475464 35.330597 1.000000 1.000000 1.000000 +vn 0.630355 -0.400865 -0.664800 +v -3.571254 166.733566 35.895599 1.000000 1.000000 1.000000 +vn 0.781766 -0.284030 -0.555129 +v -4.111248 165.406616 35.999199 1.000000 1.000000 1.000000 +vn 0.890083 -0.070692 -0.450283 +v -4.490424 164.154999 35.780399 1.000000 1.000000 1.000000 +vn 0.817060 -0.425828 -0.388694 +v -3.789404 166.013580 36.115196 1.000000 1.000000 1.000000 +vn 0.964243 -0.129871 -0.231019 +v -4.353732 164.127090 36.177998 1.000000 1.000000 1.000000 +vn 0.971935 0.089581 -0.217527 +v -4.407716 162.779190 35.946598 1.000000 1.000000 1.000000 +vn 0.998131 -0.051675 0.032620 +v -4.373754 163.455933 36.517601 1.000000 1.000000 1.000000 +vn 0.888307 0.137364 -0.438225 +v -4.546108 162.763855 35.549198 1.000000 1.000000 1.000000 +vn 0.995198 0.097723 0.005550 +v -4.356706 162.783386 36.401379 1.000000 1.000000 1.000000 +vn 0.971062 0.238665 0.008817 +v -4.251520 162.120590 36.284981 1.000000 1.000000 1.000000 +vn 0.854937 0.296266 -0.425804 +v -4.436350 162.070374 35.432598 1.000000 1.000000 1.000000 +vn 0.857211 -0.271732 0.437437 +v -4.477214 164.152206 37.457001 1.000000 1.000000 1.000000 +vn 0.910112 -0.110518 0.399352 +v -4.550472 163.464310 37.341999 1.000000 1.000000 1.000000 +vn 0.855403 0.465354 -0.227444 +v -3.839900 160.856430 35.599396 1.000000 1.000000 1.000000 +vn 0.888827 0.455745 0.047794 +v -3.795468 160.884338 36.054176 1.000000 1.000000 1.000000 +vn 0.755074 0.457013 -0.470109 +v -3.960458 160.781082 35.201996 1.000000 1.000000 1.000000 +vn 0.710207 0.296668 -0.638431 +v -4.667556 162.008972 35.098000 1.000000 1.000000 1.000000 +vn 0.535246 0.412560 -0.737093 +v -4.166868 160.652710 34.867199 1.000000 1.000000 1.000000 +vn 0.679124 0.594985 -0.429864 +v -3.603750 160.207596 35.087399 1.000000 1.000000 1.000000 +vn 0.782044 0.556625 -0.280314 +v -3.494068 160.299698 35.484798 1.000000 1.000000 1.000000 +vn 0.706094 0.706312 0.050536 +v -3.038662 159.835052 35.823399 1.000000 1.000000 1.000000 +vn 0.461780 0.577750 -0.673026 +v -3.335992 159.500168 34.636398 1.000000 1.000000 1.000000 +vn 0.500396 0.865750 -0.009026 +v -2.042486 159.052261 35.592400 1.000000 1.000000 1.000000 +vn 0.502400 0.765780 -0.401466 +v -2.679326 159.239243 34.855999 1.000000 1.000000 1.000000 +vn 0.324407 0.945899 0.005968 +v -1.472660 158.781570 35.475800 1.000000 1.000000 1.000000 +vn 0.346952 0.741287 -0.574558 +v -2.131258 158.870865 34.739998 1.000000 1.000000 1.000000 +vn 0.187408 0.951091 -0.245570 +v -0.959506 158.563889 34.918800 1.000000 1.000000 1.000000 +vn 0.112024 0.869452 -0.481149 +v -0.989624 158.417374 34.521198 1.000000 1.000000 1.000000 +vn 0.098284 0.994613 0.032932 +v -0.340608 158.519241 35.258400 1.000000 1.000000 1.000000 +vn -0.067564 0.969783 -0.234428 +v 0.282692 158.459244 34.687401 1.000000 1.000000 1.000000 +vn -0.126199 0.874843 -0.467679 +v 0.291592 158.308548 34.290001 1.000000 1.000000 1.000000 +vn -0.307112 0.839889 -0.447515 +v 0.934202 158.404831 34.173401 1.000000 1.000000 1.000000 +vn -0.076277 0.997069 0.005878 +v 0.279410 158.515060 35.142197 1.000000 1.000000 1.000000 +vn -0.242314 0.970142 0.010392 +v 0.895256 158.605759 35.025799 1.000000 1.000000 1.000000 +vn -0.481308 0.731421 -0.483080 +v 2.139704 158.875061 33.942799 1.000000 1.000000 1.000000 +vn -0.493761 0.836791 -0.236602 +v 2.074556 159.009003 34.340199 1.000000 1.000000 1.000000 +vn -0.431887 0.512561 -0.742129 +v 2.251276 158.647614 33.607998 1.000000 1.000000 1.000000 +vn -0.623212 0.650533 -0.434066 +v 2.681346 159.242035 33.828201 1.000000 1.000000 1.000000 +vn -0.587420 0.756672 -0.287028 +v 2.599708 159.364807 34.225601 1.000000 1.000000 1.000000 +vn -0.484399 0.873445 0.049524 +v 2.050520 159.057831 34.794998 1.000000 1.000000 1.000000 +vn -0.737775 0.673136 0.050764 +v 3.044314 159.842026 34.564198 1.000000 1.000000 1.000000 +vn -0.600854 0.440693 -0.666907 +v 3.342314 159.508545 33.377197 1.000000 1.000000 1.000000 +vn -0.786801 0.478116 -0.390320 +v 3.605308 160.210388 33.596798 1.000000 1.000000 1.000000 +vn -0.882887 0.469514 -0.008177 +v 3.799344 160.894104 34.333199 1.000000 1.000000 1.000000 +vn -0.720280 0.179199 -0.670138 +v 4.466748 161.330841 33.029598 1.000000 1.000000 1.000000 +vn -0.760959 0.333240 -0.556680 +v 3.964578 160.792236 33.480797 1.000000 1.000000 1.000000 +vn -0.953994 0.190696 -0.231367 +v 4.287080 162.050842 33.659599 1.000000 1.000000 1.000000 +vn -0.950327 0.311182 0.006690 +v 4.068504 161.502472 34.216599 1.000000 1.000000 1.000000 +vn -0.677280 0.587552 0.442803 +v 3.594686 160.220154 35.273399 1.000000 1.000000 1.000000 +vn -0.629186 0.701751 0.334172 +v 3.167344 159.703888 35.388599 1.000000 1.000000 1.000000 +vn -0.484976 0.493566 0.721935 +v 3.780894 160.062485 35.620998 1.000000 1.000000 1.000000 +vn -0.840267 0.447218 0.306508 +v 3.952902 160.799210 35.157398 1.000000 1.000000 1.000000 +vn -0.226442 0.644468 0.730332 +v 2.243938 158.662964 35.966999 1.000000 1.000000 1.000000 +vn -0.530247 0.765014 0.365501 +v 2.673454 159.254593 35.504601 1.000000 1.000000 1.000000 +vn -0.239735 0.898205 0.368450 +v 1.547706 158.607147 35.734798 1.000000 1.000000 1.000000 +vn 0.064707 0.671977 0.737740 +v 0.305814 158.068542 36.314178 1.000000 1.000000 1.000000 +vn -0.392729 0.816095 0.423973 +v 2.133408 158.889008 35.619400 1.000000 1.000000 1.000000 +vn -0.175232 0.922121 0.344944 +v 0.931452 158.418777 35.849998 1.000000 1.000000 1.000000 +vn 0.033156 0.890358 0.454053 +v 0.290726 158.323898 35.966599 1.000000 1.000000 1.000000 +vn 0.160148 0.890101 0.426700 +v -0.354350 158.328079 36.082779 1.000000 1.000000 1.000000 +vn 0.339079 0.821595 0.458264 +v -0.986706 158.431335 36.197777 1.000000 1.000000 1.000000 +vn 0.307864 0.599998 0.738392 +v -1.037784 158.181564 36.545601 1.000000 1.000000 1.000000 +vn 0.471607 0.821995 0.319236 +v -2.125000 158.883423 36.416580 1.000000 1.000000 1.000000 +vn 0.516585 0.462943 0.720295 +v -2.809772 159.043900 36.880180 1.000000 1.000000 1.000000 +vn 0.214304 0.182501 0.959566 +v -1.091150 157.920654 36.700180 1.000000 1.000000 1.000000 +vn 0.266736 0.087923 0.959751 +v -2.954332 158.827621 37.034779 1.000000 1.000000 1.000000 +vn 0.138031 0.230750 0.963173 +v 0.321580 157.802048 36.468781 1.000000 1.000000 1.000000 +vn 0.035677 0.262909 0.964161 +v 2.359424 158.427155 36.121578 1.000000 1.000000 1.000000 +vn -0.085413 0.254833 0.963205 +v 3.975484 159.899231 35.775597 1.000000 1.000000 1.000000 +vn -0.837612 0.325963 0.438354 +v 4.408696 162.015945 34.938599 1.000000 1.000000 1.000000 +vn -0.624421 0.298277 0.721893 +v 4.637042 161.953156 35.286400 1.000000 1.000000 1.000000 +vn -0.191517 0.206226 0.959579 +v 4.875704 161.886185 35.440998 1.000000 1.000000 1.000000 +vn -0.901200 0.167664 0.399660 +v 4.525122 162.698273 34.823601 1.000000 1.000000 1.000000 +vn -0.697290 0.080173 0.712291 +v 4.787176 163.404312 35.055000 1.000000 1.000000 1.000000 +vn -0.999384 -0.034645 0.005533 +v 4.374628 163.390350 33.882999 1.000000 1.000000 1.000000 +vn -0.992882 0.114546 0.032616 +v 4.349356 162.719193 33.999199 1.000000 1.000000 1.000000 +vn -0.902346 0.058499 0.427024 +v 4.551426 163.395935 34.707397 1.000000 1.000000 1.000000 +vn -0.984250 -0.176562 0.008819 +v 4.311490 164.060120 33.766598 1.000000 1.000000 1.000000 +vn 0.617493 0.648642 0.444934 +v -2.671446 159.251785 36.532600 1.000000 1.000000 1.000000 +vn 0.729442 0.598927 0.330456 +v -3.161410 159.696899 36.647797 1.000000 1.000000 1.000000 +vn 0.668668 0.223091 0.709304 +v -4.153284 160.661087 37.226196 1.000000 1.000000 1.000000 +vn 0.788161 0.502883 0.354840 +v -3.593140 160.215973 36.763779 1.000000 1.000000 1.000000 +vn 0.833903 0.373272 0.406539 +v -3.948794 160.788055 36.878601 1.000000 1.000000 1.000000 +vn 0.908142 0.236670 0.345349 +v -4.227740 161.413162 36.993980 1.000000 1.000000 1.000000 +vn 0.701424 -0.036135 0.711828 +v -4.767452 162.740128 37.573399 1.000000 1.000000 1.000000 +vn 0.929079 0.183182 0.321335 +v -4.423282 162.074554 37.109177 1.000000 1.000000 1.000000 +vn 0.904301 -0.001456 0.426892 +v -4.532718 162.765244 37.225777 1.000000 1.000000 1.000000 +vn -0.883572 0.126790 -0.450805 +v 4.421700 162.013168 33.262001 1.000000 1.000000 1.000000 +vn -0.975672 -0.028198 -0.217414 +v 4.425870 163.391754 33.428200 1.000000 1.000000 1.000000 +vn -0.700216 -0.041377 -0.712731 +v 4.775086 162.667572 32.812199 1.000000 1.000000 1.000000 +vn -0.895533 -0.081021 -0.437558 +v 4.564866 163.397324 33.030800 1.000000 1.000000 1.000000 +vn -0.728776 -0.250465 -0.637301 +v 4.733526 164.139648 32.579597 1.000000 1.000000 1.000000 +vn -0.872755 -0.241177 -0.424420 +v 4.498986 164.096390 32.914200 1.000000 1.000000 1.000000 +vn 0.304991 -0.530083 -0.791197 +v 3.231396 158.420181 33.503399 1.000000 1.000000 1.000000 +vn 0.468295 -0.488893 -0.735991 +v 4.344836 159.588074 33.271999 1.000000 1.000000 1.000000 +vn 0.985590 0.006145 -0.169041 +v 5.871068 163.439194 33.443596 1.000000 1.000000 1.000000 +vn 0.893388 0.423731 0.149365 +v 5.291714 166.044281 33.911999 1.000000 1.000000 1.000000 +vn 0.827766 0.540397 0.150916 +v 4.879630 166.817291 33.797398 1.000000 1.000000 1.000000 +vn 0.942017 0.300878 0.148585 +v 5.600606 165.212662 34.027397 1.000000 1.000000 1.000000 +vn 0.822710 0.309626 0.476739 +v 5.456396 165.161026 34.495598 1.000000 1.000000 1.000000 +vn 0.788671 0.419945 0.449049 +v 5.155460 165.973114 34.380398 1.000000 1.000000 1.000000 +vn 0.973376 0.175339 0.147630 +v 5.798982 164.340576 34.142799 1.000000 1.000000 1.000000 +vn 0.988017 0.046647 0.147124 +v 5.883916 163.439194 34.259201 1.000000 1.000000 1.000000 +vn 0.873891 0.198740 0.443641 +v 5.649684 164.312668 34.611000 1.000000 1.000000 1.000000 +vn 0.610378 0.212148 0.763172 +v 5.416408 164.269409 34.948799 1.000000 1.000000 1.000000 +vn 0.573651 0.368869 0.731341 +v 4.942588 165.860092 34.717999 1.000000 1.000000 1.000000 +vn 0.707012 0.516446 0.483133 +v 4.753984 166.725204 34.265598 1.000000 1.000000 1.000000 +vn 0.641839 0.616021 0.456684 +v 4.252704 167.418686 34.149399 1.000000 1.000000 1.000000 +vn 0.238946 0.154567 0.958652 +v -1.750434 158.131348 31.663198 1.000000 1.000000 1.000000 +vn 0.162986 0.656424 0.736575 +v -0.347926 158.071350 31.277399 1.000000 1.000000 1.000000 +vn 0.170068 0.210774 0.962627 +v -0.365802 157.804840 31.431999 1.000000 1.000000 1.000000 +vn 0.164264 0.876215 0.453060 +v -0.330824 158.326691 30.929798 1.000000 1.000000 1.000000 +vn -0.039429 0.938441 0.343182 +v 0.315862 158.325302 30.813198 1.000000 1.000000 1.000000 +vn -0.129136 0.668439 0.732471 +v 1.646804 158.374130 30.930199 1.000000 1.000000 1.000000 +vn -0.106285 0.923150 0.369455 +v 0.950154 158.422974 30.697998 1.000000 1.000000 1.000000 +vn -0.354025 0.933885 0.050240 +v 1.504846 158.794128 29.758198 1.000000 1.000000 1.000000 +vn -0.269565 0.863396 0.426476 +v 1.565680 158.614136 30.582598 1.000000 1.000000 1.000000 +vn -0.416348 0.831092 0.368700 +v 2.146642 158.897385 30.467798 1.000000 1.000000 1.000000 +vn -0.524407 0.781371 0.338314 +v 2.692458 159.269928 30.351599 1.000000 1.000000 1.000000 +vn -0.409289 0.552539 0.726074 +v 3.345340 159.533646 30.584198 1.000000 1.000000 1.000000 +vn -0.368897 0.898396 -0.238326 +v 1.522472 158.742493 29.303398 1.000000 1.000000 1.000000 +vn -0.576740 0.375627 0.725449 +v 4.430968 161.280609 30.249598 1.000000 1.000000 1.000000 +vn -0.680315 0.167453 0.713534 +v 4.762058 162.695480 30.018198 1.000000 1.000000 1.000000 +vn -0.159743 0.229151 0.960194 +v 4.659008 161.178757 30.403999 1.000000 1.000000 1.000000 +vn -0.046603 0.263042 0.963658 +v 3.517514 159.342484 30.738798 1.000000 1.000000 1.000000 +vn -0.887259 0.171497 0.428205 +v 4.527542 162.723389 29.670597 1.000000 1.000000 1.000000 +vn -0.947369 -0.004816 0.320108 +v 4.550074 163.423843 29.553999 1.000000 1.000000 1.000000 +vn -0.224004 0.164382 0.960625 +v 5.007142 162.667572 30.172798 1.000000 1.000000 1.000000 +vn 0.073995 0.255104 0.964078 +v 1.731572 158.122971 31.084799 1.000000 1.000000 1.000000 +vn -0.054487 -0.302846 -0.951481 +v 1.807752 157.898331 28.430199 1.000000 1.000000 1.000000 +vn -0.046934 -0.604828 -0.794972 +v 0.381892 157.298325 28.811998 1.000000 1.000000 1.000000 +vn 0.119165 -0.654325 -0.746765 +v 1.892482 157.647171 28.581398 1.000000 1.000000 1.000000 +vn 0.083247 -0.294916 -0.951890 +v 3.672230 159.170868 28.084198 1.000000 1.000000 1.000000 +vn 0.402144 0.543120 -0.737090 +v 2.259530 168.687042 26.641399 1.000000 1.000000 1.000000 +vn 0.264980 0.185782 -0.946187 +v 2.158372 168.444260 26.490398 1.000000 1.000000 1.000000 +vn 0.472187 0.411638 -0.779483 +v 3.503956 167.849838 26.860197 1.000000 1.000000 1.000000 +vn 0.042464 -0.267984 -0.962487 +v 2.062558 168.214020 26.495398 1.000000 1.000000 1.000000 +vn 0.624119 0.627311 -0.465786 +v 3.654926 168.047974 27.204599 1.000000 1.000000 1.000000 +vn 0.463995 0.773480 -0.431783 +v 2.356902 168.921448 26.985998 1.000000 1.000000 1.000000 +vn 0.551513 0.806017 -0.214874 +v 3.059054 168.682861 27.481199 1.000000 1.000000 1.000000 +vn 0.672697 0.718946 -0.174917 +v 3.739552 168.158203 27.597799 1.000000 1.000000 1.000000 +vn 0.529968 0.833700 0.155172 +v 3.065750 168.694016 28.296799 1.000000 1.000000 1.000000 +vn 0.742724 0.651971 0.152629 +v 4.350012 167.547043 28.529198 1.000000 1.000000 1.000000 +vn 0.642166 0.750931 0.154029 +v 3.747740 168.169373 28.413399 1.000000 1.000000 1.000000 +vn 0.406909 0.897356 0.170811 +v 2.416744 169.065186 28.194599 1.000000 1.000000 1.000000 +vn 0.330060 0.927062 -0.177810 +v 1.637754 169.362381 27.263798 1.000000 1.000000 1.000000 +vn 0.275623 0.948292 0.157398 +v 1.641346 169.376343 28.079399 1.000000 1.000000 1.000000 +vn 0.173543 0.968045 -0.181031 +v 0.824196 169.552155 27.147598 1.000000 1.000000 1.000000 +vn 0.127662 0.979059 0.158575 +v 0.825994 169.566101 27.963198 1.000000 1.000000 1.000000 +vn 0.325740 0.804059 -0.497375 +v 1.600686 169.224243 26.870798 1.000000 1.000000 1.000000 +vn 0.126765 -0.243540 -0.961571 +v 0.704880 168.640991 26.263998 1.000000 1.000000 1.000000 +vn 0.975885 0.137896 -0.169211 +v 5.782438 164.364288 28.174999 1.000000 1.000000 1.000000 +vn 0.985569 0.010480 -0.168950 +v 5.869318 163.474075 28.290398 1.000000 1.000000 1.000000 +vn 0.987788 0.051013 0.147219 +v 5.882166 163.474075 29.105997 1.000000 1.000000 1.000000 +vn 0.892556 0.086616 0.442541 +v 5.730706 163.468491 29.574198 1.000000 1.000000 1.000000 +vn -0.612990 -0.142142 -0.777199 +v -5.094228 160.988983 24.688999 1.000000 1.000000 1.000000 +vn 0.170662 -0.316941 0.932965 +v 0.336854 157.543900 36.464996 1.000000 1.000000 1.000000 +vn 0.256342 -0.575340 0.776706 +v 1.124802 157.416931 36.208000 1.000000 1.000000 1.000000 +vn 0.273672 -0.187194 0.943431 +v 2.471268 158.198318 36.117779 1.000000 1.000000 1.000000 +vn 0.045212 -0.652306 0.756606 +v -0.427734 157.306702 36.440578 1.000000 1.000000 1.000000 +vn 0.066936 -0.339370 0.938268 +v -1.142838 157.668091 36.696381 1.000000 1.000000 1.000000 +vn -0.116959 -0.626813 0.770342 +v -1.849852 157.637390 36.657997 1.000000 1.000000 1.000000 +vn -0.089164 -0.343057 0.935073 +v -3.094306 158.618317 37.030998 1.000000 1.000000 1.000000 +vn -0.380563 -0.799100 0.465414 +v -2.676144 157.750412 36.436798 1.000000 1.000000 1.000000 +vn -0.237016 -0.847804 0.474396 +v -1.929496 157.395996 36.320198 1.000000 1.000000 1.000000 +vn -0.208453 -0.594663 0.776481 +v -2.565680 157.977859 36.774597 1.000000 1.000000 1.000000 +vn -0.593063 -0.790206 0.154436 +v -3.453256 158.081116 36.084396 1.000000 1.000000 1.000000 +vn -0.470264 -0.868634 0.155968 +v -2.746866 157.605301 35.968578 1.000000 1.000000 1.000000 +vn -0.483455 -0.723989 0.492048 +v -3.364380 158.213669 36.552780 1.000000 1.000000 1.000000 +vn -0.382384 -0.504019 0.774434 +v -3.817110 158.960159 37.005600 1.000000 1.000000 1.000000 +vn -0.597887 -0.657897 0.457933 +v -3.981470 158.774597 36.667801 1.000000 1.000000 1.000000 +vn -0.699575 -0.698047 0.152727 +v -4.086658 158.657379 36.199600 1.000000 1.000000 1.000000 +vn -0.625535 -0.759963 -0.176529 +v -3.445724 158.092270 35.268997 1.000000 1.000000 1.000000 +vn -0.508126 -0.842728 -0.177813 +v -2.740866 157.617859 35.153000 1.000000 1.000000 1.000000 +vn -0.339945 -0.927156 0.157543 +v -1.980468 157.241119 35.851978 1.000000 1.000000 1.000000 +vn -0.595924 -0.658382 -0.459792 +v -3.367780 158.209488 34.875801 1.000000 1.000000 1.000000 +vn -0.478840 -0.740376 -0.471758 +v -2.678862 157.744843 34.759998 1.000000 1.000000 1.000000 +vn -0.367215 -0.904202 -0.218111 +v -1.976142 157.253677 35.036400 1.000000 1.000000 1.000000 +vn -0.727043 -0.664137 -0.174158 +v -4.077736 158.667145 35.383999 1.000000 1.000000 1.000000 +vn -0.675569 -0.555323 -0.484998 +v -3.985488 158.770401 34.990997 1.000000 1.000000 1.000000 +vn -0.287263 -0.852965 -0.435811 +v -1.243804 157.175537 34.541199 1.000000 1.000000 1.000000 +vn -0.202418 -0.964016 0.172338 +v -1.275366 157.020645 35.749779 1.000000 1.000000 1.000000 +vn -0.120272 -0.976427 -0.179234 +v -0.456908 156.902054 34.819000 1.000000 1.000000 1.000000 +vn -0.142659 -0.854234 -0.499934 +v -0.446584 157.045776 34.425999 1.000000 1.000000 1.000000 +vn -0.076878 -0.664101 -0.743679 +v 0.351510 157.295532 33.965199 1.000000 1.000000 1.000000 +vn -0.005044 -0.881631 -0.471912 +v 0.366676 157.038788 34.309799 1.000000 1.000000 1.000000 +vn 0.043135 -0.982407 -0.181705 +v 0.375182 156.895081 34.702999 1.000000 1.000000 1.000000 +vn 0.129101 -0.872336 -0.471554 +v 1.174456 157.158783 34.193398 1.000000 1.000000 1.000000 +vn 0.043045 -0.604507 -0.795436 +v 1.125922 157.409943 33.848801 1.000000 1.000000 1.000000 +vn 0.192566 -0.964343 -0.181553 +v 1.201654 157.017868 34.586399 1.000000 1.000000 1.000000 +vn 0.334971 -0.924814 -0.180316 +v 1.996574 157.262054 34.471001 1.000000 1.000000 1.000000 +vn 0.250677 -0.829523 -0.499051 +v 1.951384 157.397400 34.077999 1.000000 1.000000 1.000000 +vn 0.213643 -0.631742 -0.745157 +v 2.578670 157.979248 33.618198 1.000000 1.000000 1.000000 +vn 0.383000 -0.796840 -0.467287 +v 2.689780 157.751816 33.962601 1.000000 1.000000 1.000000 +vn 0.468303 -0.865235 -0.179053 +v 2.752068 157.624832 34.355797 1.000000 1.000000 1.000000 +vn 0.238865 -0.958117 0.157971 +v 1.204286 157.003906 35.402000 1.000000 1.000000 1.000000 +vn 0.379547 -0.911955 0.155829 +v 2.000938 157.249496 35.286598 1.000000 1.000000 1.000000 +vn 0.257879 -0.845309 0.467922 +v 1.173268 157.165771 35.870178 1.000000 1.000000 1.000000 +vn 0.090253 -0.983202 0.158645 +v 0.376008 156.881119 35.518398 1.000000 1.000000 1.000000 +vn 0.379633 -0.782725 0.493173 +v 1.949414 157.402969 35.754799 1.000000 1.000000 1.000000 +vn 0.495799 -0.736236 0.460587 +v 2.687050 157.757385 35.639599 1.000000 1.000000 1.000000 +vn 0.509438 -0.846477 0.154755 +v 2.758080 157.612274 35.171196 1.000000 1.000000 1.000000 +vn 0.423118 -0.524647 0.738726 +v 2.576094 157.983429 35.977180 1.000000 1.000000 1.000000 +vn 0.130189 -0.856857 0.498846 +v 0.366312 157.045776 35.986778 1.000000 1.000000 1.000000 +vn -0.061348 -0.985546 0.157912 +v -0.457900 156.888092 35.634579 1.000000 1.000000 1.000000 +vn -0.024469 -0.878993 0.476206 +v -0.446132 157.051361 36.102798 1.000000 1.000000 1.000000 +vn 0.528018 -0.365028 0.766780 +v 3.824514 158.968536 35.746399 1.000000 1.000000 1.000000 +vn 0.362486 -0.090738 0.927562 +v 4.163894 159.740158 35.771797 1.000000 1.000000 1.000000 +vn 0.648432 -0.122078 0.751420 +v 5.111146 161.054565 35.398796 1.000000 1.000000 1.000000 +vn 0.362156 0.051525 0.930692 +v 5.106780 161.820602 35.437199 1.000000 1.000000 1.000000 +vn 0.619081 -0.203822 0.758417 +v 4.773026 160.291321 35.515396 1.000000 1.000000 1.000000 +vn 0.677311 0.020712 0.735405 +v 5.463954 162.583847 35.181396 1.000000 1.000000 1.000000 +vn 0.341695 0.145462 0.928485 +v 5.272118 163.419647 35.205799 1.000000 1.000000 1.000000 +vn 0.861279 -0.235400 0.450318 +v 5.331278 160.959686 35.060997 1.000000 1.000000 1.000000 +vn 0.817150 -0.363622 0.447265 +v 4.978598 160.162949 35.177597 1.000000 1.000000 1.000000 +vn 0.748160 -0.458044 0.480055 +v 4.527452 159.433197 35.293598 1.000000 1.000000 1.000000 +vn 0.814170 -0.560859 0.150216 +v 4.647110 159.332733 34.825199 1.000000 1.000000 1.000000 +vn 0.883398 -0.444349 0.148869 +v 5.110180 160.082016 34.709396 1.000000 1.000000 1.000000 +vn 0.728135 -0.668384 0.151930 +v 4.094678 158.665756 34.940399 1.000000 1.000000 1.000000 +vn 0.685065 -0.569919 0.453738 +v 3.989246 158.784348 35.408600 1.000000 1.000000 1.000000 +vn 0.591422 -0.643260 0.486248 +v 3.367214 158.217850 35.524799 1.000000 1.000000 1.000000 +vn 0.626785 -0.763952 0.153353 +v 3.456216 158.085297 35.056599 1.000000 1.000000 1.000000 +vn 0.589396 -0.788155 -0.177269 +v 3.448672 158.096466 34.240997 1.000000 1.000000 1.000000 +vn 0.496080 -0.733999 -0.463843 +v 3.370612 158.212280 33.848000 1.000000 1.000000 1.000000 +vn 0.695258 -0.696821 -0.176230 +v 4.085744 158.676926 34.124798 1.000000 1.000000 1.000000 +vn 0.583785 -0.647419 -0.489942 +v 3.993276 158.780167 33.731796 1.000000 1.000000 1.000000 +vn 0.785811 -0.593288 -0.174670 +v 4.636966 159.341095 34.009796 1.000000 1.000000 1.000000 +vn 0.685157 -0.567425 -0.456716 +v 4.532036 159.430405 33.616600 1.000000 1.000000 1.000000 +vn 0.762405 -0.455724 -0.459406 +v 4.983634 160.160156 33.500801 1.000000 1.000000 1.000000 +vn 0.860315 -0.479736 -0.172369 +v 5.099016 160.089005 33.893799 1.000000 1.000000 1.000000 +vn 0.865699 -0.280156 -0.414824 +v 5.558262 161.695023 33.281998 1.000000 1.000000 1.000000 +vn 0.912621 -0.351221 -0.209206 +v 5.460246 160.903870 33.777199 1.000000 1.000000 1.000000 +vn 0.976806 -0.133490 -0.167425 +v 5.837142 162.537811 33.559799 1.000000 1.000000 1.000000 +vn 0.866198 -0.151776 -0.476094 +v 5.705048 162.554550 33.166798 1.000000 1.000000 1.000000 +vn 0.933831 -0.325628 0.148075 +v 5.472180 160.899673 34.592796 1.000000 1.000000 1.000000 +vn 0.965461 -0.204409 0.161562 +v 5.699396 161.655945 34.490601 1.000000 1.000000 1.000000 +vn 0.892082 -0.049213 0.449185 +v 5.699280 162.554550 34.843597 1.000000 1.000000 1.000000 +vn 0.985582 -0.083516 0.147153 +v 5.849902 162.536407 34.375397 1.000000 1.000000 1.000000 +vn 0.876387 0.086135 0.473842 +v 5.732406 163.434998 34.727600 1.000000 1.000000 1.000000 +vn -0.757167 -0.470868 -0.452749 +v -4.529796 159.424805 35.107201 1.000000 1.000000 1.000000 +vn -0.811752 -0.557926 -0.172562 +v -4.634636 159.336914 35.500198 1.000000 1.000000 1.000000 +vn -0.815103 -0.365441 -0.449510 +v -4.978160 160.147598 35.221798 1.000000 1.000000 1.000000 +vn -0.844344 -0.245126 -0.476442 +v -5.329824 160.934570 35.337196 1.000000 1.000000 1.000000 +vn -0.880229 -0.442425 -0.171632 +v -5.093404 160.075043 35.614979 1.000000 1.000000 1.000000 +vn -0.931743 -0.320819 -0.170092 +v -5.453202 160.881546 35.730179 1.000000 1.000000 1.000000 +vn -0.863691 -0.481071 0.150360 +v -5.104540 160.068069 36.430397 1.000000 1.000000 1.000000 +vn -0.669974 -0.562216 0.484818 +v -4.525212 159.429001 36.783997 1.000000 1.000000 1.000000 +vn -0.789554 -0.594701 0.151444 +v -4.644780 159.328537 36.315781 1.000000 1.000000 1.000000 +vn -0.920681 -0.360737 0.149052 +v -5.465126 160.875961 36.545776 1.000000 1.000000 1.000000 +vn -0.758614 -0.470202 0.451014 +v -4.973126 160.150391 36.898781 1.000000 1.000000 1.000000 +vn -0.546715 -0.405270 0.732706 +v -4.767838 160.278763 37.236397 1.000000 1.000000 1.000000 +vn -0.193563 -0.257056 0.946813 +v -4.573892 160.398758 37.376999 1.000000 1.000000 1.000000 +vn -0.594505 -0.250396 0.764111 +v -5.340742 161.830368 37.467178 1.000000 1.000000 1.000000 +vn -0.800343 -0.361915 0.477985 +v -5.324442 160.937347 37.014000 1.000000 1.000000 1.000000 +vn -0.859099 -0.253756 0.444474 +v -5.570712 161.770370 37.129398 1.000000 1.000000 1.000000 +vn -0.960225 -0.236743 0.148055 +v -5.717910 161.731293 36.661179 1.000000 1.000000 1.000000 +vn -0.868940 -0.141283 0.474324 +v -5.708548 162.639664 37.245998 1.000000 1.000000 1.000000 +vn -0.983074 -0.109012 0.147248 +v -5.859378 162.624313 36.777599 1.000000 1.000000 1.000000 +vn -0.965850 -0.196235 -0.169188 +v -5.705432 161.734100 35.845596 1.000000 1.000000 1.000000 +vn -0.893434 -0.007269 0.449135 +v -5.730900 163.520126 37.362000 1.000000 1.000000 1.000000 +vn -0.674429 -0.063184 0.735631 +v -5.494312 163.508957 37.699799 1.000000 1.000000 1.000000 +vn -0.330872 -0.166718 0.928832 +v -5.250258 162.688507 37.724197 1.000000 1.000000 1.000000 +vn -0.357244 -0.074331 0.931049 +v -5.185960 164.295929 37.955597 1.000000 1.000000 1.000000 +vn 0.254850 -0.118113 0.959740 +v -5.012742 162.713623 37.727997 1.000000 1.000000 1.000000 +vn 0.282795 -0.020218 0.958967 +v -4.366982 160.528519 37.380798 1.000000 1.000000 1.000000 +vn 0.206625 -0.193431 0.959109 +v -4.951356 164.248489 37.959396 1.000000 1.000000 1.000000 +vn 0.643374 -0.257957 0.720783 +v -4.709064 164.199646 37.804798 1.000000 1.000000 1.000000 +vn 0.103741 -0.248533 0.963052 +v -4.178352 166.296829 38.293999 1.000000 1.000000 1.000000 +vn 0.518820 -0.460586 0.720199 +v -3.973900 166.147537 38.139397 1.000000 1.000000 1.000000 +vn -0.016494 -0.264487 0.964248 +v -2.658764 167.886124 38.639999 1.000000 1.000000 1.000000 +vn 0.272485 -0.627021 0.729792 +v -2.528676 167.658676 38.485397 1.000000 1.000000 1.000000 +vn -0.120790 -0.239790 0.963281 +v -0.665024 168.659134 38.987198 1.000000 1.000000 1.000000 +vn -0.014727 -0.675036 0.737638 +v -0.632500 168.395416 38.832596 1.000000 1.000000 1.000000 +vn -0.200743 -0.195968 0.959843 +v 0.751910 168.645187 39.218578 1.000000 1.000000 1.000000 +vn -0.263437 -0.619648 0.739350 +v 0.715086 168.381470 39.063980 1.000000 1.000000 1.000000 +vn -0.259866 -0.104587 0.959964 +v 2.667866 167.877747 39.553177 1.000000 1.000000 1.000000 +vn -0.482783 -0.496397 0.721464 +v 2.537278 167.651703 39.398579 1.000000 1.000000 1.000000 +vn -0.282847 0.002574 0.959162 +v 4.184274 166.287064 39.899200 1.000000 1.000000 1.000000 +vn -0.094001 -0.899268 0.427178 +v 0.042486 168.184723 38.601196 1.000000 1.000000 1.000000 +vn -0.278171 -0.843369 0.459728 +v 0.679842 168.128906 38.716179 1.000000 1.000000 1.000000 +vn 0.032556 -0.890041 0.454717 +v -0.601382 168.141464 38.485001 1.000000 1.000000 1.000000 +vn 0.149502 -0.988739 0.006663 +v -0.578054 167.951691 37.660599 1.000000 1.000000 1.000000 +vn 0.312546 -0.949844 0.010544 +v -1.186708 167.814957 37.544197 1.000000 1.000000 1.000000 +vn -0.411154 -0.853657 0.319723 +v 1.843942 167.761948 38.934978 1.000000 1.000000 1.000000 +vn -0.025639 -0.999084 0.034274 +v 0.040806 167.992157 37.776798 1.000000 1.000000 1.000000 +vn 0.138594 -0.962443 -0.233444 +v -0.584812 168.006119 37.205799 1.000000 1.000000 1.000000 +vn -0.254494 -0.967053 0.006443 +v 1.186762 167.814957 37.994179 1.000000 1.000000 1.000000 +vn -0.116626 -0.962072 -0.246610 +v 0.661072 167.993561 37.437199 1.000000 1.000000 1.000000 +vn -0.570800 -0.688863 0.446829 +v 2.412302 167.435425 39.050999 1.000000 1.000000 1.000000 +vn -0.438374 -0.898757 -0.008001 +v 1.772308 167.586121 38.110779 1.000000 1.000000 1.000000 +vn -0.446047 -0.798517 -0.404244 +v 2.419434 167.446594 37.374378 1.000000 1.000000 1.000000 +vn -0.292728 -0.763001 -0.576315 +v 1.849390 167.774490 37.258400 1.000000 1.000000 1.000000 +vn -0.047370 -0.874936 -0.481917 +v 0.681856 168.142853 37.039597 1.000000 1.000000 1.000000 +vn -0.419378 -0.607422 -0.674656 +v 3.090998 167.235886 37.154800 1.000000 1.000000 1.000000 +vn -0.635991 -0.639223 -0.432330 +v 3.402644 166.549393 37.605797 1.000000 1.000000 1.000000 +vn -0.122800 -0.706582 -0.696894 +v 1.302970 168.261459 36.807178 1.000000 1.000000 1.000000 +vn 0.121074 -0.661900 -0.739750 +v 0.044864 168.456802 36.589798 1.000000 1.000000 1.000000 +vn 0.189613 -0.863720 -0.466943 +v -0.603160 168.155426 36.808399 1.000000 1.000000 1.000000 +vn 0.353037 -0.663049 -0.660099 +v -1.302790 168.261459 36.357201 1.000000 1.000000 1.000000 +vn 0.366925 -0.816185 -0.446327 +v -1.238286 168.013107 36.691799 1.000000 1.000000 1.000000 +vn 0.532357 -0.696583 -0.481008 +v -2.411284 167.453568 36.461197 1.000000 1.000000 1.000000 +vn 0.551817 -0.800321 -0.234486 +v -2.337898 167.325195 36.858597 1.000000 1.000000 1.000000 +vn 0.467329 -0.482142 -0.741042 +v -2.536942 167.672638 36.126396 1.000000 1.000000 1.000000 +vn 0.639263 -0.714318 -0.284768 +v -2.839436 166.931717 36.743996 1.000000 1.000000 1.000000 +vn 0.666746 -0.607236 -0.432104 +v -2.928568 167.047531 36.346596 1.000000 1.000000 1.000000 +vn 0.544989 -0.836963 0.049797 +v -2.310848 167.279160 37.313400 1.000000 1.000000 1.000000 +vn 0.243338 -0.906995 0.343725 +v -1.234642 167.999146 38.368401 1.000000 1.000000 1.000000 +vn 0.781774 -0.621505 0.050606 +v -3.252950 166.422409 37.082596 1.000000 1.000000 1.000000 +vn 0.450044 -0.786681 0.422603 +v -2.404190 167.441010 38.137798 1.000000 1.000000 1.000000 +vn 0.304974 -0.878531 0.367660 +v -1.837532 167.764725 38.253197 1.000000 1.000000 1.000000 +vn 0.911547 -0.411119 -0.007985 +v -3.939962 165.317307 36.851601 1.000000 1.000000 1.000000 +vn 0.676538 -0.657131 0.332380 +v -3.384362 166.550781 37.906998 1.000000 1.000000 1.000000 +vn 0.583413 -0.726276 0.363528 +v -2.919942 167.036362 38.022999 1.000000 1.000000 1.000000 +vn 0.715780 -0.541774 0.440612 +v -3.778242 166.005219 37.791798 1.000000 1.000000 1.000000 +vn 0.868429 -0.391452 0.304298 +v -4.099146 165.401031 37.675797 1.000000 1.000000 1.000000 +vn 0.968261 -0.249850 0.006829 +v -4.170216 164.690811 36.735001 1.000000 1.000000 1.000000 +vn -0.505264 -0.446692 -0.738360 +v 3.992492 166.147537 37.385597 1.000000 1.000000 1.000000 +vn -0.722256 -0.505522 -0.472011 +v 3.794656 166.003815 37.720379 1.000000 1.000000 1.000000 +vn -0.833674 -0.350456 -0.426811 +v 4.350642 164.752197 37.950996 1.000000 1.000000 1.000000 +vn -0.822634 -0.520846 -0.228020 +v 3.679118 165.920105 38.117779 1.000000 1.000000 1.000000 +vn -0.742975 -0.607322 -0.281335 +v 3.299028 166.448929 38.003197 1.000000 1.000000 1.000000 +vn -0.655619 -0.753354 0.051199 +v 2.815386 166.880081 38.341797 1.000000 1.000000 1.000000 +vn -0.856884 -0.513272 0.047977 +v 3.636528 165.889404 38.572578 1.000000 1.000000 1.000000 +vn -0.953873 -0.300078 0.008951 +v 4.169340 164.689407 38.803398 1.000000 1.000000 1.000000 +vn -0.915379 -0.242023 0.321724 +v 4.337832 164.748016 39.627579 1.000000 1.000000 1.000000 +vn -0.902565 -0.055512 0.426959 +v 4.490514 164.067093 39.744179 1.000000 1.000000 1.000000 +vn -0.702445 -0.008067 0.711692 +v 4.723110 164.108948 40.091797 1.000000 1.000000 1.000000 +vn -0.890842 -0.294325 0.346082 +v 4.101116 165.392654 39.512379 1.000000 1.000000 1.000000 +vn -0.651735 -0.264847 0.710702 +v 3.979474 166.137772 39.744598 1.000000 1.000000 1.000000 +vn -0.807440 -0.426269 0.407842 +v 3.783482 165.995438 39.396980 1.000000 1.000000 1.000000 +vn -0.752626 -0.553861 0.356079 +v 3.392616 166.541016 39.282181 1.000000 1.000000 1.000000 +vn -0.686764 -0.646713 0.331841 +v 2.929174 167.026596 39.166199 1.000000 1.000000 1.000000 +vn -0.262912 0.101551 0.959461 +v 4.966188 164.153595 40.246399 1.000000 1.000000 1.000000 +vn 0.318261 0.187332 0.929310 +v 5.201564 164.196869 40.242577 1.000000 1.000000 1.000000 +vn 0.351188 0.096622 0.931306 +v 5.238592 162.588043 40.473999 1.000000 1.000000 1.000000 +vn 0.668602 0.105428 0.736108 +v 5.496668 163.395935 40.218201 1.000000 1.000000 1.000000 +vn 0.336345 -0.022265 0.941476 +v 4.565986 160.387589 40.808578 1.000000 1.000000 1.000000 +vn 0.658313 -0.044533 0.751426 +v 5.339260 161.828964 40.435600 1.000000 1.000000 1.000000 +vn 0.557019 -0.392418 0.731941 +v 3.804120 158.946213 40.899399 1.000000 1.000000 1.000000 +vn 0.646940 -0.232482 0.726238 +v 4.759650 160.266205 40.667976 1.000000 1.000000 1.000000 +vn 0.318755 -0.109611 0.941478 +v 3.649352 159.122025 41.039997 1.000000 1.000000 1.000000 +vn 0.884864 -0.124228 0.448980 +v 5.569218 161.767578 40.097778 1.000000 1.000000 1.000000 +vn 0.844371 -0.246924 0.475464 +v 5.319922 160.926193 40.214378 1.000000 1.000000 1.000000 +vn 0.814943 -0.368720 0.447116 +v 4.964642 160.137833 40.330399 1.000000 1.000000 1.000000 +vn 0.746337 -0.461268 0.479805 +v 4.513020 159.415054 40.445396 1.000000 1.000000 1.000000 +vn 0.933431 -0.326778 0.148061 +v 5.460516 160.864807 39.746201 1.000000 1.000000 1.000000 +vn 0.880881 -0.449226 0.149145 +v 5.095862 160.055511 39.861977 1.000000 1.000000 1.000000 +vn 0.811641 -0.564369 0.150755 +v 4.632292 159.313187 39.977180 1.000000 1.000000 1.000000 +vn 0.683484 -0.572309 0.453114 +v 3.967978 158.762024 40.561577 1.000000 1.000000 1.000000 +vn 0.726080 -0.670568 0.152139 +v 4.072856 158.643433 40.093399 1.000000 1.000000 1.000000 +vn 0.692882 -0.699367 -0.175499 +v 4.063960 158.653198 39.277779 1.000000 1.000000 1.000000 +vn 0.783518 -0.596404 -0.174363 +v 4.622186 159.321564 39.161598 1.000000 1.000000 1.000000 +vn 0.857786 -0.484345 -0.172086 +v 5.084726 160.062485 39.046600 1.000000 1.000000 1.000000 +vn 0.915548 -0.363873 -0.171371 +v 5.448594 160.870377 38.930580 1.000000 1.000000 1.000000 +vn 0.667840 -0.563017 -0.486829 +v 4.517590 159.410873 38.768600 1.000000 1.000000 1.000000 +vn 0.756089 -0.472380 -0.452976 +v 4.969664 160.133652 38.653397 1.000000 1.000000 1.000000 +vn 0.595247 -0.658893 -0.459936 +v 3.971994 158.756454 38.884796 1.000000 1.000000 1.000000 +vn 0.394457 -0.538295 -0.744743 +v 3.807918 158.942032 38.540176 1.000000 1.000000 1.000000 +vn 0.541395 -0.418118 -0.729431 +v 4.764400 160.263412 38.308998 1.000000 1.000000 1.000000 +vn 0.816615 -0.352565 -0.456988 +v 5.325292 160.924805 38.537579 1.000000 1.000000 1.000000 +vn 0.950312 -0.231615 -0.207993 +v 5.703928 161.732697 38.813980 1.000000 1.000000 1.000000 +vn 0.481110 -0.724441 -0.493679 +v 3.355406 158.199707 38.999378 1.000000 1.000000 1.000000 +vn 0.219657 -0.567442 -0.793575 +v 2.559280 157.966690 38.770199 1.000000 1.000000 1.000000 +vn 0.379008 -0.798691 -0.467382 +v 2.669554 157.739243 39.114777 1.000000 1.000000 1.000000 +vn 0.586251 -0.790366 -0.177852 +v 3.433094 158.082504 39.392601 1.000000 1.000000 1.000000 +vn 0.117021 -0.857526 -0.500954 +v 1.136590 157.149033 39.346378 1.000000 1.000000 1.000000 +vn 0.255409 -0.844928 -0.469961 +v 1.923354 157.384842 39.230999 1.000000 1.000000 1.000000 +vn -0.212066 -0.636920 -0.741189 +v -0.785262 157.345764 39.271198 1.000000 1.000000 1.000000 +vn -0.013462 -0.886296 -0.462923 +v 0.321040 157.035995 39.460579 1.000000 1.000000 1.000000 +vn 0.185405 -0.965440 -0.183167 +v 1.162914 157.008102 39.739399 1.000000 1.000000 1.000000 +vn -0.046056 -0.973870 -0.222385 +v -0.001400 156.882523 39.897797 1.000000 1.000000 1.000000 +vn -0.189976 -0.859466 -0.474581 +v -0.819062 157.090424 39.615601 1.000000 1.000000 1.000000 +vn -0.176668 -0.967285 -0.182067 +v -0.838010 156.948105 40.008797 1.000000 1.000000 1.000000 +vn 0.084460 -0.996361 -0.011437 +v 0.331146 156.840652 40.259178 1.000000 1.000000 1.000000 +vn -0.337209 -0.775246 -0.534120 +v -1.626616 157.281586 39.725399 1.000000 1.000000 1.000000 +vn -0.280760 -0.946756 0.157568 +v -1.667892 157.129486 40.933998 1.000000 1.000000 1.000000 +vn -0.320306 -0.929999 -0.180295 +v -1.664250 157.143448 40.118599 1.000000 1.000000 1.000000 +vn -0.128926 -0.978730 0.159580 +v -0.839836 156.934143 40.824181 1.000000 1.000000 1.000000 +vn 0.091160 -0.974417 0.205430 +v 0.329202 156.878326 40.669197 1.000000 1.000000 1.000000 +vn -0.068556 -0.862765 0.500936 +v -0.818236 157.097397 41.292599 1.000000 1.000000 1.000000 +vn 0.067267 -0.883343 0.463876 +v -0.001380 157.033218 41.181599 1.000000 1.000000 1.000000 +vn -0.210014 -0.857796 0.469127 +v -1.624968 157.287170 41.402397 1.000000 1.000000 1.000000 +vn -0.422566 -0.892689 0.156667 +v -2.461020 157.451813 41.041580 1.000000 1.000000 1.000000 +vn 0.100659 -0.659726 0.744734 +v -0.001352 157.289948 41.519379 1.000000 1.000000 1.000000 +vn -0.089344 -0.614846 0.783570 +v -1.557904 157.534134 41.739998 1.000000 1.000000 1.000000 +vn 0.242653 -0.847896 0.471373 +v 1.135440 157.156006 41.023376 1.000000 1.000000 1.000000 +vn 0.249331 -0.579021 0.776253 +v 1.088536 157.407166 41.361000 1.000000 1.000000 1.000000 +vn 0.169021 -0.273389 0.946937 +v 0.294912 157.541107 41.615780 1.000000 1.000000 1.000000 +vn 0.079429 -0.344060 0.935582 +v -0.752582 157.591354 41.770798 1.000000 1.000000 1.000000 +vn 0.374872 -0.784010 0.494772 +v 1.921410 157.391815 40.907997 1.000000 1.000000 1.000000 +vn 0.272780 -0.191398 0.942846 +v 2.452690 158.187149 41.269997 1.000000 1.000000 1.000000 +vn 0.421022 -0.525292 0.739465 +v 2.556718 157.972275 41.129398 1.000000 1.000000 1.000000 +vn 0.230906 -0.960054 0.158046 +v 1.165468 156.994141 40.555000 1.000000 1.000000 1.000000 +vn 0.374239 -0.913993 0.156723 +v 1.972214 157.236923 40.439598 1.000000 1.000000 1.000000 +vn 0.492594 -0.737997 0.461208 +v 2.666850 157.744843 40.791779 1.000000 1.000000 1.000000 +vn 0.330058 -0.926633 -0.180038 +v 1.967902 157.249496 39.624199 1.000000 1.000000 1.000000 +vn 0.506009 -0.848505 0.154902 +v 2.737340 157.599716 40.323399 1.000000 1.000000 1.000000 +vn 0.588678 -0.645464 0.486655 +v 3.352008 158.205292 40.676376 1.000000 1.000000 1.000000 +vn 0.623859 -0.766234 0.153902 +v 3.440612 158.071350 40.208000 1.000000 1.000000 1.000000 +vn 0.464596 -0.867265 -0.178889 +v 2.731364 157.612274 39.507980 1.000000 1.000000 1.000000 +vn -0.096257 -0.353763 0.930369 +v -2.866704 158.449478 42.093201 1.000000 1.000000 1.000000 +vn -0.203748 -0.599192 0.774245 +v -2.298708 157.834137 41.847797 1.000000 1.000000 1.000000 +vn -0.410038 -0.546006 0.730579 +v -3.751204 158.891800 42.078796 1.000000 1.000000 1.000000 +vn -0.124659 -0.278691 0.952256 +v -3.598612 159.069000 42.219200 1.000000 1.000000 1.000000 +vn -0.358677 -0.802635 0.476580 +v -2.397676 157.601105 41.509998 1.000000 1.000000 1.000000 +vn -0.568475 -0.678248 0.465635 +v -3.912720 158.704819 41.740997 1.000000 1.000000 1.000000 +vn -0.533670 -0.810608 0.241062 +v -3.199262 157.892731 41.146599 1.000000 1.000000 1.000000 +vn -0.783477 -0.602480 0.152255 +v -4.594130 159.258774 41.373798 1.000000 1.000000 1.000000 +vn -0.687767 -0.708332 0.158878 +v -4.016104 158.584824 41.272598 1.000000 1.000000 1.000000 +vn -0.668000 -0.562872 0.486777 +v -4.475862 159.362030 41.841980 1.000000 1.000000 1.000000 +vn -0.561160 -0.826548 -0.043793 +v -3.218084 157.862045 40.736599 1.000000 1.000000 1.000000 +vn -0.460241 -0.869298 -0.180275 +v -2.455652 157.464371 40.226196 1.000000 1.000000 1.000000 +vn -0.582115 -0.689549 -0.430888 +v -3.120056 158.025299 39.937981 1.000000 1.000000 1.000000 +vn -0.419735 -0.732579 -0.535864 +v -2.400096 157.595535 39.833000 1.000000 1.000000 1.000000 +vn -0.703932 -0.669689 -0.236637 +v -4.007336 158.594604 40.457176 1.000000 1.000000 1.000000 +vn -0.802189 -0.571398 -0.173196 +v -4.584114 159.267136 40.558197 1.000000 1.000000 1.000000 +vn -0.729405 -0.502712 -0.463950 +v -4.480394 159.357834 40.165176 1.000000 1.000000 1.000000 +vn -0.794477 -0.371302 -0.480563 +v -4.949900 160.094574 40.264000 1.000000 1.000000 1.000000 +vn -0.852374 -0.270901 -0.447293 +v -5.313820 160.892700 40.359798 1.000000 1.000000 1.000000 +vn -0.874327 -0.454120 -0.171252 +v -5.064474 160.022018 40.656979 1.000000 1.000000 1.000000 +vn -0.928065 -0.331295 -0.170114 +v -5.436812 160.838287 40.752998 1.000000 1.000000 1.000000 +vn -0.963936 -0.205424 -0.169197 +v -5.696794 161.699219 40.846199 1.000000 1.000000 1.000000 +vn -0.860683 -0.486507 0.150122 +v -5.075546 160.015045 41.472599 1.000000 1.000000 1.000000 +vn -0.919536 -0.363630 0.149087 +v -5.448710 160.832703 41.568378 1.000000 1.000000 1.000000 +vn -0.759637 -0.469193 0.450344 +v -4.944892 160.097366 41.940781 1.000000 1.000000 1.000000 +vn -0.801982 -0.356046 0.479642 +v -5.308452 160.895493 42.036797 1.000000 1.000000 1.000000 +vn -0.960036 -0.237617 0.147883 +v -5.709258 161.696426 41.661579 1.000000 1.000000 1.000000 +vn -0.860991 -0.246460 0.444917 +v -5.562278 161.735489 42.129997 1.000000 1.000000 1.000000 +vn -0.983167 -0.107981 0.147388 +v -5.856790 162.603378 41.754379 1.000000 1.000000 1.000000 +vn -0.503549 -0.384617 0.773633 +v -4.740762 160.227142 42.278580 1.000000 1.000000 1.000000 +vn -0.603633 -0.214756 0.767794 +v -5.332656 161.798279 42.467796 1.000000 1.000000 1.000000 +vn -0.272545 -0.218844 0.936924 +v -4.882282 161.083862 42.514977 1.000000 1.000000 1.000000 +vn 0.262913 -0.004527 0.964809 +v -4.342172 160.482483 42.422779 1.000000 1.000000 1.000000 +vn 0.196687 -0.149382 0.969020 +v -4.948922 164.263840 42.883400 1.000000 1.000000 1.000000 +vn -0.354907 0.013192 0.934808 +v -4.989348 165.101028 42.964798 1.000000 1.000000 1.000000 +vn 0.108216 -0.187763 0.976235 +v -3.791542 166.841019 43.189796 1.000000 1.000000 1.000000 +vn -0.666914 0.046177 0.743703 +v -5.403210 164.357315 42.739197 1.000000 1.000000 1.000000 +vn 0.202446 -0.390322 0.898145 +v -2.453218 167.690781 43.189796 1.000000 1.000000 1.000000 +vn 0.083217 -0.520739 0.849650 +v -0.984132 168.172165 43.189796 1.000000 1.000000 1.000000 +vn -0.047736 -0.536788 0.842366 +v 0.000000 168.234955 43.189796 1.000000 1.000000 1.000000 +vn -0.188679 -0.570713 0.799179 +v 1.318136 167.921005 43.185181 1.000000 1.000000 1.000000 +vn -0.336421 -0.516190 0.787635 +v 2.202430 167.491241 43.189796 1.000000 1.000000 1.000000 +vn -0.474902 -0.392781 0.787522 +v 3.288278 166.504745 43.189198 1.000000 1.000000 1.000000 +vn -0.581172 -0.143908 0.800955 +v 4.275866 164.559647 43.189796 1.000000 1.000000 1.000000 +vn 0.746198 -0.047881 0.664000 +v 5.921280 162.921524 43.188580 1.000000 1.000000 1.000000 +vn 0.715991 -0.290910 0.634609 +v 5.488184 160.760147 43.189796 1.000000 1.000000 1.000000 +vn 0.575109 -0.543739 0.611226 +v 4.201204 158.632263 43.189598 1.000000 1.000000 1.000000 +vn -0.266927 -0.808896 0.523868 +v 2.046658 157.197861 43.189598 1.000000 1.000000 1.000000 +vn -0.690318 -0.058655 0.721125 +v -5.494416 163.506165 42.651176 1.000000 1.000000 1.000000 +vn -0.896598 -0.008102 0.442772 +v -5.731002 163.517334 42.313400 1.000000 1.000000 1.000000 +vn -0.869583 -0.130303 0.476284 +v -5.706012 162.620132 42.222797 1.000000 1.000000 1.000000 +vn 0.967853 -0.203867 0.147302 +v 5.716416 161.728516 39.629601 1.000000 1.000000 1.000000 +vn 0.983597 -0.080855 0.161245 +v 5.846490 162.511292 39.527397 1.000000 1.000000 1.000000 +vn 0.891077 0.063736 0.449354 +v 5.733410 163.402924 39.880379 1.000000 1.000000 1.000000 +vn 0.576281 -0.691341 -0.435831 +v -2.424004 167.445190 31.309599 1.000000 1.000000 1.000000 +vn 0.690044 -0.721985 0.050756 +v -2.823858 166.873108 32.045799 1.000000 1.000000 1.000000 +vn 0.850123 -0.526523 -0.008082 +v -3.643404 165.879623 31.814798 1.000000 1.000000 1.000000 +vn 0.532525 -0.795763 -0.288409 +v -2.350220 167.316833 31.707199 1.000000 1.000000 1.000000 +vn 0.427493 -0.762906 -0.484999 +v -1.860526 167.770309 31.424398 1.000000 1.000000 1.000000 +vn 0.752855 -0.528735 -0.391981 +v -3.406764 166.546600 31.078398 1.000000 1.000000 1.000000 +vn 0.393856 -0.539747 -0.744010 +v -1.957486 168.006119 31.089598 1.000000 1.000000 1.000000 +vn 0.432285 -0.869990 -0.237163 +v -1.803902 167.632172 31.821798 1.000000 1.000000 1.000000 +vn 0.420152 -0.906059 0.050286 +v -1.783032 167.581940 32.276596 1.000000 1.000000 1.000000 +vn 0.244594 -0.859599 -0.448624 +v -0.628160 168.151230 31.654999 1.000000 1.000000 1.000000 +vn 0.253577 -0.704247 -0.663125 +v -0.660868 168.406586 31.320398 1.000000 1.000000 1.000000 +vn 0.022579 -0.671790 -0.740397 +v 0.698790 168.402405 31.552998 1.000000 1.000000 1.000000 +vn 0.061199 -0.881384 -0.468420 +v 0.018960 168.198669 31.771599 1.000000 1.000000 1.000000 +vn -0.175107 -0.859395 -0.480393 +v 1.290390 167.996353 32.002800 1.000000 1.000000 1.000000 +vn -0.225079 -0.682939 -0.694934 +v 1.920586 168.022858 31.770399 1.000000 1.000000 1.000000 +vn -0.004600 -0.972138 -0.234365 +v 0.018362 168.047974 32.168999 1.000000 1.000000 1.000000 +vn -0.401662 -0.714688 -0.572616 +v 2.400830 167.460541 32.221596 1.000000 1.000000 1.000000 +vn -0.256081 -0.934962 -0.245495 +v 1.251090 167.852631 32.400398 1.000000 1.000000 1.000000 +vn -0.501497 -0.545573 -0.671454 +v 3.563064 166.741943 32.117996 1.000000 1.000000 1.000000 +vn -0.555540 -0.729071 -0.399788 +v 2.924358 167.050323 32.337601 1.000000 1.000000 1.000000 +vn -0.171058 -0.984714 0.032824 +v 0.636446 167.941940 32.739998 1.000000 1.000000 1.000000 +vn -0.392159 -0.919877 0.006191 +v 1.749326 167.597290 32.957397 1.000000 1.000000 1.000000 +vn -0.718791 -0.548026 -0.427794 +v 3.785708 166.017776 32.569000 1.000000 1.000000 1.000000 +vn -0.560495 -0.828113 -0.008589 +v 2.300766 167.284729 33.073997 1.000000 1.000000 1.000000 +vn -0.528932 -0.787517 0.316304 +v 2.393762 167.447983 33.898201 1.000000 1.000000 1.000000 +vn -0.661293 -0.605554 0.442714 +v 2.915746 167.039154 34.014198 1.000000 1.000000 1.000000 +vn 0.001945 -0.999979 0.006130 +v 0.018146 167.992157 32.623798 1.000000 1.000000 1.000000 +vn -0.397492 -0.795798 0.456844 +v 1.286590 167.982407 33.679398 1.000000 1.000000 1.000000 +vn -0.548342 -0.428302 0.718247 +v 3.066792 167.235886 34.361801 1.000000 1.000000 1.000000 +vn -0.768409 -0.549299 0.328356 +v 3.376534 166.559158 34.129398 1.000000 1.000000 1.000000 +vn -0.752439 -0.656749 0.050158 +v 3.245378 166.430786 33.305000 1.000000 1.000000 1.000000 +vn -0.682235 -0.179900 0.708654 +v 4.305350 165.523819 34.707798 1.000000 1.000000 1.000000 +vn -0.820212 -0.449754 0.353516 +v 3.774560 166.009399 34.245399 1.000000 1.000000 1.000000 +vn -0.856779 -0.318607 0.405486 +v 4.093328 165.410797 34.360199 1.000000 1.000000 1.000000 +vn -0.921569 -0.178581 0.344701 +v 4.332284 164.767548 34.475601 1.000000 1.000000 1.000000 +vn -0.916574 -0.397063 0.047267 +v 3.934336 165.327072 33.535797 1.000000 1.000000 1.000000 +vn -0.939016 -0.124092 0.320703 +v 4.485738 164.093597 34.590797 1.000000 1.000000 1.000000 +vn -0.245801 0.134352 0.959964 +v 5.033548 163.411285 35.209599 1.000000 1.000000 1.000000 +vn -0.280380 0.038220 0.959128 +v 4.526938 165.641022 34.862396 1.000000 1.000000 1.000000 +vn -0.272547 -0.070983 0.959521 +v 3.224638 167.441010 34.516399 1.000000 1.000000 1.000000 +vn -0.350670 -0.577404 0.737317 +v 1.353258 168.227982 34.027199 1.000000 1.000000 1.000000 +vn -0.226963 -0.168362 0.959240 +v 1.422924 168.484726 34.181599 1.000000 1.000000 1.000000 +vn -0.225137 -0.876218 0.426094 +v 0.662182 168.131699 33.564400 1.000000 1.000000 1.000000 +vn -0.114142 -0.666372 0.736831 +v 0.019914 168.440079 33.795799 1.000000 1.000000 1.000000 +vn -0.154301 -0.221782 0.962810 +v 0.020964 168.706573 33.950401 1.000000 1.000000 1.000000 +vn 0.178207 -0.658296 0.731361 +v -1.951100 167.990768 33.448601 1.000000 1.000000 1.000000 +vn -0.055089 -0.259531 0.964162 +v -2.051472 168.234955 33.603199 1.000000 1.000000 1.000000 +vn 0.448309 -0.524127 0.724092 +v -3.572630 166.707062 33.102600 1.000000 1.000000 1.000000 +vn 0.065733 -0.259318 0.963552 +v -3.756444 166.885666 33.257198 1.000000 1.000000 1.000000 +vn 0.601719 -0.337666 0.723820 +v -4.545786 164.884750 32.767998 1.000000 1.000000 1.000000 +vn -0.364373 -0.028916 0.930804 +v -5.006150 165.050812 32.918800 1.000000 1.000000 1.000000 +vn 0.176181 -0.218314 0.959843 +v -4.779684 164.969864 32.922398 1.000000 1.000000 1.000000 +vn -0.677491 0.021952 0.735204 +v -5.410498 164.316864 32.662998 1.000000 1.000000 1.000000 +vn -0.880251 -0.030681 0.473515 +v -5.731916 163.488022 32.209000 1.000000 1.000000 1.000000 +vn -0.623888 -0.172933 0.762140 +v -5.469180 162.632690 32.430397 1.000000 1.000000 1.000000 +vn -0.351625 -0.123538 0.927954 +v -5.271758 163.468491 32.687401 1.000000 1.000000 1.000000 +vn -0.884968 -0.142686 0.443252 +v -5.704674 162.606186 32.092598 1.000000 1.000000 1.000000 +vn -0.841358 -0.256766 0.475593 +v -5.565304 161.743866 31.977198 1.000000 1.000000 1.000000 +vn -0.982539 -0.113379 0.147521 +v -5.855412 162.588043 31.624399 1.000000 1.000000 1.000000 +vn -0.965108 -0.199691 -0.169382 +v -5.699884 161.707581 30.693398 1.000000 1.000000 1.000000 +vn -0.959366 -0.240236 0.148000 +v -5.712360 161.704788 31.508999 1.000000 1.000000 1.000000 +vn -0.598329 -0.331092 0.729644 +v -5.096674 161.009918 32.199600 1.000000 1.000000 1.000000 +vn -0.815054 -0.367718 0.447740 +v -5.316124 160.913635 31.861998 1.000000 1.000000 1.000000 +vn -0.919058 -0.364767 0.149259 +v -5.456602 160.850845 31.393599 1.000000 1.000000 1.000000 +vn -0.930280 -0.324924 -0.170307 +v -5.444692 160.856430 30.578199 1.000000 1.000000 1.000000 +vn -0.740482 -0.468902 0.481475 +v -4.962956 160.132248 31.747198 1.000000 1.000000 1.000000 +vn -0.228414 -0.229915 0.946027 +v -4.889350 161.100616 32.340199 1.000000 1.000000 1.000000 +vn -0.446735 -0.453978 0.770930 +v -4.320464 159.562943 31.968798 1.000000 1.000000 1.000000 +vn -0.861550 -0.484904 0.150329 +v -5.094098 160.049927 31.278999 1.000000 1.000000 1.000000 +vn -0.683049 -0.571687 0.454554 +v -4.506506 159.403885 31.630999 1.000000 1.000000 1.000000 +vn -0.878221 -0.446369 -0.171708 +v -5.082988 160.056900 30.463398 1.000000 1.000000 1.000000 +vn -0.787376 -0.597521 0.151684 +v -4.625572 159.302032 31.162798 1.000000 1.000000 1.000000 +vn -0.547566 -0.650149 0.526762 +v -3.965608 158.757843 31.515999 1.000000 1.000000 1.000000 +vn -0.724384 -0.667100 -0.173914 +v -4.061512 158.649002 30.232199 1.000000 1.000000 1.000000 +vn -0.696335 -0.701135 0.153389 +v -4.070396 158.639252 31.047598 1.000000 1.000000 1.000000 +vn -0.809883 -0.560575 -0.172758 +v -4.615478 159.311798 30.347198 1.000000 1.000000 1.000000 +vn -0.856582 -0.258085 -0.446832 +v -5.321506 160.910843 30.184998 1.000000 1.000000 1.000000 +vn -0.813722 -0.368492 -0.449522 +v -4.967978 160.129456 30.070398 1.000000 1.000000 1.000000 +vn -0.745316 -0.461424 -0.481240 +v -4.511062 159.399704 29.954199 1.000000 1.000000 1.000000 +vn -0.578351 -0.667676 -0.468742 +v -3.345454 158.191345 29.723198 1.000000 1.000000 1.000000 +vn -0.681531 -0.572263 -0.456103 +v -3.969626 158.752274 29.838999 1.000000 1.000000 1.000000 +vn -0.407923 -0.803563 -0.433458 +v -1.995376 157.415543 29.504398 1.000000 1.000000 1.000000 +vn -0.493062 -0.842530 -0.216870 +v -2.710946 157.601105 29.999598 1.000000 1.000000 1.000000 +vn -0.261192 -0.948713 -0.178110 +v -1.250150 157.027634 29.782198 1.000000 1.000000 1.000000 +vn -0.266104 -0.824888 -0.498747 +v -1.221870 157.168564 29.389198 1.000000 1.000000 1.000000 +vn -0.173517 -0.646836 -0.742627 +v -0.399730 157.299728 28.928398 1.000000 1.000000 1.000000 +vn -0.101005 -0.978195 -0.181476 +v -0.426556 156.899261 29.665998 1.000000 1.000000 1.000000 +vn -0.133913 -0.871619 -0.471538 +v -0.416920 157.042969 29.272999 1.000000 1.000000 1.000000 +vn -0.340343 -0.924388 0.172257 +v -2.046026 157.266235 30.712999 1.000000 1.000000 1.000000 +vn -0.204515 -0.965942 0.158525 +v -1.252882 157.015076 30.597799 1.000000 1.000000 1.000000 +vn 0.048837 -0.982132 -0.181747 +v 0.407608 156.899261 29.549599 1.000000 1.000000 1.000000 +vn 0.095814 -0.982862 0.157486 +v 0.408490 156.885300 30.365198 1.000000 1.000000 1.000000 +vn -0.055296 -0.985781 0.158678 +v -0.427490 156.885300 30.481598 1.000000 1.000000 1.000000 +vn -0.000754 -0.881714 -0.471784 +v 0.398364 157.042969 29.156399 1.000000 1.000000 1.000000 +vn 0.195781 -0.963676 -0.181653 +v 1.225778 157.023438 29.434198 1.000000 1.000000 1.000000 +vn 0.131462 -0.873327 0.469061 +v 0.397962 157.048569 30.833399 1.000000 1.000000 1.000000 +vn 0.261671 -0.827787 0.496283 +v 1.196822 157.169952 30.717999 1.000000 1.000000 1.000000 +vn 0.242218 -0.957435 0.156999 +v 1.228460 157.009491 30.249798 1.000000 1.000000 1.000000 +vn 0.002082 -0.866276 0.499561 +v -0.416498 157.049957 30.949799 1.000000 1.000000 1.000000 +vn 0.169249 -0.603993 0.778811 +v 0.381508 157.305298 31.171198 1.000000 1.000000 1.000000 +vn 0.385330 -0.797532 0.464181 +v 1.972034 157.411346 30.602798 1.000000 1.000000 1.000000 +vn 0.343423 -0.575747 0.742008 +v 1.890588 157.652740 30.940399 1.000000 1.000000 1.000000 +vn 0.383576 -0.910258 0.155886 +v 2.024164 157.257874 30.134399 1.000000 1.000000 1.000000 +vn 0.338744 -0.923424 -0.180392 +v 2.019736 157.270416 29.318998 1.000000 1.000000 1.000000 +vn 0.495185 -0.717749 0.489519 +v 2.703722 157.767166 30.487997 1.000000 1.000000 1.000000 +vn 0.471915 -0.430604 0.769335 +v 3.251108 158.443893 30.709599 1.000000 1.000000 1.000000 +vn 0.243888 -0.221505 0.944168 +v 1.813648 157.880188 31.080999 1.000000 1.000000 1.000000 +vn 0.513690 -0.843894 0.154808 +v 2.775190 157.623428 30.019798 1.000000 1.000000 1.000000 +vn 0.600193 -0.656491 0.456933 +v 3.391148 158.237381 30.371798 1.000000 1.000000 1.000000 +vn 0.472362 -0.863057 -0.178904 +v 2.769126 157.634598 29.204199 1.000000 1.000000 1.000000 +vn 0.629712 -0.761492 0.153600 +v 3.480782 158.104828 29.903599 1.000000 1.000000 1.000000 +vn 0.679140 -0.552800 0.482888 +v 4.005920 158.801102 30.256798 1.000000 1.000000 1.000000 +vn 0.592646 -0.785681 -0.177413 +v 3.473172 158.115997 29.087999 1.000000 1.000000 1.000000 +vn 0.698146 -0.693997 -0.175957 +v 4.102816 158.693665 28.972799 1.000000 1.000000 1.000000 +vn 0.731084 -0.665199 0.151745 +v 4.111790 158.683899 29.788399 1.000000 1.000000 1.000000 +vn 0.263144 -0.842580 -0.469909 +v 1.974030 157.405762 28.925798 1.000000 1.000000 1.000000 +vn 0.385996 -0.794927 -0.468080 +v 2.706452 157.761581 28.811199 1.000000 1.000000 1.000000 +vn 0.486848 -0.720818 -0.493356 +v 3.394572 158.231812 28.694998 1.000000 1.000000 1.000000 +vn 0.600637 -0.654289 -0.459502 +v 4.009962 158.796921 28.579798 1.000000 1.000000 1.000000 +vn 0.789119 -0.589051 -0.174096 +v 4.654450 159.364807 28.856998 1.000000 1.000000 1.000000 +vn 0.761303 -0.466614 0.450211 +v 4.544524 159.456909 30.140799 1.000000 1.000000 1.000000 +vn 0.816935 -0.556769 0.150422 +v 4.664646 159.356445 29.672598 1.000000 1.000000 1.000000 +vn 0.693530 -0.551431 -0.463615 +v 4.549120 159.452728 28.463799 1.000000 1.000000 1.000000 +vn 0.859419 -0.466043 -0.210245 +v 5.114814 160.121078 28.740398 1.000000 1.000000 1.000000 +vn 0.883871 -0.443499 0.148598 +v 5.126002 160.114105 29.555998 1.000000 1.000000 1.000000 +vn 0.394200 -0.545952 -0.739285 +v 3.844340 158.979706 28.235197 1.000000 1.000000 1.000000 +vn 0.462102 -0.419372 -0.781402 +v 4.361226 159.610397 28.119398 1.000000 1.000000 1.000000 +vn 0.821290 -0.389176 -0.417163 +v 5.311244 160.888519 28.245199 1.000000 1.000000 1.000000 +vn 0.951874 -0.256223 -0.168183 +v 5.693434 161.682465 28.522999 1.000000 1.000000 1.000000 +vn 0.931400 -0.325923 0.162072 +v 5.446108 160.828522 29.453798 1.000000 1.000000 1.000000 +vn 0.839031 -0.260009 -0.477935 +v 5.564608 161.718750 28.129999 1.000000 1.000000 1.000000 +vn 0.967094 -0.207261 0.147555 +v 5.705896 161.679672 29.338598 1.000000 1.000000 1.000000 +vn 0.978458 -0.118102 -0.169330 +v 5.840258 162.571289 28.406799 1.000000 1.000000 1.000000 +vn 0.589561 -0.348621 -0.728616 +v 5.091872 160.986191 27.900599 1.000000 1.000000 1.000000 +vn 0.883632 -0.145096 -0.445131 +v 5.708110 162.586655 28.013798 1.000000 1.000000 1.000000 +vn 0.224999 -0.565757 -0.793281 +v 2.594660 157.989014 28.466599 1.000000 1.000000 1.000000 +vn 0.125996 -0.856689 -0.500209 +v 1.198030 157.164383 29.041199 1.000000 1.000000 1.000000 +vn 0.986030 -0.078102 0.147119 +v 5.853044 162.569901 29.222399 1.000000 1.000000 1.000000 +vn 0.880499 -0.024830 0.473397 +v 5.702344 162.586655 29.690598 1.000000 1.000000 1.000000 +vn 0.878337 -0.161269 0.450018 +v 5.558982 161.720139 29.806799 1.000000 1.000000 1.000000 +vn 0.674718 -0.064607 0.735243 +v 5.329438 161.782928 30.144598 1.000000 1.000000 1.000000 +vn 0.359774 0.101021 0.927555 +v 5.244450 162.639664 30.168999 1.000000 1.000000 1.000000 +vn 0.365788 0.005798 0.930680 +v 4.879824 161.081085 30.400398 1.000000 1.000000 1.000000 +vn 0.626226 -0.202868 0.752785 +v 4.787794 160.320618 30.361998 1.000000 1.000000 1.000000 +vn 0.822860 -0.343591 0.452601 +v 4.994010 160.193649 30.024199 1.000000 1.000000 1.000000 +vn 0.345957 -0.135652 0.928392 +v 3.684242 159.158310 30.734999 1.000000 1.000000 1.000000 +vn 0.585833 -0.281449 0.759991 +v 4.356874 159.613190 30.478598 1.000000 1.000000 1.000000 +vn 0.122238 -0.336917 0.933566 +v -0.383110 157.546692 31.428198 1.000000 1.000000 1.000000 +vn 0.016468 -0.344428 0.938668 +v -1.833360 157.888550 31.659599 1.000000 1.000000 1.000000 +vn -0.051671 -0.652122 0.756352 +v -1.170262 157.425293 31.403799 1.000000 1.000000 1.000000 +vn -0.357614 -0.805493 0.472539 +v -2.646944 157.735062 31.283398 1.000000 1.000000 1.000000 +vn -0.153063 -0.866260 0.475568 +v -1.220642 157.175537 31.065998 1.000000 1.000000 1.000000 +vn -0.218433 -0.598712 0.770605 +v -2.537690 157.962509 31.621199 1.000000 1.000000 1.000000 +vn -0.469554 -0.868885 0.156711 +v -2.716880 157.588562 30.815199 1.000000 1.000000 1.000000 +vn -0.588495 -0.793442 0.155317 +v -3.430378 158.062973 30.931799 1.000000 1.000000 1.000000 +vn -0.621341 -0.763433 -0.176368 +v -3.422884 158.074142 30.116198 1.000000 1.000000 1.000000 +vn -0.475027 -0.700887 0.532078 +v -3.342068 158.196915 31.399998 1.000000 1.000000 1.000000 +vn -0.189202 -0.403218 0.895331 +v -3.647266 159.117844 31.994198 1.000000 1.000000 1.000000 +vn 0.235594 -0.149593 0.960270 +v -5.033278 163.458725 32.691200 1.000000 1.000000 1.000000 +vn 0.814151 -0.379203 0.439732 +v -4.321984 164.805222 32.420197 1.000000 1.000000 1.000000 +vn 0.808783 -0.501294 0.307528 +v -3.790588 165.985672 32.639000 1.000000 1.000000 1.000000 +vn 0.983659 -0.177075 0.032555 +v -4.307036 164.099182 31.480799 1.000000 1.000000 1.000000 +vn 0.579077 -0.742990 0.335612 +v -2.937928 167.019623 32.869999 1.000000 1.000000 1.000000 +vn 0.635044 -0.631887 0.444339 +v -3.396748 166.536835 32.754997 1.000000 1.000000 1.000000 +vn 0.928339 -0.371674 0.006639 +v -3.950198 165.292191 31.698198 1.000000 1.000000 1.000000 +vn 0.475781 -0.799837 0.365915 +v -2.416872 167.432648 32.986198 1.000000 1.000000 1.000000 +vn 0.173325 -0.913006 0.369295 +v -1.253050 167.993561 33.216400 1.000000 1.000000 1.000000 +vn 0.331330 -0.842204 0.425338 +v -1.855054 167.757751 33.100998 1.000000 1.000000 1.000000 +vn 0.108361 -0.932783 0.343763 +v -0.626312 168.137283 33.331596 1.000000 1.000000 1.000000 +vn -0.099774 -0.885410 0.453977 +v 0.018902 168.184723 33.448196 1.000000 1.000000 1.000000 +vn 0.170062 -0.985375 0.010687 +v -0.602010 167.947510 32.507401 1.000000 1.000000 1.000000 +vn 0.736733 -0.382317 -0.557725 +v -3.801790 165.994049 30.962399 1.000000 1.000000 1.000000 +vn 0.896656 -0.115159 0.427489 +v -4.551284 163.439194 32.188999 1.000000 1.000000 1.000000 +vn -0.700988 -0.092284 0.707177 +v 4.551026 164.866623 29.670998 1.000000 1.000000 1.000000 +vn -0.272883 0.073380 0.959245 +v 4.785258 164.950333 29.825598 1.000000 1.000000 1.000000 +vn -0.603423 -0.353613 0.714730 +v 3.539170 166.746124 29.324999 1.000000 1.000000 1.000000 +vn -0.280759 -0.036355 0.959089 +v 3.721322 166.926132 29.479597 1.000000 1.000000 1.000000 +vn -0.430707 -0.526614 0.732918 +v 1.966216 167.982407 28.990198 1.000000 1.000000 1.000000 +vn -0.249631 -0.139379 0.958258 +v 2.067424 168.225174 29.144798 1.000000 1.000000 1.000000 +vn -0.210713 -0.643854 0.735563 +v 0.671936 168.388443 28.758999 1.000000 1.000000 1.000000 +vn -0.184847 -0.199014 0.962406 +v 0.706550 168.653564 28.913601 1.000000 1.000000 1.000000 +vn -0.507923 -0.732295 0.453606 +v 1.869370 167.749374 28.642599 1.000000 1.000000 1.000000 +vn -0.349847 -0.835829 0.423080 +v 1.269538 167.989365 28.527399 1.000000 1.000000 1.000000 +vn -0.144230 -0.989523 0.006507 +v 0.613990 167.946121 27.586998 1.000000 1.000000 1.000000 +vn -0.313475 -0.948999 0.033670 +v 1.220208 167.805191 27.703199 1.000000 1.000000 1.000000 +vn -0.633954 -0.706465 0.314659 +v 2.898970 167.054504 28.861399 1.000000 1.000000 1.000000 +vn -0.227591 -0.862447 0.452092 +v 0.638822 168.135880 28.411398 1.000000 1.000000 1.000000 +vn 0.023379 -0.999674 0.010218 +v -0.006106 167.992157 27.470598 1.000000 1.000000 1.000000 +vn -0.147531 -0.961063 -0.233650 +v 0.621190 168.000534 27.132198 1.000000 1.000000 1.000000 +vn -0.389560 -0.887983 -0.244395 +v 1.817782 167.625198 27.363598 1.000000 1.000000 1.000000 +vn -0.520072 -0.854102 0.006013 +v 2.279292 167.297287 27.920597 1.000000 1.000000 1.000000 +vn -0.737834 -0.512632 0.439102 +v 3.364858 166.574509 28.977398 1.000000 1.000000 1.000000 +vn -0.669886 -0.742416 -0.008453 +v 2.786354 166.906586 28.037201 1.000000 1.000000 1.000000 +vn -0.652185 -0.646726 -0.395474 +v 3.374796 166.584274 27.300798 1.000000 1.000000 1.000000 +vn -0.498850 -0.654101 -0.568596 +v 2.907532 167.065674 27.184799 1.000000 1.000000 1.000000 +vn -0.299583 -0.826283 -0.476976 +v 1.874882 167.761948 26.965998 1.000000 1.000000 1.000000 +vn -0.321668 -0.644880 -0.693297 +v 2.502412 167.693558 26.733398 1.000000 1.000000 1.000000 +vn -0.574424 -0.474380 -0.667084 +v 3.968750 166.183807 27.081198 1.000000 1.000000 1.000000 +vn -0.786518 -0.448573 -0.424466 +v 4.098220 165.433121 27.531998 1.000000 1.000000 1.000000 +vn -0.076590 -0.667665 -0.740511 +v 1.339702 168.250305 26.516199 1.000000 1.000000 1.000000 +vn -0.069635 -0.880928 -0.468100 +v 0.640708 168.149841 26.734798 1.000000 1.000000 1.000000 +vn 0.148230 -0.731894 -0.665101 +v -0.006648 168.456802 26.283398 1.000000 1.000000 1.000000 +vn 0.115801 -0.885166 -0.450634 +v -0.006342 168.198669 26.618198 1.000000 1.000000 1.000000 +vn 0.313666 -0.814884 -0.487420 +v -1.275132 168.003326 26.387598 1.000000 1.000000 1.000000 +vn 0.302755 -0.922606 -0.239033 +v -1.236330 167.858215 26.784998 1.000000 1.000000 1.000000 +vn 0.312298 -0.587280 -0.746707 +v -1.341556 168.250305 26.052799 1.000000 1.000000 1.000000 +vn 0.413474 -0.862936 -0.290482 +v -1.817240 167.625198 26.670399 1.000000 1.000000 1.000000 +vn 0.473231 -0.763280 -0.439836 +v -1.874290 167.763336 26.272799 1.000000 1.000000 1.000000 +vn 0.284570 -0.957327 0.050457 +v -1.222018 167.805191 27.239798 1.000000 1.000000 1.000000 +vn -0.031082 -0.937823 0.345720 +v -0.006324 168.183319 28.294798 1.000000 1.000000 1.000000 +vn 0.206010 -0.880812 0.426299 +v -1.271378 167.989365 28.064198 1.000000 1.000000 1.000000 +vn 0.582860 -0.810943 0.051445 +v -2.342172 167.256821 27.008999 1.000000 1.000000 1.000000 +vn 0.036947 -0.928535 0.369401 +v -0.645222 168.134491 28.179398 1.000000 1.000000 1.000000 +vn 0.467864 -0.816441 0.338420 +v -2.436790 167.418686 27.833199 1.000000 1.000000 1.000000 +vn 0.772507 -0.634953 -0.008210 +v -3.278970 166.393112 26.777998 1.000000 1.000000 1.000000 +vn 0.355304 -0.858768 0.369158 +v -1.868766 167.749374 27.949398 1.000000 1.000000 1.000000 +vn 0.079997 -0.676356 0.732218 +v -1.337190 168.233566 28.411798 1.000000 1.000000 1.000000 +vn -0.092370 -0.249643 0.963922 +v -1.405968 168.490295 28.566399 1.000000 1.000000 1.000000 +vn 0.368690 -0.578662 0.727473 +v -3.104824 167.202408 28.065798 1.000000 1.000000 1.000000 +vn 0.026663 -0.265067 0.963861 +v -3.264562 167.406128 28.220398 1.000000 1.000000 1.000000 +vn -0.366011 0.017630 0.930443 +v -4.733114 165.773590 27.881998 1.000000 1.000000 1.000000 +vn 0.142359 -0.238843 0.960567 +v -4.518994 165.659164 27.885599 1.000000 1.000000 1.000000 +vn 0.548771 -0.412141 0.727317 +v -4.297856 165.540558 27.730997 1.000000 1.000000 1.000000 +vn -0.366100 -0.078159 0.927288 +v -5.195076 164.244293 27.650599 1.000000 1.000000 1.000000 +vn 0.667423 -0.209893 0.714487 +v -4.717330 164.152206 27.499798 1.000000 1.000000 1.000000 +vn 0.211228 -0.178529 0.960994 +v -4.960046 164.199646 27.654398 1.000000 1.000000 1.000000 +vn 0.756268 -0.481306 0.443174 +v -4.086258 165.427536 27.383398 1.000000 1.000000 1.000000 +vn 0.851318 -0.336230 0.402750 +v -4.328176 164.787079 27.268198 1.000000 1.000000 1.000000 +vn 0.988061 -0.153965 0.005422 +v -4.310898 164.075455 26.327799 1.000000 1.000000 1.000000 +vn 0.953131 -0.300801 0.032572 +v -4.160108 164.727081 26.443998 1.000000 1.000000 1.000000 +vn 0.733980 -0.604028 0.310522 +v -3.411452 166.520081 27.602198 1.000000 1.000000 1.000000 +vn 0.874398 -0.227337 0.428657 +v -4.485082 164.108948 27.151999 1.000000 1.000000 1.000000 +vn 0.872168 -0.489158 0.006943 +v -3.656626 165.855911 26.661398 1.000000 1.000000 1.000000 +vn 0.899615 -0.369111 -0.233345 +v -3.973566 165.367538 26.104399 1.000000 1.000000 1.000000 +vn 0.678249 -0.475373 -0.560355 +v -3.421520 166.529861 25.925598 1.000000 1.000000 1.000000 +vn 0.674046 -0.623528 -0.396075 +v -2.960690 167.018219 26.041599 1.000000 1.000000 1.000000 +vn 0.495805 -0.549205 -0.672720 +v -2.571344 167.648911 25.821999 1.000000 1.000000 1.000000 +vn 0.540986 -0.711688 0.448146 +v -2.951974 167.007065 27.718199 1.000000 1.000000 1.000000 +vn 0.267190 -0.090640 0.959372 +v -4.882398 161.905716 27.307198 1.000000 1.000000 1.000000 +vn -0.259401 -0.199132 0.945017 +v -5.113746 161.841537 27.303398 1.000000 1.000000 1.000000 +vn -0.245077 -0.374362 0.894310 +v -4.132298 159.694107 26.957399 1.000000 1.000000 1.000000 +vn -0.639002 -0.251552 0.726910 +v -5.330570 161.782928 27.162798 1.000000 1.000000 1.000000 +vn -0.506706 -0.391504 0.768097 +v -4.743350 160.234100 26.931999 1.000000 1.000000 1.000000 +vn -0.642343 -0.092956 0.760759 +v -5.495742 163.444778 27.393599 1.000000 1.000000 1.000000 +vn -0.034303 -0.343071 0.938683 +v -2.489756 158.209488 26.622799 1.000000 1.000000 1.000000 +vn -0.302706 -0.562503 0.769389 +v -3.178250 158.386688 26.584398 1.000000 1.000000 1.000000 +vn -0.146571 -0.637257 0.756585 +v -1.891014 157.652740 26.366999 1.000000 1.000000 1.000000 +vn 0.071424 -0.348784 0.934478 +v -1.095946 157.656921 26.391399 1.000000 1.000000 1.000000 +vn 0.208865 -0.250634 0.945282 +v 1.122236 157.662506 26.044197 1.000000 1.000000 1.000000 +vn 0.078559 -0.620327 0.780399 +v -0.368898 157.303909 26.134399 1.000000 1.000000 1.000000 +vn 0.406251 -0.489300 0.771716 +v 2.617140 158.008545 25.672798 1.000000 1.000000 1.000000 +vn 0.324121 -0.179431 0.928843 +v 3.135930 158.651794 25.698198 1.000000 1.000000 1.000000 +vn 0.256597 -0.616630 0.744262 +v 1.169858 157.425293 25.903599 1.000000 1.000000 1.000000 +vn 0.593341 -0.281224 0.754228 +v 4.375260 159.641098 25.325199 1.000000 1.000000 1.000000 +vn 0.541447 -0.354804 0.762200 +v 3.859546 159.004822 25.441799 1.000000 1.000000 1.000000 +vn 0.691205 -0.562470 0.453721 +v 4.025786 158.822021 25.103998 1.000000 1.000000 1.000000 +vn 0.769862 -0.446820 0.455702 +v 4.563708 159.486221 24.987398 1.000000 1.000000 1.000000 +vn 0.660369 -0.149149 0.735980 +v 5.095644 161.009918 25.107798 1.000000 1.000000 1.000000 +vn 0.596274 -0.638346 0.486797 +v 3.409738 158.251343 25.219801 1.000000 1.000000 1.000000 +vn 0.632923 -0.758807 0.153690 +v 3.499862 158.118790 24.751598 1.000000 1.000000 1.000000 +vn 0.734906 -0.660921 0.151979 +v 4.132196 158.704819 24.635599 1.000000 1.000000 1.000000 +vn 0.501887 -0.732124 0.460547 +v 2.729858 157.783905 25.334999 1.000000 1.000000 1.000000 +vn 0.516414 -0.842123 0.155389 +v 2.802022 157.638779 24.866798 1.000000 1.000000 1.000000 +vn 0.595506 -0.783446 -0.177722 +v 3.492228 158.129944 23.935999 1.000000 1.000000 1.000000 +vn 0.702123 -0.689914 -0.176187 +v 4.123158 158.714600 23.820198 1.000000 1.000000 1.000000 +vn 0.817727 -0.555495 0.150826 +v 4.684320 159.385742 24.519199 1.000000 1.000000 1.000000 +vn 0.789882 -0.575239 -0.212570 +v 4.674096 159.394119 23.703598 1.000000 1.000000 1.000000 +vn 0.611047 -0.638753 -0.467564 +v 4.029854 158.817841 23.426998 1.000000 1.000000 1.000000 +vn 0.502520 -0.729713 -0.463674 +v 3.413190 158.245758 23.542999 1.000000 1.000000 1.000000 +vn 0.475285 -0.861283 -0.179710 +v 2.795906 157.651352 24.051197 1.000000 1.000000 1.000000 +vn 0.378744 -0.781232 -0.496215 +v 2.732626 157.778320 23.658199 1.000000 1.000000 1.000000 +vn 0.398728 -0.476587 -0.783506 +v 3.863408 159.000626 23.082600 1.000000 1.000000 1.000000 +vn 0.761811 -0.492589 -0.420714 +v 4.965274 160.126678 23.208199 1.000000 1.000000 1.000000 +vn 0.535257 -0.421467 -0.732028 +v 4.760190 160.256439 22.863800 1.000000 1.000000 1.000000 +vn 0.797398 -0.365317 -0.480312 +v 5.320490 160.910843 23.093197 1.000000 1.000000 1.000000 +vn 0.911042 -0.376247 -0.168645 +v 5.443676 160.857819 23.486198 1.000000 1.000000 1.000000 +vn 0.639174 -0.260075 -0.723752 +v 5.341526 161.812241 22.632397 1.000000 1.000000 1.000000 +vn 0.233568 -0.199066 -0.951745 +v 5.102402 161.876419 22.481400 1.000000 1.000000 1.000000 +vn 0.611775 -0.140710 -0.778417 +v 5.474872 162.646652 22.515999 1.000000 1.000000 1.000000 +vn 0.883859 -0.141876 -0.445718 +v 5.710738 162.620132 22.860397 1.000000 1.000000 1.000000 +vn 0.857048 -0.255834 -0.447234 +v 5.571664 161.749435 22.976997 1.000000 1.000000 1.000000 +vn 0.955497 -0.241101 -0.169990 +v 5.700656 161.714569 23.369999 1.000000 1.000000 1.000000 +vn 0.881467 -0.443164 0.163161 +v 5.091356 160.048538 24.416998 1.000000 1.000000 1.000000 +vn 0.932572 -0.329240 0.148024 +v 5.455584 160.852249 24.301798 1.000000 1.000000 1.000000 +vn 0.849801 -0.271746 0.451655 +v 5.315108 160.913635 24.769999 1.000000 1.000000 1.000000 +vn 0.870144 -0.135475 0.473811 +v 5.566026 161.750839 24.653799 1.000000 1.000000 1.000000 +vn 0.968197 -0.202119 0.147453 +v 5.713120 161.711761 24.185598 1.000000 1.000000 1.000000 +vn 0.896494 -0.026380 0.442270 +v 5.704956 162.621521 24.537399 1.000000 1.000000 1.000000 +vn 0.647578 0.052257 0.760205 +v 5.469398 162.646652 24.875198 1.000000 1.000000 1.000000 +vn 0.986365 -0.073763 0.147117 +v 5.855746 162.604782 24.068998 1.000000 1.000000 1.000000 +vn 0.979004 -0.113747 -0.169154 +v 5.842948 162.606186 23.253597 1.000000 1.000000 1.000000 +vn 0.370745 0.054987 0.927105 +v 5.119088 161.872238 25.132198 1.000000 1.000000 1.000000 +vn -0.647087 -0.272984 0.711869 +v 3.945602 166.190781 24.288198 1.000000 1.000000 1.000000 +vn -0.283619 -0.000676 0.958937 +v 4.148664 166.342880 24.442799 1.000000 1.000000 1.000000 +vn -0.501931 -0.464942 0.729311 +v 2.542530 167.647522 23.953398 1.000000 1.000000 1.000000 +vn -0.267171 -0.106337 0.957764 +v 2.673390 167.873566 24.107998 1.000000 1.000000 1.000000 +vn -0.302896 -0.609425 0.732704 +v 1.311440 168.241928 23.722198 1.000000 1.000000 1.000000 +vn -0.211971 -0.174428 0.961584 +v 1.378956 168.498672 23.876799 1.000000 1.000000 1.000000 +vn -0.606193 -0.655966 0.449710 +v 2.417310 167.431229 23.605799 1.000000 1.000000 1.000000 +vn -0.466919 -0.778006 0.420349 +v 1.853238 167.757751 23.490597 1.000000 1.000000 1.000000 +vn -0.288246 -0.957539 0.005753 +v 1.198382 167.810776 22.550198 1.000000 1.000000 1.000000 +vn -0.446910 -0.893967 0.033082 +v 1.781230 167.581940 22.666397 1.000000 1.000000 1.000000 +vn -0.725127 -0.614585 0.310606 +v 3.350168 166.591248 23.824598 1.000000 1.000000 1.000000 +vn -0.351323 -0.821017 0.450004 +v 1.246838 167.996353 23.374397 1.000000 1.000000 1.000000 +vn -0.124146 -0.992210 0.010379 +v 0.589906 167.948914 22.433800 1.000000 1.000000 1.000000 +vn -0.286065 -0.929245 -0.233818 +v 1.212428 167.865189 22.095398 1.000000 1.000000 1.000000 +vn -0.634357 -0.773013 0.006505 +v 2.766770 166.923340 22.883797 1.000000 1.000000 1.000000 +vn -0.512421 -0.823484 -0.243514 +v 2.350606 167.315430 22.326797 1.000000 1.000000 1.000000 +vn -0.800499 -0.411554 0.435689 +v 3.751282 166.047073 23.940598 1.000000 1.000000 1.000000 +vn -0.764521 -0.644551 -0.007897 +v 3.220028 166.461487 23.000397 1.000000 1.000000 1.000000 +vn -0.735155 -0.553301 -0.391671 +v 3.762368 166.054047 22.264000 1.000000 1.000000 1.000000 +vn -0.586556 -0.579876 -0.565416 +v 3.360054 166.601028 22.147999 1.000000 1.000000 1.000000 +vn -0.415803 -0.775865 -0.474491 +v 2.424442 167.443802 21.929199 1.000000 1.000000 1.000000 +vn -0.634818 -0.395177 -0.663959 +v 4.300508 165.569855 22.044399 1.000000 1.000000 1.000000 +vn -0.839674 -0.342970 -0.421092 +v 4.334394 164.808014 22.495197 1.000000 1.000000 1.000000 +vn -0.412804 -0.596255 -0.688530 +v 3.037618 167.283340 21.696598 1.000000 1.000000 1.000000 +vn -0.197574 -0.862134 -0.466572 +v 1.250522 168.010300 21.697998 1.000000 1.000000 1.000000 +vn -0.174767 -0.651761 -0.738014 +v 1.955632 168.006119 21.479397 1.000000 1.000000 1.000000 +vn 0.039383 -0.744776 -0.666151 +v 0.647702 168.409378 21.246597 1.000000 1.000000 1.000000 +vn -0.014948 -0.892165 -0.451462 +v 0.615582 168.152634 21.581398 1.000000 1.000000 1.000000 +vn 0.164751 -0.956451 -0.240955 +v -0.645732 167.997757 21.748199 1.000000 1.000000 1.000000 +vn 0.191299 -0.850337 -0.490236 +v -0.665986 168.147049 21.350800 1.000000 1.000000 1.000000 +vn 0.223701 -0.622779 -0.749736 +v -0.700670 168.402405 21.015999 1.000000 1.000000 1.000000 +vn 0.283975 -0.913006 -0.292880 +v -1.250456 167.852631 21.633598 1.000000 1.000000 1.000000 +vn 0.359530 -0.821284 -0.442979 +v -1.289708 167.997757 21.236000 1.000000 1.000000 1.000000 +vn 0.141838 -0.988643 0.049670 +v -0.638258 167.941940 22.202999 1.000000 1.000000 1.000000 +vn -0.168738 -0.923035 0.345737 +v 0.613764 168.138672 23.257999 1.000000 1.000000 1.000000 +vn 0.074028 -0.900043 0.429468 +v -0.664032 168.131699 23.027397 1.000000 1.000000 1.000000 +vn 0.462477 -0.885134 0.051506 +v -1.816894 167.565186 21.972198 1.000000 1.000000 1.000000 +vn -0.100102 -0.923383 0.370600 +v -0.025390 168.184723 23.142597 1.000000 1.000000 1.000000 +vn 0.346021 -0.873689 0.341959 +v -1.890292 167.738205 22.796398 1.000000 1.000000 1.000000 +vn 0.677603 -0.735387 -0.007777 +v -2.853496 166.846588 21.740997 1.000000 1.000000 1.000000 +vn 0.226974 -0.900384 0.371202 +v -1.285906 167.983795 22.912598 1.000000 1.000000 1.000000 +vn -0.020570 -0.679890 0.733026 +v -0.698392 168.385651 23.375000 1.000000 1.000000 1.000000 +vn -0.127596 -0.235650 0.963425 +v -0.734292 168.649368 23.529598 1.000000 1.000000 1.000000 +vn 0.281589 -0.622941 0.729831 +v -2.579224 167.623795 23.028999 1.000000 1.000000 1.000000 +vn -0.012368 -0.265927 0.963914 +v -2.711912 167.848450 23.183598 1.000000 1.000000 1.000000 +vn 0.485439 -0.479668 0.730936 +v -3.969858 166.153122 22.694199 1.000000 1.000000 1.000000 +vn -0.360091 0.063471 0.930756 +v -4.371886 166.447540 22.844997 1.000000 1.000000 1.000000 +vn 0.105181 -0.254640 0.961299 +v -4.174116 166.303802 22.848797 1.000000 1.000000 1.000000 +vn 0.684041 -0.576618 0.446766 +v -3.774404 166.010788 22.346600 1.000000 1.000000 1.000000 +vn 0.799533 -0.442983 0.405602 +v -4.094678 165.410797 22.231400 1.000000 1.000000 1.000000 +vn 0.632493 -0.292909 0.717047 +v -4.559820 164.840103 22.462997 1.000000 1.000000 1.000000 +vn 0.182970 -0.203975 0.961726 +v -4.794438 164.922424 22.617599 1.000000 1.000000 1.000000 +vn -0.374353 -0.031298 0.926758 +v -5.021600 165.001968 22.613800 1.000000 1.000000 1.000000 +vn -0.649786 -0.011407 0.760031 +v -5.419934 164.254074 22.356800 1.000000 1.000000 1.000000 +vn -0.281558 -0.157805 0.946479 +v -5.242880 162.610367 22.266598 1.000000 1.000000 1.000000 +vn 0.251331 -0.123937 0.959933 +v -5.005700 162.638275 22.270397 1.000000 1.000000 1.000000 +vn -0.189878 -0.259359 0.946931 +v -4.537392 160.331787 21.919598 1.000000 1.000000 1.000000 +vn -0.673702 -0.156875 0.722160 +v -5.465190 162.582458 22.125999 1.000000 1.000000 1.000000 +vn -0.589469 -0.263404 0.763639 +v -5.323862 161.756424 22.010399 1.000000 1.000000 1.000000 +vn -0.083988 -0.334439 0.938667 +v -3.104580 158.626678 21.586800 1.000000 1.000000 1.000000 +vn -0.376988 -0.521218 0.765645 +v -3.755106 158.895981 21.546600 1.000000 1.000000 1.000000 +vn -0.238717 -0.610593 0.755109 +v -2.581992 157.986221 21.331200 1.000000 1.000000 1.000000 +vn 0.016653 -0.352604 0.935624 +v -1.793988 157.873199 21.355400 1.000000 1.000000 1.000000 +vn -0.031971 -0.647022 0.761801 +v -1.118518 157.414139 21.098400 1.000000 1.000000 1.000000 +vn 0.121965 -0.334051 0.934631 +v -0.337820 157.543900 21.123600 1.000000 1.000000 1.000000 +vn 0.249855 -0.348191 0.903513 +v 1.077632 157.652740 20.902397 1.000000 1.000000 1.000000 +vn 0.191384 -0.639557 0.744540 +v 0.427320 157.306702 20.866798 1.000000 1.000000 1.000000 +vn 0.407425 -0.485470 0.773514 +v 2.558198 157.973663 20.535000 1.000000 1.000000 1.000000 +vn 0.171059 -0.859436 0.481776 +v 0.445748 157.051361 20.528999 1.000000 1.000000 1.000000 +vn 0.009593 -0.867051 0.498127 +v -0.367258 157.045776 20.645397 1.000000 1.000000 1.000000 +vn 0.546438 -0.357477 0.757374 +v 3.987754 159.147141 20.276600 1.000000 1.000000 1.000000 +vn 0.336373 -0.757529 0.559467 +v 1.942100 157.398788 20.309799 1.000000 1.000000 1.000000 +vn 0.516000 -0.718621 0.466184 +v 2.668394 157.746231 20.197399 1.000000 1.000000 1.000000 +vn 0.652484 -0.214786 0.726726 +v 4.867128 160.476898 20.067600 1.000000 1.000000 1.000000 +vn 0.763645 -0.434601 0.477460 +v 4.663746 159.632721 19.833000 1.000000 1.000000 1.000000 +vn 0.688202 -0.558005 0.463690 +v 4.159516 158.971329 19.938795 1.000000 1.000000 1.000000 +vn 0.687938 -0.043829 0.724445 +v 5.383176 162.041061 19.863598 1.000000 1.000000 1.000000 +vn 0.851892 -0.223219 0.473765 +v 5.396348 161.145264 19.627800 1.000000 1.000000 1.000000 +vn 0.882100 -0.002124 0.471058 +v 5.721784 162.839203 19.427998 1.000000 1.000000 1.000000 +vn 0.888629 -0.118957 0.442931 +v 5.615038 161.989441 19.525799 1.000000 1.000000 1.000000 +vn 0.944098 -0.294603 0.147946 +v 5.538962 161.089447 19.159397 1.000000 1.000000 1.000000 +vn 0.980871 -0.161588 0.108545 +v 5.763434 161.955948 19.057598 1.000000 1.000000 1.000000 +vn 0.992339 -0.061974 0.106874 +v 5.872986 162.828033 18.959599 1.000000 1.000000 1.000000 +vn 0.911079 -0.120304 -0.394287 +v 5.727564 162.839203 17.750999 1.000000 1.000000 1.000000 +vn 0.909791 -0.199237 -0.364123 +v 5.620718 161.988052 17.848797 1.000000 1.000000 1.000000 +vn 0.813917 -0.327764 -0.479698 +v 5.401794 161.142471 17.950798 1.000000 1.000000 1.000000 +vn 0.934934 -0.311094 -0.170641 +v 5.526872 161.093628 18.343998 1.000000 1.000000 1.000000 +vn 0.777224 -0.437613 -0.452126 +v 5.081894 160.354111 18.052998 1.000000 1.000000 1.000000 +vn 0.651191 -0.214072 -0.728096 +v 5.388558 162.039673 17.504398 1.000000 1.000000 1.000000 +vn 0.876952 -0.448615 -0.172339 +v 5.199556 160.287140 18.445999 1.000000 1.000000 1.000000 +vn 0.897044 -0.416152 0.148762 +v 5.210924 160.280151 19.261597 1.000000 1.000000 1.000000 +vn 0.664088 -0.535545 -0.521708 +v 4.668458 159.628540 18.156197 1.000000 1.000000 1.000000 +vn 0.809185 -0.561287 -0.173713 +v 4.776554 159.544815 18.549198 1.000000 1.000000 1.000000 +vn 0.833886 -0.531103 0.150211 +v 4.787008 159.536438 19.364799 1.000000 1.000000 1.000000 +vn 0.826756 -0.341744 0.446862 +v 5.076756 160.356888 19.730000 1.000000 1.000000 1.000000 +vn 0.755487 -0.637328 0.151830 +v 4.269454 158.858307 19.470600 1.000000 1.000000 1.000000 +vn 0.606228 -0.595824 -0.526765 +v 4.163726 158.965759 18.261799 1.000000 1.000000 1.000000 +vn 0.725631 -0.665472 -0.174949 +v 4.260132 158.866684 18.654999 1.000000 1.000000 1.000000 +vn 0.554828 -0.386945 -0.736505 +v 4.871996 160.474106 17.708397 1.000000 1.000000 1.000000 +vn 0.359229 -0.572910 -0.736701 +v 3.428626 158.582031 18.025597 1.000000 1.000000 1.000000 +vn 0.161450 -0.638524 -0.752476 +v 1.863758 157.634598 18.288399 1.000000 1.000000 1.000000 +vn 0.277823 -0.831533 -0.481007 +v 1.944070 157.393219 18.632797 1.000000 1.000000 1.000000 +vn 0.017425 -0.674901 -0.737702 +v 1.124486 157.408554 18.402798 1.000000 1.000000 1.000000 +vn 0.504051 -0.724895 -0.469530 +v 3.576340 158.381104 18.370197 1.000000 1.000000 1.000000 +vn 0.116719 -0.892000 -0.436707 +v 1.172952 157.157394 18.747200 1.000000 1.000000 1.000000 +vn -0.144373 -0.654929 -0.741771 +v -0.352464 157.295532 18.623997 1.000000 1.000000 1.000000 +vn 0.322010 -0.929918 -0.177655 +v 1.989080 157.257874 19.025997 1.000000 1.000000 1.000000 +vn 0.064730 -0.972997 -0.221555 +v 0.456542 156.902054 19.245197 1.000000 1.000000 1.000000 +vn -0.110601 -0.871082 -0.478522 +v -0.367632 157.040192 18.968399 1.000000 1.000000 1.000000 +vn 0.243199 -0.954736 0.171270 +v 1.202742 157.002518 19.955799 1.000000 1.000000 1.000000 +vn 0.447429 -0.849981 -0.278101 +v 2.732948 157.613678 18.913597 1.000000 1.000000 1.000000 +vn 0.373842 -0.913915 0.158118 +v 1.993432 157.245300 19.841400 1.000000 1.000000 1.000000 +vn -0.093073 -0.978978 -0.181493 +v -0.376128 156.896469 19.361597 1.000000 1.000000 1.000000 +vn 0.099824 -0.982470 0.157441 +v 0.457544 156.888092 20.060799 1.000000 1.000000 1.000000 +vn -0.257666 -0.828015 -0.497995 +v -1.167846 157.157394 19.083797 1.000000 1.000000 1.000000 +vn -0.046537 -0.986414 0.157550 +v -0.376944 156.882523 20.176998 1.000000 1.000000 1.000000 +vn -0.239762 -0.953847 -0.180804 +v -1.194870 157.016464 19.476997 1.000000 1.000000 1.000000 +vn -0.194998 -0.968107 0.157307 +v -1.197482 157.002518 20.292400 1.000000 1.000000 1.000000 +vn -0.129184 -0.873826 0.468764 +v -1.166668 157.162979 20.760799 1.000000 1.000000 1.000000 +vn -0.339104 -0.927569 0.156922 +v -2.002084 157.248093 20.408798 1.000000 1.000000 1.000000 +vn -0.380412 -0.907182 -0.179743 +v -1.997720 157.262054 19.593399 1.000000 1.000000 1.000000 +vn -0.381219 -0.798129 -0.466543 +v -1.952516 157.397400 19.200199 1.000000 1.000000 1.000000 +vn -0.514948 -0.838234 -0.179421 +v -2.758274 157.627625 19.709599 1.000000 1.000000 1.000000 +vn -0.491953 -0.718105 -0.492247 +v -2.695882 157.754593 19.316399 1.000000 1.000000 1.000000 +vn -0.474108 -0.866538 0.155991 +v -2.764312 157.615067 20.524998 1.000000 1.000000 1.000000 +vn -0.250950 -0.830286 0.497644 +v -1.950560 157.402969 20.877197 1.000000 1.000000 1.000000 +vn -0.396988 -0.787615 0.471236 +v -2.693166 157.760178 20.993397 1.000000 1.000000 1.000000 +vn -0.576009 -0.785454 0.226442 +v -3.464740 158.090881 20.640198 1.000000 1.000000 1.000000 +vn -0.583793 -0.686067 0.434163 +v -3.916800 158.707611 21.208797 1.000000 1.000000 1.000000 +vn -0.779344 -0.606516 0.157355 +v -4.590036 159.253189 20.857197 1.000000 1.000000 1.000000 +vn -0.661587 -0.571423 0.485570 +v -4.471884 159.355057 21.325397 1.000000 1.000000 1.000000 +vn -0.718642 -0.694798 0.028436 +v -4.043940 158.561111 20.330597 1.000000 1.000000 1.000000 +vn -0.589783 -0.806234 -0.046284 +v -3.485134 158.060181 20.230198 1.000000 1.000000 1.000000 +vn -0.857423 -0.492187 0.150261 +v -5.063804 159.994110 20.973000 1.000000 1.000000 1.000000 +vn -0.808950 -0.559750 -0.179664 +v -4.580020 159.261566 20.041599 1.000000 1.000000 1.000000 +vn -0.752484 -0.480082 0.450875 +v -4.933446 160.077835 21.441399 1.000000 1.000000 1.000000 +vn -0.540797 -0.412321 0.733164 +v -4.729780 160.209000 21.779198 1.000000 1.000000 1.000000 +vn -0.795356 -0.372559 0.478131 +v -5.294108 160.857819 21.556599 1.000000 1.000000 1.000000 +vn -0.915780 -0.373048 0.148938 +v -5.433994 160.795029 21.088200 1.000000 1.000000 1.000000 +vn -0.874584 -0.453728 -0.170978 +v -5.052744 160.001083 20.157597 1.000000 1.000000 1.000000 +vn -0.963161 -0.208781 -0.169504 +v -5.687408 161.654556 20.388798 1.000000 1.000000 1.000000 +vn -0.927413 -0.333172 -0.170005 +v -5.422136 160.800613 20.272797 1.000000 1.000000 1.000000 +vn -0.957077 -0.249214 0.147971 +v -5.699846 161.651764 21.204399 1.000000 1.000000 1.000000 +vn -0.855493 -0.264871 0.444944 +v -5.553112 161.692230 21.672798 1.000000 1.000000 1.000000 +vn -0.981607 -0.121198 0.147508 +v -5.851150 162.535019 21.320000 1.000000 1.000000 1.000000 +vn -0.883448 -0.150330 0.443757 +v -5.700528 162.554550 21.788399 1.000000 1.000000 1.000000 +vn -0.982306 -0.080502 -0.169101 +v -5.838378 162.536407 20.504398 1.000000 1.000000 1.000000 +vn -0.880344 -0.037448 0.472856 +v -5.733474 163.428024 21.903599 1.000000 1.000000 1.000000 +vn -0.882389 -0.151174 -0.445575 +v -5.558724 161.690842 19.995800 1.000000 1.000000 1.000000 +vn -0.841183 -0.256048 -0.476289 +v -5.299452 160.855026 19.879597 1.000000 1.000000 1.000000 +vn -0.810509 -0.376125 -0.449005 +v -4.938430 160.073654 19.764397 1.000000 1.000000 1.000000 +vn -0.739299 -0.491325 -0.460475 +v -4.476404 159.350861 19.648598 1.000000 1.000000 1.000000 +vn -0.705422 -0.657683 -0.264258 +v -4.011508 158.598785 19.924999 1.000000 1.000000 1.000000 +vn -0.617300 -0.660996 -0.426643 +v -3.378968 158.219238 19.431599 1.000000 1.000000 1.000000 +vn -0.341426 -0.576288 -0.742509 +v -1.871920 157.638779 18.855797 1.000000 1.000000 1.000000 +vn 0.518158 -0.829939 0.206676 +v 2.738922 157.601105 19.729000 1.000000 1.000000 1.000000 +vn 0.473799 -0.880023 -0.032765 +v 2.755042 157.567627 19.319000 1.000000 1.000000 1.000000 +vn 0.653155 -0.728788 0.205566 +v 3.667158 158.258316 19.578800 1.000000 1.000000 1.000000 +vn 0.619960 -0.763315 -0.181658 +v 3.659150 158.269485 18.763199 1.000000 1.000000 1.000000 +vn -0.645279 -0.425877 -0.634227 +v 4.084366 165.989853 16.980797 1.000000 1.000000 1.000000 +vn -0.798314 -0.398919 -0.451175 +v 4.175456 165.251724 17.404598 1.000000 1.000000 1.000000 +vn -0.653133 -0.532083 -0.538799 +v 3.519536 166.402878 17.229198 1.000000 1.000000 1.000000 +vn -0.439558 -0.603036 -0.665685 +v 3.251328 167.083801 16.809998 1.000000 1.000000 1.000000 +vn -0.853119 -0.521551 0.013122 +v 3.720202 165.745682 18.167797 1.000000 1.000000 1.000000 +vn -0.658219 -0.712464 -0.243194 +v 2.996122 166.782410 17.542198 1.000000 1.000000 1.000000 +vn -0.880565 -0.232902 -0.412750 +v 4.468228 164.273605 17.542400 1.000000 1.000000 1.000000 +vn -0.706989 -0.704940 0.056793 +v 2.961438 166.741943 17.996998 1.000000 1.000000 1.000000 +vn -0.512392 -0.818431 -0.260050 +v 1.990240 167.534500 17.377598 1.000000 1.000000 1.000000 +vn -0.548874 -0.684567 -0.479694 +v 3.090224 166.894043 17.144798 1.000000 1.000000 1.000000 +vn -0.388571 -0.788938 -0.476014 +v 2.052760 167.668457 16.980000 1.000000 1.000000 1.000000 +vn -0.285347 -0.958296 -0.015641 +v 1.398410 167.742401 17.751198 1.000000 1.000000 1.000000 +vn -0.496168 -0.868040 0.017997 +v 1.967194 167.484268 17.832397 1.000000 1.000000 1.000000 +vn -0.239536 -0.613194 -0.752739 +v 2.159788 167.898682 16.645199 1.000000 1.000000 1.000000 +vn -0.127021 -0.955679 -0.265602 +v 0.238142 168.041000 17.145599 1.000000 1.000000 1.000000 +vn -0.205926 -0.751141 -0.627201 +v 1.459244 167.937744 16.898998 1.000000 1.000000 1.000000 +vn -0.043106 -0.641573 -0.765849 +v 0.901980 168.364731 16.487400 1.000000 1.000000 1.000000 +vn -0.008530 -0.887811 -0.460129 +v 0.245638 168.191696 16.748199 1.000000 1.000000 1.000000 +vn 0.116634 -0.992849 0.025442 +v -0.365070 167.975433 17.527397 1.000000 1.000000 1.000000 +vn -0.084384 -0.996271 0.017979 +v 0.235382 167.986588 17.600401 1.000000 1.000000 1.000000 +vn 0.243828 -0.871390 -0.425708 +v -1.017836 168.073105 16.602200 1.000000 1.000000 1.000000 +vn 0.078062 -0.391381 -0.916912 +v -0.400734 168.438675 16.340397 1.000000 1.000000 1.000000 +vn 0.266608 -0.927645 -0.261524 +v -0.986866 167.925186 16.999599 1.000000 1.000000 1.000000 +vn 0.225055 -0.423308 -0.877588 +v -1.760000 167.950302 16.326797 1.000000 1.000000 1.000000 +vn 0.414609 -0.908394 0.054039 +v -1.551916 167.682404 17.385197 1.000000 1.000000 1.000000 +vn 0.596634 -0.757359 -0.265397 +v -2.626552 167.113098 16.798199 1.000000 1.000000 1.000000 +vn 0.347292 -0.381738 -0.856542 +v -2.815012 167.224731 16.327400 1.000000 1.000000 1.000000 +vn 0.726047 -0.687641 -0.002231 +v -3.053326 166.648453 17.189400 1.000000 1.000000 1.000000 +vn 0.776750 -0.607369 -0.166622 +v -3.297650 166.453110 16.703800 1.000000 1.000000 1.000000 +vn 0.602156 -0.798226 0.015623 +v -2.596166 167.068451 17.252998 1.000000 1.000000 1.000000 +vn 0.169289 -0.908663 0.381672 +v -1.014840 168.057755 18.278797 1.000000 1.000000 1.000000 +vn 0.078883 -0.934322 0.347593 +v -0.379792 168.166580 18.351801 1.000000 1.000000 1.000000 +vn 0.387616 -0.804860 0.449394 +v -2.179692 167.581940 18.142399 1.000000 1.000000 1.000000 +vn -0.122533 -0.667538 0.734424 +v 0.257632 168.433090 18.772400 1.000000 1.000000 1.000000 +vn 0.159931 -0.639267 0.752170 +v -1.698200 168.100998 18.556999 1.000000 1.000000 1.000000 +vn -0.117770 -0.884008 0.452393 +v 0.244912 168.177750 18.424797 1.000000 1.000000 1.000000 +vn -0.263169 -0.889039 0.374636 +v 0.854736 168.096817 18.498798 1.000000 1.000000 1.000000 +vn -0.404006 -0.556498 0.726009 +v 2.152746 167.883331 19.004200 1.000000 1.000000 1.000000 +vn -0.357005 -0.822866 0.442085 +v 1.454956 167.923798 18.575600 1.000000 1.000000 1.000000 +vn -0.474072 -0.754947 0.453112 +v 2.046708 167.655884 18.656597 1.000000 1.000000 1.000000 +vn -0.615639 -0.698655 0.364513 +v 2.588610 167.308456 18.737997 1.000000 1.000000 1.000000 +vn -0.594357 -0.348407 0.724812 +v 3.690950 166.556366 19.253399 1.000000 1.000000 1.000000 +vn -0.673618 -0.657672 0.337203 +v 3.081110 166.882874 18.821400 1.000000 1.000000 1.000000 +vn -0.762172 -0.486264 0.427364 +v 3.509172 166.393112 18.905800 1.000000 1.000000 1.000000 +vn -0.817943 -0.510834 0.264608 +v 3.408220 166.303802 18.512199 1.000000 1.000000 1.000000 +vn -0.678869 -0.153818 0.717967 +v 4.378812 165.348007 19.428799 1.000000 1.000000 1.000000 +vn -0.875875 -0.125391 0.465961 +v 4.455058 164.269409 19.218800 1.000000 1.000000 1.000000 +vn -0.866676 -0.245782 0.434125 +v 4.163160 165.244751 19.081200 1.000000 1.000000 1.000000 +vn -0.931469 -0.278567 0.234020 +v 4.043398 165.187546 18.687399 1.000000 1.000000 1.000000 +vn -0.948411 -0.315420 -0.032057 +v 4.113256 164.866623 18.301598 1.000000 1.000000 1.000000 +vn -0.901028 -0.355325 -0.248781 +v 4.048330 165.190338 17.801998 1.000000 1.000000 1.000000 +vn -0.119842 -0.210815 0.970152 +v 0.270922 168.699600 18.926998 1.000000 1.000000 1.000000 +vn 0.358610 -0.571132 0.738381 +v -2.840904 167.428452 18.424999 1.000000 1.000000 1.000000 +vn 0.455062 -0.676353 0.579193 +v -2.701044 167.223343 18.077400 1.000000 1.000000 1.000000 +vn 0.686111 -0.685753 0.242887 +v -3.293646 166.448929 17.588997 1.000000 1.000000 1.000000 +vn -0.015721 -0.244216 0.969594 +v -1.785556 168.350769 18.711597 1.000000 1.000000 1.000000 +vn 0.069248 -0.240902 0.968076 +v -2.987058 167.643326 18.579597 1.000000 1.000000 1.000000 +vn 0.493845 -0.467406 0.733245 +v -3.566772 166.715439 18.330399 1.000000 1.000000 1.000000 +vn 0.133917 -0.205974 0.969351 +v -3.750278 166.894043 18.484997 1.000000 1.000000 1.000000 +vn 0.629383 -0.275217 0.726727 +v -4.542168 164.900101 18.155998 1.000000 1.000000 1.000000 +vn 0.644138 -0.619098 0.449226 +v -3.391174 166.543808 17.982800 1.000000 1.000000 1.000000 +vn 0.819550 -0.482539 0.309023 +v -3.772628 166.014969 17.922600 1.000000 1.000000 1.000000 +vn 0.829343 -0.341350 0.442347 +v -4.318532 164.817780 17.808399 1.000000 1.000000 1.000000 +vn 0.929733 -0.366066 -0.039894 +v -3.925028 165.350800 17.040199 1.000000 1.000000 1.000000 +vn 0.841801 -0.539617 -0.013576 +v -3.626126 165.907532 17.098400 1.000000 1.000000 1.000000 +vn 0.541598 -0.283529 -0.791380 +v -3.901608 165.719162 16.328400 1.000000 1.000000 1.000000 +vn 0.604049 -0.139226 -0.784692 +v -4.336042 164.459183 16.326797 1.000000 1.000000 1.000000 +vn 0.998855 -0.044334 -0.017978 +v -4.372234 163.493607 16.877197 1.000000 1.000000 1.000000 +vn 0.633718 0.014567 -0.773427 +v -4.448220 163.239655 16.326797 1.000000 1.000000 1.000000 +vn 0.983671 -0.179965 -0.001993 +v -4.300740 164.136856 16.929798 1.000000 1.000000 1.000000 +vn 0.969857 -0.048347 0.238832 +v -4.420528 163.056870 17.273399 1.000000 1.000000 1.000000 +vn 0.903652 -0.038566 0.426529 +v -4.551426 163.051285 17.667198 1.000000 1.000000 1.000000 +vn 0.861006 -0.166879 0.480437 +v -4.474486 164.171738 17.754200 1.000000 1.000000 1.000000 +vn 0.988174 0.150952 0.026953 +v -4.311272 162.421997 16.793598 1.000000 1.000000 1.000000 +vn 0.200095 -0.143176 0.969259 +v -4.775872 164.985214 18.310600 1.000000 1.000000 1.000000 +vn 0.689837 -0.050122 0.722227 +v -4.787124 163.041519 18.014797 1.000000 1.000000 1.000000 +vn 0.248211 -0.061965 0.966722 +v -5.033432 163.030350 18.169399 1.000000 1.000000 1.000000 +vn -0.644511 -0.227878 0.729847 +v -5.238026 161.432709 17.928799 1.000000 1.000000 1.000000 +vn -0.284084 -0.126361 0.950436 +v -5.024960 161.506653 18.069395 1.000000 1.000000 1.000000 +vn 0.636331 0.146903 0.757299 +v -4.562870 161.667114 17.918598 1.000000 1.000000 1.000000 +vn 0.256035 0.010747 0.966608 +v -4.797644 161.584793 18.073200 1.000000 1.000000 1.000000 +vn -0.506084 -0.372251 0.778016 +v -4.608576 159.992722 17.840797 1.000000 1.000000 1.000000 +vn -0.272268 -0.323671 0.906150 +v -3.502116 158.971329 17.900597 1.000000 1.000000 1.000000 +vn 0.244133 0.081533 0.966308 +v -4.221110 160.267593 17.985197 1.000000 1.000000 1.000000 +vn -0.900021 -0.002958 0.435836 +v -5.728890 163.568954 17.721600 1.000000 1.000000 1.000000 +vn -0.838761 -0.137072 0.526963 +v -5.649004 162.166641 17.638199 1.000000 1.000000 1.000000 +vn -0.857285 -0.296760 0.420709 +v -5.463580 161.354568 17.591000 1.000000 1.000000 1.000000 +vn -0.734377 -0.486237 0.473564 +v -4.807028 159.853180 17.503197 1.000000 1.000000 1.000000 +vn -0.317706 -0.555617 0.768344 +v -2.998956 158.252731 17.718197 1.000000 1.000000 1.000000 +vn -0.900815 -0.382975 0.204603 +v -5.317670 160.507599 17.077797 1.000000 1.000000 1.000000 +vn -0.581074 -0.593453 0.556926 +v -3.807776 158.597382 17.422199 1.000000 1.000000 1.000000 +vn -0.835271 -0.528265 0.152504 +v -4.934040 159.763885 17.034798 1.000000 1.000000 1.000000 +vn -0.774106 -0.607046 0.179599 +v -4.463028 159.082962 16.993599 1.000000 1.000000 1.000000 +vn -0.976023 -0.167964 0.138447 +v -5.798274 162.137344 17.169800 1.000000 1.000000 1.000000 +vn -0.723002 -0.177279 -0.667712 +v -5.695442 161.540146 16.329800 1.000000 1.000000 1.000000 +vn -0.665715 -0.326206 -0.671128 +v -5.256308 160.284348 16.327999 1.000000 1.000000 1.000000 +vn -0.665592 -0.720560 0.194372 +v -3.908394 158.474594 16.953999 1.000000 1.000000 1.000000 +vn -0.528180 -0.529993 -0.663425 +v -4.031450 158.531799 16.327000 1.000000 1.000000 1.000000 +vn -0.464552 -0.745749 0.477546 +v -3.128076 158.037857 17.380398 1.000000 1.000000 1.000000 +vn -0.561583 -0.817001 0.130901 +v -3.210732 157.899719 16.912197 1.000000 1.000000 1.000000 +vn -0.299749 -0.680259 -0.668878 +v -2.223506 157.306702 16.326797 1.000000 1.000000 1.000000 +vn -0.453612 -0.867780 0.202965 +v -2.533298 157.488083 16.876999 1.000000 1.000000 1.000000 +vn -0.072358 -0.611942 0.787585 +v -0.982170 157.384842 17.617798 1.000000 1.000000 1.000000 +vn -0.288943 -0.780566 0.554282 +v -1.762406 157.331818 17.311798 1.000000 1.000000 1.000000 +vn -0.302891 -0.938585 0.165271 +v -1.808976 157.175537 16.843597 1.000000 1.000000 1.000000 +vn -0.175895 -0.973479 0.146287 +v -1.051498 156.970428 16.811798 1.000000 1.000000 1.000000 +vn -0.041544 -0.772880 -0.633191 +v -0.321326 156.840652 16.326797 1.000000 1.000000 1.000000 +vn -0.122763 -0.874719 0.468824 +v -1.024436 157.132278 17.280197 1.000000 1.000000 1.000000 +vn 0.067676 -0.591323 0.803590 +v 0.435522 157.305298 17.561199 1.000000 1.000000 1.000000 +vn -0.089409 -0.372436 0.923741 +v -1.620952 157.807617 17.790199 1.000000 1.000000 1.000000 +vn 0.088827 -0.989096 0.117469 +v 0.466316 156.885300 16.755199 1.000000 1.000000 1.000000 +vn 0.077918 -0.876933 0.474254 +v 0.454304 157.048569 17.223400 1.000000 1.000000 1.000000 +vn 0.211809 -0.964690 0.156555 +v 1.229688 157.006714 16.729000 1.000000 1.000000 1.000000 +vn 0.824042 -0.405162 0.395978 +v 1.958374 157.451813 17.276398 1.000000 1.000000 1.000000 +vn 0.662227 -0.044624 0.747974 +v 1.838678 157.799240 17.652798 1.000000 1.000000 1.000000 +vn 0.732528 -0.455530 -0.505861 +v 2.047442 157.183914 16.326797 1.000000 1.000000 1.000000 +vn 0.195166 0.138981 0.970873 +v -3.343678 159.165283 17.904400 1.000000 1.000000 1.000000 +vn 0.143732 0.171456 0.974651 +v -1.547642 158.053207 17.793999 1.000000 1.000000 1.000000 +vn 0.015985 0.641828 0.766682 +v 0.379298 158.071350 17.550999 1.000000 1.000000 1.000000 +vn -0.985560 -0.060337 0.158213 +v -5.883568 162.994080 17.218998 1.000000 1.000000 1.000000 +vn 0.837207 -0.336694 0.430953 +v -4.335322 164.761963 22.115200 1.000000 1.000000 1.000000 +vn 0.931067 -0.173803 0.320791 +v -4.488866 164.081055 21.998798 1.000000 1.000000 1.000000 +vn 0.960551 -0.278048 0.005588 +v -4.166970 164.703369 21.291000 1.000000 1.000000 1.000000 +vn 0.906523 -0.420881 0.032807 +v -3.935674 165.327072 21.407200 1.000000 1.000000 1.000000 +vn 0.644860 -0.696904 0.313815 +v -2.968776 166.991714 22.565399 1.000000 1.000000 1.000000 +vn 0.799818 -0.600208 0.006521 +v -3.294960 166.372177 21.624599 1.000000 1.000000 1.000000 +vn 0.843699 -0.482723 -0.234840 +v -3.670326 165.934052 21.067600 1.000000 1.000000 1.000000 +vn 0.935760 -0.276769 -0.218521 +v -4.215754 164.720108 20.836197 1.000000 1.000000 1.000000 +vn 0.433517 -0.779522 0.452116 +v -2.452252 167.408905 22.681400 1.000000 1.000000 1.000000 +vn 0.581074 -0.708635 -0.400235 +v -2.459488 167.420074 21.004799 1.000000 1.000000 1.000000 +vn 0.413073 -0.609738 -0.676454 +v -1.994656 167.986588 20.785198 1.000000 1.000000 1.000000 +vn 0.606693 -0.558772 -0.565418 +v -2.977544 167.002869 20.888798 1.000000 1.000000 1.000000 +vn 0.795452 -0.397674 -0.457288 +v -3.785554 166.019165 20.669998 1.000000 1.000000 1.000000 +vn -0.920632 -0.277156 -0.274992 +v 4.202428 164.760574 22.892799 1.000000 1.000000 1.000000 +vn -0.898175 -0.436833 0.049577 +v 3.917070 165.363358 23.231400 1.000000 1.000000 1.000000 +vn -0.910793 -0.093024 0.402248 +v 4.479866 164.134064 24.286598 1.000000 1.000000 1.000000 +vn -0.909484 -0.225848 0.349042 +v 4.321636 164.802429 24.171799 1.000000 1.000000 1.000000 +vn -0.886392 -0.331910 0.322714 +v 4.075380 165.448471 24.055599 1.000000 1.000000 1.000000 +vn 0.267351 -0.841325 -0.469783 +v 1.991862 157.414139 23.774399 1.000000 1.000000 1.000000 +vn 0.343697 -0.921558 -0.180566 +v 2.037992 157.278793 24.167398 1.000000 1.000000 1.000000 +vn 0.137411 -0.871117 -0.471459 +v 1.221494 157.168564 23.888998 1.000000 1.000000 1.000000 +vn 0.247447 -0.955984 0.157684 +v 1.252524 157.015076 25.097601 1.000000 1.000000 1.000000 +vn 0.201025 -0.962715 -0.181023 +v 1.249784 157.027634 24.282198 1.000000 1.000000 1.000000 +vn 0.387676 -0.908458 0.156241 +v 2.042446 157.266235 24.982998 1.000000 1.000000 1.000000 +vn -0.001856 -0.865580 -0.500767 +v 0.422360 157.044388 24.004398 1.000000 1.000000 1.000000 +vn 0.052227 -0.981935 -0.181868 +v 0.432142 156.900650 24.397398 1.000000 1.000000 1.000000 +vn 0.099797 -0.982432 0.157698 +v 0.433098 156.886703 25.212999 1.000000 1.000000 1.000000 +vn -0.130067 -0.871893 -0.472108 +v -0.385156 157.041580 24.119598 1.000000 1.000000 1.000000 +vn -0.266350 -0.616799 -0.740687 +v -1.143536 157.414139 23.891598 1.000000 1.000000 1.000000 +vn -0.095736 -0.978717 -0.181516 +v -0.394054 156.897873 24.512798 1.000000 1.000000 1.000000 +vn -0.260474 -0.843194 -0.470295 +v -1.192768 157.161591 24.236198 1.000000 1.000000 1.000000 +vn -0.383059 -0.779019 -0.496382 +v -1.974416 157.405762 24.352398 1.000000 1.000000 1.000000 +vn -0.243556 -0.952956 -0.180431 +v -1.220370 157.020645 24.629198 1.000000 1.000000 1.000000 +vn -0.049766 -0.986228 0.157724 +v -0.394918 156.883911 25.328199 1.000000 1.000000 1.000000 +vn -0.343600 -0.925898 0.157012 +v -2.024526 157.257874 25.560999 1.000000 1.000000 1.000000 +vn -0.396211 -0.900978 -0.176793 +v -2.020108 157.270416 24.745398 1.000000 1.000000 1.000000 +vn -0.199334 -0.967059 0.158314 +v -1.223040 157.008102 25.444799 1.000000 1.000000 1.000000 +vn -0.277909 -0.835441 0.474137 +v -1.972420 157.411346 26.029198 1.000000 1.000000 1.000000 +vn -0.469943 -0.866190 0.169906 +v -2.778576 157.624832 25.676197 1.000000 1.000000 1.000000 +vn -0.125577 -0.857536 0.498861 +v -1.191568 157.168564 25.912998 1.000000 1.000000 1.000000 +vn -0.607060 -0.765217 -0.214291 +v -3.395268 158.054596 24.962799 1.000000 1.000000 1.000000 +vn -0.518014 -0.739597 -0.429718 +v -2.709788 157.762970 24.467398 1.000000 1.000000 1.000000 +vn -0.469270 -0.747671 0.469865 +v -3.315108 158.175995 26.246599 1.000000 1.000000 1.000000 +vn -0.587164 -0.794651 0.154171 +v -3.402696 158.042038 25.778399 1.000000 1.000000 1.000000 +vn -0.692775 -0.704659 0.153357 +v -4.050004 158.616928 25.894999 1.000000 1.000000 1.000000 +vn -0.569177 -0.629128 0.529373 +v -3.945756 158.736923 26.363199 1.000000 1.000000 1.000000 +vn -0.720332 -0.671187 -0.175016 +v -4.041172 158.628082 25.079399 1.000000 1.000000 1.000000 +vn -0.785113 -0.600472 0.151760 +v -4.611718 159.282486 26.010799 1.000000 1.000000 1.000000 +vn -0.632914 -0.570737 0.523144 +v -4.493000 159.384354 26.478998 1.000000 1.000000 1.000000 +vn -0.754974 -0.476544 0.450467 +v -4.947608 160.104340 26.594198 1.000000 1.000000 1.000000 +vn -0.859855 -0.487996 0.150030 +v -5.078340 160.022018 26.125998 1.000000 1.000000 1.000000 +vn -0.807446 -0.564089 -0.172728 +v -4.601650 159.290863 25.195198 1.000000 1.000000 1.000000 +vn -0.917404 -0.368961 0.149123 +v -5.448542 160.831314 26.242199 1.000000 1.000000 1.000000 +vn -0.928827 -0.329075 -0.170263 +v -5.436646 160.836884 25.426598 1.000000 1.000000 1.000000 +vn -0.876808 -0.449285 -0.171319 +v -5.067254 160.029007 25.310398 1.000000 1.000000 1.000000 +vn -0.796980 -0.368794 0.478344 +v -5.308284 160.894104 26.710398 1.000000 1.000000 1.000000 +vn -0.958338 -0.244315 0.147981 +v -5.707016 161.678284 26.356798 1.000000 1.000000 1.000000 +vn -0.856607 -0.260562 0.445344 +v -5.560102 161.718750 26.825199 1.000000 1.000000 1.000000 +vn -0.982156 -0.116733 0.147455 +v -5.853172 162.561523 26.472198 1.000000 1.000000 1.000000 +vn -0.964285 -0.203613 -0.169399 +v -5.694566 161.682465 25.541401 1.000000 1.000000 1.000000 +vn -0.868064 -0.147973 0.473886 +v -5.702498 162.579666 26.940399 1.000000 1.000000 1.000000 +vn -0.896333 -0.030154 0.442356 +v -5.732380 163.453140 27.055798 1.000000 1.000000 1.000000 +vn -0.883278 -0.147343 -0.445095 +v -5.565728 161.717346 25.148199 1.000000 1.000000 1.000000 +vn -0.855435 -0.261197 -0.447222 +v -5.313652 160.891312 25.033598 1.000000 1.000000 1.000000 +vn -0.800455 -0.360589 -0.478798 +v -4.952604 160.101547 24.917398 1.000000 1.000000 1.000000 +vn -0.753240 -0.477282 -0.452583 +v -4.497544 159.380157 24.802198 1.000000 1.000000 1.000000 +vn -0.666121 -0.583909 -0.464040 +v -3.949734 158.732727 24.686199 1.000000 1.000000 1.000000 +vn 0.001629 -0.882956 0.469453 +v -0.384762 157.047165 25.796598 1.000000 1.000000 1.000000 +vn 0.137967 -0.856513 0.497344 +v 0.421928 157.049957 25.681198 1.000000 1.000000 1.000000 +vn 0.265793 -0.843826 0.466168 +v 1.220258 157.175537 25.565998 1.000000 1.000000 1.000000 +vn 0.387387 -0.779337 0.492509 +v 1.989854 157.419724 25.451199 1.000000 1.000000 1.000000 +vn -0.610800 -0.301060 -0.732315 +v 4.565922 164.872192 27.311998 1.000000 1.000000 1.000000 +vn -0.831837 -0.302198 -0.465537 +v 4.339686 164.791260 27.646799 1.000000 1.000000 1.000000 +vn -0.876958 -0.392745 -0.276941 +v 3.973436 165.366150 27.929598 1.000000 1.000000 1.000000 +vn -0.833322 -0.550520 0.050029 +v 3.614912 165.921494 28.268198 1.000000 1.000000 1.000000 +vn -0.929693 -0.291886 -0.224664 +v 4.207540 164.745224 28.044197 1.000000 1.000000 1.000000 +vn -0.959929 -0.276259 0.047084 +v 4.158834 164.727081 28.498999 1.000000 1.000000 1.000000 +vn -0.835167 -0.443466 0.325323 +v 3.760990 166.030319 29.092398 1.000000 1.000000 1.000000 +vn -0.872504 -0.339778 0.351125 +v 4.086156 165.426147 29.208599 1.000000 1.000000 1.000000 +vn -0.891267 -0.207269 0.403341 +v 4.326902 164.787079 29.323399 1.000000 1.000000 1.000000 +vn -0.937082 -0.060807 0.343772 +v 4.482712 164.114532 29.438599 1.000000 1.000000 1.000000 +vn -0.817784 -0.503071 -0.279551 +v 3.670428 165.932648 32.966400 1.000000 1.000000 1.000000 +vn -0.884036 -0.408923 -0.226414 +v 3.980414 165.352188 33.081001 1.000000 1.000000 1.000000 +vn -0.784438 -0.406543 -0.468380 +v 4.105416 165.417786 32.683598 1.000000 1.000000 1.000000 +vn -0.563136 -0.376625 -0.735549 +v 4.319448 165.530792 32.348801 1.000000 1.000000 1.000000 +vn 0.718569 -0.341811 0.605660 +v -4.530530 164.930801 42.813980 1.000000 1.000000 1.000000 +vn 0.830123 -0.053171 0.555039 +v -4.786198 163.472672 42.640800 1.000000 1.000000 1.000000 +vn 0.827930 -0.410813 0.381791 +v -4.069058 165.462433 42.544979 1.000000 1.000000 1.000000 +vn 0.718807 -0.539256 0.438771 +v -3.731944 166.076370 42.627380 1.000000 1.000000 1.000000 +vn 0.621731 -0.435030 0.651306 +v -3.925194 166.222885 42.975197 1.000000 1.000000 1.000000 +vn 0.910138 -0.380402 0.164144 +v -3.911046 165.377319 41.720596 1.000000 1.000000 1.000000 +vn 0.655984 -0.665008 0.357000 +v -3.317594 166.630325 42.707798 1.000000 1.000000 1.000000 +vn 0.483302 -0.692826 0.535175 +v -2.834170 167.113098 42.785580 1.000000 1.000000 1.000000 +vn 0.431252 -0.780142 0.453211 +v -2.299570 167.507980 42.859779 1.000000 1.000000 1.000000 +vn 0.835312 -0.549774 0.001143 +v -3.587024 165.967529 41.803177 1.000000 1.000000 1.000000 +vn 0.849525 -0.479501 -0.219970 +v -3.629036 165.999634 41.348396 1.000000 1.000000 1.000000 +vn 0.753257 -0.618493 -0.223764 +v -3.226106 166.538223 41.428596 1.000000 1.000000 1.000000 +vn 0.665226 -0.746459 -0.016518 +v -2.724116 166.962402 41.961197 1.000000 1.000000 1.000000 +vn 0.785177 -0.432786 -0.442937 +v -3.742964 166.084747 40.950996 1.000000 1.000000 1.000000 +vn 0.867342 -0.244518 -0.433508 +v -4.320180 164.852661 40.789799 1.000000 1.000000 1.000000 +vn 0.608828 -0.686150 -0.398154 +v -2.842540 167.124268 41.108997 1.000000 1.000000 1.000000 +vn 0.626805 -0.743036 -0.234549 +v -2.756008 167.005676 41.506397 1.000000 1.000000 1.000000 +vn 0.336942 -0.563038 -0.754625 +v -1.802384 168.074493 40.921997 1.000000 1.000000 1.000000 +vn 0.397551 -0.777243 -0.487696 +v -1.713110 167.835892 41.256798 1.000000 1.000000 1.000000 +vn 0.431821 -0.873024 -0.226628 +v -1.660980 167.694962 41.654198 1.000000 1.000000 1.000000 +vn 0.422649 -0.904696 0.053790 +v -1.641758 167.644730 42.108997 1.000000 1.000000 1.000000 +vn 0.176345 -0.734022 -0.655831 +v -0.451134 168.434479 41.063797 1.000000 1.000000 1.000000 +vn 0.159069 -0.868527 -0.469422 +v -0.428816 168.176346 41.398598 1.000000 1.000000 1.000000 +vn -0.070483 -0.665827 -0.742769 +v 0.914456 168.361938 41.194977 1.000000 1.000000 1.000000 +vn -0.021501 -0.883043 -0.468799 +v 0.230768 168.193100 41.466179 1.000000 1.000000 1.000000 +vn -0.340735 -0.659051 -0.670486 +v 2.226892 167.863800 41.319397 1.000000 1.000000 1.000000 +vn -0.775028 -0.440884 -0.452717 +v 3.983646 165.670334 41.876198 1.000000 1.000000 1.000000 +vn -0.639282 -0.657485 -0.398787 +v 3.189258 166.792191 41.770180 1.000000 1.000000 1.000000 +vn -0.857989 -0.469741 -0.207843 +v 3.862340 165.596375 42.273598 1.000000 1.000000 1.000000 +vn -0.706008 -0.661503 -0.252914 +v 3.092144 166.684738 42.167797 1.000000 1.000000 1.000000 +vn -0.622313 -0.739581 -0.256411 +v 2.598934 167.135422 42.110798 1.000000 1.000000 1.000000 +vn -0.559312 -0.739003 -0.375559 +v 2.680574 167.256821 41.713398 1.000000 1.000000 1.000000 +vn -0.268047 -0.838888 -0.473728 +v 1.508052 167.921005 41.592999 1.000000 1.000000 1.000000 +vn -0.468739 -0.883212 0.014871 +v 2.028324 167.452179 42.506397 1.000000 1.000000 1.000000 +vn -0.314638 -0.916047 -0.248718 +v 1.462114 167.778671 41.990379 1.000000 1.000000 1.000000 +vn -0.638737 -0.769423 -0.001442 +v 2.568846 167.089386 42.565598 1.000000 1.000000 1.000000 +vn -0.813450 -0.581254 0.021070 +v 3.466620 166.144745 42.675579 1.000000 1.000000 1.000000 +vn -0.178056 -0.984000 0.006343 +v 0.832880 167.905655 42.381996 1.000000 1.000000 1.000000 +vn -0.054069 -0.963514 -0.262141 +v 0.223716 168.042404 41.863800 1.000000 1.000000 1.000000 +vn 0.072689 -0.996550 0.040056 +v -0.410968 167.971237 42.250977 1.000000 1.000000 1.000000 +vn 0.288113 -0.956525 -0.045282 +v -1.036340 167.856812 42.180977 1.000000 1.000000 1.000000 +vn 0.068894 -0.962020 -0.264144 +v -0.415772 168.027054 41.796181 1.000000 1.000000 1.000000 +vn 0.355973 -0.875308 0.327292 +v -1.708076 167.821945 42.933380 1.000000 1.000000 1.000000 +vn -0.884137 -0.458807 -0.088302 +v 3.817626 165.569855 42.728397 1.000000 1.000000 1.000000 +vn -0.985738 -0.139834 0.093629 +v 4.362088 163.656860 42.869797 1.000000 1.000000 1.000000 +vn 0.605547 0.310427 0.732767 +v -4.014558 160.412704 17.830597 1.000000 1.000000 1.000000 +vn 0.903913 0.137758 0.404925 +v -4.485456 162.388504 17.618000 1.000000 1.000000 1.000000 +vn 0.798180 0.407473 0.443706 +v -3.816904 160.552246 17.482998 1.000000 1.000000 1.000000 +vn 0.494901 0.467560 0.732435 +v -3.180078 159.364807 17.749798 1.000000 1.000000 1.000000 +vn 0.653540 0.601701 0.459174 +v -3.023508 159.555969 17.402199 1.000000 1.000000 1.000000 +vn 0.245432 0.620888 0.744487 +v -1.471938 158.308548 17.639397 1.000000 1.000000 1.000000 +vn 0.547867 0.757233 0.355584 +v -2.483834 159.110870 17.360197 1.000000 1.000000 1.000000 +vn 0.477403 0.794523 0.375259 +v -1.959804 158.792725 17.325199 1.000000 1.000000 1.000000 +vn 0.739793 0.624874 0.249479 +v -2.412404 159.230865 16.966599 1.000000 1.000000 1.000000 +vn 0.680397 0.710818 0.178320 +v -2.936564 159.662033 17.008400 1.000000 1.000000 1.000000 +vn 0.371061 0.619940 -0.691367 +v -2.134990 159.103897 16.327999 1.000000 1.000000 1.000000 +vn 0.179081 0.707507 -0.683640 +v -1.046904 158.635056 16.327000 1.000000 1.000000 1.000000 +vn 0.273635 0.871774 0.406366 +v -1.399478 158.551331 17.291599 1.000000 1.000000 1.000000 +vn 0.074945 0.983059 0.167266 +v -0.220860 158.459244 16.836998 1.000000 1.000000 1.000000 +vn -0.045307 0.702766 -0.709977 +v 0.229992 158.508087 16.326797 1.000000 1.000000 1.000000 +vn -0.009658 0.876001 0.482213 +v 0.360594 158.326691 17.203197 1.000000 1.000000 1.000000 +vn -0.180643 0.937021 0.298933 +v 0.923730 158.559708 16.783398 1.000000 1.000000 1.000000 +vn 0.354861 0.807300 -0.471530 +v 1.488958 158.841568 16.349197 1.000000 1.000000 1.000000 +vn -0.167080 0.894566 0.414531 +v 0.951106 158.420181 17.177200 1.000000 1.000000 1.000000 +vn 0.460972 0.645720 0.608729 +v 1.640508 158.393661 17.533798 1.000000 1.000000 1.000000 +vn 0.484463 0.499465 -0.718214 +v -2.999624 159.752716 16.327198 1.000000 1.000000 1.000000 +vn 0.889121 0.413172 0.196859 +v -3.707134 160.630386 17.089199 1.000000 1.000000 1.000000 +vn 0.584356 0.353622 -0.730396 +v -3.648322 160.573181 16.326797 1.000000 1.000000 1.000000 +vn 0.944198 0.328243 -0.027315 +v -4.169764 161.802460 16.746597 1.000000 1.000000 1.000000 +vn 0.580798 0.196219 -0.790045 +v -4.240228 161.782928 16.326797 1.000000 1.000000 1.000000 +vn -0.343745 -0.896793 -0.278571 +v 2.007454 157.309494 42.513798 1.000000 1.000000 1.000000 +vn -0.429093 -0.747814 -0.506610 +v 1.933230 157.527161 42.152798 1.000000 1.000000 1.000000 +vn 0.540256 -0.830175 -0.137596 +v 3.081238 157.825760 42.712601 1.000000 1.000000 1.000000 +vn 0.616889 -0.742332 -0.261518 +v 3.699938 158.300171 42.685997 1.000000 1.000000 1.000000 +vn 0.485030 -0.734864 -0.474048 +v 3.011496 157.948547 42.319397 1.000000 1.000000 1.000000 +vn 0.727911 -0.633175 -0.263125 +v 4.259810 158.865280 42.657600 1.000000 1.000000 1.000000 +vn 0.836738 -0.519554 -0.173014 +v 4.808742 159.592255 42.623177 1.000000 1.000000 1.000000 +vn 0.644875 -0.605901 -0.465855 +v 4.163404 158.964355 42.264580 1.000000 1.000000 1.000000 +vn 0.717239 -0.436292 -0.543340 +v 4.699910 159.674576 42.230198 1.000000 1.000000 1.000000 +vn 0.823824 -0.336960 -0.455820 +v 5.394480 161.118759 42.163597 1.000000 1.000000 1.000000 +vn 0.917771 -0.332993 -0.216363 +v 5.519366 161.069916 42.556801 1.000000 1.000000 1.000000 +vn 0.967001 -0.195995 -0.162774 +v 5.751048 161.950378 42.517197 1.000000 1.000000 1.000000 +vn -0.317187 0.587009 0.744858 +v 157.054657 -136.787827 18.567200 1.000000 1.000000 1.000000 +vn -0.481414 0.703433 0.522899 +v 156.258987 -136.902237 18.162399 1.000000 1.000000 1.000000 +vn -0.515539 0.361400 0.776923 +v 155.168503 -138.086884 18.371399 1.000000 1.000000 1.000000 +vn -0.193281 0.238710 0.951662 +v 157.134476 -137.015259 18.707798 1.000000 1.000000 1.000000 +vn -0.132242 0.611030 0.780484 +v 158.545547 -136.419449 18.709599 1.000000 1.000000 1.000000 +vn -0.305977 0.284397 0.908569 +v 155.875320 -137.754791 18.575798 1.000000 1.000000 1.000000 +vn -0.250699 0.831756 0.495311 +v 157.726715 -136.300858 18.298798 1.000000 1.000000 1.000000 +vn -0.371588 0.803772 0.464621 +v 156.970963 -136.549225 18.229597 1.000000 1.000000 1.000000 +vn -0.049144 0.405274 0.912873 +v 159.288437 -136.649689 18.923199 1.000000 1.000000 1.000000 +vn 0.127590 0.396013 0.909337 +v 161.375443 -137.253860 19.154999 1.000000 1.000000 1.000000 +vn 0.132906 0.610752 0.780588 +v 160.761307 -136.712479 18.933399 1.000000 1.000000 1.000000 +vn -0.207362 -0.146237 0.967272 +v 161.268585 -137.484100 19.158798 1.000000 1.000000 1.000000 +vn 0.195336 0.284605 0.938533 +v 163.069763 -138.714783 19.404198 1.000000 1.000000 1.000000 +vn 0.374105 0.511582 0.773518 +v 162.724716 -137.969666 19.179199 1.000000 1.000000 1.000000 +vn -0.257213 -0.061524 0.964394 +v 162.885651 -138.879425 19.407997 1.000000 1.000000 1.000000 +vn 0.237750 0.217743 0.946606 +v 163.826797 -140.045929 19.579597 1.000000 1.000000 1.000000 +vn 0.536633 0.395019 0.745643 +v 163.677444 -139.221283 19.349998 1.000000 1.000000 1.000000 +vn -0.275968 0.019059 0.960978 +v 163.609222 -140.150574 19.583397 1.000000 1.000000 1.000000 +vn 0.294910 0.132682 0.946268 +v 164.265823 -141.954742 19.811199 1.000000 1.000000 1.000000 +vn 0.608712 0.280300 0.742227 +v 164.171844 -140.324997 19.483797 1.000000 1.000000 1.000000 +vn -0.253231 0.103399 0.961864 +v 164.027649 -141.972885 19.814999 1.000000 1.000000 1.000000 +vn -0.214865 0.173036 0.961193 +v 163.934952 -143.464493 20.007797 1.000000 1.000000 1.000000 +vn 0.323590 0.059049 0.944353 +v 164.169266 -143.516129 20.003998 1.000000 1.000000 1.000000 +vn -0.119735 -0.210953 0.970135 +v 159.275558 -136.907822 18.926998 1.000000 1.000000 1.000000 +vn -0.141455 0.231423 0.962514 +v 163.462448 -144.897507 20.211800 1.000000 1.000000 1.000000 +vn 0.331646 -0.021250 0.943165 +v 163.673584 -145.017502 20.208199 1.000000 1.000000 1.000000 +vn -0.041575 0.196555 0.979611 +v 162.141479 -146.627716 20.528999 1.000000 1.000000 1.000000 +vn 0.665492 0.568672 0.483459 +v 163.423813 -138.396637 18.925999 1.000000 1.000000 1.000000 +vn 0.833838 0.335766 0.438149 +v 164.394577 -140.237091 19.146000 1.000000 1.000000 1.000000 +vn 0.753334 0.474495 0.455348 +v 163.879593 -139.085938 19.012199 1.000000 1.000000 1.000000 +vn 0.452230 0.719355 0.527273 +v 162.265076 -137.245499 18.758198 1.000000 1.000000 1.000000 +vn 0.592652 0.662317 0.458366 +v 162.885651 -137.781311 18.841400 1.000000 1.000000 1.000000 +vn 0.684874 0.712317 0.153467 +v 162.987366 -137.659897 18.373199 1.000000 1.000000 1.000000 +vn 0.578850 0.800706 0.154279 +v 162.351349 -137.110153 18.289799 1.000000 1.000000 1.000000 +vn 0.373895 0.760221 0.531288 +v 161.582718 -136.807358 18.676800 1.000000 1.000000 1.000000 +vn 0.108029 0.840216 0.531382 +v 160.081512 -136.253418 18.518997 1.000000 1.000000 1.000000 +vn 0.261899 0.844598 0.466972 +v 160.837280 -136.469696 18.595600 1.000000 1.000000 1.000000 +vn 0.457819 0.875338 0.155512 +v 161.650955 -136.660858 18.208397 1.000000 1.000000 1.000000 +vn 0.602199 0.778553 -0.176668 +v 162.343628 -137.122711 17.474400 1.000000 1.000000 1.000000 +vn 0.484686 0.856354 -0.178151 +v 161.644531 -136.673401 17.392998 1.000000 1.000000 1.000000 +vn 0.326389 0.932137 0.156814 +v 160.884903 -136.314804 18.127399 1.000000 1.000000 1.000000 +vn 0.188764 0.971929 0.140437 +v 160.109848 -136.091553 18.050598 1.000000 1.000000 1.000000 +vn 0.331247 0.924414 -0.189032 +v 160.881042 -136.327362 17.311798 1.000000 1.000000 1.000000 +vn 0.462077 0.754844 -0.465505 +v 161.585297 -136.801773 16.999798 1.000000 1.000000 1.000000 +vn 0.559802 0.668464 -0.489671 +v 162.267670 -137.239914 17.081200 1.000000 1.000000 1.000000 +vn 0.323054 0.809929 -0.489542 +v 160.838562 -136.464111 16.918800 1.000000 1.000000 1.000000 +vn 0.100363 0.976786 -0.189254 +v 159.320618 -136.000854 17.160999 1.000000 1.000000 1.000000 +vn 0.116400 0.867686 -0.483292 +v 159.312897 -136.144577 16.767998 1.000000 1.000000 1.000000 +vn 0.389055 0.539850 -0.746457 +v 161.478439 -137.032013 16.655399 1.000000 1.000000 1.000000 +vn 0.475262 0.394248 -0.786571 +v 162.728577 -137.965485 16.820000 1.000000 1.000000 1.000000 +vn 0.658213 0.597101 -0.458504 +v 162.889511 -137.775711 17.164600 1.000000 1.000000 1.000000 +vn 0.237448 0.191690 -0.952299 +v 161.367706 -137.270599 16.504200 1.000000 1.000000 1.000000 +vn 0.221744 0.661952 -0.715995 +v 160.037750 -136.498993 16.497597 1.000000 1.000000 1.000000 +vn 0.290146 0.078559 -0.953753 +v 163.055603 -138.727341 16.753399 1.000000 1.000000 1.000000 +vn 0.137647 0.227212 -0.964068 +v 159.991394 -136.761307 16.346397 1.000000 1.000000 1.000000 +vn 0.033264 0.419324 -0.907227 +v 158.975571 -136.475266 16.326599 1.000000 1.000000 1.000000 +vn -0.042735 0.863442 -0.502634 +v 158.526245 -136.158524 16.695000 1.000000 1.000000 1.000000 +vn -0.178437 0.574504 -0.798815 +v 157.258072 -136.546432 16.330997 1.000000 1.000000 1.000000 +vn -0.075246 0.980389 -0.182139 +v 158.514664 -136.014801 17.087997 1.000000 1.000000 1.000000 +vn -0.234657 0.950109 -0.205498 +v 157.695816 -136.154343 17.014999 1.000000 1.000000 1.000000 +vn -0.329889 0.501948 -0.799513 +v 155.910080 -137.160385 16.327000 1.000000 1.000000 1.000000 +vn -0.458315 0.867240 -0.194531 +v 156.193329 -136.769684 16.878597 1.000000 1.000000 1.000000 +vn -0.386598 0.911760 0.138695 +v 156.916885 -136.395737 17.761200 1.000000 1.000000 1.000000 +vn -0.250477 0.955255 0.157319 +v 157.693237 -136.140396 17.830597 1.000000 1.000000 1.000000 +vn -0.601068 0.774996 -0.195188 +v 155.519974 -137.231537 16.813599 1.000000 1.000000 1.000000 +vn -0.510342 0.845829 0.155318 +v 156.186890 -136.757126 17.694199 1.000000 1.000000 1.000000 +vn -0.694741 0.654694 -0.297844 +v 154.907135 -137.795258 16.750000 1.000000 1.000000 1.000000 +vn -0.579851 0.375507 -0.723026 +v 154.178421 -138.875244 16.327999 1.000000 1.000000 1.000000 +vn -0.621412 0.766807 0.160793 +v 155.513535 -137.220383 17.629200 1.000000 1.000000 1.000000 +vn -0.732775 0.680414 -0.008807 +v 154.873657 -137.757584 17.155399 1.000000 1.000000 1.000000 +vn -0.550073 0.650402 0.523829 +v 155.602371 -137.352936 18.097397 1.000000 1.000000 1.000000 +vn -0.680178 0.576348 0.452969 +v 155.003693 -137.902695 18.033798 1.000000 1.000000 1.000000 +vn -0.774621 0.606194 0.180256 +v 154.621307 -138.098038 17.534599 1.000000 1.000000 1.000000 +vn -0.847501 0.516567 0.122069 +v 154.128204 -138.783142 17.474400 1.000000 1.000000 1.000000 +vn -0.725171 0.440234 0.529454 +v 154.253082 -138.875244 17.942799 1.000000 1.000000 1.000000 +vn -0.651729 0.228272 0.723285 +v 154.074127 -139.718033 18.222397 1.000000 1.000000 1.000000 +vn -0.105435 0.981860 0.157593 +v 158.513367 -136.000854 17.903599 1.000000 1.000000 1.000000 +vn -0.124144 0.874630 0.468626 +v 158.526245 -136.164108 18.371799 1.000000 1.000000 1.000000 +vn 0.042295 0.986629 0.157400 +v 159.321915 -135.986908 17.976597 1.000000 1.000000 1.000000 +vn 0.016417 0.845559 0.533630 +v 159.312897 -136.150146 18.444798 1.000000 1.000000 1.000000 +vn -0.307700 0.076980 0.948364 +v 154.274979 -139.825470 18.362997 1.000000 1.000000 1.000000 +vn -0.830311 0.314564 0.460036 +v 153.861694 -139.603607 17.884598 1.000000 1.000000 1.000000 +vn -0.631415 -0.049922 0.773836 +v 153.511505 -142.051025 18.059399 1.000000 1.000000 1.000000 +vn -0.419962 0.026239 0.907163 +v 153.821777 -141.289169 18.252598 1.000000 1.000000 1.000000 +vn -0.830383 0.148272 0.537103 +v 153.369888 -141.195679 17.774197 1.000000 1.000000 1.000000 +vn -0.898683 0.417556 0.134222 +v 153.725235 -139.531052 17.416397 1.000000 1.000000 1.000000 +vn -0.933994 0.274283 0.228964 +v 153.421387 -140.329178 17.360197 1.000000 1.000000 1.000000 +vn -0.900415 -0.002715 0.435024 +v 153.275894 -142.037064 17.721600 1.000000 1.000000 1.000000 +vn -0.644048 -0.227972 0.730227 +v 153.766418 -144.174728 17.928799 1.000000 1.000000 1.000000 +vn -0.282951 -0.126240 0.950790 +v 153.980148 -144.100769 18.069199 1.000000 1.000000 1.000000 +vn -0.838825 -0.136940 0.526897 +v 153.355713 -143.440781 17.638199 1.000000 1.000000 1.000000 +vn -0.842225 -0.293123 0.452478 +v 153.541122 -144.252869 17.591000 1.000000 1.000000 1.000000 +vn -0.970791 0.144079 0.191850 +v 153.220535 -141.164978 17.306000 1.000000 1.000000 1.000000 +vn -0.977350 -0.035551 0.208623 +v 153.121399 -142.613342 17.218998 1.000000 1.000000 1.000000 +vn -0.982852 0.170040 -0.071330 +v 153.185776 -141.158005 16.896000 1.000000 1.000000 1.000000 +vn -0.998463 -0.029432 -0.046955 +v 153.086639 -142.614731 16.808998 1.000000 1.000000 1.000000 +vn -0.972357 -0.176957 0.152344 +v 153.206375 -143.470078 17.169800 1.000000 1.000000 1.000000 +vn -0.949068 -0.284618 0.135140 +v 153.396912 -144.303085 17.122597 1.000000 1.000000 1.000000 +vn -0.668322 -0.320565 -0.671256 +v 153.748398 -145.324478 16.327999 1.000000 1.000000 1.000000 +vn -0.894453 -0.395837 0.208007 +v 153.686600 -145.098434 17.077797 1.000000 1.000000 1.000000 +vn -0.697516 -0.128774 -0.704903 +v 153.229538 -143.495193 16.326599 1.000000 1.000000 1.000000 +vn -0.681056 0.055632 -0.730115 +v 153.171616 -141.940796 16.326599 1.000000 1.000000 1.000000 +vn -0.639015 0.277478 -0.717402 +v 153.653122 -139.828247 16.327797 1.000000 1.000000 1.000000 +vn -0.952867 0.299058 -0.051070 +v 153.389191 -140.316620 16.950199 1.000000 1.000000 1.000000 +vn 0.595139 0.340085 -0.728115 +v 163.246140 -138.557114 16.904598 1.000000 1.000000 1.000000 +vn 0.736106 0.502421 -0.453565 +v 163.428970 -138.393845 17.248997 1.000000 1.000000 1.000000 +vn 0.820994 0.404714 -0.402710 +v 163.884735 -139.083145 17.335400 1.000000 1.000000 1.000000 +vn 0.664344 0.178018 -0.725918 +v 164.036652 -139.945465 17.079800 1.000000 1.000000 1.000000 +vn 0.705428 0.686855 -0.174933 +v 162.979630 -137.669678 17.557598 1.000000 1.000000 1.000000 +vn 0.805362 0.567852 -0.170109 +v 163.530685 -138.301758 17.642197 1.000000 1.000000 1.000000 +vn 0.776517 0.611579 0.151634 +v 163.540985 -138.291992 18.457600 1.000000 1.000000 1.000000 +vn 0.859363 0.498269 0.114993 +v 164.008331 -138.999420 18.543999 1.000000 1.000000 1.000000 +vn 0.942271 0.334553 -0.014157 +v 164.569672 -140.168716 18.267597 1.000000 1.000000 1.000000 +vn 0.921669 0.317284 -0.223286 +v 164.524612 -140.186859 17.862198 1.000000 1.000000 1.000000 +vn 0.853833 0.307009 -0.420374 +v 164.252960 -139.840820 17.424400 1.000000 1.000000 1.000000 +vn 0.897960 0.402529 0.177875 +v 164.386856 -139.778030 18.632999 1.000000 1.000000 1.000000 +vn -0.119573 -0.976528 -0.179155 +v 158.548141 -148.705368 34.819000 1.000000 1.000000 1.000000 +vn -0.287385 -0.852917 -0.435824 +v 157.760193 -148.431885 34.541199 1.000000 1.000000 1.000000 +vn -0.142124 -0.853932 -0.500601 +v 158.558426 -148.561646 34.425999 1.000000 1.000000 1.000000 +vn 0.043952 -0.982345 -0.181844 +v 159.379837 -148.710953 34.702797 1.000000 1.000000 1.000000 +vn -0.202684 -0.964050 0.171835 +v 157.729294 -148.586761 35.749718 1.000000 1.000000 1.000000 +vn -0.060859 -0.985620 0.157636 +v 158.546844 -148.719330 35.634518 1.000000 1.000000 1.000000 +vn -0.366982 -0.904389 -0.217726 +v 157.028900 -148.352356 35.036400 1.000000 1.000000 1.000000 +vn -0.339847 -0.927291 0.156954 +v 157.023743 -148.366302 35.851936 1.000000 1.000000 1.000000 +vn -0.236781 -0.847739 0.474630 +v 157.075256 -148.211426 36.320137 1.000000 1.000000 1.000000 +vn -0.024236 -0.878415 0.477284 +v 158.558426 -148.556076 36.102718 1.000000 1.000000 1.000000 +vn 0.090984 -0.983329 0.157435 +v 159.381134 -148.724899 35.518398 1.000000 1.000000 1.000000 +vn 0.130174 -0.857075 0.498474 +v 159.370834 -148.561646 35.986717 1.000000 1.000000 1.000000 +vn 0.045264 -0.652007 0.756861 +v 158.576447 -148.299332 36.440521 1.000000 1.000000 1.000000 +vn 0.256487 -0.575343 0.776656 +v 160.129150 -148.190491 36.207916 1.000000 1.000000 1.000000 +vn 0.258495 -0.845710 0.466856 +v 160.178085 -148.441650 35.870117 1.000000 1.000000 1.000000 +vn 0.238570 -0.958327 0.157140 +v 160.208969 -148.602112 35.402000 1.000000 1.000000 1.000000 +vn 0.379306 -0.782314 0.494076 +v 160.954437 -148.203049 35.754719 1.000000 1.000000 1.000000 +vn 0.422906 -0.524644 0.738850 +v 161.580139 -147.622589 35.977119 1.000000 1.000000 1.000000 +vn 0.170460 -0.317848 0.932693 +v 159.341217 -148.063522 36.464920 1.000000 1.000000 1.000000 +vn 0.274193 -0.188283 0.943063 +v 161.475861 -147.409103 36.117718 1.000000 1.000000 1.000000 +vn 0.378575 -0.912215 0.156668 +v 161.005936 -148.357925 35.286598 1.000000 1.000000 1.000000 +vn 0.495337 -0.735588 0.462116 +v 161.692154 -147.850037 35.639519 1.000000 1.000000 1.000000 +vn 0.591229 -0.643017 0.486803 +v 162.371948 -147.389572 35.524799 1.000000 1.000000 1.000000 +vn 0.532256 -0.360557 0.765965 +v 162.829010 -146.638885 35.746319 1.000000 1.000000 1.000000 +vn 0.509532 -0.846455 0.154566 +v 161.762970 -147.995148 35.171196 1.000000 1.000000 1.000000 +vn 0.334191 -0.924840 -0.181626 +v 161.000778 -148.345383 34.471001 1.000000 1.000000 1.000000 +vn 0.467946 -0.865396 -0.179210 +v 161.756531 -147.982590 34.355797 1.000000 1.000000 1.000000 +vn 0.627150 -0.763714 0.153050 +v 162.460785 -147.522125 35.056599 1.000000 1.000000 1.000000 +vn 0.589527 -0.787792 -0.178443 +v 162.453064 -147.510971 34.240997 1.000000 1.000000 1.000000 +vn 0.685615 -0.569700 0.453182 +v 162.993805 -146.823059 35.408600 1.000000 1.000000 1.000000 +vn 0.728522 -0.668034 0.151615 +v 163.099380 -146.940277 34.940399 1.000000 1.000000 1.000000 +vn 0.382703 -0.796832 -0.467544 +v 161.694733 -147.855606 33.962601 1.000000 1.000000 1.000000 +vn 0.695455 -0.696661 -0.176083 +v 163.090363 -146.930511 34.124798 1.000000 1.000000 1.000000 +vn 0.495840 -0.733336 -0.465146 +v 162.374512 -147.393768 33.848000 1.000000 1.000000 1.000000 +vn 0.250017 -0.829230 -0.499869 +v 160.955719 -148.208633 34.077999 1.000000 1.000000 1.000000 +vn 0.213893 -0.631721 -0.745103 +v 161.582718 -147.628174 33.618198 1.000000 1.000000 1.000000 +vn 0.305300 -0.530389 -0.790873 +v 162.235474 -147.185852 33.503399 1.000000 1.000000 1.000000 +vn 0.583268 -0.647678 -0.490215 +v 162.997665 -146.827240 33.731796 1.000000 1.000000 1.000000 +vn 0.785754 -0.593640 -0.173732 +v 163.641403 -146.264923 34.009796 1.000000 1.000000 1.000000 +vn 0.468167 -0.488522 -0.736319 +v 163.349152 -146.019363 33.271999 1.000000 1.000000 1.000000 +vn 0.685345 -0.567764 -0.456011 +v 163.537125 -146.177032 33.616600 1.000000 1.000000 1.000000 +vn -0.008949 -0.306805 -0.951730 +v 161.468140 -147.392365 33.466999 1.000000 1.000000 1.000000 +vn 0.762223 -0.455121 -0.460305 +v 163.987732 -145.447266 33.500801 1.000000 1.000000 1.000000 +vn 0.516602 -0.355802 -0.778799 +v 163.781738 -145.318893 33.156197 1.000000 1.000000 1.000000 +vn 0.125343 -0.281377 -0.951376 +v 163.154739 -145.856094 33.120998 1.000000 1.000000 1.000000 +vn 0.860406 -0.479345 -0.173002 +v 164.103607 -145.518433 33.893799 1.000000 1.000000 1.000000 +vn 0.813788 -0.561311 0.150600 +v 163.651703 -146.274704 34.825199 1.000000 1.000000 1.000000 +vn 0.883194 -0.444390 0.149956 +v 164.115204 -145.525406 34.709396 1.000000 1.000000 1.000000 +vn 0.934045 -0.325035 0.148028 +v 164.476974 -144.707733 34.592796 1.000000 1.000000 1.000000 +vn 0.912817 -0.350897 -0.208891 +v 164.464096 -144.702164 33.777199 1.000000 1.000000 1.000000 +vn 0.742489 -0.427512 0.515697 +v 163.531967 -146.172836 35.293598 1.000000 1.000000 1.000000 +vn 0.778651 -0.352132 0.519331 +v 163.982574 -145.443085 35.177597 1.000000 1.000000 1.000000 +vn 0.645246 -0.132200 0.752450 +v 164.115204 -144.552856 35.398796 1.000000 1.000000 1.000000 +vn 0.860997 -0.235234 0.450943 +v 164.335358 -144.647736 35.060997 1.000000 1.000000 1.000000 +vn 0.965481 -0.204404 0.161448 +v 164.703583 -143.951462 34.490601 1.000000 1.000000 1.000000 +vn 0.891933 -0.049148 0.449488 +v 164.703583 -143.051483 34.843597 1.000000 1.000000 1.000000 +vn 0.677351 0.020672 0.735370 +v 164.467972 -143.023575 35.181396 1.000000 1.000000 1.000000 +vn 0.445576 -0.128525 0.885970 +v 163.168900 -145.867264 35.771736 1.000000 1.000000 1.000000 +vn 0.362004 0.051681 0.930743 +v 164.111343 -143.785416 35.437199 1.000000 1.000000 1.000000 +vn 0.035647 0.262884 0.964169 +v 161.363846 -147.180283 36.121521 1.000000 1.000000 1.000000 +vn -0.085716 0.255017 0.963130 +v 162.979630 -145.708191 35.775520 1.000000 1.000000 1.000000 +vn 0.342100 0.145442 0.928340 +v 164.276138 -142.187759 35.205799 1.000000 1.000000 1.000000 +vn 0.609679 0.211926 0.763793 +v 164.420334 -141.338013 34.948799 1.000000 1.000000 1.000000 +vn 0.875973 0.085870 0.474655 +v 164.737061 -142.172409 34.727398 1.000000 1.000000 1.000000 +vn 0.873358 0.198338 0.444868 +v 164.654648 -141.294754 34.611000 1.000000 1.000000 1.000000 +vn 0.822169 0.309907 0.477489 +v 164.461533 -140.444992 34.495598 1.000000 1.000000 1.000000 +vn 0.573152 0.368834 0.731750 +v 163.946533 -139.747330 34.717999 1.000000 1.000000 1.000000 +vn 0.985529 -0.083947 0.147258 +v 164.854218 -143.071014 34.375397 1.000000 1.000000 1.000000 +vn 0.987965 0.046343 0.147571 +v 164.888977 -142.166840 34.259201 1.000000 1.000000 1.000000 +vn 0.973353 0.175419 0.147688 +v 164.804001 -141.265442 34.142799 1.000000 1.000000 1.000000 +vn 0.942063 0.300956 0.148131 +v 164.605728 -140.394760 34.027397 1.000000 1.000000 1.000000 +vn 0.787972 0.420023 0.450201 +v 164.160248 -139.634308 34.380398 1.000000 1.000000 1.000000 +vn 0.893269 0.423859 0.149715 +v 164.296738 -139.561752 33.911999 1.000000 1.000000 1.000000 +vn 0.976880 -0.133941 -0.166631 +v 164.841339 -143.069626 33.559799 1.000000 1.000000 1.000000 +vn 0.865854 -0.280400 -0.414334 +v 164.563248 -143.912399 33.281998 1.000000 1.000000 1.000000 +vn 0.866140 -0.151771 -0.476200 +v 164.710007 -143.052872 33.166798 1.000000 1.000000 1.000000 +vn 0.985429 0.005990 -0.169985 +v 164.876099 -142.168228 33.443596 1.000000 1.000000 1.000000 +vn 0.976210 0.134695 -0.169913 +v 164.791122 -141.268250 33.327198 1.000000 1.000000 1.000000 +vn 0.894719 -0.032301 -0.445460 +v 164.742203 -142.172409 33.050598 1.000000 1.000000 1.000000 +vn 0.688233 -0.090609 -0.719809 +v 164.505310 -142.179398 32.706001 1.000000 1.000000 1.000000 +vn 0.632436 -0.270037 -0.726020 +v 164.332779 -143.848221 32.937401 1.000000 1.000000 1.000000 +vn 0.891693 0.083361 -0.444898 +v 164.659805 -141.293365 32.934196 1.000000 1.000000 1.000000 +vn 0.950405 0.260451 -0.169988 +v 164.592850 -140.398956 33.211800 1.000000 1.000000 1.000000 +vn 0.858719 0.190800 -0.475601 +v 164.466675 -140.443604 32.818798 1.000000 1.000000 1.000000 +vn 0.907120 0.384543 -0.171055 +v 164.285141 -139.568726 33.096596 1.000000 1.000000 1.000000 +vn 0.629485 0.016357 -0.776841 +v 164.426758 -141.336609 32.589600 1.000000 1.000000 1.000000 +vn 0.668421 0.170103 -0.724071 +v 163.951691 -139.744537 32.359001 1.000000 1.000000 1.000000 +vn 0.837509 0.312287 -0.448392 +v 164.165405 -139.631516 32.703400 1.000000 1.000000 1.000000 +vn 0.281545 -0.134222 -0.950114 +v 164.259399 -142.187759 32.555000 1.000000 1.000000 1.000000 +vn 0.325614 -0.023843 -0.945202 +v 163.730240 -139.861740 32.207798 1.000000 1.000000 1.000000 +vn 0.571945 0.255491 -0.779489 +v 163.566727 -139.021759 32.244198 1.000000 1.000000 1.000000 +vn 0.239516 -0.206307 -0.948720 +v 164.094604 -143.781235 32.786400 1.000000 1.000000 1.000000 +vn 0.138080 0.230714 0.963175 +v 159.325775 -147.805389 36.468719 1.000000 1.000000 1.000000 +vn 0.214370 0.182672 0.959519 +v 157.913406 -147.686783 36.700138 1.000000 1.000000 1.000000 +vn 0.066977 -0.340129 0.937991 +v 157.861908 -147.939331 36.696320 1.000000 1.000000 1.000000 +vn 0.267049 0.088277 0.959631 +v 156.050415 -146.778412 37.034737 1.000000 1.000000 1.000000 +vn 0.517020 0.463340 0.719726 +v 156.194611 -146.562134 36.880138 1.000000 1.000000 1.000000 +vn 0.282321 -0.020398 0.959103 +v 154.638046 -145.078903 37.380737 1.000000 1.000000 1.000000 +vn -0.089331 -0.343215 0.934999 +v 155.910080 -146.989120 37.030937 1.000000 1.000000 1.000000 +vn 0.668725 0.223221 0.709210 +v 154.851776 -144.946335 37.226139 1.000000 1.000000 1.000000 +vn 0.254643 -0.118371 0.959763 +v 153.991730 -142.892410 37.727936 1.000000 1.000000 1.000000 +vn 0.701196 -0.036027 0.712058 +v 154.237640 -142.867294 37.573338 1.000000 1.000000 1.000000 +vn 0.206929 -0.193386 0.959053 +v 154.053528 -141.358932 37.959339 1.000000 1.000000 1.000000 +vn -0.329737 -0.166742 0.929231 +v 153.754837 -142.918930 37.724136 1.000000 1.000000 1.000000 +vn -0.192884 -0.256577 0.947082 +v 154.430756 -145.207275 37.376938 1.000000 1.000000 1.000000 +vn 0.644020 -0.257673 0.720308 +v 154.295578 -141.407776 37.804741 1.000000 1.000000 1.000000 +vn 0.103928 -0.248664 0.962998 +v 154.826019 -139.309189 38.293938 1.000000 1.000000 1.000000 +vn -0.358335 -0.074019 0.930654 +v 153.817917 -141.311493 37.955536 1.000000 1.000000 1.000000 +vn 0.518308 -0.460255 0.720780 +v 155.030731 -139.458496 38.139336 1.000000 1.000000 1.000000 +vn 0.857264 -0.271929 0.437210 +v 154.527328 -141.453827 37.456940 1.000000 1.000000 1.000000 +vn 0.910272 -0.110283 0.399053 +v 154.453949 -142.143112 37.341938 1.000000 1.000000 1.000000 +vn -0.016579 -0.264248 0.964312 +v 156.345245 -137.721313 38.639938 1.000000 1.000000 1.000000 +vn -0.453642 0.099972 0.885559 +v 154.627747 -139.165466 38.290138 1.000000 1.000000 1.000000 +vn -0.121041 -0.239015 0.963442 +v 158.339554 -136.946899 38.987137 1.000000 1.000000 1.000000 +vn -0.286604 0.168966 0.943032 +v 156.220367 -137.502228 38.636139 1.000000 1.000000 1.000000 +vn 0.272699 -0.627442 0.729350 +v 156.475296 -137.948746 38.485336 1.000000 1.000000 1.000000 +vn -0.015039 -0.674088 0.738498 +v 158.371750 -137.212006 38.832539 1.000000 1.000000 1.000000 +vn -0.200484 -0.195240 0.960046 +v 159.755783 -136.960846 39.218536 1.000000 1.000000 1.000000 +vn -0.263434 -0.619074 0.739831 +v 159.719742 -137.225952 39.063938 1.000000 1.000000 1.000000 +vn -0.259328 -0.103620 0.960214 +v 161.672836 -137.728287 39.553139 1.000000 1.000000 1.000000 +vn -0.278059 -0.843727 0.459139 +v 159.684967 -137.478516 38.716141 1.000000 1.000000 1.000000 +vn -0.093858 -0.899298 0.427147 +v 159.046387 -137.422699 38.601139 1.000000 1.000000 1.000000 +vn -0.482515 -0.495558 0.722219 +v 161.541519 -137.955719 39.398537 1.000000 1.000000 1.000000 +vn -0.282918 0.002452 0.959141 +v 163.188217 -139.320358 39.899139 1.000000 1.000000 1.000000 +vn -0.411440 -0.853495 0.319788 +v 160.848862 -137.845490 38.934937 1.000000 1.000000 1.000000 +vn -0.651975 -0.265088 0.710392 +v 162.983505 -139.469666 39.744537 1.000000 1.000000 1.000000 +vn -0.686882 -0.646883 0.331265 +v 161.934204 -138.580826 39.166138 1.000000 1.000000 1.000000 +vn -0.570666 -0.689404 0.446164 +v 161.416641 -138.171997 39.050938 1.000000 1.000000 1.000000 +vn -0.024455 -0.999172 0.032509 +v 159.045090 -137.613861 37.776741 1.000000 1.000000 1.000000 +vn -0.254685 -0.967007 0.005811 +v 160.190948 -137.792465 37.994141 1.000000 1.000000 1.000000 +vn -0.436874 -0.899478 -0.008977 +v 160.776764 -138.019897 38.110741 1.000000 1.000000 1.000000 +vn -0.752885 -0.553698 0.355785 +v 162.397705 -139.066406 39.282139 1.000000 1.000000 1.000000 +vn -0.655923 -0.753134 0.050545 +v 161.819611 -138.727341 38.341736 1.000000 1.000000 1.000000 +vn -0.890901 -0.294726 0.345590 +v 163.105804 -140.214767 39.512337 1.000000 1.000000 1.000000 +vn -0.807534 -0.426297 0.407628 +v 162.787811 -139.611984 39.396938 1.000000 1.000000 1.000000 +vn -0.856910 -0.513245 0.047803 +v 162.641022 -139.718033 38.572540 1.000000 1.000000 1.000000 +vn -0.636560 -0.639437 -0.431174 +v 162.406708 -139.056625 37.605736 1.000000 1.000000 1.000000 +vn -0.915527 -0.241925 0.321377 +v 163.342712 -140.859406 39.627541 1.000000 1.000000 1.000000 +vn -0.953902 -0.299986 0.008927 +v 163.174042 -140.918015 38.803337 1.000000 1.000000 1.000000 +vn -0.446626 -0.798975 -0.402697 +v 161.424362 -138.159439 37.374336 1.000000 1.000000 1.000000 +vn -0.418352 -0.606652 -0.675984 +v 162.095139 -138.371521 37.154739 1.000000 1.000000 1.000000 +vn -0.122276 -0.706436 -0.697135 +v 160.306824 -137.345963 36.807137 1.000000 1.000000 1.000000 +vn -0.293302 -0.763980 -0.574725 +v 160.854004 -137.831528 37.258339 1.000000 1.000000 1.000000 +vn -0.116927 -0.962184 -0.246028 +v 159.665665 -137.612473 37.437138 1.000000 1.000000 1.000000 +vn -0.127970 -0.260267 -0.957019 +v 163.179199 -139.327332 37.249741 1.000000 1.000000 1.000000 +vn 0.032497 -0.247751 -0.968278 +v 161.666412 -137.739441 36.903740 1.000000 1.000000 1.000000 +vn -0.504541 -0.446404 -0.739028 +v 162.996368 -139.459885 37.385536 1.000000 1.000000 1.000000 +vn -0.211953 -0.184545 -0.959697 +v 163.959412 -141.455215 37.596916 1.000000 1.000000 1.000000 +vn -0.687270 -0.341622 -0.641057 +v 163.582184 -140.777084 37.616341 1.000000 1.000000 1.000000 +vn -0.722723 -0.505280 -0.471555 +v 162.799393 -139.603607 37.720337 1.000000 1.000000 1.000000 +vn -0.833529 -0.350673 -0.426917 +v 163.355576 -140.855225 37.950939 1.000000 1.000000 1.000000 +vn -0.822950 -0.520251 -0.228239 +v 162.683517 -139.687332 38.117737 1.000000 1.000000 1.000000 +vn -0.742578 -0.607668 -0.281632 +v 162.303711 -139.157104 38.003136 1.000000 1.000000 1.000000 +vn 0.266666 -0.174684 -0.947826 +v 164.225922 -143.016602 37.823120 1.000000 1.000000 1.000000 +vn -0.262605 -0.117814 -0.957684 +v 163.994171 -142.987289 37.828117 1.000000 1.000000 1.000000 +vn 0.297899 -0.097729 -0.949582 +v 164.188583 -141.413361 37.591721 1.000000 1.000000 1.000000 +vn 0.165598 -0.251413 -0.953608 +v 163.555145 -145.210052 38.157719 1.000000 1.000000 1.000000 +vn -0.306865 -0.006918 -0.951728 +v 163.353012 -145.084473 38.162918 1.000000 1.000000 1.000000 +vn 0.089656 -0.296047 -0.950956 +v 162.642319 -146.471436 38.389118 1.000000 1.000000 1.000000 +vn 0.327072 0.017926 -0.944829 +v 163.372314 -139.186401 37.244537 1.000000 1.000000 1.000000 +vn 0.292435 0.142732 -0.945574 +v 161.790009 -137.524551 36.898537 1.000000 1.000000 1.000000 +vn 0.118634 -0.248358 -0.961376 +v 159.754501 -136.974792 36.568939 1.000000 1.000000 1.000000 +vn 0.200432 0.246820 -0.948107 +v 159.789261 -136.723633 36.563938 1.000000 1.000000 1.000000 +vn 0.120731 -0.662857 -0.738949 +v 159.048965 -137.149216 36.589737 1.000000 1.000000 1.000000 +vn 0.193110 -0.203214 -0.959902 +v 158.340851 -136.960846 36.337738 1.000000 1.000000 1.000000 +vn -0.047710 -0.875378 -0.481079 +v 159.686264 -137.464554 37.039539 1.000000 1.000000 1.000000 +vn 0.353225 -0.662641 -0.660408 +v 157.702255 -137.345963 36.357140 1.000000 1.000000 1.000000 +vn 0.190300 -0.863754 -0.466600 +v 158.401352 -137.450607 36.808338 1.000000 1.000000 1.000000 +vn 0.273907 -0.127763 -0.953232 +v 156.351685 -137.732468 35.990540 1.000000 1.000000 1.000000 +vn 0.466835 -0.482187 -0.741323 +v 156.467560 -137.933395 36.126339 1.000000 1.000000 1.000000 +vn 0.367689 -0.816020 -0.446001 +v 157.766632 -137.594330 36.691738 1.000000 1.000000 1.000000 +vn 0.531742 -0.696927 -0.481190 +v 156.593735 -138.153854 36.461136 1.000000 1.000000 1.000000 +vn 0.139532 -0.962153 -0.234078 +v 158.419373 -137.599899 37.205738 1.000000 1.000000 1.000000 +vn 0.150860 -0.988543 0.004855 +v 158.425827 -137.655716 37.660538 1.000000 1.000000 1.000000 +vn 0.313003 -0.949699 0.010051 +v 157.818130 -137.792465 37.544136 1.000000 1.000000 1.000000 +vn 0.551419 -0.800603 -0.234463 +v 156.667114 -138.280823 36.858536 1.000000 1.000000 1.000000 +vn 0.243049 -0.906870 0.344259 +v 157.770493 -137.608276 38.368340 1.000000 1.000000 1.000000 +vn 0.544620 -0.837236 0.049250 +v 156.694153 -138.328278 37.313339 1.000000 1.000000 1.000000 +vn 0.032652 -0.890034 0.454724 +v 158.402634 -137.465958 38.484940 1.000000 1.000000 1.000000 +vn 0.304386 -0.878638 0.367892 +v 157.166656 -137.842697 38.253136 1.000000 1.000000 1.000000 +vn 0.449431 -0.787188 0.422313 +v 156.600174 -138.165009 38.137741 1.000000 1.000000 1.000000 +vn 0.583621 -0.726325 0.363096 +v 156.085175 -138.569656 38.022938 1.000000 1.000000 1.000000 +vn 0.676576 -0.657115 0.332332 +v 155.620407 -139.055237 37.906937 1.000000 1.000000 1.000000 +vn 0.781785 -0.621492 0.050598 +v 155.751724 -139.183609 37.082539 1.000000 1.000000 1.000000 +vn 0.716132 -0.541085 0.440887 +v 155.226425 -139.602219 37.791740 1.000000 1.000000 1.000000 +vn 0.911526 -0.411162 -0.008186 +v 155.064209 -140.290115 36.851540 1.000000 1.000000 1.000000 +vn 0.867937 -0.391682 0.305401 +v 154.905853 -140.206390 37.675739 1.000000 1.000000 1.000000 +vn 0.968300 -0.249709 0.006418 +v 154.833755 -140.916611 36.734940 1.000000 1.000000 1.000000 +vn 0.817046 -0.426118 -0.388407 +v 155.214844 -139.593842 36.115139 1.000000 1.000000 1.000000 +vn 0.666714 -0.607509 -0.431770 +v 156.076157 -138.558502 36.346539 1.000000 1.000000 1.000000 +vn 0.964381 -0.129934 -0.230404 +v 154.650925 -141.478928 36.177940 1.000000 1.000000 1.000000 +vn 0.998183 -0.050898 0.032246 +v 154.630325 -142.151489 36.517540 1.000000 1.000000 1.000000 +vn 0.995251 0.097177 0.005636 +v 154.648346 -142.822647 36.401337 1.000000 1.000000 1.000000 +vn 0.971767 0.089757 -0.218203 +v 154.596848 -142.828217 35.946541 1.000000 1.000000 1.000000 +vn 0.971145 0.238318 0.009062 +v 154.752640 -143.486816 36.284939 1.000000 1.000000 1.000000 +vn 0.889924 -0.070411 -0.450641 +v 154.514450 -141.451035 35.780338 1.000000 1.000000 1.000000 +vn 0.888200 0.137693 -0.438339 +v 154.457809 -142.843582 35.549198 1.000000 1.000000 1.000000 +vn 0.854759 0.296623 -0.425914 +v 154.568527 -143.535660 35.432598 1.000000 1.000000 1.000000 +vn 0.695971 0.085188 -0.712999 +v 154.202881 -142.130554 35.330597 1.000000 1.000000 1.000000 +vn 0.781398 -0.284326 -0.555495 +v 154.892975 -140.199417 35.999138 1.000000 1.000000 1.000000 +vn 0.731763 -0.133559 -0.668344 +v 154.425613 -140.774292 35.547997 1.000000 1.000000 1.000000 +vn 0.710248 0.296842 -0.638305 +v 154.336777 -143.597061 35.098000 1.000000 1.000000 1.000000 +vn 0.270534 0.101067 -0.957391 +v 154.065125 -141.360336 35.309799 1.000000 1.000000 1.000000 +vn 0.225056 0.170571 -0.959300 +v 154.003311 -142.891006 35.078598 1.000000 1.000000 1.000000 +vn 0.267826 0.021212 -0.963234 +v 154.836319 -139.316177 35.644539 1.000000 1.000000 1.000000 +vn 0.630020 -0.400301 -0.665458 +v 155.433716 -138.873856 35.895538 1.000000 1.000000 1.000000 +vn 0.638838 -0.714594 -0.285029 +v 156.164993 -138.674316 36.743938 1.000000 1.000000 1.000000 +vn 0.904634 -0.001094 0.426187 +v 154.471970 -142.842178 37.225739 1.000000 1.000000 1.000000 +vn 0.908411 0.236904 0.344479 +v 154.777100 -144.192856 36.993938 1.000000 1.000000 1.000000 +vn 0.929408 0.183810 0.320025 +v 154.581406 -143.532867 37.109138 1.000000 1.000000 1.000000 +vn 0.888829 0.455720 0.047987 +v 155.208405 -144.723083 36.054138 1.000000 1.000000 1.000000 +vn 0.834298 0.373386 0.405624 +v 155.055191 -144.817978 36.878540 1.000000 1.000000 1.000000 +vn -0.116756 -0.626928 0.770279 +v 157.155075 -147.970032 36.657936 1.000000 1.000000 1.000000 +vn -0.380671 -0.798890 0.465687 +v 156.328506 -147.857010 36.436737 1.000000 1.000000 1.000000 +vn -0.208643 -0.594644 0.776444 +v 156.439240 -147.629578 36.774536 1.000000 1.000000 1.000000 +vn -0.382880 -0.504278 0.774020 +v 155.187805 -146.647247 37.005539 1.000000 1.000000 1.000000 +vn -0.483547 -0.723563 0.492583 +v 155.639709 -147.392365 36.552738 1.000000 1.000000 1.000000 +vn -0.592934 -0.790156 0.155186 +v 155.550873 -147.526306 36.084339 1.000000 1.000000 1.000000 +vn -0.470213 -0.868672 0.155914 +v 156.257690 -148.002121 35.968536 1.000000 1.000000 1.000000 +vn -0.507602 -0.842987 -0.178083 +v 156.264145 -147.989563 35.153000 1.000000 1.000000 1.000000 +vn -0.699554 -0.697832 0.153802 +v 154.917435 -146.950043 36.199539 1.000000 1.000000 1.000000 +vn -0.625320 -0.760032 -0.176995 +v 155.558594 -147.515152 35.268997 1.000000 1.000000 1.000000 +vn -0.597982 -0.657514 0.458360 +v 155.022995 -146.831436 36.667740 1.000000 1.000000 1.000000 +vn -0.789787 -0.594160 0.152347 +v 154.359955 -146.278885 36.315739 1.000000 1.000000 1.000000 +vn -0.811879 -0.557670 -0.172793 +v 154.370255 -146.270523 35.500198 1.000000 1.000000 1.000000 +vn -0.727213 -0.663840 -0.174576 +v 154.926453 -146.940277 35.383999 1.000000 1.000000 1.000000 +vn -0.595708 -0.658345 -0.460123 +v 155.637131 -147.397949 34.875801 1.000000 1.000000 1.000000 +vn -0.675541 -0.555250 -0.485122 +v 155.019150 -146.837021 34.990997 1.000000 1.000000 1.000000 +vn -0.510592 -0.449231 -0.733136 +v 155.776184 -147.190033 34.531197 1.000000 1.000000 1.000000 +vn -0.478728 -0.740629 -0.471474 +v 156.325928 -147.862595 34.759998 1.000000 1.000000 1.000000 +vn -0.757533 -0.470629 -0.452384 +v 154.474548 -146.181213 35.107201 1.000000 1.000000 1.000000 +vn -0.553627 -0.292017 -0.779887 +v 154.661224 -146.023544 34.762596 1.000000 1.000000 1.000000 +vn -0.815023 -0.365203 -0.449850 +v 154.026505 -145.459824 35.221798 1.000000 1.000000 1.000000 +vn -0.656208 -0.212586 -0.724016 +v 154.232498 -145.331451 34.877396 1.000000 1.000000 1.000000 +vn -0.880315 -0.442354 -0.171374 +v 153.910614 -145.530991 35.614937 1.000000 1.000000 1.000000 +vn -0.374604 -0.496455 -0.783074 +v 156.436661 -147.635147 34.415398 1.000000 1.000000 1.000000 +vn -0.328199 0.002680 -0.944605 +v 154.444931 -145.198898 34.726196 1.000000 1.000000 1.000000 +vn -0.301455 -0.123145 -0.945495 +v 155.920380 -146.973755 34.380196 1.000000 1.000000 1.000000 +vn -0.276088 -0.611444 -0.741560 +v 157.811691 -148.180725 34.196598 1.000000 1.000000 1.000000 +vn -0.218399 -0.233630 -0.947480 +v 157.865753 -147.921188 34.045601 1.000000 1.000000 1.000000 +vn -0.076622 -0.664719 -0.743154 +v 159.355377 -148.310486 33.965199 1.000000 1.000000 1.000000 +vn -0.004376 -0.881562 -0.472048 +v 159.370834 -148.567230 34.309799 1.000000 1.000000 1.000000 +vn 0.128794 -0.872267 -0.471765 +v 160.179367 -148.447235 34.193398 1.000000 1.000000 1.000000 +vn 0.043157 -0.605083 -0.794992 +v 160.130447 -148.196075 33.848801 1.000000 1.000000 1.000000 +vn -0.134502 -0.271815 -0.952904 +v 159.339935 -148.045380 33.814198 1.000000 1.000000 1.000000 +vn 0.191854 -0.964488 -0.181536 +v 160.206406 -148.588165 34.586399 1.000000 1.000000 1.000000 +vn -0.863599 -0.481274 0.150238 +v 153.900330 -145.537964 36.430336 1.000000 1.000000 1.000000 +vn -0.920481 -0.361284 0.148960 +v 153.539825 -144.731461 36.545738 1.000000 1.000000 1.000000 +vn -0.931577 -0.321026 -0.170610 +v 153.551422 -144.725876 35.730141 1.000000 1.000000 1.000000 +vn -0.758776 -0.470927 0.449986 +v 154.031647 -145.457031 36.898739 1.000000 1.000000 1.000000 +vn -0.800443 -0.361989 0.477759 +v 153.680161 -144.670059 37.013939 1.000000 1.000000 1.000000 +vn -0.670112 -0.562155 0.484698 +v 154.479691 -146.177032 36.783939 1.000000 1.000000 1.000000 +vn -0.546151 -0.405281 0.733121 +v 154.236359 -145.328659 37.236336 1.000000 1.000000 1.000000 +vn -0.594744 -0.250251 0.763973 +v 153.663422 -143.775650 37.467140 1.000000 1.000000 1.000000 +vn -0.858871 -0.253680 0.444957 +v 153.434265 -143.837051 37.129341 1.000000 1.000000 1.000000 +vn -0.768635 -0.549280 0.327859 +v 162.380966 -139.048264 34.129196 1.000000 1.000000 1.000000 +vn -0.548563 -0.428558 0.717925 +v 162.070679 -138.371521 34.361801 1.000000 1.000000 1.000000 +vn -0.661496 -0.605516 0.442464 +v 161.920044 -138.566879 34.014198 1.000000 1.000000 1.000000 +vn -0.820149 -0.450360 0.352889 +v 162.778793 -139.598022 34.245399 1.000000 1.000000 1.000000 +vn -0.682085 -0.179753 0.708836 +v 163.309235 -140.083603 34.707798 1.000000 1.000000 1.000000 +vn -0.560778 -0.827921 -0.008654 +v 161.304626 -138.322693 33.073997 1.000000 1.000000 1.000000 +vn -0.752301 -0.656902 0.050221 +v 162.249649 -139.176636 33.305000 1.000000 1.000000 1.000000 +vn -0.529080 -0.787406 0.316332 +v 161.398605 -138.159439 33.898201 1.000000 1.000000 1.000000 +vn -0.392568 -0.919700 0.006481 +v 160.753586 -138.010132 32.957397 1.000000 1.000000 1.000000 +vn -0.718934 -0.547678 -0.427998 +v 162.790375 -139.589661 32.568798 1.000000 1.000000 1.000000 +vn -0.555747 -0.729172 -0.399315 +v 161.929062 -138.555710 32.337601 1.000000 1.000000 1.000000 +vn -0.256702 -0.934571 -0.246335 +v 160.255325 -137.754791 32.400398 1.000000 1.000000 1.000000 +vn -0.171867 -0.984546 0.033615 +v 159.641205 -137.664093 32.739998 1.000000 1.000000 1.000000 +vn -0.397809 -0.796030 0.456163 +v 160.291382 -137.623642 33.679398 1.000000 1.000000 1.000000 +vn -0.004161 -0.972058 -0.234704 +v 159.023209 -137.558044 32.168999 1.000000 1.000000 1.000000 +vn 0.003334 -0.999979 0.005481 +v 159.023209 -137.613861 32.623798 1.000000 1.000000 1.000000 +vn -0.400285 -0.715229 -0.572904 +v 161.405045 -138.146881 32.221596 1.000000 1.000000 1.000000 +vn -0.175688 -0.859261 -0.480420 +v 160.295242 -137.609680 32.002800 1.000000 1.000000 1.000000 +vn 0.170856 -0.985247 0.009807 +v 158.402634 -137.659897 32.507401 1.000000 1.000000 1.000000 +vn 0.244765 -0.859344 -0.449019 +v 158.376892 -137.454803 31.654999 1.000000 1.000000 1.000000 +vn 0.060924 -0.881779 -0.467712 +v 159.023209 -137.407349 31.771599 1.000000 1.000000 1.000000 +vn -0.224536 -0.876948 0.424908 +v 159.666946 -137.474335 33.564400 1.000000 1.000000 1.000000 +vn -0.350974 -0.578097 0.736628 +v 160.358337 -137.379440 34.027199 1.000000 1.000000 1.000000 +vn -0.114172 -0.665665 0.737465 +v 159.024490 -137.167358 33.795799 1.000000 1.000000 1.000000 +vn -0.098478 -0.885800 0.453498 +v 159.023209 -137.422699 33.448196 1.000000 1.000000 1.000000 +vn -0.272549 -0.070938 0.959523 +v 162.229034 -138.166412 34.516399 1.000000 1.000000 1.000000 +vn -0.227132 -0.168695 0.959142 +v 160.427856 -137.122711 34.181599 1.000000 1.000000 1.000000 +vn -0.279700 0.038645 0.959309 +v 163.531967 -139.966385 34.862396 1.000000 1.000000 1.000000 +vn -0.154472 -0.220517 0.963074 +v 159.025787 -136.899445 33.950401 1.000000 1.000000 1.000000 +vn 0.178481 -0.658288 0.731301 +v 157.053360 -137.616653 33.448601 1.000000 1.000000 1.000000 +vn -0.259364 0.204507 0.943879 +v 156.856384 -137.136658 33.599396 1.000000 1.000000 1.000000 +vn -0.055111 -0.259394 0.964198 +v 156.952942 -137.372467 33.603199 1.000000 1.000000 1.000000 +vn 0.448941 -0.524729 0.723265 +v 155.432419 -138.898956 33.102600 1.000000 1.000000 1.000000 +vn 0.066112 -0.259501 0.963477 +v 155.248322 -138.721756 33.257198 1.000000 1.000000 1.000000 +vn -0.355313 0.113603 0.927819 +v 155.070648 -138.548737 33.253399 1.000000 1.000000 1.000000 +vn -0.364827 -0.028740 0.930632 +v 153.998169 -140.555222 32.918800 1.000000 1.000000 1.000000 +vn 0.176196 -0.218203 0.959866 +v 154.224777 -140.637558 32.922398 1.000000 1.000000 1.000000 +vn 0.601345 -0.338003 0.723974 +v 154.459091 -140.721268 32.767998 1.000000 1.000000 1.000000 +vn -0.350864 -0.123515 0.928245 +v 153.732941 -142.138931 32.687401 1.000000 1.000000 1.000000 +vn 0.235895 -0.149572 0.960199 +v 153.971146 -142.148697 32.691200 1.000000 1.000000 1.000000 +vn 0.690671 -0.124059 0.712448 +v 154.217041 -142.158463 32.536598 1.000000 1.000000 1.000000 +vn 0.814018 -0.379180 0.439996 +v 154.683105 -140.802200 32.420197 1.000000 1.000000 1.000000 +vn 0.887900 -0.225292 0.401094 +v 154.523453 -141.473358 32.305000 1.000000 1.000000 1.000000 +vn 0.809875 -0.500568 0.305833 +v 155.213547 -139.621750 32.639000 1.000000 1.000000 1.000000 +vn 0.999582 -0.028403 0.005417 +v 154.630325 -142.175201 31.364599 1.000000 1.000000 1.000000 +vn 0.983773 -0.176536 0.032038 +v 154.697266 -141.508240 31.480799 1.000000 1.000000 1.000000 +vn 0.634805 -0.631909 0.444651 +v 155.607529 -139.069199 32.754997 1.000000 1.000000 1.000000 +vn 0.928359 -0.371628 0.006517 +v 155.053909 -140.313828 31.698198 1.000000 1.000000 1.000000 +vn 0.578869 -0.743300 0.335285 +v 156.067154 -138.586411 32.869999 1.000000 1.000000 1.000000 +vn 0.849295 -0.527857 -0.008013 +v 155.361618 -139.727798 31.814798 1.000000 1.000000 1.000000 +vn 0.752697 -0.528970 -0.391968 +v 155.597214 -139.059433 31.078398 1.000000 1.000000 1.000000 +vn 0.940071 -0.250892 -0.230913 +v 154.801559 -140.845459 31.141199 1.000000 1.000000 1.000000 +vn 0.576155 -0.691328 -0.436017 +v 156.580856 -138.162231 31.309599 1.000000 1.000000 1.000000 +vn 0.690124 -0.721863 0.051415 +v 156.180450 -138.732925 32.045799 1.000000 1.000000 1.000000 +vn 0.475090 -0.800165 0.366094 +v 156.587296 -138.174789 32.986198 1.000000 1.000000 1.000000 +vn 0.532224 -0.796117 -0.287985 +v 156.654251 -138.290604 31.707199 1.000000 1.000000 1.000000 +vn 0.420363 -0.906030 0.049049 +v 157.222015 -138.025482 32.276596 1.000000 1.000000 1.000000 +vn 0.332045 -0.841918 0.425347 +v 157.149918 -137.849670 33.100998 1.000000 1.000000 1.000000 +vn 0.172931 -0.913046 0.369381 +v 157.751175 -137.612473 33.216400 1.000000 1.000000 1.000000 +vn 0.433373 -0.869312 -0.237664 +v 157.200134 -137.973862 31.821798 1.000000 1.000000 1.000000 +vn 0.106880 -0.932325 0.345467 +v 158.378189 -137.470154 33.331596 1.000000 1.000000 1.000000 +vn 0.428432 -0.763122 -0.483829 +v 157.143494 -137.837128 31.424398 1.000000 1.000000 1.000000 +vn 0.253711 -0.704119 -0.663210 +v 158.343414 -137.199448 31.320198 1.000000 1.000000 1.000000 +vn 0.393985 -0.539060 -0.744439 +v 157.046936 -137.601303 31.089598 1.000000 1.000000 1.000000 +vn 0.022208 -0.671961 -0.740253 +v 159.703003 -137.205032 31.552998 1.000000 1.000000 1.000000 +vn 0.161330 -0.225102 -0.960886 +v 159.025787 -136.912018 31.300999 1.000000 1.000000 1.000000 +vn 0.252461 -0.160225 -0.954249 +v 156.958099 -137.383636 30.953798 1.000000 1.000000 1.000000 +vn 0.568693 -0.479266 -0.668500 +v 155.904938 -138.378494 30.858797 1.000000 1.000000 1.000000 +vn 0.706638 -0.224643 -0.670969 +v 154.667664 -140.114304 30.511198 1.000000 1.000000 1.000000 +vn 0.268527 -0.012731 -0.963188 +v 155.257324 -138.730133 30.607798 1.000000 1.000000 1.000000 +vn 0.737285 -0.380591 -0.558177 +v 155.203247 -139.613373 30.962399 1.000000 1.000000 1.000000 +vn 0.282475 0.066083 -0.956996 +v 154.236359 -140.641739 30.272999 1.000000 1.000000 1.000000 +vn 0.701174 -0.002957 -0.712984 +v 154.276276 -141.424530 30.293798 1.000000 1.000000 1.000000 +vn 0.873467 -0.182531 -0.451374 +v 154.670242 -140.798004 30.743599 1.000000 1.000000 1.000000 +vn 0.975499 -0.033136 -0.217493 +v 154.578827 -142.173813 30.909798 1.000000 1.000000 1.000000 +vn 0.899016 0.024198 -0.437247 +v 154.439774 -142.168228 30.512398 1.000000 1.000000 1.000000 +vn 0.247383 0.140666 -0.958653 +v 153.982727 -142.148697 30.041798 1.000000 1.000000 1.000000 +vn 0.743554 0.203471 -0.636967 +v 154.224777 -142.896606 30.060999 1.000000 1.000000 1.000000 +vn 0.886752 0.185057 -0.423586 +v 154.461670 -142.870087 30.395798 1.000000 1.000000 1.000000 +vn 0.993453 0.113879 0.009132 +v 154.650925 -142.849152 31.248198 1.000000 1.000000 1.000000 +vn 0.908875 0.351083 -0.225140 +v 154.899399 -144.162170 30.562599 1.000000 1.000000 1.000000 +vn 0.810054 0.355221 -0.466509 +v 154.770660 -144.217987 30.165199 1.000000 1.000000 1.000000 +vn 0.940186 0.337395 0.047066 +v 154.947037 -144.141235 31.017399 1.000000 1.000000 1.000000 +vn 0.896396 -0.115458 0.427952 +v 154.452652 -142.168228 32.188999 1.000000 1.000000 1.000000 +vn 0.945034 0.064630 0.320522 +v 154.474548 -142.868683 32.072399 1.000000 1.000000 1.000000 +vn 0.931248 0.120047 0.344043 +v 154.585266 -143.552399 31.957199 1.000000 1.000000 1.000000 +vn 0.693309 0.136604 0.707575 +v 154.564667 -144.308670 32.189400 1.000000 1.000000 1.000000 +vn 0.875829 0.263833 0.404124 +v 154.783539 -144.212387 31.841799 1.000000 1.000000 1.000000 +vn 0.848181 0.394547 0.353443 +v 155.064209 -144.831924 31.726999 1.000000 1.000000 1.000000 +vn 0.794827 0.604738 0.050415 +v 155.565033 -145.292389 30.786598 1.000000 1.000000 1.000000 +vn 0.277835 -0.055663 0.959015 +v 154.336777 -144.409149 32.343998 1.000000 1.000000 1.000000 +vn 0.577348 0.391666 0.716427 +v 155.692505 -146.108658 31.843399 1.000000 1.000000 1.000000 +vn -0.228380 -0.230011 0.946011 +v 154.115341 -144.506821 32.340199 1.000000 1.000000 1.000000 +vn 0.276982 0.053649 0.959376 +v 155.522552 -146.302597 31.997999 1.000000 1.000000 1.000000 +vn -0.187532 -0.401471 0.896467 +v 155.357758 -146.488190 31.994198 1.000000 1.000000 1.000000 +vn 0.016270 -0.345499 0.938278 +v 157.170517 -147.718872 31.659599 1.000000 1.000000 1.000000 +vn 0.238694 0.153933 0.958817 +v 157.254211 -147.476089 31.663198 1.000000 1.000000 1.000000 +vn -0.051158 -0.651368 0.757036 +v 157.834869 -148.180725 31.403799 1.000000 1.000000 1.000000 +vn 0.122158 -0.335921 0.933935 +v 158.621521 -148.059326 31.428198 1.000000 1.000000 1.000000 +vn -0.218454 -0.598939 0.770422 +v 156.466278 -147.644928 31.621199 1.000000 1.000000 1.000000 +vn -0.446789 -0.453876 0.770958 +v 154.684387 -146.044464 31.968798 1.000000 1.000000 1.000000 +vn -0.548021 -0.650038 0.526424 +v 155.038452 -146.849579 31.515999 1.000000 1.000000 1.000000 +vn -0.475021 -0.701162 0.531720 +v 155.662888 -147.410507 31.399998 1.000000 1.000000 1.000000 +vn -0.357403 -0.806035 0.471775 +v 156.358124 -147.872360 31.283398 1.000000 1.000000 1.000000 +vn -0.598123 -0.331168 0.729778 +v 153.908051 -144.597504 32.199600 1.000000 1.000000 1.000000 +vn -0.740608 -0.469100 0.481088 +v 154.041946 -145.473785 31.747198 1.000000 1.000000 1.000000 +vn -0.683901 -0.571219 0.453859 +v 154.497711 -146.202133 31.630999 1.000000 1.000000 1.000000 +vn -0.624310 -0.173124 0.761751 +v 153.534683 -142.974731 32.430397 1.000000 1.000000 1.000000 +vn -0.814890 -0.368045 0.447770 +v 153.687897 -144.693787 31.861998 1.000000 1.000000 1.000000 +vn -0.841556 -0.256632 0.475315 +v 153.439407 -143.862167 31.977198 1.000000 1.000000 1.000000 +vn -0.861358 -0.485100 0.150801 +v 153.910614 -145.556107 31.278999 1.000000 1.000000 1.000000 +vn -0.919166 -0.364750 0.148630 +v 153.547562 -144.755173 31.393599 1.000000 1.000000 1.000000 +vn -0.787679 -0.597157 0.151542 +v 154.379257 -146.304001 31.162798 1.000000 1.000000 1.000000 +vn -0.878202 -0.446496 -0.171471 +v 153.920929 -145.549118 30.463398 1.000000 1.000000 1.000000 +vn -0.930428 -0.324875 -0.169588 +v 153.560425 -144.750992 30.578199 1.000000 1.000000 1.000000 +vn -0.809761 -0.560679 -0.172989 +v 154.389572 -146.295624 30.347198 1.000000 1.000000 1.000000 +vn -0.724555 -0.666759 -0.174507 +v 154.943176 -146.958405 30.232199 1.000000 1.000000 1.000000 +vn -0.696764 -0.700769 0.153111 +v 154.934174 -146.968185 31.047598 1.000000 1.000000 1.000000 +vn -0.620970 -0.763714 -0.176459 +v 155.581772 -147.533295 30.116198 1.000000 1.000000 1.000000 +vn -0.588226 -0.793635 0.155349 +v 155.574051 -147.544449 30.931799 1.000000 1.000000 1.000000 +vn -0.469253 -0.869213 0.155791 +v 156.287308 -148.017471 30.815199 1.000000 1.000000 1.000000 +vn -0.340982 -0.924345 0.171225 +v 156.958099 -148.339783 30.712999 1.000000 1.000000 1.000000 +vn -0.153152 -0.865677 0.476600 +v 157.783371 -148.431885 31.065998 1.000000 1.000000 1.000000 +vn -0.492694 -0.842961 -0.216030 +v 156.293747 -148.004913 29.999598 1.000000 1.000000 1.000000 +vn -0.262014 -0.948413 -0.178497 +v 157.753754 -148.578400 29.782198 1.000000 1.000000 1.000000 +vn -0.205566 -0.965820 0.157904 +v 157.751175 -148.592346 30.597799 1.000000 1.000000 1.000000 +vn 0.001970 -0.866002 0.500037 +v 158.588043 -148.557465 30.949799 1.000000 1.000000 1.000000 +vn 0.169314 -0.603709 0.779018 +v 159.386276 -148.302124 31.171198 1.000000 1.000000 1.000000 +vn -0.055351 -0.985781 0.158659 +v 158.576447 -148.722107 30.481598 1.000000 1.000000 1.000000 +vn 0.132260 -0.873237 0.469004 +v 159.403015 -148.558868 30.833399 1.000000 1.000000 1.000000 +vn -0.101585 -0.978103 -0.181648 +v 158.577744 -148.708160 29.665998 1.000000 1.000000 1.000000 +vn 0.096119 -0.982798 0.157698 +v 159.413315 -148.722107 30.365198 1.000000 1.000000 1.000000 +vn 0.261950 -0.827560 0.496515 +v 160.201248 -148.436066 30.717999 1.000000 1.000000 1.000000 +vn 0.243776 -0.221362 0.944231 +v 160.817947 -147.727249 31.080999 1.000000 1.000000 1.000000 +vn 0.343686 -0.576652 0.741183 +v 160.895203 -147.954681 30.940399 1.000000 1.000000 1.000000 +vn 0.242374 -0.957170 0.158368 +v 160.233444 -148.597931 30.249798 1.000000 1.000000 1.000000 +vn 0.385438 -0.797374 0.464363 +v 160.976318 -148.194672 30.602798 1.000000 1.000000 1.000000 +vn 0.048783 -0.982131 -0.181766 +v 159.412033 -148.708160 29.549599 1.000000 1.000000 1.000000 +vn 0.195888 -0.963660 -0.181625 +v 160.230865 -148.583969 29.434198 1.000000 1.000000 1.000000 +vn 0.383923 -0.909918 0.157009 +v 161.029099 -148.349564 30.134399 1.000000 1.000000 1.000000 +vn 0.339468 -0.923147 -0.180449 +v 161.023956 -148.337006 29.318798 1.000000 1.000000 1.000000 +vn 0.494844 -0.717770 0.489833 +v 161.707611 -147.838867 30.487997 1.000000 1.000000 1.000000 +vn 0.471999 -0.431073 0.769021 +v 162.256073 -147.163528 30.709599 1.000000 1.000000 1.000000 +vn 0.599729 -0.656986 0.456831 +v 162.395126 -147.370026 30.371798 1.000000 1.000000 1.000000 +vn 0.513606 -0.843880 0.155162 +v 161.779709 -147.983978 30.019798 1.000000 1.000000 1.000000 +vn 0.472385 -0.863044 -0.178907 +v 161.773270 -147.971420 29.204199 1.000000 1.000000 1.000000 +vn 0.125577 -0.856439 -0.500743 +v 160.202545 -148.443054 29.040998 1.000000 1.000000 1.000000 +vn 0.263931 -0.842421 -0.469752 +v 160.978882 -148.201645 28.925798 1.000000 1.000000 1.000000 +vn 0.592121 -0.785875 -0.178304 +v 162.477524 -147.491440 29.087999 1.000000 1.000000 1.000000 +vn 0.629515 -0.761658 0.153582 +v 162.485245 -147.502594 29.903599 1.000000 1.000000 1.000000 +vn 0.386565 -0.795185 -0.467171 +v 161.711472 -147.844452 28.810999 1.000000 1.000000 1.000000 +vn 0.679528 -0.552293 0.482923 +v 163.010544 -146.806320 30.256798 1.000000 1.000000 1.000000 +vn 0.698136 -0.693984 -0.176045 +v 163.107101 -146.913757 28.972799 1.000000 1.000000 1.000000 +vn 0.731352 -0.664928 0.151642 +v 163.116119 -146.923523 29.788399 1.000000 1.000000 1.000000 +vn 0.486722 -0.720394 -0.494099 +v 162.398987 -147.374222 28.694799 1.000000 1.000000 1.000000 +vn 0.225558 -0.566200 -0.792806 +v 161.599457 -147.618408 28.466599 1.000000 1.000000 1.000000 +vn 0.119208 -0.654209 -0.746860 +v 160.896500 -147.960266 28.581198 1.000000 1.000000 1.000000 +vn -0.054185 -0.303085 -0.951422 +v 160.812805 -147.709106 28.430199 1.000000 1.000000 1.000000 +vn -0.046839 -0.604247 -0.795419 +v 159.386276 -148.307709 28.811998 1.000000 1.000000 1.000000 +vn -0.173347 -0.251430 -0.952226 +v 158.622803 -148.041199 28.777399 1.000000 1.000000 1.000000 +vn 0.393669 -0.545842 -0.739649 +v 162.848312 -146.626328 28.235197 1.000000 1.000000 1.000000 +vn 0.599984 -0.654164 -0.460532 +v 163.014404 -146.810516 28.579798 1.000000 1.000000 1.000000 +vn 0.083841 -0.295517 -0.951651 +v 162.677078 -146.435165 28.084198 1.000000 1.000000 1.000000 +vn 0.462079 -0.419821 -0.781174 +v 163.365891 -145.997040 28.119398 1.000000 1.000000 1.000000 +vn 0.693615 -0.551487 -0.463422 +v 163.553848 -146.153305 28.463799 1.000000 1.000000 1.000000 +vn 0.789174 -0.588913 -0.174313 +v 163.659424 -146.241211 28.856998 1.000000 1.000000 1.000000 +vn 0.820983 -0.389220 -0.417726 +v 164.316040 -144.717514 28.244999 1.000000 1.000000 1.000000 +vn 0.859262 -0.466146 -0.210660 +v 164.119064 -145.486328 28.740398 1.000000 1.000000 1.000000 +vn 0.589500 -0.348618 -0.728667 +v 164.095886 -144.619843 27.900599 1.000000 1.000000 1.000000 +vn 0.207827 -0.234892 -0.949544 +v 163.867996 -144.519363 27.749399 1.000000 1.000000 1.000000 +vn 0.669782 -0.176573 -0.721259 +v 164.476974 -142.992874 27.669197 1.000000 1.000000 1.000000 +vn 0.838683 -0.260382 -0.478343 +v 164.569672 -143.888687 28.129799 1.000000 1.000000 1.000000 +vn 0.951993 -0.256261 -0.167451 +v 164.698425 -143.923569 28.522999 1.000000 1.000000 1.000000 +vn 0.931363 -0.325818 0.162499 +v 164.451233 -144.777512 29.453598 1.000000 1.000000 1.000000 +vn 0.883766 -0.443438 0.149401 +v 164.130646 -145.493317 29.555798 1.000000 1.000000 1.000000 +vn 0.978456 -0.117760 -0.169574 +v 164.845200 -143.036133 28.406799 1.000000 1.000000 1.000000 +vn 0.967071 -0.207347 0.147585 +v 164.710007 -143.927750 29.338398 1.000000 1.000000 1.000000 +vn 0.883411 -0.144667 -0.445709 +v 164.712585 -143.020782 28.013599 1.000000 1.000000 1.000000 +vn 0.985582 0.010285 -0.168888 +v 164.873535 -142.133347 28.290398 1.000000 1.000000 1.000000 +vn 0.987889 0.051178 0.146480 +v 164.886398 -142.131958 29.105799 1.000000 1.000000 1.000000 +vn 0.986048 -0.078349 0.146871 +v 164.858063 -143.037521 29.222399 1.000000 1.000000 1.000000 +vn 0.878313 -0.161766 0.449886 +v 164.563248 -143.887283 29.806799 1.000000 1.000000 1.000000 +vn 0.880435 -0.025167 0.473498 +v 164.707443 -143.020782 29.690598 1.000000 1.000000 1.000000 +vn 0.822766 -0.343410 0.452909 +v 163.998032 -145.412384 30.024199 1.000000 1.000000 1.000000 +vn 0.674802 -0.064735 0.735154 +v 164.334061 -143.823090 30.144598 1.000000 1.000000 1.000000 +vn 0.634117 0.133320 0.761657 +v 164.498856 -142.147308 29.911999 1.000000 1.000000 1.000000 +vn 0.892659 0.086875 0.442281 +v 164.735764 -142.137527 29.574198 1.000000 1.000000 1.000000 +vn 0.856367 0.203022 0.474783 +v 164.650787 -141.268250 29.458799 1.000000 1.000000 1.000000 +vn 0.359402 0.101104 0.927690 +v 164.249084 -142.966354 30.168999 1.000000 1.000000 1.000000 +vn 0.619935 0.292014 0.728291 +v 164.228500 -140.500809 29.681198 1.000000 1.000000 1.000000 +vn 0.244299 0.214909 0.945586 +v 164.016052 -140.576157 29.821798 1.000000 1.000000 1.000000 +vn 0.837669 0.314677 0.446419 +v 164.453812 -140.421280 29.343399 1.000000 1.000000 1.000000 +vn 0.972772 0.178561 0.147754 +v 164.800140 -141.240326 28.990599 1.000000 1.000000 1.000000 +vn 0.940498 0.305409 0.148960 +v 164.598007 -140.369644 28.875198 1.000000 1.000000 1.000000 +vn 0.770973 0.419518 0.479172 +v 164.151245 -139.616165 29.228798 1.000000 1.000000 1.000000 +vn 0.891659 0.427418 0.149189 +v 164.286423 -139.543610 28.760399 1.000000 1.000000 1.000000 +vn 0.366457 0.005477 0.930419 +v 163.884735 -144.526352 30.400398 1.000000 1.000000 1.000000 +vn 0.626772 -0.203464 0.752170 +v 163.792038 -145.286804 30.361998 1.000000 1.000000 1.000000 +vn 0.346702 -0.136090 0.928050 +v 162.688660 -146.449112 30.734999 1.000000 1.000000 1.000000 +vn -0.046145 0.262663 0.963784 +v 162.522583 -146.263535 30.738798 1.000000 1.000000 1.000000 +vn 0.761243 -0.466117 0.450826 +v 163.548706 -146.149109 30.140799 1.000000 1.000000 1.000000 +vn 0.586005 -0.281636 0.759789 +v 163.360733 -145.992844 30.478598 1.000000 1.000000 1.000000 +vn 0.073509 0.256057 0.963863 +v 160.735565 -147.483063 31.084799 1.000000 1.000000 1.000000 +vn 0.816947 -0.556547 0.151171 +v 163.669724 -146.249588 29.672598 1.000000 1.000000 1.000000 +vn 0.170108 0.210837 0.962607 +v 158.638260 -147.802597 31.431999 1.000000 1.000000 1.000000 +vn 0.975859 0.137715 -0.169511 +v 164.787262 -141.241730 28.174999 1.000000 1.000000 1.000000 +vn 0.895174 -0.029249 -0.444756 +v 164.740921 -142.137527 27.897198 1.000000 1.000000 1.000000 +vn 0.876320 0.080695 -0.474924 +v 164.655945 -141.266846 27.781799 1.000000 1.000000 1.000000 +vn 0.949199 0.265187 -0.169404 +v 164.586411 -140.373825 28.059599 1.000000 1.000000 1.000000 +vn 0.905701 0.388298 -0.170087 +v 164.274841 -139.549194 27.944998 1.000000 1.000000 1.000000 +vn 0.871845 0.203138 -0.445670 +v 164.460236 -140.418488 27.666599 1.000000 1.000000 1.000000 +vn 0.836642 0.315583 -0.447703 +v 164.156387 -139.613373 27.551798 1.000000 1.000000 1.000000 +vn 0.686004 0.084132 -0.722717 +v 164.234940 -140.499420 27.321999 1.000000 1.000000 1.000000 +vn 0.602062 0.180974 -0.777669 +v 163.943954 -139.726395 27.207399 1.000000 1.000000 1.000000 +vn 0.260507 -0.168118 -0.950722 +v 164.232361 -142.964966 27.518198 1.000000 1.000000 1.000000 +vn 0.318774 -0.064124 -0.945659 +v 164.000610 -140.581741 27.170998 1.000000 1.000000 1.000000 +vn 0.626139 -0.062655 -0.777190 +v 164.504013 -142.147308 27.552799 1.000000 1.000000 1.000000 +vn 0.594497 0.340978 -0.728222 +v 163.071045 -138.339432 26.975998 1.000000 1.000000 1.000000 +vn 0.321369 0.062970 -0.944858 +v 162.889511 -138.519440 26.824999 1.000000 1.000000 1.000000 +vn -0.173459 -0.646806 -0.742667 +v 158.604782 -148.307709 28.928398 1.000000 1.000000 1.000000 +vn -0.251017 -0.202875 -0.946484 +v 157.176956 -147.700729 29.008799 1.000000 1.000000 1.000000 +vn -0.361963 -0.568537 -0.738748 +v 157.091980 -147.950485 29.159798 1.000000 1.000000 1.000000 +vn -0.316428 -0.083537 -0.944931 +v 155.369339 -146.475632 29.343399 1.000000 1.000000 1.000000 +vn -0.407496 -0.803795 -0.433429 +v 157.009583 -148.191895 29.504198 1.000000 1.000000 1.000000 +vn -0.266468 -0.824703 -0.498859 +v 157.782074 -148.437469 29.388998 1.000000 1.000000 1.000000 +vn -0.442054 -0.441692 -0.780702 +v 155.796783 -147.206787 29.378599 1.000000 1.000000 1.000000 +vn -0.569226 -0.378216 -0.730023 +v 155.199387 -146.668182 29.494398 1.000000 1.000000 1.000000 +vn -0.578547 -0.667869 -0.468225 +v 155.659027 -147.416092 29.723198 1.000000 1.000000 1.000000 +vn -0.134403 -0.871537 -0.471550 +v 158.588043 -148.564438 29.272799 1.000000 1.000000 1.000000 +vn -0.000676 -0.881226 -0.472695 +v 159.403015 -148.564438 29.156399 1.000000 1.000000 1.000000 +vn -0.681889 -0.571614 -0.456382 +v 155.034592 -146.853760 29.838999 1.000000 1.000000 1.000000 +vn -0.745127 -0.461273 -0.481678 +v 154.493851 -146.206329 29.954199 1.000000 1.000000 1.000000 +vn -0.588436 -0.218842 -0.778364 +v 154.241516 -145.348190 29.725798 1.000000 1.000000 1.000000 +vn -0.813295 -0.368921 -0.449942 +v 154.036789 -145.477966 30.070398 1.000000 1.000000 1.000000 +vn 0.183124 0.230427 -0.955703 +v 154.347076 -144.404953 29.694599 1.000000 1.000000 1.000000 +vn 0.081259 -0.260805 -0.961966 +v 160.423981 -137.135254 31.532198 1.000000 1.000000 1.000000 +vn -0.225542 -0.683244 -0.694484 +v 160.924820 -137.584549 31.770399 1.000000 1.000000 1.000000 +vn -0.004468 -0.249698 -0.968314 +v 162.221313 -138.176178 31.866999 1.000000 1.000000 1.000000 +vn -0.502293 -0.545709 -0.670749 +v 162.567642 -138.865479 32.117996 1.000000 1.000000 1.000000 +vn -0.165830 -0.241792 -0.956053 +v 163.520386 -139.971985 32.212997 1.000000 1.000000 1.000000 +vn -0.563185 -0.376793 -0.735425 +v 163.323395 -140.076630 32.348801 1.000000 1.000000 1.000000 +vn -0.817855 -0.502931 -0.279597 +v 162.674500 -139.674774 32.966400 1.000000 1.000000 1.000000 +vn -0.784488 -0.406711 -0.468151 +v 163.109680 -140.189651 32.683598 1.000000 1.000000 1.000000 +vn -0.728707 -0.250710 -0.637284 +v 163.737961 -141.466385 32.579597 1.000000 1.000000 1.000000 +vn -0.884074 -0.409075 -0.225987 +v 162.984787 -140.255219 33.081001 1.000000 1.000000 1.000000 +vn -0.916484 -0.397205 0.047811 +v 162.938446 -140.278961 33.535797 1.000000 1.000000 1.000000 +vn 0.309101 0.103055 -0.945429 +v 162.370651 -137.980835 31.861799 1.000000 1.000000 1.000000 +vn 0.235299 0.218789 -0.946977 +v 160.489655 -136.892471 31.527199 1.000000 1.000000 1.000000 +vn -0.236906 -0.155960 -0.958933 +v 164.026367 -142.194733 32.560196 1.000000 1.000000 1.000000 +vn -0.276337 -0.083965 -0.957386 +v 163.869293 -143.718445 32.791397 1.000000 1.000000 1.000000 +vn -0.269135 -0.004081 -0.963094 +v 162.970627 -145.699814 33.126198 1.000000 1.000000 1.000000 +vn 0.154334 0.262322 -0.952559 +v 159.025787 -136.659454 31.295799 1.000000 1.000000 1.000000 +vn -0.857157 -0.318701 0.404612 +v 163.098083 -140.195221 34.360199 1.000000 1.000000 1.000000 +vn -0.108459 0.251088 -0.961869 +v 157.961044 -147.685379 23.745598 1.000000 1.000000 1.000000 +vn 0.125785 0.660870 -0.739885 +v 157.352066 -147.248642 23.997599 1.000000 1.000000 1.000000 +vn -0.094207 0.739819 -0.666178 +v 158.682022 -147.554214 23.764999 1.000000 1.000000 1.000000 +vn -0.212922 0.205387 -0.955239 +v 160.073792 -147.678406 23.398399 1.000000 1.000000 1.000000 +vn -0.022174 0.270909 -0.962350 +v 156.632355 -147.157944 23.976999 1.000000 1.000000 1.000000 +vn 0.368521 0.622507 -0.690418 +v 156.226807 -146.608185 24.214998 1.000000 1.000000 1.000000 +vn 0.358328 0.802827 -0.476519 +v 156.848648 -146.721207 24.447599 1.000000 1.000000 1.000000 +vn 0.134608 0.873923 -0.467054 +v 158.055023 -147.199814 24.216198 1.000000 1.000000 1.000000 +vn 0.058964 0.243411 -0.968129 +v 155.068069 -145.743073 24.311598 1.000000 1.000000 1.000000 +vn 0.606352 0.435589 -0.665282 +v 154.859497 -144.992386 24.562599 1.000000 1.000000 1.000000 +vn 0.695832 0.601134 -0.393007 +v 155.425995 -145.436111 24.782198 1.000000 1.000000 1.000000 +vn 0.542814 0.618416 -0.568256 +v 155.862442 -145.950974 24.666401 1.000000 1.000000 1.000000 +vn 0.452661 0.857939 -0.242980 +v 156.914322 -146.588654 24.844999 1.000000 1.000000 1.000000 +vn 0.217909 0.947806 -0.232765 +v 158.084641 -147.053299 24.613798 1.000000 1.000000 1.000000 +vn -0.050302 0.891086 -0.451038 +v 158.697479 -147.296082 24.099798 1.000000 1.000000 1.000000 +vn 0.381688 0.923688 0.033384 +v 157.498840 -146.813309 25.184799 1.000000 1.000000 1.000000 +vn 0.216987 0.976157 0.005884 +v 158.094940 -146.998871 25.068598 1.000000 1.000000 1.000000 +vn 0.050460 0.998672 0.010415 +v 158.710358 -147.090973 24.951998 1.000000 1.000000 1.000000 +vn -0.252958 0.834875 -0.488873 +v 159.975937 -147.195618 23.868998 1.000000 1.000000 1.000000 +vn -0.233580 0.942253 -0.240000 +v 159.946335 -147.047714 24.266598 1.000000 1.000000 1.000000 +vn -0.268921 0.606786 -0.747993 +v 160.027435 -147.446777 23.534397 1.000000 1.000000 1.000000 +vn -0.418098 0.794184 -0.440983 +v 160.588791 -147.000275 23.754398 1.000000 1.000000 1.000000 +vn -0.351441 0.889668 -0.291514 +v 160.541153 -146.859344 24.151798 1.000000 1.000000 1.000000 +vn -0.214366 0.975486 0.049732 +v 159.936035 -146.993301 24.721399 1.000000 1.000000 1.000000 +vn -0.524324 0.849976 0.051234 +v 161.087036 -146.528656 24.490398 1.000000 1.000000 1.000000 +vn -0.455599 0.580591 -0.674792 +v 161.291748 -146.937485 23.303398 1.000000 1.000000 1.000000 +vn -0.629077 0.667343 -0.398642 +v 161.719193 -146.337494 23.522999 1.000000 1.000000 1.000000 +vn -0.726705 0.686905 -0.007821 +v 162.077118 -145.736099 24.259399 1.000000 1.000000 1.000000 +vn -0.260107 0.063011 -0.963522 +v 161.990860 -146.736557 23.052399 1.000000 1.000000 1.000000 +vn -0.646266 0.354909 -0.675559 +v 162.827713 -145.511459 22.955799 1.000000 1.000000 1.000000 +vn -0.643800 0.518387 -0.562846 +v 162.209717 -145.884003 23.407200 1.000000 1.000000 1.000000 +vn -0.873784 0.426665 -0.233365 +v 162.834152 -144.766342 23.585800 1.000000 1.000000 1.000000 +vn -0.838068 0.545530 0.006275 +v 162.487823 -145.229599 24.142799 1.000000 1.000000 1.000000 +vn -0.488869 0.747391 0.449904 +v 161.711472 -146.326324 25.199598 1.000000 1.000000 1.000000 +vn -0.408114 0.847090 0.340412 +v 161.172012 -146.697495 25.314798 1.000000 1.000000 1.000000 +vn -0.931844 0.361384 0.032682 +v 163.060745 -144.139847 23.925398 1.000000 1.000000 1.000000 +vn -0.691339 0.651751 0.311884 +v 162.200714 -145.872849 25.083799 1.000000 1.000000 1.000000 +vn -0.820838 0.345568 -0.454761 +v 162.953888 -144.841690 23.188400 1.000000 1.000000 1.000000 +vn -0.951654 0.216743 -0.217662 +v 163.301498 -143.514725 23.354597 1.000000 1.000000 1.000000 +vn -0.886910 0.145879 -0.438303 +v 163.436691 -143.551010 22.956997 1.000000 1.000000 1.000000 +vn -0.686827 0.134872 -0.714198 +v 163.457291 -144.314255 22.738400 1.000000 1.000000 1.000000 +vn -0.906336 -0.014568 -0.422307 +v 163.547424 -142.857529 22.840599 1.000000 1.000000 1.000000 +vn -0.976359 0.216081 0.005721 +v 163.252594 -143.500778 23.809399 1.000000 1.000000 1.000000 +vn -0.997169 0.074633 0.009169 +v 163.358170 -142.836594 23.692799 1.000000 1.000000 1.000000 +vn -0.770582 -0.058770 -0.634625 +v 163.784317 -142.884033 22.505798 1.000000 1.000000 1.000000 +vn -0.291212 -0.011390 -0.956591 +v 163.349152 -145.090057 22.717800 1.000000 1.000000 1.000000 +vn -0.272535 -0.091140 -0.957819 +v 163.880875 -143.669601 22.486397 1.000000 1.000000 1.000000 +vn -0.864734 -0.193750 -0.463352 +v 163.497208 -141.470566 22.609798 1.000000 1.000000 1.000000 +vn -0.646703 -0.220702 -0.730114 +v 163.731522 -141.423126 22.275200 1.000000 1.000000 1.000000 +vn -0.229301 -0.190273 -0.954577 +v 163.947815 -141.381256 22.139198 1.000000 1.000000 1.000000 +vn -0.839691 -0.342713 -0.421269 +v 163.338837 -140.799408 22.495197 1.000000 1.000000 1.000000 +vn -0.959758 -0.170795 -0.222922 +v 163.360733 -141.497070 23.007397 1.000000 1.000000 1.000000 +vn -0.920882 -0.277161 -0.274149 +v 163.207520 -140.846848 22.892597 1.000000 1.000000 1.000000 +vn -0.635927 -0.395379 -0.662776 +v 163.305374 -140.036163 22.044197 1.000000 1.000000 1.000000 +vn -0.898033 -0.437062 0.050133 +v 162.921707 -140.242676 23.231197 1.000000 1.000000 1.000000 +vn -0.987239 -0.152141 0.047033 +v 163.310516 -141.506851 23.462200 1.000000 1.000000 1.000000 +vn 0.040149 -0.304517 -0.951661 +v 162.129898 -146.940277 23.047398 1.000000 1.000000 1.000000 +vn -0.098709 -0.294779 -0.950453 +v 160.122726 -147.926773 23.393398 1.000000 1.000000 1.000000 +vn -0.208969 -0.226716 -0.951279 +v 157.912109 -147.932358 23.740599 1.000000 1.000000 1.000000 +vn -0.277798 -0.167721 -0.945885 +v 156.522919 -147.381195 23.971798 1.000000 1.000000 1.000000 +vn -0.324525 -0.042306 -0.944931 +v 154.885254 -145.900757 24.306599 1.000000 1.000000 1.000000 +vn -0.314076 0.083920 -0.945682 +v 153.906754 -143.760300 24.652599 1.000000 1.000000 1.000000 +vn 0.215578 0.204751 -0.954779 +v 154.133362 -143.697525 24.657598 1.000000 1.000000 1.000000 +vn -0.246828 0.183765 -0.951476 +v 153.826935 -141.365921 24.999798 1.000000 1.000000 1.000000 +vn 0.265461 0.108142 -0.958037 +v 154.056107 -141.409164 25.004799 1.000000 1.000000 1.000000 +vn -0.655878 0.218449 -0.722568 +v 153.583603 -141.319870 25.150799 1.000000 1.000000 1.000000 +vn -0.189992 0.247008 -0.950205 +v 154.286560 -139.842209 25.230997 1.000000 1.000000 1.000000 +vn -0.620093 0.101892 -0.777883 +v 153.503769 -142.161255 25.034401 1.000000 1.000000 1.000000 +vn -0.690374 -0.040686 -0.722308 +v 153.668579 -143.825897 24.803598 1.000000 1.000000 1.000000 +vn 0.289979 0.029734 -0.956571 +v 154.496429 -139.953842 25.236198 1.000000 1.000000 1.000000 +vn -0.061832 0.300022 -0.951926 +v 155.595932 -138.018509 25.565798 1.000000 1.000000 1.000000 +vn 0.264086 -0.046410 -0.963382 +v 155.747864 -138.211060 25.570799 1.000000 1.000000 1.000000 +vn 0.076695 0.299112 -0.951131 +v 157.536163 -136.885498 25.911798 1.000000 1.000000 1.000000 +vn -0.353928 0.570649 -0.741009 +v 155.436279 -137.814789 25.716799 1.000000 1.000000 1.000000 +vn -0.431500 0.449122 -0.782366 +v 154.881378 -138.405014 25.600998 1.000000 1.000000 1.000000 +vn -0.564006 0.386042 -0.729979 +v 154.065125 -139.723602 25.382198 1.000000 1.000000 1.000000 +vn -0.070704 0.660907 -0.747130 +v 157.467926 -136.628754 26.062798 1.000000 1.000000 1.000000 +vn 0.191603 0.239147 -0.951891 +v 159.741623 -136.716660 26.258999 1.000000 1.000000 1.000000 +vn -0.183306 0.580057 -0.793683 +v 156.745651 -136.917587 25.948198 1.000000 1.000000 1.000000 +vn 0.091561 0.599748 -0.794933 +v 158.997467 -136.392944 26.293598 1.000000 1.000000 1.000000 +vn 0.220484 0.633505 -0.741659 +v 159.776382 -136.451553 26.409998 1.000000 1.000000 1.000000 +vn 0.264876 0.185043 -0.946361 +v 161.163010 -137.163177 26.490198 1.000000 1.000000 1.000000 +vn 0.065647 0.879392 -0.471551 +v 158.996170 -136.136200 26.637999 1.000000 1.000000 1.000000 +vn -0.062359 0.863646 -0.500227 +v 158.191498 -136.198990 26.522598 1.000000 1.000000 1.000000 +vn 0.325275 0.804124 -0.497576 +v 160.605530 -136.381775 26.870598 1.000000 1.000000 1.000000 +vn 0.197701 0.860241 -0.469999 +v 159.809860 -136.197601 26.754398 1.000000 1.000000 1.000000 +vn 0.402041 0.542694 -0.737459 +v 161.263428 -136.918991 26.641399 1.000000 1.000000 1.000000 +vn 0.464599 0.773329 -0.431405 +v 161.361282 -136.684570 26.985798 1.000000 1.000000 1.000000 +vn 0.472558 0.411565 -0.779297 +v 162.508423 -137.757584 26.860197 1.000000 1.000000 1.000000 +vn 0.329272 0.927488 -0.177047 +v 160.642868 -136.243637 27.263798 1.000000 1.000000 1.000000 +vn 0.172943 0.968178 -0.180891 +v 159.829178 -136.055283 27.147598 1.000000 1.000000 1.000000 +vn 0.023813 0.983137 -0.181315 +v 158.996170 -135.992477 27.031199 1.000000 1.000000 1.000000 +vn 0.274692 0.948466 0.157978 +v 160.645432 -136.231094 28.079199 1.000000 1.000000 1.000000 +vn 0.127623 0.979216 0.157631 +v 159.830460 -136.041321 27.963198 1.000000 1.000000 1.000000 +vn 0.406654 0.897328 0.171565 +v 161.421783 -136.540848 28.194399 1.000000 1.000000 1.000000 +vn 0.551848 0.805724 -0.215111 +v 162.062958 -136.924561 27.481199 1.000000 1.000000 1.000000 +vn 0.216707 0.852979 0.474830 +v 160.602951 -136.388763 28.547598 1.000000 1.000000 1.000000 +vn 0.061472 0.864516 0.498832 +v 159.808578 -136.203171 28.431398 1.000000 1.000000 1.000000 +vn -0.066810 0.880302 0.469685 +v 158.996170 -136.143173 28.314999 1.000000 1.000000 1.000000 +vn -0.022827 0.987139 0.158227 +v 158.996170 -135.978531 27.846598 1.000000 1.000000 1.000000 +vn 0.099899 0.646323 0.756496 +v 160.537292 -136.634338 28.885399 1.000000 1.000000 1.000000 +vn -0.124345 0.614197 0.779295 +v 158.997467 -136.399918 28.652599 1.000000 1.000000 1.000000 +vn 0.414865 0.778451 0.471065 +v 161.990860 -137.052933 28.764999 1.000000 1.000000 1.000000 +vn 0.008647 0.343700 0.939040 +v 161.169434 -137.146423 29.140999 1.000000 1.000000 1.000000 +vn -0.097129 0.344045 0.933916 +v 159.744202 -136.697128 28.909798 1.000000 1.000000 1.000000 +vn 0.261447 0.582168 0.769887 +v 161.868546 -137.272003 29.102798 1.000000 1.000000 1.000000 +vn 0.642030 0.750960 0.154453 +v 162.751755 -137.438049 28.413198 1.000000 1.000000 1.000000 +vn 0.530374 0.833310 0.155876 +v 162.070679 -136.912018 28.296598 1.000000 1.000000 1.000000 +vn 0.523491 0.666935 0.530240 +v 162.655197 -137.565018 28.881599 1.000000 1.000000 1.000000 +vn 0.672676 0.718820 -0.175515 +v 162.744034 -137.449219 27.597799 1.000000 1.000000 1.000000 +vn 0.742240 0.652387 0.153203 +v 163.354294 -138.058975 28.529198 1.000000 1.000000 1.000000 +vn 0.624319 0.627185 -0.465688 +v 162.659058 -137.559448 27.204599 1.000000 1.000000 1.000000 +vn 0.718882 0.525577 -0.454947 +v 163.246140 -138.166412 27.320599 1.000000 1.000000 1.000000 +vn 0.774113 0.411808 -0.480795 +v 163.745682 -138.851532 27.435598 1.000000 1.000000 1.000000 +vn 0.767391 0.616870 -0.174880 +v 163.345291 -138.068741 27.713598 1.000000 1.000000 1.000000 +vn 0.845341 0.505549 -0.172683 +v 163.856415 -138.770599 27.828798 1.000000 1.000000 1.000000 +vn 0.825759 0.543341 0.151339 +v 163.866714 -138.762222 28.644199 1.000000 1.000000 1.000000 +vn 0.591651 0.611714 0.525123 +v 163.242279 -138.170609 28.997398 1.000000 1.000000 1.000000 +vn 0.477887 0.423737 0.769462 +v 163.546127 -138.999420 29.450399 1.000000 1.000000 1.000000 +vn 0.721066 0.525043 0.452098 +v 163.741821 -138.855713 29.112598 1.000000 1.000000 1.000000 +vn 0.216193 0.388499 0.895728 +v 162.902390 -138.506882 29.475798 1.000000 1.000000 1.000000 +vn -0.272897 0.073435 0.959236 +v 163.789474 -140.657089 29.825598 1.000000 1.000000 1.000000 +vn -0.280667 -0.036061 0.959127 +v 162.725998 -138.681290 29.479399 1.000000 1.000000 1.000000 +vn -0.223341 0.164505 0.960759 +v 164.012192 -142.939850 30.172798 1.000000 1.000000 1.000000 +vn -0.160130 0.229272 0.960101 +v 163.663300 -144.428680 30.403999 1.000000 1.000000 1.000000 +vn -0.249576 -0.139519 0.958252 +v 161.071594 -137.382233 29.144798 1.000000 1.000000 1.000000 +vn -0.185072 -0.200414 0.962072 +v 159.710724 -136.953873 28.913399 1.000000 1.000000 1.000000 +vn -0.226767 0.236563 0.944783 +v 157.532303 -136.867355 28.562599 1.000000 1.000000 1.000000 +vn -0.301100 0.597786 0.742960 +v 157.469223 -136.634338 28.421997 1.000000 1.000000 1.000000 +vn -0.440104 0.460969 0.770595 +v 156.061996 -137.323639 28.191198 1.000000 1.000000 1.000000 +vn -0.335242 0.156919 0.928972 +v 155.585632 -138.004547 28.216599 1.000000 1.000000 1.000000 +vn -0.200532 0.844480 0.496628 +v 158.191498 -136.204575 28.199598 1.000000 1.000000 1.000000 +vn -0.327024 0.822835 0.464755 +v 157.403564 -136.388763 28.084198 1.000000 1.000000 1.000000 +vn -0.442229 0.750071 0.491759 +v 156.651672 -136.690155 27.969599 1.000000 1.000000 1.000000 +vn -0.171785 0.972538 0.157035 +v 158.170898 -136.042709 27.731199 1.000000 1.000000 1.000000 +vn -0.316265 0.935519 0.157415 +v 157.361069 -136.231094 27.615999 1.000000 1.000000 1.000000 +vn -0.451778 0.878264 0.156682 +v 156.588577 -136.539459 27.501198 1.000000 1.000000 1.000000 +vn -0.552200 0.695922 0.459094 +v 155.935822 -137.107361 27.853399 1.000000 1.000000 1.000000 +vn -0.270502 0.945630 -0.180587 +v 157.364929 -136.243637 26.800398 1.000000 1.000000 1.000000 +vn -0.409433 0.894420 -0.179936 +v 156.593735 -136.552017 26.685799 1.000000 1.000000 1.000000 +vn -0.124645 0.975485 -0.181365 +v 158.172180 -136.056671 26.915798 1.000000 1.000000 1.000000 +vn -0.200731 0.859226 -0.470572 +v 157.402267 -136.381775 26.407398 1.000000 1.000000 1.000000 +vn -0.327691 0.820174 -0.468971 +v 156.649094 -136.683182 26.292599 1.000000 1.000000 1.000000 +vn -0.535615 0.825418 -0.178329 +v 155.861160 -136.980377 26.569599 1.000000 1.000000 1.000000 +vn -0.434247 0.752810 -0.494678 +v 155.931961 -137.101776 26.176399 1.000000 1.000000 1.000000 +vn -0.649320 0.739695 -0.176733 +v 155.196808 -137.509216 26.454399 1.000000 1.000000 1.000000 +vn -0.553483 0.693129 -0.461767 +v 155.283081 -137.619446 26.061398 1.000000 1.000000 1.000000 +vn -0.575056 0.803402 0.154453 +v 155.854721 -136.967819 27.384998 1.000000 1.000000 1.000000 +vn -0.747565 0.640849 -0.174526 +v 154.604568 -138.139908 26.338598 1.000000 1.000000 1.000000 +vn -0.684240 0.713183 0.152270 +v 155.189102 -137.499451 27.269999 1.000000 1.000000 1.000000 +vn -0.654247 0.596738 -0.464613 +v 154.703720 -138.234787 25.945398 1.000000 1.000000 1.000000 +vn -0.826544 0.521767 -0.211151 +v 154.097305 -138.858490 26.221998 1.000000 1.000000 1.000000 +vn -0.793700 0.441780 -0.418176 +v 153.852692 -139.610580 25.726599 1.000000 1.000000 1.000000 +vn -0.777702 0.610399 0.150309 +v 154.594269 -138.130142 27.153999 1.000000 1.000000 1.000000 +vn -0.852808 0.500435 0.149275 +v 154.087006 -138.850128 27.037399 1.000000 1.000000 1.000000 +vn -0.933636 0.316464 -0.167852 +v 153.421387 -140.375229 26.004599 1.000000 1.000000 1.000000 +vn -0.908516 0.384956 0.162502 +v 153.722656 -139.540817 26.935198 1.000000 1.000000 1.000000 +vn -0.820268 0.312890 -0.478811 +v 153.547562 -140.419876 25.611399 1.000000 1.000000 1.000000 +vn -0.968884 0.179952 -0.169942 +v 153.219254 -141.250107 25.888399 1.000000 1.000000 1.000000 +vn -0.951798 0.268697 0.147927 +v 153.409790 -140.371033 26.819998 1.000000 1.000000 1.000000 +vn -0.798264 0.395782 0.454017 +v 154.213181 -138.940826 27.505798 1.000000 1.000000 1.000000 +vn -0.866286 0.217351 0.449785 +v 153.553986 -140.421280 27.288399 1.000000 1.000000 1.000000 +vn -0.669315 0.107276 0.735193 +v 153.778015 -140.500809 27.626198 1.000000 1.000000 1.000000 +vn -0.610804 0.242390 0.753767 +v 154.411453 -139.081757 27.843599 1.000000 1.000000 1.000000 +vn -0.727932 0.515587 0.451979 +v 154.707581 -138.238968 27.622398 1.000000 1.000000 1.000000 +vn -0.877102 0.080314 0.473541 +v 153.355713 -141.275223 27.172199 1.000000 1.000000 1.000000 +vn -0.979048 0.140749 0.147158 +v 153.206375 -141.247299 26.703999 1.000000 1.000000 1.000000 +vn -0.642112 -0.093089 0.760938 +v 153.508926 -142.162659 27.393398 1.000000 1.000000 1.000000 +vn -0.896017 -0.030133 0.442996 +v 153.272034 -142.154282 27.055798 1.000000 1.000000 1.000000 +vn -0.989017 0.011433 0.147360 +v 153.120117 -142.148697 26.587399 1.000000 1.000000 1.000000 +vn -0.868032 -0.148261 0.473855 +v 153.301636 -143.027756 26.940399 1.000000 1.000000 1.000000 +vn -0.638464 -0.251596 0.727367 +v 153.673721 -143.824493 27.162798 1.000000 1.000000 1.000000 +vn -0.366352 -0.078311 0.927175 +v 153.808914 -141.363113 27.650398 1.000000 1.000000 1.000000 +vn -0.982148 -0.117028 0.147274 +v 153.151016 -143.044495 26.471998 1.000000 1.000000 1.000000 +vn -0.857170 -0.260251 0.444442 +v 153.444550 -143.887283 26.824999 1.000000 1.000000 1.000000 +vn -0.958227 -0.244556 0.148302 +v 153.297775 -143.927750 26.356798 1.000000 1.000000 1.000000 +vn -0.797421 -0.369363 0.477170 +v 153.695618 -144.713318 26.710398 1.000000 1.000000 1.000000 +vn -0.917533 -0.368924 0.148421 +v 153.556564 -144.774719 26.241999 1.000000 1.000000 1.000000 +vn -0.984067 0.051822 -0.170078 +v 153.132980 -142.148697 25.771999 1.000000 1.000000 1.000000 +vn -0.982591 -0.075724 -0.169647 +v 153.163879 -143.043106 25.656601 1.000000 1.000000 1.000000 +vn -0.872180 0.200468 -0.446223 +v 153.350571 -141.275223 25.495199 1.000000 1.000000 1.000000 +vn -0.890886 0.085730 -0.446062 +v 153.266876 -142.152878 25.378798 1.000000 1.000000 1.000000 +vn -0.879602 -0.025046 -0.475050 +v 153.296494 -143.027756 25.263399 1.000000 1.000000 1.000000 +vn -0.964238 -0.204057 -0.169133 +v 153.309372 -143.924957 25.541199 1.000000 1.000000 1.000000 +vn -0.883091 -0.147009 -0.445577 +v 153.438126 -143.888687 25.148199 1.000000 1.000000 1.000000 +vn -0.928824 -0.329364 -0.169720 +v 153.568146 -144.770523 25.426598 1.000000 1.000000 1.000000 +vn -0.855361 -0.261227 -0.447345 +v 153.690460 -144.714706 25.033398 1.000000 1.000000 1.000000 +vn -0.613007 -0.142341 -0.777150 +v 153.910614 -144.618439 24.688999 1.000000 1.000000 1.000000 +vn -0.800615 -0.360491 -0.478604 +v 154.052246 -145.505875 24.917198 1.000000 1.000000 1.000000 +vn -0.616785 -0.302148 -0.726831 +v 154.692123 -146.066788 24.457598 1.000000 1.000000 1.000000 +vn -0.365657 0.017648 0.930582 +v 154.271118 -139.833847 27.881798 1.000000 1.000000 1.000000 +vn -0.564617 0.318416 0.761459 +v 154.885254 -138.409195 27.959999 1.000000 1.000000 1.000000 +vn -0.639578 0.596980 0.484309 +v 155.286942 -137.623642 27.738199 1.000000 1.000000 1.000000 +vn -0.827191 0.390283 0.404270 +v 163.224258 -144.212387 24.749798 1.000000 1.000000 1.000000 +vn -0.721767 0.530123 0.444997 +v 162.942307 -144.834717 24.864998 1.000000 1.000000 1.000000 +vn -0.326057 0.602225 0.728705 +v 161.851807 -146.531433 25.547199 1.000000 1.000000 1.000000 +vn -0.518638 0.446825 0.728946 +v 163.147018 -144.961685 25.212599 1.000000 1.000000 1.000000 +vn 0.110232 0.242910 0.963766 +v 160.076370 -147.690964 26.047998 1.000000 1.000000 1.000000 +vn -0.007175 0.266233 0.963882 +v 161.998581 -146.746323 25.701799 1.000000 1.000000 1.000000 +vn -0.029610 0.679797 0.732802 +v 160.023575 -147.430038 25.893398 1.000000 1.000000 1.000000 +vn -0.291960 0.881800 0.370390 +v 160.584915 -146.986328 25.430998 1.000000 1.000000 1.000000 +vn 0.030788 0.928726 0.369487 +v 159.339935 -147.279343 25.660999 1.000000 1.000000 1.000000 +vn -0.140198 0.892897 0.427878 +v 159.973373 -147.180283 25.545597 1.000000 1.000000 1.000000 +vn 0.257725 0.627766 0.734499 +v 158.008667 -147.435623 26.240398 1.000000 1.000000 1.000000 +vn 0.099316 0.933900 0.343463 +v 158.698761 -147.282135 25.776398 1.000000 1.000000 1.000000 +vn 0.290536 0.843924 0.450978 +v 158.058884 -147.185852 25.892799 1.000000 1.000000 1.000000 +vn 0.409840 0.808608 0.422119 +v 157.438309 -146.993301 26.008999 1.000000 1.000000 1.000000 +vn 0.558559 0.695607 0.451822 +v 156.855087 -146.708649 26.124199 1.000000 1.000000 1.000000 +vn 0.467480 0.496653 0.731299 +v 156.743088 -146.934692 26.471798 1.000000 1.000000 1.000000 +vn 0.681155 0.662624 0.311380 +v 155.871460 -145.941223 26.342999 1.000000 1.000000 1.000000 +vn 0.578748 0.815477 0.006896 +v 156.473999 -146.228653 25.401999 1.000000 1.000000 1.000000 +vn 0.626735 0.313994 0.713170 +v 155.252182 -145.585403 26.806398 1.000000 1.000000 1.000000 +vn 0.771276 0.462747 0.437034 +v 155.436279 -145.426331 26.458799 1.000000 1.000000 1.000000 +vn 0.862862 0.387922 0.324015 +v 155.075790 -144.854248 26.573999 1.000000 1.000000 1.000000 +vn 0.283224 0.018811 0.958869 +v 155.059052 -145.751450 26.960999 1.000000 1.000000 1.000000 +vn 0.718861 0.695099 -0.008680 +v 155.992477 -145.801682 25.518599 1.000000 1.000000 1.000000 +vn 0.867897 0.494231 0.049908 +v 155.229004 -144.757980 25.749598 1.000000 1.000000 1.000000 +vn 0.892737 0.283172 0.350478 +v 154.789963 -144.227737 26.690199 1.000000 1.000000 1.000000 +vn 0.814836 0.396556 -0.422830 +v 154.777100 -144.233337 25.013599 1.000000 1.000000 1.000000 +vn 0.630911 0.261677 -0.730395 +v 154.345795 -143.640305 24.793598 1.000000 1.000000 1.000000 +vn 0.849769 0.248558 -0.464878 +v 154.576248 -143.576126 25.128199 1.000000 1.000000 1.000000 +vn 0.765378 0.107254 -0.634581 +v 154.201584 -142.186371 25.024199 1.000000 1.000000 1.000000 +vn 0.259301 0.123667 0.957846 +v 156.627213 -147.169113 26.626398 1.000000 1.000000 1.000000 +vn 0.198714 0.186750 0.962101 +v 157.958466 -147.697937 26.394999 1.000000 1.000000 1.000000 +vn -0.651144 0.252045 0.715880 +v 163.652985 -143.608215 24.981199 1.000000 1.000000 1.000000 +vn -0.124133 0.247468 0.960912 +v 163.359451 -145.097031 25.367199 1.000000 1.000000 1.000000 +vn -0.857284 0.282772 0.430237 +v 163.423813 -143.546814 24.633598 1.000000 1.000000 1.000000 +vn -0.940604 0.114157 0.319737 +v 163.534546 -142.856140 24.517199 1.000000 1.000000 1.000000 +vn -0.937425 0.057225 0.343452 +v 163.553848 -142.162659 24.401798 1.000000 1.000000 1.000000 +vn -0.911079 -0.092933 0.401621 +v 163.484329 -141.473358 24.286398 1.000000 1.000000 1.000000 +vn -0.707110 -0.003095 0.707097 +v 163.716080 -141.427307 24.634199 1.000000 1.000000 1.000000 +vn -0.909679 -0.225719 0.348619 +v 163.325974 -140.803604 24.171799 1.000000 1.000000 1.000000 +vn -0.886487 -0.331972 0.322391 +v 163.080063 -140.157547 24.055599 1.000000 1.000000 1.000000 +vn -0.646797 -0.273151 0.712069 +v 162.950027 -139.415237 24.287998 1.000000 1.000000 1.000000 +vn -0.259248 0.107650 0.959793 +v 163.959412 -141.378464 24.788799 1.000000 1.000000 1.000000 +vn -0.284216 -0.000984 0.958760 +v 163.153442 -139.264542 24.442598 1.000000 1.000000 1.000000 +vn -0.197484 0.191633 0.961393 +v 163.892456 -143.672409 25.135799 1.000000 1.000000 1.000000 +vn 0.774693 0.412922 0.478902 +v 164.169266 -139.658020 39.532341 1.000000 1.000000 1.000000 +vn 0.942904 0.298001 0.148753 +v 164.612167 -140.419876 39.179539 1.000000 1.000000 1.000000 +vn 0.895214 0.419822 0.149471 +v 164.305740 -139.586868 39.064140 1.000000 1.000000 1.000000 +vn 0.575883 0.287670 0.765248 +v 164.242661 -140.548248 39.985538 1.000000 1.000000 1.000000 +vn 0.840431 0.308271 0.445696 +v 164.467972 -140.470108 39.647739 1.000000 1.000000 1.000000 +vn 0.974082 0.170894 0.148188 +v 164.809158 -141.300339 39.295921 1.000000 1.000000 1.000000 +vn 0.858066 0.195760 0.474765 +v 164.659805 -141.328247 39.764320 1.000000 1.000000 1.000000 +vn 0.668483 0.105400 0.736221 +v 164.501434 -142.211487 40.218117 1.000000 1.000000 1.000000 +vn 0.318544 0.187328 0.929214 +v 164.206604 -141.410568 40.242519 1.000000 1.000000 1.000000 +vn 0.988336 0.041182 0.146613 +v 164.888977 -142.200333 39.412117 1.000000 1.000000 1.000000 +vn 0.891383 0.063921 0.448720 +v 164.738342 -142.204514 39.880318 1.000000 1.000000 1.000000 +vn 0.885321 -0.124307 0.448057 +v 164.573532 -143.838440 40.097717 1.000000 1.000000 1.000000 +vn 0.350082 0.096850 0.931699 +v 164.242661 -143.019394 40.473919 1.000000 1.000000 1.000000 +vn 0.658680 -0.044743 0.751092 +v 164.344376 -143.778442 40.435516 1.000000 1.000000 1.000000 +vn 0.983639 -0.080901 0.160963 +v 164.850342 -143.094742 39.527336 1.000000 1.000000 1.000000 +vn 0.967897 -0.203656 0.147309 +v 164.720322 -143.877518 39.629517 1.000000 1.000000 1.000000 +vn 0.844307 -0.247032 0.475522 +v 164.323776 -144.679840 40.214317 1.000000 1.000000 1.000000 +vn 0.933438 -0.326692 0.148212 +v 164.465393 -144.741226 39.746117 1.000000 1.000000 1.000000 +vn 0.336832 -0.022663 0.941292 +v 163.570587 -145.219818 40.808517 1.000000 1.000000 1.000000 +vn 0.646850 -0.232381 0.726350 +v 163.763718 -145.341217 40.667919 1.000000 1.000000 1.000000 +vn 0.880923 -0.449298 0.148680 +v 164.099747 -145.551926 39.861919 1.000000 1.000000 1.000000 +vn 0.815319 -0.368228 0.446837 +v 163.969711 -145.469589 40.330318 1.000000 1.000000 1.000000 +vn 0.915643 -0.364171 -0.170226 +v 164.452515 -144.735641 38.930519 1.000000 1.000000 1.000000 +vn 0.950407 -0.231744 -0.207417 +v 164.708725 -143.874725 38.813919 1.000000 1.000000 1.000000 +vn 0.857951 -0.483749 -0.172936 +v 164.089447 -145.544937 39.046516 1.000000 1.000000 1.000000 +vn 0.756311 -0.472017 -0.452982 +v 163.973572 -145.472382 38.653320 1.000000 1.000000 1.000000 +vn 0.817013 -0.353319 -0.455692 +v 164.330200 -144.682632 38.537518 1.000000 1.000000 1.000000 +vn 0.811908 -0.564228 0.149837 +v 163.636246 -146.292847 39.977119 1.000000 1.000000 1.000000 +vn 0.746461 -0.461451 0.479435 +v 163.517807 -146.192383 40.445320 1.000000 1.000000 1.000000 +vn 0.692975 -0.699211 -0.175753 +v 163.068466 -146.954224 39.277718 1.000000 1.000000 1.000000 +vn 0.783616 -0.596440 -0.173800 +v 163.627243 -146.284470 39.161518 1.000000 1.000000 1.000000 +vn 0.725966 -0.670672 0.152228 +v 163.077484 -146.963989 40.093338 1.000000 1.000000 1.000000 +vn 0.667553 -0.563223 -0.486984 +v 163.521667 -146.196564 38.768517 1.000000 1.000000 1.000000 +vn 0.541207 -0.418240 -0.729500 +v 163.768860 -145.344009 38.308918 1.000000 1.000000 1.000000 +vn 0.595308 -0.658204 -0.460842 +v 162.977066 -146.849579 38.884720 1.000000 1.000000 1.000000 +vn 0.394697 -0.538597 -0.744397 +v 162.812271 -146.664001 38.540119 1.000000 1.000000 1.000000 +vn 0.480738 -0.724907 -0.493357 +v 162.360367 -147.407700 38.999321 1.000000 1.000000 1.000000 +vn -0.059377 -0.306042 -0.950164 +v 160.766464 -147.727249 38.735321 1.000000 1.000000 1.000000 +vn 0.219525 -0.567021 -0.793912 +v 161.563416 -147.639328 38.770119 1.000000 1.000000 1.000000 +vn 0.586115 -0.790684 -0.176883 +v 162.437607 -147.523514 39.392540 1.000000 1.000000 1.000000 +vn 0.378838 -0.798292 -0.468201 +v 161.674133 -147.866776 39.114719 1.000000 1.000000 1.000000 +vn 0.110291 -0.654880 -0.747642 +v 160.848862 -147.979797 38.886520 1.000000 1.000000 1.000000 +vn -0.180745 -0.255284 -0.949822 +v 158.254578 -147.997940 39.119919 1.000000 1.000000 1.000000 +vn 0.117305 -0.857061 -0.501683 +v 160.140747 -148.457001 39.346321 1.000000 1.000000 1.000000 +vn -0.064401 -0.585325 -0.808237 +v 159.311600 -148.314682 39.115921 1.000000 1.000000 1.000000 +vn 0.255254 -0.844856 -0.470174 +v 160.927399 -148.221191 39.230919 1.000000 1.000000 1.000000 +vn 0.464809 -0.866817 -0.180502 +v 161.735931 -147.995148 39.507736 1.000000 1.000000 1.000000 +vn 0.329596 -0.926522 -0.181447 +v 160.972458 -148.357925 39.624119 1.000000 1.000000 1.000000 +vn -0.013220 -0.886235 -0.463046 +v 159.325775 -148.571411 39.460518 1.000000 1.000000 1.000000 +vn 0.185693 -0.965258 -0.183832 +v 160.167786 -148.599335 39.739319 1.000000 1.000000 1.000000 +vn -0.212069 -0.637597 -0.740605 +v 158.219818 -148.261658 39.271118 1.000000 1.000000 1.000000 +vn -0.229145 -0.231998 -0.945341 +v 156.806168 -147.534683 39.337540 1.000000 1.000000 1.000000 +vn -0.464187 -0.477012 -0.746318 +v 156.013077 -147.365845 39.593338 1.000000 1.000000 1.000000 +vn -0.189786 -0.859369 -0.474833 +v 158.185059 -148.515610 39.615517 1.000000 1.000000 1.000000 +vn -0.336945 -0.775316 -0.534184 +v 157.377808 -148.325836 39.725338 1.000000 1.000000 1.000000 +vn -0.048323 -0.974981 -0.216972 +v 159.002609 -148.724899 39.897720 1.000000 1.000000 1.000000 +vn -0.174686 -0.967811 -0.181179 +v 158.167038 -148.659332 40.008720 1.000000 1.000000 1.000000 +vn -0.320331 -0.930180 -0.179312 +v 157.340469 -148.463974 40.118519 1.000000 1.000000 1.000000 +vn -0.420487 -0.733003 -0.534693 +v 156.604034 -148.011902 39.832939 1.000000 1.000000 1.000000 +vn -0.128740 -0.978963 0.158297 +v 158.164459 -148.671890 40.824120 1.000000 1.000000 1.000000 +vn 0.081947 -0.996566 -0.011909 +v 159.336075 -148.765366 40.259117 1.000000 1.000000 1.000000 +vn -0.069018 -0.863370 0.499828 +v 158.186340 -148.510025 41.292519 1.000000 1.000000 1.000000 +vn 0.066860 -0.883579 0.463485 +v 159.002609 -148.574219 41.181519 1.000000 1.000000 1.000000 +vn -0.280904 -0.946649 0.157950 +v 157.336609 -148.476547 40.933918 1.000000 1.000000 1.000000 +vn 0.090374 -0.974780 0.204050 +v 159.333481 -148.729095 40.669121 1.000000 1.000000 1.000000 +vn 0.242691 -0.848379 0.470482 +v 160.139465 -148.451416 41.023319 1.000000 1.000000 1.000000 +vn 0.231401 -0.959968 0.157846 +v 160.170349 -148.611893 40.554916 1.000000 1.000000 1.000000 +vn 0.100569 -0.659854 0.744633 +v 159.002609 -148.317459 41.519318 1.000000 1.000000 1.000000 +vn 0.249437 -0.579123 0.776143 +v 160.093109 -148.200256 41.360916 1.000000 1.000000 1.000000 +vn 0.375256 -0.783838 0.494754 +v 160.926102 -148.215607 40.907921 1.000000 1.000000 1.000000 +vn 0.373711 -0.914188 0.156848 +v 160.976318 -148.370483 40.439518 1.000000 1.000000 1.000000 +vn 0.492274 -0.737424 0.462463 +v 161.671555 -147.861191 40.791718 1.000000 1.000000 1.000000 +vn 0.421264 -0.525298 0.739323 +v 161.560837 -147.633759 41.129318 1.000000 1.000000 1.000000 +vn 0.169011 -0.273574 0.946886 +v 159.300018 -148.066299 41.615719 1.000000 1.000000 1.000000 +vn 0.273216 -0.192318 0.942532 +v 161.456543 -147.420273 41.269920 1.000000 1.000000 1.000000 +vn 0.588758 -0.645231 0.486868 +v 162.356491 -147.402130 40.676319 1.000000 1.000000 1.000000 +vn 0.557089 -0.392443 0.731874 +v 162.808411 -146.659821 40.899319 1.000000 1.000000 1.000000 +vn 0.319374 -0.110427 0.941173 +v 162.653900 -146.485397 41.039917 1.000000 1.000000 1.000000 +vn 0.506119 -0.848293 0.155703 +v 161.742371 -148.007706 40.323318 1.000000 1.000000 1.000000 +vn 0.624268 -0.766036 0.153224 +v 162.445328 -147.534683 40.207916 1.000000 1.000000 1.000000 +vn 0.682947 -0.572327 0.453900 +v 162.971909 -146.845383 40.561520 1.000000 1.000000 1.000000 +vn -0.043532 0.269672 0.961968 +v 162.489105 -146.298416 41.043716 1.000000 1.000000 1.000000 +vn 0.077483 0.244216 0.966620 +v 160.691788 -147.501190 41.389919 1.000000 1.000000 1.000000 +vn 0.182783 0.207678 0.960968 +v 158.285492 -147.759338 41.774536 1.000000 1.000000 1.000000 +vn 0.226939 0.134319 0.964602 +v 156.898865 -147.317017 41.991920 1.000000 1.000000 1.000000 +vn 0.079443 -0.343914 0.935635 +v 158.252014 -148.016083 41.770737 1.000000 1.000000 1.000000 +vn -0.096298 -0.353762 0.930365 +v 156.137970 -147.156540 42.093117 1.000000 1.000000 1.000000 +vn 0.264541 0.081262 0.960945 +v 155.568893 -146.348648 42.222919 1.000000 1.000000 1.000000 +vn -0.125229 -0.279206 0.952030 +v 155.405396 -146.537018 42.219116 1.000000 1.000000 1.000000 +vn 0.262558 -0.004796 0.964904 +v 154.662506 -145.124954 42.422718 1.000000 1.000000 1.000000 +vn 0.557235 0.398166 0.728665 +v 155.736267 -146.153305 42.068336 1.000000 1.000000 1.000000 +vn -0.273461 -0.218976 0.936626 +v 154.121765 -144.522156 42.514919 1.000000 1.000000 1.000000 +vn -0.237846 -0.119345 0.963943 +v 153.732941 -142.111023 42.791538 1.000000 1.000000 1.000000 +vn 0.650551 0.242171 0.719817 +v 154.874939 -144.989609 42.268120 1.000000 1.000000 1.000000 +vn 0.196938 -0.149509 0.968949 +v 154.056107 -141.342194 42.883339 1.000000 1.000000 1.000000 +vn -0.355058 0.013081 0.934753 +v 154.014908 -140.504990 42.964737 1.000000 1.000000 1.000000 +vn 0.847933 0.186425 0.496241 +v 154.358658 -143.620773 42.457336 1.000000 1.000000 1.000000 +vn 0.108558 -0.188349 0.976084 +v 155.213547 -138.766403 43.189739 1.000000 1.000000 1.000000 +vn -0.339008 0.265321 0.902595 +v 155.302383 -138.130142 43.189739 1.000000 1.000000 1.000000 +vn -0.281554 0.385380 0.878754 +v 156.275726 -137.143631 43.189739 1.000000 1.000000 1.000000 +vn 0.203704 -0.391340 0.897417 +v 156.551254 -137.916656 43.189739 1.000000 1.000000 1.000000 +vn -0.199986 0.564219 0.801038 +v 157.364929 -136.476654 43.187340 1.000000 1.000000 1.000000 +vn 0.082477 -0.519909 0.850231 +v 158.020264 -137.435257 43.189739 1.000000 1.000000 1.000000 +vn 0.088964 0.622196 0.777790 +v 159.784119 -136.162720 43.189938 1.000000 1.000000 1.000000 +vn -0.040308 -0.547958 0.835534 +v 159.037369 -137.371063 43.189739 1.000000 1.000000 1.000000 +vn 0.356251 0.563225 0.745562 +v 162.083557 -137.012466 43.189720 1.000000 1.000000 1.000000 +vn -0.266363 -0.539970 0.798425 +v 160.819244 -137.895721 43.187317 1.000000 1.000000 1.000000 +vn -0.440879 -0.407988 0.799482 +v 162.089996 -138.847336 43.189140 1.000000 1.000000 1.000000 +vn 0.587392 0.426234 0.687964 +v 163.680038 -138.413391 43.189720 1.000000 1.000000 1.000000 +vn -0.564000 -0.121477 0.816791 +v 163.341431 -141.243118 43.189720 1.000000 1.000000 1.000000 +vn 0.741347 0.084219 0.665816 +v 164.892838 -141.600327 43.188519 1.000000 1.000000 1.000000 +vn -0.701418 0.095448 0.706330 +v 163.342712 -143.034744 43.187920 1.000000 1.000000 1.000000 +vn 0.738298 -0.136210 0.660577 +v 164.823318 -143.597061 43.188919 1.000000 1.000000 1.000000 +vn -0.648019 0.286195 0.705808 +v 162.901108 -144.566818 43.188721 1.000000 1.000000 1.000000 +vn 0.669094 -0.383683 0.636475 +v 164.074005 -145.751450 43.189720 1.000000 1.000000 1.000000 +vn -0.497047 0.499887 0.709266 +v 161.992142 -145.835175 43.189320 1.000000 1.000000 1.000000 +vn 0.521474 -0.617209 0.589167 +v 162.642319 -147.476089 43.185516 1.000000 1.000000 1.000000 +vn -0.769787 0.318281 0.553287 +v 160.515411 -146.828644 43.189537 1.000000 1.000000 1.000000 +vn -0.281072 -0.791290 0.543009 +v 161.045837 -148.397003 43.189720 1.000000 1.000000 1.000000 +vn 0.879710 0.260220 0.397990 +v 154.789963 -144.226349 42.016541 1.000000 1.000000 1.000000 +vn 0.816899 0.412987 0.402639 +v 155.078369 -144.859833 41.920517 1.000000 1.000000 1.000000 +vn 0.900336 0.162496 0.403720 +v 154.587845 -143.559387 42.109737 1.000000 1.000000 1.000000 +vn 0.879236 0.472971 0.056938 +v 155.230286 -144.763550 41.096336 1.000000 1.000000 1.000000 +vn 0.918052 0.022255 0.395834 +v 154.473251 -142.857529 42.202538 1.000000 1.000000 1.000000 +vn 0.830387 -0.053525 0.554610 +v 154.218323 -142.133347 42.640739 1.000000 1.000000 1.000000 +vn 0.965664 0.255490 0.047089 +v 154.759079 -143.511932 41.285339 1.000000 1.000000 1.000000 +vn 0.896245 -0.097497 0.432711 +v 154.453949 -142.144516 42.293137 1.000000 1.000000 1.000000 +vn 0.874106 -0.238557 0.423119 +v 154.529907 -141.439865 42.381138 1.000000 1.000000 1.000000 +vn 0.718816 -0.341846 0.605347 +v 154.474548 -140.675232 42.813938 1.000000 1.000000 1.000000 +vn 0.994845 0.101323 0.004010 +v 154.649628 -142.837997 41.378139 1.000000 1.000000 1.000000 +vn 0.827876 -0.410861 0.381857 +v 154.935455 -140.143600 42.544937 1.000000 1.000000 1.000000 +vn 0.999239 -0.039000 0.000200 +v 154.630325 -142.152878 41.468739 1.000000 1.000000 1.000000 +vn 0.956234 0.002244 -0.292594 +v 154.578827 -142.151489 41.013939 1.000000 1.000000 1.000000 +vn 0.966713 0.075014 -0.244619 +v 154.598145 -142.843582 40.923340 1.000000 1.000000 1.000000 +vn 0.982655 -0.153671 -0.103798 +v 154.703720 -141.474747 41.556938 1.000000 1.000000 1.000000 +vn 0.867179 -0.244468 -0.433861 +v 154.684387 -140.753357 40.789738 1.000000 1.000000 1.000000 +vn 0.895226 0.164738 -0.414044 +v 154.460373 -142.858932 40.525940 1.000000 1.000000 1.000000 +vn 0.536524 0.699107 -0.472643 +v 154.202881 -142.133347 40.281738 1.000000 1.000000 1.000000 +vn 0.779157 0.323552 -0.536870 +v 154.777100 -144.231918 40.339939 1.000000 1.000000 1.000000 +vn 0.834843 0.496949 -0.236812 +v 155.186523 -144.791458 40.641541 1.000000 1.000000 1.000000 +vn 0.721646 0.229480 -0.653120 +v 154.344498 -143.624954 40.098339 1.000000 1.000000 1.000000 +vn 0.338816 0.137943 -0.930685 +v 153.984009 -142.123581 40.145939 1.000000 1.000000 1.000000 +vn 0.183474 0.182935 -0.965853 +v 154.353516 -144.420303 39.869339 1.000000 1.000000 1.000000 +vn 0.849528 -0.479179 -0.220656 +v 155.375778 -139.607788 41.348339 1.000000 1.000000 1.000000 +vn 0.784724 -0.432430 -0.444086 +v 155.261200 -139.521286 40.950737 1.000000 1.000000 1.000000 +vn 0.753069 -0.618577 -0.224164 +v 155.778763 -139.069199 41.428539 1.000000 1.000000 1.000000 +vn 0.835636 -0.549281 0.001482 +v 155.416977 -139.639893 41.803139 1.000000 1.000000 1.000000 +vn 0.910091 -0.380385 0.164443 +v 155.093811 -140.230118 41.720539 1.000000 1.000000 1.000000 +vn 0.643886 -0.159752 -0.748258 +v 154.710144 -140.022202 40.533539 1.000000 1.000000 1.000000 +vn -0.103174 0.177168 -0.978758 +v 154.695984 -139.092911 40.475140 1.000000 1.000000 1.000000 +vn -0.103728 0.246367 -0.963610 +v 155.732407 -137.897125 40.633141 1.000000 1.000000 1.000000 +vn 0.528370 -0.326867 -0.783571 +v 155.503235 -138.788742 40.696339 1.000000 1.000000 1.000000 +vn 0.137713 -0.115954 -0.983661 +v 155.877899 -138.095261 40.638336 1.000000 1.000000 1.000000 +vn 0.336800 -0.562178 -0.755329 +v 157.202713 -137.532928 40.921940 1.000000 1.000000 1.000000 +vn 0.608713 -0.686137 -0.398352 +v 156.162430 -138.483154 41.108940 1.000000 1.000000 1.000000 +vn 0.398174 -0.778002 -0.485974 +v 157.291550 -137.771530 41.256737 1.000000 1.000000 1.000000 +vn 0.627435 -0.742530 -0.234468 +v 156.248688 -138.600357 41.506340 1.000000 1.000000 1.000000 +vn 0.224624 -0.248381 -0.942258 +v 157.120316 -137.312469 40.785938 1.000000 1.000000 1.000000 +vn 0.176174 -0.733016 -0.657001 +v 158.553284 -137.172928 41.063740 1.000000 1.000000 1.000000 +vn 0.002819 0.315382 -0.948961 +v 157.760193 -136.824097 40.852940 1.000000 1.000000 1.000000 +vn 0.079083 -0.227198 -0.970632 +v 159.258820 -136.918991 40.995537 1.000000 1.000000 1.000000 +vn -0.069925 -0.664979 -0.743581 +v 159.919296 -137.245499 41.194939 1.000000 1.000000 1.000000 +vn -0.021617 -0.883084 -0.468716 +v 159.235641 -137.414337 41.466141 1.000000 1.000000 1.000000 +vn 0.158174 -0.868765 -0.469285 +v 158.575165 -137.429672 41.398537 1.000000 1.000000 1.000000 +vn -0.003374 -0.236190 -0.971701 +v 160.663467 -137.217590 41.122337 1.000000 1.000000 1.000000 +vn -0.340498 -0.658535 -0.671114 +v 161.231247 -137.742233 41.319340 1.000000 1.000000 1.000000 +vn 0.251648 0.136605 -0.958130 +v 162.675797 -138.279434 41.294540 1.000000 1.000000 1.000000 +vn -0.084184 -0.193486 -0.977485 +v 162.513565 -138.459442 41.299538 1.000000 1.000000 1.000000 +vn -0.592657 -0.461807 -0.659918 +v 162.810974 -139.178040 41.488541 1.000000 1.000000 1.000000 +vn 0.195059 -0.011928 -0.980719 +v 164.138367 -141.125916 41.499920 1.000000 1.000000 1.000000 +vn -0.553598 -0.277245 -0.785280 +v 163.493347 -140.498016 41.592140 1.000000 1.000000 1.000000 +vn -0.774220 -0.450193 -0.444869 +v 162.988647 -139.937088 41.876137 1.000000 1.000000 1.000000 +vn -0.648486 -0.651997 -0.392895 +v 162.194275 -138.815247 41.770119 1.000000 1.000000 1.000000 +vn -0.909755 -0.379433 -0.168453 +v 163.140564 -140.644516 42.324341 1.000000 1.000000 1.000000 +vn -0.842799 -0.491028 -0.220412 +v 162.866333 -140.009659 42.273537 1.000000 1.000000 1.000000 +vn -0.614394 -0.787928 -0.041101 +v 161.573715 -138.516647 42.565536 1.000000 1.000000 1.000000 +vn -0.590814 -0.771940 -0.234623 +v 161.603317 -138.471985 42.110741 1.000000 1.000000 1.000000 +vn -0.558413 -0.738722 -0.377446 +v 161.684433 -138.350601 41.713341 1.000000 1.000000 1.000000 +vn -0.267938 -0.839082 -0.473445 +v 160.512817 -137.685028 41.592937 1.000000 1.000000 1.000000 +vn -0.484400 -0.874819 -0.006937 +v 161.032959 -138.153854 42.506340 1.000000 1.000000 1.000000 +vn -0.314585 -0.916108 -0.248560 +v 160.466476 -137.827347 41.990318 1.000000 1.000000 1.000000 +vn -0.192906 -0.981024 0.019457 +v 159.836899 -137.700363 42.381939 1.000000 1.000000 1.000000 +vn -0.053764 -0.963875 -0.260872 +v 159.227921 -137.565018 41.863739 1.000000 1.000000 1.000000 +vn 0.080360 -0.995832 0.043135 +v 158.593185 -137.634796 42.250938 1.000000 1.000000 1.000000 +vn 0.068145 -0.961977 -0.264494 +v 158.589325 -137.580368 41.796139 1.000000 1.000000 1.000000 +vn -0.227516 -0.963039 0.144194 +v 159.845901 -137.651535 42.812538 1.000000 1.000000 1.000000 +vn 0.288920 -0.955989 -0.051087 +v 157.968765 -137.750610 42.180939 1.000000 1.000000 1.000000 +vn 0.422557 -0.904830 0.052230 +v 157.362350 -137.962692 42.108940 1.000000 1.000000 1.000000 +vn -0.794119 -0.600709 0.092325 +v 162.471085 -139.461273 42.675518 1.000000 1.000000 1.000000 +vn -0.876872 -0.459953 -0.139784 +v 162.822571 -140.037552 42.728340 1.000000 1.000000 1.000000 +vn 0.431901 -0.872997 -0.226579 +v 157.343048 -137.911072 41.654137 1.000000 1.000000 1.000000 +vn 0.665343 -0.746343 -0.017064 +v 156.280884 -138.645004 41.961140 1.000000 1.000000 1.000000 +vn 0.356045 -0.875308 0.327213 +v 157.296707 -137.785492 42.933140 1.000000 1.000000 1.000000 +vn 0.431110 -0.780163 0.453310 +v 156.704453 -138.099442 42.859737 1.000000 1.000000 1.000000 +vn 0.483454 -0.692992 0.534822 +v 156.170151 -138.494308 42.785538 1.000000 1.000000 1.000000 +vn 0.655557 -0.665511 0.356848 +v 155.687347 -138.975708 42.707741 1.000000 1.000000 1.000000 +vn 0.622856 -0.435521 0.649901 +v 155.079666 -139.383148 42.975140 1.000000 1.000000 1.000000 +vn 0.718454 -0.539351 0.439232 +v 155.272781 -139.529663 42.627338 1.000000 1.000000 1.000000 +vn -0.878537 -0.194330 -0.436359 +v 163.463730 -141.287781 41.975719 1.000000 1.000000 1.000000 +vn -0.937797 -0.343655 -0.049377 +v 163.092941 -140.664063 42.779137 1.000000 1.000000 1.000000 +vn -0.090097 -0.615426 0.783029 +v 157.446045 -148.073288 41.739937 1.000000 1.000000 1.000000 +vn -0.204281 -0.599208 0.774093 +v 156.705734 -147.771896 41.847740 1.000000 1.000000 1.000000 +vn -0.211056 -0.858183 0.467951 +v 157.379089 -148.318863 41.402336 1.000000 1.000000 1.000000 +vn -0.358977 -0.802701 0.476242 +v 156.606613 -148.004913 41.509937 1.000000 1.000000 1.000000 +vn -0.409376 -0.545420 0.731388 +v 155.253464 -146.714233 42.078720 1.000000 1.000000 1.000000 +vn -0.567928 -0.678087 0.466537 +v 155.091248 -146.902603 41.740936 1.000000 1.000000 1.000000 +vn -0.532676 -0.811047 0.241784 +v 155.805786 -147.713287 41.146538 1.000000 1.000000 1.000000 +vn -0.422836 -0.892541 0.156779 +v 156.543518 -148.154221 41.041538 1.000000 1.000000 1.000000 +vn -0.460906 -0.869203 -0.179029 +v 156.548676 -148.141647 40.226139 1.000000 1.000000 1.000000 +vn -0.559796 -0.827542 -0.042448 +v 155.786484 -147.745377 40.736538 1.000000 1.000000 1.000000 +vn -0.687587 -0.708572 0.158587 +v 154.988235 -147.022598 41.272537 1.000000 1.000000 1.000000 +vn -0.582396 -0.689653 -0.430340 +v 155.884338 -147.580734 39.937939 1.000000 1.000000 1.000000 +vn -0.703936 -0.669681 -0.236647 +v 154.997253 -147.012833 40.457138 1.000000 1.000000 1.000000 +vn -0.802499 -0.571225 -0.172328 +v 154.420471 -146.338882 40.558140 1.000000 1.000000 1.000000 +vn -0.783581 -0.602491 0.151676 +v 154.410172 -146.348648 41.373737 1.000000 1.000000 1.000000 +vn -0.874253 -0.454182 -0.171467 +v 153.940231 -145.585403 40.656937 1.000000 1.000000 1.000000 +vn -0.860707 -0.486251 0.150809 +v 153.928650 -145.592392 41.472538 1.000000 1.000000 1.000000 +vn -0.667690 -0.562503 0.487628 +v 154.528610 -146.245392 41.841919 1.000000 1.000000 1.000000 +vn -0.503737 -0.384734 0.773453 +v 154.263397 -145.378891 42.278519 1.000000 1.000000 1.000000 +vn -0.759586 -0.468897 0.450738 +v 154.059982 -145.508652 41.940720 1.000000 1.000000 1.000000 +vn -0.919661 -0.363586 0.148425 +v 153.555283 -144.773315 41.568336 1.000000 1.000000 1.000000 +vn -0.928243 -0.330842 -0.170025 +v 153.568146 -144.767731 40.752937 1.000000 1.000000 1.000000 +vn -0.801732 -0.356285 0.479882 +v 153.695618 -144.711929 42.036739 1.000000 1.000000 1.000000 +vn -0.603544 -0.214451 0.767949 +v 153.672440 -143.807755 42.467739 1.000000 1.000000 1.000000 +vn -0.860654 -0.245884 0.445888 +v 153.441986 -143.870544 42.129936 1.000000 1.000000 1.000000 +vn -0.690537 -0.058884 0.720896 +v 153.510223 -142.101257 42.651138 1.000000 1.000000 1.000000 +vn -0.729965 -0.502806 -0.462966 +v 154.523453 -146.249588 40.165138 1.000000 1.000000 1.000000 +vn -0.581493 -0.341778 -0.738278 +v 154.708862 -146.089111 39.820538 1.000000 1.000000 1.000000 +vn -0.794605 -0.371245 -0.480395 +v 154.054825 -145.512848 40.263939 1.000000 1.000000 1.000000 +vn -0.260434 -0.097968 -0.960508 +v 155.416977 -146.524460 39.568539 1.000000 1.000000 1.000000 +vn 0.560937 -0.286314 -0.776772 +v 164.110046 -144.586349 38.192917 1.000000 1.000000 1.000000 +vn 0.664699 -0.187165 -0.723287 +v 164.470551 -143.047287 37.974121 1.000000 1.000000 1.000000 +vn 0.895257 -0.167474 -0.412877 +v 164.706146 -143.076599 38.318718 1.000000 1.000000 1.000000 +vn 0.985955 -0.009588 -0.166737 +v 164.876099 -142.200333 38.596519 1.000000 1.000000 1.000000 +vn 0.879002 -0.041827 -0.474979 +v 164.743484 -142.204514 38.203518 1.000000 1.000000 1.000000 +vn 0.693997 -0.003379 -0.719970 +v 164.431915 -141.370102 37.742718 1.000000 1.000000 1.000000 +vn 0.621927 0.095462 -0.777234 +v 164.247803 -140.546844 37.626339 1.000000 1.000000 1.000000 +vn 0.872962 0.195918 -0.446715 +v 164.473114 -140.468719 37.970940 1.000000 1.000000 1.000000 +vn 0.891761 0.080232 -0.445337 +v 164.666245 -141.326843 38.087318 1.000000 1.000000 1.000000 +vn 0.977040 0.129944 -0.168843 +v 164.797562 -141.303116 38.480518 1.000000 1.000000 1.000000 +vn 0.951003 0.258009 -0.170366 +v 164.600571 -140.424057 38.363937 1.000000 1.000000 1.000000 +vn 0.908831 0.380574 -0.170850 +v 164.294159 -139.592438 38.248539 1.000000 1.000000 1.000000 +vn 0.826441 0.298553 -0.477348 +v 164.174423 -139.655228 37.855537 1.000000 1.000000 1.000000 +vn 0.639493 0.253784 -0.725702 +v 163.577026 -139.038498 37.395737 1.000000 1.000000 1.000000 +vn -0.509489 -0.451618 -0.732436 +v 155.764603 -147.180283 19.086998 1.000000 1.000000 1.000000 +vn -0.326677 -0.000761 -0.945136 +v 154.482269 -145.265869 19.268799 1.000000 1.000000 1.000000 +vn -0.298576 -0.129200 -0.945600 +v 155.910080 -146.963989 18.935999 1.000000 1.000000 1.000000 +vn -0.341426 -0.576161 -0.742608 +v 157.133179 -147.968628 18.855598 1.000000 1.000000 1.000000 +vn -0.617138 -0.660854 -0.427098 +v 155.625549 -147.388168 19.431599 1.000000 1.000000 1.000000 +vn -0.491800 -0.717819 -0.492817 +v 156.309204 -147.852814 19.316399 1.000000 1.000000 1.000000 +vn -0.549023 -0.312026 -0.775380 +v 154.712723 -146.094711 19.303999 1.000000 1.000000 1.000000 +vn -0.237634 -0.203786 -0.949738 +v 157.216873 -147.717468 18.704597 1.000000 1.000000 1.000000 +vn -0.144272 -0.654087 -0.742534 +v 158.652405 -148.310486 18.623798 1.000000 1.000000 1.000000 +vn -0.146975 -0.237238 -0.960269 +v 158.667862 -148.043976 18.472797 1.000000 1.000000 1.000000 +vn -0.257537 -0.827688 -0.498606 +v 157.836151 -148.450027 19.083797 1.000000 1.000000 1.000000 +vn -0.110620 -0.870463 -0.479644 +v 158.636963 -148.567230 18.968399 1.000000 1.000000 1.000000 +vn 0.017264 -0.674575 -0.738004 +v 160.129150 -148.197464 18.402599 1.000000 1.000000 1.000000 +vn 0.116645 -0.891578 -0.437588 +v 160.178085 -148.450027 18.747200 1.000000 1.000000 1.000000 +vn -0.101868 -0.228361 -0.968233 +v 160.078949 -147.936539 18.251598 1.000000 1.000000 1.000000 +vn 0.277604 -0.831034 -0.481994 +v 160.947998 -148.214218 18.632797 1.000000 1.000000 1.000000 +vn 0.161499 -0.637908 -0.752989 +v 160.868164 -147.971420 18.288200 1.000000 1.000000 1.000000 +vn 0.310226 -0.932326 -0.185819 +v 160.993057 -148.349564 19.025997 1.000000 1.000000 1.000000 +vn 0.064715 -0.972994 -0.221572 +v 159.460953 -148.705368 19.245197 1.000000 1.000000 1.000000 +vn -0.093073 -0.978954 -0.181620 +v 158.627960 -148.710953 19.361397 1.000000 1.000000 1.000000 +vn 0.099794 -0.982482 0.157387 +v 159.462250 -148.719330 20.060799 1.000000 1.000000 1.000000 +vn 0.243535 -0.954561 0.171769 +v 160.207687 -148.604904 19.955799 1.000000 1.000000 1.000000 +vn -0.195296 -0.967801 0.158809 +v 157.806534 -148.604904 20.292400 1.000000 1.000000 1.000000 +vn -0.239885 -0.953803 -0.180870 +v 157.809113 -148.590942 19.476801 1.000000 1.000000 1.000000 +vn -0.046547 -0.986240 0.158631 +v 158.627960 -148.724899 20.176998 1.000000 1.000000 1.000000 +vn 0.170714 -0.858746 0.483128 +v 159.450653 -148.556076 20.528999 1.000000 1.000000 1.000000 +vn 0.336229 -0.757287 0.559881 +v 160.946716 -148.207245 20.309799 1.000000 1.000000 1.000000 +vn 0.370477 -0.914279 0.163831 +v 160.998215 -148.362122 19.841400 1.000000 1.000000 1.000000 +vn 0.190850 -0.639275 0.744919 +v 159.431335 -148.299332 20.866798 1.000000 1.000000 1.000000 +vn 0.407176 -0.485766 0.773459 +v 161.562119 -147.633759 20.535000 1.000000 1.000000 1.000000 +vn 0.009296 -0.866262 0.499504 +v 158.636963 -148.560257 20.645397 1.000000 1.000000 1.000000 +vn -0.128888 -0.873461 0.469525 +v 157.837448 -148.443054 20.760597 1.000000 1.000000 1.000000 +vn -0.031822 -0.647582 0.761331 +v 157.886368 -148.191895 21.098400 1.000000 1.000000 1.000000 +vn 0.121785 -0.335815 0.934022 +v 158.666580 -148.063522 21.123600 1.000000 1.000000 1.000000 +vn 0.250035 -0.349885 0.902808 +v 160.081512 -147.954681 20.902397 1.000000 1.000000 1.000000 +vn 0.015763 -0.354380 0.934969 +v 157.210434 -147.734222 21.355400 1.000000 1.000000 1.000000 +vn -0.238874 -0.610280 0.755313 +v 156.422501 -147.619797 21.330997 1.000000 1.000000 1.000000 +vn -0.250261 -0.830508 0.497621 +v 157.053360 -148.204437 20.877197 1.000000 1.000000 1.000000 +vn -0.338685 -0.927743 0.156798 +v 157.001862 -148.357925 20.408798 1.000000 1.000000 1.000000 +vn -0.473923 -0.866604 0.156185 +v 156.239670 -147.992355 20.524998 1.000000 1.000000 1.000000 +vn -0.396665 -0.786961 0.472598 +v 156.311768 -147.847244 20.993198 1.000000 1.000000 1.000000 +vn -0.380511 -0.907202 -0.179432 +v 157.007004 -148.345383 19.593399 1.000000 1.000000 1.000000 +vn -0.515013 -0.838090 -0.179909 +v 156.246109 -147.979797 19.709400 1.000000 1.000000 1.000000 +vn -0.381490 -0.797978 -0.466580 +v 157.052078 -148.210037 19.200199 1.000000 1.000000 1.000000 +vn -0.576229 -0.785432 0.225959 +v 155.539276 -147.516541 20.640198 1.000000 1.000000 1.000000 +vn -0.583627 -0.685927 0.434608 +v 155.087387 -146.898407 21.208797 1.000000 1.000000 1.000000 +vn -0.779174 -0.606513 0.158211 +v 154.414032 -146.354233 20.856998 1.000000 1.000000 1.000000 +vn -0.718214 -0.695286 0.027311 +v 154.959915 -147.046326 20.330399 1.000000 1.000000 1.000000 +vn -0.590386 -0.805710 -0.047698 +v 155.519974 -147.545837 20.230198 1.000000 1.000000 1.000000 +vn -0.376931 -0.521581 0.765426 +v 155.249603 -146.711441 21.546600 1.000000 1.000000 1.000000 +vn -0.661383 -0.571267 0.486032 +v 154.532471 -146.250977 21.325397 1.000000 1.000000 1.000000 +vn -0.083451 -0.334144 0.938820 +v 155.899780 -146.979340 21.586800 1.000000 1.000000 1.000000 +vn -0.190141 -0.259277 0.946901 +v 154.466812 -145.274246 21.919598 1.000000 1.000000 1.000000 +vn -0.540558 -0.412564 0.733204 +v 154.274979 -145.398438 21.778999 1.000000 1.000000 1.000000 +vn -0.752127 -0.480286 0.451255 +v 154.071564 -145.529587 21.441200 1.000000 1.000000 1.000000 +vn -0.857474 -0.491910 0.150872 +v 153.940231 -145.613312 20.973000 1.000000 1.000000 1.000000 +vn -0.589835 -0.263283 0.763399 +v 153.680161 -143.849609 22.010399 1.000000 1.000000 1.000000 +vn -0.795283 -0.372907 0.477980 +v 153.709778 -144.749603 21.556400 1.000000 1.000000 1.000000 +vn -0.281675 -0.157747 0.946454 +v 153.761276 -142.997055 22.266598 1.000000 1.000000 1.000000 +vn -0.674092 -0.156779 0.721817 +v 153.539825 -143.024963 22.125999 1.000000 1.000000 1.000000 +vn -0.855625 -0.264208 0.445085 +v 153.450989 -143.913788 21.672600 1.000000 1.000000 1.000000 +vn -0.915775 -0.373257 0.148447 +v 153.570724 -144.812378 21.088200 1.000000 1.000000 1.000000 +vn -0.705046 -0.657730 -0.265145 +v 154.993393 -147.008652 19.924999 1.000000 1.000000 1.000000 +vn -0.739354 -0.491051 -0.460679 +v 154.528610 -146.255173 19.648399 1.000000 1.000000 1.000000 +vn -0.808774 -0.559480 -0.181289 +v 154.424332 -146.345871 20.041599 1.000000 1.000000 1.000000 +vn -0.810198 -0.376206 -0.449498 +v 154.066406 -145.532379 19.764397 1.000000 1.000000 1.000000 +vn -0.652610 -0.220960 -0.724760 +v 154.269821 -145.401230 19.419800 1.000000 1.000000 1.000000 +vn -0.874460 -0.453545 -0.172094 +v 153.951813 -145.606323 20.157398 1.000000 1.000000 1.000000 +vn -0.841080 -0.255985 -0.476504 +v 153.704636 -144.750992 19.879597 1.000000 1.000000 1.000000 +vn -0.927437 -0.333126 -0.169964 +v 153.582321 -144.806808 20.272598 1.000000 1.000000 1.000000 +vn 0.306466 -0.189991 0.932729 +v 162.290833 -146.830048 20.525398 1.000000 1.000000 1.000000 +vn 0.106273 0.252542 0.961732 +v 160.033890 -147.702133 20.906197 1.000000 1.000000 1.000000 +vn 0.175057 0.217911 0.960141 +v 158.682022 -147.805389 21.127399 1.000000 1.000000 1.000000 +vn 0.546673 -0.357779 0.757062 +v 162.992508 -146.460281 20.276398 1.000000 1.000000 1.000000 +vn 0.515636 -0.718585 0.466642 +v 161.672836 -147.861191 20.197195 1.000000 1.000000 1.000000 +vn -0.179996 0.632310 0.753516 +v 161.232529 -146.952835 20.524799 1.000000 1.000000 1.000000 +vn 0.652302 -0.214729 0.726907 +v 163.871857 -145.130524 20.067600 1.000000 1.000000 1.000000 +vn 0.688214 -0.043943 0.724176 +v 164.388138 -143.566360 19.863400 1.000000 1.000000 1.000000 +vn 0.676548 0.127071 0.725352 +v 164.488571 -141.938004 19.670597 1.000000 1.000000 1.000000 +vn 0.851790 -0.223380 0.473872 +v 164.401016 -144.462158 19.627800 1.000000 1.000000 1.000000 +vn 0.882206 -0.001967 0.470859 +v 164.726746 -142.768219 19.427799 1.000000 1.000000 1.000000 +vn 0.888738 -0.118959 0.442712 +v 164.619888 -143.617981 19.525799 1.000000 1.000000 1.000000 +vn 0.852756 0.218845 0.474251 +v 164.616028 -141.071487 19.238998 1.000000 1.000000 1.000000 +vn 0.890056 0.106295 0.443285 +v 164.725464 -141.919861 19.332798 1.000000 1.000000 1.000000 +vn 0.980954 -0.161509 0.107904 +v 164.767944 -143.651474 19.057400 1.000000 1.000000 1.000000 +vn 0.992404 -0.061677 0.106441 +v 164.877380 -142.777985 18.959599 1.000000 1.000000 1.000000 +vn 0.944061 -0.295006 0.147381 +v 164.543930 -144.517975 19.159397 1.000000 1.000000 1.000000 +vn 0.897177 -0.416029 0.148301 +v 164.215622 -145.325867 19.261597 1.000000 1.000000 1.000000 +vn 0.934992 -0.310851 -0.170770 +v 164.531052 -144.512390 18.343998 1.000000 1.000000 1.000000 +vn 0.827000 -0.341874 0.446311 +v 164.081726 -145.250519 19.729797 1.000000 1.000000 1.000000 +vn 0.834207 -0.530748 0.149684 +v 163.792038 -146.069580 19.364597 1.000000 1.000000 1.000000 +vn 0.877289 -0.448239 -0.171596 +v 164.204041 -145.320297 18.445999 1.000000 1.000000 1.000000 +vn 0.763727 -0.434736 0.477206 +v 163.668442 -145.974701 19.833000 1.000000 1.000000 1.000000 +vn 0.755464 -0.637475 0.151326 +v 163.274475 -146.749115 19.470398 1.000000 1.000000 1.000000 +vn 0.808848 -0.561972 -0.173067 +v 163.780457 -146.062607 18.549198 1.000000 1.000000 1.000000 +vn 0.777786 -0.437076 -0.451678 +v 164.086868 -145.253311 18.052998 1.000000 1.000000 1.000000 +vn 0.664154 -0.536344 -0.520802 +v 163.673584 -145.978897 18.155998 1.000000 1.000000 1.000000 +vn 0.606387 -0.596957 -0.525297 +v 163.167618 -146.640274 18.261799 1.000000 1.000000 1.000000 +vn 0.725371 -0.665457 -0.176082 +v 163.264175 -146.739349 18.654999 1.000000 1.000000 1.000000 +vn 0.687952 -0.558102 0.463944 +v 163.163757 -146.636093 19.938795 1.000000 1.000000 1.000000 +vn 0.653236 -0.728681 0.205685 +v 162.671936 -147.349106 19.578800 1.000000 1.000000 1.000000 +vn 0.503910 -0.724332 -0.470550 +v 162.580521 -147.224930 18.370197 1.000000 1.000000 1.000000 +vn 0.620231 -0.762701 -0.183305 +v 162.664215 -147.337952 18.763199 1.000000 1.000000 1.000000 +vn 0.359328 -0.573026 -0.736562 +v 162.433746 -147.024002 18.025597 1.000000 1.000000 1.000000 +vn 0.554745 -0.386552 -0.736774 +v 163.877014 -145.133316 17.708397 1.000000 1.000000 1.000000 +vn 0.093268 -0.286313 -0.953586 +v 162.279251 -146.814697 17.874599 1.000000 1.000000 1.000000 +vn -0.022893 -0.251878 -0.967488 +v 161.450119 -147.402130 18.024799 1.000000 1.000000 1.000000 +vn 0.188710 -0.240650 -0.952090 +v 163.658142 -145.009140 17.557400 1.000000 1.000000 1.000000 +vn 0.651354 -0.213975 -0.727979 +v 164.393295 -143.566360 17.504398 1.000000 1.000000 1.000000 +vn 0.814368 -0.327429 -0.479160 +v 164.406174 -144.463547 17.950798 1.000000 1.000000 1.000000 +vn 0.064048 -0.185924 -0.980475 +v 164.151245 -143.513336 17.353201 1.000000 1.000000 1.000000 +vn 0.911206 -0.120215 -0.394019 +v 164.731903 -142.768219 17.750999 1.000000 1.000000 1.000000 +vn 0.909713 -0.199526 -0.364159 +v 164.625031 -143.619385 17.848797 1.000000 1.000000 1.000000 +vn 0.691416 -0.049640 -0.720749 +v 164.495010 -141.936600 17.311398 1.000000 1.000000 1.000000 +vn 0.985727 0.028015 -0.166006 +v 164.863220 -141.908707 18.049000 1.000000 1.000000 1.000000 +vn 0.895926 0.009686 -0.444097 +v 164.730606 -141.918472 17.655998 1.000000 1.000000 1.000000 +vn 0.985940 0.079947 0.146732 +v 164.876099 -141.907303 18.864597 1.000000 1.000000 1.000000 +vn 0.970839 0.162194 -0.176536 +v 164.751205 -141.040802 17.955200 1.000000 1.000000 1.000000 +vn 0.883494 0.132510 -0.449309 +v 164.621170 -141.070099 17.562000 1.000000 1.000000 1.000000 +vn 0.967068 0.203014 0.153510 +v 164.764084 -141.038010 18.770798 1.000000 1.000000 1.000000 +vn 0.636311 0.060401 -0.769064 +v 164.389435 -141.123123 17.217598 1.000000 1.000000 1.000000 +vn 0.272873 -0.091779 -0.957662 +v 164.249084 -141.956146 17.160397 1.000000 1.000000 1.000000 +vn 0.314665 0.003080 -0.949198 +v 163.811356 -140.052902 16.928799 1.000000 1.000000 1.000000 +vn 0.455488 -0.841560 -0.290359 +v 161.737228 -147.993759 18.913399 1.000000 1.000000 1.000000 +vn 0.500549 -0.865535 -0.017319 +v 161.759109 -148.039795 19.319000 1.000000 1.000000 1.000000 +vn 0.518203 -0.829958 0.206485 +v 161.743652 -148.006302 19.729000 1.000000 1.000000 1.000000 +vn 0.232012 0.163584 0.958859 +v 157.291550 -147.491440 21.359200 1.000000 1.000000 1.000000 +vn 0.274558 0.089240 0.957420 +v 156.040115 -146.770035 21.590599 1.000000 1.000000 1.000000 +vn 0.283629 -0.016671 0.958789 +v 154.672821 -145.143082 21.923397 1.000000 1.000000 1.000000 +vn 0.664484 0.231897 0.710412 +v 154.883957 -145.006332 21.768799 1.000000 1.000000 1.000000 +vn 0.251050 -0.124249 0.959967 +v 153.998169 -142.967758 22.270199 1.000000 1.000000 1.000000 +vn 0.904904 0.248172 0.345774 +v 154.800278 -144.257050 21.536198 1.000000 1.000000 1.000000 +vn 0.705368 -0.041116 0.707648 +v 154.244080 -142.938461 22.115799 1.000000 1.000000 1.000000 +vn 0.828445 0.384642 0.407098 +v 155.087387 -144.876572 21.421200 1.000000 1.000000 1.000000 +vn 0.183905 -0.204062 0.961529 +v 154.210602 -140.684982 22.617397 1.000000 1.000000 1.000000 +vn 0.633194 -0.293119 0.716343 +v 154.444931 -140.765930 22.462799 1.000000 1.000000 1.000000 +vn 0.105410 -0.254526 0.961304 +v 154.829895 -139.303604 22.848797 1.000000 1.000000 1.000000 +vn -0.374178 -0.031603 0.926818 +v 153.982727 -140.605453 22.613598 1.000000 1.000000 1.000000 +vn -0.360143 0.063824 0.930711 +v 154.632904 -139.158493 22.844997 1.000000 1.000000 1.000000 +vn 0.485009 -0.479715 0.731191 +v 155.034592 -139.452911 22.694199 1.000000 1.000000 1.000000 +vn -0.012832 -0.265642 0.963986 +v 156.292465 -137.757584 23.183399 1.000000 1.000000 1.000000 +vn 0.683640 -0.576424 0.447629 +v 155.230286 -139.596634 22.346600 1.000000 1.000000 1.000000 +vn 0.799035 -0.443212 0.406333 +v 154.909714 -140.196625 22.231400 1.000000 1.000000 1.000000 +vn 0.281171 -0.622350 0.730495 +v 156.425079 -137.983627 23.028797 1.000000 1.000000 1.000000 +vn -0.127525 -0.235648 0.963435 +v 158.270035 -136.958054 23.529598 1.000000 1.000000 1.000000 +vn -0.020476 -0.680529 0.732435 +v 158.306076 -137.221771 23.375000 1.000000 1.000000 1.000000 +vn 0.644704 -0.697115 0.313667 +v 156.036255 -138.614319 22.565399 1.000000 1.000000 1.000000 +vn 0.345647 -0.874063 0.341382 +v 157.113876 -137.867813 22.796398 1.000000 1.000000 1.000000 +vn 0.434567 -0.779440 0.451247 +v 156.552536 -138.198502 22.681198 1.000000 1.000000 1.000000 +vn 0.906476 -0.421021 0.032279 +v 155.069351 -140.280350 21.406998 1.000000 1.000000 1.000000 +vn 0.800219 -0.599679 0.005912 +v 155.709229 -139.235245 21.624397 1.000000 1.000000 1.000000 +vn 0.678295 -0.734740 -0.008536 +v 156.150833 -138.759430 21.740997 1.000000 1.000000 1.000000 +vn 0.462272 -0.885216 0.051939 +v 157.187256 -138.042221 21.972000 1.000000 1.000000 1.000000 +vn 0.226271 -0.900141 0.372221 +v 157.718994 -137.623642 22.912598 1.000000 1.000000 1.000000 +vn 0.581050 -0.708704 -0.400150 +v 156.544800 -138.185959 21.004597 1.000000 1.000000 1.000000 +vn 0.359527 -0.821414 -0.442742 +v 157.715134 -137.609680 21.236000 1.000000 1.000000 1.000000 +vn 0.843612 -0.482632 -0.235343 +v 155.334579 -139.671982 21.067398 1.000000 1.000000 1.000000 +vn 0.607094 -0.559103 -0.564659 +v 156.027252 -138.603149 20.888798 1.000000 1.000000 1.000000 +vn 0.412686 -0.609920 -0.676526 +v 157.009583 -137.619446 20.785000 1.000000 1.000000 1.000000 +vn 0.619601 -0.395227 -0.678152 +v 155.387360 -138.929657 20.437399 1.000000 1.000000 1.000000 +vn 0.795522 -0.397789 -0.457065 +v 155.218704 -139.588257 20.669998 1.000000 1.000000 1.000000 +vn 0.935667 -0.276711 -0.218995 +v 154.788681 -140.885925 20.836197 1.000000 1.000000 1.000000 +vn 0.254730 -0.079034 -0.963777 +v 156.298904 -137.768738 20.533997 1.000000 1.000000 1.000000 +vn 0.291196 -0.007009 -0.956638 +v 154.840179 -139.310593 20.199398 1.000000 1.000000 1.000000 +vn 0.676301 -0.178136 -0.714762 +v 154.683105 -140.076630 20.219997 1.000000 1.000000 1.000000 +vn 0.875412 -0.201163 -0.439532 +v 154.656082 -140.839874 20.438599 1.000000 1.000000 1.000000 +vn 0.278853 0.073701 -0.957501 +v 154.220917 -140.687790 19.967999 1.000000 1.000000 1.000000 +vn 0.773762 0.013060 -0.633342 +v 154.267258 -141.478928 19.987400 1.000000 1.000000 1.000000 +vn 0.905151 -0.042119 -0.422999 +v 154.502869 -141.523590 20.322195 1.000000 1.000000 1.000000 +vn 0.917918 0.128248 -0.375472 +v 154.464233 -142.911942 20.091400 1.000000 1.000000 1.000000 +vn 0.706795 0.300530 -0.640408 +v 154.352234 -143.662628 19.641197 1.000000 1.000000 1.000000 +vn 0.967302 0.063496 -0.245551 +v 154.603287 -142.895203 20.488998 1.000000 1.000000 1.000000 +vn 0.990489 -0.137289 0.009169 +v 154.689545 -141.558472 21.174400 1.000000 1.000000 1.000000 +vn 0.996205 0.085772 0.014789 +v 154.653503 -142.888229 20.943798 1.000000 1.000000 1.000000 +vn 0.964215 0.261342 0.044610 +v 154.766800 -143.545425 20.828197 1.000000 1.000000 1.000000 +vn 0.960386 -0.278620 0.005449 +v 154.837616 -140.904068 21.291000 1.000000 1.000000 1.000000 +vn 0.837024 -0.337049 0.431031 +v 154.668961 -140.844070 22.115200 1.000000 1.000000 1.000000 +vn 0.930773 -0.174286 0.321383 +v 154.515732 -141.524979 21.998798 1.000000 1.000000 1.000000 +vn 0.931130 -0.111712 0.347157 +v 154.451355 -142.215668 21.883400 1.000000 1.000000 1.000000 +vn 0.904561 0.010727 0.426209 +v 154.478409 -142.910553 21.767998 1.000000 1.000000 1.000000 +vn 0.926402 0.194161 0.322615 +v 154.595551 -143.594269 21.652397 1.000000 1.000000 1.000000 +vn 0.887246 0.459911 0.035729 +v 155.239304 -144.778900 20.596798 1.000000 1.000000 1.000000 +vn 0.723368 0.278591 -0.631764 +v 154.582687 -143.597061 19.975800 1.000000 1.000000 1.000000 +vn 0.881231 0.423666 -0.209617 +v 155.195526 -144.806808 20.141998 1.000000 1.000000 1.000000 +vn 0.194755 0.162689 -0.967266 +v 154.011047 -142.966354 19.620800 1.000000 1.000000 1.000000 +vn 0.197417 -0.218190 -0.955730 +v 158.271317 -136.970612 20.879997 1.000000 1.000000 1.000000 +vn 0.089546 -0.257776 -0.962046 +v 160.380219 -137.121307 21.227200 1.000000 1.000000 1.000000 +vn 0.039128 -0.745340 -0.665535 +v 159.652786 -137.198059 21.246597 1.000000 1.000000 1.000000 +vn 0.223497 -0.622825 -0.749758 +v 158.303513 -137.205032 21.015999 1.000000 1.000000 1.000000 +vn 0.191228 -0.850523 -0.489942 +v 158.338272 -137.460373 21.350597 1.000000 1.000000 1.000000 +vn -0.015609 -0.892463 -0.450851 +v 159.620590 -137.453400 21.581398 1.000000 1.000000 1.000000 +vn -0.174004 -0.651160 -0.738724 +v 160.959579 -137.601303 21.479198 1.000000 1.000000 1.000000 +vn -0.198426 -0.862055 -0.466357 +v 160.255325 -137.597122 21.697800 1.000000 1.000000 1.000000 +vn 0.163589 -0.956932 -0.239832 +v 158.358871 -137.609680 21.748199 1.000000 1.000000 1.000000 +vn 0.285126 -0.913075 -0.291544 +v 157.753754 -137.753387 21.633400 1.000000 1.000000 1.000000 +vn 0.140988 -0.988711 0.050718 +v 158.366592 -137.664093 22.202999 1.000000 1.000000 1.000000 +vn -0.124234 -0.992203 0.009972 +v 159.594849 -137.658508 22.433598 1.000000 1.000000 1.000000 +vn -0.286602 -0.929199 -0.233343 +v 160.216705 -137.742233 22.095398 1.000000 1.000000 1.000000 +vn -0.415656 -0.775929 -0.474515 +v 161.429520 -138.163620 21.929199 1.000000 1.000000 1.000000 +vn -0.512022 -0.823732 -0.243513 +v 161.354828 -138.291992 22.326599 1.000000 1.000000 1.000000 +vn -0.447633 -0.893572 0.033972 +v 160.785782 -138.025482 22.666199 1.000000 1.000000 1.000000 +vn -0.287849 -0.957656 0.006178 +v 160.202545 -137.795258 22.550198 1.000000 1.000000 1.000000 +vn -0.586031 -0.580101 -0.565730 +v 162.364227 -139.005005 22.147999 1.000000 1.000000 1.000000 +vn -0.412545 -0.596028 -0.688882 +v 162.042358 -138.324097 21.696598 1.000000 1.000000 1.000000 +vn -0.735014 -0.553268 -0.391981 +v 162.767197 -139.551987 22.263798 1.000000 1.000000 1.000000 +vn -0.633994 -0.773308 0.006899 +v 161.770691 -138.682693 22.883598 1.000000 1.000000 1.000000 +vn 0.002607 -0.271131 -0.962539 +v 161.671555 -137.743637 21.458599 1.000000 1.000000 1.000000 +vn -0.076861 -0.239296 -0.967900 +v 163.143143 -139.271530 21.793198 1.000000 1.000000 1.000000 +vn 0.327356 0.021781 -0.944650 +v 163.336273 -139.127792 21.788200 1.000000 1.000000 1.000000 +vn 0.288886 0.148899 -0.945714 +v 161.795151 -137.530151 21.453400 1.000000 1.000000 1.000000 +vn 0.306703 -0.103394 -0.946173 +v 164.176987 -141.335220 22.134197 1.000000 1.000000 1.000000 +vn 0.233969 -0.199237 -0.951611 +v 164.107468 -143.731003 22.481400 1.000000 1.000000 1.000000 +vn 0.171992 -0.258770 -0.950504 +v 163.551270 -145.217026 22.712597 1.000000 1.000000 1.000000 +vn 0.225570 0.212884 -0.950683 +v 160.444595 -136.877121 21.222198 1.000000 1.000000 1.000000 +vn 0.120296 0.287213 -0.950283 +v 158.237839 -136.719452 20.875000 1.000000 1.000000 1.000000 +vn -0.764384 -0.644704 -0.008562 +v 162.223892 -139.144547 23.000198 1.000000 1.000000 1.000000 +vn -0.606017 -0.656518 0.449141 +v 161.421783 -138.176178 23.605799 1.000000 1.000000 1.000000 +vn -0.725265 -0.614580 0.310293 +v 162.355209 -139.014771 23.824598 1.000000 1.000000 1.000000 +vn -0.467010 -0.778225 0.419843 +v 160.857880 -137.849670 23.490597 1.000000 1.000000 1.000000 +vn -0.501808 -0.464970 0.729377 +v 161.546677 -137.959900 23.953398 1.000000 1.000000 1.000000 +vn -0.302820 -0.609177 0.732942 +v 160.315842 -137.365494 23.721998 1.000000 1.000000 1.000000 +vn -0.351264 -0.821074 0.449945 +v 160.251465 -137.611069 23.374397 1.000000 1.000000 1.000000 +vn -0.168862 -0.923009 0.345746 +v 159.618027 -137.468750 23.257999 1.000000 1.000000 1.000000 +vn -0.100478 -0.923668 0.369786 +v 158.979446 -137.422699 23.142597 1.000000 1.000000 1.000000 +vn 0.074168 -0.900683 0.428100 +v 158.340851 -137.474335 23.027199 1.000000 1.000000 1.000000 +vn -0.267317 -0.106410 0.957715 +v 161.677994 -137.733856 24.107998 1.000000 1.000000 1.000000 +vn -0.212081 -0.174430 0.961559 +v 160.384079 -137.108749 23.876598 1.000000 1.000000 1.000000 +vn -0.800397 -0.411419 0.436003 +v 162.755615 -139.560349 23.940399 1.000000 1.000000 1.000000 +vn -0.310607 0.200160 0.929225 +v 156.163712 -137.539902 23.179798 1.000000 1.000000 1.000000 +vn 0.475782 0.484604 -0.734024 +v 161.926468 -137.304092 21.604597 1.000000 1.000000 1.000000 +vn 0.311078 0.598195 -0.738508 +v 160.511536 -136.620392 21.373199 1.000000 1.000000 1.000000 +vn 0.526374 0.346685 -0.776363 +v 163.054321 -138.317108 21.823399 1.000000 1.000000 1.000000 +vn 0.568912 0.701976 -0.428449 +v 162.052643 -137.086426 21.948997 1.000000 1.000000 1.000000 +vn 0.438306 0.750325 -0.494873 +v 161.340683 -136.674805 21.833797 1.000000 1.000000 1.000000 +vn 0.178950 0.581801 -0.793401 +v 159.746780 -136.447372 21.256798 1.000000 1.000000 1.000000 +vn 0.026785 0.664567 -0.746748 +v 158.201797 -136.455734 21.025997 1.000000 1.000000 1.000000 +vn 0.065428 0.863564 -0.499977 +v 158.972992 -136.136200 21.485798 1.000000 1.000000 1.000000 +vn 0.194288 0.860935 -0.470153 +v 159.778961 -136.193420 21.601200 1.000000 1.000000 1.000000 +vn -0.096323 0.599289 -0.794717 +v 157.449905 -136.635742 20.911400 1.000000 1.000000 1.000000 +vn -0.072865 0.878970 -0.471277 +v 158.167038 -136.201782 21.370598 1.000000 1.000000 1.000000 +vn -0.204643 0.857895 -0.471314 +v 157.382950 -136.388763 21.255798 1.000000 1.000000 1.000000 +vn -0.268187 0.612781 -0.743354 +v 156.040115 -137.330612 20.680000 1.000000 1.000000 1.000000 +vn -0.017601 0.306254 -0.951787 +v 156.172729 -137.555252 20.528999 1.000000 1.000000 1.000000 +vn -0.321189 0.805511 -0.497986 +v 156.622055 -136.697128 21.139599 1.000000 1.000000 1.000000 +vn -0.412927 0.892821 -0.179895 +v 156.566696 -136.565964 21.532799 1.000000 1.000000 1.000000 +vn -0.275398 0.944215 -0.180594 +v 157.345627 -136.250626 21.648998 1.000000 1.000000 1.000000 +vn -0.129403 0.974852 -0.181435 +v 158.147720 -136.059464 21.763599 1.000000 1.000000 1.000000 +vn -0.455555 0.876573 0.155207 +v 156.561539 -136.553406 22.348198 1.000000 1.000000 1.000000 +vn -0.176535 0.971646 0.157287 +v 158.146439 -136.045502 22.579197 1.000000 1.000000 1.000000 +vn -0.320784 0.933982 0.157399 +v 157.341766 -136.238068 22.464397 1.000000 1.000000 1.000000 +vn -0.538809 0.823396 -0.178057 +v 155.841843 -136.992935 21.417599 1.000000 1.000000 1.000000 +vn -0.449559 0.762666 -0.465014 +v 155.912659 -137.114334 21.024399 1.000000 1.000000 1.000000 +vn -0.652992 0.736311 -0.177335 +v 155.174927 -137.528748 21.301800 1.000000 1.000000 1.000000 +vn -0.578318 0.801078 0.154349 +v 155.834122 -136.981766 22.233200 1.000000 1.000000 1.000000 +vn -0.564863 0.678370 -0.469834 +v 155.262482 -137.638977 20.908600 1.000000 1.000000 1.000000 +vn -0.688125 0.709453 0.152188 +v 155.167206 -137.518982 22.117199 1.000000 1.000000 1.000000 +vn -0.778462 0.609357 0.150603 +v 154.573669 -138.158035 22.000599 1.000000 1.000000 1.000000 +vn -0.749245 0.626778 -0.213967 +v 154.582687 -138.166412 21.185200 1.000000 1.000000 1.000000 +vn -0.650661 0.607661 0.455399 +v 155.265060 -137.643173 22.585598 1.000000 1.000000 1.000000 +vn -0.549770 0.677388 0.488772 +v 155.916519 -137.119919 22.701397 1.000000 1.000000 1.000000 +vn -0.737955 0.496620 0.456937 +v 154.686981 -138.265488 22.468998 1.000000 1.000000 1.000000 +vn -0.850267 0.500231 0.163754 +v 154.125626 -138.787338 21.898399 1.000000 1.000000 1.000000 +vn -0.726325 0.541884 -0.422864 +v 154.246658 -138.876633 20.689800 1.000000 1.000000 1.000000 +vn -0.884364 0.434608 -0.170341 +v 153.722656 -139.568726 20.967800 1.000000 1.000000 1.000000 +vn -0.830223 0.325405 0.452594 +v 153.847534 -139.635696 22.251598 1.000000 1.000000 1.000000 +vn -0.909367 0.388379 0.149044 +v 153.711060 -139.563141 21.783199 1.000000 1.000000 1.000000 +vn -0.572136 0.318407 0.755829 +v 154.865936 -138.434311 22.806599 1.000000 1.000000 1.000000 +vn -0.648864 0.190603 0.736645 +v 154.059982 -139.747330 22.589397 1.000000 1.000000 1.000000 +vn -0.859581 0.190243 0.474266 +v 153.544983 -140.451965 22.135399 1.000000 1.000000 1.000000 +vn -0.953245 0.263478 0.147994 +v 153.400787 -140.401733 21.667000 1.000000 1.000000 1.000000 +vn -0.938040 0.301866 -0.170173 +v 153.412369 -140.405930 20.851597 1.000000 1.000000 1.000000 +vn -0.770938 0.415967 -0.482314 +v 153.842377 -139.632904 20.574600 1.000000 1.000000 1.000000 +vn -0.838159 0.310226 -0.448608 +v 153.538544 -140.450577 20.458397 1.000000 1.000000 1.000000 +vn -0.969760 0.175128 -0.169990 +v 153.214096 -141.283585 20.735197 1.000000 1.000000 1.000000 +vn -0.979725 0.135990 0.147127 +v 153.201218 -141.282196 21.550598 1.000000 1.000000 1.000000 +vn -0.892492 0.083117 0.443340 +v 153.350571 -141.310104 22.018997 1.000000 1.000000 1.000000 +vn -0.649391 -0.011449 0.760369 +v 153.584885 -141.353363 22.356598 1.000000 1.000000 1.000000 +vn -0.880406 -0.037949 0.472699 +v 153.270737 -142.179398 21.903599 1.000000 1.000000 1.000000 +vn -0.984458 0.048062 -0.168915 +v 153.132980 -142.175201 20.619797 1.000000 1.000000 1.000000 +vn -0.989197 0.007409 0.146407 +v 153.120117 -142.175201 21.435200 1.000000 1.000000 1.000000 +vn -0.872389 0.197021 -0.447348 +v 153.345428 -141.308716 20.341999 1.000000 1.000000 1.000000 +vn -0.876037 0.085461 -0.474611 +v 153.265594 -142.179398 20.226597 1.000000 1.000000 1.000000 +vn -0.982477 -0.080125 -0.168285 +v 153.166458 -143.069626 20.504398 1.000000 1.000000 1.000000 +vn -0.981701 -0.120643 0.147340 +v 153.153580 -143.071014 21.320000 1.000000 1.000000 1.000000 +vn -0.963234 -0.208551 -0.169374 +v 153.317093 -143.951462 20.388798 1.000000 1.000000 1.000000 +vn -0.957195 -0.248879 0.147774 +v 153.304214 -143.955658 21.204399 1.000000 1.000000 1.000000 +vn -0.895505 -0.034944 -0.443678 +v 153.297775 -143.054276 20.111397 1.000000 1.000000 1.000000 +vn -0.689247 0.046614 -0.723026 +v 153.533386 -143.024963 19.766800 1.000000 1.000000 1.000000 +vn -0.882480 -0.151430 -0.445306 +v 153.445847 -143.916580 19.995800 1.000000 1.000000 1.000000 +vn -0.626188 -0.063868 -0.777052 +v 153.675018 -143.851013 19.651199 1.000000 1.000000 1.000000 +vn -0.297229 0.122262 -0.946946 +v 153.779297 -142.995667 19.615799 1.000000 1.000000 1.000000 +vn -0.218601 0.213161 -0.952248 +v 153.999451 -140.611038 19.962997 1.000000 1.000000 1.000000 +vn 0.144019 0.253505 -0.956553 +v 154.683105 -145.136108 19.273998 1.000000 1.000000 1.000000 +vn -0.600599 0.178993 -0.779258 +v 153.579742 -141.351959 19.997597 1.000000 1.000000 1.000000 +vn -0.619402 0.300315 -0.725364 +v 153.765137 -140.528717 20.113998 1.000000 1.000000 1.000000 +vn -0.153155 0.269381 -0.950777 +v 154.647064 -139.169662 20.194199 1.000000 1.000000 1.000000 +vn -0.504992 0.455787 -0.732967 +v 154.442352 -139.020370 20.345398 1.000000 1.000000 1.000000 +vn -0.364025 0.502255 -0.784364 +v 155.416977 -137.832932 20.563999 1.000000 1.000000 1.000000 +vn -0.021531 0.245633 -0.969124 +v 156.047852 -146.760269 18.940998 1.000000 1.000000 1.000000 +vn -0.024729 0.374093 -0.927061 +v 157.295410 -147.478867 18.709797 1.000000 1.000000 1.000000 +vn 0.449443 0.573248 -0.685119 +v 155.722107 -146.163071 19.177200 1.000000 1.000000 1.000000 +vn -0.070768 0.148644 -0.986355 +v 158.683319 -147.791428 18.477997 1.000000 1.000000 1.000000 +vn -0.387749 0.419846 -0.820597 +v 161.240250 -146.968185 18.165798 1.000000 1.000000 1.000000 +vn -0.222307 0.602646 -0.766419 +v 159.377274 -147.550034 18.497597 1.000000 1.000000 1.000000 +vn -0.716736 0.494877 -0.491311 +v 162.489105 -145.942612 17.907200 1.000000 1.000000 1.000000 +vn 0.472069 0.743341 -0.473915 +v 156.315643 -146.359818 19.411598 1.000000 1.000000 1.000000 +vn 0.530003 0.419398 -0.737023 +v 154.871078 -145.014709 19.409798 1.000000 1.000000 1.000000 +vn 0.680881 0.610495 -0.404595 +v 155.442734 -145.458435 19.628597 1.000000 1.000000 1.000000 +vn 0.203620 0.803787 -0.558986 +v 157.451187 -147.012833 19.180399 1.000000 1.000000 1.000000 +vn -0.027445 0.880995 -0.472328 +v 158.711639 -147.297485 18.948595 1.000000 1.000000 1.000000 +vn 0.304745 0.923970 -0.231107 +v 157.498840 -146.871902 19.577797 1.000000 1.000000 1.000000 +vn 0.039560 0.972113 -0.231151 +v 158.720657 -147.146790 19.345997 1.000000 1.000000 1.000000 +vn -0.298145 0.851109 -0.432114 +v 159.937317 -147.203995 18.727398 1.000000 1.000000 1.000000 +vn -0.255062 0.934962 -0.246556 +v 159.908997 -147.056091 19.124798 1.000000 1.000000 1.000000 +vn -0.488663 0.726660 -0.482881 +v 161.129532 -146.740738 18.500599 1.000000 1.000000 1.000000 +vn -0.504673 0.841297 -0.193715 +v 161.065155 -146.606781 18.897999 1.000000 1.000000 1.000000 +vn -0.333587 0.942239 0.030091 +v 160.487076 -146.821671 19.465199 1.000000 1.000000 1.000000 +vn -0.123866 0.992281 0.005888 +v 159.345078 -147.088181 19.684599 1.000000 1.000000 1.000000 +vn -0.651289 0.758824 -0.003087 +v 161.730774 -146.068192 19.202599 1.000000 1.000000 1.000000 +vn -0.612968 0.746700 -0.258284 +v 161.762970 -146.112839 18.747799 1.000000 1.000000 1.000000 +vn -0.455260 0.872351 0.178165 +v 161.062576 -146.601212 19.783398 1.000000 1.000000 1.000000 +vn -0.634504 0.648792 -0.420088 +v 161.849228 -146.230057 18.350197 1.000000 1.000000 1.000000 +vn -0.784099 0.619614 -0.035600 +v 162.178833 -145.623077 19.094200 1.000000 1.000000 1.000000 +vn -0.684663 0.496963 -0.533165 +v 162.316589 -145.765411 18.241997 1.000000 1.000000 1.000000 +vn -0.832002 0.507907 -0.223167 +v 162.604980 -145.150055 18.533600 1.000000 1.000000 1.000000 +vn -0.897111 0.434460 0.080225 +v 162.879211 -144.565414 18.885399 1.000000 1.000000 1.000000 +vn -0.526859 0.742819 0.413085 +v 161.841507 -146.218887 20.026798 1.000000 1.000000 1.000000 +vn -0.544905 0.802557 0.242860 +v 161.759109 -146.107254 19.633198 1.000000 1.000000 1.000000 +vn -0.952321 0.305031 -0.006370 +v 163.122543 -143.964035 18.783199 1.000000 1.000000 1.000000 +vn -0.718839 0.561785 0.409473 +v 162.707977 -145.229599 19.812798 1.000000 1.000000 1.000000 +vn -0.576987 0.636679 0.511592 +v 162.307571 -145.754242 19.918598 1.000000 1.000000 1.000000 +vn -0.571983 0.569311 0.590525 +v 162.477524 -145.931442 20.266197 1.000000 1.000000 1.000000 +vn -0.567315 0.402821 0.718254 +v 163.243576 -144.773315 20.057400 1.000000 1.000000 1.000000 +vn -0.775353 0.456832 0.436043 +v 163.034988 -144.654709 19.709599 1.000000 1.000000 1.000000 +vn -0.658415 0.228410 0.717160 +v 163.694183 -143.410080 19.853201 1.000000 1.000000 1.000000 +vn -0.844581 0.355867 0.400052 +v 163.288635 -144.028214 19.607597 1.000000 1.000000 1.000000 +vn -0.984519 0.169071 0.046243 +v 163.289917 -143.319382 18.681198 1.000000 1.000000 1.000000 +vn -0.887409 0.222042 0.403983 +v 163.462448 -143.358444 19.505600 1.000000 1.000000 1.000000 +vn -0.698576 0.040862 0.714368 +v 163.781738 -141.992416 19.660397 1.000000 1.000000 1.000000 +vn -0.909485 0.125122 0.396462 +v 163.547424 -142.683121 19.407597 1.000000 1.000000 1.000000 +vn -0.996620 -0.061532 0.054426 +v 163.369751 -142.023117 18.488400 1.000000 1.000000 1.000000 +vn -0.968579 -0.075582 -0.236942 +v 163.421249 -142.018921 18.033600 1.000000 1.000000 1.000000 +vn -0.967555 0.135047 -0.213541 +v 163.340134 -143.330551 18.226398 1.000000 1.000000 1.000000 +vn -0.948481 -0.315236 -0.031795 +v 163.117401 -140.739410 18.301598 1.000000 1.000000 1.000000 +vn -0.842801 0.012854 -0.538072 +v 163.475311 -143.361252 17.828999 1.000000 1.000000 1.000000 +vn -0.882988 -0.091022 -0.460485 +v 163.560287 -142.009171 17.635998 1.000000 1.000000 1.000000 +vn -0.806282 0.345375 -0.480235 +v 163.047867 -144.660309 18.032997 1.000000 1.000000 1.000000 +vn -0.672284 0.366467 -0.643223 +v 162.911407 -145.388657 17.801399 1.000000 1.000000 1.000000 +vn -0.292444 0.009097 -0.956240 +v 163.452148 -144.891922 17.562399 1.000000 1.000000 1.000000 +vn -0.553923 -0.617012 -0.558986 +v 163.708359 -143.414261 17.494198 1.000000 1.000000 1.000000 +vn -0.242933 -0.115492 -0.963143 +v 164.016052 -141.974274 17.165398 1.000000 1.000000 1.000000 +vn -0.670532 -0.135423 -0.729415 +v 163.797195 -141.991028 17.301399 1.000000 1.000000 1.000000 +vn -0.718341 -0.354500 -0.598595 +v 163.520386 -140.581741 17.114397 1.000000 1.000000 1.000000 +vn -0.880691 -0.232836 -0.412517 +v 163.472748 -141.333817 17.542198 1.000000 1.000000 1.000000 +vn -0.798543 -0.398412 -0.451216 +v 163.180496 -140.355682 17.404400 1.000000 1.000000 1.000000 +vn -0.901170 -0.354885 -0.248895 +v 163.053024 -140.417099 17.801998 1.000000 1.000000 1.000000 +vn -0.853135 -0.521528 0.013020 +v 162.724716 -139.860352 18.167797 1.000000 1.000000 1.000000 +vn -0.913882 -0.018346 0.405565 +v 163.546127 -142.009171 19.312599 1.000000 1.000000 1.000000 +vn -0.876001 -0.125248 0.465764 +v 163.459869 -141.336609 19.218800 1.000000 1.000000 1.000000 +vn -0.931466 -0.278309 0.234342 +v 163.047867 -140.418488 18.687399 1.000000 1.000000 1.000000 +vn -0.678754 -0.153829 0.718074 +v 163.383911 -140.258011 19.428799 1.000000 1.000000 1.000000 +vn -0.866531 -0.245531 0.434555 +v 163.167618 -140.361282 19.080997 1.000000 1.000000 1.000000 +vn -0.817857 -0.510956 0.264640 +v 162.413147 -139.303604 18.511997 1.000000 1.000000 1.000000 +vn -0.594245 -0.348356 0.724928 +v 162.695099 -139.049667 19.253399 1.000000 1.000000 1.000000 +vn -0.344781 0.813256 0.468764 +v 161.123093 -146.726791 20.176998 1.000000 1.000000 1.000000 +vn -0.017515 0.662318 0.749018 +v 159.982391 -147.439804 20.751598 1.000000 1.000000 1.000000 +vn -0.096132 0.878325 0.468298 +v 159.934738 -147.190033 20.403999 1.000000 1.000000 1.000000 +vn 0.168740 0.648362 0.742397 +v 158.697479 -147.538864 20.972797 1.000000 1.000000 1.000000 +vn 0.123111 0.881416 0.456014 +v 158.712936 -147.283524 20.625198 1.000000 1.000000 1.000000 +vn 0.280088 0.860838 0.424862 +v 158.078201 -147.190033 20.740398 1.000000 1.000000 1.000000 +vn 0.361213 0.577467 0.732159 +v 157.375229 -147.240280 21.204597 1.000000 1.000000 1.000000 +vn 0.092952 0.995519 0.017363 +v 158.724518 -147.092361 19.800800 1.000000 1.000000 1.000000 +vn 0.391873 0.816341 0.424291 +v 157.455048 -146.998871 20.856998 1.000000 1.000000 1.000000 +vn 0.527470 0.741563 0.414558 +v 156.865387 -146.715622 20.973198 1.000000 1.000000 1.000000 +vn 0.533859 0.430849 0.727574 +v 156.185593 -146.555161 21.435999 1.000000 1.000000 1.000000 +vn 0.343582 0.937836 0.049142 +v 157.515579 -146.818878 20.032597 1.000000 1.000000 1.000000 +vn 0.650598 0.613600 0.447457 +v 156.324646 -146.348648 21.088200 1.000000 1.000000 1.000000 +vn 0.510288 0.859365 0.033145 +v 156.949081 -146.546783 20.148800 1.000000 1.000000 1.000000 +vn 0.764768 0.564622 0.310372 +v 155.454300 -145.450058 21.305199 1.000000 1.000000 1.000000 +vn 0.680563 0.731553 -0.040784 +v 156.015656 -145.822617 20.364397 1.000000 1.000000 1.000000 +vn 0.558436 0.794514 -0.238530 +v 156.398041 -146.238419 19.809200 1.000000 1.000000 1.000000 +vn 0.749567 0.466033 -0.470067 +v 155.075790 -144.883545 19.744598 1.000000 1.000000 1.000000 +vn -0.883532 -0.150291 0.443604 +v 153.304214 -143.052872 21.788200 1.000000 1.000000 1.000000 +vn -0.514926 0.389024 0.763879 +v 155.419556 -137.838516 22.923199 1.000000 1.000000 1.000000 +vn -0.189836 0.263979 0.945662 +v 158.235275 -136.701309 23.525799 1.000000 1.000000 1.000000 +vn -0.369643 0.514500 0.773727 +v 156.722473 -136.937119 23.154400 1.000000 1.000000 1.000000 +vn -0.448461 0.764482 0.463088 +v 156.623352 -136.702713 22.816595 1.000000 1.000000 1.000000 +vn -0.211015 0.632088 0.745612 +v 158.203079 -136.461319 23.385197 1.000000 1.000000 1.000000 +vn -0.329618 0.804079 0.494782 +v 157.385529 -136.395737 22.932800 1.000000 1.000000 1.000000 +vn -0.045808 0.351920 0.934909 +v 160.448456 -136.860382 23.872799 1.000000 1.000000 1.000000 +vn -0.032323 0.623677 0.781014 +v 159.745483 -136.454330 23.615799 1.000000 1.000000 1.000000 +vn -0.203837 0.860261 0.467335 +v 158.168320 -136.207367 23.047398 1.000000 1.000000 1.000000 +vn -0.073981 0.864041 0.497955 +v 158.972992 -136.141785 23.162800 1.000000 1.000000 1.000000 +vn -0.026804 0.987197 0.157236 +v 158.971710 -135.978531 22.694395 1.000000 1.000000 1.000000 +vn 0.063624 0.880462 0.469828 +v 159.777664 -136.198990 23.278198 1.000000 1.000000 1.000000 +vn 0.122216 0.979984 0.157145 +v 159.798264 -136.037140 22.809799 1.000000 1.000000 1.000000 +vn 0.019974 0.983229 -0.181280 +v 158.971710 -135.992477 21.878998 1.000000 1.000000 1.000000 +vn 0.168025 0.969049 -0.180861 +v 159.796982 -136.051086 21.994400 1.000000 1.000000 1.000000 +vn 0.321564 0.823238 -0.467841 +v 160.575912 -136.373413 21.717598 1.000000 1.000000 1.000000 +vn 0.312441 0.932640 -0.180451 +v 160.613251 -136.235275 22.110798 1.000000 1.000000 1.000000 +vn 0.459473 0.870363 -0.177069 +v 161.394745 -136.542252 22.226997 1.000000 1.000000 1.000000 +vn 0.409580 0.898592 0.157406 +v 161.399902 -136.529694 23.042400 1.000000 1.000000 1.000000 +vn 0.269520 0.949942 0.158014 +v 160.617111 -136.221313 22.926197 1.000000 1.000000 1.000000 +vn 0.188246 0.845677 0.499393 +v 160.574631 -136.380386 23.394600 1.000000 1.000000 1.000000 +vn 0.337919 0.813482 0.473347 +v 161.338104 -136.680389 23.510799 1.000000 1.000000 1.000000 +vn 0.530504 0.830433 0.170138 +v 162.129898 -136.952469 23.157597 1.000000 1.000000 1.000000 +vn 0.193261 0.626014 0.755485 +v 161.242828 -136.914795 23.848598 1.000000 1.000000 1.000000 +vn 0.521617 0.714051 0.466956 +v 162.629440 -137.542694 23.728201 1.000000 1.000000 1.000000 +vn 0.658885 0.721305 -0.213516 +v 162.718277 -137.426880 22.444395 1.000000 1.000000 1.000000 +vn 0.641504 0.751458 0.154220 +v 162.725998 -137.415726 23.259800 1.000000 1.000000 1.000000 +vn 0.611940 0.589807 0.526931 +v 163.224258 -138.148285 23.844801 1.000000 1.000000 1.000000 +vn 0.738861 0.656389 0.152437 +v 163.334976 -138.036652 23.376400 1.000000 1.000000 1.000000 +vn 0.342992 0.541572 0.767500 +v 162.480087 -137.740845 24.065798 1.000000 1.000000 1.000000 +vn 0.670782 0.527323 0.521520 +v 163.728943 -138.834778 23.960598 1.000000 1.000000 1.000000 +vn 0.823323 0.547052 0.151243 +v 163.853836 -138.741287 23.492397 1.000000 1.000000 1.000000 +vn 0.268832 0.355770 0.895074 +v 163.349152 -139.118042 24.438999 1.000000 1.000000 1.000000 +vn 0.059255 0.339893 0.938595 +v 161.804169 -137.513397 24.104198 1.000000 1.000000 1.000000 +vn 0.533004 0.357816 0.766729 +v 163.925934 -139.701279 24.413601 1.000000 1.000000 1.000000 +vn 0.785425 0.426155 0.448888 +v 164.137085 -139.586868 24.075798 1.000000 1.000000 1.000000 +vn 0.890009 0.430602 0.149887 +v 164.273560 -139.514313 23.607397 1.000000 1.000000 1.000000 +vn 0.272847 0.182285 0.944630 +v 164.193726 -141.332428 24.784998 1.000000 1.000000 1.000000 +vn 0.654971 0.210379 0.725778 +v 164.413895 -141.289169 24.644398 1.000000 1.000000 1.000000 +vn 0.819861 0.316801 0.476933 +v 164.447357 -140.401733 24.191998 1.000000 1.000000 1.000000 +vn 0.939345 0.309128 0.148564 +v 164.591553 -140.348709 23.723598 1.000000 1.000000 1.000000 +vn 0.371752 0.054554 0.926728 +v 164.124207 -143.735199 25.131998 1.000000 1.000000 1.000000 +vn 0.364399 -0.040843 0.930347 +v 163.566727 -145.226807 25.363398 1.000000 1.000000 1.000000 +vn 0.764255 0.621063 -0.173766 +v 163.325974 -138.046417 22.560999 1.000000 1.000000 1.000000 +vn 0.704787 0.538372 -0.461986 +v 163.228119 -138.144089 22.167797 1.000000 1.000000 1.000000 +vn 0.636446 0.261465 -0.725653 +v 163.538406 -138.977097 21.939198 1.000000 1.000000 1.000000 +vn 0.783803 0.426831 -0.451074 +v 163.734100 -138.830597 22.283600 1.000000 1.000000 1.000000 +vn 0.843232 0.509339 -0.171852 +v 163.843536 -138.749664 22.676800 1.000000 1.000000 1.000000 +vn 0.822474 0.308283 -0.478014 +v 164.142227 -139.584076 22.398800 1.000000 1.000000 1.000000 +vn 0.904262 0.391121 -0.171274 +v 164.261963 -139.519882 22.792000 1.000000 1.000000 1.000000 +vn -0.459515 0.495236 0.737284 +v 156.101913 -137.295731 38.495537 1.000000 1.000000 1.000000 +vn -0.556048 0.325095 0.764934 +v 154.918732 -138.370132 38.264740 1.000000 1.000000 1.000000 +vn -0.193380 0.304463 0.932688 +v 158.307373 -136.691544 38.983337 1.000000 1.000000 1.000000 +vn -0.297949 0.556543 0.775556 +v 157.514282 -136.621780 38.726341 1.000000 1.000000 1.000000 +vn -0.652250 0.091244 0.752492 +v 153.766418 -140.546844 37.917137 1.000000 1.000000 1.000000 +vn -0.769527 0.378294 0.514512 +v 154.246658 -138.886414 37.811939 1.000000 1.000000 1.000000 +vn -0.800384 0.301572 0.518111 +v 153.842377 -139.648254 37.695938 1.000000 1.000000 1.000000 +vn -0.874468 0.180247 0.450351 +v 153.539825 -140.468719 37.579338 1.000000 1.000000 1.000000 +vn -0.674285 -0.063491 0.735737 +v 153.510223 -142.098465 37.699738 1.000000 1.000000 1.000000 +vn -0.893613 -0.007808 0.448770 +v 153.273331 -142.087311 37.361938 1.000000 1.000000 1.000000 +vn -0.868744 -0.141195 0.474708 +v 153.296494 -142.967758 37.245941 1.000000 1.000000 1.000000 +vn -0.976624 0.142624 0.160822 +v 153.216660 -141.190109 37.008938 1.000000 1.000000 1.000000 +vn -0.988961 0.020932 0.146690 +v 153.122681 -142.080322 36.893738 1.000000 1.000000 1.000000 +vn -0.982984 -0.108571 0.148171 +v 153.144562 -142.983109 36.777538 1.000000 1.000000 1.000000 +vn -0.983350 0.071691 -0.166983 +v 153.135559 -142.080322 36.078140 1.000000 1.000000 1.000000 +vn -0.983194 -0.067979 -0.169439 +v 153.157440 -142.981705 35.961937 1.000000 1.000000 1.000000 +vn -0.952843 0.265335 0.147267 +v 153.395630 -140.418488 37.111137 1.000000 1.000000 1.000000 +vn -0.933363 0.292025 -0.208698 +v 153.408508 -140.422668 36.295540 1.000000 1.000000 1.000000 +vn -0.910296 0.386343 0.148662 +v 153.705917 -139.575699 37.227737 1.000000 1.000000 1.000000 +vn -0.889898 0.422409 -0.172197 +v 153.717499 -139.582687 36.412140 1.000000 1.000000 1.000000 +vn -0.791664 0.405048 -0.457389 +v 153.837234 -139.645477 36.019138 1.000000 1.000000 1.000000 +vn -0.882939 0.224017 -0.412596 +v 153.359573 -141.219406 35.800339 1.000000 1.000000 1.000000 +vn -0.874693 0.096680 -0.474938 +v 153.268173 -142.087311 35.685139 1.000000 1.000000 1.000000 +vn -0.650001 0.228846 -0.724657 +v 153.592606 -141.265442 35.455799 1.000000 1.000000 1.000000 +vn -0.541081 0.322258 -0.776776 +v 154.049667 -139.757095 35.674538 1.000000 1.000000 1.000000 +vn -0.722751 0.520519 -0.454632 +v 154.241516 -138.883621 36.134941 1.000000 1.000000 1.000000 +vn -0.502229 0.457145 -0.734019 +v 154.438492 -139.025940 35.790337 1.000000 1.000000 1.000000 +vn -0.145605 0.272748 -0.951004 +v 154.641907 -139.175247 35.639336 1.000000 1.000000 1.000000 +vn -0.252537 0.190712 -0.948606 +v 153.835953 -141.314285 35.304798 1.000000 1.000000 1.000000 +vn -0.692568 0.047029 -0.719818 +v 153.525665 -142.942642 35.224396 1.000000 1.000000 1.000000 +vn -0.012905 0.305547 -0.952089 +v 156.229370 -137.517578 35.985336 1.000000 1.000000 1.000000 +vn -0.290034 0.116217 -0.949934 +v 153.771576 -142.916138 35.073399 1.000000 1.000000 1.000000 +vn 0.148621 0.252268 -0.956176 +v 154.648346 -145.071930 34.731400 1.000000 1.000000 1.000000 +vn -0.626425 -0.056229 -0.777451 +v 153.658279 -143.777054 35.107998 1.000000 1.000000 1.000000 +vn -0.844055 -0.245055 -0.476989 +v 153.675018 -144.671463 35.337196 1.000000 1.000000 1.000000 +vn -0.014049 0.249191 -0.968352 +v 156.056854 -146.768646 34.385399 1.000000 1.000000 1.000000 +vn -0.100533 0.254436 -0.961850 +v 157.915970 -147.674225 34.050598 1.000000 1.000000 1.000000 +vn -0.177546 0.214387 -0.960477 +v 159.325775 -147.792816 33.819397 1.000000 1.000000 1.000000 +vn -0.263745 0.144305 -0.953737 +v 161.358704 -147.169113 33.472198 1.000000 1.000000 1.000000 +vn -0.072174 0.667628 -0.740988 +v 158.630524 -147.550034 34.071396 1.000000 1.000000 1.000000 +vn -0.304119 0.684454 -0.662597 +v 159.987534 -147.455154 33.838799 1.000000 1.000000 1.000000 +vn 0.111732 0.869869 -0.480462 +v 158.015121 -147.190033 34.521198 1.000000 1.000000 1.000000 +vn -0.125409 0.875494 -0.466671 +v 159.296158 -147.297485 34.290001 1.000000 1.000000 1.000000 +vn 0.174015 0.695979 -0.696658 +v 157.388107 -147.262604 34.288799 1.000000 1.000000 1.000000 +vn 0.502356 0.765710 -0.401654 +v 156.324646 -146.366791 34.855999 1.000000 1.000000 1.000000 +vn 0.348154 0.740987 -0.574218 +v 156.873123 -146.736557 34.739998 1.000000 1.000000 1.000000 +vn 0.461683 0.577615 -0.673209 +v 155.668030 -146.105865 34.636398 1.000000 1.000000 1.000000 +vn 0.536196 0.412840 -0.736245 +v 154.837616 -144.954712 34.867199 1.000000 1.000000 1.000000 +vn 0.679264 0.594736 -0.429988 +v 155.400238 -145.399826 35.087399 1.000000 1.000000 1.000000 +vn 0.755246 0.456407 -0.470421 +v 155.043610 -144.824951 35.201996 1.000000 1.000000 1.000000 +vn 0.782473 0.555905 -0.280545 +v 155.510971 -145.307739 35.484798 1.000000 1.000000 1.000000 +vn 0.705807 0.706600 0.050524 +v 155.965439 -145.772385 35.823338 1.000000 1.000000 1.000000 +vn 0.500050 0.865954 -0.008613 +v 156.961960 -146.553757 35.592400 1.000000 1.000000 1.000000 +vn 0.855555 0.465532 -0.226508 +v 155.164627 -144.750992 35.599396 1.000000 1.000000 1.000000 +vn 0.325306 0.945588 0.006362 +v 157.532303 -146.824463 35.475800 1.000000 1.000000 1.000000 +vn 0.617311 0.648957 0.444727 +v 156.333664 -146.355621 36.532539 1.000000 1.000000 1.000000 +vn 0.729668 0.598927 0.329956 +v 155.843124 -145.910522 36.647739 1.000000 1.000000 1.000000 +vn 0.187782 0.950820 -0.246331 +v 158.044724 -147.043533 34.918800 1.000000 1.000000 1.000000 +vn 0.098483 0.994594 0.032918 +v 158.664001 -147.088181 35.258400 1.000000 1.000000 1.000000 +vn 0.471799 0.822124 0.318620 +v 156.879547 -146.723999 36.416538 1.000000 1.000000 1.000000 +vn -0.067900 0.969948 -0.233648 +v 159.287140 -147.148178 34.687401 1.000000 1.000000 1.000000 +vn -0.077564 0.996974 0.005234 +v 159.283279 -147.092361 35.142197 1.000000 1.000000 1.000000 +vn 0.339233 0.821461 0.458392 +v 158.017685 -147.176086 36.197739 1.000000 1.000000 1.000000 +vn 0.308158 0.599982 0.738282 +v 157.966187 -147.425842 36.545540 1.000000 1.000000 1.000000 +vn 0.160070 0.890093 0.426745 +v 158.649841 -147.279343 36.082718 1.000000 1.000000 1.000000 +vn 0.064622 0.671944 0.737778 +v 159.310318 -147.538864 36.314117 1.000000 1.000000 1.000000 +vn 0.033331 0.890023 0.454695 +v 159.294861 -147.283524 35.966518 1.000000 1.000000 1.000000 +vn -0.242504 0.970094 0.010422 +v 159.899979 -147.000275 35.025799 1.000000 1.000000 1.000000 +vn -0.176295 0.922279 0.343980 +v 159.936035 -147.188644 35.849918 1.000000 1.000000 1.000000 +vn -0.240128 0.898126 0.368387 +v 160.552734 -146.998871 35.734718 1.000000 1.000000 1.000000 +vn -0.483911 0.873716 0.049499 +v 161.054855 -146.549576 34.794998 1.000000 1.000000 1.000000 +vn -0.226085 0.644609 0.730318 +v 161.247971 -146.944458 35.966938 1.000000 1.000000 1.000000 +vn -0.392138 0.816480 0.423779 +v 161.138535 -146.718414 35.619316 1.000000 1.000000 1.000000 +vn -0.493720 0.837158 -0.235387 +v 161.079315 -146.598419 34.340199 1.000000 1.000000 1.000000 +vn -0.588132 0.756760 -0.285333 +v 161.604599 -146.242599 34.225601 1.000000 1.000000 1.000000 +vn -0.737840 0.673003 0.051570 +v 162.048782 -145.765411 34.564198 1.000000 1.000000 1.000000 +vn -0.530178 0.765081 0.365463 +v 161.677994 -146.352844 35.504601 1.000000 1.000000 1.000000 +vn -0.629338 0.701737 0.333913 +v 162.172379 -145.903549 35.388397 1.000000 1.000000 1.000000 +vn -0.485080 0.493485 0.721921 +v 162.785217 -145.544937 35.620918 1.000000 1.000000 1.000000 +vn -0.623475 0.650392 -0.433900 +v 161.685715 -146.364014 33.827999 1.000000 1.000000 1.000000 +vn -0.882335 0.470551 -0.008233 +v 162.803253 -144.713318 34.333199 1.000000 1.000000 1.000000 +vn -0.481561 0.731541 -0.482645 +v 161.143692 -146.730972 33.942799 1.000000 1.000000 1.000000 +vn -0.431487 0.511469 -0.743114 +v 161.255707 -146.959808 33.607998 1.000000 1.000000 1.000000 +vn -0.600785 0.440595 -0.667034 +v 162.346191 -146.098892 33.377197 1.000000 1.000000 1.000000 +vn -0.786625 0.478323 -0.390421 +v 162.610138 -145.395645 33.596798 1.000000 1.000000 1.000000 +vn -0.950253 0.311396 0.007140 +v 163.073624 -144.104950 34.216599 1.000000 1.000000 1.000000 +vn -0.677460 0.587311 0.442847 +v 162.598541 -145.387268 35.273399 1.000000 1.000000 1.000000 +vn -0.840407 0.447408 0.305846 +v 162.957748 -144.808197 35.157398 1.000000 1.000000 1.000000 +vn -0.954055 0.190727 -0.231087 +v 163.291214 -143.556595 33.659599 1.000000 1.000000 1.000000 +vn -0.992943 0.113990 0.032710 +v 163.354294 -142.888229 33.999199 1.000000 1.000000 1.000000 +vn -0.760702 0.333708 -0.556751 +v 162.969345 -144.815186 33.480797 1.000000 1.000000 1.000000 +vn -0.720183 0.179267 -0.670224 +v 163.471451 -144.276581 33.029598 1.000000 1.000000 1.000000 +vn -0.883491 0.126581 -0.451023 +v 163.426392 -143.594269 33.262001 1.000000 1.000000 1.000000 +vn -0.975626 -0.028463 -0.217585 +v 163.430267 -142.214279 33.428200 1.000000 1.000000 1.000000 +vn -0.999368 -0.035165 0.005164 +v 163.378754 -142.215668 33.882999 1.000000 1.000000 1.000000 +vn -0.837947 0.325521 0.438042 +v 163.413528 -143.590073 34.938599 1.000000 1.000000 1.000000 +vn -0.624320 0.298393 0.721932 +v 163.641403 -143.654266 35.286400 1.000000 1.000000 1.000000 +vn -0.900996 0.167827 0.400051 +v 163.529388 -142.909149 34.823601 1.000000 1.000000 1.000000 +vn -0.697734 0.080262 0.711846 +v 163.792038 -142.203110 35.055000 1.000000 1.000000 1.000000 +vn -0.192518 0.206551 0.959309 +v 163.879593 -143.721237 35.440796 1.000000 1.000000 1.000000 +vn -0.245869 0.134109 0.959981 +v 164.037949 -142.194733 35.209599 1.000000 1.000000 1.000000 +vn -0.921683 -0.179104 0.344125 +v 163.336273 -140.839874 34.475601 1.000000 1.000000 1.000000 +vn -0.939271 -0.125059 0.319579 +v 163.490768 -141.513824 34.590797 1.000000 1.000000 1.000000 +vn -0.902022 0.058995 0.427639 +v 163.556427 -142.210083 34.707397 1.000000 1.000000 1.000000 +vn -0.984231 -0.176653 0.009064 +v 163.315674 -141.545914 33.766598 1.000000 1.000000 1.000000 +vn -0.872678 -0.241057 -0.424647 +v 163.503647 -141.511032 32.914200 1.000000 1.000000 1.000000 +vn -0.895660 -0.080734 -0.437350 +v 163.569305 -142.210083 33.030800 1.000000 1.000000 1.000000 +vn -0.699662 -0.041600 -0.713262 +v 163.779160 -142.939850 32.812199 1.000000 1.000000 1.000000 +vn -0.306763 0.839909 -0.447716 +v 159.938599 -147.202606 34.173401 1.000000 1.000000 1.000000 +vn 0.788220 0.502134 0.355768 +v 155.411819 -145.390060 36.763741 1.000000 1.000000 1.000000 +vn -0.884284 -0.140118 -0.445430 +v 153.427811 -143.838440 35.452599 1.000000 1.000000 1.000000 +vn -0.895515 -0.023787 -0.444396 +v 153.290054 -142.967758 35.569000 1.000000 1.000000 1.000000 +vn -0.965760 -0.196477 -0.169425 +v 153.299072 -143.873337 35.845539 1.000000 1.000000 1.000000 +vn -0.259282 0.615669 -0.744127 +v 156.099350 -137.290146 36.136536 1.000000 1.000000 1.000000 +vn 0.114006 0.278450 -0.953660 +v 158.309937 -136.709686 36.332539 1.000000 1.000000 1.000000 +vn -0.342820 0.508505 -0.789871 +v 155.474915 -137.779907 36.021736 1.000000 1.000000 1.000000 +vn -0.087577 0.600035 -0.795166 +v 157.513000 -136.616211 36.367138 1.000000 1.000000 1.000000 +vn 0.027432 0.667939 -0.743710 +v 158.277756 -136.444580 36.483536 1.000000 1.000000 1.000000 +vn -0.192587 0.861123 -0.470507 +v 157.448624 -136.369232 36.711739 1.000000 1.000000 1.000000 +vn -0.310124 0.809761 -0.498107 +v 156.687714 -136.665039 36.596336 1.000000 1.000000 1.000000 +vn 0.078603 0.861589 -0.501484 +v 159.057968 -136.136200 36.944336 1.000000 1.000000 1.000000 +vn -0.060571 0.879606 -0.471831 +v 158.246857 -136.190628 36.828140 1.000000 1.000000 1.000000 +vn 0.230729 0.628780 -0.742563 +v 159.826599 -136.459915 36.714939 1.000000 1.000000 1.000000 +vn 0.224329 0.871035 -0.437007 +v 159.861359 -136.205963 37.059540 1.000000 1.000000 1.000000 +vn 0.338293 0.521121 -0.783575 +v 161.233810 -136.903641 36.933739 1.000000 1.000000 1.000000 +vn -0.116325 0.976248 -0.182781 +v 158.228836 -136.046906 37.221336 1.000000 1.000000 1.000000 +vn 0.047512 0.982489 -0.180161 +v 159.059265 -135.991089 37.337341 1.000000 1.000000 1.000000 +vn -0.262188 0.947848 -0.181223 +v 157.412567 -136.231094 37.104736 1.000000 1.000000 1.000000 +vn -0.308323 0.938326 0.156466 +v 157.408707 -136.217133 37.920338 1.000000 1.000000 1.000000 +vn -0.011600 0.987291 0.158501 +v 159.059265 -135.977142 38.152939 1.000000 1.000000 1.000000 +vn -0.162954 0.973937 0.157775 +v 158.227554 -136.032944 38.036739 1.000000 1.000000 1.000000 +vn 0.131293 0.976165 0.172813 +v 159.883240 -136.049683 38.268139 1.000000 1.000000 1.000000 +vn 0.300666 0.928232 -0.219057 +v 160.597794 -136.231094 37.554741 1.000000 1.000000 1.000000 +vn -0.192835 0.845426 0.498065 +v 158.246857 -136.196198 38.505138 1.000000 1.000000 1.000000 +vn -0.040279 0.877824 0.477287 +v 159.057968 -136.141785 38.621140 1.000000 1.000000 1.000000 +vn -0.319531 0.825272 0.465645 +v 157.449905 -136.374802 38.388538 1.000000 1.000000 1.000000 +vn -0.093382 0.647412 0.756397 +v 159.055405 -136.398529 38.958939 1.000000 1.000000 1.000000 +vn 0.174052 0.862101 0.475907 +v 160.559174 -136.376205 38.838539 1.000000 1.000000 1.000000 +vn 0.271163 0.949413 0.158387 +v 160.600372 -136.217133 38.370338 1.000000 1.000000 1.000000 +vn 0.321703 0.823741 0.466860 +v 161.326508 -136.674805 38.955139 1.000000 1.000000 1.000000 +vn 0.406711 0.899875 0.157513 +v 161.388306 -136.524109 38.486938 1.000000 1.000000 1.000000 +vn 0.070504 0.633575 0.770462 +v 160.496078 -136.623169 39.176338 1.000000 1.000000 1.000000 +vn 0.446280 0.876679 -0.179633 +v 161.383163 -136.536667 37.671341 1.000000 1.000000 1.000000 +vn 0.535716 0.829857 0.156033 +v 162.123459 -136.946899 38.602737 1.000000 1.000000 1.000000 +vn 0.164504 0.607903 0.776784 +v 161.231247 -136.909225 39.292938 1.000000 1.000000 1.000000 +vn 0.430329 0.755713 0.493674 +v 162.042358 -137.086426 39.071136 1.000000 1.000000 1.000000 +vn 0.063634 0.348031 0.935321 +v 161.799011 -137.509216 39.549339 1.000000 1.000000 1.000000 +vn -0.091641 0.335192 0.937683 +v 159.791840 -136.705505 39.214737 1.000000 1.000000 1.000000 +vn 0.345495 0.528612 0.775373 +v 162.541901 -137.796646 39.523941 1.000000 1.000000 1.000000 +vn 0.649691 0.744420 0.154079 +v 162.791672 -137.474335 38.717941 1.000000 1.000000 1.000000 +vn 0.550199 0.697049 0.459787 +v 162.693817 -137.599899 39.186138 1.000000 1.000000 1.000000 +vn 0.173636 0.268251 0.947571 +v 163.386475 -139.176636 39.895340 1.000000 1.000000 1.000000 +vn 0.516297 0.439670 0.734933 +v 163.573166 -139.041290 39.754738 1.000000 1.000000 1.000000 +vn 0.629893 0.605880 0.485947 +v 163.277054 -138.212463 39.302338 1.000000 1.000000 1.000000 +vn 0.747808 0.646057 0.152947 +v 163.390335 -138.103622 38.834137 1.000000 1.000000 1.000000 +vn 0.725485 0.519144 0.451842 +v 163.770157 -138.898956 39.417137 1.000000 1.000000 1.000000 +vn 0.830145 0.536814 0.150633 +v 163.895035 -138.806885 38.948738 1.000000 1.000000 1.000000 +vn -0.220271 0.179633 0.958756 +v 164.005768 -142.988678 40.477718 1.000000 1.000000 1.000000 +vn -0.262658 0.101629 0.959522 +v 163.971008 -141.453827 40.246319 1.000000 1.000000 1.000000 +vn -0.132996 0.236816 0.962409 +v 163.363312 -145.090057 40.812317 1.000000 1.000000 1.000000 +vn -0.435269 0.754059 0.491870 +v 156.690292 -136.670609 38.273140 1.000000 1.000000 1.000000 +vn -0.443679 0.882523 0.155895 +v 156.629776 -136.519928 37.804939 1.000000 1.000000 1.000000 +vn -0.546441 0.700455 0.459092 +v 155.977036 -137.078049 38.157936 1.000000 1.000000 1.000000 +vn -0.634779 0.601870 0.484571 +v 155.326843 -137.587357 38.043137 1.000000 1.000000 1.000000 +vn -0.568187 0.808297 0.154339 +v 155.897202 -136.938522 37.689537 1.000000 1.000000 1.000000 +vn -0.400135 0.898541 -0.180323 +v 156.634933 -136.532471 36.989338 1.000000 1.000000 1.000000 +vn -0.528782 0.829831 -0.178242 +v 155.903641 -136.949692 36.874138 1.000000 1.000000 1.000000 +vn -0.439528 0.768089 -0.465677 +v 155.973175 -137.072479 36.480938 1.000000 1.000000 1.000000 +vn -0.643039 0.745235 -0.176423 +v 155.238007 -137.472931 36.759338 1.000000 1.000000 1.000000 +vn -0.678179 0.718992 0.152066 +v 155.230286 -137.461761 37.574936 1.000000 1.000000 1.000000 +vn -0.547034 0.698042 -0.462052 +v 155.322983 -137.583160 36.366341 1.000000 1.000000 1.000000 +vn -0.741178 0.648032 -0.175242 +v 154.639343 -138.098038 36.643139 1.000000 1.000000 1.000000 +vn -0.771982 0.617403 0.151191 +v 154.629028 -138.089676 37.458740 1.000000 1.000000 1.000000 +vn -0.627378 0.606595 -0.488302 +v 154.738464 -138.194321 36.250137 1.000000 1.000000 1.000000 +vn -0.823865 0.539432 -0.173952 +v 154.130783 -138.802689 36.528137 1.000000 1.000000 1.000000 +vn -0.849467 0.505829 0.150145 +v 154.120483 -138.794312 37.343536 1.000000 1.000000 1.000000 +vn -0.722857 0.522810 0.451827 +v 154.742340 -138.198502 37.926941 1.000000 1.000000 1.000000 +vn 0.571130 0.801527 -0.177101 +v 162.115738 -136.958054 37.787338 1.000000 1.000000 1.000000 +vn 0.679669 0.712174 -0.175667 +v 162.782654 -137.485489 37.902336 1.000000 1.000000 1.000000 +vn 0.772471 0.610837 -0.173683 +v 163.381332 -138.112000 38.018539 1.000000 1.000000 1.000000 +vn 0.635782 0.599125 -0.486652 +v 162.697678 -137.595718 37.509338 1.000000 1.000000 1.000000 +vn 0.548358 0.697188 -0.461771 +v 162.046219 -137.080841 37.394138 1.000000 1.000000 1.000000 +vn 0.424263 0.771609 -0.473941 +v 161.329086 -136.669220 37.278339 1.000000 1.000000 1.000000 +vn 0.477757 0.481939 -0.734495 +v 161.920044 -137.298523 37.049736 1.000000 1.000000 1.000000 +vn 0.723154 0.519446 -0.455219 +v 163.282196 -138.208282 37.625538 1.000000 1.000000 1.000000 +vn 0.531137 0.326749 -0.781748 +v 163.104523 -138.379898 37.280937 1.000000 1.000000 1.000000 +vn 0.789188 0.417090 -0.450796 +v 163.774017 -138.894775 37.740139 1.000000 1.000000 1.000000 +vn 0.849677 0.498484 -0.171937 +v 163.884735 -138.815247 38.133339 1.000000 1.000000 1.000000 +vn -0.960077 -0.237025 0.148562 +v 153.286194 -143.876114 36.661140 1.000000 1.000000 1.000000 +vn -0.505982 -0.371961 0.778220 +v 154.395996 -145.613312 17.840797 1.000000 1.000000 1.000000 +vn -0.734039 -0.486091 0.474239 +v 154.197723 -145.754242 17.502998 1.000000 1.000000 1.000000 +vn -0.317683 -0.555212 0.768646 +v 156.005356 -147.353302 17.718197 1.000000 1.000000 1.000000 +vn -0.273773 -0.324991 0.905223 +v 155.501953 -146.636093 17.900597 1.000000 1.000000 1.000000 +vn -0.580863 -0.593322 0.557286 +v 155.196808 -147.010040 17.422199 1.000000 1.000000 1.000000 +vn -0.464486 -0.745815 0.477508 +v 155.876602 -147.569565 17.380398 1.000000 1.000000 1.000000 +vn -0.096282 -0.646399 0.756900 +v 158.022842 -148.222580 17.617798 1.000000 1.000000 1.000000 +vn -0.111222 -0.378656 0.918831 +v 157.382950 -147.799805 17.789997 1.000000 1.000000 1.000000 +vn -0.773919 -0.607366 0.179320 +v 154.541489 -146.524460 16.993599 1.000000 1.000000 1.000000 +vn -0.665349 -0.721271 0.192558 +v 155.096390 -147.132828 16.953999 1.000000 1.000000 1.000000 +vn -0.835249 -0.528089 0.153237 +v 154.070267 -145.843552 17.034798 1.000000 1.000000 1.000000 +vn -0.527835 -0.529200 -0.664332 +v 154.971497 -147.071442 16.327000 1.000000 1.000000 1.000000 +vn -0.562236 -0.816797 0.129359 +v 155.794205 -147.706314 16.911999 1.000000 1.000000 1.000000 +vn -0.299853 -0.680873 -0.668206 +v 156.780426 -148.300720 16.326599 1.000000 1.000000 1.000000 +vn -0.453677 -0.867668 0.203297 +v 156.471420 -148.119324 16.876999 1.000000 1.000000 1.000000 +vn -0.042158 -0.773297 -0.632640 +v 158.683319 -148.766754 16.326599 1.000000 1.000000 1.000000 +vn -0.176110 -0.973419 0.146429 +v 157.953308 -148.635605 16.811798 1.000000 1.000000 1.000000 +vn -0.302527 -0.938529 0.166253 +v 157.194992 -148.430496 16.843399 1.000000 1.000000 1.000000 +vn -0.289100 -0.780802 0.553868 +v 157.242630 -148.274216 17.311798 1.000000 1.000000 1.000000 +vn -0.123401 -0.875120 0.467907 +v 157.980347 -148.475143 17.279999 1.000000 1.000000 1.000000 +vn 0.088946 -0.988793 0.119903 +v 159.471252 -148.722107 16.754997 1.000000 1.000000 1.000000 +vn 0.087082 -0.873338 0.479267 +v 159.458374 -148.557465 17.223400 1.000000 1.000000 1.000000 +vn 0.104243 -0.635068 0.765390 +v 159.440353 -148.302124 17.561199 1.000000 1.000000 1.000000 +vn 0.023375 -0.317070 0.948114 +v 158.741241 -148.069092 17.729000 1.000000 1.000000 1.000000 +vn 0.829805 -0.432652 0.352472 +v 161.005936 -148.283981 16.993797 1.000000 1.000000 1.000000 +vn 0.640915 0.042412 0.766439 +v 160.792206 -147.650497 17.692600 1.000000 1.000000 1.000000 +vn 0.201878 -0.966229 0.160148 +v 160.234726 -148.599335 16.729000 1.000000 1.000000 1.000000 +vn 0.726290 -0.448274 -0.521107 +v 161.053574 -148.426300 16.326599 1.000000 1.000000 1.000000 +vn 0.533685 0.689323 0.489913 +v 162.677078 -137.583160 34.034401 1.000000 1.000000 1.000000 +vn 0.745499 0.649000 0.151757 +v 163.369751 -138.078506 33.681198 1.000000 1.000000 1.000000 +vn 0.646466 0.747366 0.153381 +v 162.773636 -137.457581 33.565998 1.000000 1.000000 1.000000 +vn 0.250887 0.579072 0.775713 +v 161.895584 -137.288742 34.256199 1.000000 1.000000 1.000000 +vn 0.437064 0.770536 0.463949 +v 162.019180 -137.069687 33.918396 1.000000 1.000000 1.000000 +vn 0.642461 0.615754 0.456170 +v 163.257736 -138.188736 34.149399 1.000000 1.000000 1.000000 +vn 0.417618 0.477401 0.773100 +v 163.081345 -138.360367 34.487198 1.000000 1.000000 1.000000 +vn 0.827600 0.540702 0.150727 +v 163.884735 -138.790131 33.797398 1.000000 1.000000 1.000000 +vn 0.706829 0.516263 0.483596 +v 163.758560 -138.882217 34.265598 1.000000 1.000000 1.000000 +vn 0.211577 0.243904 0.946439 +v 163.745682 -139.853378 34.858597 1.000000 1.000000 1.000000 +vn 0.113541 0.335870 0.935040 +v 162.382248 -137.966873 34.512596 1.000000 1.000000 1.000000 +vn 0.162644 0.616670 0.770237 +v 161.201630 -136.896667 34.139599 1.000000 1.000000 1.000000 +vn -0.041656 0.342971 0.938422 +v 160.494797 -136.874344 34.177998 1.000000 1.000000 1.000000 +vn -0.146753 0.326944 0.933580 +v 159.027069 -136.641312 33.946598 1.000000 1.000000 1.000000 +vn 0.003172 0.653411 0.756996 +v 159.804718 -136.461319 33.922199 1.000000 1.000000 1.000000 +vn 0.298102 0.828503 0.474044 +v 161.296906 -136.660858 33.801796 1.000000 1.000000 1.000000 +vn 0.088926 0.874802 0.476250 +v 159.838196 -136.207367 33.584396 1.000000 1.000000 1.000000 +vn -0.066486 0.863982 0.499113 +v 159.028351 -136.141785 33.468201 1.000000 1.000000 1.000000 +vn -0.213530 0.591026 0.777877 +v 158.248154 -136.455734 33.689598 1.000000 1.000000 1.000000 +vn 0.531110 0.832958 0.155253 +v 162.098999 -136.930145 33.450199 1.000000 1.000000 1.000000 +vn 0.406012 0.900317 0.156793 +v 161.357422 -136.510147 33.333599 1.000000 1.000000 1.000000 +vn 0.272379 0.946713 0.171883 +v 160.667328 -136.238068 33.231400 1.000000 1.000000 1.000000 +vn 0.566443 0.804795 -0.177332 +v 162.092560 -136.942703 32.634598 1.000000 1.000000 1.000000 +vn 0.431607 0.875424 -0.217598 +v 161.352264 -136.522720 32.517998 1.000000 1.000000 1.000000 +vn 0.191693 0.965064 -0.178623 +v 159.858780 -136.059464 32.300598 1.000000 1.000000 1.000000 +vn 0.133624 0.978407 0.157682 +v 159.860077 -136.045502 33.116196 1.000000 1.000000 1.000000 +vn 0.530211 0.705827 -0.469771 +v 162.023041 -137.065506 32.241600 1.000000 1.000000 1.000000 +vn 0.348324 0.830160 -0.435322 +v 160.626129 -136.390152 32.022797 1.000000 1.000000 1.000000 +vn 0.640685 0.616916 -0.457097 +v 162.680954 -137.578979 32.357399 1.000000 1.000000 1.000000 +vn 0.676910 0.714949 -0.175044 +v 162.765915 -137.468750 32.750599 1.000000 1.000000 1.000000 +vn 0.770469 0.613456 -0.173345 +v 163.359451 -138.088272 32.865601 1.000000 1.000000 1.000000 +vn 0.712437 0.509551 -0.482484 +v 163.261597 -138.184555 32.472599 1.000000 1.000000 1.000000 +vn 0.541038 0.414646 -0.731674 +v 162.529022 -137.775711 32.012798 1.000000 1.000000 1.000000 +vn 0.787566 0.420668 -0.450310 +v 163.763718 -138.878036 32.588799 1.000000 1.000000 1.000000 +vn 0.847003 0.503121 -0.171625 +v 163.873154 -138.798492 32.981796 1.000000 1.000000 1.000000 +vn 0.319865 0.591340 -0.740273 +v 160.559174 -136.637131 31.678198 1.000000 1.000000 1.000000 +vn 0.409327 0.470578 -0.781670 +v 161.898163 -137.283173 31.896999 1.000000 1.000000 1.000000 +vn 0.205105 0.841501 -0.499807 +v 159.839478 -136.201782 31.907598 1.000000 1.000000 1.000000 +vn 0.125600 0.657540 -0.742877 +v 159.027069 -136.392944 31.446798 1.000000 1.000000 1.000000 +vn 0.069771 0.878624 -0.472390 +v 159.028351 -136.136200 31.791401 1.000000 1.000000 1.000000 +vn -0.064427 0.879050 -0.472356 +v 158.214676 -136.194809 31.674999 1.000000 1.000000 1.000000 +vn 0.001848 0.605578 -0.795784 +v 158.248154 -136.450150 31.330399 1.000000 1.000000 1.000000 +vn 0.029248 0.982731 -0.182711 +v 159.029648 -135.991089 32.184399 1.000000 1.000000 1.000000 +vn -0.121314 0.975872 -0.181539 +v 158.196655 -136.052475 32.068001 1.000000 1.000000 1.000000 +vn -0.017586 0.987204 0.158493 +v 159.029648 -135.977142 33.000000 1.000000 1.000000 1.000000 +vn -0.168021 0.973038 0.158006 +v 158.195358 -136.038528 32.883598 1.000000 1.000000 1.000000 +vn -0.266762 0.946574 -0.181204 +v 157.388107 -136.238068 31.952599 1.000000 1.000000 1.000000 +vn -0.321810 0.807103 0.494998 +v 157.426743 -136.381775 33.236397 1.000000 1.000000 1.000000 +vn -0.311893 0.937129 0.156565 +v 157.384247 -136.224106 32.768196 1.000000 1.000000 1.000000 +vn -0.195570 0.861706 0.468205 +v 158.215958 -136.201782 33.351799 1.000000 1.000000 1.000000 +vn -0.441460 0.768367 0.463385 +v 156.668396 -136.680389 33.121201 1.000000 1.000000 1.000000 +vn -0.384166 0.551131 0.740723 +v 156.764969 -136.914795 33.458801 1.000000 1.000000 1.000000 +vn -0.501192 0.398358 0.768191 +v 155.456894 -137.805023 33.227997 1.000000 1.000000 1.000000 +vn -0.544627 0.681595 0.488681 +v 155.960297 -137.089218 33.006401 1.000000 1.000000 1.000000 +vn -0.447489 0.880672 0.155469 +v 156.606613 -136.529694 32.652798 1.000000 1.000000 1.000000 +vn -0.644533 0.614240 0.455287 +v 155.304962 -137.608276 32.890198 1.000000 1.000000 1.000000 +vn -0.572046 0.805656 0.153888 +v 155.880463 -136.949692 32.538200 1.000000 1.000000 1.000000 +vn -0.404512 0.896616 -0.180137 +v 156.611755 -136.543640 31.837399 1.000000 1.000000 1.000000 +vn -0.532335 0.827533 -0.178350 +v 155.886902 -136.962234 31.722601 1.000000 1.000000 1.000000 +vn -0.680985 0.716187 0.152761 +v 155.207123 -137.482697 32.421997 1.000000 1.000000 1.000000 +vn -0.715626 0.506093 0.481403 +v 154.726883 -138.216644 32.775200 1.000000 1.000000 1.000000 +vn -0.774894 0.613666 0.151505 +v 154.613586 -138.107803 32.306801 1.000000 1.000000 1.000000 +vn -0.744161 0.644728 -0.174787 +v 154.622604 -138.116180 31.491398 1.000000 1.000000 1.000000 +vn -0.645477 0.742931 -0.177237 +v 155.214844 -137.493866 31.606398 1.000000 1.000000 1.000000 +vn -0.324129 0.822144 -0.467996 +v 156.665833 -136.674805 31.444199 1.000000 1.000000 1.000000 +vn -0.442388 0.766382 -0.465781 +v 155.957718 -137.083633 31.329599 1.000000 1.000000 1.000000 +vn -0.536490 0.685433 -0.492301 +v 155.301102 -137.604095 31.213398 1.000000 1.000000 1.000000 +vn -0.826858 0.535188 -0.172856 +v 154.115341 -138.827805 31.375399 1.000000 1.000000 1.000000 +vn -0.644051 0.611959 -0.459026 +v 154.721741 -138.212463 31.098198 1.000000 1.000000 1.000000 +vn -0.432063 0.518622 -0.737803 +v 154.899399 -138.384094 30.753599 1.000000 1.000000 1.000000 +vn -0.265888 0.549212 -0.792256 +v 156.083893 -137.301315 30.984999 1.000000 1.000000 1.000000 +vn -0.166937 0.644922 -0.745794 +v 156.762390 -136.909225 31.099798 1.000000 1.000000 1.000000 +vn -0.189084 0.845279 -0.499750 +v 157.425446 -136.376205 31.559599 1.000000 1.000000 1.000000 +vn 0.031966 0.305457 -0.951669 +v 156.862808 -137.153397 30.948599 1.000000 1.000000 1.000000 +vn -0.105143 0.289536 -0.951375 +v 155.082230 -138.561295 30.602598 1.000000 1.000000 1.000000 +vn -0.490872 0.389026 -0.779554 +v 154.423035 -139.049667 30.637798 1.000000 1.000000 1.000000 +vn -0.612255 0.309594 -0.727527 +v 153.780594 -140.477097 30.418999 1.000000 1.000000 1.000000 +vn -0.223285 0.220547 -0.949475 +v 154.014908 -140.562195 30.267998 1.000000 1.000000 1.000000 +vn -0.271344 0.151532 -0.950479 +v 153.749680 -142.138931 30.036598 1.000000 1.000000 1.000000 +vn -0.680531 0.134038 -0.720355 +v 153.503769 -142.129166 30.187599 1.000000 1.000000 1.000000 +vn -0.845532 0.334964 -0.415783 +v 153.555283 -140.396164 30.763599 1.000000 1.000000 1.000000 +vn -0.854360 0.205792 -0.477199 +v 153.355713 -141.243118 30.648399 1.000000 1.000000 1.000000 +vn -0.729796 0.504601 -0.461276 +v 154.226059 -138.907333 30.982397 1.000000 1.000000 1.000000 +vn -0.887909 0.409479 -0.209629 +v 153.703339 -139.614761 31.258799 1.000000 1.000000 1.000000 +vn -0.966294 0.194810 -0.168299 +v 153.224396 -141.216614 31.041401 1.000000 1.000000 1.000000 +vn -0.891263 0.089320 -0.444603 +v 153.266876 -142.119385 30.532198 1.000000 1.000000 1.000000 +vn -0.983984 0.056404 -0.169098 +v 153.134277 -142.113815 30.925198 1.000000 1.000000 1.000000 +vn -0.950434 0.265499 0.161818 +v 153.417526 -140.347321 31.972198 1.000000 1.000000 1.000000 +vn -0.978270 0.145912 0.147302 +v 153.211517 -141.213821 31.856998 1.000000 1.000000 1.000000 +vn -0.910729 0.385350 0.148584 +v 153.691757 -139.609192 32.074398 1.000000 1.000000 1.000000 +vn -0.852119 0.501383 0.150028 +v 154.105026 -138.820816 32.190998 1.000000 1.000000 1.000000 +vn -0.843894 0.290209 0.451245 +v 153.828232 -139.680359 32.542599 1.000000 1.000000 1.000000 +vn -0.886865 0.105545 0.449812 +v 153.360870 -141.244522 32.325199 1.000000 1.000000 1.000000 +vn -0.880586 -0.030987 0.472872 +v 153.272034 -142.119385 32.209000 1.000000 1.000000 1.000000 +vn -0.989068 0.015615 0.146632 +v 153.121399 -142.112411 31.740799 1.000000 1.000000 1.000000 +vn -0.677303 0.021918 0.735378 +v 153.593903 -141.290573 32.662998 1.000000 1.000000 1.000000 +vn -0.638778 0.163100 0.751905 +v 154.041946 -139.790573 32.880398 1.000000 1.000000 1.000000 +vn -0.791107 0.415975 0.448458 +v 154.231201 -138.911530 32.659199 1.000000 1.000000 1.000000 +vn -0.604053 0.243564 0.758812 +v 154.428192 -139.053848 32.996998 1.000000 1.000000 1.000000 +vn -0.885137 -0.142862 0.442857 +v 153.300354 -143.001251 32.092598 1.000000 1.000000 1.000000 +vn -0.982446 -0.113126 0.148331 +v 153.148438 -143.017990 31.624399 1.000000 1.000000 1.000000 +vn -0.959240 -0.240604 0.148218 +v 153.292633 -143.902634 31.508999 1.000000 1.000000 1.000000 +vn -0.965080 -0.200134 -0.169016 +v 153.304214 -143.898438 30.693398 1.000000 1.000000 1.000000 +vn -0.982887 -0.072320 -0.169420 +v 153.161301 -143.016602 30.808798 1.000000 1.000000 1.000000 +vn -0.895137 -0.027075 -0.444968 +v 153.293930 -143.002640 30.415798 1.000000 1.000000 1.000000 +vn -0.869352 -0.136239 -0.475044 +v 153.432968 -143.863556 30.300398 1.000000 1.000000 1.000000 +vn -0.628983 0.023200 -0.777072 +v 153.529526 -142.976135 30.071199 1.000000 1.000000 1.000000 +vn -0.679017 -0.127826 -0.722909 +v 153.902893 -144.600311 29.840599 1.000000 1.000000 1.000000 +vn -0.856739 -0.258211 -0.446458 +v 153.682739 -144.696579 30.184998 1.000000 1.000000 1.000000 +vn -0.323374 0.044041 -0.945246 +v 154.130783 -144.499832 29.689398 1.000000 1.000000 1.000000 +vn 0.022454 0.248548 -0.968359 +v 155.530273 -146.292847 29.348398 1.000000 1.000000 1.000000 +vn -0.062095 0.265047 -0.962234 +v 157.258072 -147.463516 29.013798 1.000000 1.000000 1.000000 +vn -0.144392 0.235058 -0.961196 +v 158.639542 -147.788635 28.782398 1.000000 1.000000 1.000000 +vn -0.240240 0.175793 -0.954663 +v 160.731705 -147.471893 28.435198 1.000000 1.000000 1.000000 +vn -0.266227 0.029034 -0.963473 +v 162.513565 -146.255173 28.089199 1.000000 1.000000 1.000000 +vn -0.286477 -0.048187 -0.956875 +v 163.652985 -144.423080 27.754599 1.000000 1.000000 1.000000 +vn -0.688600 0.268415 -0.673634 +v 163.188217 -144.917038 27.992598 1.000000 1.000000 1.000000 +vn -0.699464 0.046760 -0.713136 +v 163.662003 -143.638916 27.775198 1.000000 1.000000 1.000000 +vn -0.257494 -0.124546 -0.958220 +v 163.999313 -142.938461 27.523199 1.000000 1.000000 1.000000 +vn -0.757822 -0.155497 -0.633661 +v 163.806198 -142.173813 27.542599 1.000000 1.000000 1.000000 +vn -0.859393 0.237750 -0.452680 +v 163.229401 -144.234726 28.225199 1.000000 1.000000 1.000000 +vn -0.898633 0.032973 -0.437461 +v 163.544846 -142.885437 27.993799 1.000000 1.000000 1.000000 +vn -0.200299 -0.218298 -0.955105 +v 163.777878 -140.661270 27.175999 1.000000 1.000000 1.000000 +vn -0.896945 -0.128340 -0.423106 +v 163.568008 -142.182190 27.877398 1.000000 1.000000 1.000000 +vn -0.831932 -0.302456 -0.465198 +v 163.343994 -140.814758 27.646599 1.000000 1.000000 1.000000 +vn -0.611717 -0.301134 -0.731520 +v 163.570587 -140.735229 27.311998 1.000000 1.000000 1.000000 +vn -0.971445 0.094755 -0.217521 +v 163.407074 -142.868683 28.391399 1.000000 1.000000 1.000000 +vn -0.929895 -0.291669 -0.224108 +v 163.212662 -140.862198 28.044197 1.000000 1.000000 1.000000 +vn -0.998669 -0.050785 0.009029 +v 163.377472 -142.190552 28.729597 1.000000 1.000000 1.000000 +vn -0.921907 0.310200 -0.232083 +v 163.100662 -144.177521 28.622599 1.000000 1.000000 1.000000 +vn -0.995773 0.091666 0.005776 +v 163.355576 -142.863113 28.846201 1.000000 1.000000 1.000000 +vn -0.970402 0.239238 0.032937 +v 163.246140 -143.524490 28.962399 1.000000 1.000000 1.000000 +vn -0.959883 -0.276468 0.046806 +v 163.163757 -140.878937 28.498999 1.000000 1.000000 1.000000 +vn -0.876957 -0.392863 -0.276776 +v 162.978348 -140.241287 27.929398 1.000000 1.000000 1.000000 +vn -0.833393 -0.550428 0.049856 +v 162.619141 -139.684540 28.267998 1.000000 1.000000 1.000000 +vn -0.786728 -0.448508 -0.424146 +v 163.103241 -140.174301 27.531998 1.000000 1.000000 1.000000 +vn -0.871731 0.280682 0.401625 +v 163.418671 -143.571930 29.786598 1.000000 1.000000 1.000000 +vn -0.786773 0.430892 0.441951 +v 163.217819 -144.229141 29.901798 1.000000 1.000000 1.000000 +vn -0.576835 0.375755 0.725307 +v 163.435410 -144.326813 30.249399 1.000000 1.000000 1.000000 +vn -0.679976 0.167273 0.713900 +v 163.766281 -142.910553 30.018198 1.000000 1.000000 1.000000 +vn -0.887498 0.171424 0.427741 +v 163.531967 -142.884033 29.670597 1.000000 1.000000 1.000000 +vn -0.409773 0.552878 0.725543 +v 162.350052 -146.072372 30.584198 1.000000 1.000000 1.000000 +vn -0.773573 0.553529 0.308530 +v 162.612701 -145.369125 30.120598 1.000000 1.000000 1.000000 +vn -0.129999 0.669236 0.731589 +v 160.651871 -147.233292 30.930199 1.000000 1.000000 1.000000 +vn 0.163222 0.655927 0.736966 +v 158.656281 -147.536087 31.277399 1.000000 1.000000 1.000000 +vn 0.391829 0.552693 0.735528 +v 157.339188 -147.224930 31.508799 1.000000 1.000000 1.000000 +vn 0.453936 0.766025 0.455135 +v 157.421585 -146.984924 31.160999 1.000000 1.000000 1.000000 +vn 0.288712 0.857973 0.424886 +v 158.035706 -147.180283 31.045799 1.000000 1.000000 1.000000 +vn 0.582996 0.749034 0.314745 +v 156.350403 -146.369583 31.379799 1.000000 1.000000 1.000000 +vn 0.070919 0.997470 0.004991 +v 158.685883 -147.089569 30.105398 1.000000 1.000000 1.000000 +vn 0.243688 0.969292 0.033020 +v 158.073044 -146.993301 30.221598 1.000000 1.000000 1.000000 +vn 0.803901 0.497002 0.326699 +v 155.425995 -145.410980 31.610798 1.000000 1.000000 1.000000 +vn 0.701216 0.560347 0.440804 +v 155.856003 -145.924469 31.495798 1.000000 1.000000 1.000000 +vn 0.457542 0.889164 0.006503 +v 156.983841 -146.566330 30.438999 1.000000 1.000000 1.000000 +vn 0.323923 0.913752 -0.245216 +v 157.465363 -146.857956 29.881998 1.000000 1.000000 1.000000 +vn 0.076291 0.969270 -0.233870 +v 158.683319 -147.145386 29.650599 1.000000 1.000000 1.000000 +vn 0.605442 0.689285 -0.397903 +v 155.846985 -145.934235 29.819199 1.000000 1.000000 1.000000 +vn 0.617460 0.786561 -0.008067 +v 156.453400 -146.213303 30.555599 1.000000 1.000000 1.000000 +vn 0.452989 0.685461 -0.570039 +v 156.342667 -146.382141 29.703199 1.000000 1.000000 1.000000 +vn 0.238136 0.845043 -0.478741 +v 157.416428 -146.998871 29.484398 1.000000 1.000000 1.000000 +vn 0.538532 0.510906 -0.670044 +v 155.229004 -145.579819 29.599398 1.000000 1.000000 1.000000 +vn 0.274253 0.665851 -0.693850 +v 156.786850 -146.977951 29.251799 1.000000 1.000000 1.000000 +vn 0.754306 0.499538 -0.426010 +v 155.052612 -144.840302 30.050398 1.000000 1.000000 1.000000 +vn 0.849402 0.448995 -0.277344 +v 155.172363 -144.763550 30.447998 1.000000 1.000000 1.000000 +vn 0.588110 0.339700 -0.733983 +v 154.550507 -144.315659 29.830399 1.000000 1.000000 1.000000 +vn 0.027084 0.671559 -0.740456 +v 157.981644 -147.446777 29.034401 1.000000 1.000000 1.000000 +vn 0.005001 0.884186 -0.467108 +v 158.673004 -147.294693 29.252998 1.000000 1.000000 1.000000 +vn -0.201221 0.720230 -0.663912 +v 159.337357 -147.552826 28.801798 1.000000 1.000000 1.000000 +vn -0.180868 0.875002 -0.449063 +v 159.321915 -147.296082 29.136599 1.000000 1.000000 1.000000 +vn -0.371828 0.790895 -0.486035 +v 160.574631 -147.005859 28.905998 1.000000 1.000000 1.000000 +vn -0.354020 0.564202 -0.745886 +v 160.657013 -147.248642 28.571199 1.000000 1.000000 1.000000 +vn -0.368788 0.898710 -0.237308 +v 160.526993 -146.864929 29.303398 1.000000 1.000000 1.000000 +vn -0.097305 0.995205 0.009950 +v 159.307739 -147.089569 29.988998 1.000000 1.000000 1.000000 +vn -0.353458 0.934096 0.050328 +v 160.508957 -146.813309 29.758198 1.000000 1.000000 1.000000 +vn -0.038340 0.937454 0.345991 +v 159.320618 -147.280731 30.813198 1.000000 1.000000 1.000000 +vn 0.164584 0.875590 0.454153 +v 158.674301 -147.280731 30.929798 1.000000 1.000000 1.000000 +vn -0.475211 0.831125 -0.288800 +v 161.092194 -146.590042 29.188599 1.000000 1.000000 1.000000 +vn -0.526492 0.728878 -0.437656 +v 161.157852 -146.722595 28.791199 1.000000 1.000000 1.000000 +vn -0.638239 0.768128 0.051289 +v 161.591736 -146.182602 29.527399 1.000000 1.000000 1.000000 +vn -0.533271 0.514409 -0.671569 +v 161.845367 -146.556549 28.340199 1.000000 1.000000 1.000000 +vn -0.715174 0.577637 -0.393525 +v 162.194275 -145.900757 28.559799 1.000000 1.000000 1.000000 +vn -0.812418 0.583019 -0.008054 +v 162.472366 -145.251923 29.296198 1.000000 1.000000 1.000000 +vn -0.902528 0.430581 0.006674 +v 162.816132 -144.689606 29.179598 1.000000 1.000000 1.000000 +vn -0.589539 0.673268 0.446268 +v 162.185257 -145.889587 30.236597 1.000000 1.000000 1.000000 +vn -0.524801 0.781378 0.337686 +v 161.697311 -146.337494 30.351599 1.000000 1.000000 1.000000 +vn -0.416281 0.830981 0.369027 +v 161.151413 -146.710037 30.467798 1.000000 1.000000 1.000000 +vn -0.269424 0.863351 0.426657 +v 160.570770 -146.993301 30.582598 1.000000 1.000000 1.000000 +vn -0.105219 0.922979 0.370187 +v 159.954056 -147.184464 30.697998 1.000000 1.000000 1.000000 +vn -0.709433 0.428478 -0.559564 +v 162.623001 -145.377502 28.443998 1.000000 1.000000 1.000000 +vn -0.947883 -0.005336 0.318574 +v 163.555145 -142.183578 29.553999 1.000000 1.000000 1.000000 +vn -0.937365 -0.061434 0.342889 +v 163.486908 -141.492889 29.438599 1.000000 1.000000 1.000000 +vn -0.700837 -0.092582 0.707288 +v 163.555145 -140.739410 29.670998 1.000000 1.000000 1.000000 +vn -0.603330 -0.353436 0.714896 +v 162.543182 -138.861282 29.324999 1.000000 1.000000 1.000000 +vn -0.891464 -0.207376 0.402848 +v 163.331116 -140.820328 29.323198 1.000000 1.000000 1.000000 +vn -0.872416 -0.338975 0.352116 +v 163.090363 -140.181274 29.208599 1.000000 1.000000 1.000000 +vn 0.495896 -0.549223 -0.672637 +v 156.432800 -137.958511 25.821798 1.000000 1.000000 1.000000 +vn 0.473782 -0.762939 -0.439835 +v 157.130615 -137.844101 26.272799 1.000000 1.000000 1.000000 +vn 0.673519 -0.623654 -0.396772 +v 156.043976 -138.587799 26.041401 1.000000 1.000000 1.000000 +vn 0.227134 -0.191173 -0.954915 +v 157.601837 -137.128281 25.916798 1.000000 1.000000 1.000000 +vn 0.312230 -0.586666 -0.747218 +v 157.662338 -137.355728 26.052799 1.000000 1.000000 1.000000 +vn 0.669848 -0.313107 -0.673251 +v 154.989532 -139.494766 25.474199 1.000000 1.000000 1.000000 +vn 0.126762 -0.243750 -0.961518 +v 159.709427 -136.966431 26.263998 1.000000 1.000000 1.000000 +vn 0.148172 -0.731417 -0.665638 +v 158.997467 -137.150604 26.283398 1.000000 1.000000 1.000000 +vn 0.313284 -0.814459 -0.488375 +v 157.729294 -137.604095 26.387398 1.000000 1.000000 1.000000 +vn -0.076600 -0.668019 -0.740191 +v 160.344162 -137.355728 26.515999 1.000000 1.000000 1.000000 +vn 0.115881 -0.885212 -0.450523 +v 158.998749 -137.408737 26.618198 1.000000 1.000000 1.000000 +vn -0.069579 -0.881301 -0.467405 +v 159.645065 -137.457581 26.734598 1.000000 1.000000 1.000000 +vn 0.041796 -0.269384 -0.962125 +v 161.066437 -137.393402 26.495398 1.000000 1.000000 1.000000 +vn -0.299172 -0.825800 -0.478071 +v 160.879761 -137.845490 26.965998 1.000000 1.000000 1.000000 +vn -0.322665 -0.646028 -0.691763 +v 161.506760 -137.912460 26.733398 1.000000 1.000000 1.000000 +vn -0.147352 -0.961111 -0.233567 +v 159.625748 -137.605499 27.132198 1.000000 1.000000 1.000000 +vn -0.499357 -0.653189 -0.569199 +v 161.912323 -138.540359 27.184799 1.000000 1.000000 1.000000 +vn -0.389304 -0.888138 -0.244241 +v 160.821823 -137.982224 27.363398 1.000000 1.000000 1.000000 +vn -0.652519 -0.646614 -0.395108 +v 162.379669 -139.023148 27.300598 1.000000 1.000000 1.000000 +vn -0.574948 -0.474523 -0.666531 +v 162.973206 -139.423599 27.080999 1.000000 1.000000 1.000000 +vn -0.040995 -0.246682 -0.968229 +v 162.716995 -138.689667 26.829998 1.000000 1.000000 1.000000 +vn -0.669726 -0.742558 -0.008630 +v 161.791290 -138.699432 28.036999 1.000000 1.000000 1.000000 +vn -0.519465 -0.854467 0.006512 +v 161.284027 -138.308746 27.920399 1.000000 1.000000 1.000000 +vn -0.738187 -0.513055 0.438012 +v 162.369370 -139.032913 28.977198 1.000000 1.000000 1.000000 +vn -0.835431 -0.443481 0.324623 +v 162.765915 -139.577087 29.092398 1.000000 1.000000 1.000000 +vn -0.633923 -0.707532 0.312313 +v 161.903305 -138.551529 28.861399 1.000000 1.000000 1.000000 +vn -0.507799 -0.732303 0.453731 +v 160.873322 -137.858047 28.642599 1.000000 1.000000 1.000000 +vn -0.431032 -0.526367 0.732904 +v 160.971161 -137.625031 28.990198 1.000000 1.000000 1.000000 +vn -0.313410 -0.949047 0.032936 +v 160.224426 -137.802231 27.703199 1.000000 1.000000 1.000000 +vn -0.350431 -0.835149 0.423939 +v 160.274643 -137.618042 28.527399 1.000000 1.000000 1.000000 +vn -0.144004 -0.989564 0.005073 +v 159.618027 -137.661301 27.586998 1.000000 1.000000 1.000000 +vn -0.210785 -0.644085 0.735339 +v 159.675964 -137.217590 28.758799 1.000000 1.000000 1.000000 +vn -0.228478 -0.861700 0.453068 +v 159.643784 -137.471542 28.411198 1.000000 1.000000 1.000000 +vn 0.023475 -0.999670 0.010439 +v 158.998749 -137.615250 27.470398 1.000000 1.000000 1.000000 +vn -0.030583 -0.938071 0.345090 +v 158.998749 -137.422699 28.294798 1.000000 1.000000 1.000000 +vn 0.284458 -0.957367 0.050320 +v 157.782074 -137.802231 27.239798 1.000000 1.000000 1.000000 +vn 0.301859 -0.922953 -0.238830 +v 157.767914 -137.749207 26.784998 1.000000 1.000000 1.000000 +vn 0.037619 -0.928175 0.370238 +v 158.358871 -137.472931 28.179398 1.000000 1.000000 1.000000 +vn 0.205049 -0.880499 0.427407 +v 157.733154 -137.618042 28.063999 1.000000 1.000000 1.000000 +vn 0.583380 -0.810555 0.051653 +v 156.661972 -138.350601 27.008799 1.000000 1.000000 1.000000 +vn 0.414378 -0.862809 -0.289573 +v 157.187256 -137.980835 26.670198 1.000000 1.000000 1.000000 +vn 0.468317 -0.816128 0.338547 +v 156.567993 -138.188736 27.833199 1.000000 1.000000 1.000000 +vn 0.771430 -0.636261 -0.008197 +v 155.725967 -139.214310 26.777798 1.000000 1.000000 1.000000 +vn 0.355762 -0.858742 0.368776 +v 157.135773 -137.856659 27.949398 1.000000 1.000000 1.000000 +vn 0.079433 -0.675775 0.732815 +v 157.667496 -137.372467 28.411798 1.000000 1.000000 1.000000 +vn 0.368936 -0.578881 0.727175 +v 155.899780 -138.405014 28.065598 1.000000 1.000000 1.000000 +vn 0.540577 -0.712059 0.448050 +v 156.052994 -138.598969 27.717999 1.000000 1.000000 1.000000 +vn 0.872170 -0.489164 0.006139 +v 155.347458 -139.750122 26.661198 1.000000 1.000000 1.000000 +vn 0.734419 -0.603779 0.309966 +v 155.593353 -139.087341 27.602198 1.000000 1.000000 1.000000 +vn 0.953266 -0.300401 0.032289 +v 154.844040 -140.880341 26.443998 1.000000 1.000000 1.000000 +vn 0.899698 -0.369149 -0.232964 +v 155.030731 -140.238480 26.104198 1.000000 1.000000 1.000000 +vn 0.678106 -0.474044 -0.561654 +v 155.583069 -139.077576 25.925598 1.000000 1.000000 1.000000 +vn 0.841988 -0.291804 -0.453770 +v 154.905853 -140.172897 25.706799 1.000000 1.000000 1.000000 +vn 0.963646 -0.156006 -0.216907 +v 154.643204 -141.522202 25.872999 1.000000 1.000000 1.000000 +vn 0.755819 -0.481354 0.443887 +v 154.918732 -140.178482 27.383398 1.000000 1.000000 1.000000 +vn 0.987997 -0.154368 0.005674 +v 154.693405 -141.531952 26.327799 1.000000 1.000000 1.000000 +vn 0.850949 -0.336147 0.403598 +v 154.676666 -140.820328 27.268198 1.000000 1.000000 1.000000 +vn 0.549294 -0.412400 0.726775 +v 154.706284 -140.065475 27.730997 1.000000 1.000000 1.000000 +vn 0.999892 -0.011611 0.009009 +v 154.629028 -142.201721 26.211199 1.000000 1.000000 1.000000 +vn 0.873992 -0.227648 0.429320 +v 154.519592 -141.498474 27.151999 1.000000 1.000000 1.000000 +vn 0.667394 -0.210072 0.714461 +v 154.286560 -141.453827 27.499598 1.000000 1.000000 1.000000 +vn 0.027004 -0.265434 0.963751 +v 155.740128 -138.201294 28.220198 1.000000 1.000000 1.000000 +vn 0.143405 -0.239258 0.960307 +v 154.486130 -139.948257 27.885599 1.000000 1.000000 1.000000 +vn -0.092429 -0.249218 0.964027 +v 157.597961 -137.115723 28.566399 1.000000 1.000000 1.000000 +vn 0.212160 -0.178583 0.960779 +v 154.044525 -141.407776 27.654198 1.000000 1.000000 1.000000 +vn 0.705555 0.047904 0.707035 +v 154.361237 -143.636124 27.152599 1.000000 1.000000 1.000000 +vn -0.258495 -0.198846 0.945326 +v 153.891312 -143.764496 27.303398 1.000000 1.000000 1.000000 +vn 0.266345 -0.090882 0.959584 +v 154.121765 -143.701706 27.307198 1.000000 1.000000 1.000000 +vn 0.938988 0.001760 0.343946 +v 154.477112 -142.889618 26.920198 1.000000 1.000000 1.000000 +vn 0.945933 -0.054333 0.319778 +v 154.452652 -142.196136 27.035599 1.000000 1.000000 1.000000 +vn 0.903130 0.150006 0.402312 +v 154.589127 -143.571930 26.804798 1.000000 1.000000 1.000000 +vn 0.975517 0.214820 0.047097 +v 154.761642 -143.525894 25.980598 1.000000 1.000000 1.000000 +vn -0.244273 -0.373681 0.894814 +v 154.872375 -145.911911 26.957399 1.000000 1.000000 1.000000 +vn -0.034219 -0.342865 0.938761 +v 156.515198 -147.397949 26.622599 1.000000 1.000000 1.000000 +vn 0.071445 -0.348810 0.934466 +v 157.908249 -147.950485 26.391199 1.000000 1.000000 1.000000 +vn 0.209145 -0.251922 0.944878 +v 160.126587 -147.944916 26.044197 1.000000 1.000000 1.000000 +vn 0.078529 -0.620966 0.779894 +v 158.635681 -148.303513 26.134199 1.000000 1.000000 1.000000 +vn 0.323713 -0.178954 0.929078 +v 162.140198 -146.954224 25.698198 1.000000 1.000000 1.000000 +vn 0.256769 -0.616547 0.744271 +v 160.174210 -148.180725 25.903599 1.000000 1.000000 1.000000 +vn 0.405883 -0.488416 0.772469 +v 161.621338 -147.597473 25.672798 1.000000 1.000000 1.000000 +vn 0.593544 -0.281317 0.754034 +v 163.380051 -145.966324 25.324999 1.000000 1.000000 1.000000 +vn 0.541373 -0.355001 0.762161 +v 162.863770 -146.602600 25.441599 1.000000 1.000000 1.000000 +vn 0.691057 -0.562575 0.453817 +v 163.029846 -146.785385 25.103998 1.000000 1.000000 1.000000 +vn 0.770011 -0.446951 0.455321 +v 163.568008 -146.121216 24.987398 1.000000 1.000000 1.000000 +vn 0.660184 -0.149106 0.736155 +v 164.099747 -144.596115 25.107798 1.000000 1.000000 1.000000 +vn 0.869970 -0.135557 0.474105 +v 164.570969 -143.855194 24.653799 1.000000 1.000000 1.000000 +vn 0.647381 0.052452 0.760359 +v 164.474411 -142.959381 24.874998 1.000000 1.000000 1.000000 +vn 0.849478 -0.271514 0.452401 +v 164.319901 -144.692383 24.769999 1.000000 1.000000 1.000000 +vn 0.896514 -0.026205 0.442240 +v 164.710007 -142.985901 24.537399 1.000000 1.000000 1.000000 +vn 0.875977 0.092978 0.473308 +v 164.734467 -142.112411 24.421997 1.000000 1.000000 1.000000 +vn 0.968217 -0.202431 0.146891 +v 164.717743 -143.895660 24.185398 1.000000 1.000000 1.000000 +vn 0.986382 -0.073857 0.146957 +v 164.860641 -143.002640 24.068998 1.000000 1.000000 1.000000 +vn 0.987546 0.054500 0.147589 +v 164.886398 -142.105438 23.953598 1.000000 1.000000 1.000000 +vn 0.872029 0.205467 0.444240 +v 164.646927 -141.243118 24.306599 1.000000 1.000000 1.000000 +vn 0.971959 0.182956 0.147729 +v 164.796280 -141.213821 23.838398 1.000000 1.000000 1.000000 +vn 0.932555 -0.329185 0.148252 +v 164.460236 -144.755173 24.301598 1.000000 1.000000 1.000000 +vn 0.955468 -0.241190 -0.170024 +v 164.704865 -143.891464 23.369999 1.000000 1.000000 1.000000 +vn 0.881315 -0.443438 0.163239 +v 164.095886 -145.558899 24.416798 1.000000 1.000000 1.000000 +vn 0.911040 -0.375903 -0.169419 +v 164.448654 -144.749603 23.486198 1.000000 1.000000 1.000000 +vn 0.789917 -0.575108 -0.212793 +v 163.678741 -146.211914 23.703598 1.000000 1.000000 1.000000 +vn 0.817827 -0.555468 0.150382 +v 163.689041 -146.220276 24.518999 1.000000 1.000000 1.000000 +vn 0.797340 -0.364944 -0.480692 +v 164.325058 -144.695175 23.092999 1.000000 1.000000 1.000000 +vn 0.761783 -0.492834 -0.420478 +v 163.969711 -145.479355 23.208199 1.000000 1.000000 1.000000 +vn 0.702083 -0.689848 -0.176607 +v 163.127701 -146.892838 23.820198 1.000000 1.000000 1.000000 +vn 0.610861 -0.638704 -0.467875 +v 163.033707 -146.789566 23.426998 1.000000 1.000000 1.000000 +vn 0.734720 -0.661084 0.152164 +v 163.136703 -146.902603 24.635599 1.000000 1.000000 1.000000 +vn 0.633259 -0.758677 0.152944 +v 162.504562 -147.487244 24.751598 1.000000 1.000000 1.000000 +vn 0.595574 -0.783452 -0.177465 +v 162.496826 -147.476089 23.935999 1.000000 1.000000 1.000000 +vn 0.502701 -0.729528 -0.463768 +v 162.418304 -147.360275 23.542999 1.000000 1.000000 1.000000 +vn 0.311902 -0.593275 -0.742120 +v 162.276672 -147.153763 23.198399 1.000000 1.000000 1.000000 +vn 0.398879 -0.476972 -0.783194 +v 162.867630 -146.606781 23.082600 1.000000 1.000000 1.000000 +vn 0.378907 -0.780689 -0.496944 +v 161.737228 -147.829102 23.658001 1.000000 1.000000 1.000000 +vn 0.516731 -0.842003 0.154984 +v 161.806747 -147.968628 24.866598 1.000000 1.000000 1.000000 +vn 0.475813 -0.861022 -0.179561 +v 161.800308 -147.956085 24.051197 1.000000 1.000000 1.000000 +vn 0.596475 -0.638271 0.486650 +v 162.414444 -147.356079 25.219801 1.000000 1.000000 1.000000 +vn 0.501694 -0.731544 0.461678 +v 161.734650 -147.823517 25.334999 1.000000 1.000000 1.000000 +vn 0.387575 -0.908533 0.156057 +v 161.047134 -148.341187 24.982798 1.000000 1.000000 1.000000 +vn 0.342952 -0.921857 -0.180455 +v 161.041977 -148.328629 24.167398 1.000000 1.000000 1.000000 +vn 0.266630 -0.841221 -0.470378 +v 160.996918 -148.193283 23.774199 1.000000 1.000000 1.000000 +vn 0.247166 -0.956155 0.157088 +v 160.256622 -148.592346 25.097601 1.000000 1.000000 1.000000 +vn 0.200859 -0.962617 -0.181724 +v 160.254044 -148.578400 24.281998 1.000000 1.000000 1.000000 +vn 0.137430 -0.871089 -0.471505 +v 160.225708 -148.437469 23.888998 1.000000 1.000000 1.000000 +vn 0.387197 -0.778837 0.493448 +v 160.994339 -148.187714 25.451199 1.000000 1.000000 1.000000 +vn 0.265718 -0.843342 0.467085 +v 160.224426 -148.431885 25.565798 1.000000 1.000000 1.000000 +vn 0.100046 -0.982443 0.157469 +v 159.437775 -148.720718 25.212799 1.000000 1.000000 1.000000 +vn 0.052987 -0.981916 -0.181752 +v 159.436493 -148.706757 24.397398 1.000000 1.000000 1.000000 +vn -0.001091 -0.865400 -0.501081 +v 159.427475 -148.563049 24.004198 1.000000 1.000000 1.000000 +vn 0.022139 -0.664907 -0.746598 +v 160.175507 -148.186310 23.544399 1.000000 1.000000 1.000000 +vn -0.135309 -0.591818 -0.794634 +v 158.635681 -148.309097 23.775198 1.000000 1.000000 1.000000 +vn -0.130531 -0.871882 -0.471999 +v 158.618942 -148.565842 24.119598 1.000000 1.000000 1.000000 +vn -0.050156 -0.986071 0.158583 +v 158.609924 -148.723511 25.328199 1.000000 1.000000 1.000000 +vn -0.096606 -0.978643 -0.181452 +v 158.609924 -148.709564 24.512798 1.000000 1.000000 1.000000 +vn 0.138004 -0.856210 0.497854 +v 159.426193 -148.557465 25.681198 1.000000 1.000000 1.000000 +vn 0.001418 -0.882924 0.469514 +v 158.620239 -148.558868 25.796598 1.000000 1.000000 1.000000 +vn -0.243563 -0.952915 -0.180639 +v 157.784653 -148.585373 24.629198 1.000000 1.000000 1.000000 +vn -0.199042 -0.967224 0.157672 +v 157.782074 -148.599335 25.444799 1.000000 1.000000 1.000000 +vn -0.260616 -0.843790 -0.469146 +v 157.811691 -148.444443 24.235998 1.000000 1.000000 1.000000 +vn -0.395632 -0.901158 -0.177172 +v 156.983841 -148.337006 24.745398 1.000000 1.000000 1.000000 +vn -0.383016 -0.779118 -0.496259 +v 157.030197 -148.201645 24.352198 1.000000 1.000000 1.000000 +vn -0.343248 -0.926082 0.156695 +v 156.979980 -148.349564 25.560799 1.000000 1.000000 1.000000 +vn -0.125091 -0.857734 0.498643 +v 157.812973 -148.438873 25.912998 1.000000 1.000000 1.000000 +vn -0.278118 -0.835288 0.474284 +v 157.031479 -148.196075 26.029198 1.000000 1.000000 1.000000 +vn -0.146553 -0.636943 0.756853 +v 157.113876 -147.954681 26.366999 1.000000 1.000000 1.000000 +vn -0.470540 -0.865739 0.170552 +v 156.225510 -147.982590 25.675999 1.000000 1.000000 1.000000 +vn -0.469723 -0.748000 0.468888 +v 155.689926 -147.430038 26.246599 1.000000 1.000000 1.000000 +vn -0.302965 -0.563122 0.768834 +v 155.826385 -147.220734 26.584198 1.000000 1.000000 1.000000 +vn -0.632623 -0.570279 0.523994 +v 154.511871 -146.223068 26.478998 1.000000 1.000000 1.000000 +vn -0.568963 -0.629920 0.528661 +v 155.059052 -146.870514 26.363199 1.000000 1.000000 1.000000 +vn -0.506680 -0.391644 0.768043 +v 154.260818 -145.371918 26.931999 1.000000 1.000000 1.000000 +vn -0.755099 -0.476312 0.450502 +v 154.057388 -145.501678 26.594198 1.000000 1.000000 1.000000 +vn -0.860065 -0.487324 0.151007 +v 153.926071 -145.585403 26.125799 1.000000 1.000000 1.000000 +vn -0.784934 -0.600589 0.152223 +v 154.392136 -146.324921 26.010799 1.000000 1.000000 1.000000 +vn -0.692010 -0.705482 0.153029 +v 154.954773 -146.989120 25.894798 1.000000 1.000000 1.000000 +vn -0.807221 -0.564105 -0.173723 +v 154.402451 -146.316559 25.195198 1.000000 1.000000 1.000000 +vn -0.587906 -0.793939 0.155008 +v 155.602371 -147.563980 25.778198 1.000000 1.000000 1.000000 +vn -0.720266 -0.671352 -0.174652 +v 154.963776 -146.979340 25.079399 1.000000 1.000000 1.000000 +vn -0.607305 -0.764953 -0.214540 +v 155.608810 -147.552826 24.962799 1.000000 1.000000 1.000000 +vn -0.876942 -0.448979 -0.171437 +v 153.937668 -145.578430 25.310398 1.000000 1.000000 1.000000 +vn -0.665970 -0.583936 -0.464223 +v 155.055191 -146.874695 24.686199 1.000000 1.000000 1.000000 +vn -0.518334 -0.738946 -0.430451 +v 156.295044 -147.843063 24.467398 1.000000 1.000000 1.000000 +vn -0.500296 -0.380012 -0.778007 +v 155.217407 -146.687714 24.341799 1.000000 1.000000 1.000000 +vn -0.440404 -0.515115 -0.735323 +v 156.407043 -147.617004 24.122999 1.000000 1.000000 1.000000 +vn -0.753190 -0.477367 -0.452577 +v 154.506729 -146.225861 24.802198 1.000000 1.000000 1.000000 +vn -0.266401 -0.617336 -0.740221 +v 157.860611 -148.193283 23.891598 1.000000 1.000000 1.000000 +vn 0.140143 -0.591184 -0.794268 +v 160.914520 -147.951889 23.429798 1.000000 1.000000 1.000000 +vn 0.535860 -0.421835 -0.731375 +v 163.764999 -145.350983 22.863800 1.000000 1.000000 1.000000 +vn 0.639660 -0.260294 -0.723244 +v 164.345657 -143.795197 22.632397 1.000000 1.000000 1.000000 +vn 0.612080 -0.140994 -0.778125 +v 164.479553 -142.960785 22.515999 1.000000 1.000000 1.000000 +vn 0.857122 -0.255871 -0.447071 +v 164.576126 -143.856583 22.976801 1.000000 1.000000 1.000000 +vn 0.883782 -0.142025 -0.445822 +v 164.715164 -142.985901 22.860397 1.000000 1.000000 1.000000 +vn 0.978870 -0.114067 -0.169710 +v 164.847778 -143.001251 23.253597 1.000000 1.000000 1.000000 +vn 0.985545 0.013962 -0.168837 +v 164.873535 -142.105438 23.138199 1.000000 1.000000 1.000000 +vn 0.879604 -0.030002 -0.474761 +v 164.740921 -142.112411 22.744999 1.000000 1.000000 1.000000 +vn 0.691880 -0.002822 -0.722007 +v 164.419037 -141.287781 22.285198 1.000000 1.000000 1.000000 +vn 0.871244 0.205987 -0.445537 +v 164.452515 -140.398956 22.514999 1.000000 1.000000 1.000000 +vn 0.621853 0.103179 -0.776307 +v 164.228500 -140.479874 22.170597 1.000000 1.000000 1.000000 +vn 0.890866 0.091796 -0.444894 +v 164.652084 -141.241730 22.629799 1.000000 1.000000 1.000000 +vn 0.975117 0.142572 -0.169764 +v 164.783401 -141.216614 23.022797 1.000000 1.000000 1.000000 +vn 0.948169 0.268446 -0.170038 +v 164.578690 -140.354294 22.908199 1.000000 1.000000 1.000000 +vn 0.894712 -0.089269 -0.437631 +v 154.506729 -141.495682 25.475401 1.000000 1.000000 1.000000 +vn 0.903595 0.071371 -0.422400 +v 154.439774 -142.194733 25.358999 1.000000 1.000000 1.000000 +vn 0.695004 -0.090984 -0.713226 +v 154.437210 -140.735229 25.256798 1.000000 1.000000 1.000000 +vn 0.946479 0.231685 -0.224723 +v 154.711441 -143.538452 25.525799 1.000000 1.000000 1.000000 +vn 0.900699 0.335492 -0.276020 +v 154.905853 -144.176117 25.410999 1.000000 1.000000 1.000000 +vn -0.686973 0.601251 0.408125 +v 162.588242 -145.402618 40.425320 1.000000 1.000000 1.000000 +vn -0.555468 0.411514 0.722572 +v 163.150879 -144.956116 40.657719 1.000000 1.000000 1.000000 +vn -0.774145 0.482397 0.409868 +v 162.946167 -144.829132 40.310120 1.000000 1.000000 1.000000 +vn -0.609008 0.674199 0.417809 +v 162.154358 -145.920288 40.541321 1.000000 1.000000 1.000000 +vn -0.390385 0.565786 0.726282 +v 162.317871 -146.105865 40.889118 1.000000 1.000000 1.000000 +vn -0.870596 0.490764 0.034839 +v 162.792953 -144.732849 39.485718 1.000000 1.000000 1.000000 +vn -0.892164 0.334372 0.303710 +v 163.228119 -144.201233 40.194118 1.000000 1.000000 1.000000 +vn -0.982777 0.180625 -0.039037 +v 163.255157 -143.488220 39.253319 1.000000 1.000000 1.000000 +vn -0.714937 0.696889 0.056661 +v 162.032043 -145.782135 39.717117 1.000000 1.000000 1.000000 +vn -0.840010 0.500010 -0.210648 +v 162.838013 -144.760757 39.030918 1.000000 1.000000 1.000000 +vn -0.886058 0.244280 -0.393990 +v 163.240997 -144.206818 38.517540 1.000000 1.000000 1.000000 +vn -0.688661 0.548201 -0.474575 +v 162.164673 -145.931442 38.864918 1.000000 1.000000 1.000000 +vn -0.728660 0.643997 -0.233072 +v 162.068100 -145.822617 39.262318 1.000000 1.000000 1.000000 +vn -0.802230 0.372874 -0.466253 +v 162.957748 -144.836121 38.633518 1.000000 1.000000 1.000000 +vn -0.432445 0.503740 -0.747822 +v 161.238968 -146.969574 38.760117 1.000000 1.000000 1.000000 +vn -0.504661 0.715716 -0.482771 +v 161.128250 -146.740738 39.094917 1.000000 1.000000 1.000000 +vn -0.562270 0.369579 -0.739773 +v 162.329468 -146.118423 38.530136 1.000000 1.000000 1.000000 +vn -0.533489 0.815272 -0.225212 +v 161.063858 -146.606781 39.492317 1.000000 1.000000 1.000000 +vn -0.512572 0.857235 0.049182 +v 161.039413 -146.557953 39.947121 1.000000 1.000000 1.000000 +vn -0.302451 0.692184 -0.655289 +v 159.955338 -147.463516 38.991718 1.000000 1.000000 1.000000 +vn -0.287855 0.840544 -0.458939 +v 159.908997 -147.210968 39.326519 1.000000 1.000000 1.000000 +vn -0.120972 0.872845 -0.472766 +v 159.260101 -147.300278 39.440720 1.000000 1.000000 1.000000 +vn -0.371246 0.928454 -0.012273 +v 160.470337 -146.828644 40.063316 1.000000 1.000000 1.000000 +vn -0.094266 0.668761 -0.737477 +v 159.002609 -147.565384 39.150116 1.000000 1.000000 1.000000 +vn -0.170488 0.266911 -0.948521 +v 159.285858 -147.795609 38.970116 1.000000 1.000000 1.000000 +vn -0.297384 0.195352 -0.934559 +v 161.340683 -147.178879 38.624321 1.000000 1.000000 1.000000 +vn 0.085347 0.882505 -0.462493 +v 158.352432 -147.257019 39.595741 1.000000 1.000000 1.000000 +vn 0.036048 0.606257 -0.794451 +v 157.643036 -147.353302 39.370739 1.000000 1.000000 1.000000 +vn 0.251447 0.616201 -0.746372 +v 156.392883 -146.729568 39.583336 1.000000 1.000000 1.000000 +vn 0.322578 0.838825 -0.438539 +v 157.094559 -146.855164 39.813137 1.000000 1.000000 1.000000 +vn 0.013101 0.999502 -0.028695 +v 159.003891 -147.102142 40.337120 1.000000 1.000000 1.000000 +vn -0.059972 0.963391 -0.261307 +v 159.252380 -147.149567 39.838120 1.000000 1.000000 1.000000 +vn -0.253228 0.960833 -0.112588 +v 159.870361 -147.008652 40.178719 1.000000 1.000000 1.000000 +vn -0.008334 0.972179 0.234092 +v 159.251099 -147.143997 40.723518 1.000000 1.000000 1.000000 +vn 0.325611 0.858022 0.397211 +v 157.713837 -147.090973 41.382137 1.000000 1.000000 1.000000 +vn 0.284581 0.957097 0.054581 +v 157.764053 -146.906784 40.557739 1.000000 1.000000 1.000000 +vn -0.111268 0.897431 0.426892 +v 159.906418 -147.195618 41.003120 1.000000 1.000000 1.000000 +vn 0.043447 0.880478 0.472092 +v 159.258820 -147.286316 41.117317 1.000000 1.000000 1.000000 +vn -0.071327 0.936465 0.343433 +v 159.271698 -147.541656 41.464920 1.000000 1.000000 1.000000 +vn -0.126722 0.671371 0.730208 +v 160.609390 -147.250031 41.235317 1.000000 1.000000 1.000000 +vn -0.230413 0.861020 0.453381 +v 160.529556 -147.008652 40.887718 1.000000 1.000000 1.000000 +vn 0.231065 0.783469 0.576875 +v 158.355011 -147.243057 41.272339 1.000000 1.000000 1.000000 +vn 0.227727 0.633693 0.739306 +v 158.321533 -147.495621 41.619919 1.000000 1.000000 1.000000 +vn 0.404383 0.550593 0.730289 +v 157.001862 -147.074219 41.837318 1.000000 1.000000 1.000000 +vn -0.490850 0.791629 0.363854 +v 161.666412 -146.362595 40.656120 1.000000 1.000000 1.000000 +vn -0.873295 0.216762 0.436314 +v 163.526825 -142.928680 39.975319 1.000000 1.000000 1.000000 +vn -0.660167 0.216317 0.719296 +v 163.761139 -142.957993 40.323120 1.000000 1.000000 1.000000 +vn -0.915495 0.052712 0.398861 +v 163.556427 -142.236603 39.860317 1.000000 1.000000 1.000000 +vn -0.702068 -0.007824 0.712067 +v 163.727661 -141.498474 40.091740 1.000000 1.000000 1.000000 +vn -0.987068 -0.160206 0.005464 +v 163.320816 -141.572418 38.919739 1.000000 1.000000 1.000000 +vn -0.999396 -0.011315 0.032850 +v 163.380051 -142.240799 39.035919 1.000000 1.000000 1.000000 +vn -0.972275 0.056045 -0.227025 +v 163.401932 -142.913330 38.696320 1.000000 1.000000 1.000000 +vn -0.964206 -0.150693 -0.218169 +v 163.371033 -141.562653 38.464939 1.000000 1.000000 1.000000 +vn -0.892578 0.014104 -0.450672 +v 163.539703 -142.930084 38.298721 1.000000 1.000000 1.000000 +vn -0.740792 0.082513 -0.666647 +v 163.671021 -143.598450 38.066319 1.000000 1.000000 1.000000 +vn -0.648380 0.218678 -0.729235 +v 163.163757 -144.964478 38.298721 1.000000 1.000000 1.000000 +vn -0.877255 -0.193504 -0.439295 +v 163.508789 -141.537537 38.067539 1.000000 1.000000 1.000000 +vn -0.688493 -0.128970 -0.713684 +v 163.808777 -142.229630 37.848919 1.000000 1.000000 1.000000 +vn -0.295705 0.075461 -0.952294 +v 162.480087 -146.288651 38.394119 1.000000 1.000000 1.000000 +vn -0.902522 -0.055159 0.427096 +v 163.494629 -141.540329 39.744141 1.000000 1.000000 1.000000 +vn -0.438096 0.832413 0.339354 +v 161.121796 -146.728180 40.771519 1.000000 1.000000 1.000000 +vn 0.473792 0.758079 0.448149 +v 157.100998 -146.842606 41.489738 1.000000 1.000000 1.000000 +vn 0.579597 0.721816 0.378218 +v 156.529358 -146.500748 41.594540 1.000000 1.000000 1.000000 +vn 0.707503 0.577226 0.407738 +v 155.897202 -145.966324 41.720718 1.000000 1.000000 1.000000 +vn 0.556708 0.828977 0.053599 +v 156.625916 -146.340271 40.770340 1.000000 1.000000 1.000000 +vn 0.735117 0.675965 0.051724 +v 156.018234 -145.825409 40.896339 1.000000 1.000000 1.000000 +vn 0.517924 0.818645 -0.248143 +v 156.597595 -146.386337 40.315536 1.000000 1.000000 1.000000 +vn 0.590629 0.649044 -0.479477 +v 155.888199 -145.977493 40.044140 1.000000 1.000000 1.000000 +vn 0.685050 0.690048 -0.233536 +v 155.983459 -145.867264 40.441540 1.000000 1.000000 1.000000 +vn 0.445884 0.753624 -0.482947 +v 156.521637 -146.513306 39.917938 1.000000 1.000000 1.000000 +vn 0.486545 0.639993 -0.594712 +v 155.725967 -146.165863 39.709339 1.000000 1.000000 1.000000 +vn -0.237433 -0.002078 -0.971402 +v 154.471970 -145.246338 39.768337 1.000000 1.000000 1.000000 +vn 0.450156 0.363629 -0.815557 +v 154.860779 -144.997971 39.909138 1.000000 1.000000 1.000000 +vn 0.723641 0.504690 -0.470779 +v 155.066788 -144.866806 40.243938 1.000000 1.000000 1.000000 +vn -0.339688 0.031808 -0.940000 +v 153.905472 -143.744949 39.957539 1.000000 1.000000 1.000000 +vn -0.653949 -0.158483 -0.739752 +v 153.910614 -144.617035 40.015339 1.000000 1.000000 1.000000 +vn -0.672962 0.009631 -0.739615 +v 153.528244 -142.960785 40.201340 1.000000 1.000000 1.000000 +vn -0.272178 0.121498 -0.954546 +v 153.750977 -142.112411 40.140938 1.000000 1.000000 1.000000 +vn -0.866601 -0.149985 -0.475928 +v 153.436829 -143.871933 40.452938 1.000000 1.000000 1.000000 +vn -0.894542 -0.039383 -0.445245 +v 153.292633 -142.987289 40.545738 1.000000 1.000000 1.000000 +vn -0.682485 0.113240 -0.722075 +v 153.505066 -142.101257 40.291939 1.000000 1.000000 1.000000 +vn -0.250147 0.180237 -0.951284 +v 154.031647 -140.510574 40.313938 1.000000 1.000000 1.000000 +vn -0.625867 0.273781 -0.730298 +v 153.798615 -140.424057 40.464939 1.000000 1.000000 1.000000 +vn -0.891443 0.079034 -0.446186 +v 153.268173 -142.090088 40.636337 1.000000 1.000000 1.000000 +vn -0.855870 0.196610 -0.478363 +v 153.363449 -141.199875 40.724339 1.000000 1.000000 1.000000 +vn -0.838660 0.308761 -0.448682 +v 153.574585 -140.341736 40.809540 1.000000 1.000000 1.000000 +vn -0.775256 0.410066 -0.480442 +v 153.874573 -139.567337 40.888138 1.000000 1.000000 1.000000 +vn -0.526328 0.424922 -0.736492 +v 154.493851 -138.939423 40.626137 1.000000 1.000000 1.000000 +vn -0.725876 0.516896 -0.453786 +v 154.299438 -138.792923 40.970737 1.000000 1.000000 1.000000 +vn -0.629581 0.603562 -0.489224 +v 154.822159 -138.093857 41.050938 1.000000 1.000000 1.000000 +vn -0.371142 0.550931 -0.747482 +v 155.579193 -137.687820 40.784340 1.000000 1.000000 1.000000 +vn -0.934684 0.311792 -0.170737 +v 153.448410 -140.294296 41.202740 1.000000 1.000000 1.000000 +vn -0.885915 0.430957 -0.171552 +v 153.756134 -139.501740 41.281338 1.000000 1.000000 1.000000 +vn -0.819208 0.546830 -0.172844 +v 154.191299 -138.710602 41.363739 1.000000 1.000000 1.000000 +vn -0.733339 0.657084 -0.174512 +v 154.725601 -137.996185 41.444138 1.000000 1.000000 1.000000 +vn -0.546383 0.698216 -0.462558 +v 155.431137 -137.486877 41.128738 1.000000 1.000000 1.000000 +vn -0.838301 0.524251 0.149709 +v 154.179703 -138.702225 42.179337 1.000000 1.000000 1.000000 +vn -0.755050 0.638071 0.150883 +v 154.715302 -137.986420 42.259537 1.000000 1.000000 1.000000 +vn -0.901877 0.405584 0.148727 +v 153.744537 -139.496170 42.096741 1.000000 1.000000 1.000000 +vn -0.852302 0.221519 0.473825 +v 153.579742 -140.343140 42.486538 1.000000 1.000000 1.000000 +vn -0.827711 0.340109 0.446342 +v 153.879715 -139.570114 42.565140 1.000000 1.000000 1.000000 +vn -0.947084 0.284841 0.147976 +v 153.436829 -140.290115 42.018139 1.000000 1.000000 1.000000 +vn -0.771975 0.448156 0.450789 +v 154.304596 -138.795715 42.647537 1.000000 1.000000 1.000000 +vn -0.686432 0.542285 0.484497 +v 154.826019 -138.098038 42.727940 1.000000 1.000000 1.000000 +vn -0.653103 0.741526 0.153607 +v 155.341019 -137.362701 42.337337 1.000000 1.000000 1.000000 +vn -0.597336 0.204714 0.775423 +v 154.090866 -139.684540 42.902939 1.000000 1.000000 1.000000 +vn -0.544509 0.255367 0.798935 +v 154.499008 -138.943619 42.985336 1.000000 1.000000 1.000000 +vn -0.667133 0.046328 0.743497 +v 153.601624 -141.248718 42.739140 1.000000 1.000000 1.000000 +vn -0.600950 0.628439 0.493886 +v 155.434998 -137.492477 42.805740 1.000000 1.000000 1.000000 +vn -0.507888 0.733070 0.452391 +v 156.108353 -136.994339 42.879936 1.000000 1.000000 1.000000 +vn -0.537498 0.829018 0.154357 +v 156.032394 -136.853409 42.411537 1.000000 1.000000 1.000000 +vn -0.411513 0.895431 0.169881 +v 156.797165 -136.445969 42.485138 1.000000 1.000000 1.000000 +vn -0.380650 0.907148 -0.179408 +v 156.801025 -136.459915 41.669540 1.000000 1.000000 1.000000 +vn -0.511161 0.840906 -0.177738 +v 156.038834 -136.864563 41.596138 1.000000 1.000000 1.000000 +vn -0.629643 0.756543 -0.176615 +v 155.348740 -137.373871 41.521938 1.000000 1.000000 1.000000 +vn -0.256554 0.951510 0.169731 +v 157.610840 -136.161316 42.557137 1.000000 1.000000 1.000000 +vn -0.112905 0.966641 0.229909 +v 158.451569 -136.006439 42.627136 1.000000 1.000000 1.000000 +vn -0.238191 0.954085 -0.181621 +v 157.613419 -136.173874 41.741539 1.000000 1.000000 1.000000 +vn 0.022320 0.985514 0.168121 +v 159.302597 -135.985504 42.694538 1.000000 1.000000 1.000000 +vn -0.086394 0.979531 -0.181812 +v 158.452850 -136.020386 41.811539 1.000000 1.000000 1.000000 +vn -0.052064 0.879619 -0.472821 +v 158.465729 -136.164108 41.418339 1.000000 1.000000 1.000000 +vn -0.181673 0.845146 -0.502716 +v 157.645599 -136.314804 41.348537 1.000000 1.000000 1.000000 +vn 0.066460 0.981183 -0.181280 +v 159.301315 -135.999466 41.879139 1.000000 1.000000 1.000000 +vn 0.083926 0.877491 -0.472193 +v 159.294861 -136.143173 41.485939 1.000000 1.000000 1.000000 +vn 0.256418 0.942827 0.212900 +v 160.125290 -136.094345 42.758141 1.000000 1.000000 1.000000 +vn 0.207720 0.959930 -0.188112 +v 160.122726 -136.108292 41.942738 1.000000 1.000000 1.000000 +vn 0.216356 0.838509 -0.500093 +v 160.096970 -136.249237 41.549538 1.000000 1.000000 1.000000 +vn 0.110170 0.656368 -0.746354 +v 159.283279 -136.399918 41.141541 1.000000 1.000000 1.000000 +vn -0.009037 0.646804 -0.762603 +v 158.487610 -136.419449 41.073936 1.000000 1.000000 1.000000 +vn 0.293507 0.592673 -0.750062 +v 160.821823 -136.727829 41.268139 1.000000 1.000000 1.000000 +vn 0.184019 0.230608 -0.955488 +v 160.740707 -136.978989 41.117138 1.000000 1.000000 1.000000 +vn 0.105664 0.258639 -0.960178 +v 159.270401 -136.666428 40.990540 1.000000 1.000000 1.000000 +vn 0.344063 0.813265 -0.469277 +v 160.900360 -136.485046 41.612740 1.000000 1.000000 1.000000 +vn 0.403546 0.461485 -0.790052 +v 162.235474 -137.528748 41.388538 1.000000 1.000000 1.000000 +vn 0.457626 0.737802 -0.496212 +v 161.665115 -136.843628 41.673920 1.000000 1.000000 1.000000 +vn 0.359522 0.903397 -0.233703 +v 160.944138 -136.348297 42.005737 1.000000 1.000000 1.000000 +vn 0.572015 0.678318 -0.461177 +v 162.374512 -137.319443 41.733116 1.000000 1.000000 1.000000 +vn 0.493243 0.838737 -0.230722 +v 161.726913 -136.716660 42.067120 1.000000 1.000000 1.000000 +vn 0.533482 0.421794 -0.733135 +v 162.848312 -138.088272 41.445538 1.000000 1.000000 1.000000 +vn 0.292650 0.082991 -0.952611 +v 163.589905 -139.570114 41.400539 1.000000 1.000000 1.000000 +vn 0.624165 0.273751 -0.731764 +v 163.804916 -139.440353 41.551537 1.000000 1.000000 1.000000 +vn 0.729865 0.482063 -0.484678 +v 163.551270 -138.558502 41.843117 1.000000 1.000000 1.000000 +vn 0.664573 0.591030 -0.457194 +v 163.013107 -137.904099 41.790119 1.000000 1.000000 1.000000 +vn 0.613074 0.756389 -0.228069 +v 162.451767 -137.203629 42.126137 1.000000 1.000000 1.000000 +vn 0.715808 0.660674 -0.226118 +v 163.105804 -137.800842 42.183121 1.000000 1.000000 1.000000 +vn 0.803856 0.387535 -0.451255 +v 164.012192 -139.314774 41.895920 1.000000 1.000000 1.000000 +vn 0.801840 0.554150 -0.223541 +v 163.656845 -138.470596 42.236320 1.000000 1.000000 1.000000 +vn 0.835793 0.267236 -0.479619 +v 164.367538 -140.135223 41.946716 1.000000 1.000000 1.000000 +vn 0.871368 0.437551 -0.221960 +v 164.128082 -139.243607 42.289120 1.000000 1.000000 1.000000 +vn 0.896872 0.440772 0.036624 +v 164.169266 -139.218491 42.694519 1.000000 1.000000 1.000000 +vn 0.816202 0.574379 -0.062474 +v 163.694183 -138.439911 42.641720 1.000000 1.000000 1.000000 +vn 0.709303 0.704525 0.023092 +v 163.139282 -137.764557 42.588718 1.000000 1.000000 1.000000 +vn 0.624318 0.780396 0.034767 +v 162.480087 -137.161774 42.531719 1.000000 1.000000 1.000000 +vn 0.478214 0.877212 0.042547 +v 161.748810 -136.670609 42.472519 1.000000 1.000000 1.000000 +vn 0.350071 0.932807 0.085567 +v 160.959579 -136.299454 42.411339 1.000000 1.000000 1.000000 +vn 0.923532 0.313631 -0.220735 +v 164.491150 -140.085007 42.339737 1.000000 1.000000 1.000000 +vn 0.932653 0.331550 0.142240 +v 164.536194 -140.065475 42.745319 1.000000 1.000000 1.000000 +vn -0.193798 0.575176 -0.794742 +v 156.940063 -136.831085 40.931938 1.000000 1.000000 1.000000 +vn -0.316989 0.824483 -0.468771 +v 156.851227 -136.592468 41.276539 1.000000 1.000000 1.000000 +vn -0.426396 0.756248 -0.496261 +v 156.105774 -136.988754 41.202938 1.000000 1.000000 1.000000 +vn 0.259397 -0.042360 -0.964841 +v 164.254242 -142.698456 41.586121 1.000000 1.000000 1.000000 +vn 0.253417 -0.140929 -0.957036 +v 163.945251 -144.308670 41.667919 1.000000 1.000000 1.000000 +vn -0.182256 0.022468 -0.982994 +v 164.021210 -142.683121 41.591316 1.000000 1.000000 1.000000 +vn -0.612105 -0.107342 -0.783457 +v 163.793335 -141.910095 41.682716 1.000000 1.000000 1.000000 +vn -0.652598 0.170606 -0.738248 +v 163.519104 -144.141235 41.808937 1.000000 1.000000 1.000000 +vn -0.924485 0.039519 -0.379165 +v 163.565445 -142.653809 42.061920 1.000000 1.000000 1.000000 +vn -0.266573 0.039569 -0.963002 +v 163.725082 -144.222168 41.673119 1.000000 1.000000 1.000000 +vn 0.186578 -0.212957 -0.959082 +v 162.817413 -146.281677 41.768936 1.000000 1.000000 1.000000 +vn -0.182565 0.106926 -0.977362 +v 162.647476 -146.108658 41.773918 1.000000 1.000000 1.000000 +vn -0.662998 0.372610 -0.649305 +v 162.938446 -145.349594 41.875519 1.000000 1.000000 1.000000 +vn -0.792517 0.264924 -0.549302 +v 163.296356 -144.051926 42.143719 1.000000 1.000000 1.000000 +vn -0.484514 0.656117 -0.578582 +v 161.524780 -146.795166 41.964737 1.000000 1.000000 1.000000 +vn -0.675162 0.623565 -0.394111 +v 162.316589 -145.766800 42.244518 1.000000 1.000000 1.000000 +vn -0.787421 0.452760 -0.418303 +v 162.742737 -145.201691 42.210320 1.000000 1.000000 1.000000 +vn -0.961616 0.206259 -0.180972 +v 163.340134 -143.337524 42.501717 1.000000 1.000000 1.000000 +vn -0.510669 0.712064 -0.481853 +v 161.399902 -146.574692 42.299519 1.000000 1.000000 1.000000 +vn -0.715291 0.655127 -0.243246 +v 162.216171 -145.663544 42.642120 1.000000 1.000000 1.000000 +vn -0.977831 0.003035 -0.209373 +v 163.426392 -142.644043 42.459320 1.000000 1.000000 1.000000 +vn -0.993912 -0.095257 0.055355 +v 163.367172 -141.950562 42.869720 1.000000 1.000000 1.000000 +vn -0.549337 0.789775 -0.272917 +v 161.327805 -146.446335 42.696918 1.000000 1.000000 1.000000 +vn -0.902193 0.379018 -0.205894 +v 160.539856 -146.901199 42.600319 1.000000 1.000000 1.000000 +vn -0.850898 0.265883 -0.453078 +v 160.620972 -147.142593 42.119720 1.000000 1.000000 1.000000 +vn -0.699539 -0.035833 -0.713695 +v 160.722687 -147.445389 41.876320 1.000000 1.000000 1.000000 +vn -0.419837 -0.599224 -0.681665 +v 160.872025 -147.865387 41.896519 1.000000 1.000000 1.000000 +vn -0.888835 0.112859 0.444113 +v 153.368591 -141.201263 42.401337 1.000000 1.000000 1.000000 +vn -0.896724 -0.008685 0.442504 +v 153.273331 -142.090088 42.313339 1.000000 1.000000 1.000000 +vn -0.869239 -0.130100 0.476967 +v 153.299072 -142.985901 42.222740 1.000000 1.000000 1.000000 +vn -0.976331 0.157970 0.147727 +v 153.219254 -141.170578 41.933140 1.000000 1.000000 1.000000 +vn -0.988786 0.024196 0.147367 +v 153.122681 -142.083115 41.844940 1.000000 1.000000 1.000000 +vn -0.983105 -0.107398 0.148224 +v 153.147141 -143.002640 41.754337 1.000000 1.000000 1.000000 +vn -0.982587 -0.076469 -0.169341 +v 153.160019 -143.001251 40.938938 1.000000 1.000000 1.000000 +vn -0.983977 0.055116 -0.169564 +v 153.134277 -142.083115 41.029537 1.000000 1.000000 1.000000 +vn -0.960033 -0.237802 0.147603 +v 153.295212 -143.911011 41.661537 1.000000 1.000000 1.000000 +vn -0.963801 -0.205763 -0.169558 +v 153.308075 -143.906815 40.846138 1.000000 1.000000 1.000000 +vn -0.967525 0.186871 -0.170219 +v 153.232117 -141.173355 41.117538 1.000000 1.000000 1.000000 +vn -0.852662 -0.270525 -0.446972 +v 153.690460 -144.713318 40.359737 1.000000 1.000000 1.000000 +vn -0.403802 -0.555661 0.726764 +v 161.157852 -137.722702 19.004200 1.000000 1.000000 1.000000 +vn -0.762228 -0.486092 0.427460 +v 162.513565 -139.212921 18.905800 1.000000 1.000000 1.000000 +vn -0.673325 -0.658956 0.335276 +v 162.086121 -138.723145 18.821198 1.000000 1.000000 1.000000 +vn -0.615065 -0.699069 0.364688 +v 161.593018 -138.298965 18.737997 1.000000 1.000000 1.000000 +vn -0.122579 -0.667559 0.734398 +v 159.262680 -137.174332 18.772400 1.000000 1.000000 1.000000 +vn 0.160337 -0.639782 0.751646 +v 157.305710 -137.506424 18.556999 1.000000 1.000000 1.000000 +vn -0.015789 -0.244568 0.969504 +v 157.219452 -137.256668 18.711597 1.000000 1.000000 1.000000 +vn 0.357947 -0.570534 0.739165 +v 156.163712 -138.177582 18.424797 1.000000 1.000000 1.000000 +vn 0.168643 -0.908863 0.381481 +v 157.989365 -137.548279 18.278599 1.000000 1.000000 1.000000 +vn 0.387722 -0.804713 0.449565 +v 156.824188 -138.025482 18.142197 1.000000 1.000000 1.000000 +vn 0.069351 -0.240993 0.968046 +v 156.016937 -137.962692 18.579399 1.000000 1.000000 1.000000 +vn 0.494817 -0.467277 0.732672 +v 155.437576 -138.891983 18.330399 1.000000 1.000000 1.000000 +vn 0.134658 -0.206242 0.969191 +v 155.254745 -138.713394 18.484997 1.000000 1.000000 1.000000 +vn 0.629905 -0.275376 0.726214 +v 154.462952 -140.707321 18.155998 1.000000 1.000000 1.000000 +vn 0.644457 -0.619182 0.448653 +v 155.613953 -139.062225 17.982800 1.000000 1.000000 1.000000 +vn 0.819346 -0.482634 0.309412 +v 155.231583 -139.592438 17.922600 1.000000 1.000000 1.000000 +vn 0.829646 -0.341585 0.441597 +v 154.685684 -140.788254 17.808399 1.000000 1.000000 1.000000 +vn 0.199651 -0.143096 0.969362 +v 154.228638 -140.622192 18.310600 1.000000 1.000000 1.000000 +vn 0.689846 -0.050106 0.722220 +v 154.217041 -142.565903 18.014797 1.000000 1.000000 1.000000 +vn 0.249003 -0.062009 0.966516 +v 153.971146 -142.577057 18.169197 1.000000 1.000000 1.000000 +vn 0.256756 0.010993 0.966414 +v 154.206741 -144.021240 18.072998 1.000000 1.000000 1.000000 +vn 0.243313 0.081062 0.966555 +v 154.783539 -145.339828 17.985197 1.000000 1.000000 1.000000 +vn 0.195544 0.139219 0.970763 +v 155.660309 -146.442139 17.904198 1.000000 1.000000 1.000000 +vn 0.119207 0.193533 0.973825 +v 157.456345 -147.552826 17.793800 1.000000 1.000000 1.000000 +vn 0.009645 0.275667 0.961205 +v 159.403015 -147.802597 17.705399 1.000000 1.000000 1.000000 +vn 0.635998 0.146890 0.757582 +v 154.441071 -143.940308 17.918400 1.000000 1.000000 1.000000 +vn 0.903629 -0.038203 0.426608 +v 154.452652 -142.556137 17.667000 1.000000 1.000000 1.000000 +vn 0.903638 0.138193 0.405390 +v 154.519592 -143.217514 17.618000 1.000000 1.000000 1.000000 +vn 0.605495 0.310013 0.732985 +v 154.989532 -145.193314 17.830597 1.000000 1.000000 1.000000 +vn 0.798835 0.407312 0.442673 +v 155.187805 -145.053787 17.482800 1.000000 1.000000 1.000000 +vn 0.889498 0.414382 0.192563 +v 155.297241 -144.977036 17.089199 1.000000 1.000000 1.000000 +vn 0.945517 0.321719 0.049954 +v 154.835037 -143.803558 16.746597 1.000000 1.000000 1.000000 +vn 0.987860 0.155350 -0.000022 +v 154.693405 -143.184036 16.793598 1.000000 1.000000 1.000000 +vn 0.600619 0.314241 -0.735194 +v 155.214844 -144.802628 16.328400 1.000000 1.000000 1.000000 +vn 0.622529 0.099197 -0.776284 +v 154.618744 -143.144958 16.326599 1.000000 1.000000 1.000000 +vn 0.969792 -0.048352 0.239095 +v 154.583984 -142.550552 17.273399 1.000000 1.000000 1.000000 +vn 0.999533 -0.029518 -0.007850 +v 154.631607 -142.113815 16.877197 1.000000 1.000000 1.000000 +vn 0.861353 -0.166883 0.479813 +v 154.529907 -141.434280 17.754200 1.000000 1.000000 1.000000 +vn 0.981526 -0.191317 -0.001948 +v 154.703720 -141.470566 16.929798 1.000000 1.000000 1.000000 +vn 0.913519 -0.402862 0.056438 +v 155.079666 -140.256622 17.040199 1.000000 1.000000 1.000000 +vn 0.630020 -0.076527 -0.772799 +v 154.589127 -141.658936 16.327198 1.000000 1.000000 1.000000 +vn 0.956609 -0.288926 -0.037696 +v 154.805420 -140.831497 16.529198 1.000000 1.000000 1.000000 +vn 0.500061 -0.278093 -0.820124 +v 155.176224 -139.671982 16.326599 1.000000 1.000000 1.000000 +vn 0.850930 -0.524665 -0.025403 +v 155.378342 -139.699890 17.098198 1.000000 1.000000 1.000000 +vn 0.686939 -0.685118 0.242339 +v 155.710526 -139.157104 17.588997 1.000000 1.000000 1.000000 +vn 0.725965 -0.687727 -0.002452 +v 155.951279 -138.957565 17.189198 1.000000 1.000000 1.000000 +vn 0.752327 -0.635467 -0.173740 +v 155.706665 -139.152908 16.703598 1.000000 1.000000 1.000000 +vn 0.319107 -0.413838 -0.852590 +v 156.440521 -138.192932 16.327400 1.000000 1.000000 1.000000 +vn 0.619002 -0.747319 -0.241559 +v 156.377441 -138.492920 16.798199 1.000000 1.000000 1.000000 +vn 0.601545 -0.798701 0.014822 +v 156.408340 -138.538971 17.252998 1.000000 1.000000 1.000000 +vn 0.455357 -0.676400 0.578906 +v 156.304047 -138.384094 18.077198 1.000000 1.000000 1.000000 +vn 0.412965 -0.910666 -0.012118 +v 157.452484 -137.925018 17.384998 1.000000 1.000000 1.000000 +vn 0.425077 -0.870391 -0.248453 +v 157.434448 -137.871994 16.930199 1.000000 1.000000 1.000000 +vn 0.120550 -0.428061 -0.895674 +v 157.948166 -137.348740 16.326599 1.000000 1.000000 1.000000 +vn 0.234645 -0.936985 -0.258846 +v 158.017685 -137.680832 16.999599 1.000000 1.000000 1.000000 +vn 0.176139 -0.855019 -0.487768 +v 157.986786 -137.534332 16.601997 1.000000 1.000000 1.000000 +vn 0.077912 -0.934127 0.348333 +v 158.624100 -137.440842 18.351597 1.000000 1.000000 1.000000 +vn 0.106194 -0.991870 0.070127 +v 158.639542 -137.630600 17.527397 1.000000 1.000000 1.000000 +vn -0.117907 -0.884283 0.451820 +v 159.249802 -137.429672 18.424797 1.000000 1.000000 1.000000 +vn -0.262087 -0.889419 0.374493 +v 159.858780 -137.510605 18.498798 1.000000 1.000000 1.000000 +vn -0.085154 -0.996224 0.016960 +v 159.239502 -137.620834 17.600401 1.000000 1.000000 1.000000 +vn -0.042955 -0.971762 -0.232021 +v 159.242081 -137.565018 17.145599 1.000000 1.000000 1.000000 +vn -0.356670 -0.823033 0.442044 +v 160.460037 -137.682236 18.575397 1.000000 1.000000 1.000000 +vn -0.474491 -0.754149 0.454002 +v 161.050995 -137.951523 18.656597 1.000000 1.000000 1.000000 +vn -0.285062 -0.958360 -0.016888 +v 160.403381 -137.863632 17.751198 1.000000 1.000000 1.000000 +vn -0.496561 -0.867795 0.018922 +v 160.971161 -138.121765 17.832199 1.000000 1.000000 1.000000 +vn -0.389010 -0.788164 -0.476937 +v 161.057434 -137.937576 16.980000 1.000000 1.000000 1.000000 +vn -0.513848 -0.817210 -0.261012 +v 160.994339 -138.072937 17.377399 1.000000 1.000000 1.000000 +vn -0.706961 -0.705003 0.056364 +v 161.966400 -138.865479 17.996998 1.000000 1.000000 1.000000 +vn -0.657714 -0.713047 -0.242850 +v 162.001160 -138.823608 17.542198 1.000000 1.000000 1.000000 +vn -0.549488 -0.684734 -0.478751 +v 162.095139 -138.713394 17.144600 1.000000 1.000000 1.000000 +vn -0.653332 -0.532356 -0.538288 +v 162.523865 -139.204544 17.229198 1.000000 1.000000 1.000000 +vn -0.438750 -0.602443 -0.666754 +v 162.256073 -138.523621 16.809799 1.000000 1.000000 1.000000 +vn -0.644782 -0.425722 -0.634836 +v 163.089066 -139.616165 16.980797 1.000000 1.000000 1.000000 +vn -0.112218 -0.231553 -0.966328 +v 162.876648 -138.887802 16.758598 1.000000 1.000000 1.000000 +vn -0.240436 -0.614086 -0.751724 +v 161.164291 -137.707352 16.645199 1.000000 1.000000 1.000000 +vn -0.018202 -0.267441 -0.963402 +v 161.262131 -137.496658 16.509399 1.000000 1.000000 1.000000 +vn 0.035507 -0.236656 -0.970945 +v 159.947617 -137.009689 16.351597 1.000000 1.000000 1.000000 +vn -0.028150 -0.646919 -0.762039 +v 159.906418 -137.242706 16.487400 1.000000 1.000000 1.000000 +vn 0.029477 -0.909373 -0.414936 +v 159.249802 -137.414337 16.748199 1.000000 1.000000 1.000000 +vn -0.205837 -0.751605 -0.626675 +v 160.463898 -137.668289 16.898998 1.000000 1.000000 1.000000 +vn 0.487298 0.467421 0.737603 +v 155.823822 -146.242599 17.749599 1.000000 1.000000 1.000000 +vn 0.641286 0.618253 0.454439 +v 155.980896 -146.051437 17.401997 1.000000 1.000000 1.000000 +vn 0.259281 0.627535 0.734149 +v 157.532303 -147.298874 17.639198 1.000000 1.000000 1.000000 +vn 0.486463 0.789587 0.374041 +v 157.044342 -146.814697 17.324997 1.000000 1.000000 1.000000 +vn 0.572140 0.799164 0.184374 +v 156.592438 -146.376556 16.966400 1.000000 1.000000 1.000000 +vn 0.683235 0.706529 0.184408 +v 156.068436 -145.945404 17.008400 1.000000 1.000000 1.000000 +vn 0.503538 0.491122 -0.710808 +v 155.951279 -145.786331 16.326599 1.000000 1.000000 1.000000 +vn 0.338868 0.595763 -0.728173 +v 156.807449 -146.474228 16.326599 1.000000 1.000000 1.000000 +vn 0.189533 0.703638 -0.684815 +v 157.923706 -146.959808 16.327000 1.000000 1.000000 1.000000 +vn 0.311155 0.852290 0.420456 +v 157.604401 -147.056091 17.291599 1.000000 1.000000 1.000000 +vn -0.026057 0.709027 -0.704699 +v 159.104324 -147.103531 16.326599 1.000000 1.000000 1.000000 +vn 0.145136 0.923229 0.355785 +v 158.191498 -147.215149 17.259800 1.000000 1.000000 1.000000 +vn 0.003009 0.657862 0.753133 +v 159.383698 -147.536087 17.550800 1.000000 1.000000 1.000000 +vn 0.003411 0.836046 0.548650 +v 159.365677 -147.280731 17.203197 1.000000 1.000000 1.000000 +vn -0.198741 0.964926 0.171524 +v 159.928314 -147.047714 16.783398 1.000000 1.000000 1.000000 +vn 0.428014 0.878217 0.213400 +v 160.534714 -146.895630 16.941799 1.000000 1.000000 1.000000 +vn 0.487405 0.684203 0.542496 +v 160.637711 -147.197006 17.473598 1.000000 1.000000 1.000000 +vn 0.382383 0.736458 -0.558044 +v 160.514114 -146.849579 16.326599 1.000000 1.000000 1.000000 +vn -0.335028 -0.914655 -0.226191 +v 161.031677 -148.356537 42.746319 1.000000 1.000000 1.000000 +vn 0.547015 -0.807887 -0.219302 +v 162.086121 -147.781662 42.712517 1.000000 1.000000 1.000000 +vn 0.490213 -0.738833 -0.462404 +v 162.016602 -147.658875 42.319321 1.000000 1.000000 1.000000 +vn 0.638826 -0.621244 -0.453826 +v 163.167618 -146.643066 42.264519 1.000000 1.000000 1.000000 +vn 0.719585 -0.667519 -0.191355 +v 163.264175 -146.742142 42.657516 1.000000 1.000000 1.000000 +vn 0.337959 -0.513311 -0.788857 +v 161.891708 -147.439804 41.974918 1.000000 1.000000 1.000000 +vn 0.485106 -0.464152 -0.741104 +v 162.996368 -146.465866 41.919918 1.000000 1.000000 1.000000 +vn 0.706544 -0.444175 -0.550912 +v 163.704498 -145.932846 42.230141 1.000000 1.000000 1.000000 +vn 0.804257 -0.552023 -0.220094 +v 163.812637 -146.015167 42.623119 1.000000 1.000000 1.000000 +vn 0.875010 -0.416079 -0.247458 +v 164.214325 -145.302155 42.590736 1.000000 1.000000 1.000000 +vn 0.823804 -0.325681 -0.463982 +v 164.398453 -144.487274 42.163521 1.000000 1.000000 1.000000 +vn 0.933026 -0.321848 -0.160863 +v 164.523331 -144.537506 42.556717 1.000000 1.000000 1.000000 +vn 0.959395 -0.196886 -0.201985 +v 164.755081 -143.657059 42.517120 1.000000 1.000000 1.000000 +vn 0.631747 -0.280119 -0.722793 +v 164.175705 -144.399368 41.818916 1.000000 1.000000 1.000000 +vn 0.858064 -0.187303 -0.478166 +v 164.625031 -143.627747 42.123917 1.000000 1.000000 1.000000 +vn 0.984092 -0.058564 -0.167730 +v 164.869659 -142.737518 42.474918 1.000000 1.000000 1.000000 +vn 0.892422 -0.071410 -0.445514 +v 164.737061 -142.729156 42.081718 1.000000 1.000000 1.000000 +vn 0.979586 0.060121 -0.191826 +v 164.859360 -141.811035 42.430519 1.000000 1.000000 1.000000 +vn 0.681839 -0.075155 -0.727632 +v 164.500153 -142.713806 41.737137 1.000000 1.000000 1.000000 +vn 0.878824 0.043414 -0.475166 +v 164.726746 -141.823578 42.037319 1.000000 1.000000 1.000000 +vn 0.963720 0.192918 -0.184461 +v 164.740921 -140.980804 42.388519 1.000000 1.000000 1.000000 +vn 0.880133 0.160850 -0.446646 +v 164.610886 -141.012894 41.995537 1.000000 1.000000 1.000000 +vn 0.677432 0.101121 -0.728602 +v 164.379135 -141.067307 41.650940 1.000000 1.000000 1.000000 +vn -0.649291 0.218461 0.728489 +v -163.954269 -139.771042 18.567398 1.000000 1.000000 1.000000 +vn -0.839627 0.195053 0.506933 +v -164.460236 -140.446381 18.162399 1.000000 1.000000 1.000000 +vn -0.631572 -0.065134 0.772577 +v -164.498856 -142.119385 18.371597 1.000000 1.000000 1.000000 +vn -0.313897 0.048158 0.948235 +v -163.753418 -139.877090 18.707798 1.000000 1.000000 1.000000 +vn -0.539279 0.348598 0.766588 +v -163.107101 -138.392456 18.709599 1.000000 1.000000 1.000000 +vn -0.425334 0.011135 0.904968 +v -164.196304 -141.351959 18.575798 1.000000 1.000000 1.000000 +vn -0.830455 0.332260 0.447156 +v -164.167984 -139.659424 18.229597 1.000000 1.000000 1.000000 +vn -0.333991 0.259063 0.906276 +v -162.423447 -138.004547 18.923199 1.000000 1.000000 1.000000 +vn 0.069136 -0.231949 0.970268 +v -162.268951 -138.201294 18.926998 1.000000 1.000000 1.000000 +vn -0.044601 -0.240014 0.969744 +v -160.456177 -137.133865 19.158798 1.000000 1.000000 1.000000 +vn -0.202907 0.368981 0.907018 +v -160.525696 -136.885498 19.154999 1.000000 1.000000 1.000000 +vn 0.171893 -0.187856 0.967038 +v -163.538406 -139.988724 18.711597 1.000000 1.000000 1.000000 +vn -0.643409 -0.250032 0.723539 +v -164.256821 -144.120300 18.222397 1.000000 1.000000 1.000000 +vn -0.281012 -0.137145 0.949854 +v -164.043106 -144.047745 18.362997 1.000000 1.000000 1.000000 +vn -0.329918 -0.251291 0.909949 +v -163.443130 -145.447266 18.252598 1.000000 1.000000 1.000000 +vn -0.897249 -0.014664 0.441282 +v -164.735764 -142.109634 18.033798 1.000000 1.000000 1.000000 +vn -0.841087 -0.138803 0.522787 +v -164.662369 -143.375198 17.942799 1.000000 1.000000 1.000000 +vn -0.835489 -0.301177 0.459620 +v -164.483414 -144.195663 17.884598 1.000000 1.000000 1.000000 +vn -0.430617 -0.444281 0.785610 +v -163.183060 -146.231445 18.059399 1.000000 1.000000 1.000000 +vn -0.852862 0.118620 0.508484 +v -164.649506 -141.264053 18.097397 1.000000 1.000000 1.000000 +vn -0.976016 0.154155 0.153717 +v -164.798859 -141.234756 17.629200 1.000000 1.000000 1.000000 +vn -0.980611 -0.042927 0.191204 +v -164.888977 -142.536606 17.534599 1.000000 1.000000 1.000000 +vn -0.966904 -0.161830 0.197253 +v -164.811722 -143.401718 17.474598 1.000000 1.000000 1.000000 +vn -0.989941 -0.134002 -0.045387 +v -164.846481 -143.407288 17.064400 1.000000 1.000000 1.000000 +vn -0.999178 0.040345 -0.004088 +v -164.921158 -142.101257 17.155399 1.000000 1.000000 1.000000 +vn -0.950386 0.273876 0.147510 +v -164.604431 -140.396164 17.694199 1.000000 1.000000 1.000000 +vn -0.907389 0.393257 0.148303 +v -164.304459 -139.588257 17.761200 1.000000 1.000000 1.000000 +vn -0.656280 -0.131251 -0.743014 +v -164.675247 -143.749146 16.326599 1.000000 1.000000 1.000000 +vn -0.957616 -0.283386 -0.051612 +v -164.661087 -144.255661 17.006397 1.000000 1.000000 1.000000 +vn -0.949210 0.033766 -0.312825 +v -164.873535 -142.104050 16.750000 1.000000 1.000000 1.000000 +vn -0.909191 -0.394431 -0.133400 +v -164.372696 -145.064941 16.950199 1.000000 1.000000 1.000000 +vn -0.587711 0.151130 -0.794831 +v -164.551651 -140.898468 16.326797 1.000000 1.000000 1.000000 +vn -0.545385 -0.385355 -0.744350 +v -163.499771 -146.405869 16.326797 1.000000 1.000000 1.000000 +vn -0.938842 -0.282000 0.197615 +v -164.627609 -144.244492 17.416397 1.000000 1.000000 1.000000 +vn -0.888951 -0.396578 0.229110 +v -164.341797 -145.049606 17.360197 1.000000 1.000000 1.000000 +vn -0.868173 -0.486221 -0.099319 +v -163.986450 -145.826797 16.896000 1.000000 1.000000 1.000000 +vn -0.467256 -0.556730 -0.686821 +v -162.653900 -147.368637 16.326599 1.000000 1.000000 1.000000 +vn -0.779900 -0.625880 -0.005441 +v -163.504929 -146.530045 16.843399 1.000000 1.000000 1.000000 +vn -0.832613 -0.516523 0.199902 +v -163.958130 -145.805878 17.306000 1.000000 1.000000 1.000000 +vn -0.723672 -0.426145 0.542862 +v -163.830658 -145.717957 17.774399 1.000000 1.000000 1.000000 +vn -0.668872 -0.592130 0.449436 +v -163.363312 -146.398880 17.721600 1.000000 1.000000 1.000000 +vn -0.697778 -0.697274 0.164056 +v -163.109680 -146.931900 17.218998 1.000000 1.000000 1.000000 +vn -0.609061 -0.777198 0.158142 +v -162.504562 -147.488647 17.169800 1.000000 1.000000 1.000000 +vn -0.524642 -0.656870 0.541547 +v -162.414444 -147.357483 17.638199 1.000000 1.000000 1.000000 +vn -0.305902 -0.591105 0.746337 +v -161.649673 -147.582123 17.928799 1.000000 1.000000 1.000000 +vn -0.409385 -0.780797 0.471974 +v -161.764252 -147.806778 17.591000 1.000000 1.000000 1.000000 +vn -0.092397 -0.609174 0.787636 +v -160.279785 -148.156998 17.840797 1.000000 1.000000 1.000000 +vn -0.116118 -0.277402 0.953711 +v -161.542816 -147.370026 18.069395 1.000000 1.000000 1.000000 +vn -0.501930 -0.853349 0.140930 +v -161.836349 -147.951889 17.122799 1.000000 1.000000 1.000000 +vn -0.178351 -0.851983 0.492256 +v -160.333862 -148.406769 17.503197 1.000000 1.000000 1.000000 +vn -0.372426 -0.902265 0.217292 +v -161.120514 -148.313278 17.077797 1.000000 1.000000 1.000000 +vn 0.185919 -0.610026 0.770261 +v -158.006104 -148.218399 17.718197 1.000000 1.000000 1.000000 +vn 0.044100 -0.415542 0.908504 +v -158.827515 -148.073288 17.900597 1.000000 1.000000 1.000000 +vn 0.022473 -0.822250 0.568682 +v -158.812057 -148.572815 17.422199 1.000000 1.000000 1.000000 +vn -0.223445 -0.961466 0.160175 +v -160.369904 -148.565842 17.034798 1.000000 1.000000 1.000000 +vn -0.113296 -0.978095 0.174627 +v -159.596130 -148.708160 16.993599 1.000000 1.000000 1.000000 +vn -0.260015 -0.696928 -0.668344 +v -160.933838 -148.429092 16.327999 1.000000 1.000000 1.000000 +vn 0.040941 -0.759821 -0.648842 +v -158.703918 -148.797455 16.326797 1.000000 1.000000 1.000000 +vn 0.047067 -0.975102 0.216703 +v -158.806915 -148.736069 16.953999 1.000000 1.000000 1.000000 +vn 0.219848 -0.847629 0.482900 +v -157.963608 -148.470947 17.380398 1.000000 1.000000 1.000000 +vn 0.218472 -0.964066 0.151154 +v -157.935287 -148.632813 16.911999 1.000000 1.000000 1.000000 +vn 0.314901 -0.928429 0.197123 +v -157.183395 -148.426300 16.876999 1.000000 1.000000 1.000000 +vn 0.289917 -0.685610 -0.667748 +v -156.842209 -148.327240 16.326797 1.000000 1.000000 1.000000 +vn 0.400257 -0.483167 0.778681 +v -155.992477 -147.344925 17.617798 1.000000 1.000000 1.000000 +vn 0.370735 -0.746085 0.553094 +v -156.524200 -147.964447 17.311798 1.000000 1.000000 1.000000 +vn 0.474379 -0.864735 0.164916 +v -156.458557 -148.112350 16.843597 1.000000 1.000000 1.000000 +vn 0.582768 -0.799906 0.143287 +v -155.778763 -147.696548 16.811798 1.000000 1.000000 1.000000 +vn 0.525157 -0.565846 -0.635632 +v -155.167206 -147.247253 16.326797 1.000000 1.000000 1.000000 +vn 0.550198 -0.697492 0.459116 +v -155.862442 -147.558411 17.279999 1.000000 1.000000 1.000000 +vn 0.204704 -0.339585 0.918029 +v -156.723770 -147.513763 17.790199 1.000000 1.000000 1.000000 +vn 0.484852 -0.374976 0.790134 +v -154.912277 -146.344467 17.561199 1.000000 1.000000 1.000000 +vn 0.766348 -0.632423 0.112919 +v -154.623886 -146.626328 16.755199 1.000000 1.000000 1.000000 +vn 0.686996 -0.561457 0.461305 +v -154.735901 -146.516083 17.223400 1.000000 1.000000 1.000000 +vn 0.824995 -0.545813 0.146531 +v -154.147522 -145.969116 16.729000 1.000000 1.000000 1.000000 +vn 0.918705 0.262686 0.294918 +v -153.788315 -145.162628 16.993797 1.000000 1.000000 1.000000 +vn 0.589007 0.375539 0.715571 +v -154.169403 -144.960297 17.642998 1.000000 1.000000 1.000000 +vn -0.140064 0.175689 0.974431 +v -155.257324 -146.009583 17.705399 1.000000 1.000000 1.000000 +vn 0.040545 0.224017 0.973741 +v -158.835236 -147.815140 17.904400 1.000000 1.000000 1.000000 +vn 0.116969 0.212862 0.970056 +v -160.171646 -147.670029 17.985197 1.000000 1.000000 1.000000 +vn 0.178076 0.171616 0.968936 +v -161.426941 -147.142593 18.072998 1.000000 1.000000 1.000000 +vn 0.224748 0.113722 0.967758 +v -162.516144 -146.270523 18.169399 1.000000 1.000000 1.000000 +vn 0.241302 0.024602 0.970138 +v -163.570587 -144.660309 18.310600 1.000000 1.000000 1.000000 +vn 0.130720 -0.085341 0.987739 +v -164.039246 -142.511490 18.484997 1.000000 1.000000 1.000000 +vn 0.242372 -0.145162 0.959262 +v -163.961990 -141.396606 18.579597 1.000000 1.000000 1.000000 +vn 0.830429 0.182661 -0.526329 +v -153.666000 -145.229599 16.326797 1.000000 1.000000 1.000000 +vn -0.967683 0.171516 -0.184854 +v -164.785965 -141.237549 16.813599 1.000000 1.000000 1.000000 +vn -0.932782 0.308225 -0.186857 +v -164.591553 -140.400345 16.878597 1.000000 1.000000 1.000000 +vn -0.881975 0.411918 -0.229005 +v -164.292877 -139.595230 16.945795 1.000000 1.000000 1.000000 +vn -0.142762 -0.208509 0.967545 +v -158.396210 -136.939911 19.407997 1.000000 1.000000 1.000000 +vn -0.071002 0.331457 0.940795 +v -158.367874 -136.683182 19.404198 1.000000 1.000000 1.000000 +vn -0.214791 -0.161641 0.963191 +v -157.064957 -137.322235 19.583397 1.000000 1.000000 1.000000 +vn 0.012140 0.312598 0.949808 +v -156.973541 -137.082245 19.579597 1.000000 1.000000 1.000000 +vn -0.259280 -0.086364 0.961933 +v -155.603668 -138.331070 19.814999 1.000000 1.000000 1.000000 +vn -0.545512 -0.421261 0.724538 +v -155.769745 -138.527802 19.660397 1.000000 1.000000 1.000000 +vn -0.282573 -0.012204 0.959168 +v -154.724319 -139.482208 20.007797 1.000000 1.000000 1.000000 +vn -0.386335 -0.557287 0.734967 +v -157.160233 -137.567825 19.428799 1.000000 1.000000 1.000000 +vn -0.649680 -0.253087 0.716843 +v -154.932877 -139.623154 19.853201 1.000000 1.000000 1.000000 +vn -0.272543 0.075737 0.959158 +v -154.156540 -140.874756 20.211998 1.000000 1.000000 1.000000 +vn -0.702171 -0.066176 0.708927 +v -154.394714 -140.947311 20.057400 1.000000 1.000000 1.000000 +vn -0.874459 -0.276553 0.398548 +v -154.833755 -140.373825 19.607597 1.000000 1.000000 1.000000 +vn -0.817515 -0.406746 0.407710 +v -155.133728 -139.757095 19.505600 1.000000 1.000000 1.000000 +vn -0.767752 -0.497064 0.404333 +v -155.500656 -139.204544 19.407799 1.000000 1.000000 1.000000 +vn -0.178430 0.115685 0.977128 +v -154.016190 -143.114273 20.529198 1.000000 1.000000 1.000000 +vn -0.588021 0.337462 0.735085 +v -154.468094 -144.029602 20.524799 1.000000 1.000000 1.000000 +vn 0.362916 0.055671 0.930157 +v -153.779297 -143.150543 20.525398 1.000000 1.000000 1.000000 +vn -0.818089 0.045907 0.573257 +v -154.214462 -142.358002 20.266197 1.000000 1.000000 1.000000 +vn -0.819573 0.355124 0.449652 +v -154.692123 -143.947281 20.177200 1.000000 1.000000 1.000000 +vn -0.897684 0.195358 0.394966 +v -154.493851 -143.043106 20.026798 1.000000 1.000000 1.000000 +vn -0.863749 0.093206 0.495228 +v -154.450073 -142.358002 19.918598 1.000000 1.000000 1.000000 +vn -0.915973 -0.048745 0.398268 +v -154.493851 -141.678467 19.812798 1.000000 1.000000 1.000000 +vn -0.964546 -0.252018 0.078347 +v -154.791260 -141.068710 18.885399 1.000000 1.000000 1.000000 +vn -0.947154 0.223261 0.230333 +v -154.623886 -143.022171 19.633198 1.000000 1.000000 1.000000 +vn -0.998240 -0.048012 -0.034797 +v -154.627747 -142.358002 19.094200 1.000000 1.000000 1.000000 +vn -0.930058 0.326316 0.168850 +v -154.815720 -143.901230 19.783398 1.000000 1.000000 1.000000 +vn -0.991484 0.130210 -0.001993 +v -154.668961 -143.015198 19.202599 1.000000 1.000000 1.000000 +vn -0.943916 0.275029 -0.182704 +v -154.810562 -143.902634 18.897999 1.000000 1.000000 1.000000 +vn -0.958312 0.145499 -0.245902 +v -154.618744 -143.023575 18.747799 1.000000 1.000000 1.000000 +vn -0.963068 -0.157026 -0.218733 +v -154.617447 -141.698013 18.533798 1.000000 1.000000 1.000000 +vn -0.911789 0.066345 -0.405265 +v -154.480972 -143.044495 18.350401 1.000000 1.000000 1.000000 +vn -0.860957 0.207759 -0.464316 +v -154.679245 -143.951462 18.500599 1.000000 1.000000 1.000000 +vn -0.582960 0.056209 -0.810554 +v -154.453949 -144.035187 18.165798 1.000000 1.000000 1.000000 +vn -0.869082 -0.095638 -0.485336 +v -154.199020 -142.358002 17.907200 1.000000 1.000000 1.000000 +vn -0.850266 -0.071854 -0.521426 +v -154.437210 -142.358002 18.241997 1.000000 1.000000 1.000000 +vn -0.814197 0.410041 -0.411035 +v -155.249603 -145.177963 18.727398 1.000000 1.000000 1.000000 +vn -0.838990 -0.261625 -0.477125 +v -154.608429 -141.012894 18.033199 1.000000 1.000000 1.000000 +vn -0.922560 -0.385791 -0.006885 +v -154.995972 -140.450577 18.783199 1.000000 1.000000 1.000000 +vn -0.754487 -0.159790 -0.636566 +v -154.244080 -141.640793 17.801399 1.000000 1.000000 1.000000 +vn 0.164523 -0.195139 -0.966878 +v -154.025208 -144.192856 18.024799 1.000000 1.000000 1.000000 +vn -0.220600 -0.180097 -0.958593 +v -154.168121 -140.877548 17.562399 1.000000 1.000000 1.000000 +vn 0.189618 -0.094008 -0.977347 +v -154.536331 -139.355240 17.353397 1.000000 1.000000 1.000000 +vn -0.635088 -0.536405 -0.555818 +v -155.122147 -139.750122 17.828999 1.000000 1.000000 1.000000 +vn -0.889377 -0.157356 0.429242 +v -154.621307 -141.017090 19.709797 1.000000 1.000000 1.000000 +vn -0.857296 -0.512643 0.047333 +v -155.284363 -139.858963 18.681198 1.000000 1.000000 1.000000 +vn -0.820501 -0.527881 -0.219360 +v -155.240601 -139.829651 18.226398 1.000000 1.000000 1.000000 +vn -0.705988 -0.705971 0.056454 +v -156.049133 -138.858490 18.488400 1.000000 1.000000 1.000000 +vn -0.669907 -0.612923 0.418986 +v -155.929398 -138.717575 19.312798 1.000000 1.000000 1.000000 +vn -0.478405 -0.877498 -0.033565 +v -157.046936 -138.114792 18.301598 1.000000 1.000000 1.000000 +vn -0.672541 -0.697701 -0.246783 +v -156.014374 -138.816635 18.033600 1.000000 1.000000 1.000000 +vn -0.592706 -0.649305 -0.476553 +v -155.920380 -138.706406 17.636200 1.000000 1.000000 1.000000 +vn 0.043788 -0.820106 -0.570533 +v -154.920013 -139.614761 17.494198 1.000000 1.000000 1.000000 +vn -0.484077 -0.761235 -0.431498 +v -156.412201 -138.282227 17.542198 1.000000 1.000000 1.000000 +vn -0.394164 -0.536871 -0.745925 +v -155.759445 -138.515259 17.301399 1.000000 1.000000 1.000000 +vn -0.088765 -0.240166 -0.966665 +v -155.611389 -138.340836 17.165600 1.000000 1.000000 1.000000 +vn -0.265136 -0.738974 -0.619371 +v -156.855087 -137.700363 17.114597 1.000000 1.000000 1.000000 +vn -0.408974 -0.874742 -0.259936 +v -157.299271 -137.929199 17.801998 1.000000 1.000000 1.000000 +vn -0.292447 -0.831805 -0.471779 +v -157.246490 -137.791061 17.404598 1.000000 1.000000 1.000000 +vn 0.268212 0.106833 -0.957418 +v -155.454300 -138.153854 17.160397 1.000000 1.000000 1.000000 +vn -0.154796 -0.740256 -0.654262 +v -157.780792 -137.322235 16.980797 1.000000 1.000000 1.000000 +vn -0.078661 -0.826455 -0.557480 +v -158.452850 -137.443634 17.229198 1.000000 1.000000 1.000000 +vn 0.054682 -0.966596 -0.250403 +v -159.074707 -137.559448 17.542198 1.000000 1.000000 1.000000 +vn -0.243528 -0.969791 0.014141 +v -157.890228 -137.771530 18.167797 1.000000 1.000000 1.000000 +vn -0.493032 -0.834662 0.245475 +v -157.301849 -137.934799 18.687399 1.000000 1.000000 1.000000 +vn -0.224751 -0.934154 0.277206 +v -158.470871 -137.599899 18.511997 1.000000 1.000000 1.000000 +vn 0.012504 -0.998152 0.059472 +v -159.073425 -137.613861 17.996998 1.000000 1.000000 1.000000 +vn -0.463907 -0.761139 0.453274 +v -157.251633 -137.803635 19.081200 1.000000 1.000000 1.000000 +vn -0.561670 -0.671863 0.482832 +v -156.419922 -138.293396 19.218800 1.000000 1.000000 1.000000 +vn -0.197344 -0.873334 0.445358 +v -158.455429 -137.458984 18.905800 1.000000 1.000000 1.000000 +vn -0.175408 -0.646384 0.742577 +v -158.425827 -137.205032 19.253399 1.000000 1.000000 1.000000 +vn 0.000510 -0.937227 0.348720 +v -159.075989 -137.422699 18.821198 1.000000 1.000000 1.000000 +vn 0.123699 -0.668109 0.733709 +v -160.385361 -137.389206 19.004200 1.000000 1.000000 1.000000 +vn 0.076093 -0.923384 0.376260 +v -159.703003 -137.481308 18.737997 1.000000 1.000000 1.000000 +vn 0.290809 -0.956600 0.018609 +v -160.265640 -137.817581 17.832397 1.000000 1.000000 1.000000 +vn 0.221425 -0.859836 0.460058 +v -160.317123 -137.633392 18.656597 1.000000 1.000000 1.000000 +vn 0.501010 -0.865301 -0.015603 +v -160.842422 -138.054794 17.751198 1.000000 1.000000 1.000000 +vn 0.354399 -0.823700 0.442629 +v -160.917099 -137.880371 18.575600 1.000000 1.000000 1.000000 +vn 0.466096 -0.803425 0.370491 +v -161.461700 -138.202682 18.498798 1.000000 1.000000 1.000000 +vn 0.404112 -0.555185 0.726955 +v -162.109299 -138.405014 18.772400 1.000000 1.000000 1.000000 +vn 0.659443 -0.751567 0.016791 +v -161.841507 -138.745468 17.600401 1.000000 1.000000 1.000000 +vn 0.560900 -0.699740 0.442442 +v -161.956085 -138.598969 18.424797 1.000000 1.000000 1.000000 +vn 0.779396 -0.622769 0.068569 +v -162.270233 -139.200363 17.527397 1.000000 1.000000 1.000000 +vn 0.724607 -0.603109 0.333474 +v -162.401566 -139.073380 18.351597 1.000000 1.000000 1.000000 +vn 0.765653 -0.530208 0.364218 +v -162.794235 -139.625931 18.278797 1.000000 1.000000 1.000000 +vn 0.578273 -0.352754 0.735639 +v -163.316956 -140.104538 18.556999 1.000000 1.000000 1.000000 +vn 0.926583 -0.375932 -0.010917 +v -162.944870 -140.298492 17.384998 1.000000 1.000000 1.000000 +vn 0.843892 -0.323361 0.428117 +v -163.336273 -140.839874 18.142197 1.000000 1.000000 1.000000 +vn 0.982473 -0.185825 0.014687 +v -163.313095 -141.523590 17.252998 1.000000 1.000000 1.000000 +vn 0.636227 -0.237760 0.733952 +v -163.718658 -141.444061 18.424999 1.000000 1.000000 1.000000 +vn 0.897828 -0.016639 0.440033 +v -163.556427 -142.496140 17.982800 1.000000 1.000000 1.000000 +vn 0.734348 0.130736 0.666064 +v -163.579605 -143.892868 18.212200 1.000000 1.000000 1.000000 +vn 0.306644 -0.822116 -0.479682 +v -160.320999 -137.619446 16.980000 1.000000 1.000000 1.000000 +vn 0.240943 -0.933565 -0.265335 +v -160.281067 -137.764557 17.377598 1.000000 1.000000 1.000000 +vn 0.669486 -0.708016 -0.224725 +v -161.874985 -138.703613 17.145599 1.000000 1.000000 1.000000 +vn 0.115222 -0.864050 -0.490042 +v -159.075989 -137.408737 17.144798 1.000000 1.000000 1.000000 +vn 0.130565 -0.725256 -0.675985 +v -159.079849 -137.150604 16.809998 1.000000 1.000000 1.000000 +vn 0.282791 -0.596669 -0.751009 +v -160.389221 -137.372467 16.645199 1.000000 1.000000 1.000000 +vn 0.183330 -0.204114 -0.961628 +v -160.452316 -137.146423 16.509399 1.000000 1.000000 1.000000 +vn 0.090762 -0.239088 -0.966747 +v -158.397491 -136.952469 16.758598 1.000000 1.000000 1.000000 +vn 0.200561 -0.151040 -0.967968 +v -161.715332 -137.774323 16.351597 1.000000 1.000000 1.000000 +vn 0.407295 -0.669178 -0.621540 +v -160.922241 -137.867813 16.898998 1.000000 1.000000 1.000000 +vn 0.454976 -0.478928 -0.750750 +v -161.598175 -137.973862 16.487400 1.000000 1.000000 1.000000 +vn 0.398839 -0.236426 -0.886020 +v -162.950027 -139.511520 16.326797 1.000000 1.000000 1.000000 +vn 0.674792 -0.620525 -0.399506 +v -161.965103 -138.587799 16.748199 1.000000 1.000000 1.000000 +vn 0.827408 -0.504599 -0.246530 +v -162.689957 -139.701279 16.999599 1.000000 1.000000 1.000000 +vn 0.736765 -0.488774 -0.467201 +v -162.804550 -139.617554 16.602200 1.000000 1.000000 1.000000 +vn 0.909542 -0.342953 -0.234768 +v -162.991226 -140.274765 16.930199 1.000000 1.000000 1.000000 +vn 0.313906 -0.057197 -0.947730 +v -153.944092 -140.809174 17.557400 1.000000 1.000000 1.000000 +vn 0.275598 -0.148603 -0.949717 +v -153.797333 -143.147766 17.874599 1.000000 1.000000 1.000000 +vn 0.575107 -0.351323 -0.738799 +v -154.085724 -145.039825 18.288399 1.000000 1.000000 1.000000 +vn 0.093305 -0.227382 -0.969325 +v -154.681824 -145.603546 18.251598 1.000000 1.000000 1.000000 +vn 0.787179 -0.409324 -0.461305 +v -153.874573 -145.155640 18.632797 1.000000 1.000000 1.000000 +vn 0.503653 -0.468468 -0.725859 +v -154.478409 -145.755630 18.402599 1.000000 1.000000 1.000000 +vn 0.669006 -0.182472 -0.720511 +v -153.552704 -143.185425 18.025597 1.000000 1.000000 1.000000 +vn 0.071972 -0.264862 -0.961597 +v -155.637131 -146.733765 18.472797 1.000000 1.000000 1.000000 +vn 0.720297 -0.551212 -0.421115 +v -154.283997 -145.902145 18.747200 1.000000 1.000000 1.000000 +vn 0.377717 -0.560814 -0.736762 +v -155.478775 -146.938873 18.623997 1.000000 1.000000 1.000000 +vn 0.878946 -0.445826 -0.169392 +v -153.756134 -145.219818 19.025997 1.000000 1.000000 1.000000 +vn 0.910025 -0.316549 -0.267679 +v -153.441986 -144.407745 18.913399 1.000000 1.000000 1.000000 +vn 0.554700 -0.686779 -0.469726 +v -155.326843 -147.135620 18.968399 1.000000 1.000000 1.000000 +vn 0.739356 -0.638059 -0.215019 +v -154.640625 -146.622147 19.245197 1.000000 1.000000 1.000000 +vn 0.426313 -0.756694 -0.495653 +v -155.982178 -147.647705 19.083797 1.000000 1.000000 1.000000 +vn 0.641042 -0.746817 -0.177002 +v -155.241882 -147.247253 19.361597 1.000000 1.000000 1.000000 +vn 0.844107 -0.510587 0.163660 +v -154.164246 -145.991440 19.955799 1.000000 1.000000 1.000000 +vn 0.902453 -0.403674 0.150415 +v -153.744537 -145.226807 19.841400 1.000000 1.000000 1.000000 +vn 0.769196 -0.620989 0.150701 +v -154.631607 -146.630508 20.060799 1.000000 1.000000 1.000000 +vn 0.676760 -0.720235 0.152504 +v -155.234146 -147.257019 20.176998 1.000000 1.000000 1.000000 +vn 0.567113 -0.809100 0.154081 +v -155.904938 -147.781662 20.292400 1.000000 1.000000 1.000000 +vn 0.633352 -0.603209 0.484773 +v -155.330719 -147.131439 20.645397 1.000000 1.000000 1.000000 +vn 0.442357 -0.883344 0.154995 +v -156.645233 -148.204437 20.408798 1.000000 1.000000 1.000000 +vn 0.398809 -0.899262 -0.179666 +v -156.650375 -148.190491 19.593399 1.000000 1.000000 1.000000 +vn 0.526942 -0.830946 -0.178495 +v -155.912659 -147.770493 19.476801 1.000000 1.000000 1.000000 +vn 0.545818 -0.700961 0.459061 +v -155.984756 -147.642120 20.760597 1.000000 1.000000 1.000000 +vn 0.304013 -0.939615 0.157159 +v -157.430603 -148.507233 20.524998 1.000000 1.000000 1.000000 +vn 0.433657 -0.754296 0.492930 +v -156.705734 -148.053757 20.877197 1.000000 1.000000 1.000000 +vn 0.452692 -0.480753 0.750964 +v -156.109634 -147.424454 21.098400 1.000000 1.000000 1.000000 +vn 0.298985 -0.828065 0.474253 +v -157.471786 -148.348160 20.993397 1.000000 1.000000 1.000000 +vn 0.282602 -0.594640 0.752688 +v -157.534882 -148.101196 21.330997 1.000000 1.000000 1.000000 +vn 0.170098 -0.958081 0.230539 +v -158.241699 -148.684433 20.640198 1.000000 1.000000 1.000000 +vn 0.253970 -0.949613 -0.183668 +v -157.434448 -148.493271 19.709599 1.000000 1.000000 1.000000 +vn 0.088999 -0.891224 0.444746 +v -158.961411 -148.572815 21.208797 1.000000 1.000000 1.000000 +vn 0.117539 -0.626614 0.770415 +v -158.962708 -148.316071 21.546600 1.000000 1.000000 1.000000 +vn 0.188158 -0.295867 0.936514 +v -158.320251 -148.025833 21.586800 1.000000 1.000000 1.000000 +vn 0.273553 -0.243657 0.930484 +v -156.891144 -147.596085 21.355400 1.000000 1.000000 1.000000 +vn -0.055848 -0.864776 0.499042 +v -159.775101 -148.518402 21.325397 1.000000 1.000000 1.000000 +vn -0.118817 -0.979311 0.163804 +v -159.795700 -148.680252 20.857197 1.000000 1.000000 1.000000 +vn -0.087894 -0.658133 0.747754 +v -160.503815 -148.091431 21.778999 1.000000 1.000000 1.000000 +vn 0.054646 -0.313462 0.948027 +v -160.443298 -147.858414 21.919598 1.000000 1.000000 1.000000 +vn 0.219260 0.166848 0.961294 +v -160.377640 -147.608643 21.923397 1.000000 1.000000 1.000000 +vn 0.271951 0.069643 0.959788 +v -162.247055 -146.534225 22.270397 1.000000 1.000000 1.000000 +vn -0.090674 -0.297139 0.950519 +v -162.401566 -146.732376 22.266598 1.000000 1.000000 1.000000 +vn 0.281636 -0.029987 0.959053 +v -163.544846 -144.720306 22.617397 1.000000 1.000000 1.000000 +vn -0.251789 -0.262714 0.931442 +v -163.759857 -144.831924 22.613800 1.000000 1.000000 1.000000 +vn -0.239831 -0.581353 0.777502 +v -161.917465 -147.411896 22.010399 1.000000 1.000000 1.000000 +vn -0.382417 -0.556442 0.737651 +v -162.544464 -146.917953 22.125999 1.000000 1.000000 1.000000 +vn -0.549905 -0.696581 0.460847 +v -162.697678 -147.113297 21.788200 1.000000 1.000000 1.000000 +vn -0.441838 -0.768472 0.462850 +v -162.043640 -147.629578 21.672600 1.000000 1.000000 1.000000 +vn -0.313354 -0.809756 0.496090 +v -161.325226 -148.041199 21.556400 1.000000 1.000000 1.000000 +vn -0.472153 -0.427569 0.770880 +v -163.573166 -145.671921 22.356800 1.000000 1.000000 1.000000 +vn -0.630703 -0.605031 0.485954 +v -163.275757 -146.504929 21.903599 1.000000 1.000000 1.000000 +vn -0.614983 -0.273646 0.739536 +v -164.247803 -144.151001 22.589397 1.000000 1.000000 1.000000 +vn -0.774224 -0.412331 0.480168 +v -164.174423 -145.048203 22.135399 1.000000 1.000000 1.000000 +vn -0.725435 -0.519099 0.451974 +v -163.770157 -145.814240 22.018997 1.000000 1.000000 1.000000 +vn -0.830300 -0.536469 0.151006 +v -163.896332 -145.904938 21.550598 1.000000 1.000000 1.000000 +vn -0.748626 -0.645127 0.152872 +v -163.389053 -146.613754 21.435398 1.000000 1.000000 1.000000 +vn -0.895416 -0.419477 0.149231 +v -164.310898 -145.119354 21.667198 1.000000 1.000000 1.000000 +vn -0.909325 -0.379622 -0.170337 +v -164.299301 -145.112381 20.851597 1.000000 1.000000 1.000000 +vn -0.773207 -0.609990 -0.173389 +v -163.380051 -146.605392 20.619797 1.000000 1.000000 1.000000 +vn -0.849718 -0.498365 -0.172079 +v -163.886032 -145.897949 20.735197 1.000000 1.000000 1.000000 +vn -0.679950 -0.711979 -0.175371 +v -162.786514 -147.229111 20.504398 1.000000 1.000000 1.000000 +vn -0.650123 -0.743982 0.154373 +v -162.795532 -147.240280 21.320000 1.000000 1.000000 1.000000 +vn -0.570270 -0.802007 -0.177702 +v -162.117020 -147.756546 20.388798 1.000000 1.000000 1.000000 +vn -0.534654 -0.830711 0.155129 +v -162.123459 -147.767700 21.204399 1.000000 1.000000 1.000000 +vn -0.714502 -0.505652 -0.483532 +v -163.280914 -146.509109 20.226801 1.000000 1.000000 1.000000 +vn -0.642987 -0.613966 -0.457836 +v -162.701538 -147.118866 20.111397 1.000000 1.000000 1.000000 +vn -0.407910 -0.899338 0.157484 +v -161.387024 -148.191895 21.088200 1.000000 1.000000 1.000000 +vn -0.547953 -0.697120 -0.462354 +v -162.046219 -147.633759 19.995800 1.000000 1.000000 1.000000 +vn -0.447604 -0.875990 -0.179699 +v -161.381882 -148.179321 20.272598 1.000000 1.000000 1.000000 +vn -0.311483 -0.932860 -0.180971 +v -160.606812 -148.483521 20.157597 1.000000 1.000000 1.000000 +vn -0.268511 -0.950286 0.157666 +v -160.609390 -148.496078 20.973000 1.000000 1.000000 1.000000 +vn -0.196483 -0.861463 0.468269 +v -160.568176 -148.338394 21.441399 1.000000 1.000000 1.000000 +vn -0.436919 -0.751191 -0.494787 +v -161.327805 -148.046768 19.879597 1.000000 1.000000 1.000000 +vn -0.178277 -0.965693 -0.188822 +v -159.793121 -148.666306 20.041599 1.000000 1.000000 1.000000 +vn -0.320890 -0.822840 -0.469003 +v -160.569473 -148.343979 19.764397 1.000000 1.000000 1.000000 +vn -0.004210 -0.999595 0.028162 +v -158.960129 -148.775131 20.330597 1.000000 1.000000 1.000000 +vn -0.021866 -0.961401 -0.274283 +v -158.960129 -148.723511 19.924999 1.000000 1.000000 1.000000 +vn 0.175902 -0.983214 -0.048458 +v -158.236557 -148.720718 20.230198 1.000000 1.000000 1.000000 +vn -0.178016 -0.860268 -0.477755 +v -159.776382 -148.523972 19.648598 1.000000 1.000000 1.000000 +vn 0.044936 -0.897121 -0.439494 +v -158.259735 -148.526764 19.431599 1.000000 1.000000 1.000000 +vn 0.181890 -0.846393 -0.500535 +v -157.470505 -148.353745 19.316399 1.000000 1.000000 1.000000 +vn -0.168809 -0.592393 -0.787766 +v -159.744202 -148.270035 19.303999 1.000000 1.000000 1.000000 +vn -0.033684 -0.665718 -0.745443 +v -158.290634 -148.272812 19.086998 1.000000 1.000000 1.000000 +vn -0.317068 -0.591706 -0.741183 +v -160.505096 -148.097000 19.419998 1.000000 1.000000 1.000000 +vn -0.238037 -0.214085 -0.947368 +v -160.438156 -147.840271 19.268799 1.000000 1.000000 1.000000 +vn -0.117838 -0.288417 -0.950226 +v -158.322815 -148.007706 18.935999 1.000000 1.000000 1.000000 +vn 0.181864 -0.639168 -0.747255 +v -156.798447 -147.823517 18.855797 1.000000 1.000000 1.000000 +vn -0.310405 -0.102602 -0.945051 +v -162.389969 -146.718414 19.615799 1.000000 1.000000 1.000000 +vn -0.416651 -0.456142 -0.786343 +v -161.921326 -147.416092 19.651199 1.000000 1.000000 1.000000 +vn -0.542952 -0.412477 -0.731483 +v -162.548325 -146.922134 19.766800 1.000000 1.000000 1.000000 +vn -0.317273 0.017443 -0.948174 +v -163.744400 -144.823547 19.962997 1.000000 1.000000 1.000000 +vn -0.572924 -0.252606 -0.779711 +v -163.578323 -145.674713 19.997597 1.000000 1.000000 1.000000 +vn -0.670511 -0.175788 -0.720773 +v -163.965851 -144.939362 20.113998 1.000000 1.000000 1.000000 +vn -0.307275 0.100557 -0.946293 +v -164.189865 -143.294266 20.194395 1.000000 1.000000 1.000000 +vn -0.789364 -0.416187 -0.451324 +v -163.775299 -145.817032 20.341999 1.000000 1.000000 1.000000 +vn -0.839428 -0.308396 -0.447496 +v -164.179565 -145.050995 20.458599 1.000000 1.000000 1.000000 +vn -0.693078 0.009036 -0.720806 +v -164.433212 -143.338913 20.345398 1.000000 1.000000 1.000000 +vn -0.859875 -0.185828 -0.475482 +v -164.479553 -144.230530 20.574799 1.000000 1.000000 1.000000 +vn -0.235531 0.210227 -0.948857 +v -164.107468 -140.984985 20.528999 1.000000 1.000000 1.000000 +vn -0.909074 -0.068386 -0.410984 +v -164.666245 -143.380783 20.689800 1.000000 1.000000 1.000000 +vn -0.621292 0.131347 -0.772492 +v -164.479553 -141.751022 20.564198 1.000000 1.000000 1.000000 +vn -0.954881 -0.245248 -0.167501 +v -164.605728 -144.273788 20.967800 1.000000 1.000000 1.000000 +vn -0.943803 -0.295199 0.148641 +v -164.618607 -144.277985 21.783398 1.000000 1.000000 1.000000 +vn -0.978167 -0.020702 -0.206787 +v -164.872238 -142.614731 21.185200 1.000000 1.000000 1.000000 +vn -0.971294 -0.174485 0.161689 +v -164.810425 -143.407288 21.898399 1.000000 1.000000 1.000000 +vn -0.882458 0.128017 -0.452637 +v -164.715164 -141.725906 20.908600 1.000000 1.000000 1.000000 +vn -0.633299 0.267278 -0.726289 +v -164.345657 -140.920807 20.680000 1.000000 1.000000 1.000000 +vn -0.857058 0.256171 -0.447021 +v -164.576126 -140.859406 21.024597 1.000000 1.000000 1.000000 +vn -0.978928 0.113571 -0.169714 +v -164.847778 -141.710556 21.301800 1.000000 1.000000 1.000000 +vn -0.987876 -0.051820 0.146343 +v -164.885101 -142.616135 22.000599 1.000000 1.000000 1.000000 +vn -0.968181 0.202528 0.146995 +v -164.717743 -140.821747 22.233200 1.000000 1.000000 1.000000 +vn -0.986422 0.073670 0.146779 +v -164.860641 -141.709167 22.117199 1.000000 1.000000 1.000000 +vn -0.955323 0.241790 -0.169989 +v -164.704865 -140.824524 21.417599 1.000000 1.000000 1.000000 +vn -0.887217 -0.107535 0.448646 +v -164.734467 -142.609161 22.468998 1.000000 1.000000 1.000000 +vn -0.896382 0.025769 0.442533 +v -164.710007 -141.725906 22.585598 1.000000 1.000000 1.000000 +vn -0.842501 -0.291768 0.452840 +v -164.473114 -144.229141 22.251598 1.000000 1.000000 1.000000 +vn -0.645971 -0.130525 0.752120 +v -164.497574 -142.599380 22.806799 1.000000 1.000000 1.000000 +vn -0.870292 0.136099 0.473359 +v -164.570969 -140.860809 22.701397 1.000000 1.000000 1.000000 +vn -0.932766 0.328414 0.148634 +v -164.462814 -139.969193 22.348400 1.000000 1.000000 1.000000 +vn -0.857446 0.258716 0.444806 +v -164.321198 -140.030579 22.816595 1.000000 1.000000 1.000000 +vn -0.635091 0.134340 0.760666 +v -164.102325 -140.126862 23.154400 1.000000 1.000000 1.000000 +vn -0.651957 -0.045544 0.756887 +v -164.474411 -141.752426 22.923397 1.000000 1.000000 1.000000 +vn -0.880853 0.449052 0.149831 +v -164.095886 -139.157104 22.464397 1.000000 1.000000 1.000000 +vn -0.803274 0.357257 0.476570 +v -163.964554 -139.239426 22.932800 1.000000 1.000000 1.000000 +vn -0.607803 0.315758 0.728610 +v -163.329834 -138.678497 23.385197 1.000000 1.000000 1.000000 +vn -0.329711 0.066743 0.941720 +v -163.153442 -138.827805 23.525799 1.000000 1.000000 1.000000 +vn -0.370406 -0.052917 0.927361 +v -164.124207 -140.980804 23.179798 1.000000 1.000000 1.000000 +vn -0.308997 -0.183160 0.933259 +v -164.206604 -143.298447 22.844997 1.000000 1.000000 1.000000 +vn 0.083394 -0.254449 0.963484 +v -162.965485 -138.986877 23.529598 1.000000 1.000000 1.000000 +vn 0.189668 -0.199413 0.961385 +v -163.892456 -141.043594 23.183598 1.000000 1.000000 1.000000 +vn -0.025715 -0.264151 0.964138 +v -161.336807 -137.520370 23.876598 1.000000 1.000000 1.000000 +vn -0.293258 0.223313 0.929586 +v -161.447540 -137.291534 23.872999 1.000000 1.000000 1.000000 +vn -0.117531 -0.247774 0.961662 +v -160.001694 -137.008286 24.107998 1.000000 1.000000 1.000000 +vn -0.209813 0.283932 0.935607 +v -160.048035 -136.754333 24.104198 1.000000 1.000000 1.000000 +vn -0.206708 -0.179169 0.961858 +v -157.958466 -137.018051 24.442799 1.000000 1.000000 1.000000 +vn -0.069105 0.347768 0.935030 +v -157.909546 -136.765503 24.438999 1.000000 1.000000 1.000000 +vn -0.266352 -0.086529 0.959984 +v -156.031113 -137.951523 24.788799 1.000000 1.000000 1.000000 +vn -0.272780 -0.625965 0.730588 +v -158.009964 -137.280380 24.288198 1.000000 1.000000 1.000000 +vn -0.520450 -0.460948 0.718790 +v -156.176590 -138.167816 24.634199 1.000000 1.000000 1.000000 +vn -0.283482 0.011909 0.958903 +v -154.622604 -139.666397 25.135799 1.000000 1.000000 1.000000 +vn -0.660398 -0.230831 0.714557 +v -154.837616 -139.797562 24.981398 1.000000 1.000000 1.000000 +vn -0.272607 0.097809 0.957141 +v -154.105026 -141.095230 25.367199 1.000000 1.000000 1.000000 +vn -0.697866 -0.005851 0.716205 +v -154.344498 -141.156616 25.212599 1.000000 1.000000 1.000000 +vn -0.205005 0.186813 0.960767 +v -154.044525 -143.308228 25.701998 1.000000 1.000000 1.000000 +vn -0.666806 0.223714 0.710860 +v -154.286560 -143.262161 25.547398 1.000000 1.000000 1.000000 +vn -0.897797 -0.071466 0.434573 +v -154.573669 -141.216614 24.864998 1.000000 1.000000 1.000000 +vn -0.884071 -0.241202 0.400300 +v -154.764221 -140.555222 24.749798 1.000000 1.000000 1.000000 +vn -0.883887 0.337830 0.323442 +v -154.675385 -143.888687 25.314798 1.000000 1.000000 1.000000 +vn -0.873671 0.222864 0.432470 +v -154.519592 -143.217514 25.199598 1.000000 1.000000 1.000000 +vn -0.952808 0.032072 0.301875 +v -154.452652 -142.524033 25.083799 1.000000 1.000000 1.000000 +vn -0.882861 -0.469588 0.006580 +v -155.195526 -140.018021 23.809399 1.000000 1.000000 1.000000 +vn -0.943769 -0.328918 0.033374 +v -154.929016 -140.624985 23.925598 1.000000 1.000000 1.000000 +vn -0.991021 -0.133537 0.006752 +v -154.653503 -141.843109 24.142998 1.000000 1.000000 1.000000 +vn -0.999431 0.032814 -0.007752 +v -154.629028 -142.517059 24.259399 1.000000 1.000000 1.000000 +vn -0.962278 0.267469 0.049805 +v -154.842758 -143.830078 24.490599 1.000000 1.000000 1.000000 +vn -0.920441 0.081694 -0.382250 +v -154.506729 -143.218918 23.523197 1.000000 1.000000 1.000000 +vn -0.856245 0.298874 -0.421330 +v -154.905853 -144.543091 23.754398 1.000000 1.000000 1.000000 +vn -0.941808 -0.243079 -0.232188 +v -154.695984 -141.247299 23.585800 1.000000 1.000000 1.000000 +vn -0.863842 -0.452764 -0.220868 +v -155.151764 -139.991516 23.354597 1.000000 1.000000 1.000000 +vn -0.834124 -0.031127 -0.550697 +v -154.438492 -142.524033 23.407200 1.000000 1.000000 1.000000 +vn -0.849360 -0.271177 -0.452826 +v -154.560806 -141.212433 23.188400 1.000000 1.000000 1.000000 +vn -0.727559 -0.152401 -0.668904 +v -154.227341 -141.792892 22.955799 1.000000 1.000000 1.000000 +vn -0.763537 -0.466500 -0.446529 +v -155.030731 -139.916168 22.956997 1.000000 1.000000 1.000000 +vn -0.604269 -0.342244 -0.719534 +v -154.529907 -140.454773 22.738400 1.000000 1.000000 1.000000 +vn -0.235501 -0.120282 -0.964402 +v -154.056107 -143.305435 23.052399 1.000000 1.000000 1.000000 +vn -0.203358 -0.194144 -0.959663 +v -154.116623 -141.098007 22.717800 1.000000 1.000000 1.000000 +vn -0.743681 0.129078 -0.655955 +v -154.435913 -143.973785 23.303398 1.000000 1.000000 1.000000 +vn -0.526660 -0.546540 -0.651095 +v -155.201965 -139.173843 22.505798 1.000000 1.000000 1.000000 +vn -0.131468 -0.241289 -0.961507 +v -154.632904 -139.671982 22.486397 1.000000 1.000000 1.000000 +vn -0.666789 -0.604933 -0.435257 +v -155.389938 -139.331528 22.840599 1.000000 1.000000 1.000000 +vn -0.502058 -0.718217 -0.481770 +v -156.307907 -138.361771 22.609997 1.000000 1.000000 1.000000 +vn -0.312925 -0.586746 -0.746865 +v -156.167572 -138.153854 22.275200 1.000000 1.000000 1.000000 +vn -0.024080 -0.285731 -0.958007 +v -156.037537 -137.962692 22.139397 1.000000 1.000000 1.000000 +vn -0.802813 -0.596151 0.009724 +v -155.540573 -139.457092 23.692799 1.000000 1.000000 1.000000 +vn -0.594909 -0.769121 -0.233528 +v -156.390320 -138.483154 23.007397 1.000000 1.000000 1.000000 +vn -0.836074 -0.340629 0.430060 +v -155.042313 -139.923141 24.633598 1.000000 1.000000 1.000000 +vn -0.784943 -0.526224 0.327038 +v -155.400238 -139.339890 24.517199 1.000000 1.000000 1.000000 +vn -0.631466 -0.773834 0.049315 +v -156.419922 -138.527802 23.462200 1.000000 1.000000 1.000000 +vn -0.485408 -0.825015 -0.289362 +v -156.914322 -138.127335 22.892799 1.000000 1.000000 1.000000 +vn -0.613613 -0.670977 0.416257 +v -156.315643 -138.374313 24.286598 1.000000 1.000000 1.000000 +vn -0.345597 -0.936966 0.051553 +v -157.505264 -137.901306 23.231400 1.000000 1.000000 1.000000 +vn -0.742136 -0.570155 0.352360 +v -155.826385 -138.822220 24.401798 1.000000 1.000000 1.000000 +vn -0.514447 -0.775484 0.366018 +v -156.855087 -138.007339 24.171799 1.000000 1.000000 1.000000 +vn -0.367808 -0.818594 -0.441158 +v -156.848648 -137.993393 22.495197 1.000000 1.000000 1.000000 +vn -0.415385 -0.843806 0.339775 +v -157.444763 -137.721313 24.055599 1.000000 1.000000 1.000000 +vn -0.079453 -0.996802 -0.008571 +v -158.707779 -137.625031 23.000198 1.000000 1.000000 1.000000 +vn -0.169407 -0.709468 -0.684074 +v -157.358490 -137.465958 22.044197 1.000000 1.000000 1.000000 +vn -0.125107 -0.903560 -0.409790 +v -158.056305 -137.516190 22.264000 1.000000 1.000000 1.000000 +vn -0.285172 -0.843878 0.454474 +v -158.058884 -137.530151 23.940399 1.000000 1.000000 1.000000 +vn 0.119597 -0.992805 0.005969 +v -159.329620 -137.627823 22.883598 1.000000 1.000000 1.000000 +vn 0.246500 -0.937333 -0.246263 +v -159.880676 -137.654327 22.326599 1.000000 1.000000 1.000000 +vn 0.146293 -0.701715 -0.697276 +v -159.361816 -137.164566 21.696598 1.000000 1.000000 1.000000 +vn 0.007061 -0.815240 -0.579081 +v -158.694901 -137.418518 22.147999 1.000000 1.000000 1.000000 +vn 0.343575 -0.938518 0.033777 +v -160.462616 -137.885956 22.666397 1.000000 1.000000 1.000000 +vn -0.071695 -0.943246 0.324264 +v -158.696198 -137.433868 23.824598 1.000000 1.000000 1.000000 +vn 0.051661 -0.885197 0.462338 +v -159.905136 -137.520370 23.605799 1.000000 1.000000 1.000000 +vn 0.498766 -0.866712 0.006549 +v -161.031677 -138.153854 22.550198 1.000000 1.000000 1.000000 +vn 0.479775 -0.846739 -0.229892 +v -161.054855 -138.105011 22.095398 1.000000 1.000000 1.000000 +vn 0.244063 -0.871665 0.425009 +v -160.521835 -137.704559 23.490597 1.000000 1.000000 1.000000 +vn -0.018193 -0.668538 0.743456 +v -159.952774 -137.270599 23.953398 1.000000 1.000000 1.000000 +vn 0.234764 -0.635863 0.735231 +v -161.222229 -137.757584 23.722198 1.000000 1.000000 1.000000 +vn 0.482762 -0.496854 0.721164 +v -162.772354 -139.152908 23.375000 1.000000 1.000000 1.000000 +vn 0.357042 -0.818527 0.450037 +v -161.114075 -137.983627 23.374397 1.000000 1.000000 1.000000 +vn 0.555566 -0.760966 0.335079 +v -161.663834 -138.351990 23.257999 1.000000 1.000000 1.000000 +vn 0.599610 -0.714921 0.359659 +v -162.155655 -138.795715 23.142597 1.000000 1.000000 1.000000 +vn 0.649836 -0.265518 0.712189 +v -163.652985 -141.107773 23.028999 1.000000 1.000000 1.000000 +vn 0.859935 -0.394298 0.324100 +v -163.226837 -140.510574 22.796398 1.000000 1.000000 1.000000 +vn 0.857707 -0.277546 0.432789 +v -163.423813 -141.169174 22.681198 1.000000 1.000000 1.000000 +vn 0.698270 -0.584040 0.413904 +v -162.586960 -139.310593 23.027397 1.000000 1.000000 1.000000 +vn 0.798653 -0.486532 0.354174 +v -162.943588 -139.881287 22.912598 1.000000 1.000000 1.000000 +vn 0.943068 -0.328818 0.050011 +v -163.062042 -140.581741 21.972198 1.000000 1.000000 1.000000 +vn 0.800394 -0.597579 0.047623 +v -162.446625 -139.429199 22.202999 1.000000 1.000000 1.000000 +vn 0.631365 -0.775418 0.010198 +v -161.560837 -138.508270 22.433598 1.000000 1.000000 1.000000 +vn 0.490305 -0.740603 -0.459466 +v -161.119232 -137.971069 21.697800 1.000000 1.000000 1.000000 +vn 0.633763 -0.638236 -0.437035 +v -161.671555 -138.340836 21.581398 1.000000 1.000000 1.000000 +vn 0.277621 -0.832771 -0.478976 +v -159.907715 -137.506424 21.929199 1.000000 1.000000 1.000000 +vn 0.794273 -0.562177 -0.230406 +v -162.487823 -139.394302 21.748199 1.000000 1.000000 1.000000 +vn 0.742696 -0.476369 -0.470612 +v -162.597260 -139.300827 21.350800 1.000000 1.000000 1.000000 +vn 0.568664 -0.504261 -0.649878 +v -161.810608 -138.131531 21.246597 1.000000 1.000000 1.000000 +vn 0.355622 -0.578231 -0.734290 +v -160.605530 -137.447815 21.479198 1.000000 1.000000 1.000000 +vn 0.610527 -0.302207 -0.732071 +v -162.783936 -139.141754 21.015999 1.000000 1.000000 1.000000 +vn 0.255005 -0.128125 -0.958414 +v -161.331665 -137.531540 21.227200 1.000000 1.000000 1.000000 +vn 0.303944 -0.033354 -0.952106 +v -162.956467 -138.995239 20.880199 1.000000 1.000000 1.000000 +vn 0.844281 -0.457676 -0.278788 +v -162.834152 -139.949661 21.633598 1.000000 1.000000 1.000000 +vn 0.834495 -0.353422 -0.422742 +v -162.955170 -139.874313 21.236000 1.000000 1.000000 1.000000 +vn 0.202950 -0.194303 -0.959717 +v -159.999130 -137.020844 21.458599 1.000000 1.000000 1.000000 +vn 0.121918 -0.222047 -0.967384 +v -157.961044 -137.030609 21.793198 1.000000 1.000000 1.000000 +vn -0.306462 0.014631 -0.951770 +v -154.849197 -145.420761 23.398598 1.000000 1.000000 1.000000 +vn -0.630475 0.262397 -0.730513 +v -155.029449 -145.286804 23.534397 1.000000 1.000000 1.000000 +vn 0.264755 -0.115130 0.957418 +v -163.971008 -143.255203 22.848797 1.000000 1.000000 1.000000 +vn -0.914902 0.365567 -0.171219 +v -164.449951 -139.974762 21.532799 1.000000 1.000000 1.000000 +vn -0.798208 0.364824 -0.479341 +v -164.327637 -140.029190 21.139599 1.000000 1.000000 1.000000 +vn -0.017790 -0.300135 -0.953731 +v -156.897583 -147.579330 18.704800 1.000000 1.000000 1.000000 +vn 0.318454 -0.824208 -0.468260 +v -156.703171 -148.059326 19.200199 1.000000 1.000000 1.000000 +vn 0.597807 -0.330517 0.730332 +v -154.920013 -146.348648 20.866798 1.000000 1.000000 1.000000 +vn 0.333548 -0.161213 0.928847 +v -155.625549 -146.747711 21.123600 1.000000 1.000000 1.000000 +vn 0.734303 -0.495551 0.463928 +v -154.743622 -146.521683 20.528999 1.000000 1.000000 1.000000 +vn 0.640814 -0.089289 0.762486 +v -153.797333 -144.276581 20.535000 1.000000 1.000000 1.000000 +vn 0.433431 -0.090532 0.896628 +v -154.667664 -145.614716 20.902397 1.000000 1.000000 1.000000 +vn 0.775670 -0.322153 0.542728 +v -153.879715 -145.152847 20.309799 1.000000 1.000000 1.000000 +vn 0.947336 -0.318794 -0.030399 +v -153.396912 -144.424484 19.319000 1.000000 1.000000 1.000000 +vn 0.079333 0.651397 -0.754578 +v -159.661804 -147.078415 16.327797 1.000000 1.000000 1.000000 +vn 0.234169 0.953468 0.189906 +v -160.030014 -147.022598 17.089199 1.000000 1.000000 1.000000 +vn -0.114750 0.681238 -0.723013 +v -158.357590 -147.065857 16.327999 1.000000 1.000000 1.000000 +vn 0.462710 0.782891 0.415911 +v -161.195190 -146.684921 17.570795 1.000000 1.000000 1.000000 +vn 0.482058 0.875620 0.030174 +v -161.110214 -146.517487 16.746597 1.000000 1.000000 1.000000 +vn 0.251861 0.843932 0.473650 +v -160.059631 -147.160736 17.482998 1.000000 1.000000 1.000000 +vn 0.034382 0.966802 0.253204 +v -158.855835 -147.149567 17.008400 1.000000 1.000000 1.000000 +vn -0.201377 0.961570 0.186628 +v -158.201797 -147.072830 16.966400 1.000000 1.000000 1.000000 +vn -0.376768 0.622959 -0.685542 +v -156.866669 -146.503540 16.327198 1.000000 1.000000 1.000000 +vn 0.004148 0.883635 0.468158 +v -158.851974 -147.291901 17.401997 1.000000 1.000000 1.000000 +vn 0.381597 0.553999 0.739911 +v -161.308487 -146.909576 17.918598 1.000000 1.000000 1.000000 +vn 0.213332 0.624708 0.751152 +v -160.114990 -147.409103 17.830597 1.000000 1.000000 1.000000 +vn 0.004910 0.660128 0.751137 +v -158.842957 -147.547241 17.749798 1.000000 1.000000 1.000000 +vn -0.239001 0.894046 0.378892 +v -157.595398 -147.051895 17.325199 1.000000 1.000000 1.000000 +vn -0.407423 0.811946 0.418031 +v -157.035339 -146.809113 17.291599 1.000000 1.000000 1.000000 +vn -0.525315 0.476934 -0.704683 +v -155.916519 -145.726334 16.326797 1.000000 1.000000 1.000000 +vn -0.278982 0.618947 0.734217 +v -156.933624 -147.039337 17.639198 1.000000 1.000000 1.000000 +vn 0.541231 0.423435 0.726479 +v -162.344910 -146.079361 18.014797 1.000000 1.000000 1.000000 +vn 0.680238 0.391323 0.619792 +v -163.033707 -145.164017 18.101801 1.000000 1.000000 1.000000 +vn 0.691920 0.567633 0.446139 +v -162.180115 -145.896561 17.667198 1.000000 1.000000 1.000000 +vn 0.603011 0.683141 0.411943 +v -161.711472 -146.327728 17.618000 1.000000 1.000000 1.000000 +vn 0.851693 0.302780 0.427720 +v -163.132843 -144.439835 17.808399 1.000000 1.000000 1.000000 +vn 0.725649 0.368508 0.581065 +v -162.835434 -145.025864 17.754200 1.000000 1.000000 1.000000 +vn 0.917574 0.107891 0.382645 +v -163.497208 -143.165894 17.922600 1.000000 1.000000 1.000000 +vn 0.864255 0.503046 -0.002701 +v -162.687378 -144.921219 16.929798 1.000000 1.000000 1.000000 +vn 0.950898 0.308866 -0.019871 +v -163.185638 -143.760300 17.040199 1.000000 1.000000 1.000000 +vn 0.805146 -0.195889 0.559792 +v -163.486908 -141.488708 18.077198 1.000000 1.000000 1.000000 +vn 0.983656 -0.009487 0.179808 +v -163.425110 -142.491959 17.588997 1.000000 1.000000 1.000000 +vn 0.547928 0.285510 -0.786294 +v -162.917847 -144.714706 16.326797 1.000000 1.000000 1.000000 +vn 0.938007 0.304248 -0.166058 +v -163.234558 -143.777054 16.585400 1.000000 1.000000 1.000000 +vn 0.782290 0.622652 -0.018082 +v -162.330750 -145.441681 16.877197 1.000000 1.000000 1.000000 +vn 0.492235 0.098501 -0.864871 +v -163.485626 -143.266357 16.326797 1.000000 1.000000 1.000000 +vn 0.463052 0.427278 -0.776541 +v -162.225174 -145.681686 16.326797 1.000000 1.000000 1.000000 +vn 0.991126 0.030948 -0.129275 +v -163.430267 -142.491959 16.703598 1.000000 1.000000 1.000000 +vn 0.995110 -0.098604 -0.005787 +v -163.377472 -142.168228 17.189198 1.000000 1.000000 1.000000 +vn 0.962519 -0.141040 -0.231656 +v -163.363312 -141.513824 16.798199 1.000000 1.000000 1.000000 +vn 0.522993 -0.093677 -0.847173 +v -163.510086 -141.247299 16.327599 1.000000 1.000000 1.000000 +vn 0.634541 0.772360 0.028601 +v -161.605896 -146.172836 16.793598 1.000000 1.000000 1.000000 +vn 0.278346 0.533902 -0.798418 +v -161.147552 -146.584457 16.326797 1.000000 1.000000 1.000000 +vn 0.762409 0.598289 0.246541 +v -162.088699 -145.794708 17.273399 1.000000 1.000000 1.000000 +vn -0.054111 0.218008 0.974446 +v -156.826767 -147.280731 17.793800 1.000000 1.000000 1.000000 +vn -0.489738 0.466411 0.736626 +v -155.440155 -145.830978 17.550800 1.000000 1.000000 1.000000 +vn -0.568176 0.745768 0.347860 +v -156.510056 -146.488190 17.259998 1.000000 1.000000 1.000000 +vn -0.602249 0.592176 0.535372 +v -155.615250 -145.659363 17.203197 1.000000 1.000000 1.000000 +vn -0.299376 0.933092 0.199285 +v -155.011429 -144.509598 16.941799 1.000000 1.000000 1.000000 +vn -0.091260 0.787844 0.609076 +v -154.729462 -144.656113 17.533600 1.000000 1.000000 1.000000 +vn -0.821943 0.545395 0.164174 +v -155.355179 -145.070526 16.783398 1.000000 1.000000 1.000000 +vn -0.087363 -0.238220 0.967274 +v -162.983505 -146.110046 42.791580 1.000000 1.000000 1.000000 +vn -0.466666 -0.491862 0.735048 +v -163.152161 -146.269119 42.651176 1.000000 1.000000 1.000000 +vn -0.286230 -0.554013 0.781756 +v -161.950943 -147.386780 42.467777 1.000000 1.000000 1.000000 +vn 0.252787 0.016578 0.967380 +v -163.238419 -145.311920 42.883377 1.000000 1.000000 1.000000 +vn -0.269380 -0.217140 0.938235 +v -163.799759 -144.735641 42.964779 1.000000 1.000000 1.000000 +vn -0.526579 -0.395186 0.752690 +v -163.627243 -145.584000 42.739178 1.000000 1.000000 1.000000 +vn -0.036781 -0.337135 0.940738 +v -161.170731 -147.569565 42.514977 1.000000 1.000000 1.000000 +vn 0.194643 0.162831 0.967264 +v -160.395660 -147.604462 42.422779 1.000000 1.000000 1.000000 +vn 0.216584 -0.066096 0.974024 +v -164.035370 -142.579849 43.189777 1.000000 1.000000 1.000000 +vn -0.438014 -0.021868 0.898702 +v -164.375259 -142.052414 43.189777 1.000000 1.000000 1.000000 +vn -0.586738 -0.230236 0.776357 +v -164.265823 -144.082626 42.902977 1.000000 1.000000 1.000000 +vn -0.743196 -0.493034 0.452303 +v -163.826797 -145.722137 42.401379 1.000000 1.000000 1.000000 +vn -0.790114 -0.383529 0.478148 +v -164.218201 -144.942154 42.486580 1.000000 1.000000 1.000000 +vn -0.581194 -0.159606 0.797959 +v -164.440933 -143.241241 42.985378 1.000000 1.000000 1.000000 +vn -0.880971 -0.163386 0.444066 +v -164.675247 -143.278915 42.647579 1.000000 1.000000 1.000000 +vn -0.850761 -0.278836 0.445484 +v -164.492432 -144.157974 42.565178 1.000000 1.000000 1.000000 +vn -0.949278 -0.277529 0.147812 +v -164.636627 -144.205414 42.096779 1.000000 1.000000 1.000000 +vn -0.904948 -0.398444 0.149372 +v -164.355957 -145.010529 42.018181 1.000000 1.000000 1.000000 +vn -0.977689 -0.150050 0.147003 +v -164.824600 -143.304031 42.179379 1.000000 1.000000 1.000000 +vn -0.988930 -0.017234 0.147379 +v -164.891541 -142.384506 42.259579 1.000000 1.000000 1.000000 +vn -0.879473 -0.041990 0.474092 +v -164.739624 -142.384506 42.727978 1.000000 1.000000 1.000000 +vn -0.874314 0.071431 0.480077 +v -164.682983 -141.490097 42.805779 1.000000 1.000000 1.000000 +vn -0.982094 0.116899 0.147735 +v -164.833618 -141.466385 42.337379 1.000000 1.000000 1.000000 +vn -0.878380 0.196252 0.435814 +v -164.510452 -140.626389 42.879978 1.000000 1.000000 1.000000 +vn -0.957840 0.246514 0.147560 +v -164.655945 -140.581741 42.411579 1.000000 1.000000 1.000000 +vn -0.475337 0.102439 0.873820 +v -164.294159 -140.609650 43.189777 1.000000 1.000000 1.000000 +vn 0.420596 -0.155229 0.893870 +v -163.604065 -140.965454 43.189777 1.000000 1.000000 1.000000 +vn 0.410111 -0.276493 0.869115 +v -163.019562 -139.797562 43.187378 1.000000 1.000000 1.000000 +vn -0.508273 0.336752 0.792627 +v -163.540985 -138.611526 43.189377 1.000000 1.000000 1.000000 +vn 0.354019 -0.378827 0.855079 +v -162.185257 -138.770599 43.189777 1.000000 1.000000 1.000000 +vn -0.396446 0.561551 0.726286 +v -162.053940 -137.022232 43.185780 1.000000 1.000000 1.000000 +vn 0.350347 -0.474888 0.807303 +v -161.591736 -138.298965 43.189777 1.000000 1.000000 1.000000 +vn 0.261553 -0.556844 0.788362 +v -161.013657 -137.986420 43.182579 1.000000 1.000000 1.000000 +vn -0.202724 0.668727 0.715337 +v -160.517975 -136.249237 43.188580 1.000000 1.000000 1.000000 +vn 0.140075 -0.597418 0.789602 +v -160.099548 -137.637573 43.189777 1.000000 1.000000 1.000000 +vn 0.113320 0.717532 0.687246 +v -158.116821 -136.009232 43.189777 1.000000 1.000000 1.000000 +vn -0.055457 -0.608282 0.791782 +v -158.685883 -137.542694 43.189178 1.000000 1.000000 1.000000 +vn -0.326330 -0.494406 0.805650 +v -156.734070 -138.218033 43.189777 1.000000 1.000000 1.000000 +vn 0.485283 0.567671 0.665018 +v -155.225143 -137.407349 43.188377 1.000000 1.000000 1.000000 +vn -0.513142 -0.458112 0.725823 +v -155.818665 -139.066406 43.189777 1.000000 1.000000 1.000000 +vn 0.595613 0.453786 0.662815 +v -154.480972 -138.204086 43.188580 1.000000 1.000000 1.000000 +vn -0.637074 -0.299846 0.710091 +v -155.109268 -140.177094 43.188377 1.000000 1.000000 1.000000 +vn 0.696593 0.299226 0.652090 +v -153.637680 -139.669189 43.189777 1.000000 1.000000 1.000000 +vn 0.753576 0.147433 0.640614 +v -153.185776 -140.982193 43.189579 1.000000 1.000000 1.000000 +vn -0.720964 -0.151892 0.676121 +v -154.715302 -141.379868 43.189777 1.000000 1.000000 1.000000 +vn -0.705159 0.044271 0.707666 +v -154.623886 -142.614731 43.189377 1.000000 1.000000 1.000000 +vn 0.796556 -0.109480 0.594569 +v -153.114960 -143.373795 43.186760 1.000000 1.000000 1.000000 +vn -0.764521 -0.300220 0.570416 +v -155.039734 -144.484497 43.189377 1.000000 1.000000 1.000000 +vn 0.348852 -0.779432 0.520373 +v -153.680161 -145.221222 43.189579 1.000000 1.000000 1.000000 +vn -0.916116 0.372476 0.148301 +v -164.359818 -139.716629 42.485180 1.000000 1.000000 1.000000 +vn -0.811697 0.311205 0.494267 +v -164.222061 -139.783600 42.953377 1.000000 1.000000 1.000000 +vn -0.978074 -0.121570 -0.169093 +v -164.811722 -143.301239 41.363777 1.000000 1.000000 1.000000 +vn -0.913230 -0.369981 -0.170658 +v -164.344376 -145.004944 41.202778 1.000000 1.000000 1.000000 +vn -0.953653 -0.248660 -0.169454 +v -164.625031 -144.201233 41.281380 1.000000 1.000000 1.000000 +vn -0.842582 -0.517012 0.150843 +v -163.954269 -145.811447 41.933178 1.000000 1.000000 1.000000 +vn -0.855721 -0.488283 -0.171234 +v -163.942673 -145.804474 41.117577 1.000000 1.000000 1.000000 +vn -0.839048 -0.309290 -0.447593 +v -164.223343 -144.944946 40.809578 1.000000 1.000000 1.000000 +vn -0.858544 -0.192122 -0.475386 +v -164.497574 -144.159378 40.888180 1.000000 1.000000 1.000000 +vn -0.891647 -0.084085 -0.444854 +v -164.680389 -143.280304 40.970779 1.000000 1.000000 1.000000 +vn -0.687561 -0.026344 -0.725648 +v -164.446075 -143.242630 40.626179 1.000000 1.000000 1.000000 +vn -0.655975 -0.199355 -0.727980 +v -164.008331 -144.838898 40.464977 1.000000 1.000000 1.000000 +vn -0.777247 -0.405642 -0.480980 +v -163.831955 -145.726334 40.724380 1.000000 1.000000 1.000000 +vn -0.777486 -0.604580 -0.173203 +v -163.436691 -146.537018 41.029579 1.000000 1.000000 1.000000 +vn -0.721562 -0.522022 -0.454798 +v -163.336273 -146.442139 40.636379 1.000000 1.000000 1.000000 +vn -0.584975 -0.355714 -0.728884 +v -163.157303 -146.273300 40.291977 1.000000 1.000000 1.000000 +vn -0.315755 -0.026113 -0.948481 +v -163.784317 -144.727280 40.313980 1.000000 1.000000 1.000000 +vn -0.203297 0.065942 -0.976894 +v -164.202744 -143.202164 40.475178 1.000000 1.000000 1.000000 +vn -0.505132 -0.429668 -0.748483 +v -162.593399 -146.880280 40.201378 1.000000 1.000000 1.000000 +vn -0.289249 -0.084283 -0.953536 +v -162.970627 -146.097488 40.140980 1.000000 1.000000 1.000000 +vn -0.640017 -0.617234 -0.457603 +v -162.747894 -147.074219 40.545776 1.000000 1.000000 1.000000 +vn -0.683082 -0.709067 -0.174993 +v -162.834152 -147.183060 40.938980 1.000000 1.000000 1.000000 +vn -0.536958 -0.685672 -0.491457 +v -162.080978 -147.610031 40.452980 1.000000 1.000000 1.000000 +vn -0.573135 -0.800207 -0.176594 +v -162.151794 -147.731430 40.846176 1.000000 1.000000 1.000000 +vn -0.272757 -0.196224 -0.941860 +v -161.822205 -147.167709 39.957581 1.000000 1.000000 1.000000 +vn -0.365555 -0.546279 -0.753624 +v -161.264709 -147.795609 40.015377 1.000000 1.000000 1.000000 +vn -0.449179 -0.875488 -0.178211 +v -161.416641 -148.161194 40.752979 1.000000 1.000000 1.000000 +vn -0.434634 -0.770930 -0.465575 +v -161.362564 -148.030029 40.359779 1.000000 1.000000 1.000000 +vn -0.545884 -0.823447 0.154744 +v -162.159515 -147.742599 41.661579 1.000000 1.000000 1.000000 +vn -0.311888 -0.932936 -0.179880 +v -160.627411 -148.476547 40.656979 1.000000 1.000000 1.000000 +vn -0.417722 -0.895014 0.156391 +v -161.421783 -148.173752 41.568378 1.000000 1.000000 1.000000 +vn -0.312486 -0.808781 -0.498223 +v -160.591370 -148.338394 40.263977 1.000000 1.000000 1.000000 +vn -0.164243 -0.969700 -0.180849 +v -159.800858 -148.664902 40.558178 1.000000 1.000000 1.000000 +vn -0.276847 -0.947833 0.158011 +v -160.631271 -148.490494 41.472580 1.000000 1.000000 1.000000 +vn -0.211428 -0.857889 0.468322 +v -160.590073 -148.331421 41.940781 1.000000 1.000000 1.000000 +vn -0.330823 -0.802282 0.496890 +v -161.359985 -148.024445 42.036777 1.000000 1.000000 1.000000 +vn -0.067296 -0.863020 0.500668 +v -159.781525 -148.516998 41.841980 1.000000 1.000000 1.000000 +vn -0.125262 -0.979526 0.157603 +v -159.802139 -148.678864 41.373779 1.000000 1.000000 1.000000 +vn -0.082685 -0.614500 0.784572 +v -160.524414 -148.085846 42.278580 1.000000 1.000000 1.000000 +vn -0.459779 -0.757345 0.463716 +v -162.078400 -147.604462 42.129978 1.000000 1.000000 1.000000 +vn 0.110798 -0.664952 0.738622 +v -158.957550 -148.316071 42.078777 1.000000 1.000000 1.000000 +vn 0.118391 -0.283638 0.951595 +v -158.960129 -148.073288 42.219177 1.000000 1.000000 1.000000 +vn 0.094064 -0.874172 0.476419 +v -158.956253 -148.572815 41.740978 1.000000 1.000000 1.000000 +vn 0.028873 -0.986014 0.164141 +v -158.954971 -148.737457 41.272579 1.000000 1.000000 1.000000 +vn 0.220838 -0.944204 0.244357 +v -157.923706 -148.630020 41.146580 1.000000 1.000000 1.000000 +vn 0.337032 -0.812164 0.476234 +v -157.156372 -148.243515 41.509979 1.000000 1.000000 1.000000 +vn 0.299202 -0.563312 0.770167 +v -157.232330 -148.000732 41.847778 1.000000 1.000000 1.000000 +vn 0.193564 -0.316464 0.928646 +v -158.035706 -147.977005 42.093178 1.000000 1.000000 1.000000 +vn 0.389450 -0.495839 0.776191 +v -156.503601 -147.665848 41.739979 1.000000 1.000000 1.000000 +vn 0.359418 -0.919958 0.156511 +v -157.107437 -148.398392 41.041580 1.000000 1.000000 1.000000 +vn 0.479346 -0.746190 0.461983 +v -156.396744 -147.894684 41.402378 1.000000 1.000000 1.000000 +vn 0.579085 -0.652344 0.488986 +v -155.689926 -147.431442 41.292580 1.000000 1.000000 1.000000 +vn 0.551631 -0.403154 0.730185 +v -155.219986 -146.682144 41.519379 1.000000 1.000000 1.000000 +vn 0.310978 -0.195731 0.930044 +v -155.956436 -147.024002 41.770779 1.000000 1.000000 1.000000 +vn 0.494477 -0.855219 0.155221 +v -156.327225 -148.041199 40.933979 1.000000 1.000000 1.000000 +vn 0.315418 -0.931250 -0.182439 +v -157.111298 -148.385849 40.226177 1.000000 1.000000 1.000000 +vn 0.456500 -0.871417 -0.179559 +v -156.333664 -148.028625 40.118580 1.000000 1.000000 1.000000 +vn 0.617834 -0.771118 0.153813 +v -155.602371 -147.565384 40.824181 1.000000 1.000000 1.000000 +vn 0.578712 -0.795595 -0.179224 +v -155.610092 -147.552826 40.008778 1.000000 1.000000 1.000000 +vn 0.244104 -0.805582 -0.539862 +v -157.155075 -148.249100 39.832977 1.000000 1.000000 1.000000 +vn 0.332957 -0.775777 -0.536013 +v -156.394180 -147.900269 39.725380 1.000000 1.000000 1.000000 +vn 0.750574 -0.660286 -0.025720 +v -154.693405 -146.758881 40.259178 1.000000 1.000000 1.000000 +vn 0.494785 -0.733020 -0.466764 +v -155.687347 -147.435623 39.615578 1.000000 1.000000 1.000000 +vn 0.667963 -0.712292 -0.215560 +v -154.961212 -146.976547 39.897778 1.000000 1.000000 1.000000 +vn 0.020975 -0.652234 -0.757728 +v -157.993225 -148.221191 39.593376 1.000000 1.000000 1.000000 +vn 0.319146 -0.594341 -0.738177 +v -155.823822 -147.226318 39.271179 1.000000 1.000000 1.000000 +vn 0.092199 -0.892250 -0.442028 +v -157.949448 -148.473740 39.937981 1.000000 1.000000 1.000000 +vn -0.116052 -0.241645 -0.963400 +v -158.960129 -148.055145 39.568581 1.000000 1.000000 1.000000 +vn 0.009149 -0.318048 -0.948030 +v -157.310852 -147.752350 39.337578 1.000000 1.000000 1.000000 +vn -0.169834 -0.636339 -0.752482 +v -159.750641 -148.268631 39.820580 1.000000 1.000000 1.000000 +vn -0.172961 -0.160434 -0.971774 +v -160.457458 -147.834671 39.768379 1.000000 1.000000 1.000000 +vn -0.161050 -0.861814 -0.480977 +v -159.782822 -148.522583 40.165176 1.000000 1.000000 1.000000 +vn -0.011904 -0.969443 -0.245029 +v -158.954971 -148.723511 40.457176 1.000000 1.000000 1.000000 +vn 0.211678 -0.976277 -0.045557 +v -157.917267 -148.666306 40.736580 1.000000 1.000000 1.000000 +vn 0.059253 -0.298347 -0.952617 +v -155.966736 -147.008652 39.119980 1.000000 1.000000 1.000000 +vn 0.382810 -0.457283 -0.802713 +v -154.997253 -146.449112 39.115978 1.000000 1.000000 1.000000 +vn 0.630985 -0.632272 -0.449544 +v -154.824738 -146.624924 39.460579 1.000000 1.000000 1.000000 +vn -0.321962 0.086402 -0.942802 +v -155.346161 -146.091904 38.970177 1.000000 1.000000 1.000000 +vn 0.181397 -0.257995 -0.948965 +v -154.314896 -144.939362 38.735378 1.000000 1.000000 1.000000 +vn 0.553562 -0.396796 -0.732204 +v -154.096024 -145.060760 38.886578 1.000000 1.000000 1.000000 +vn 0.697064 -0.527149 -0.486020 +v -154.305878 -145.934235 39.346378 1.000000 1.000000 1.000000 +vn 0.814416 -0.551559 -0.180307 +v -154.196442 -146.017960 39.739380 1.000000 1.000000 1.000000 +vn 0.780728 -0.432340 -0.451161 +v -153.884872 -145.176575 39.230980 1.000000 1.000000 1.000000 +vn 0.881868 -0.439046 -0.171896 +v -153.766418 -145.242157 39.624180 1.000000 1.000000 1.000000 +vn 0.565444 -0.265381 -0.780926 +v -153.792175 -144.280762 38.770180 1.000000 1.000000 1.000000 +vn 0.832829 -0.324453 -0.448471 +v -153.568146 -144.363083 39.114777 1.000000 1.000000 1.000000 +vn 0.933066 -0.316751 -0.170462 +v -153.441986 -144.409149 39.507778 1.000000 1.000000 1.000000 +vn -0.360252 -0.047459 -0.931647 +v -154.246658 -144.113327 38.624378 1.000000 1.000000 1.000000 +vn -0.270836 -0.134489 -0.953185 +v -153.985291 -142.616135 38.394180 1.000000 1.000000 1.000000 +vn 0.278925 -0.158603 -0.947125 +v -153.752258 -142.628693 38.389179 1.000000 1.000000 1.000000 +vn -0.218051 -0.202486 -0.954701 +v -154.116623 -141.091034 38.162979 1.000000 1.000000 1.000000 +vn 0.305268 -0.079001 -0.948984 +v -153.890030 -141.032425 38.157776 1.000000 1.000000 1.000000 +vn -0.103559 -0.254072 -0.961625 +v -154.984375 -139.091522 37.828178 1.000000 1.000000 1.000000 +vn 0.325065 0.041326 -0.944788 +v -154.797699 -138.940826 37.823181 1.000000 1.000000 1.000000 +vn -0.016973 -0.270642 -0.962530 +v -155.982178 -138.007339 37.596977 1.000000 1.000000 1.000000 +vn 0.750585 -0.627349 0.207498 +v -154.719162 -146.733765 40.669178 1.000000 1.000000 1.000000 +vn 0.844073 -0.512768 0.156875 +v -154.186142 -146.024933 40.554977 1.000000 1.000000 1.000000 +vn 0.682319 -0.577712 0.447984 +v -155.056473 -146.867722 41.181580 1.000000 1.000000 1.000000 +vn 0.774809 -0.441498 0.452493 +v -154.309738 -145.931442 41.023376 1.000000 1.000000 1.000000 +vn 0.902978 -0.403166 0.148619 +v -153.754837 -145.247742 40.439579 1.000000 1.000000 1.000000 +vn 0.820203 -0.316001 0.476875 +v -153.890030 -145.173782 40.907978 1.000000 1.000000 1.000000 +vn 0.595635 -0.251681 0.762807 +v -154.504150 -145.783554 41.360977 1.000000 1.000000 1.000000 +vn 0.680155 -0.109913 0.724781 +v -153.797333 -144.277985 41.129379 1.000000 1.000000 1.000000 +vn 0.323137 -0.088219 0.942231 +v -155.164627 -146.278885 41.615761 1.000000 1.000000 1.000000 +vn 0.948987 -0.278758 0.147369 +v -153.430389 -144.413330 40.323380 1.000000 1.000000 1.000000 +vn 0.133561 0.228080 0.964438 +v -158.961411 -147.815140 42.222977 1.000000 1.000000 1.000000 +vn 0.067079 0.243077 0.967685 +v -157.381668 -147.526306 41.991978 1.000000 1.000000 1.000000 +vn -0.554437 -0.670974 0.492334 +v -162.744034 -147.070038 42.222778 1.000000 1.000000 1.000000 +vn -0.663568 -0.593111 0.455958 +v -163.331116 -146.437943 42.313377 1.000000 1.000000 1.000000 +vn -0.760051 -0.631712 0.152517 +v -163.445709 -146.545395 41.844978 1.000000 1.000000 1.000000 +vn -0.660980 -0.734609 0.153149 +v -162.843170 -147.194214 41.754379 1.000000 1.000000 1.000000 +vn -0.253929 0.110631 -0.960875 +v -164.210464 -141.562653 40.633179 1.000000 1.000000 1.000000 +vn -0.877776 0.036793 -0.477657 +v -164.744781 -142.384506 41.050980 1.000000 1.000000 1.000000 +vn -0.663247 0.159569 -0.731192 +v -164.453812 -141.524979 40.784378 1.000000 1.000000 1.000000 +vn -0.881538 0.153657 -0.446409 +v -164.689407 -141.488708 41.128777 1.000000 1.000000 1.000000 +vn -0.985438 0.009465 -0.169771 +v -164.878677 -142.384506 41.444180 1.000000 1.000000 1.000000 +vn -0.836603 0.266405 -0.478669 +v -164.515594 -140.624985 41.202980 1.000000 1.000000 1.000000 +vn -0.975265 0.142487 -0.168984 +v -164.820740 -141.469177 41.521980 1.000000 1.000000 1.000000 +vn -0.947591 0.270463 -0.170062 +v -164.643066 -140.584518 41.596176 1.000000 1.000000 1.000000 +vn -0.902934 0.394384 -0.170795 +v -164.348236 -139.722214 41.669579 1.000000 1.000000 1.000000 +vn -0.808198 0.378977 -0.450769 +v -164.227203 -139.780823 41.276581 1.000000 1.000000 1.000000 +vn -0.263145 0.178887 -0.948026 +v -164.232361 -141.751022 25.565798 1.000000 1.000000 1.000000 +vn 0.226691 0.134895 -0.964580 +v -163.999313 -141.778931 25.570799 1.000000 1.000000 1.000000 +vn 0.187905 0.206552 -0.960223 +v -163.801056 -143.976578 25.236198 1.000000 1.000000 1.000000 +vn -0.163388 0.263455 -0.950734 +v -163.543564 -139.482208 25.911798 1.000000 1.000000 1.000000 +vn -0.319626 0.061142 -0.945569 +v -164.023788 -144.051926 25.231199 1.000000 1.000000 1.000000 +vn 0.306847 0.004955 -0.951746 +v -163.342712 -139.610580 25.916998 1.000000 1.000000 1.000000 +vn -0.040066 0.294475 -0.954819 +v -162.051361 -137.714325 26.258999 1.000000 1.000000 1.000000 +vn 0.271861 -0.095393 -0.957597 +v -161.916183 -137.920837 26.263998 1.000000 1.000000 1.000000 +vn 0.050894 0.304727 -0.951079 +v -160.736847 -136.978989 26.490398 1.000000 1.000000 1.000000 +vn 0.229368 -0.167215 -0.958869 +v -160.659607 -137.217590 26.495398 1.000000 1.000000 1.000000 +vn 0.185452 0.255075 -0.948970 +v -158.622803 -136.674805 26.824999 1.000000 1.000000 1.000000 +vn 0.153461 -0.204997 -0.966657 +v -158.639542 -136.927368 26.829998 1.000000 1.000000 1.000000 +vn 0.281289 0.159003 -0.946359 +v -156.507462 -137.343170 27.170998 1.000000 1.000000 1.000000 +vn 0.018363 -0.285808 -0.958111 +v -156.618195 -137.565018 27.176197 1.000000 1.000000 1.000000 +vn 0.315069 0.042926 -0.948097 +v -154.826019 -138.898956 27.518198 1.000000 1.000000 1.000000 +vn 0.620699 0.299491 -0.724595 +v -154.630325 -138.737106 27.669197 1.000000 1.000000 1.000000 +vn 0.324487 -0.040747 -0.945012 +v -154.102463 -140.297089 27.749598 1.000000 1.000000 1.000000 +vn 0.509131 0.357634 -0.782869 +v -155.147888 -138.102234 27.552799 1.000000 1.000000 1.000000 +vn 0.443955 0.509498 -0.737099 +v -156.390320 -137.107361 27.321999 1.000000 1.000000 1.000000 +vn 0.681070 0.121900 -0.722000 +v -153.873291 -140.200806 27.900599 1.000000 1.000000 1.000000 +vn 0.275473 -0.162124 -0.947539 +v -153.749680 -142.577057 28.084198 1.000000 1.000000 1.000000 +vn 0.635701 -0.012255 -0.771838 +v -153.528244 -141.744049 28.119398 1.000000 1.000000 1.000000 +vn 0.878073 0.239269 -0.414414 +v -153.651840 -140.107330 28.244999 1.000000 1.000000 1.000000 +vn 0.806569 0.345461 -0.479691 +v -153.994308 -139.317566 28.129999 1.000000 1.000000 1.000000 +vn 0.675689 -0.142078 -0.723366 +v -153.503769 -142.586838 28.235197 1.000000 1.000000 1.000000 +vn 0.891072 0.040326 -0.452068 +v -153.292633 -141.717545 28.463799 1.000000 1.000000 1.000000 +vn 0.956612 0.204981 -0.207064 +v -153.305496 -140.811966 28.740398 1.000000 1.000000 1.000000 +vn 0.889707 0.423814 -0.169717 +v -153.878433 -139.246399 28.522999 1.000000 1.000000 1.000000 +vn 0.761183 0.464224 -0.452876 +v -154.441071 -138.580826 28.013798 1.000000 1.000000 1.000000 +vn 0.816789 0.550368 -0.173065 +v -154.335495 -138.492920 28.406799 1.000000 1.000000 1.000000 +vn 0.920041 0.356043 0.163577 +v -153.515366 -140.050125 29.453598 1.000000 1.000000 1.000000 +vn 0.868664 0.471952 0.150611 +v -153.866852 -139.239426 29.338598 1.000000 1.000000 1.000000 +vn 0.732664 0.657867 -0.174396 +v -154.889114 -137.816177 28.290398 1.000000 1.000000 1.000000 +vn 0.705343 0.692178 0.152907 +v -154.880096 -137.806412 29.105799 1.000000 1.000000 1.000000 +vn 0.794964 0.587250 0.152215 +v -154.325195 -138.484558 29.222399 1.000000 1.000000 1.000000 +vn 0.689511 0.562823 -0.455856 +v -154.981812 -137.919449 27.897198 1.000000 1.000000 1.000000 +vn 0.596015 0.637378 -0.488379 +v -155.595932 -137.350143 27.781998 1.000000 1.000000 1.000000 +vn 0.633249 0.753689 -0.175921 +v -155.517395 -137.234329 28.174999 1.000000 1.000000 1.000000 +vn 0.516329 0.837807 -0.177436 +v -156.213928 -136.754333 28.059599 1.000000 1.000000 1.000000 +vn 0.600395 0.784519 0.155100 +v -155.509674 -137.223175 28.990599 1.000000 1.000000 1.000000 +vn 0.500533 0.731077 -0.463674 +v -156.277023 -136.881317 27.666599 1.000000 1.000000 1.000000 +vn 0.387616 0.904076 -0.180004 +v -156.963242 -136.388763 27.944998 1.000000 1.000000 1.000000 +vn 0.479295 0.863631 0.156261 +v -156.208786 -136.743179 28.875198 1.000000 1.000000 1.000000 +vn 0.490593 0.719455 0.491633 +v -155.599808 -137.355728 29.458799 1.000000 1.000000 1.000000 +vn 0.390128 0.795142 0.464274 +v -156.280884 -136.886887 29.343399 1.000000 1.000000 1.000000 +vn 0.257961 0.828298 0.497372 +v -157.010880 -136.529694 29.228798 1.000000 1.000000 1.000000 +vn 0.347200 0.924524 0.157187 +v -156.958099 -136.374802 28.760599 1.000000 1.000000 1.000000 +vn 0.239043 0.622477 0.745239 +v -156.392883 -137.112930 29.681198 1.000000 1.000000 1.000000 +vn 0.603824 0.652804 0.457431 +v -154.985672 -137.923630 29.574198 1.000000 1.000000 1.000000 +vn 0.371766 0.511005 0.775025 +v -155.151764 -138.106415 29.911999 1.000000 1.000000 1.000000 +vn 0.675023 0.555353 0.485723 +v -154.446213 -138.585007 29.690598 1.000000 1.000000 1.000000 +vn 0.545473 0.385856 0.744026 +v -154.206741 -139.445938 30.144598 1.000000 1.000000 1.000000 +vn 0.189795 0.305623 0.933045 +v -154.811859 -138.887802 30.168999 1.000000 1.000000 1.000000 +vn 0.020009 0.315823 0.948607 +v -156.498459 -137.326416 29.821798 1.000000 1.000000 1.000000 +vn 0.031510 0.624985 0.780001 +v -157.841309 -136.533875 29.450399 1.000000 1.000000 1.000000 +vn 0.137079 0.872341 0.469287 +v -157.791092 -136.282715 29.112598 1.000000 1.000000 1.000000 +vn -0.026035 0.844021 0.535678 +v -158.588043 -136.158524 28.997398 1.000000 1.000000 1.000000 +vn -0.245864 0.590220 0.768890 +v -160.156189 -136.531082 29.102798 1.000000 1.000000 1.000000 +vn -0.132013 0.424089 0.895947 +v -158.621521 -136.656662 29.475798 1.000000 1.000000 1.000000 +vn 0.204191 0.966134 0.157767 +v -157.758896 -136.122253 28.644398 1.000000 1.000000 1.000000 +vn 0.249229 0.951349 -0.181163 +v -157.761490 -136.136200 27.828798 1.000000 1.000000 1.000000 +vn 0.102173 0.978053 -0.181586 +v -158.579025 -136.007828 27.713598 1.000000 1.000000 1.000000 +vn 0.055572 0.985731 0.158891 +v -158.577744 -135.993881 28.529198 1.000000 1.000000 1.000000 +vn 0.388055 0.794599 -0.466932 +v -157.009583 -136.524109 27.551798 1.000000 1.000000 1.000000 +vn 0.265694 0.825400 -0.498118 +v -157.789795 -136.277130 27.435799 1.000000 1.000000 1.000000 +vn 0.135196 0.871520 -0.471354 +v -158.588043 -136.151550 27.320599 1.000000 1.000000 1.000000 +vn -0.048843 0.982127 -0.181770 +v -159.408173 -136.006439 27.597799 1.000000 1.000000 1.000000 +vn -0.120424 0.833813 0.538753 +v -159.399155 -136.157135 28.881599 1.000000 1.000000 1.000000 +vn -0.096008 0.982659 0.158628 +v -159.409454 -135.992477 28.413198 1.000000 1.000000 1.000000 +vn -0.014507 0.876961 -0.480343 +v -159.399155 -136.150146 27.204599 1.000000 1.000000 1.000000 +vn -0.203853 0.953941 -0.220091 +v -160.234726 -136.133423 27.481199 1.000000 1.000000 1.000000 +vn -0.239723 0.957907 0.157944 +v -160.237305 -136.119461 28.296598 1.000000 1.000000 1.000000 +vn 0.181599 0.641279 -0.745509 +v -158.604782 -136.408295 26.975998 1.000000 1.000000 1.000000 +vn 0.034660 0.612181 -0.789958 +v -159.382416 -136.406906 26.860197 1.000000 1.000000 1.000000 +vn -0.240566 0.866440 -0.437504 +v -160.896500 -136.483643 26.985798 1.000000 1.000000 1.000000 +vn -0.448393 0.876148 -0.176944 +v -161.698593 -136.699921 27.263798 1.000000 1.000000 1.000000 +vn -0.374395 0.911411 0.170757 +v -160.944138 -136.334335 28.194399 1.000000 1.000000 1.000000 +vn -0.280380 0.834987 0.473480 +v -160.206406 -136.281311 28.764999 1.000000 1.000000 1.000000 +vn -0.471650 0.746643 0.469118 +v -161.634216 -136.833878 28.547598 1.000000 1.000000 1.000000 +vn -0.405647 0.524489 0.748573 +v -161.526077 -137.062714 28.885399 1.000000 1.000000 1.000000 +vn -0.500466 0.851732 0.155202 +v -161.703751 -136.688751 28.079399 1.000000 1.000000 1.000000 +vn -0.584334 0.648721 0.487560 +v -162.328171 -137.292938 28.431398 1.000000 1.000000 1.000000 +vn -0.535613 0.355801 0.765849 +v -162.792953 -138.040833 28.652798 1.000000 1.000000 1.000000 +vn -0.249373 0.253854 0.934544 +v -160.741989 -136.960846 29.140999 1.000000 1.000000 1.000000 +vn -0.323110 0.184607 0.928181 +v -162.061661 -137.698975 28.909798 1.000000 1.000000 1.000000 +vn -0.679967 0.575655 0.454165 +v -162.956467 -137.853851 28.314999 1.000000 1.000000 1.000000 +vn -0.744251 0.464685 0.479749 +v -163.501068 -138.499908 28.199598 1.000000 1.000000 1.000000 +vn -0.646521 0.235686 0.725578 +v -163.752136 -139.351059 28.421997 1.000000 1.000000 1.000000 +vn -0.618768 0.770455 0.153379 +v -162.415726 -137.158981 27.963198 1.000000 1.000000 1.000000 +vn -0.722401 0.674657 0.151575 +v -163.060745 -137.735260 27.846598 1.000000 1.000000 1.000000 +vn -0.809196 0.568011 0.150215 +v -163.619522 -138.398041 27.731398 1.000000 1.000000 1.000000 +vn -0.813675 0.372365 0.446405 +v -163.955551 -139.221283 28.084198 1.000000 1.000000 1.000000 +vn -0.878873 0.453116 0.149222 +v -164.086868 -139.138962 27.615999 1.000000 1.000000 1.000000 +vn -0.581318 0.794170 -0.177099 +v -162.407990 -137.170151 27.147598 1.000000 1.000000 1.000000 +vn -0.362743 0.787738 -0.497882 +v -161.636795 -136.828278 26.870798 1.000000 1.000000 1.000000 +vn -0.489227 0.738769 -0.463548 +v -162.332031 -137.287354 26.754599 1.000000 1.000000 1.000000 +vn -0.689179 0.702921 -0.175883 +v -163.051727 -137.745026 27.031199 1.000000 1.000000 1.000000 +vn -0.112877 0.656586 -0.745757 +v -160.817947 -136.726425 26.641399 1.000000 1.000000 1.000000 +vn -0.310190 0.597168 -0.739711 +v -162.194275 -137.496658 26.409998 1.000000 1.000000 1.000000 +vn -0.590982 0.661641 -0.461489 +v -162.960327 -137.849670 26.637999 1.000000 1.000000 1.000000 +vn -0.780785 0.599993 -0.174309 +v -163.609222 -138.406418 26.915798 1.000000 1.000000 1.000000 +vn -0.664993 0.566260 -0.486964 +v -163.504929 -138.495712 26.522799 1.000000 1.000000 1.000000 +vn -0.855415 0.488314 -0.172668 +v -164.075287 -139.145935 26.800398 1.000000 1.000000 1.000000 +vn -0.375037 0.485071 -0.789971 +v -162.796814 -138.036652 26.293598 1.000000 1.000000 1.000000 +vn -0.531015 0.425626 -0.732711 +v -163.755997 -139.348251 26.062798 1.000000 1.000000 1.000000 +vn -0.754133 0.475655 -0.452809 +v -163.960693 -139.218491 26.407398 1.000000 1.000000 1.000000 +vn -0.913565 0.368706 -0.171625 +v -164.439636 -139.944061 26.685799 1.000000 1.000000 1.000000 +vn -0.812402 0.370472 -0.450281 +v -164.316040 -139.998489 26.292599 1.000000 1.000000 1.000000 +vn -0.931644 0.331660 0.148464 +v -164.451233 -139.938492 27.501398 1.000000 1.000000 1.000000 +vn -0.549248 0.296746 -0.781197 +v -164.097168 -140.096161 25.948198 1.000000 1.000000 1.000000 +vn -0.839674 0.259814 -0.476911 +v -164.569672 -140.835678 26.176598 1.000000 1.000000 1.000000 +vn -0.664548 0.184623 -0.724079 +v -164.476974 -141.723114 25.716799 1.000000 1.000000 1.000000 +vn 0.310012 0.529358 -0.789729 +v -157.091980 -136.764099 27.207399 1.000000 1.000000 1.000000 +vn -0.281482 -0.023275 0.959284 +v -155.001114 -139.044083 30.172798 1.000000 1.000000 1.000000 +vn -0.283676 0.062454 0.956884 +v -154.308456 -140.383606 30.403999 1.000000 1.000000 1.000000 +vn 0.262946 0.237918 0.935016 +v -154.087006 -140.290115 30.400398 1.000000 1.000000 1.000000 +vn -0.230014 0.158575 0.960181 +v -153.971146 -142.567307 30.738798 1.000000 1.000000 1.000000 +vn 0.440002 0.135651 0.887692 +v -153.732941 -142.577057 30.734999 1.000000 1.000000 1.000000 +vn -0.691898 0.137682 0.708746 +v -154.217041 -142.557526 30.584198 1.000000 1.000000 1.000000 +vn -0.138789 0.233263 0.962458 +v -154.492569 -144.784485 31.084799 1.000000 1.000000 1.000000 +vn 0.336159 -0.002809 0.941801 +v -154.278839 -144.898895 31.080999 1.000000 1.000000 1.000000 +vn -0.577401 0.392912 0.715702 +v -154.712723 -144.665878 30.930199 1.000000 1.000000 1.000000 +vn -0.033550 0.264369 0.963838 +v -155.812241 -146.580276 31.431999 1.000000 1.000000 1.000000 +vn 0.335338 -0.162983 0.927893 +v -155.660309 -146.779816 31.428198 1.000000 1.000000 1.000000 +vn -0.367616 0.574729 0.731126 +v -155.968018 -146.373764 31.277399 1.000000 1.000000 1.000000 +vn 0.060750 0.266347 0.961961 +v -157.023743 -147.375626 31.663198 1.000000 1.000000 1.000000 +vn 0.267417 -0.237366 0.933887 +v -156.929764 -147.614227 31.659599 1.000000 1.000000 1.000000 +vn -0.129016 0.657255 0.742543 +v -157.120316 -147.130035 31.508799 1.000000 1.000000 1.000000 +vn 0.163876 0.214775 0.962817 +v -159.024490 -147.816544 31.997999 1.000000 1.000000 1.000000 +vn -0.245150 0.853363 0.460079 +v -157.213013 -146.895630 31.160999 1.000000 1.000000 1.000000 +vn -0.427135 0.800204 0.420986 +v -156.643951 -146.578888 31.045799 1.000000 1.000000 1.000000 +vn 0.129765 0.667391 0.733315 +v -159.024490 -147.548645 31.843399 1.000000 1.000000 1.000000 +vn 0.241957 0.133710 0.961030 +v -161.087036 -147.328171 32.343998 1.000000 1.000000 1.000000 +vn 0.093586 0.884480 0.457096 +v -159.023209 -147.293289 31.495798 1.000000 1.000000 1.000000 +vn -0.137177 0.936289 0.323334 +v -158.380753 -147.247253 31.379799 1.000000 1.000000 1.000000 +vn 0.222686 0.912549 0.343022 +v -159.660522 -147.241669 31.610798 1.000000 1.000000 1.000000 +vn 0.411673 0.553617 0.723902 +v -160.985336 -147.084000 32.189400 1.000000 1.000000 1.000000 +vn 0.279854 0.041826 0.959131 +v -162.787811 -145.959351 32.691200 1.000000 1.000000 1.000000 +vn 0.599595 0.352817 0.718335 +v -162.602402 -145.783554 32.536598 1.000000 1.000000 1.000000 +vn 0.287372 -0.044441 0.956788 +v -163.564148 -144.674255 32.922398 1.000000 1.000000 1.000000 +vn 0.682156 0.136400 0.718372 +v -163.340134 -144.561218 32.767998 1.000000 1.000000 1.000000 +vn 0.241207 -0.143310 0.959834 +v -164.037949 -142.521255 33.257198 1.000000 1.000000 1.000000 +vn 0.867286 0.239779 0.436259 +v -163.126419 -144.452393 32.420197 1.000000 1.000000 1.000000 +vn 0.699785 -0.093437 0.708216 +v -163.792038 -142.512878 33.102600 1.000000 1.000000 1.000000 +vn 0.819777 0.405496 0.404399 +v -162.816132 -145.057968 32.305000 1.000000 1.000000 1.000000 +vn 0.941913 0.149288 0.300854 +v -163.490768 -143.199387 32.639000 1.000000 1.000000 1.000000 +vn 0.772451 0.635047 0.005843 +v -162.293411 -145.487732 31.364599 1.000000 1.000000 1.000000 +vn 0.862000 0.505841 0.032868 +v -162.668076 -144.953323 31.480799 1.000000 1.000000 1.000000 +vn 0.901033 -0.053872 0.430393 +v -163.556427 -142.505905 32.754997 1.000000 1.000000 1.000000 +vn 0.932911 -0.163729 0.320734 +v -163.529388 -141.813828 32.869999 1.000000 1.000000 1.000000 +vn 0.603346 -0.354859 0.714177 +v -163.430267 -140.372437 33.448601 1.000000 1.000000 1.000000 +vn 0.947528 0.319607 0.006435 +v -163.167618 -143.821701 31.698198 1.000000 1.000000 1.000000 +vn 0.877251 0.419107 -0.234050 +v -163.013107 -144.395187 31.141199 1.000000 1.000000 1.000000 +vn 0.756350 0.614252 -0.225010 +v -162.330750 -145.525406 30.909798 1.000000 1.000000 1.000000 +vn 0.665134 0.746665 0.009395 +v -161.850510 -145.960754 31.248198 1.000000 1.000000 1.000000 +vn 0.653314 0.607601 -0.451665 +v -162.436325 -145.624466 30.512398 1.000000 1.000000 1.000000 +vn 0.526124 0.727122 -0.441006 +v -161.974121 -146.118423 30.395798 1.000000 1.000000 1.000000 +vn 0.778975 0.429474 -0.456891 +v -163.139282 -144.459366 30.743599 1.000000 1.000000 1.000000 +vn 0.812120 0.188246 -0.552291 +v -163.504929 -143.202164 30.962399 1.000000 1.000000 1.000000 +vn 0.919637 0.092998 -0.381601 +v -163.569305 -142.505905 31.078398 1.000000 1.000000 1.000000 +vn 0.520210 0.452135 -0.724539 +v -163.025986 -145.207275 30.293798 1.000000 1.000000 1.000000 +vn 0.682108 0.287693 -0.672281 +v -163.574463 -143.964035 30.511198 1.000000 1.000000 1.000000 +vn 0.399210 0.639934 -0.656595 +v -162.128616 -146.313766 30.060999 1.000000 1.000000 1.000000 +vn 0.156560 0.228713 -0.960822 +v -163.552567 -144.668671 30.272999 1.000000 1.000000 1.000000 +vn 0.075922 0.261335 -0.962258 +v -162.778793 -145.950974 30.041798 1.000000 1.000000 1.000000 +vn 0.204436 0.162226 -0.965344 +v -164.026367 -142.521255 30.607798 1.000000 1.000000 1.000000 +vn 0.755265 0.013313 -0.655285 +v -163.779160 -141.783112 30.858797 1.000000 1.000000 1.000000 +vn -0.286060 0.144535 -0.947248 +v -164.259399 -142.528229 30.602598 1.000000 1.000000 1.000000 +vn -0.325621 0.020728 -0.945273 +v -163.763718 -144.776123 30.267998 1.000000 1.000000 1.000000 +vn -0.311220 -0.062717 -0.948266 +v -162.953888 -146.118423 30.036598 1.000000 1.000000 1.000000 +vn -0.039284 0.283961 -0.958031 +v -161.081894 -147.315628 29.694599 1.000000 1.000000 1.000000 +vn -0.269151 -0.177242 -0.946648 +v -161.178452 -147.545837 29.689398 1.000000 1.000000 1.000000 +vn -0.168114 0.194355 -0.966418 +v -159.024490 -147.803986 29.348398 1.000000 1.000000 1.000000 +vn -0.166051 -0.266825 -0.949332 +v -159.025787 -148.056549 29.343399 1.000000 1.000000 1.000000 +vn 0.178107 0.636424 -0.750495 +v -160.991760 -147.099335 29.830399 1.000000 1.000000 1.000000 +vn 0.010088 0.728315 -0.685168 +v -159.696564 -147.510971 29.599598 1.000000 1.000000 1.000000 +vn 0.336919 0.806185 -0.486366 +v -160.893921 -146.864929 30.165199 1.000000 1.000000 1.000000 +vn 0.181115 0.876997 -0.445055 +v -160.295242 -147.106323 30.050398 1.000000 1.000000 1.000000 +vn -0.076176 0.908869 -0.410067 +v -159.023209 -147.308640 29.819199 1.000000 1.000000 1.000000 +vn -0.295998 0.655283 -0.694975 +v -157.677795 -147.363052 29.251799 1.000000 1.000000 1.000000 +vn -0.241033 0.151704 -0.958587 +v -157.027603 -147.364456 29.013798 1.000000 1.000000 1.000000 +vn -0.188334 0.794059 -0.577929 +v -158.379471 -147.261200 29.703199 1.000000 1.000000 1.000000 +vn -0.450534 0.756750 -0.473654 +v -157.207870 -146.908188 29.484398 1.000000 1.000000 1.000000 +vn -0.471882 0.495937 -0.728953 +v -156.513916 -146.811905 29.034599 1.000000 1.000000 1.000000 +vn -0.277472 0.077360 -0.957614 +v -155.818665 -146.570511 28.782398 1.000000 1.000000 1.000000 +vn -0.635426 0.624913 -0.453561 +v -156.108353 -146.186783 29.252998 1.000000 1.000000 1.000000 +vn -0.662408 0.383348 -0.643630 +v -155.462036 -145.877029 28.801798 1.000000 1.000000 1.000000 +vn -0.443399 0.862939 -0.242350 +v -157.261932 -146.770035 29.881998 1.000000 1.000000 1.000000 +vn -0.647435 0.727712 -0.226414 +v -156.197189 -146.069580 29.650599 1.000000 1.000000 1.000000 +vn -0.536870 0.842994 0.033639 +v -156.735352 -146.415619 30.221598 1.000000 1.000000 1.000000 +vn -0.333399 0.942767 0.005974 +v -157.796234 -146.917953 30.438999 1.000000 1.000000 1.000000 +vn -0.751560 0.498512 -0.432022 +v -155.638428 -145.702606 29.136599 1.000000 1.000000 1.000000 +vn -0.776143 0.630476 0.010101 +v -155.778763 -145.564468 29.988998 1.000000 1.000000 1.000000 +vn -0.669614 0.742684 0.006200 +v -156.229370 -146.027725 30.105398 1.000000 1.000000 1.000000 +vn -0.889625 0.396949 -0.225828 +v -155.037170 -144.491470 29.303398 1.000000 1.000000 1.000000 +vn -0.823114 0.323526 -0.466706 +v -154.912277 -144.558441 28.905998 1.000000 1.000000 1.000000 +vn -0.902150 0.428747 0.047979 +v -155.082230 -144.466354 29.758198 1.000000 1.000000 1.000000 +vn -0.660803 0.180189 -0.728609 +v -154.698563 -144.672852 28.571199 1.000000 1.000000 1.000000 +vn -0.305715 -0.024251 -0.951814 +v -154.502869 -144.778900 28.435398 1.000000 1.000000 1.000000 +vn -0.141227 0.989936 -0.009043 +v -158.405228 -147.057480 30.555599 1.000000 1.000000 1.000000 +vn 0.133359 0.989698 0.052095 +v -159.634766 -147.051895 30.786598 1.000000 1.000000 1.000000 +vn 0.336146 0.866481 0.369075 +v -160.291382 -147.092361 31.726999 1.000000 1.000000 1.000000 +vn 0.459875 0.781354 0.421901 +v -160.887482 -146.852371 31.841799 1.000000 1.000000 1.000000 +vn 0.454683 0.889295 0.049178 +v -160.814087 -146.676559 31.017399 1.000000 1.000000 1.000000 +vn 0.296826 0.908787 -0.293257 +v -160.255325 -146.961197 30.447998 1.000000 1.000000 1.000000 +vn 0.418035 0.876607 -0.238343 +v -160.835983 -146.728180 30.562599 1.000000 1.000000 1.000000 +vn 0.609384 0.707104 0.358686 +v -161.450119 -146.520279 31.957199 1.000000 1.000000 1.000000 +vn 0.661626 0.672160 0.332342 +v -161.965103 -146.107254 32.072399 1.000000 1.000000 1.000000 +vn 0.751605 0.495927 0.434909 +v -162.426025 -145.614716 32.188999 1.000000 1.000000 1.000000 +vn -0.523625 0.725865 0.446024 +v -156.117371 -146.175629 30.929798 1.000000 1.000000 1.000000 +vn -0.701655 0.631153 0.330644 +v -155.647430 -145.692841 30.813198 1.000000 1.000000 1.000000 +vn -0.733970 0.579178 0.354740 +v -155.249603 -145.150055 30.697998 1.000000 1.000000 1.000000 +vn -0.802184 0.435236 0.408742 +v -154.923874 -144.551468 30.582598 1.000000 1.000000 1.000000 +vn -0.879750 0.322115 0.349689 +v -154.681824 -143.913788 30.467798 1.000000 1.000000 1.000000 +vn -0.988443 0.143404 0.049143 +v -154.697266 -143.202164 29.527399 1.000000 1.000000 1.000000 +vn -0.199410 0.240071 -0.950053 +v -163.862854 -140.178482 30.948599 1.000000 1.000000 1.000000 +vn -0.082615 0.286349 -0.954557 +v -162.606262 -138.206879 31.295799 1.000000 1.000000 1.000000 +vn 0.303473 0.043563 -0.951844 +v -163.646561 -140.276154 30.953798 1.000000 1.000000 1.000000 +vn 0.283159 -0.060091 -0.957189 +v -162.446625 -138.391068 31.300999 1.000000 1.000000 1.000000 +vn 0.005439 0.308151 -0.951322 +v -161.396042 -137.284561 31.527199 1.000000 1.000000 1.000000 +vn 0.506608 -0.464457 -0.726380 +v -161.769409 -138.098038 31.552998 1.000000 1.000000 1.000000 +vn 0.687771 -0.340000 -0.641383 +v -162.758194 -139.108261 31.320198 1.000000 1.000000 1.000000 +vn 0.251850 -0.136797 -0.958049 +v -161.290466 -137.509216 31.532198 1.000000 1.000000 1.000000 +vn 0.145710 0.276225 -0.949983 +v -159.341217 -136.672012 31.861799 1.000000 1.000000 1.000000 +vn 0.181897 -0.183411 -0.966061 +v -159.325775 -136.923172 31.866999 1.000000 1.000000 1.000000 +vn 0.255969 0.194837 -0.946847 +v -157.160233 -137.020844 32.207798 1.000000 1.000000 1.000000 +vn 0.059890 -0.281143 -0.957795 +v -157.242630 -137.258057 32.212997 1.000000 1.000000 1.000000 +vn 0.306107 0.082456 -0.948420 +v -155.299820 -138.314316 32.555000 1.000000 1.000000 1.000000 +vn 0.573601 0.377073 -0.727184 +v -155.126007 -138.124557 32.706001 1.000000 1.000000 1.000000 +vn 0.326996 0.000028 -0.945026 +v -154.407593 -139.592438 32.786400 1.000000 1.000000 1.000000 +vn 0.453595 0.420521 -0.785757 +v -155.718246 -137.573395 32.589600 1.000000 1.000000 1.000000 +vn 0.367035 0.564012 -0.739713 +v -157.073959 -136.771088 32.359001 1.000000 1.000000 1.000000 +vn 0.658285 0.206816 -0.723801 +v -154.191299 -139.464066 32.937401 1.000000 1.000000 1.000000 +vn 0.294977 -0.126002 -0.947160 +v -153.771576 -141.798462 33.120998 1.000000 1.000000 1.000000 +vn 0.632041 0.067682 -0.771973 +v -153.656982 -140.941742 33.156197 1.000000 1.000000 1.000000 +vn 0.839901 0.349835 -0.414948 +v -153.984009 -139.338501 33.281998 1.000000 1.000000 1.000000 +vn 0.753636 0.447337 -0.481584 +v -154.423035 -138.605942 33.166798 1.000000 1.000000 1.000000 +vn 0.688817 -0.055281 -0.722825 +v -153.525665 -141.773361 33.271999 1.000000 1.000000 1.000000 +vn 0.216845 -0.227074 -0.949429 +v -154.018768 -144.171921 33.466999 1.000000 1.000000 1.000000 +vn 0.878724 0.152996 -0.452146 +v -153.426529 -140.880341 33.500801 1.000000 1.000000 1.000000 +vn 0.922504 0.325415 -0.207587 +v -153.553986 -139.985931 33.777199 1.000000 1.000000 1.000000 +vn 0.826557 0.536561 -0.170016 +v -154.317474 -138.519440 33.559799 1.000000 1.000000 1.000000 +vn 0.691285 0.560526 -0.456000 +v -154.958633 -137.943161 33.050598 1.000000 1.000000 1.000000 +vn 0.735517 0.654475 -0.175151 +v -154.864655 -137.839905 33.443596 1.000000 1.000000 1.000000 +vn 0.798612 0.582410 0.151714 +v -154.307159 -138.511063 34.375397 1.000000 1.000000 1.000000 +vn 0.865830 0.472426 0.164778 +v -153.856552 -139.261749 34.490601 1.000000 1.000000 1.000000 +vn 0.708830 0.688489 0.153434 +v -154.855637 -137.830139 34.259201 1.000000 1.000000 1.000000 +vn 0.603090 0.782644 0.154113 +v -155.490372 -137.239914 34.142799 1.000000 1.000000 1.000000 +vn 0.635430 0.751823 -0.176041 +v -155.498093 -137.251068 33.327198 1.000000 1.000000 1.000000 +vn 0.605391 0.649949 -0.459421 +v -155.576614 -137.366882 32.934196 1.000000 1.000000 1.000000 +vn 0.500359 0.712713 -0.491611 +v -156.256409 -136.893875 32.818798 1.000000 1.000000 1.000000 +vn 0.521111 0.834903 -0.177144 +v -156.193329 -136.768280 33.211800 1.000000 1.000000 1.000000 +vn 0.484013 0.861064 0.155883 +v -156.186890 -136.755737 34.027397 1.000000 1.000000 1.000000 +vn 0.392113 0.902293 -0.179206 +v -156.943924 -136.395737 33.096596 1.000000 1.000000 1.000000 +vn 0.390826 0.793439 -0.466594 +v -156.991562 -136.529694 32.703400 1.000000 1.000000 1.000000 +vn 0.350832 0.923093 0.157532 +v -156.940063 -136.381775 33.911999 1.000000 1.000000 1.000000 +vn 0.252501 0.950454 -0.181330 +v -157.731873 -136.143173 32.981796 1.000000 1.000000 1.000000 +vn 0.382459 0.780435 0.494618 +v -156.260284 -136.899445 34.495598 1.000000 1.000000 1.000000 +vn 0.271003 0.841271 0.467782 +v -156.992859 -136.536667 34.380398 1.000000 1.000000 1.000000 +vn 0.207864 0.965300 0.158078 +v -157.729294 -136.129227 33.797398 1.000000 1.000000 1.000000 +vn 0.133198 0.856588 0.498513 +v -157.762772 -136.289688 34.265598 1.000000 1.000000 1.000000 +vn 0.145418 0.648320 0.747352 +v -157.076538 -136.776657 34.717999 1.000000 1.000000 1.000000 +vn 0.506058 0.728673 0.461456 +v -155.580490 -137.371063 34.611000 1.000000 1.000000 1.000000 +vn 0.294302 0.555207 0.777902 +v -155.722107 -137.577576 34.948799 1.000000 1.000000 1.000000 +vn 0.592314 0.640250 0.489125 +v -154.962494 -137.947342 34.727398 1.000000 1.000000 1.000000 +vn 0.486693 0.453196 0.746822 +v -154.617447 -138.765015 35.181396 1.000000 1.000000 1.000000 +vn 0.143601 0.327471 0.933885 +v -155.286942 -138.301758 35.205799 1.000000 1.000000 1.000000 +vn -0.027009 0.315630 0.948498 +v -157.155075 -137.004105 34.858597 1.000000 1.000000 1.000000 +vn -0.060880 0.623648 0.779331 +v -158.584183 -136.416656 34.487198 1.000000 1.000000 1.000000 +vn 0.007923 0.882796 0.469689 +v -158.566162 -136.161316 34.149399 1.000000 1.000000 1.000000 +vn -0.150065 0.832099 0.533940 +v -159.370834 -136.154343 34.034401 1.000000 1.000000 1.000000 +vn -0.329262 0.551039 0.766774 +v -160.877182 -136.755737 34.139599 1.000000 1.000000 1.000000 +vn -0.193185 0.404427 0.893934 +v -159.341217 -136.652466 34.512596 1.000000 1.000000 1.000000 +vn 0.060316 0.985486 0.158677 +v -158.554565 -135.996674 33.681198 1.000000 1.000000 1.000000 +vn 0.106602 0.977553 -0.181732 +v -158.555847 -136.010620 32.865601 1.000000 1.000000 1.000000 +vn -0.042609 0.982428 -0.181714 +v -159.379837 -136.005035 32.750599 1.000000 1.000000 1.000000 +vn -0.090002 0.983389 0.157627 +v -159.381134 -135.991089 33.565998 1.000000 1.000000 1.000000 +vn 0.268975 0.841031 -0.469382 +v -157.761490 -136.284103 32.588799 1.000000 1.000000 1.000000 +vn 0.141376 0.854475 -0.499886 +v -158.566162 -136.154343 32.472599 1.000000 1.000000 1.000000 +vn 0.005473 0.881600 -0.471965 +v -159.372116 -136.148758 32.357399 1.000000 1.000000 1.000000 +vn -0.192353 0.964432 -0.181302 +v -160.202545 -136.125046 32.634598 1.000000 1.000000 1.000000 +vn -0.241276 0.808040 0.537455 +v -160.174210 -136.272949 33.918396 1.000000 1.000000 1.000000 +vn -0.238612 0.958214 0.157765 +v -160.205109 -136.111084 33.450199 1.000000 1.000000 1.000000 +vn -0.143034 0.865534 -0.479993 +v -160.175507 -136.265961 32.241600 1.000000 1.000000 1.000000 +vn -0.340931 0.914187 -0.219154 +v -161.005936 -136.373413 32.517998 1.000000 1.000000 1.000000 +vn -0.376618 0.913190 0.155705 +v -161.009796 -136.360855 33.333599 1.000000 1.000000 1.000000 +vn 0.085695 0.659352 -0.746935 +v -159.356674 -136.405502 32.012798 1.000000 1.000000 1.000000 +vn -0.056129 0.610018 -0.790397 +v -160.126587 -136.518524 31.896999 1.000000 1.000000 1.000000 +vn -0.363667 0.823509 -0.435406 +v -161.616196 -136.818527 32.022797 1.000000 1.000000 1.000000 +vn -0.567304 0.804483 -0.175995 +v -162.383530 -137.150604 32.300598 1.000000 1.000000 1.000000 +vn -0.500923 0.848849 0.168912 +v -161.683151 -136.677597 33.231400 1.000000 1.000000 1.000000 +vn -0.398254 0.787428 0.470480 +v -160.958298 -136.514343 33.801796 1.000000 1.000000 1.000000 +vn -0.572363 0.674657 0.466089 +v -162.303711 -137.273392 33.584396 1.000000 1.000000 1.000000 +vn -0.476842 0.465529 0.745590 +v -162.167236 -137.484100 33.922199 1.000000 1.000000 1.000000 +vn -0.614579 0.773775 0.153509 +v -162.391251 -137.139450 33.116196 1.000000 1.000000 1.000000 +vn -0.668516 0.564118 0.484622 +v -162.933289 -137.830139 33.468201 1.000000 1.000000 1.000000 +vn -0.580048 0.283331 0.763720 +v -163.300217 -138.639435 33.689598 1.000000 1.000000 1.000000 +vn -0.284431 0.220078 0.933094 +v -161.405045 -137.267822 34.177998 1.000000 1.000000 1.000000 +vn -0.345555 0.140797 0.927776 +v -162.617859 -138.194321 33.946598 1.000000 1.000000 1.000000 +vn -0.719027 0.678185 0.151873 +v -163.037582 -137.710144 33.000000 1.000000 1.000000 1.000000 +vn -0.752273 0.480724 0.450545 +v -163.485626 -138.478973 33.351799 1.000000 1.000000 1.000000 +vn -0.799909 0.364142 0.477019 +v -163.943954 -139.198959 33.236397 1.000000 1.000000 1.000000 +vn -0.806859 0.571365 0.150072 +v -163.604065 -138.377106 32.883598 1.000000 1.000000 1.000000 +vn -0.877076 0.456746 0.148732 +v -164.074005 -139.115234 32.768196 1.000000 1.000000 1.000000 +vn -0.685630 0.706222 -0.176528 +v -163.028564 -137.721313 32.184399 1.000000 1.000000 1.000000 +vn -0.472036 0.729818 -0.494518 +v -162.307571 -137.269211 31.907598 1.000000 1.000000 1.000000 +vn -0.588449 0.664598 -0.460475 +v -162.937149 -137.825958 31.791401 1.000000 1.000000 1.000000 +vn -0.778001 0.603353 -0.175157 +v -163.593765 -138.385483 32.068001 1.000000 1.000000 1.000000 +vn -0.208289 0.635394 -0.743566 +v -161.509338 -137.047363 31.678198 1.000000 1.000000 1.000000 +vn -0.393809 0.550343 -0.736232 +v -162.774933 -138.012939 31.446798 1.000000 1.000000 1.000000 +vn -0.440914 0.431639 -0.786945 +v -163.304077 -138.636642 31.330399 1.000000 1.000000 1.000000 +vn -0.676886 0.576214 -0.458041 +v -163.489487 -138.476166 31.674999 1.000000 1.000000 1.000000 +vn -0.735877 0.474135 -0.483405 +v -163.947815 -139.196167 31.559599 1.000000 1.000000 1.000000 +vn -0.853190 0.491894 -0.173514 +v -164.062408 -139.122223 31.952599 1.000000 1.000000 1.000000 +vn -0.585862 0.353276 -0.729357 +v -164.090729 -140.076630 31.099798 1.000000 1.000000 1.000000 +vn -0.585144 0.224142 -0.779337 +v -164.334061 -140.867783 30.984999 1.000000 1.000000 1.000000 +vn -0.811428 0.373921 -0.449185 +v -164.309616 -139.978958 31.444199 1.000000 1.000000 1.000000 +vn -0.854921 0.263400 -0.446913 +v -164.563248 -140.803604 31.329599 1.000000 1.000000 1.000000 +vn -0.912013 0.372905 -0.170808 +v -164.431915 -139.923141 31.837399 1.000000 1.000000 1.000000 +vn -0.930583 0.334893 0.147855 +v -164.443497 -139.918961 32.652798 1.000000 1.000000 1.000000 +vn -0.684137 0.098795 -0.722631 +v -164.505310 -142.536606 30.753599 1.000000 1.000000 1.000000 +vn 0.230027 0.566336 -0.791423 +v -157.811691 -136.533875 32.244198 1.000000 1.000000 1.000000 +vn -0.275454 -0.058697 0.959521 +v -155.455597 -138.484558 35.209599 1.000000 1.000000 1.000000 +vn -0.290407 0.025678 0.956559 +v -154.600708 -139.709656 35.440796 1.000000 1.000000 1.000000 +vn 0.226420 0.269404 0.936032 +v -154.392136 -139.584076 35.437199 1.000000 1.000000 1.000000 +vn -0.249881 0.127673 0.959822 +v -153.991730 -141.822189 35.775578 1.000000 1.000000 1.000000 +vn 0.415580 0.189980 0.889494 +v -153.754837 -141.797073 35.771778 1.000000 1.000000 1.000000 +vn -0.171825 0.213026 0.961819 +v -154.229919 -144.096588 36.121578 1.000000 1.000000 1.000000 +vn 0.333272 0.039131 0.942018 +v -154.003311 -144.178909 36.117779 1.000000 1.000000 1.000000 +vn -0.072328 0.257755 0.963499 +v -155.311401 -146.069580 36.468781 1.000000 1.000000 1.000000 +vn -0.626730 0.314894 0.712777 +v -154.462952 -144.011459 35.966980 1.000000 1.000000 1.000000 +vn 0.354987 -0.118530 0.927327 +v -155.136307 -146.245392 36.464981 1.000000 1.000000 1.000000 +vn -0.446979 0.520560 0.727480 +v -155.491653 -145.888199 36.314178 1.000000 1.000000 1.000000 +vn 0.021093 0.271589 0.962182 +v -156.410904 -147.036545 36.700180 1.000000 1.000000 1.000000 +vn 0.299413 -0.200948 0.932723 +v -156.288605 -147.258408 36.696381 1.000000 1.000000 1.000000 +vn -0.223954 0.633502 0.740621 +v -156.538376 -146.807709 36.545578 1.000000 1.000000 1.000000 +vn 0.131472 0.234178 0.963263 +v -158.339554 -147.769104 37.034779 1.000000 1.000000 1.000000 +vn 0.190632 -0.304637 0.933197 +v -158.307373 -148.024445 37.030979 1.000000 1.000000 1.000000 +vn 0.220691 0.163226 0.961589 +v -160.443298 -147.589111 37.380779 1.000000 1.000000 1.000000 +vn 0.030081 0.677948 0.734494 +v -158.371750 -147.503983 36.880180 1.000000 1.000000 1.000000 +vn 0.327546 0.603287 0.727158 +v -160.373779 -147.332352 37.226181 1.000000 1.000000 1.000000 +vn 0.270684 0.076091 0.959656 +v -162.299850 -146.485397 37.727978 1.000000 1.000000 1.000000 +vn 0.544536 0.426559 0.722169 +v -162.138916 -146.283066 37.573380 1.000000 1.000000 1.000000 +vn 0.290870 -0.007670 0.956732 +v -163.230698 -145.325867 37.959381 1.000000 1.000000 1.000000 +vn 0.657614 0.221795 0.719966 +v -163.023422 -145.180756 37.804779 1.000000 1.000000 1.000000 +vn 0.258840 -0.111341 0.959481 +v -163.971008 -143.262161 38.293976 1.000000 1.000000 1.000000 +vn 0.705882 -0.004609 0.708314 +v -163.727661 -143.218918 38.139378 1.000000 1.000000 1.000000 +vn 0.828140 0.348711 0.438845 +v -162.825150 -145.041229 37.456978 1.000000 1.000000 1.000000 +vn 0.757812 0.508654 0.408647 +v -162.441467 -145.595169 37.341980 1.000000 1.000000 1.000000 +vn 0.186907 -0.201417 0.961508 +v -163.877014 -140.976624 38.639977 1.000000 1.000000 1.000000 +vn 0.946395 -0.044889 0.319876 +v -163.556427 -142.486359 37.906979 1.000000 1.000000 1.000000 +vn 0.646784 -0.273981 0.711762 +v -163.638824 -141.044983 38.485378 1.000000 1.000000 1.000000 +vn 0.900840 0.060363 0.429935 +v -163.494629 -143.175659 37.791779 1.000000 1.000000 1.000000 +vn 0.915076 0.266873 0.302349 +v -163.343994 -143.853790 37.675781 1.000000 1.000000 1.000000 +vn 0.960155 0.279339 -0.008523 +v -163.175339 -143.796585 36.851578 1.000000 1.000000 1.000000 +vn 0.997781 0.044694 0.049359 +v -163.378754 -142.480789 37.082581 1.000000 1.000000 1.000000 +vn 0.924581 -0.150656 0.349932 +v -163.526825 -141.787308 38.022980 1.000000 1.000000 1.000000 +vn 0.872811 -0.271913 0.405294 +v -163.409653 -141.109177 38.137779 1.000000 1.000000 1.000000 +vn 0.967749 -0.247529 0.046807 +v -163.238419 -141.158005 37.313377 1.000000 1.000000 1.000000 +vn 0.834924 -0.424366 0.350449 +v -163.204941 -140.451965 38.253178 1.000000 1.000000 1.000000 +vn 0.899981 0.208987 -0.382568 +v -163.508789 -143.178452 36.115181 1.000000 1.000000 1.000000 +vn 0.898390 0.439146 0.006825 +v -162.944870 -144.421692 36.734978 1.000000 1.000000 1.000000 +vn 0.908227 -0.017944 -0.418093 +v -163.540985 -141.785904 36.346581 1.000000 1.000000 1.000000 +vn 0.814502 0.529902 -0.236201 +v -162.719574 -144.967270 36.177979 1.000000 1.000000 1.000000 +vn 0.635331 0.372442 -0.676492 +v -163.329834 -144.624023 35.547997 1.000000 1.000000 1.000000 +vn 0.779664 0.290687 -0.554640 +v -163.356873 -143.857986 35.999176 1.000000 1.000000 1.000000 +vn 0.747383 0.108350 -0.655499 +v -163.807495 -142.493347 35.895576 1.000000 1.000000 1.000000 +vn 0.713432 0.527263 -0.461528 +v -162.836731 -145.049606 35.780380 1.000000 1.000000 1.000000 +vn 0.665470 0.710947 -0.227385 +v -161.902023 -145.987259 35.946579 1.000000 1.000000 1.000000 +vn 0.787344 0.615642 0.032769 +v -162.307571 -145.469589 36.517578 1.000000 1.000000 1.000000 +vn 0.450201 0.515673 -0.728972 +v -162.630737 -145.775162 35.330597 1.000000 1.000000 1.000000 +vn 0.562230 0.690099 -0.455697 +v -161.993423 -146.100281 35.549198 1.000000 1.000000 1.000000 +vn 0.416943 0.792733 -0.444671 +v -161.473282 -146.521683 35.432598 1.000000 1.000000 1.000000 +vn 0.678676 0.734421 0.004917 +v -161.868546 -145.944000 36.401379 1.000000 1.000000 1.000000 +vn 0.554581 0.832072 0.009777 +v -161.370285 -146.347260 36.284981 1.000000 1.000000 1.000000 +vn 0.676954 0.590400 0.439500 +v -161.984421 -146.089111 37.225777 1.000000 1.000000 1.000000 +vn 0.562580 0.754748 0.337430 +v -161.466858 -146.509109 37.109177 1.000000 1.000000 1.000000 +vn 0.503943 0.784125 0.362201 +v -160.905502 -146.842606 36.993980 1.000000 1.000000 1.000000 +vn 0.322282 0.945292 0.050562 +v -160.255325 -146.903992 36.054176 1.000000 1.000000 1.000000 +vn 0.341796 0.838303 0.424763 +v -160.305542 -147.088181 36.878578 1.000000 1.000000 1.000000 +vn 0.206912 0.904628 0.372606 +v -159.683685 -147.237488 36.763779 1.000000 1.000000 1.000000 +vn 0.087129 0.934543 0.345019 +v -159.041229 -147.293289 36.647778 1.000000 1.000000 1.000000 +vn -0.013877 0.998557 0.051869 +v -159.039948 -147.100739 35.823380 1.000000 1.000000 1.000000 +vn 0.160344 0.942114 -0.294468 +v -159.665665 -147.103531 35.484798 1.000000 1.000000 1.000000 +vn 0.288197 0.927148 -0.239456 +v -160.269501 -146.957016 35.599396 1.000000 1.000000 1.000000 +vn -0.285529 0.958328 -0.008955 +v -157.820709 -146.924927 35.592400 1.000000 1.000000 1.000000 +vn 0.049860 0.893504 -0.446278 +v -159.686264 -147.252823 35.087399 1.000000 1.000000 1.000000 +vn -0.037507 0.888023 0.458267 +v -158.402634 -147.250031 36.532578 1.000000 1.000000 1.000000 +vn -0.208474 0.888065 -0.409732 +v -158.401352 -147.265381 34.855999 1.000000 1.000000 1.000000 +vn -0.465400 0.885077 0.006412 +v -157.234894 -146.696091 35.475800 1.000000 1.000000 1.000000 +vn 0.215990 0.844647 -0.489816 +v -160.309402 -147.102142 35.201996 1.000000 1.000000 1.000000 +vn 0.082621 0.653916 -0.752042 +v -160.377640 -147.349106 34.867199 1.000000 1.000000 1.000000 +vn -0.097212 0.723120 -0.683847 +v -159.042526 -147.565384 34.636398 1.000000 1.000000 1.000000 +vn 0.301709 0.686229 -0.661862 +v -161.602036 -146.737946 35.098000 1.000000 1.000000 1.000000 +vn -0.080549 0.275635 -0.957882 +v -160.440720 -147.576538 34.731400 1.000000 1.000000 1.000000 +vn -0.195187 0.172312 -0.965511 +v -158.340851 -147.755142 34.385399 1.000000 1.000000 1.000000 +vn -0.388224 0.611234 -0.689692 +v -157.062378 -147.121674 34.288799 1.000000 1.000000 1.000000 +vn 0.036632 0.268788 -0.962502 +v -162.292130 -146.475632 35.078598 1.000000 1.000000 1.000000 +vn -0.327897 -0.021202 -0.944476 +v -163.416092 -145.457031 35.304798 1.000000 1.000000 1.000000 +vn 0.121368 0.246269 -0.961572 +v -163.220398 -145.318893 35.309799 1.000000 1.000000 1.000000 +vn -0.300062 -0.102231 -0.948426 +v -162.445328 -146.666794 35.073399 1.000000 1.000000 1.000000 +vn -0.304024 0.107493 -0.946581 +v -164.188583 -143.302643 35.639378 1.000000 1.000000 1.000000 +vn 0.178645 0.186584 -0.966060 +v -163.959412 -143.260773 35.644577 1.000000 1.000000 1.000000 +vn 0.293913 0.081766 -0.952329 +v -163.865433 -140.980804 35.990578 1.000000 1.000000 1.000000 +vn 0.684253 -0.052189 -0.727375 +v -163.652985 -141.040802 36.126381 1.000000 1.000000 1.000000 +vn 0.289156 -0.024014 -0.956981 +v -162.912689 -138.936630 36.337776 1.000000 1.000000 1.000000 +vn 0.728401 -0.249244 -0.638208 +v -163.131561 -139.692902 36.357178 1.000000 1.000000 1.000000 +vn 0.871726 -0.161230 -0.462708 +v -163.422531 -141.106384 36.461178 1.000000 1.000000 1.000000 +vn 0.955617 -0.107846 -0.274165 +v -163.401932 -141.804047 36.743980 1.000000 1.000000 1.000000 +vn 0.836672 -0.343170 -0.426865 +v -162.926849 -139.825470 36.691780 1.000000 1.000000 1.000000 +vn 0.949746 -0.218771 -0.223880 +v -163.288635 -141.144058 36.858578 1.000000 1.000000 1.000000 +vn 0.567629 -0.394565 -0.722576 +v -162.277954 -138.545944 36.589779 1.000000 1.000000 1.000000 +vn -0.039536 0.304519 -0.951685 +v -162.011444 -137.685028 36.563980 1.000000 1.000000 1.000000 +vn -0.122916 0.272563 -0.954254 +v -163.094223 -138.777573 36.332581 1.000000 1.000000 1.000000 +vn 0.269585 -0.103678 -0.957379 +v -161.878845 -137.892929 36.568977 1.000000 1.000000 1.000000 +vn 0.103444 0.292827 -0.950553 +v -160.051910 -136.773880 36.898579 1.000000 1.000000 1.000000 +vn 0.207170 -0.159193 -0.965266 +v -160.005554 -137.022232 36.903778 1.000000 1.000000 1.000000 +vn 0.224561 0.225782 -0.947942 +v -157.847733 -136.798981 37.244579 1.000000 1.000000 1.000000 +vn 0.100533 -0.270160 -0.957552 +v -157.899231 -137.045959 37.249779 1.000000 1.000000 1.000000 +vn 0.291806 0.121046 -0.948787 +v -155.841843 -137.805023 37.591778 1.000000 1.000000 1.000000 +vn 0.515609 0.448193 -0.730253 +v -155.693787 -137.591537 37.742779 1.000000 1.000000 1.000000 +vn 0.389536 0.477018 -0.787855 +v -156.350403 -137.132477 37.626381 1.000000 1.000000 1.000000 +vn 0.281573 0.607291 -0.742909 +v -157.793655 -136.538055 37.395779 1.000000 1.000000 1.000000 +vn 0.624026 0.289588 -0.725762 +v -154.600708 -138.780365 37.974178 1.000000 1.000000 1.000000 +vn 0.617180 0.146659 -0.773033 +v -153.884872 -140.165924 38.192978 1.000000 1.000000 1.000000 +vn 0.785291 0.455178 -0.419679 +v -154.410172 -138.626877 38.318779 1.000000 1.000000 1.000000 +vn 0.685840 0.542066 -0.485580 +v -154.938034 -137.965485 38.203579 1.000000 1.000000 1.000000 +vn 0.693557 0.040232 -0.719277 +v -153.650558 -140.969635 38.308979 1.000000 1.000000 1.000000 +vn 0.850976 0.262807 -0.454722 +v -153.663422 -140.071045 38.537579 1.000000 1.000000 1.000000 +vn 0.872317 0.442144 -0.208738 +v -153.901611 -139.203140 38.813980 1.000000 1.000000 1.000000 +vn 0.746824 0.642137 -0.172960 +v -154.842758 -137.863632 38.596581 1.000000 1.000000 1.000000 +vn 0.608278 0.647696 -0.458789 +v -155.550873 -137.386414 38.087379 1.000000 1.000000 1.000000 +vn 0.639591 0.748387 -0.175615 +v -155.471039 -137.272003 38.480579 1.000000 1.000000 1.000000 +vn 0.713003 0.684163 0.153453 +v -154.833755 -137.853851 39.412178 1.000000 1.000000 1.000000 +vn 0.795632 0.582591 0.166003 +v -154.294296 -138.531982 39.527378 1.000000 1.000000 1.000000 +vn 0.607067 0.779446 0.154706 +v -155.463318 -137.260849 39.295979 1.000000 1.000000 1.000000 +vn 0.486919 0.859292 0.156613 +v -156.166290 -136.768280 39.179581 1.000000 1.000000 1.000000 +vn 0.523872 0.832905 -0.178401 +v -156.171448 -136.780853 38.363979 1.000000 1.000000 1.000000 +vn 0.507627 0.726064 -0.463838 +v -156.235809 -136.907822 37.970978 1.000000 1.000000 1.000000 +vn 0.393516 0.774965 -0.494545 +v -156.968384 -136.539459 37.855579 1.000000 1.000000 1.000000 +vn 0.396207 0.900630 -0.178567 +v -156.922043 -136.405502 38.248581 1.000000 1.000000 1.000000 +vn 0.355008 0.921542 0.157256 +v -156.916885 -136.392944 39.064178 1.000000 1.000000 1.000000 +vn 0.257173 0.949492 -0.179796 +v -157.712555 -136.147369 38.133377 1.000000 1.000000 1.000000 +vn 0.272111 0.840377 -0.468746 +v -157.742157 -136.286911 37.740181 1.000000 1.000000 1.000000 +vn 0.213201 0.964177 0.157826 +v -157.709976 -136.133423 38.948776 1.000000 1.000000 1.000000 +vn 0.110592 0.977152 -0.181501 +v -158.524948 -136.013412 38.018578 1.000000 1.000000 1.000000 +vn 0.265814 0.826305 0.496551 +v -156.970963 -136.546432 39.532379 1.000000 1.000000 1.000000 +vn 0.145689 0.871330 0.468571 +v -157.743454 -136.293884 39.417179 1.000000 1.000000 1.000000 +vn 0.064231 0.985353 0.157965 +v -158.523666 -135.999466 38.834179 1.000000 1.000000 1.000000 +vn 0.005712 0.867054 0.498182 +v -158.536545 -136.162720 39.302376 1.000000 1.000000 1.000000 +vn -0.038084 0.982599 -0.181792 +v -159.356674 -136.003647 37.902378 1.000000 1.000000 1.000000 +vn 0.143145 0.870339 -0.471189 +v -158.535263 -136.157135 37.625580 1.000000 1.000000 1.000000 +vn 0.144284 0.591243 -0.793482 +v -158.554565 -136.412476 37.280979 1.000000 1.000000 1.000000 +vn 0.014170 0.865421 -0.500845 +v -159.348938 -136.147369 37.509377 1.000000 1.000000 1.000000 +vn -0.085295 0.983645 0.158642 +v -159.357956 -135.989685 38.717979 1.000000 1.000000 1.000000 +vn -0.186993 0.965495 -0.181254 +v -160.175507 -136.119461 37.787376 1.000000 1.000000 1.000000 +vn -0.122677 0.874848 0.468606 +v -159.348938 -136.154343 39.186180 1.000000 1.000000 1.000000 +vn -0.232917 0.959608 0.157806 +v -160.176804 -136.105499 38.602779 1.000000 1.000000 1.000000 +vn -0.270370 0.802128 0.532438 +v -160.147186 -136.267365 39.071178 1.000000 1.000000 1.000000 +vn -0.124539 0.872800 -0.471922 +v -160.148468 -136.260391 37.394180 1.000000 1.000000 1.000000 +vn -0.331292 0.926069 -0.180670 +v -160.975021 -136.360855 37.671379 1.000000 1.000000 1.000000 +vn -0.011990 0.664686 -0.747027 +v -160.100830 -136.512939 37.049778 1.000000 1.000000 1.000000 +vn -0.268422 0.836834 -0.477135 +v -160.929977 -136.496201 37.278378 1.000000 1.000000 1.000000 +vn -0.375408 0.913598 0.156227 +v -160.978882 -136.346909 38.486977 1.000000 1.000000 1.000000 +vn -0.468290 0.856288 -0.217890 +v -161.738510 -136.725037 37.554779 1.000000 1.000000 1.000000 +vn -0.503242 0.850197 0.154634 +v -161.744934 -136.712479 38.370377 1.000000 1.000000 1.000000 +vn -0.145546 0.597081 -0.788866 +v -160.850143 -136.737595 36.933777 1.000000 1.000000 1.000000 +vn -0.478124 0.764935 -0.431591 +v -162.288269 -137.255249 37.059578 1.000000 1.000000 1.000000 +vn -0.673329 0.718556 -0.174085 +v -163.006683 -137.697586 37.337379 1.000000 1.000000 1.000000 +vn -0.615082 0.770499 0.167351 +v -162.371948 -137.125504 38.268181 1.000000 1.000000 1.000000 +vn -0.506669 0.724601 0.467162 +v -161.674133 -136.857590 38.838577 1.000000 1.000000 1.000000 +vn -0.356158 0.765750 0.535517 +v -160.927399 -136.501785 38.955177 1.000000 1.000000 1.000000 +vn -0.660794 0.591268 0.462336 +v -162.912689 -137.807816 38.621178 1.000000 1.000000 1.000000 +vn -0.405916 0.501618 0.763945 +v -161.564697 -137.085037 39.176376 1.000000 1.000000 1.000000 +vn -0.537632 0.398383 0.743130 +v -162.750473 -137.996185 38.958977 1.000000 1.000000 1.000000 +vn -0.715457 0.681940 0.151917 +v -163.015686 -137.687820 38.152977 1.000000 1.000000 1.000000 +vn -0.739972 0.470691 0.480511 +v -163.466309 -138.452454 38.505180 1.000000 1.000000 1.000000 +vn -0.614121 0.206387 0.761748 +v -163.727661 -139.307800 38.726379 1.000000 1.000000 1.000000 +vn -0.313263 0.181137 0.932232 +v -162.021759 -137.669678 39.214779 1.000000 1.000000 1.000000 +vn -0.804233 0.574905 0.150642 +v -163.583466 -138.349197 38.036781 1.000000 1.000000 1.000000 +vn -0.810607 0.378527 0.446805 +v -163.931091 -139.176636 38.388580 1.000000 1.000000 1.000000 +vn -0.875319 0.459993 0.149076 +v -164.061127 -139.092911 37.920380 1.000000 1.000000 1.000000 +vn -0.152510 0.609218 0.778200 +v -159.334778 -136.409683 39.523979 1.000000 1.000000 1.000000 +vn -0.250455 0.374304 0.892843 +v -160.055771 -136.755737 39.549377 1.000000 1.000000 1.000000 +vn 0.049227 0.661820 0.748045 +v -157.794952 -136.543640 39.754780 1.000000 1.000000 1.000000 +vn 0.211173 0.590018 0.779285 +v -156.352982 -137.138046 39.985580 1.000000 1.000000 1.000000 +vn -0.073437 0.309344 0.948110 +v -157.843872 -136.780853 39.895378 1.000000 1.000000 1.000000 +vn 0.397103 0.791263 0.464987 +v -156.238388 -136.913406 39.647778 1.000000 1.000000 1.000000 +vn 0.496450 0.715134 0.492058 +v -155.554733 -137.392014 39.764378 1.000000 1.000000 1.000000 +vn 0.618853 0.633658 0.464218 +v -154.941895 -137.969666 39.880379 1.000000 1.000000 1.000000 +vn 0.417919 0.513052 0.749748 +v -155.109268 -138.151062 40.218178 1.000000 1.000000 1.000000 +vn 0.747263 0.481730 0.457749 +v -154.022629 -139.277100 40.097778 1.000000 1.000000 1.000000 +vn 0.519232 0.390243 0.760334 +v -154.228638 -139.405472 40.435577 1.000000 1.000000 1.000000 +vn 0.186145 0.296151 0.936827 +v -154.783539 -138.929657 40.473976 1.000000 1.000000 1.000000 +vn 0.093891 0.342776 0.934713 +v -155.831543 -137.791061 40.242577 1.000000 1.000000 1.000000 +vn 0.641779 0.243662 0.727151 +v -153.655701 -140.971039 40.667976 1.000000 1.000000 1.000000 +vn 0.801056 0.359203 0.478834 +v -153.669861 -140.073837 40.214378 1.000000 1.000000 1.000000 +vn 0.261679 0.196236 0.944995 +v -153.873291 -141.028244 40.808578 1.000000 1.000000 1.000000 +vn 0.685891 0.069492 0.724379 +v -153.511505 -142.641251 40.899380 1.000000 1.000000 1.000000 +vn 0.870005 0.136791 0.473688 +v -153.293930 -141.773361 40.445377 1.000000 1.000000 1.000000 +vn 0.860241 0.249905 0.444447 +v -153.425247 -140.911041 40.330379 1.000000 1.000000 1.000000 +vn 0.961464 0.232122 0.147331 +v -153.278473 -140.873367 39.861977 1.000000 1.000000 1.000000 +vn 0.921864 0.357574 0.149361 +v -153.528244 -140.013840 39.746178 1.000000 1.000000 1.000000 +vn 0.983599 0.104346 0.147122 +v -153.143280 -141.756607 39.977180 1.000000 1.000000 1.000000 +vn 0.896770 0.018862 0.442096 +v -153.274612 -142.653809 40.561577 1.000000 1.000000 1.000000 +vn 0.988926 -0.023580 0.146524 +v -153.123978 -142.660782 40.093376 1.000000 1.000000 1.000000 +vn 0.983540 -0.063955 -0.168996 +v -153.136841 -142.660782 39.277779 1.000000 1.000000 1.000000 +vn 0.966906 0.191125 -0.169009 +v -153.291351 -140.876144 39.046577 1.000000 1.000000 1.000000 +vn 0.983474 0.063972 -0.169373 +v -153.156158 -141.758011 39.161579 1.000000 1.000000 1.000000 +vn 0.977318 -0.152139 0.147317 +v -153.219254 -143.546814 40.207977 1.000000 1.000000 1.000000 +vn 0.876420 -0.090796 0.472910 +v -153.368591 -143.516129 40.676376 1.000000 1.000000 1.000000 +vn 0.966863 -0.191236 -0.169132 +v -153.232117 -143.544037 39.392578 1.000000 1.000000 1.000000 +vn 0.870698 -0.213094 0.443256 +v -153.573303 -144.361694 40.791779 1.000000 1.000000 1.000000 +vn 0.310035 0.121885 0.942880 +v -153.735519 -142.630096 41.039978 1.000000 1.000000 1.000000 +vn 0.335075 0.035880 0.941508 +v -154.009766 -144.199844 41.269978 1.000000 1.000000 1.000000 +vn 0.879985 0.014587 -0.474778 +v -153.288773 -141.771957 38.768578 1.000000 1.000000 1.000000 +vn 0.885455 0.135721 -0.444466 +v -153.420090 -140.909637 38.653378 1.000000 1.000000 1.000000 +vn 0.932994 0.317450 -0.169555 +v -153.539825 -140.019409 38.930580 1.000000 1.000000 1.000000 +vn 0.890430 -0.095841 -0.444915 +v -153.269455 -142.653809 38.884781 1.000000 1.000000 1.000000 +vn 0.853555 -0.211749 -0.476031 +v -153.362152 -143.517517 38.999378 1.000000 1.000000 1.000000 +vn 0.671619 -0.136134 -0.728282 +v -153.506363 -142.641251 38.540176 1.000000 1.000000 1.000000 +vn 0.866920 0.475348 0.149981 +v -153.891312 -139.196167 39.629578 1.000000 1.000000 1.000000 +vn -0.775564 0.606579 -0.174822 +v -163.574463 -138.357574 37.221378 1.000000 1.000000 1.000000 +vn -0.570293 0.658295 -0.491339 +v -162.916550 -137.803635 36.944378 1.000000 1.000000 1.000000 +vn -0.674917 0.579016 -0.457414 +v -163.470169 -138.448273 36.828178 1.000000 1.000000 1.000000 +vn -0.851796 0.494649 -0.172526 +v -164.049530 -139.099899 37.104778 1.000000 1.000000 1.000000 +vn -0.298263 0.600701 -0.741753 +v -162.153076 -137.465958 36.714981 1.000000 1.000000 1.000000 +vn -0.468122 0.492892 -0.733430 +v -163.286057 -138.610123 36.483578 1.000000 1.000000 1.000000 +vn -0.496908 0.369978 -0.784983 +v -163.731522 -139.305008 36.367180 1.000000 1.000000 1.000000 +vn -0.749814 0.481877 -0.453401 +v -163.936234 -139.173843 36.711777 1.000000 1.000000 1.000000 +vn -0.793464 0.374182 -0.480003 +v -164.299301 -139.955231 36.596378 1.000000 1.000000 1.000000 +vn -0.910386 0.376526 -0.171537 +v -164.421616 -139.899414 36.989380 1.000000 1.000000 1.000000 +vn -0.628893 0.274696 -0.727348 +v -164.328918 -140.848251 36.136578 1.000000 1.000000 1.000000 +vn -0.231823 0.212550 -0.949252 +v -164.090729 -140.916611 35.985378 1.000000 1.000000 1.000000 +vn -0.610783 0.148353 -0.777776 +v -164.470551 -141.668701 36.021778 1.000000 1.000000 1.000000 +vn -0.853890 0.266691 -0.446931 +v -164.559387 -140.784058 36.480980 1.000000 1.000000 1.000000 +vn -0.691069 0.011892 -0.722691 +v -164.431915 -143.347290 35.790379 1.000000 1.000000 1.000000 +vn -0.928801 0.339617 0.148283 +v -164.434494 -139.893845 37.804977 1.000000 1.000000 1.000000 +vn 0.885675 -0.464213 0.009270 +v -162.763336 -139.930115 37.544178 1.000000 1.000000 1.000000 +vn -0.240898 -0.211395 -0.947249 +v -160.506393 -147.819336 34.726196 1.000000 1.000000 1.000000 +vn -0.301266 0.759955 -0.575941 +v -157.769211 -147.124466 34.739998 1.000000 1.000000 1.000000 +vn -0.553351 0.687669 -0.470015 +v -156.652969 -146.601212 34.521198 1.000000 1.000000 1.000000 +vn -0.538086 0.430111 -0.724891 +v -155.977036 -146.403076 34.071396 1.000000 1.000000 1.000000 +vn -0.261316 0.120630 -0.957686 +v -156.417343 -147.025391 34.050598 1.000000 1.000000 1.000000 +vn -0.561247 0.791560 -0.241733 +v -156.723770 -146.471436 34.918800 1.000000 1.000000 1.000000 +vn -0.741088 0.633062 -0.223653 +v -155.756866 -145.621674 34.687401 1.000000 1.000000 1.000000 +vn -0.715873 0.535216 -0.448408 +v -155.655167 -145.723541 34.290001 1.000000 1.000000 1.000000 +vn -0.649087 0.759988 0.033232 +v -156.247406 -146.043076 35.258400 1.000000 1.000000 1.000000 +vn -0.272071 0.906408 0.323113 +v -157.773071 -147.110504 36.416580 1.000000 1.000000 1.000000 +vn -0.764411 0.644702 0.005953 +v -155.794205 -145.584000 35.142197 1.000000 1.000000 1.000000 +vn -0.366221 0.810039 0.457950 +v -156.659393 -146.588654 36.197777 1.000000 1.000000 1.000000 +vn -0.853235 0.521437 0.009721 +v -155.405396 -145.057968 35.025799 1.000000 1.000000 1.000000 +vn -0.811997 0.397144 -0.427712 +v -155.249603 -145.175171 34.173401 1.000000 1.000000 1.000000 +vn -0.708702 0.294618 -0.641048 +v -155.053909 -145.321686 33.838799 1.000000 1.000000 1.000000 +vn -0.933750 0.278883 -0.224354 +v -154.805420 -143.885895 34.340199 1.000000 1.000000 1.000000 +vn -0.859134 0.215796 -0.464027 +v -154.674103 -143.934723 33.942799 1.000000 1.000000 1.000000 +vn -0.949967 0.308795 0.046988 +v -154.854340 -143.869141 34.794998 1.000000 1.000000 1.000000 +vn -0.286287 0.041702 -0.957236 +v -155.319122 -146.061218 33.819397 1.000000 1.000000 1.000000 +vn -0.299180 -0.062713 -0.952134 +v -154.240219 -144.092392 33.472198 1.000000 1.000000 1.000000 +vn -0.536244 0.733437 0.417746 +v -156.135391 -146.192383 36.082779 1.000000 1.000000 1.000000 +vn -0.620965 0.647293 0.442057 +v -155.664169 -145.713776 35.966576 1.000000 1.000000 1.000000 +vn -0.780538 0.532169 0.327959 +v -155.259903 -145.166809 35.849979 1.000000 1.000000 1.000000 +vn -0.805423 0.477317 0.351371 +v -154.932877 -144.569595 35.734779 1.000000 1.000000 1.000000 +vn -0.853283 0.327136 0.406066 +v -154.686981 -143.929138 35.619377 1.000000 1.000000 1.000000 +vn 0.571433 0.315786 0.757459 +v -153.901611 -140.136627 35.398796 1.000000 1.000000 1.000000 +vn 0.805655 0.380586 0.453954 +v -153.682739 -140.041733 35.060997 1.000000 1.000000 1.000000 +vn 0.700269 0.545222 0.460821 +v -154.428192 -138.610123 34.843597 1.000000 1.000000 1.000000 +vn 0.645747 0.075100 0.759849 +v -153.510223 -142.610550 35.746376 1.000000 1.000000 1.000000 +vn 0.844160 0.159371 0.511854 +v -153.296494 -141.748230 35.293598 1.000000 1.000000 1.000000 +vn 0.822768 0.237397 0.516426 +v -153.431671 -140.883133 35.177597 1.000000 1.000000 1.000000 +vn 0.681633 -0.108380 0.723623 +v -153.790878 -144.255661 35.977180 1.000000 1.000000 1.000000 +vn 0.876852 -0.087263 0.472775 +v -153.366028 -143.495193 35.524799 1.000000 1.000000 1.000000 +vn 0.896738 0.022016 0.442015 +v -153.274612 -142.620316 35.408600 1.000000 1.000000 1.000000 +vn 0.988824 -0.020509 0.147669 +v -153.122681 -142.627304 34.940399 1.000000 1.000000 1.000000 +vn 0.983065 0.108096 0.147980 +v -153.144562 -141.732895 34.825199 1.000000 1.000000 1.000000 +vn 0.960173 0.237184 0.147684 +v -153.284912 -140.844070 34.709396 1.000000 1.000000 1.000000 +vn 0.965750 0.196672 -0.169252 +v -153.297775 -140.846848 33.893799 1.000000 1.000000 1.000000 +vn 0.983219 0.067995 -0.169285 +v -153.157440 -141.732895 34.009796 1.000000 1.000000 1.000000 +vn 0.921586 0.358310 0.149308 +v -153.541122 -139.980347 34.592796 1.000000 1.000000 1.000000 +vn 0.895539 0.023497 -0.444362 +v -153.290054 -141.748230 33.616600 1.000000 1.000000 1.000000 +vn 0.983749 -0.060996 -0.168869 +v -153.135559 -142.627304 34.124798 1.000000 1.000000 1.000000 +vn 0.874865 -0.096350 -0.474687 +v -153.268173 -142.621704 33.731796 1.000000 1.000000 1.000000 +vn 0.870478 -0.208387 -0.445917 +v -153.359573 -143.496597 33.848000 1.000000 1.000000 1.000000 +vn 0.599422 -0.186880 -0.778312 +v -153.592606 -143.450546 33.503399 1.000000 1.000000 1.000000 +vn 0.967571 -0.187628 -0.169120 +v -153.229538 -143.523102 34.240997 1.000000 1.000000 1.000000 +vn 0.834528 -0.320663 -0.448038 +v -153.560425 -144.339371 33.962601 1.000000 1.000000 1.000000 +vn 0.608781 -0.314564 -0.728310 +v -153.785736 -144.257050 33.618198 1.000000 1.000000 1.000000 +vn 0.934274 -0.313528 -0.169803 +v -153.435547 -144.385406 34.355797 1.000000 1.000000 1.000000 +vn 0.977911 -0.148054 0.147548 +v -153.216660 -143.525894 35.056599 1.000000 1.000000 1.000000 +vn 0.949825 -0.275520 0.148058 +v -153.422668 -144.389603 35.171196 1.000000 1.000000 1.000000 +vn 0.871303 -0.209628 0.443720 +v -153.566864 -144.336578 35.639580 1.000000 1.000000 1.000000 +vn 0.822689 -0.311914 0.475281 +v -153.877151 -145.144485 35.754776 1.000000 1.000000 1.000000 +vn 0.905120 -0.398441 0.148335 +v -153.741959 -145.217026 35.286598 1.000000 1.000000 1.000000 +vn 0.598715 -0.245309 0.762472 +v -154.483551 -145.750061 36.207977 1.000000 1.000000 1.000000 +vn 0.884076 -0.434753 -0.171460 +v -153.753540 -145.211456 34.471001 1.000000 1.000000 1.000000 +vn 0.671678 -0.137987 -0.727879 +v -163.444412 -140.366852 31.089598 1.000000 1.000000 1.000000 +vn 0.843070 -0.270009 -0.465111 +v -163.224258 -140.465927 31.424398 1.000000 1.000000 1.000000 +vn 0.783837 -0.448290 -0.429693 +v -162.572800 -139.270111 31.654999 1.000000 1.000000 1.000000 +vn 0.898544 -0.131759 -0.418639 +v -163.426392 -141.121735 31.309599 1.000000 1.000000 1.000000 +vn 0.987952 0.154581 -0.007513 +v -163.316956 -143.167297 31.814798 1.000000 1.000000 1.000000 +vn 0.934361 -0.228015 -0.273822 +v -163.291214 -141.159409 31.707199 1.000000 1.000000 1.000000 +vn 0.995519 -0.080423 0.049746 +v -163.354294 -141.834747 32.045799 1.000000 1.000000 1.000000 +vn 0.913726 -0.338686 -0.224490 +v -163.095520 -140.523132 31.821798 1.000000 1.000000 1.000000 +vn 0.927798 -0.369905 0.048597 +v -163.049164 -140.544067 32.276596 1.000000 1.000000 1.000000 +vn 0.898913 -0.265066 0.348849 +v -163.413528 -141.125916 32.986198 1.000000 1.000000 1.000000 +vn 0.829693 -0.382312 0.406752 +v -163.212662 -140.470108 33.100998 1.000000 1.000000 1.000000 +vn 0.609616 0.239915 0.755519 +v -153.669861 -140.911041 30.361998 1.000000 1.000000 1.000000 +vn 0.849573 0.273520 0.451013 +v -153.440689 -140.848251 30.024199 1.000000 1.000000 1.000000 +vn 0.767586 0.448530 0.457856 +v -153.999451 -139.320358 29.806799 1.000000 1.000000 1.000000 +vn 0.650047 -0.006428 0.759867 +v -153.593903 -143.418457 30.709599 1.000000 1.000000 1.000000 +vn 0.858713 0.051931 0.509819 +v -153.272034 -142.596603 30.256798 1.000000 1.000000 1.000000 +vn 0.847731 0.131479 0.513874 +v -153.299072 -141.718933 30.140799 1.000000 1.000000 1.000000 +vn 0.660191 -0.193739 0.725682 +v -154.078003 -145.007736 30.940399 1.000000 1.000000 1.000000 +vn 0.858455 -0.197003 0.473545 +v -153.560425 -144.317047 30.487997 1.000000 1.000000 1.000000 +vn 0.892030 -0.091322 0.442655 +v -153.360870 -143.464493 30.371798 1.000000 1.000000 1.000000 +vn 0.978395 -0.145070 0.147305 +v -153.211517 -143.493790 29.903599 1.000000 1.000000 1.000000 +vn 0.989064 -0.016249 0.146590 +v -153.121399 -142.602173 29.788399 1.000000 1.000000 1.000000 +vn 0.982466 0.113463 0.147944 +v -153.148438 -141.702194 29.672598 1.000000 1.000000 1.000000 +vn 0.983974 -0.057213 -0.168883 +v -153.134277 -142.602173 28.972799 1.000000 1.000000 1.000000 +vn 0.951214 -0.270991 0.147502 +v -153.417526 -144.368683 30.019798 1.000000 1.000000 1.000000 +vn 0.935644 -0.309239 -0.170120 +v -153.429108 -144.364487 29.204199 1.000000 1.000000 1.000000 +vn 0.968213 -0.184153 -0.169268 +v -153.224396 -143.491013 29.087999 1.000000 1.000000 1.000000 +vn 0.982993 0.072446 -0.168752 +v -153.160019 -141.703583 28.856998 1.000000 1.000000 1.000000 +vn 0.960158 0.237001 0.148079 +v -153.293930 -140.809174 29.555798 1.000000 1.000000 1.000000 +vn 0.891221 -0.089744 -0.444602 +v -153.266876 -142.596603 28.579798 1.000000 1.000000 1.000000 +vn 0.855097 -0.205540 -0.475986 +v -153.354431 -143.464493 28.694998 1.000000 1.000000 1.000000 +vn 0.835360 -0.317497 -0.448742 +v -153.555283 -144.319839 28.810999 1.000000 1.000000 1.000000 +vn 0.567697 -0.260820 -0.780828 +v -153.780594 -144.238907 28.466599 1.000000 1.000000 1.000000 +vn 0.836316 -0.319257 0.445702 +v -153.865570 -145.120758 30.602798 1.000000 1.000000 1.000000 +vn 0.906571 -0.395174 0.148215 +v -153.730377 -145.194702 30.134399 1.000000 1.000000 1.000000 +vn 0.885748 -0.431293 -0.171572 +v -153.741959 -145.187729 29.318798 1.000000 1.000000 1.000000 +vn 0.113145 0.248828 -0.961916 +v -163.195938 -145.360764 25.004799 1.000000 1.000000 1.000000 +vn -0.317888 -0.023146 -0.947846 +v -163.390335 -145.500290 24.999798 1.000000 1.000000 1.000000 +vn 0.715373 0.198219 -0.670037 +v -163.734100 -143.274734 25.474199 1.000000 1.000000 1.000000 +vn 0.578224 0.380248 -0.721851 +v -163.346573 -144.587738 25.256798 1.000000 1.000000 1.000000 +vn 0.486318 0.580144 -0.653397 +v -162.597260 -145.815628 25.024199 1.000000 1.000000 1.000000 +vn 0.002714 0.286375 -0.958114 +v -161.685715 -146.962601 24.657799 1.000000 1.000000 1.000000 +vn -0.292977 -0.141648 -0.945569 +v -161.810608 -147.177475 24.652599 1.000000 1.000000 1.000000 +vn -0.138018 0.213642 -0.967113 +v -159.709427 -147.749573 24.311598 1.000000 1.000000 1.000000 +vn -0.203748 -0.242080 -0.948622 +v -159.741623 -147.999329 24.306599 1.000000 1.000000 1.000000 +vn -0.216642 0.181357 -0.959258 +v -157.675217 -147.608643 23.976999 1.000000 1.000000 1.000000 +vn -0.396786 0.554372 -0.731596 +v -157.095840 -147.138412 23.997599 1.000000 1.000000 1.000000 +vn -0.264441 0.112520 -0.957815 +v -156.377441 -147.000275 23.745598 1.000000 1.000000 1.000000 +vn -0.197298 0.690350 -0.696053 +v -158.320251 -147.512360 24.214998 1.000000 1.000000 1.000000 +vn -0.337197 0.811491 -0.477264 +v -157.796234 -147.131439 24.447599 1.000000 1.000000 1.000000 +vn -0.603446 0.466479 -0.646722 +v -155.937119 -146.366791 23.764999 1.000000 1.000000 1.000000 +vn -0.541706 0.705051 -0.457666 +v -156.616913 -146.578888 24.216198 1.000000 1.000000 1.000000 +vn -0.772953 0.426428 -0.469790 +v -155.226425 -145.141678 23.869198 1.000000 1.000000 1.000000 +vn -0.676738 0.593706 -0.435360 +v -156.089035 -146.168655 24.099798 1.000000 1.000000 1.000000 +vn -0.539330 0.810347 -0.229044 +v -156.689011 -146.449112 24.613798 1.000000 1.000000 1.000000 +vn -0.829628 0.509222 -0.228935 +v -155.342300 -145.056580 24.266598 1.000000 1.000000 1.000000 +vn -0.683788 0.729614 0.009863 +v -156.211349 -146.009583 24.951998 1.000000 1.000000 1.000000 +vn -0.872810 0.402127 -0.276579 +v -155.030731 -144.477509 24.151999 1.000000 1.000000 1.000000 +vn -0.837961 0.543588 0.048301 +v -155.384796 -145.025864 24.721399 1.000000 1.000000 1.000000 +vn -0.559987 0.828479 0.006117 +v -156.716049 -146.403076 25.068598 1.000000 1.000000 1.000000 +vn -0.410712 0.911141 0.033723 +v -157.267090 -146.712845 25.184799 1.000000 1.000000 1.000000 +vn -0.306838 0.851925 0.424351 +v -157.196274 -146.888657 26.008999 1.000000 1.000000 1.000000 +vn -0.116498 0.878868 0.462623 +v -157.800110 -147.117477 26.124199 1.000000 1.000000 1.000000 +vn 0.002353 0.945421 0.325842 +v -159.001328 -147.293289 26.342999 1.000000 1.000000 1.000000 +vn -0.192294 0.981321 0.005655 +v -158.380753 -147.053299 25.402199 1.000000 1.000000 1.000000 +vn -0.313996 0.917262 -0.245022 +v -157.833588 -146.986328 24.845198 1.000000 1.000000 1.000000 +vn 0.226141 0.643297 0.731457 +v -159.675964 -147.498413 26.806599 1.000000 1.000000 1.000000 +vn -0.031331 0.668234 0.743291 +v -157.737015 -147.364456 26.471798 1.000000 1.000000 1.000000 +vn 0.222301 0.861611 0.456300 +v -159.642487 -147.244461 26.458799 1.000000 1.000000 1.000000 +vn 0.058464 0.910455 -0.409455 +v -159.645065 -147.259811 24.782398 1.000000 1.000000 1.000000 +vn 0.005503 0.999942 -0.009251 +v -159.001328 -147.102142 25.518599 1.000000 1.000000 1.000000 +vn 0.353485 0.870857 0.341551 +v -160.268204 -147.099335 26.573999 1.000000 1.000000 1.000000 +vn 0.307812 0.842385 -0.442311 +v -160.879761 -146.871902 25.013599 1.000000 1.000000 1.000000 +vn 0.276843 0.959526 0.051645 +v -160.219284 -146.915161 25.749798 1.000000 1.000000 1.000000 +vn 0.458086 0.809282 0.367722 +v -160.873322 -146.857956 26.690199 1.000000 1.000000 1.000000 +vn 0.486615 0.494227 0.720379 +v -161.560837 -146.747711 27.152599 1.000000 1.000000 1.000000 +vn 0.425484 0.856880 -0.291067 +v -160.821823 -146.733765 25.411198 1.000000 1.000000 1.000000 +vn 0.576128 0.815880 0.049162 +v -161.340683 -146.369583 25.980598 1.000000 1.000000 1.000000 +vn 0.565030 0.711034 0.418535 +v -161.434662 -146.531433 26.804998 1.000000 1.000000 1.000000 +vn 0.701420 0.617811 0.355416 +v -161.950943 -146.121216 26.920198 1.000000 1.000000 1.000000 +vn 0.643287 0.273055 0.715278 +v -163.000229 -145.221222 27.499798 1.000000 1.000000 1.000000 +vn 0.539365 0.808547 -0.235240 +v -161.367706 -146.417023 25.525799 1.000000 1.000000 1.000000 +vn 0.760820 0.648892 0.009671 +v -162.276672 -145.507263 26.211199 1.000000 1.000000 1.000000 +vn 0.747248 0.575837 0.331712 +v -162.407990 -145.635635 27.035599 1.000000 1.000000 1.000000 +vn 0.449937 0.751026 -0.483236 +v -161.442383 -146.544006 25.128399 1.000000 1.000000 1.000000 +vn 0.622481 0.648551 -0.438063 +v -162.418304 -145.643997 25.358999 1.000000 1.000000 1.000000 +vn 0.269423 0.606344 -0.748170 +v -161.568558 -146.761673 24.793598 1.000000 1.000000 1.000000 +vn 0.117229 0.719882 -0.684125 +v -160.337738 -147.360275 24.562599 1.000000 1.000000 1.000000 +vn 0.730247 0.515563 -0.448256 +v -162.814835 -145.087280 25.475401 1.000000 1.000000 1.000000 +vn 0.831618 0.508852 -0.222443 +v -162.697678 -145.004944 25.872999 1.000000 1.000000 1.000000 +vn 0.829612 0.325231 -0.453837 +v -163.364594 -143.828690 25.706799 1.000000 1.000000 1.000000 +vn 0.830250 0.083483 -0.551104 +v -163.569305 -142.529633 25.925598 1.000000 1.000000 1.000000 +vn 0.924343 0.302581 -0.232454 +v -163.231979 -143.784027 26.104399 1.000000 1.000000 1.000000 +vn 0.920405 0.389581 0.032879 +v -162.960327 -144.388214 26.443998 1.000000 1.000000 1.000000 +vn 0.849966 0.526803 0.005974 +v -162.655197 -144.974243 26.327799 1.000000 1.000000 1.000000 +vn 0.923641 -0.023568 -0.382535 +v -163.544846 -141.830566 26.041599 1.000000 1.000000 1.000000 +vn 0.980580 0.195997 0.006961 +v -163.311813 -143.193802 26.661398 1.000000 1.000000 1.000000 +vn 0.751119 -0.081880 -0.655069 +v -163.663300 -141.084061 25.821798 1.000000 1.000000 1.000000 +vn 0.873672 -0.243538 -0.421173 +v -163.229401 -140.481277 26.272799 1.000000 1.000000 1.000000 +vn 0.999517 0.030105 -0.007671 +v -163.378754 -142.522644 26.777798 1.000000 1.000000 1.000000 +vn 0.646280 -0.221430 -0.730267 +v -163.153442 -139.729187 26.052799 1.000000 1.000000 1.000000 +vn 0.800384 -0.375164 -0.467587 +v -162.947449 -139.860352 26.387598 1.000000 1.000000 1.000000 +vn 0.897438 -0.344670 -0.275333 +v -163.100662 -140.538483 26.670399 1.000000 1.000000 1.000000 +vn 0.977275 -0.206030 0.049857 +v -163.247437 -141.197083 27.008999 1.000000 1.000000 1.000000 +vn 0.634422 -0.426087 -0.644949 +v -162.315292 -138.585007 26.283398 1.000000 1.000000 1.000000 +vn 0.862294 -0.452626 -0.227111 +v -162.827713 -139.935699 26.784998 1.000000 1.000000 1.000000 +vn 0.872367 -0.486557 0.047308 +v -162.782654 -139.963608 27.239798 1.000000 1.000000 1.000000 +vn 0.953426 0.028581 0.300271 +v -163.555145 -142.529633 27.602198 1.000000 1.000000 1.000000 +vn 0.886947 -0.166799 0.430701 +v -163.531967 -141.833359 27.717999 1.000000 1.000000 1.000000 +vn 0.891273 0.128014 0.435023 +v -163.351715 -143.824493 27.383398 1.000000 1.000000 1.000000 +vn 0.680271 -0.181193 0.710212 +v -163.766281 -141.805435 28.065798 1.000000 1.000000 1.000000 +vn 0.904313 -0.280651 0.321642 +v -163.418671 -141.151031 27.833199 1.000000 1.000000 1.000000 +vn 0.216774 -0.173034 0.960765 +v -164.012192 -141.777542 28.220398 1.000000 1.000000 1.000000 +vn 0.695305 0.049254 0.717026 +v -163.577026 -143.901230 27.730997 1.000000 1.000000 1.000000 +vn 0.548701 -0.429333 0.717356 +v -163.139282 -139.738953 28.411798 1.000000 1.000000 1.000000 +vn 0.866097 0.296439 0.402493 +v -163.119965 -144.470535 27.268198 1.000000 1.000000 1.000000 +vn 0.811125 0.393767 0.432462 +v -162.803253 -145.080292 27.151999 1.000000 1.000000 1.000000 +vn 0.278493 -0.080389 0.957068 +v -163.812637 -143.980774 27.885599 1.000000 1.000000 1.000000 +vn 0.283901 0.006593 0.958831 +v -163.204941 -145.367737 27.654398 1.000000 1.000000 1.000000 +vn 0.259613 0.103070 0.960197 +v -161.692154 -146.973755 27.307198 1.000000 1.000000 1.000000 +vn 0.193517 0.192899 0.961947 +v -159.710724 -147.762131 26.961199 1.000000 1.000000 1.000000 +vn 0.098903 0.256044 0.961592 +v -157.672653 -147.621185 26.626398 1.000000 1.000000 1.000000 +vn -0.281345 0.618804 0.733435 +v -156.501038 -146.783997 26.240599 1.000000 1.000000 1.000000 +vn 0.308501 -0.204121 0.929065 +v -156.247406 -147.231888 26.391399 1.000000 1.000000 1.000000 +vn 0.005838 0.265650 0.964052 +v -156.372284 -147.011444 26.395199 1.000000 1.000000 1.000000 +vn 0.230245 -0.269562 0.935053 +v -157.609558 -147.870956 26.622599 1.000000 1.000000 1.000000 +vn 0.333402 -0.045464 0.941688 +v -154.641907 -145.572845 26.044197 1.000000 1.000000 1.000000 +vn -0.102175 0.248555 0.963214 +v -154.838898 -145.427734 26.047998 1.000000 1.000000 1.000000 +vn 0.364975 0.076306 0.927885 +v -153.808914 -143.352875 25.698198 1.000000 1.000000 1.000000 +vn -0.516801 0.463981 0.719471 +v -155.042313 -145.277039 25.893398 1.000000 1.000000 1.000000 +vn 0.296214 0.202335 0.933444 +v -153.871994 -141.035233 25.363398 1.000000 1.000000 1.000000 +vn 0.231514 0.278075 0.932242 +v -154.415314 -139.538025 25.132198 1.000000 1.000000 1.000000 +vn 0.065820 0.309581 0.948592 +v -155.890762 -137.742233 24.784998 1.000000 1.000000 1.000000 +vn -0.829860 0.433011 0.351900 +v -154.917435 -144.537506 25.430998 1.000000 1.000000 1.000000 +vn -0.647697 0.672431 0.358226 +v -155.634567 -145.678894 25.660999 1.000000 1.000000 1.000000 +vn -0.736699 0.535969 0.412325 +v -155.238007 -145.133316 25.545799 1.000000 1.000000 1.000000 +vn -0.606735 0.720774 0.335199 +v -156.098053 -146.157486 25.776398 1.000000 1.000000 1.000000 +vn -0.415591 0.791056 0.448904 +v -156.623352 -146.566330 25.892799 1.000000 1.000000 1.000000 +vn 0.856874 -0.378130 0.350406 +v -163.217819 -140.486847 27.949398 1.000000 1.000000 1.000000 +vn -0.068658 0.812773 -0.578521 +v -159.001328 -147.308640 24.666401 1.000000 1.000000 1.000000 +vn -0.597764 0.288790 -0.747850 +v -155.434998 -145.846329 18.497597 1.000000 1.000000 1.000000 +vn -0.653791 0.603549 -0.456383 +v -156.078735 -146.158890 18.948595 1.000000 1.000000 1.000000 +vn -0.839115 0.490106 -0.235970 +v -155.362900 -145.091461 19.124798 1.000000 1.000000 1.000000 +vn -0.290939 0.253847 -0.922451 +v -156.991562 -147.347702 18.709797 1.000000 1.000000 1.000000 +vn -0.446149 0.704410 -0.552048 +v -157.174393 -146.892838 19.180399 1.000000 1.000000 1.000000 +vn -0.676529 0.694780 -0.244109 +v -156.167572 -146.043076 19.345997 1.000000 1.000000 1.000000 +vn -0.894898 0.445280 0.029717 +v -155.093811 -144.490067 19.465199 1.000000 1.000000 1.000000 +vn -0.783578 0.621284 0.003371 +v -155.753006 -145.535172 19.684599 1.000000 1.000000 1.000000 +vn -0.564029 0.822720 0.070728 +v -156.700592 -146.390518 19.916199 1.000000 1.000000 1.000000 +vn -0.451538 0.865146 -0.218256 +v -157.229752 -146.756088 19.577797 1.000000 1.000000 1.000000 +vn -0.460248 0.796797 0.391518 +v -156.606613 -146.553757 20.740597 1.000000 1.000000 1.000000 +vn -0.295913 0.841527 0.451961 +v -157.179535 -146.880280 20.856998 1.000000 1.000000 1.000000 +vn -0.178005 0.886645 0.426820 +v -157.787231 -147.114685 20.973198 1.000000 1.000000 1.000000 +vn -0.435174 0.900332 0.005112 +v -157.250351 -146.704468 20.032597 1.000000 1.000000 1.000000 +vn -0.555142 0.701830 0.446377 +v -156.087753 -146.147720 20.625198 1.000000 1.000000 1.000000 +vn -0.170400 0.653876 0.737164 +v -157.085556 -147.114685 21.204597 1.000000 1.000000 1.000000 +vn -0.358277 0.573018 0.737080 +v -155.935822 -146.344467 20.972797 1.000000 1.000000 1.000000 +vn 0.014618 0.886312 0.462857 +v -158.414230 -147.251434 21.088398 1.000000 1.000000 1.000000 +vn 0.067983 0.665965 0.742878 +v -158.383331 -147.505386 21.435999 1.000000 1.000000 1.000000 +vn -0.273368 0.961342 0.033036 +v -157.834869 -146.929108 20.148800 1.000000 1.000000 1.000000 +vn 0.140647 0.935205 0.324977 +v -159.616730 -147.248642 21.305199 1.000000 1.000000 1.000000 +vn 0.317639 0.607112 0.728368 +v -160.310684 -147.351898 21.768799 1.000000 1.000000 1.000000 +vn 0.135281 0.240971 0.961058 +v -158.351135 -147.769104 21.590599 1.000000 1.000000 1.000000 +vn 0.551921 0.426126 0.716798 +v -162.088699 -146.329117 22.115799 1.000000 1.000000 1.000000 +vn 0.492608 0.791106 0.362613 +v -160.847565 -146.870514 21.536400 1.000000 1.000000 1.000000 +vn 0.329856 0.842902 0.425101 +v -160.246307 -147.106323 21.421200 1.000000 1.000000 1.000000 +vn 0.674546 0.187918 0.713915 +v -163.322098 -144.604492 22.462997 1.000000 1.000000 1.000000 +vn 0.696601 -0.038251 0.716438 +v -163.727661 -143.211945 22.694199 1.000000 1.000000 1.000000 +vn 0.900741 0.015442 0.434082 +v -163.495911 -143.170090 22.346600 1.000000 1.000000 1.000000 +vn 0.897883 0.184757 0.399589 +v -163.346573 -143.844025 22.231400 1.000000 1.000000 1.000000 +vn 0.949239 -0.092017 0.300797 +v -163.534546 -141.855682 22.565399 1.000000 1.000000 1.000000 +vn 0.911298 0.411711 0.005544 +v -162.950027 -144.410538 21.291000 1.000000 1.000000 1.000000 +vn 0.962872 0.267857 0.033602 +v -163.177902 -143.785416 21.407200 1.000000 1.000000 1.000000 +vn 0.856499 0.285742 0.429838 +v -163.109680 -144.494247 22.115200 1.000000 1.000000 1.000000 +vn 0.840554 0.541642 0.009669 +v -162.641022 -144.995178 21.174400 1.000000 1.000000 1.000000 +vn 0.891370 0.396174 -0.220241 +v -162.996368 -144.434250 20.836197 1.000000 1.000000 1.000000 +vn 0.955504 0.182734 -0.231562 +v -163.371033 -143.146362 21.067398 1.000000 1.000000 1.000000 +vn 0.997446 0.071073 0.007072 +v -163.377472 -142.549164 21.624397 1.000000 1.000000 1.000000 +vn 0.995234 -0.097217 -0.007682 +v -163.358170 -141.875214 21.740997 1.000000 1.000000 1.000000 +vn 0.865152 0.216173 -0.452528 +v -163.508789 -143.171478 20.669998 1.000000 1.000000 1.000000 +vn 0.793580 0.415763 -0.444266 +v -163.121262 -144.499832 20.438599 1.000000 1.000000 1.000000 +vn 0.706501 0.559012 -0.434006 +v -162.799393 -145.109604 20.322195 1.000000 1.000000 1.000000 +vn 0.735707 0.106089 -0.668940 +v -163.804916 -142.568695 20.437399 1.000000 1.000000 1.000000 +vn 0.626362 0.302726 -0.718350 +v -163.587326 -143.924957 20.219997 1.000000 1.000000 1.000000 +vn 0.833834 -0.020294 -0.551642 +v -163.547424 -141.854279 20.888798 1.000000 1.000000 1.000000 +vn 0.561868 0.513203 -0.648789 +v -162.997665 -145.253311 19.987400 1.000000 1.000000 1.000000 +vn 0.217038 0.180855 -0.959263 +v -163.959412 -143.253799 20.199398 1.000000 1.000000 1.000000 +vn 0.148941 0.232268 -0.961181 +v -163.533249 -144.714706 19.967999 1.000000 1.000000 1.000000 +vn 0.243798 0.105110 -0.964113 +v -163.880875 -141.046387 20.533997 1.000000 1.000000 1.000000 +vn 0.020301 0.243396 -0.969714 +v -162.239334 -146.524460 19.620800 1.000000 1.000000 1.000000 +vn 0.296461 0.686268 -0.664189 +v -161.550537 -146.774231 19.641197 1.000000 1.000000 1.000000 +vn -0.084467 0.274248 -0.957942 +v -160.375061 -147.597473 19.273998 1.000000 1.000000 1.000000 +vn 0.591191 0.705324 -0.391167 +v -161.945801 -146.144928 20.091599 1.000000 1.000000 1.000000 +vn 0.328302 0.683806 -0.651634 +v -161.424362 -146.555161 19.975998 1.000000 1.000000 1.000000 +vn 0.204387 0.847604 -0.489687 +v -160.250183 -147.120270 19.744598 1.000000 1.000000 1.000000 +vn 0.072609 0.654629 -0.752455 +v -160.314545 -147.368637 19.409798 1.000000 1.000000 1.000000 +vn -0.103673 0.709653 -0.696882 +v -158.967850 -147.565384 19.177399 1.000000 1.000000 1.000000 +vn -0.197467 0.164529 -0.966404 +v -158.352432 -147.756546 18.941200 1.000000 1.000000 1.000000 +vn 0.039369 0.906662 -0.420016 +v -159.618027 -147.263992 19.628597 1.000000 1.000000 1.000000 +vn 0.341619 0.913634 -0.220383 +v -160.211563 -146.975159 20.141998 1.000000 1.000000 1.000000 +vn 0.316733 0.947796 0.036924 +v -160.197388 -146.922134 20.596798 1.000000 1.000000 1.000000 +vn 0.532716 0.845025 0.046339 +v -161.323944 -146.380737 20.828197 1.000000 1.000000 1.000000 +vn -0.212960 0.850322 -0.481249 +v -158.411652 -147.265381 19.411797 1.000000 1.000000 1.000000 +vn -0.052707 0.997678 -0.043141 +v -158.971710 -147.100739 20.364397 1.000000 1.000000 1.000000 +vn -0.191968 0.950981 -0.242452 +v -158.429688 -147.116089 19.809200 1.000000 1.000000 1.000000 +vn 0.551734 0.762777 0.337285 +v -161.417923 -146.542603 21.652599 1.000000 1.000000 1.000000 +vn 0.668689 0.600612 0.438316 +v -161.936783 -146.133774 21.768200 1.000000 1.000000 1.000000 +vn 0.774762 0.522881 0.355443 +v -162.396408 -145.650986 21.883400 1.000000 1.000000 1.000000 +vn 0.689361 0.724251 0.015542 +v -161.822205 -145.987259 20.943798 1.000000 1.000000 1.000000 +vn 0.680412 0.686647 -0.256038 +v -161.855667 -146.030518 20.488998 1.000000 1.000000 1.000000 +vn 0.818144 0.473183 0.326708 +v -162.789093 -145.102615 21.998798 1.000000 1.000000 1.000000 +vn -0.161833 0.065212 -0.984661 +v -155.786484 -146.539810 18.477997 1.000000 1.000000 1.000000 +vn -0.124290 0.282153 -0.951284 +v -163.140564 -138.838959 20.875000 1.000000 1.000000 1.000000 +vn 0.003562 0.297189 -0.954812 +v -161.439804 -137.308289 21.222198 1.000000 1.000000 1.000000 +vn 0.095440 0.296688 -0.950193 +v -160.045471 -136.772476 21.453598 1.000000 1.000000 1.000000 +vn 0.221814 0.229056 -0.947804 +v -157.912109 -136.783630 21.788200 1.000000 1.000000 1.000000 +vn 0.302126 0.122178 -0.945406 +v -155.899780 -137.757584 22.134197 1.000000 1.000000 1.000000 +vn 0.512758 0.447093 -0.732930 +v -155.754288 -137.542694 22.285198 1.000000 1.000000 1.000000 +vn 0.317970 0.002711 -0.948097 +v -154.429474 -139.547791 22.481400 1.000000 1.000000 1.000000 +vn 0.657243 0.218466 -0.721321 +v -154.215759 -139.415237 22.632397 1.000000 1.000000 1.000000 +vn 0.314702 -0.080921 -0.945735 +v -153.888733 -141.039413 22.712799 1.000000 1.000000 1.000000 +vn 0.554189 0.289054 -0.780591 +v -154.649628 -138.710602 22.515999 1.000000 1.000000 1.000000 +vn 0.692119 0.034871 -0.720941 +v -153.649261 -140.978012 22.863800 1.000000 1.000000 1.000000 +vn 0.249987 -0.194974 -0.948415 +v -153.825638 -143.350082 23.047398 1.000000 1.000000 1.000000 +vn 0.628619 -0.091730 -0.772285 +v -153.502487 -142.557526 23.082600 1.000000 1.000000 1.000000 +vn 0.902552 0.126284 -0.411645 +v -153.418808 -140.918015 23.208199 1.000000 1.000000 1.000000 +vn 0.845729 0.240112 -0.476539 +v -153.659561 -140.085007 23.093197 1.000000 1.000000 1.000000 +vn 0.650613 -0.226397 -0.724878 +v -153.583603 -143.396118 23.198399 1.000000 1.000000 1.000000 +vn 0.889228 -0.072412 -0.451697 +v -153.265594 -142.567307 23.426998 1.000000 1.000000 1.000000 +vn 0.974967 0.082531 -0.206463 +v -153.165161 -141.667313 23.703598 1.000000 1.000000 1.000000 +vn 0.937089 0.305694 -0.168566 +v -153.535965 -140.031982 23.486198 1.000000 1.000000 1.000000 +vn 0.817279 0.361471 -0.448768 +v -154.009766 -139.289658 22.976997 1.000000 1.000000 1.000000 +vn 0.882596 0.437583 -0.171890 +v -153.893890 -139.218491 23.369999 1.000000 1.000000 1.000000 +vn 0.958220 0.235670 0.162089 +v -153.277191 -140.881744 24.416798 1.000000 1.000000 1.000000 +vn 0.922888 0.355115 0.148897 +v -153.523087 -140.026382 24.301798 1.000000 1.000000 1.000000 +vn 0.984278 -0.051625 -0.168911 +v -153.132980 -142.571487 23.820198 1.000000 1.000000 1.000000 +vn 0.872112 -0.201318 -0.445973 +v -153.350571 -143.440781 23.542999 1.000000 1.000000 1.000000 +vn 0.820618 -0.312588 -0.478409 +v -153.546265 -144.287735 23.658001 1.000000 1.000000 1.000000 +vn 0.968752 -0.180517 -0.170095 +v -153.219254 -143.465897 23.935999 1.000000 1.000000 1.000000 +vn 0.936750 -0.305832 -0.170197 +v -153.420090 -144.332397 24.051197 1.000000 1.000000 1.000000 +vn 0.982481 0.114243 0.147242 +v -153.152298 -141.665909 24.518999 1.000000 1.000000 1.000000 +vn 0.878079 0.163723 0.449635 +v -153.302933 -141.684052 24.987398 1.000000 1.000000 1.000000 +vn 0.821188 0.345437 0.454230 +v -153.664703 -140.086395 24.769999 1.000000 1.000000 1.000000 +vn 0.989165 -0.010957 0.146398 +v -153.120117 -142.571487 24.635599 1.000000 1.000000 1.000000 +vn 0.896341 0.031182 0.442267 +v -153.270737 -142.565903 25.103998 1.000000 1.000000 1.000000 +vn 0.635885 0.171026 0.752596 +v -153.538544 -141.711960 25.325199 1.000000 1.000000 1.000000 +vn 0.594420 0.312332 0.741022 +v -153.884872 -140.181274 25.107798 1.000000 1.000000 1.000000 +vn 0.744615 0.461618 0.482138 +v -154.014908 -139.292450 24.653799 1.000000 1.000000 1.000000 +vn 0.440562 0.457075 0.772650 +v -154.653503 -138.714783 24.875198 1.000000 1.000000 1.000000 +vn 0.866160 0.476599 0.150400 +v -153.882309 -139.211517 24.185598 1.000000 1.000000 1.000000 +vn 0.687916 0.565647 0.454768 +v -154.465530 -138.557114 24.537399 1.000000 1.000000 1.000000 +vn 0.792653 0.590539 0.151542 +v -154.345795 -138.456635 24.068998 1.000000 1.000000 1.000000 +vn 0.586884 0.645769 0.488415 +v -155.002411 -137.905487 24.421997 1.000000 1.000000 1.000000 +vn 0.730019 0.660737 -0.174640 +v -154.905853 -137.796646 23.138199 1.000000 1.000000 1.000000 +vn 0.702543 0.694859 0.153638 +v -154.896835 -137.786880 23.953798 1.000000 1.000000 1.000000 +vn 0.814578 0.553417 -0.173760 +v -154.356094 -138.465012 23.253597 1.000000 1.000000 1.000000 +vn 0.759450 0.466691 -0.453250 +v -154.461670 -138.554321 22.860397 1.000000 1.000000 1.000000 +vn 0.628899 0.757296 -0.176035 +v -155.536713 -137.218994 23.022797 1.000000 1.000000 1.000000 +vn 0.678429 0.551874 -0.484943 +v -154.998550 -137.899902 22.745197 1.000000 1.000000 1.000000 +vn 0.596290 0.787765 0.154483 +v -155.528992 -137.207825 23.838398 1.000000 1.000000 1.000000 +vn 0.499875 0.733150 0.461103 +v -155.617828 -137.340378 24.306599 1.000000 1.000000 1.000000 +vn 0.513118 0.839593 -0.178308 +v -156.231949 -136.745956 22.908199 1.000000 1.000000 1.000000 +vn 0.598849 0.656213 -0.459090 +v -155.615250 -137.334793 22.629799 1.000000 1.000000 1.000000 +vn 0.497898 0.732795 -0.463798 +v -156.295044 -136.872940 22.514999 1.000000 1.000000 1.000000 +vn 0.475796 0.865561 0.156278 +v -156.225510 -136.733414 23.723799 1.000000 1.000000 1.000000 +vn 0.384122 0.905649 -0.179586 +v -156.991562 -136.377594 22.792000 1.000000 1.000000 1.000000 +vn 0.383258 0.482939 -0.787327 +v -156.407043 -137.098984 22.170597 1.000000 1.000000 1.000000 +vn 0.382551 0.779637 -0.495803 +v -157.037918 -136.512939 22.398800 1.000000 1.000000 1.000000 +vn 0.273664 0.611274 -0.742598 +v -157.861908 -136.522720 21.939198 1.000000 1.000000 1.000000 +vn 0.261447 0.843403 -0.469379 +v -157.811691 -136.271561 22.283798 1.000000 1.000000 1.000000 +vn 0.244490 0.952653 -0.180769 +v -157.784653 -136.130615 22.676800 1.000000 1.000000 1.000000 +vn 0.342601 0.926304 0.156798 +v -156.987701 -136.365036 23.607599 1.000000 1.000000 1.000000 +vn 0.200281 0.967000 0.157473 +v -157.782074 -136.116669 23.492397 1.000000 1.000000 1.000000 +vn 0.096107 0.978684 -0.181496 +v -158.606064 -136.006439 22.560999 1.000000 1.000000 1.000000 +vn 0.114876 0.870364 -0.478822 +v -158.615082 -136.150146 22.167797 1.000000 1.000000 1.000000 +vn 0.049512 0.986264 0.157583 +v -158.606064 -135.992477 23.376400 1.000000 1.000000 1.000000 +vn -0.096352 0.982825 0.157387 +v -159.442932 -135.996674 23.259800 1.000000 1.000000 1.000000 +vn -0.061566 0.973602 -0.219794 +v -159.441635 -136.010620 22.444395 1.000000 1.000000 1.000000 +vn 0.126375 0.857617 0.498521 +v -157.812973 -136.277130 23.960598 1.000000 1.000000 1.000000 +vn -0.002539 0.882816 0.469711 +v -158.616364 -136.155746 23.844801 1.000000 1.000000 1.000000 +vn -0.155335 0.866407 0.474563 +v -159.431335 -136.159927 23.728201 1.000000 1.000000 1.000000 +vn -0.237661 0.956099 0.171440 +v -160.169067 -136.104111 23.157597 1.000000 1.000000 1.000000 +vn -0.111598 0.891778 -0.438495 +v -160.140747 -136.258987 21.948997 1.000000 1.000000 1.000000 +vn -0.316501 0.931655 -0.178456 +v -160.962158 -136.355270 22.226997 1.000000 1.000000 1.000000 +vn -0.372926 0.914536 0.156682 +v -160.966019 -136.342712 23.042599 1.000000 1.000000 1.000000 +vn -0.359543 0.805013 0.471893 +v -160.915802 -136.497589 23.510799 1.000000 1.000000 1.000000 +vn -0.169271 0.616182 0.769199 +v -159.413315 -136.415268 24.065998 1.000000 1.000000 1.000000 +vn -0.325960 0.574101 0.751104 +v -160.837280 -136.738983 23.848598 1.000000 1.000000 1.000000 +vn -0.487352 0.722314 0.490664 +v -161.661255 -136.849228 23.394600 1.000000 1.000000 1.000000 +vn -0.463242 0.867837 -0.179624 +v -161.725632 -136.715271 22.110798 1.000000 1.000000 1.000000 +vn -0.504611 0.849276 0.155235 +v -161.730774 -136.704102 22.926399 1.000000 1.000000 1.000000 +vn -0.244388 0.830660 -0.500279 +v -160.918381 -136.492020 21.834000 1.000000 1.000000 1.000000 +vn -0.622852 0.767169 0.153319 +v -162.442749 -137.179916 22.809799 1.000000 1.000000 1.000000 +vn -0.378388 0.798574 -0.468083 +v -161.663834 -136.843628 21.717800 1.000000 1.000000 1.000000 +vn -0.585413 0.790823 -0.178577 +v -162.435028 -137.191071 21.994400 1.000000 1.000000 1.000000 +vn -0.593868 0.661439 0.458060 +v -162.353912 -137.312469 23.278198 1.000000 1.000000 1.000000 +vn -0.480359 0.422034 0.768858 +v -162.214874 -137.521774 23.615999 1.000000 1.000000 1.000000 +vn -0.674217 0.558441 0.483295 +v -162.974487 -137.871994 23.162800 1.000000 1.000000 1.000000 +vn -0.725285 0.671530 0.151690 +v -163.078781 -137.753387 22.694599 1.000000 1.000000 1.000000 +vn -0.756571 0.474361 0.450092 +v -163.515228 -138.519440 23.047398 1.000000 1.000000 1.000000 +vn -0.811368 0.564781 0.150682 +v -163.634964 -138.417572 22.579197 1.000000 1.000000 1.000000 +vn -0.070336 0.625175 0.777309 +v -158.631821 -136.412476 24.182598 1.000000 1.000000 1.000000 +vn 0.130211 0.612153 0.779945 +v -157.120316 -136.759918 24.413601 1.000000 1.000000 1.000000 +vn 0.327264 0.584455 0.742503 +v -155.758148 -137.546890 24.644398 1.000000 1.000000 1.000000 +vn 0.375329 0.783875 0.494639 +v -156.297623 -136.878525 24.191998 1.000000 1.000000 1.000000 +vn 0.263977 0.843919 0.467030 +v -157.039200 -136.518524 24.075798 1.000000 1.000000 1.000000 +vn -0.692008 0.700047 -0.176236 +v -163.069763 -137.763168 21.878998 1.000000 1.000000 1.000000 +vn -0.783023 0.597198 -0.173867 +v -163.624664 -138.427338 21.763599 1.000000 1.000000 1.000000 +vn -0.491946 0.736274 -0.464640 +v -162.356491 -137.308289 21.601200 1.000000 1.000000 1.000000 +vn -0.580389 0.650402 -0.490027 +v -162.978348 -137.867813 21.486000 1.000000 1.000000 1.000000 +vn -0.857700 0.484075 -0.173268 +v -164.085587 -139.164078 21.648998 1.000000 1.000000 1.000000 +vn -0.682721 0.570803 -0.456153 +v -163.520386 -138.515259 21.370598 1.000000 1.000000 1.000000 +vn -0.301919 0.531419 -0.791479 +v -162.218735 -137.516190 21.256798 1.000000 1.000000 1.000000 +vn -0.465834 0.490767 -0.736306 +v -163.333694 -138.674316 21.025997 1.000000 1.000000 1.000000 +vn -0.755654 0.472426 -0.453652 +v -163.969711 -139.236633 21.255798 1.000000 1.000000 1.000000 +vn -0.503172 0.364783 -0.783423 +v -163.764999 -139.365005 20.911400 1.000000 1.000000 1.000000 +vn -0.220147 0.633280 -0.741951 +v -161.553116 -137.071075 21.373199 1.000000 1.000000 1.000000 +vn -0.015658 0.665764 -0.745998 +v -160.093109 -136.511551 21.604597 1.000000 1.000000 1.000000 +vn 0.124963 0.602278 -0.788445 +v -158.631821 -136.405502 21.823399 1.000000 1.000000 1.000000 +vn 0.642282 -0.093578 0.760735 +v -153.776733 -144.206818 25.672798 1.000000 1.000000 1.000000 +vn 0.646672 0.086761 0.757818 +v -153.507645 -142.557526 25.441799 1.000000 1.000000 1.000000 +vn 0.877277 -0.081200 0.473066 +v -153.355713 -143.439392 25.219801 1.000000 1.000000 1.000000 +vn 0.628087 -0.276113 0.727509 +v -154.456512 -145.709595 25.903599 1.000000 1.000000 1.000000 +vn 0.824863 -0.305050 0.475968 +v -153.857834 -145.102615 25.451199 1.000000 1.000000 1.000000 +vn 0.873200 -0.202788 0.443169 +v -153.551422 -144.286346 25.334999 1.000000 1.000000 1.000000 +vn 0.952223 -0.267667 0.147059 +v -153.408508 -144.337982 24.866798 1.000000 1.000000 1.000000 +vn 0.978943 -0.141505 0.147126 +v -153.206375 -143.468689 24.751598 1.000000 1.000000 1.000000 +vn 0.908284 -0.391064 0.148623 +v -153.721375 -145.175171 24.982998 1.000000 1.000000 1.000000 +vn 0.887814 -0.426904 -0.171873 +v -153.732941 -145.168198 24.167398 1.000000 1.000000 1.000000 +vn 0.913201 -0.139517 -0.382882 +v -163.436691 -141.166382 21.004597 1.000000 1.000000 1.000000 +vn 0.733002 -0.175620 -0.657165 +v -163.459869 -140.408707 20.785000 1.000000 1.000000 1.000000 +vn 0.047993 0.268919 0.961966 +v -156.986420 -147.358871 21.359200 1.000000 1.000000 1.000000 +vn -0.035210 0.272093 0.961626 +v -155.778763 -146.549576 21.127399 1.000000 1.000000 1.000000 +vn -0.497155 0.461019 0.735050 +v -155.066788 -145.314713 20.751598 1.000000 1.000000 1.000000 +vn -0.697263 0.556324 0.452026 +v -155.259903 -145.169601 20.403999 1.000000 1.000000 1.000000 +vn -0.111668 0.252084 0.961241 +v -154.863358 -145.466797 20.906197 1.000000 1.000000 1.000000 +vn 0.258538 0.194150 0.946289 +v -153.927353 -140.803604 20.208199 1.000000 1.000000 1.000000 +vn 0.195548 0.249237 0.948494 +v -154.520889 -139.345474 20.003998 1.000000 1.000000 1.000000 +vn 0.119415 0.286645 0.950566 +v -155.442734 -138.139908 19.811199 1.000000 1.000000 1.000000 +vn 0.901113 0.062928 0.428994 +v -163.507507 -143.089157 42.627380 1.000000 1.000000 1.000000 +vn 0.939515 0.300823 0.163761 +v -163.192078 -143.731003 41.720577 1.000000 1.000000 1.000000 +vn 0.937024 -0.064717 0.343216 +v -163.557724 -142.378922 42.707779 1.000000 1.000000 1.000000 +vn 0.897514 0.227359 0.377858 +v -163.360733 -143.786819 42.544979 1.000000 1.000000 1.000000 +vn 0.764306 0.080055 0.639866 +v -163.740540 -143.126816 42.975178 1.000000 1.000000 1.000000 +vn 0.990133 0.140120 0.001867 +v -163.332413 -143.061249 41.803177 1.000000 1.000000 1.000000 +vn 0.844322 0.524815 -0.108119 +v -162.684814 -144.925415 41.556976 1.000000 1.000000 1.000000 +vn 0.957750 0.189242 -0.216570 +v -163.382614 -143.069626 41.348377 1.000000 1.000000 1.000000 +vn 0.835979 -0.189784 0.514899 +v -163.512650 -141.668701 42.785580 1.000000 1.000000 1.000000 +vn 0.770679 0.207914 0.602350 +v -163.358170 -144.516571 42.813980 1.000000 1.000000 1.000000 +vn 0.852403 -0.299218 0.428810 +v -163.376190 -140.983597 42.859779 1.000000 1.000000 1.000000 +vn 0.654733 0.500226 0.566656 +v -162.617859 -145.765411 42.640778 1.000000 1.000000 1.000000 +vn 0.817783 0.385580 0.427270 +v -162.832870 -145.028671 42.381180 1.000000 1.000000 1.000000 +vn 0.779533 0.626361 0.000140 +v -162.306290 -145.470978 41.468781 1.000000 1.000000 1.000000 +vn 0.738317 0.509989 0.441361 +v -162.440186 -145.597961 42.293179 1.000000 1.000000 1.000000 +vn 0.675726 0.737136 0.005026 +v -161.858246 -145.953766 41.378178 1.000000 1.000000 1.000000 +vn 0.493993 0.699009 0.517067 +v -161.571136 -146.739349 42.457378 1.000000 1.000000 1.000000 +vn 0.669737 0.619842 0.408959 +v -161.972824 -146.098892 42.202579 1.000000 1.000000 1.000000 +vn 0.538067 0.841506 0.048495 +v -161.349686 -146.361206 41.285378 1.000000 1.000000 1.000000 +vn 0.671508 0.695669 -0.255190 +v -161.891708 -145.995636 40.923378 1.000000 1.000000 1.000000 +vn 0.716925 0.628222 -0.302251 +v -162.344910 -145.508652 41.013977 1.000000 1.000000 1.000000 +vn 0.545757 0.718016 -0.431975 +v -161.981842 -146.110046 40.525978 1.000000 1.000000 1.000000 +vn 0.247568 0.935569 -0.251837 +v -160.228287 -146.970978 40.641579 1.000000 1.000000 1.000000 +vn 0.301689 0.951532 0.059745 +v -160.214127 -146.916550 41.096378 1.000000 1.000000 1.000000 +vn 0.555117 0.717852 0.420160 +v -161.444962 -146.523071 42.109779 1.000000 1.000000 1.000000 +vn 0.464468 0.781034 0.417439 +v -160.874619 -146.856552 42.016579 1.000000 1.000000 1.000000 +vn 0.298184 0.856350 0.421605 +v -160.263046 -147.102142 41.920578 1.000000 1.000000 1.000000 +vn 0.030676 0.998064 0.054103 +v -158.967850 -147.100739 40.896378 1.000000 1.000000 1.000000 +vn -0.017800 0.970179 -0.241737 +v -158.966568 -147.156540 40.441578 1.000000 1.000000 1.000000 +vn 0.299614 0.605350 0.737416 +v -160.328720 -147.347702 42.268181 1.000000 1.000000 1.000000 +vn 0.086167 0.901842 0.423386 +v -158.966568 -147.291901 41.720779 1.000000 1.000000 1.000000 +vn -0.218090 0.974397 0.054652 +v -158.200516 -147.021194 40.770378 1.000000 1.000000 1.000000 +vn -0.119201 0.914114 0.387540 +v -158.168320 -147.209564 41.594578 1.000000 1.000000 1.000000 +vn 0.109821 0.657406 0.745491 +v -158.963989 -147.548645 42.068378 1.000000 1.000000 1.000000 +vn -0.118555 0.663612 0.738623 +v -157.461502 -147.272354 41.837357 1.000000 1.000000 1.000000 +vn -0.306453 0.602648 0.736819 +v -156.237091 -146.594223 41.619957 1.000000 1.000000 1.000000 +vn -0.225649 0.862205 0.453525 +v -157.537460 -147.030975 41.489777 1.000000 1.000000 1.000000 +vn -0.401200 0.826604 0.394671 +v -156.933624 -146.753296 41.382179 1.000000 1.000000 1.000000 +vn -0.020941 0.268724 0.962990 +v -156.094193 -146.811905 41.774578 1.000000 1.000000 1.000000 +vn -0.127040 0.227363 0.965488 +v -154.513168 -144.830521 41.389977 1.000000 1.000000 1.000000 +vn -0.717946 0.610526 0.334382 +v -155.517395 -145.917496 41.464977 1.000000 1.000000 1.000000 +vn -0.576806 0.396327 0.714297 +v -154.733322 -144.709137 41.235378 1.000000 1.000000 1.000000 +vn -0.232435 0.165776 0.958380 +v -153.973709 -142.617523 41.043777 1.000000 1.000000 1.000000 +vn -0.687127 0.158362 0.709068 +v -154.219620 -142.604980 40.889179 1.000000 1.000000 1.000000 +vn -0.270267 0.084943 0.959031 +v -154.106323 -141.088242 40.812378 1.000000 1.000000 1.000000 +vn -0.290719 -0.010820 0.956747 +v -154.974091 -139.084549 40.477779 1.000000 1.000000 1.000000 +vn -0.607902 0.647989 0.458875 +v -155.688644 -145.743073 41.117378 1.000000 1.000000 1.000000 +vn -0.721553 0.558708 0.408909 +v -155.276642 -145.194702 41.003178 1.000000 1.000000 1.000000 +vn -0.412143 0.708290 0.573117 +v -156.372284 -146.386337 41.272377 1.000000 1.000000 1.000000 +vn -0.708527 0.705101 -0.028656 +v -155.991196 -145.800278 40.337177 1.000000 1.000000 1.000000 +vn -0.500908 0.863814 0.053996 +v -157.013458 -146.583069 40.557777 1.000000 1.000000 1.000000 +vn -0.703872 0.673410 0.226014 +v -155.785202 -145.645401 40.723579 1.000000 1.000000 1.000000 +vn -0.910407 0.413588 -0.010232 +v -155.100266 -144.506821 40.063377 1.000000 1.000000 1.000000 +vn -0.958488 0.281267 0.046789 +v -154.859497 -143.887283 39.947178 1.000000 1.000000 1.000000 +vn -0.895716 0.308504 0.320186 +v -154.692123 -143.948685 40.771580 1.000000 1.000000 1.000000 +vn -0.775752 0.458220 0.433871 +v -154.943176 -144.593323 40.887779 1.000000 1.000000 1.000000 +vn -0.854630 0.508246 -0.106269 +v -155.422134 -145.084473 40.178780 1.000000 1.000000 1.000000 +vn -0.237563 0.938197 -0.251695 +v -158.191498 -147.075623 40.315578 1.000000 1.000000 1.000000 +vn -0.388779 0.810891 -0.437386 +v -157.532303 -147.044922 39.813179 1.000000 1.000000 1.000000 +vn -0.240631 0.839019 -0.488000 +v -158.165741 -147.223526 39.917976 1.000000 1.000000 1.000000 +vn -0.057008 0.868682 -0.492079 +v -158.965271 -147.307251 40.044178 1.000000 1.000000 1.000000 +vn 0.155014 0.858711 -0.488453 +v -160.266922 -147.116089 40.243980 1.000000 1.000000 1.000000 +vn 0.057234 0.561373 -0.825581 +v -160.332581 -147.363052 39.909180 1.000000 1.000000 1.000000 +vn -0.275469 0.607862 -0.744729 +v -158.121979 -147.477478 39.583378 1.000000 1.000000 1.000000 +vn -0.124556 0.782465 -0.610111 +v -158.963989 -147.565384 39.709377 1.000000 1.000000 1.000000 +vn -0.420051 0.457632 -0.783665 +v -156.819046 -146.996078 39.370781 1.000000 1.000000 1.000000 +vn -0.001995 0.250132 -0.968210 +v -161.067719 -147.322601 39.869377 1.000000 1.000000 1.000000 +vn 0.363105 0.644882 -0.672519 +v -161.580139 -146.753296 40.098377 1.000000 1.000000 1.000000 +vn 0.143332 0.315758 -0.937951 +v -162.795532 -145.931442 40.145981 1.000000 1.000000 1.000000 +vn 0.587806 0.294864 -0.753352 +v -163.601486 -143.864960 40.533577 1.000000 1.000000 1.000000 +vn 0.817059 0.377382 -0.435887 +v -163.156021 -144.416107 40.789780 1.000000 1.000000 1.000000 +vn 0.880416 0.184206 -0.436962 +v -163.520386 -143.091949 40.950779 1.000000 1.000000 1.000000 +vn 0.620591 0.099803 -0.777757 +v -163.810059 -142.380325 40.696381 1.000000 1.000000 1.000000 +vn 0.927229 -0.109347 -0.358176 +v -163.526825 -141.665909 41.108978 1.000000 1.000000 1.000000 +vn 0.983736 0.066507 -0.166854 +v -163.432831 -142.377533 41.428577 1.000000 1.000000 1.000000 +vn 0.187536 0.005238 -0.982244 +v -163.978729 -141.597549 40.638378 1.000000 1.000000 1.000000 +vn 0.647835 -0.189951 -0.737718 +v -163.374893 -140.200806 40.921978 1.000000 1.000000 1.000000 +vn -0.229794 0.228605 -0.946010 +v -163.421249 -139.271530 40.852978 1.000000 1.000000 1.000000 +vn 0.346893 -0.037549 -0.937153 +v -163.574463 -140.103134 40.785980 1.000000 1.000000 1.000000 +vn 0.774283 -0.303208 -0.555473 +v -163.158600 -140.308258 41.256779 1.000000 1.000000 1.000000 +vn 0.654781 -0.408729 -0.635769 +v -162.623001 -138.932449 41.063778 1.000000 1.000000 1.000000 +vn 0.225215 -0.114477 -0.967560 +v -162.272812 -138.222229 40.995579 1.000000 1.000000 1.000000 +vn -0.110621 0.262277 -0.958631 +v -162.424728 -138.031067 40.990578 1.000000 1.000000 1.000000 +vn -0.023159 0.313174 -0.949413 +v -160.442017 -136.877121 41.178379 1.000000 1.000000 1.000000 +vn 0.214110 -0.228541 -0.949698 +v -161.063858 -137.390610 41.122379 1.000000 1.000000 1.000000 +vn 0.081960 0.262915 -0.961332 +v -158.930511 -136.659454 41.294579 1.000000 1.000000 1.000000 +vn 0.080368 -0.193248 -0.977853 +v -158.933090 -136.913406 41.299580 1.000000 1.000000 1.000000 +vn 0.151737 0.250877 -0.956053 +v -157.447327 -136.914795 41.400578 1.000000 1.000000 1.000000 +vn 0.155544 0.118713 -0.980670 +v -156.061996 -137.633392 41.499977 1.000000 1.000000 1.000000 +vn 0.425939 0.516692 -0.742702 +v -155.924240 -137.412933 41.650978 1.000000 1.000000 1.000000 +vn 0.220736 0.132800 -0.966250 +v -154.979233 -138.688263 41.586178 1.000000 1.000000 1.000000 +vn 0.557172 0.384422 -0.736057 +v -154.789963 -138.516647 41.737179 1.000000 1.000000 1.000000 +vn -0.146928 -0.100086 -0.984071 +v -155.158188 -138.851532 41.591377 1.000000 1.000000 1.000000 +vn -0.371577 -0.474642 -0.797900 +v -155.813522 -138.460831 41.682777 1.000000 1.000000 1.000000 +vn 0.624989 0.609874 -0.487280 +v -155.191666 -137.701767 42.037376 1.000000 1.000000 1.000000 +vn 0.663287 0.197881 -0.721730 +v -153.954407 -139.981735 41.818977 1.000000 1.000000 1.000000 +vn 0.287677 0.055626 -0.956111 +v -154.180984 -140.087799 41.667976 1.000000 1.000000 1.000000 +vn 0.716431 0.528172 -0.455808 +v -154.608429 -138.350601 42.081779 1.000000 1.000000 1.000000 +vn 0.771456 0.414162 -0.483038 +v -154.119202 -139.085938 42.123978 1.000000 1.000000 1.000000 +vn 0.288878 -0.037994 -0.956612 +v -153.745819 -142.360794 41.768978 1.000000 1.000000 1.000000 +vn -0.222511 -0.142796 -0.964416 +v -154.394714 -140.188248 41.673180 1.000000 1.000000 1.000000 +vn 0.684187 -0.027290 -0.728796 +v -153.498627 -142.360794 41.919979 1.000000 1.000000 1.000000 +vn 0.113300 -0.728593 -0.675511 +v -154.150101 -144.960297 41.896378 1.000000 1.000000 1.000000 +vn -0.212619 -0.038670 -0.976370 +v -153.978867 -142.360794 41.773979 1.000000 1.000000 1.000000 +vn 0.610280 -0.153340 -0.777204 +v -153.681442 -143.891464 41.974960 1.000000 1.000000 1.000000 +vn -0.458376 -0.520113 -0.720676 +v -154.468094 -144.795654 41.874977 1.000000 1.000000 1.000000 +vn 0.896806 -0.042729 -0.440355 +v -153.261734 -142.360794 42.264580 1.000000 1.000000 1.000000 +vn 0.857303 0.298077 -0.419740 +v -153.736801 -139.878494 42.163578 1.000000 1.000000 1.000000 +vn 0.828927 0.124616 -0.545299 +v -153.323532 -141.444061 42.230179 1.000000 1.000000 1.000000 +vn 0.870149 -0.215221 -0.443306 +v -153.452286 -143.957047 42.319378 1.000000 1.000000 1.000000 +vn 0.949396 -0.228744 -0.215231 +v -153.323532 -143.993332 42.712578 1.000000 1.000000 1.000000 +vn 0.341632 -0.904224 -0.256254 +v -153.766418 -145.175171 42.640179 1.000000 1.000000 1.000000 +vn 0.984036 -0.022167 -0.176585 +v -153.129120 -142.360794 42.657578 1.000000 1.000000 1.000000 +vn 0.972644 0.107450 -0.205954 +v -153.192215 -141.423126 42.623177 1.000000 1.000000 1.000000 +vn 0.933613 0.264845 -0.241297 +v -153.354431 -140.606842 42.590778 1.000000 1.000000 1.000000 +vn 0.864563 0.471510 -0.173808 +v -154.005890 -139.010590 42.517178 1.000000 1.000000 1.000000 +vn 0.779620 0.592683 -0.202283 +v -154.506729 -138.257111 42.474979 1.000000 1.000000 1.000000 +vn 0.688860 0.696237 -0.201804 +v -155.104126 -137.594330 42.430580 1.000000 1.000000 1.000000 +vn 0.582905 0.789281 -0.193024 +v -155.716949 -137.080841 42.388580 1.000000 1.000000 1.000000 +vn 0.453535 0.879147 0.146307 +v -156.446960 -136.568756 42.745377 1.000000 1.000000 1.000000 +vn 0.539050 0.703694 -0.462861 +v -155.791626 -137.199448 41.995579 1.000000 1.000000 1.000000 +vn 0.459026 0.857561 -0.232131 +v -156.467560 -136.616211 42.339779 1.000000 1.000000 1.000000 +vn 0.424951 0.756659 -0.496874 +v -156.524200 -136.745956 41.946777 1.000000 1.000000 1.000000 +vn 0.323000 0.917132 -0.233537 +v -157.264511 -136.277130 42.289177 1.000000 1.000000 1.000000 +vn 0.340600 0.939430 0.038233 +v -157.250351 -136.226898 42.694580 1.000000 1.000000 1.000000 +vn 0.308176 0.827828 -0.468752 +v -157.303131 -136.413879 41.895981 1.000000 1.000000 1.000000 +vn 0.177359 0.955614 -0.235258 +v -158.096222 -136.067825 42.236378 1.000000 1.000000 1.000000 +vn 0.255596 0.611737 -0.748631 +v -157.373947 -136.659454 41.551579 1.000000 1.000000 1.000000 +vn 0.176329 0.847215 -0.501134 +v -158.116821 -136.210159 41.843178 1.000000 1.000000 1.000000 +vn 0.074245 0.660725 -0.746947 +v -158.926651 -136.392944 41.445580 1.000000 1.000000 1.000000 +vn 0.028574 0.971526 -0.235204 +v -158.921494 -135.992477 42.183178 1.000000 1.000000 1.000000 +vn 0.172199 0.982885 -0.065462 +v -158.089783 -136.016205 42.641777 1.000000 1.000000 1.000000 +vn 0.043155 0.880522 -0.472036 +v -158.924072 -136.136200 41.790176 1.000000 1.000000 1.000000 +vn -0.121703 0.964338 -0.235032 +v -159.776382 -136.046906 42.126179 1.000000 1.000000 1.000000 +vn -0.010489 0.999671 0.023412 +v -158.921494 -135.940857 42.588779 1.000000 1.000000 1.000000 +vn -0.144192 0.988294 0.049831 +v -159.781525 -135.995270 42.531776 1.000000 1.000000 1.000000 +vn -0.276579 0.944566 -0.176913 +v -160.611969 -136.233887 42.067177 1.000000 1.000000 1.000000 +vn -0.092744 0.876362 -0.472640 +v -159.758362 -136.189224 41.733177 1.000000 1.000000 1.000000 +vn -0.045007 0.644547 -0.763239 +v -159.727463 -136.444580 41.388580 1.000000 1.000000 1.000000 +vn -0.220994 0.835609 -0.502911 +v -160.574631 -136.373413 41.673981 1.000000 1.000000 1.000000 +vn -0.226899 0.564082 -0.793932 +v -161.260849 -136.917587 41.268181 1.000000 1.000000 1.000000 +vn -0.410243 0.881864 -0.232414 +v -161.412781 -136.550613 42.005779 1.000000 1.000000 1.000000 +vn -0.355440 0.808153 -0.469629 +v -161.358704 -136.683182 41.612778 1.000000 1.000000 1.000000 +vn -0.393546 0.540602 -0.743553 +v -162.585663 -137.827347 41.141579 1.000000 1.000000 1.000000 +vn -0.461927 0.735083 -0.496263 +v -162.089996 -137.111542 41.549580 1.000000 1.000000 1.000000 +vn -0.669701 0.584426 -0.458199 +v -163.328552 -138.265488 41.418381 1.000000 1.000000 1.000000 +vn -0.577434 0.673597 -0.461343 +v -162.740173 -137.632004 41.485977 1.000000 1.000000 1.000000 +vn -0.476931 0.453220 -0.753080 +v -163.149582 -138.434311 41.073978 1.000000 1.000000 1.000000 +vn -0.653116 0.739467 -0.163185 +v -162.826431 -137.523163 41.879177 1.000000 1.000000 1.000000 +vn -0.565461 0.811495 -0.147408 +v -162.162094 -136.988754 41.942780 1.000000 1.000000 1.000000 +vn -0.444417 0.894992 0.038511 +v -161.432083 -136.504578 42.411377 1.000000 1.000000 1.000000 +vn -0.656055 0.733974 0.175709 +v -162.834152 -137.512009 42.694580 1.000000 1.000000 1.000000 +vn -0.758999 0.627376 -0.174127 +v -163.428970 -138.170609 41.811577 1.000000 1.000000 1.000000 +vn -0.768813 0.618837 0.161145 +v -163.437988 -138.162231 42.627178 1.000000 1.000000 1.000000 +vn -0.839837 0.514819 -0.172150 +v -163.938812 -138.908737 41.741577 1.000000 1.000000 1.000000 +vn -0.858545 0.488637 0.155350 +v -163.950409 -138.901749 42.557178 1.000000 1.000000 1.000000 +vn -0.731956 0.478351 -0.485202 +v -163.828094 -138.986877 41.348579 1.000000 1.000000 1.000000 +vn -0.553287 0.285194 -0.782648 +v -164.010910 -139.888260 40.931976 1.000000 1.000000 1.000000 +vn 0.943966 -0.245669 -0.220399 +v -163.255157 -141.021271 41.580578 1.000000 1.000000 1.000000 +vn 0.992766 0.038867 -0.113602 +v -163.381332 -142.377533 41.883377 1.000000 1.000000 1.000000 +vn 0.988772 -0.124177 0.083127 +v -163.337555 -141.695221 41.961178 1.000000 1.000000 1.000000 +vn -0.104321 0.865168 -0.490511 +v -162.629440 -145.776566 40.281776 1.000000 1.000000 1.000000 +vn 0.335928 0.758887 -0.557892 +v -160.879761 -146.870514 40.339977 1.000000 1.000000 1.000000 +vn -0.579690 0.678762 -0.450824 +v -156.364563 -146.397491 39.595779 1.000000 1.000000 1.000000 +vn -0.553528 0.416630 -0.721128 +v -155.696365 -146.136566 39.150177 1.000000 1.000000 1.000000 +vn -0.711194 0.535501 -0.455457 +v -155.679626 -145.752838 39.440781 1.000000 1.000000 1.000000 +vn -0.732446 0.632991 -0.250690 +v -155.780045 -145.649597 39.838181 1.000000 1.000000 1.000000 +vn -0.713154 0.301429 -0.632892 +v -155.070648 -145.352386 38.991779 1.000000 1.000000 1.000000 +vn -0.799135 0.408485 -0.441048 +v -155.266342 -145.203094 39.326576 1.000000 1.000000 1.000000 +vn -0.865360 0.190882 -0.463375 +v -154.679245 -143.952866 39.094978 1.000000 1.000000 1.000000 +vn -0.946615 0.240707 -0.214429 +v -154.810562 -143.904037 39.492378 1.000000 1.000000 1.000000 +vn -0.674789 0.088179 -0.732724 +v -154.453949 -144.036575 38.760178 1.000000 1.000000 1.000000 +vn -0.796016 -0.383277 -0.468462 +v -154.792542 -144.622635 42.119778 1.000000 1.000000 1.000000 +vn -0.925946 -0.332225 -0.179584 +v -155.004974 -144.508209 42.600380 1.000000 1.000000 1.000000 +vn 0.120558 -0.241400 0.962908 +v -163.351715 -139.603607 28.566399 1.000000 1.000000 1.000000 +vn -0.336241 0.024735 0.941451 +v -163.559006 -139.472443 28.562599 1.000000 1.000000 1.000000 +vn -0.358243 -0.099166 0.928347 +v -164.249084 -141.749634 28.216599 1.000000 1.000000 1.000000 +vn 0.013823 -0.265475 0.964019 +v -161.922607 -137.909668 28.913601 1.000000 1.000000 1.000000 +vn -0.647489 0.053011 0.760229 +v -164.335358 -140.899872 28.191198 1.000000 1.000000 1.000000 +vn -0.080220 -0.261149 0.961960 +v -160.663467 -137.205032 29.144798 1.000000 1.000000 1.000000 +vn -0.179063 -0.203794 0.962499 +v -158.639542 -136.913406 29.479597 1.000000 1.000000 1.000000 +vn -0.251233 -0.118531 0.960642 +v -156.611755 -137.553864 29.825598 1.000000 1.000000 1.000000 +vn -0.450227 -0.524808 0.722407 +v -156.728928 -137.789673 29.670998 1.000000 1.000000 1.000000 +vn -0.622219 -0.312747 0.717658 +v -155.198105 -139.205933 30.018198 1.000000 1.000000 1.000000 +vn -0.690255 -0.092854 0.717584 +v -154.538910 -140.481277 30.249399 1.000000 1.000000 1.000000 +vn -0.881148 -0.184545 0.435341 +v -154.759079 -140.573364 29.901798 1.000000 1.000000 1.000000 +vn -0.844969 -0.351666 0.402938 +v -155.030731 -139.945465 29.786598 1.000000 1.000000 1.000000 +vn -0.949917 -0.089460 0.299424 +v -154.473251 -141.850098 30.120598 1.000000 1.000000 1.000000 +vn -0.813564 -0.581438 0.006583 +v -155.525116 -139.478027 28.846201 1.000000 1.000000 1.000000 +vn -0.893342 -0.448137 0.033367 +v -155.185226 -140.038956 28.962399 1.000000 1.000000 1.000000 +vn -0.783399 -0.445671 0.433202 +v -155.384796 -139.362213 29.670597 1.000000 1.000000 1.000000 +vn -0.714784 -0.699275 0.009885 +v -155.937119 -138.972916 28.729799 1.000000 1.000000 1.000000 +vn -0.796363 -0.562201 -0.223017 +v -155.485214 -139.444534 28.391399 1.000000 1.000000 1.000000 +vn -0.902818 -0.361542 -0.232823 +v -154.876236 -140.622192 28.622799 1.000000 1.000000 1.000000 +vn -0.966011 -0.258394 0.007398 +v -154.757797 -141.205444 29.179798 1.000000 1.000000 1.000000 +vn -0.895483 0.111403 0.430929 +v -154.452652 -142.547760 30.236597 1.000000 1.000000 1.000000 +vn -0.920307 0.222548 0.321726 +v -154.523453 -143.235657 30.351599 1.000000 1.000000 1.000000 +vn -0.995710 -0.092210 -0.007653 +v -154.649628 -141.869629 29.296398 1.000000 1.000000 1.000000 +vn -0.923627 -0.035160 -0.381678 +v -154.439774 -142.547760 28.559998 1.000000 1.000000 1.000000 +vn -0.699689 -0.243381 -0.671715 +v -154.343216 -141.093826 27.992598 1.000000 1.000000 1.000000 +vn -0.822920 -0.136721 -0.551462 +v -154.460373 -141.848709 28.443998 1.000000 1.000000 1.000000 +vn -0.755216 0.034456 -0.654570 +v -154.274979 -143.284500 28.340399 1.000000 1.000000 1.000000 +vn -0.887890 0.188144 -0.419826 +v -154.668961 -143.917984 28.791199 1.000000 1.000000 1.000000 +vn -0.215765 -0.149027 -0.965006 +v -153.982727 -142.567307 28.089199 1.000000 1.000000 1.000000 +vn -0.917703 0.286541 -0.275164 +v -154.801559 -143.870544 29.188799 1.000000 1.000000 1.000000 +vn -0.805986 -0.377624 -0.455836 +v -154.746201 -140.567780 28.225199 1.000000 1.000000 1.000000 +vn -0.172804 -0.217953 -0.960539 +v -154.320038 -140.389175 27.754599 1.000000 1.000000 1.000000 +vn -0.551053 -0.417134 -0.722731 +v -154.810562 -139.812897 27.775398 1.000000 1.000000 1.000000 +vn -0.693015 -0.562803 -0.450537 +v -155.374481 -139.352448 27.993799 1.000000 1.000000 1.000000 +vn -0.095197 -0.255982 -0.961983 +v -155.011429 -139.052444 27.523199 1.000000 1.000000 1.000000 +vn -0.444077 -0.611397 -0.654973 +v -155.637131 -138.642227 27.542599 1.000000 1.000000 1.000000 +vn -0.575744 -0.689416 -0.439572 +v -155.804504 -138.826416 27.877398 1.000000 1.000000 1.000000 +vn -0.480674 -0.844384 -0.236577 +v -156.901443 -138.134323 28.044197 1.000000 1.000000 1.000000 +vn -0.394128 -0.780266 -0.485642 +v -156.834488 -138.001770 27.646799 1.000000 1.000000 1.000000 +vn -0.223614 -0.622322 -0.750141 +v -156.722473 -137.774323 27.311998 1.000000 1.000000 1.000000 +vn -0.362334 -0.885603 -0.290553 +v -157.465363 -137.858047 27.929598 1.000000 1.000000 1.000000 +vn -0.244468 -0.861964 -0.444131 +v -157.417725 -137.717117 27.531998 1.000000 1.000000 1.000000 +vn -0.517077 -0.854489 0.049794 +v -156.925903 -138.183151 28.498999 1.000000 1.000000 1.000000 +vn -0.706490 -0.625512 0.331071 +v -155.813522 -138.836166 29.553999 1.000000 1.000000 1.000000 +vn -0.514333 -0.747501 0.420362 +v -156.840927 -138.014328 29.323399 1.000000 1.000000 1.000000 +vn -0.205815 -0.977179 0.052554 +v -158.078201 -137.721313 28.268198 1.000000 1.000000 1.000000 +vn -0.657160 -0.663841 0.357011 +v -156.300186 -138.386871 29.438599 1.000000 1.000000 1.000000 +vn -0.288953 -0.894100 0.342185 +v -158.040863 -137.534332 29.092398 1.000000 1.000000 1.000000 +vn 0.068385 -0.997624 -0.008390 +v -159.305176 -137.625031 28.036999 1.000000 1.000000 1.000000 +vn -0.398266 -0.840322 0.367754 +v -157.421585 -137.729675 29.208599 1.000000 1.000000 1.000000 +vn -0.178341 -0.656816 0.732658 +v -158.657562 -137.179916 29.324999 1.000000 1.000000 1.000000 +vn 0.080155 -0.663924 0.743492 +v -160.582352 -137.457581 28.990198 1.000000 1.000000 1.000000 +vn 0.181880 -0.868256 0.461575 +v -160.505096 -137.698975 28.642599 1.000000 1.000000 1.000000 +vn 0.324894 -0.597691 0.732946 +v -161.779709 -138.127335 28.758999 1.000000 1.000000 1.000000 +vn 0.368316 -0.828012 0.422776 +v -161.092194 -137.972473 28.527399 1.000000 1.000000 1.000000 +vn 0.470700 -0.760282 0.447676 +v -161.643234 -138.336639 28.411198 1.000000 1.000000 1.000000 +vn 0.655977 -0.677607 0.332480 +v -162.141479 -138.781754 28.294798 1.000000 1.000000 1.000000 +vn 0.693016 -0.626968 0.355866 +v -162.574081 -139.295242 28.179398 1.000000 1.000000 1.000000 +vn 0.731948 -0.681297 0.009321 +v -162.020462 -138.921280 27.470398 1.000000 1.000000 1.000000 +vn 0.771638 -0.486590 0.409639 +v -162.935867 -139.867325 28.064198 1.000000 1.000000 1.000000 +vn 0.616038 -0.787700 0.005109 +v -161.540237 -138.491531 27.586998 1.000000 1.000000 1.000000 +vn 0.594918 -0.770857 -0.227710 +v -161.571136 -138.446884 27.132198 1.000000 1.000000 1.000000 +vn 0.475117 -0.879303 0.033009 +v -161.011078 -138.142685 27.703199 1.000000 1.000000 1.000000 +vn 0.068059 -0.943369 0.324688 +v -159.318054 -137.433868 28.861399 1.000000 1.000000 1.000000 +vn 0.263899 -0.964531 0.006130 +v -159.921875 -137.719910 27.920597 1.000000 1.000000 1.000000 +vn 0.379867 -0.892178 -0.244375 +v -160.463898 -137.827347 27.363598 1.000000 1.000000 1.000000 +vn -0.158744 -0.875190 0.456993 +v -158.674301 -137.435257 28.977198 1.000000 1.000000 1.000000 +vn 0.009081 -0.911571 -0.411042 +v -158.673004 -137.421310 27.300798 1.000000 1.000000 1.000000 +vn 0.394671 -0.786174 -0.475569 +v -160.508957 -137.685028 26.965998 1.000000 1.000000 1.000000 +vn 0.128159 -0.805659 -0.578351 +v -159.318054 -137.419907 27.184799 1.000000 1.000000 1.000000 +vn 0.247155 -0.675021 -0.695170 +v -160.010712 -137.266418 26.733398 1.000000 1.000000 1.000000 +vn -0.063758 -0.726141 -0.684583 +v -157.988068 -137.267822 27.080999 1.000000 1.000000 1.000000 +vn 0.435800 -0.526817 -0.729755 +v -161.208069 -137.729675 26.516199 1.000000 1.000000 1.000000 +vn 0.590207 -0.666985 -0.454739 +v -161.650955 -138.324097 26.734598 1.000000 1.000000 1.000000 +vn 0.716044 -0.547756 -0.432716 +v -162.151794 -138.771988 26.618198 1.000000 1.000000 1.000000 +vn -0.843495 0.251611 0.474562 +v -164.310898 -140.001282 27.969599 1.000000 1.000000 1.000000 +vn -0.884502 0.147515 0.442601 +v -164.564529 -140.837082 27.853399 1.000000 1.000000 1.000000 +vn -0.880818 0.025453 0.472770 +v -164.707443 -141.696609 27.738199 1.000000 1.000000 1.000000 +vn -0.640196 -0.127115 0.757622 +v -164.500153 -142.564499 27.960199 1.000000 1.000000 1.000000 +vn -0.967241 0.206804 0.147229 +v -164.711304 -140.796616 27.385199 1.000000 1.000000 1.000000 +vn -0.985962 0.078926 0.147140 +v -164.858063 -141.678467 27.269999 1.000000 1.000000 1.000000 +vn -0.892435 -0.087571 0.442597 +v -164.735764 -142.574280 27.622398 1.000000 1.000000 1.000000 +vn -0.623001 -0.210733 0.753301 +v -164.416473 -143.407288 27.843599 1.000000 1.000000 1.000000 +vn -0.280618 -0.220793 0.934079 +v -164.040527 -144.057510 27.881798 1.000000 1.000000 1.000000 +vn -0.865550 -0.218796 0.450502 +v -164.649506 -143.451935 27.505798 1.000000 1.000000 1.000000 +vn -0.571496 -0.349838 0.742298 +v -163.973572 -144.908661 27.626198 1.000000 1.000000 1.000000 +vn -0.987734 -0.051160 0.147524 +v -164.887695 -142.579849 27.153999 1.000000 1.000000 1.000000 +vn -0.973253 -0.176028 0.147623 +v -164.798859 -143.481247 27.037399 1.000000 1.000000 1.000000 +vn -0.940989 -0.296576 0.163040 +v -164.625031 -144.254257 26.935198 1.000000 1.000000 1.000000 +vn -0.796480 -0.397632 0.455532 +v -164.187302 -145.018890 27.288399 1.000000 1.000000 1.000000 +vn -0.985583 -0.010596 -0.168859 +v -164.874802 -142.579849 26.338598 1.000000 1.000000 1.000000 +vn -0.967622 -0.143943 -0.207338 +v -164.785965 -143.478455 26.221998 1.000000 1.000000 1.000000 +vn -0.915241 -0.365551 -0.169431 +v -164.313477 -145.083084 26.004599 1.000000 1.000000 1.000000 +vn -0.897649 -0.414413 0.149960 +v -164.325058 -145.088669 26.820198 1.000000 1.000000 1.000000 +vn -0.711854 -0.509429 0.483473 +v -163.788177 -145.786331 27.172199 1.000000 1.000000 1.000000 +vn -0.832969 -0.532394 0.150731 +v -163.915634 -145.875626 26.703999 1.000000 1.000000 1.000000 +vn -0.851723 -0.494864 -0.172274 +v -163.904053 -145.868652 25.888399 1.000000 1.000000 1.000000 +vn -0.827765 -0.293474 -0.478203 +v -164.192444 -145.021683 25.611597 1.000000 1.000000 1.000000 +vn -0.892347 -0.182779 -0.412684 +v -164.484711 -144.206818 25.726599 1.000000 1.000000 1.000000 +vn -0.791133 -0.413380 -0.450806 +v -163.793335 -145.789124 25.495398 1.000000 1.000000 1.000000 +vn -0.775573 -0.606957 -0.173465 +v -163.395493 -146.584457 25.771999 1.000000 1.000000 1.000000 +vn -0.751104 -0.642497 0.151792 +v -163.405792 -146.594223 26.587399 1.000000 1.000000 1.000000 +vn -0.647685 -0.610422 0.455948 +v -163.292496 -146.485397 27.055798 1.000000 1.000000 1.000000 +vn -0.683620 -0.708687 -0.174434 +v -162.804550 -147.210968 25.656601 1.000000 1.000000 1.000000 +vn -0.653343 -0.741285 0.153751 +v -162.813553 -147.222137 26.472198 1.000000 1.000000 1.000000 +vn -0.540143 -0.684449 0.489668 +v -162.715714 -147.096542 26.940399 1.000000 1.000000 1.000000 +vn -0.726610 -0.516008 -0.453623 +v -163.296356 -146.489578 25.378798 1.000000 1.000000 1.000000 +vn -0.640578 -0.259135 -0.722848 +v -163.595062 -145.646805 25.150799 1.000000 1.000000 1.000000 +vn -0.532779 -0.323686 -0.781904 +v -163.118683 -146.319351 25.034401 1.000000 1.000000 1.000000 +vn -0.638848 -0.596437 -0.485938 +v -162.719574 -147.102142 25.263599 1.000000 1.000000 1.000000 +vn -0.574633 -0.798909 -0.177597 +v -162.140198 -147.741196 25.541199 1.000000 1.000000 1.000000 +vn -0.479929 -0.479523 -0.734660 +v -161.941925 -147.402130 24.803598 1.000000 1.000000 1.000000 +vn -0.551096 -0.695047 -0.461740 +v -162.068100 -147.619797 25.148199 1.000000 1.000000 1.000000 +vn -0.347587 -0.506830 -0.788864 +v -161.263428 -147.796997 24.688999 1.000000 1.000000 1.000000 +vn -0.444874 -0.765164 -0.465415 +v -161.361282 -148.031433 25.033398 1.000000 1.000000 1.000000 +vn -0.451919 -0.874070 -0.178244 +v -161.415344 -148.162582 25.426598 1.000000 1.000000 1.000000 +vn -0.539634 -0.827383 0.155669 +v -162.146637 -147.753754 26.356798 1.000000 1.000000 1.000000 +vn -0.411784 -0.897774 0.156320 +v -161.420502 -148.175140 26.242199 1.000000 1.000000 1.000000 +vn -0.274372 -0.948620 0.157605 +v -160.637711 -148.486298 26.125998 1.000000 1.000000 1.000000 +vn -0.317133 -0.931255 -0.179416 +v -160.635132 -148.473740 25.310398 1.000000 1.000000 1.000000 +vn -0.324740 -0.804676 -0.497032 +v -160.597794 -148.335602 24.917398 1.000000 1.000000 1.000000 +vn -0.174040 -0.967997 -0.180811 +v -159.827881 -148.660721 25.195198 1.000000 1.000000 1.000000 +vn -0.201629 -0.860857 0.467194 +v -160.596512 -148.328629 26.594198 1.000000 1.000000 1.000000 +vn -0.062619 -0.864787 0.498220 +v -159.808578 -148.512817 26.478998 1.000000 1.000000 1.000000 +vn -0.128894 -0.979068 0.157521 +v -159.830460 -148.674683 26.010799 1.000000 1.000000 1.000000 +vn -0.317481 -0.808683 0.495214 +v -161.358704 -148.025833 26.710398 1.000000 1.000000 1.000000 +vn -0.084783 -0.620132 0.779903 +v -160.530853 -148.083054 26.931999 1.000000 1.000000 1.000000 +vn 0.067641 -0.880179 0.469798 +v -159.000031 -148.574219 26.363199 1.000000 1.000000 1.000000 +vn 0.116939 -0.618946 0.776679 +v -159.000031 -148.317459 26.700998 1.000000 1.000000 1.000000 +vn -0.024442 -0.983123 -0.181305 +v -159.000031 -148.724899 25.079399 1.000000 1.000000 1.000000 +vn 0.022567 -0.987105 0.158474 +v -159.000031 -148.738861 25.894798 1.000000 1.000000 1.000000 +vn 0.218772 -0.852522 0.474705 +v -158.187637 -148.510025 26.246599 1.000000 1.000000 1.000000 +vn 0.214468 -0.602877 0.768468 +v -158.221100 -148.256073 26.584398 1.000000 1.000000 1.000000 +vn 0.094679 -0.342538 0.934721 +v -159.744202 -148.018875 26.957399 1.000000 1.000000 1.000000 +vn 0.366740 -0.550393 0.750046 +v -156.821625 -147.827713 26.366999 1.000000 1.000000 1.000000 +vn -0.042887 -0.313223 0.948711 +v -161.819611 -147.192825 27.303398 1.000000 1.000000 1.000000 +vn 0.509339 -0.389997 0.767122 +v -155.495514 -146.945862 26.134399 1.000000 1.000000 1.000000 +vn 0.537275 -0.686946 0.489326 +v -156.006638 -147.657471 25.912998 1.000000 1.000000 1.000000 +vn 0.638598 -0.620074 0.455743 +v -155.344879 -147.143997 25.796598 1.000000 1.000000 1.000000 +vn 0.710938 -0.512697 0.481362 +v -154.760361 -146.539810 25.681198 1.000000 1.000000 1.000000 +vn 0.416578 -0.777506 0.471112 +v -156.727631 -148.063522 26.029198 1.000000 1.000000 1.000000 +vn 0.437368 -0.885650 0.155991 +v -156.667114 -148.214218 25.560999 1.000000 1.000000 1.000000 +vn 0.563664 -0.811386 0.154713 +v -155.926819 -147.796997 25.444799 1.000000 1.000000 1.000000 +vn 0.674693 -0.722106 0.152815 +v -155.247025 -147.269577 25.328199 1.000000 1.000000 1.000000 +vn 0.523798 -0.832950 -0.178412 +v -155.933258 -147.785843 24.629198 1.000000 1.000000 1.000000 +vn 0.307493 -0.936038 0.171119 +v -157.447327 -148.510025 25.675999 1.000000 1.000000 1.000000 +vn 0.383121 -0.906415 -0.177848 +v -156.672272 -148.201645 24.745398 1.000000 1.000000 1.000000 +vn 0.304384 -0.811630 -0.498605 +v -156.725067 -148.069092 24.352398 1.000000 1.000000 1.000000 +vn 0.434879 -0.770397 -0.466228 +v -156.002777 -147.663055 24.236198 1.000000 1.000000 1.000000 +vn 0.639556 -0.747991 -0.177421 +v -155.256042 -147.259811 24.512798 1.000000 1.000000 1.000000 +vn 0.737987 -0.651741 -0.174954 +v -154.658646 -146.640274 24.397398 1.000000 1.000000 1.000000 +vn 0.769068 -0.621154 0.150672 +v -154.648346 -146.650040 25.212999 1.000000 1.000000 1.000000 +vn 0.543217 -0.700236 -0.463233 +v -155.341019 -147.148178 24.119598 1.000000 1.000000 1.000000 +vn 0.265948 -0.616745 -0.740876 +v -156.127670 -147.443985 23.891598 1.000000 1.000000 1.000000 +vn 0.339551 -0.509434 -0.790685 +v -155.491653 -146.950043 23.775198 1.000000 1.000000 1.000000 +vn 0.624310 -0.610045 -0.487937 +v -154.756500 -146.544006 24.004398 1.000000 1.000000 1.000000 +vn 0.821215 -0.543757 -0.173017 +v -154.146225 -145.938431 24.281998 1.000000 1.000000 1.000000 +vn 0.499171 -0.459039 -0.734923 +v -154.452652 -145.712387 23.544399 1.000000 1.000000 1.000000 +vn 0.719764 -0.524188 -0.455155 +v -154.255661 -145.857498 23.888998 1.000000 1.000000 1.000000 +vn 0.018271 -0.296689 -0.954799 +v -156.256409 -147.216553 23.740599 1.000000 1.000000 1.000000 +vn 0.144397 -0.273534 -0.950962 +v -154.656082 -145.563080 23.393398 1.000000 1.000000 1.000000 +vn 0.527061 -0.331219 -0.782624 +v -154.065125 -144.990997 23.429798 1.000000 1.000000 1.000000 +vn 0.785756 -0.422236 -0.452000 +v -153.852692 -145.105408 23.774199 1.000000 1.000000 1.000000 +vn -0.073444 -0.300795 -0.950857 +v -157.613419 -147.852814 23.971998 1.000000 1.000000 1.000000 +vn -0.227983 -0.627478 -0.744510 +v -159.776382 -148.264450 24.457598 1.000000 1.000000 1.000000 +vn -0.079764 -0.607914 -0.789986 +v -159.000031 -148.323059 24.341799 1.000000 1.000000 1.000000 +vn -0.198943 -0.860129 -0.469681 +v -159.809860 -148.518402 24.802198 1.000000 1.000000 1.000000 +vn -0.050443 -0.875623 -0.480354 +v -159.000031 -148.581192 24.686199 1.000000 1.000000 1.000000 +vn 0.176666 -0.881349 -0.438192 +v -157.485962 -148.357925 24.467398 1.000000 1.000000 1.000000 +vn 0.133892 -0.966190 -0.220339 +v -158.167038 -148.659332 24.962799 1.000000 1.000000 1.000000 +vn 0.064356 -0.663312 -0.745570 +v -157.549042 -148.110962 24.122999 1.000000 1.000000 1.000000 +vn 0.169652 -0.972723 0.158200 +v -158.165741 -148.673279 25.778198 1.000000 1.000000 1.000000 +vn 0.847018 -0.509976 0.149947 +v -154.135941 -145.946793 25.097601 1.000000 1.000000 1.000000 +vn 0.786865 -0.424161 0.448253 +v -154.260818 -145.853302 25.565798 1.000000 1.000000 1.000000 +vn -0.210939 -0.292299 0.932773 +v -163.404510 -145.510056 27.650599 1.000000 1.000000 1.000000 +vn -0.406960 -0.484970 0.774072 +v -163.114822 -146.315170 27.393599 1.000000 1.000000 1.000000 +vn -0.284080 -0.604973 0.743845 +v -161.939346 -147.397949 27.162798 1.000000 1.000000 1.000000 +vn -0.446608 -0.765579 0.463065 +v -162.065521 -147.614227 26.824999 1.000000 1.000000 1.000000 +vn -0.688562 -0.078815 -0.720882 +v -164.259399 -144.131470 25.382198 1.000000 1.000000 1.000000 +vn -0.633587 0.052011 -0.771921 +v -164.505310 -142.565903 25.600998 1.000000 1.000000 1.000000 +vn -0.892082 0.015917 -0.451594 +v -164.742203 -142.574280 25.945398 1.000000 1.000000 1.000000 +vn -0.883238 0.146063 -0.445596 +v -164.712585 -141.695221 26.061398 1.000000 1.000000 1.000000 +vn -0.978248 0.119096 -0.169844 +v -164.845200 -141.679871 26.454399 1.000000 1.000000 1.000000 +vn -0.954272 0.245688 -0.170304 +v -164.698425 -140.800797 26.569599 1.000000 1.000000 1.000000 +vn -0.087015 -0.729844 -0.678053 +v -158.262314 -137.212006 41.488579 1.000000 1.000000 1.000000 +vn -0.243280 -0.846482 -0.473585 +v -157.650757 -137.629211 41.876179 1.000000 1.000000 1.000000 +vn 0.025623 -0.910457 -0.412809 +v -158.939514 -137.408737 41.770180 1.000000 1.000000 1.000000 +vn -0.200073 -0.564522 -0.800803 +v -156.928482 -137.659897 41.592178 1.000000 1.000000 1.000000 +vn 0.243410 -0.697104 -0.674387 +v -160.318420 -137.348740 41.319378 1.000000 1.000000 1.000000 +vn -0.508440 -0.730502 -0.455911 +v -156.448242 -138.254318 41.975777 1.000000 1.000000 1.000000 +vn -0.602941 -0.293004 -0.742031 +v -154.595551 -140.283142 41.808979 1.000000 1.000000 1.000000 +vn -0.718159 -0.575321 -0.391476 +v -155.507095 -139.169662 42.061977 1.000000 1.000000 1.000000 +vn -0.285927 -0.933193 -0.217707 +v -157.691956 -137.772934 42.273579 1.000000 1.000000 1.000000 +vn -0.745654 -0.635011 -0.201893 +v -155.613953 -139.267334 42.459377 1.000000 1.000000 1.000000 +vn -0.458195 -0.888488 -0.025409 +v -157.113876 -138.078506 42.779179 1.000000 1.000000 1.000000 +vn -0.774971 -0.311676 -0.549798 +v -154.814438 -140.384995 42.143780 1.000000 1.000000 1.000000 +vn -0.857276 -0.482532 -0.179558 +v -155.236725 -139.833847 42.501778 1.000000 1.000000 1.000000 +vn -0.639509 -0.762341 0.099319 +v -156.098053 -138.808273 42.869778 1.000000 1.000000 1.000000 +vn -0.315790 -0.944244 -0.093167 +v -157.707397 -137.825958 42.728378 1.000000 1.000000 1.000000 +vn -0.898091 -0.174241 -0.403823 +v -154.484833 -141.631027 42.210381 1.000000 1.000000 1.000000 +vn -0.751652 -0.151723 -0.641872 +v -154.249222 -141.593353 41.875580 1.000000 1.000000 1.000000 +vn -0.926404 0.028482 -0.375452 +v -154.435913 -142.359390 42.244579 1.000000 1.000000 1.000000 +vn -0.765359 0.138300 -0.628569 +v -154.357376 -143.696121 41.964779 1.000000 1.000000 1.000000 +vn -0.971620 0.045176 -0.232194 +v -154.574966 -142.359390 42.642178 1.000000 1.000000 1.000000 +vn -0.866696 0.185055 -0.463241 +v -154.587845 -143.630539 42.299580 1.000000 1.000000 1.000000 +vn -0.945694 0.208435 -0.249436 +v -154.721741 -143.591461 42.696980 1.000000 1.000000 1.000000 +vn -0.163065 -0.986365 0.022234 +v -158.327972 -137.671066 42.675579 1.000000 1.000000 1.000000 +vn 0.114064 -0.993473 -0.000097 +v -159.579407 -137.654327 42.565578 1.000000 1.000000 1.000000 +vn -0.020019 -0.965142 -0.260961 +v -158.942108 -137.559448 42.167778 1.000000 1.000000 1.000000 +vn 0.333304 -0.942008 0.039118 +v -160.201248 -137.795258 42.506378 1.000000 1.000000 1.000000 +vn 0.101738 -0.959271 -0.263531 +v -159.585846 -137.599899 42.110779 1.000000 1.000000 1.000000 +vn 0.559400 -0.826845 0.058294 +v -161.357422 -138.357574 42.381977 1.000000 1.000000 1.000000 +vn 0.554976 -0.802129 -0.220434 +v -161.384445 -138.310135 41.927177 1.000000 1.000000 1.000000 +vn 0.155674 -0.908401 -0.388037 +v -159.603867 -137.450607 41.713379 1.000000 1.000000 1.000000 +vn 0.375842 -0.738711 -0.559507 +v -160.877182 -137.842697 41.592979 1.000000 1.000000 1.000000 +vn 0.438399 -0.520368 -0.732819 +v -161.586578 -137.965485 41.194977 1.000000 1.000000 1.000000 +vn 0.632221 -0.644538 -0.429961 +v -161.975403 -138.598969 41.466179 1.000000 1.000000 1.000000 +vn 0.789352 -0.608320 -0.082883 +v -162.301132 -139.238037 42.250977 1.000000 1.000000 1.000000 +vn 0.735123 -0.505022 -0.452268 +v -162.444046 -139.102692 41.398579 1.000000 1.000000 1.000000 +vn 0.767623 -0.597430 -0.232019 +v -162.339767 -139.201752 41.796181 1.000000 1.000000 1.000000 +vn 0.864557 -0.501820 -0.026799 +v -162.680954 -139.787796 42.180977 1.000000 1.000000 1.000000 +vn 0.929998 -0.366870 0.022578 +v -162.986084 -140.393356 42.108978 1.000000 1.000000 1.000000 +vn 0.652261 0.087287 0.752952 +v -153.506363 -142.358002 20.276600 1.000000 1.000000 1.000000 +vn 0.874030 -0.184907 0.449312 +v -153.573303 -144.358902 20.197399 1.000000 1.000000 1.000000 +vn 0.634457 0.260153 0.727863 +v -153.712357 -140.738007 20.067600 1.000000 1.000000 1.000000 +vn 0.890961 0.032764 0.452896 +v -153.269455 -142.358002 19.938795 1.000000 1.000000 1.000000 +vn 0.865140 0.167490 0.472736 +v -153.323532 -141.502655 19.833000 1.000000 1.000000 1.000000 +vn 0.539459 0.412137 0.734253 +v -154.331635 -139.218491 19.863598 1.000000 1.000000 1.000000 +vn 0.851145 0.276654 0.446111 +v -153.484467 -140.668259 19.729797 1.000000 1.000000 1.000000 +vn 0.790812 0.381872 0.478320 +v -153.752258 -139.858963 19.627800 1.000000 1.000000 1.000000 +vn 0.982521 0.141654 0.120779 +v -153.172897 -141.480331 19.364799 1.000000 1.000000 1.000000 +vn 0.988928 0.017325 0.147378 +v -153.117538 -142.358002 19.470398 1.000000 1.000000 1.000000 +vn 0.973953 -0.108311 0.199211 +v -153.174179 -143.242630 19.578800 1.000000 1.000000 1.000000 +vn 0.985657 -0.001895 -0.168749 +v -153.130417 -142.358002 18.654999 1.000000 1.000000 1.000000 +vn 0.962911 0.212564 -0.166192 +v -153.350571 -140.627792 18.445999 1.000000 1.000000 1.000000 +vn 0.952342 0.266412 0.148557 +v -153.337692 -140.623596 19.261597 1.000000 1.000000 1.000000 +vn 0.912825 0.370975 -0.170672 +v -153.624802 -139.798950 18.343998 1.000000 1.000000 1.000000 +vn 0.909091 0.388968 0.149186 +v -153.613220 -139.793365 19.159397 1.000000 1.000000 1.000000 +vn 0.877746 0.174476 -0.446230 +v -153.478027 -140.666855 18.052998 1.000000 1.000000 1.000000 +vn 0.895060 0.040915 -0.444066 +v -153.317093 -141.501266 18.155998 1.000000 1.000000 1.000000 +vn 0.681442 0.072355 -0.728287 +v -153.707199 -140.736618 17.708397 1.000000 1.000000 1.000000 +vn 0.832838 0.278195 -0.478528 +v -153.747116 -139.856171 17.950798 1.000000 1.000000 1.000000 +vn 0.857030 -0.046693 -0.513147 +v -153.263016 -142.358002 18.261799 1.000000 1.000000 1.000000 +vn 0.869779 -0.196726 -0.452530 +v -153.318375 -143.220306 18.370197 1.000000 1.000000 1.000000 +vn 0.972856 -0.151671 -0.174776 +v -153.185776 -143.241241 18.763199 1.000000 1.000000 1.000000 +vn 0.945636 -0.258741 0.197040 +v -153.429108 -144.411926 19.729000 1.000000 1.000000 1.000000 +vn 0.632802 0.259920 -0.729385 +v -154.326477 -139.215714 17.504398 1.000000 1.000000 1.000000 +vn 0.819017 0.440152 -0.368073 +v -154.124344 -139.080368 17.848797 1.000000 1.000000 1.000000 +vn 0.546599 0.409813 -0.730262 +v -155.288223 -137.957123 17.311398 1.000000 1.000000 1.000000 +vn 0.766260 0.502346 -0.400617 +v -154.587845 -138.382690 17.750999 1.000000 1.000000 1.000000 +vn 0.848773 0.517036 0.110717 +v -154.000748 -138.996628 19.057400 1.000000 1.000000 1.000000 +vn 0.720561 0.672052 -0.170701 +v -155.038452 -137.661301 18.049000 1.000000 1.000000 1.000000 +vn 0.788815 0.604620 0.110480 +v -154.475830 -138.282227 18.959599 1.000000 1.000000 1.000000 +vn 0.661852 0.593947 -0.457360 +v -155.127289 -137.767349 17.655998 1.000000 1.000000 1.000000 +vn 0.747036 0.487573 0.451896 +v -154.129486 -139.083145 19.525799 1.000000 1.000000 1.000000 +vn 0.660606 0.574547 0.483213 +v -154.591690 -138.386871 19.427799 1.000000 1.000000 1.000000 +vn 0.683213 0.714170 0.152257 +v -155.029449 -137.651535 18.864597 1.000000 1.000000 1.000000 +vn 0.587576 0.666767 0.458451 +v -155.131149 -137.771530 19.332798 1.000000 1.000000 1.000000 +vn 0.610423 0.770297 -0.184461 +v -155.670609 -137.115723 17.955200 1.000000 1.000000 1.000000 +vn 0.562434 0.683278 -0.465618 +v -155.746567 -137.234329 17.562199 1.000000 1.000000 1.000000 +vn 0.453873 0.860296 -0.232140 +v -156.377441 -136.665039 17.862198 1.000000 1.000000 1.000000 +vn 0.458087 0.888769 -0.015682 +v -156.356842 -136.618988 18.267799 1.000000 1.000000 1.000000 +vn 0.576816 0.800915 0.160680 +v -155.664169 -137.104568 18.770798 1.000000 1.000000 1.000000 +vn 0.475433 0.730573 0.490130 +v -155.749146 -137.238525 19.238998 1.000000 1.000000 1.000000 +vn 0.405658 0.534974 0.741110 +v -155.292084 -137.961304 19.670597 1.000000 1.000000 1.000000 +vn 0.370998 0.808967 0.455997 +v -156.439240 -136.798981 19.146000 1.000000 1.000000 1.000000 +vn 0.240234 0.607945 0.756763 +v -156.546097 -137.027832 19.483797 1.000000 1.000000 1.000000 +vn 0.371577 0.909494 0.186418 +v -156.737930 -136.471085 18.632999 1.000000 1.000000 1.000000 +vn 0.097993 0.645316 0.757604 +v -157.604401 -136.595261 19.349998 1.000000 1.000000 1.000000 +vn 0.201865 0.858353 0.471678 +v -157.545181 -136.348297 19.012199 1.000000 1.000000 1.000000 +vn -0.111117 0.617496 0.778686 +v -159.091446 -136.398529 19.179199 1.000000 1.000000 1.000000 +vn 0.061744 0.865798 0.496570 +v -158.312515 -136.187820 18.925999 1.000000 1.000000 1.000000 +vn -0.356891 0.523823 0.773459 +v -161.313629 -136.951080 18.933399 1.000000 1.000000 1.000000 +vn -0.537134 0.663433 0.520907 +v -162.098999 -137.125504 18.518997 1.000000 1.000000 1.000000 +vn -0.768578 0.425316 0.477906 +v -163.776596 -138.917099 18.298798 1.000000 1.000000 1.000000 +vn -0.600500 0.605205 0.522615 +v -162.722137 -137.623642 18.445000 1.000000 1.000000 1.000000 +vn -0.714018 0.534054 0.452730 +v -163.283478 -138.220825 18.371799 1.000000 1.000000 1.000000 +vn -0.772668 0.616427 0.151667 +v -163.396790 -138.112000 17.903599 1.000000 1.000000 1.000000 +vn -0.848689 0.507163 0.150045 +v -163.902756 -138.826416 17.830597 1.000000 1.000000 1.000000 +vn -0.679951 0.717295 0.152165 +v -162.819992 -137.499451 17.976597 1.000000 1.000000 1.000000 +vn -0.574192 0.807210 0.136804 +v -162.181396 -136.987366 18.050598 1.000000 1.000000 1.000000 +vn -0.634366 0.750823 -0.183971 +v -162.810974 -137.509216 17.161198 1.000000 1.000000 1.000000 +vn -0.453657 0.877414 0.156014 +v -161.477142 -136.570145 18.127399 1.000000 1.000000 1.000000 +vn -0.443796 0.876033 -0.188711 +v -161.472000 -136.582718 17.311798 1.000000 1.000000 1.000000 +vn -0.752110 0.635488 -0.174600 +v -163.387772 -138.120361 17.087997 1.000000 1.000000 1.000000 +vn -0.549283 0.687766 -0.474621 +v -162.725998 -137.619446 16.767998 1.000000 1.000000 1.000000 +vn -0.826802 0.519875 -0.214778 +v -163.892456 -138.833389 17.014999 1.000000 1.000000 1.000000 +vn -0.654150 0.576308 -0.489855 +v -163.288635 -138.216644 16.695000 1.000000 1.000000 1.000000 +vn -0.472165 0.284255 -0.834422 +v -163.770157 -139.239426 16.326797 1.000000 1.000000 1.000000 +vn -0.288963 0.331239 -0.898210 +v -162.760773 -138.112000 16.326797 1.000000 1.000000 1.000000 +vn -0.328917 0.618222 -0.713874 +v -161.974121 -137.336197 16.497597 1.000000 1.000000 1.000000 +vn -0.070119 0.252800 -0.964974 +v -161.841507 -137.560837 16.346600 1.000000 1.000000 1.000000 +vn -0.367808 0.790395 -0.489891 +v -161.415344 -136.713882 16.918800 1.000000 1.000000 1.000000 +vn -0.120330 0.646437 -0.753419 +v -160.591370 -136.648285 16.655399 1.000000 1.000000 1.000000 +vn 0.025912 0.292840 -0.955810 +v -160.520554 -136.903641 16.504398 1.000000 1.000000 1.000000 +vn -0.230286 0.851569 -0.470954 +v -160.659607 -136.402710 16.999798 1.000000 1.000000 1.000000 +vn -0.289310 0.939892 -0.181392 +v -160.698227 -136.264572 17.392998 1.000000 1.000000 1.000000 +vn -0.095003 0.860356 -0.500761 +v -159.885818 -136.210159 17.081200 1.000000 1.000000 1.000000 +vn 0.051033 0.602379 -0.796577 +v -159.091446 -136.392944 16.820000 1.000000 1.000000 1.000000 +vn 0.151665 0.246941 -0.957088 +v -158.370468 -136.701309 16.753597 1.000000 1.000000 1.000000 +vn -0.146542 0.972383 -0.181649 +v -159.906418 -136.067825 17.474400 1.000000 1.000000 1.000000 +vn 0.033967 0.880688 -0.472477 +v -159.095306 -136.136200 17.164600 1.000000 1.000000 1.000000 +vn -0.321884 0.933719 0.156717 +v -160.702087 -136.250626 18.208397 1.000000 1.000000 1.000000 +vn -0.180228 0.970825 0.158167 +v -159.907715 -136.053879 18.289799 1.000000 1.000000 1.000000 +vn -0.034077 0.986937 0.157462 +v -159.097885 -135.978531 18.373199 1.000000 1.000000 1.000000 +vn 0.001270 0.983374 -0.181586 +v -159.096588 -135.992477 17.557598 1.000000 1.000000 1.000000 +vn 0.165610 0.866324 -0.471229 +v -158.311234 -136.180847 17.248997 1.000000 1.000000 1.000000 +vn 0.182798 0.642097 -0.744511 +v -158.340851 -136.436203 16.904598 1.000000 1.000000 1.000000 +vn 0.228200 0.206428 -0.951479 +v -156.979980 -137.100388 16.928799 1.000000 1.000000 1.000000 +vn 0.357596 0.566638 -0.742325 +v -156.884705 -136.853409 17.079800 1.000000 1.000000 1.000000 +vn 0.307481 0.854698 -0.418266 +v -157.543884 -136.341309 17.335400 1.000000 1.000000 1.000000 +vn 0.169631 0.969522 -0.176783 +v -158.295776 -136.038528 17.642197 1.000000 1.000000 1.000000 +vn 0.113217 0.980943 0.157904 +v -158.294495 -136.024582 18.457600 1.000000 1.000000 1.000000 +vn 0.265555 0.956435 0.121296 +v -157.506561 -136.189224 18.543999 1.000000 1.000000 1.000000 +vn 0.408608 0.800861 -0.437792 +v -156.794571 -136.616211 17.424400 1.000000 1.000000 1.000000 +vn -0.065279 0.880747 0.469067 +v -159.095306 -136.141785 18.841400 1.000000 1.000000 1.000000 +vn -0.210922 0.820783 0.530874 +v -159.884537 -136.217133 18.758198 1.000000 1.000000 1.000000 +vn -0.297340 0.792055 0.533140 +v -160.658310 -136.408295 18.676800 1.000000 1.000000 1.000000 +vn -0.434780 0.772289 0.463181 +v -161.412781 -136.719452 18.595798 1.000000 1.000000 1.000000 +vn 0.427667 0.459483 -0.778445 +v -155.880463 -137.445023 17.217598 1.000000 1.000000 1.000000 +vn -0.208657 -0.177478 0.961750 +v -157.896667 -137.033401 39.899178 1.000000 1.000000 1.000000 +vn -0.113936 -0.242797 0.963363 +v -160.008133 -137.009689 39.553177 1.000000 1.000000 1.000000 +vn -0.264479 -0.092393 0.959955 +v -155.974457 -137.997574 40.246380 1.000000 1.000000 1.000000 +vn -0.513082 -0.461038 0.724010 +v -156.123810 -138.211060 40.091778 1.000000 1.000000 1.000000 +vn -0.641030 -0.263450 0.720885 +v -155.171066 -139.245010 40.323177 1.000000 1.000000 1.000000 +vn -0.699594 -0.053001 0.712572 +v -154.345795 -141.149628 40.657780 1.000000 1.000000 1.000000 +vn -0.803079 -0.401722 0.440096 +v -155.360321 -139.398499 39.975380 1.000000 1.000000 1.000000 +vn -0.721446 -0.558289 0.409669 +v -155.778763 -138.873856 39.860378 1.000000 1.000000 1.000000 +vn -0.904075 0.251427 0.345589 +v -154.529907 -143.277527 40.656178 1.000000 1.000000 1.000000 +vn -0.910300 0.098489 0.402061 +v -154.455231 -142.592407 40.541378 1.000000 1.000000 1.000000 +vn -0.918610 -0.001145 0.395164 +v -154.470673 -141.893356 40.425377 1.000000 1.000000 1.000000 +vn -0.997315 0.048661 0.054722 +v -154.631607 -142.582642 39.717178 1.000000 1.000000 1.000000 +vn -0.980474 -0.193548 0.034781 +v -154.747482 -141.254288 39.485779 1.000000 1.000000 1.000000 +vn -0.904804 -0.138482 0.402681 +v -154.574966 -141.209641 40.310181 1.000000 1.000000 1.000000 +vn -0.863633 -0.502523 -0.040113 +v -155.201965 -140.006851 39.253380 1.000000 1.000000 1.000000 +vn -0.964010 -0.166462 -0.207306 +v -154.697266 -141.241730 39.030979 1.000000 1.000000 1.000000 +vn -0.831334 -0.389284 -0.396664 +v -154.755203 -140.538483 38.517578 1.000000 1.000000 1.000000 +vn -0.895984 -0.325356 0.302253 +v -154.768082 -140.544067 40.194180 1.000000 1.000000 1.000000 +vn -0.744112 -0.667250 0.032782 +v -155.903641 -139.009201 39.035980 1.000000 1.000000 1.000000 +vn -0.626384 -0.779497 0.005248 +v -156.371002 -138.568268 38.919777 1.000000 1.000000 1.000000 +vn -0.769643 -0.594208 -0.233595 +v -155.460754 -139.479416 38.696381 1.000000 1.000000 1.000000 +vn -0.614913 -0.754893 -0.228075 +v -156.340103 -138.523621 38.464981 1.000000 1.000000 1.000000 +vn -0.675161 -0.573860 -0.463511 +v -155.350037 -139.388733 38.298779 1.000000 1.000000 1.000000 +vn -0.512011 -0.726650 -0.458067 +v -156.256409 -138.403625 38.067581 1.000000 1.000000 1.000000 +vn -0.358627 -0.819756 -0.446527 +v -156.802307 -138.021301 37.950981 1.000000 1.000000 1.000000 +vn -0.494267 -0.869255 0.009851 +v -156.893723 -138.202682 38.803379 1.000000 1.000000 1.000000 +vn -0.634787 -0.634942 0.440334 +v -156.265427 -138.414780 39.744179 1.000000 1.000000 1.000000 +vn -0.507335 -0.793205 0.336804 +v -156.808746 -138.033859 39.627579 1.000000 1.000000 1.000000 +vn -0.251782 -0.966499 0.049847 +v -158.042145 -137.729675 38.572578 1.000000 1.000000 1.000000 +vn -0.218842 -0.945907 -0.239518 +v -158.030563 -137.675262 38.117779 1.000000 1.000000 1.000000 +vn -0.282563 -0.623961 0.728581 +v -157.950729 -137.292938 39.744579 1.000000 1.000000 1.000000 +vn -0.446587 -0.817404 0.363883 +v -157.389404 -137.743637 39.512379 1.000000 1.000000 1.000000 +vn -0.280211 -0.859867 0.426744 +v -158.003525 -137.542694 39.396980 1.000000 1.000000 1.000000 +vn -0.138993 -0.917352 0.373023 +v -158.633102 -137.439438 39.282181 1.000000 1.000000 1.000000 +vn -0.017614 -0.938066 0.346009 +v -159.278122 -137.432480 39.166176 1.000000 1.000000 1.000000 +vn 0.020255 -0.678730 0.734109 +v -159.959198 -137.270599 39.398579 1.000000 1.000000 1.000000 +vn 0.087488 -0.994845 0.051270 +v -159.266541 -137.623642 38.341778 1.000000 1.000000 1.000000 +vn 0.355448 -0.934658 -0.008449 +v -160.472916 -137.888748 38.110779 1.000000 1.000000 1.000000 +vn 0.102560 -0.882946 0.458135 +v -159.911575 -137.521774 39.050980 1.000000 1.000000 1.000000 +vn -0.090371 -0.951343 -0.294585 +v -158.642120 -137.574799 38.003178 1.000000 1.000000 1.000000 +vn 0.016029 -0.894885 -0.446009 +v -158.631821 -137.424088 37.605778 1.000000 1.000000 1.000000 +vn 0.272847 -0.871112 -0.408312 +v -159.914154 -137.507828 37.374378 1.000000 1.000000 1.000000 +vn 0.526911 -0.849896 0.006395 +v -161.041977 -138.160828 37.994179 1.000000 1.000000 1.000000 +vn 0.337022 -0.884265 0.323252 +v -160.532135 -137.708740 38.934978 1.000000 1.000000 1.000000 +vn 0.700814 -0.712591 0.032777 +v -161.987000 -138.885010 37.776779 1.000000 1.000000 1.000000 +vn 0.615031 -0.750984 -0.240333 +v -161.537659 -138.421768 37.437180 1.000000 1.000000 1.000000 +vn 0.424332 -0.782241 0.456115 +v -161.609756 -138.310135 38.716179 1.000000 1.000000 1.000000 +vn 0.782575 -0.581195 -0.223135 +v -162.449203 -139.342682 37.205780 1.000000 1.000000 1.000000 +vn 0.806658 -0.590996 0.005143 +v -162.409286 -139.377563 37.660576 1.000000 1.000000 1.000000 +vn 0.587400 -0.694431 0.415605 +v -162.106735 -138.745468 38.601181 1.000000 1.000000 1.000000 +vn 0.269968 -0.616887 0.739302 +v -161.743652 -138.100830 39.063980 1.000000 1.000000 1.000000 +vn 0.664086 -0.604158 0.440435 +v -162.547043 -139.257568 38.484978 1.000000 1.000000 1.000000 +vn 0.482587 -0.489842 0.726061 +v -162.729858 -139.095703 38.832581 1.000000 1.000000 1.000000 +vn -0.001063 -0.272511 0.962152 +v -161.885284 -137.881775 39.218578 1.000000 1.000000 1.000000 +vn 0.091252 -0.252421 0.963305 +v -162.921707 -138.928268 38.987179 1.000000 1.000000 1.000000 +vn 0.813511 -0.480155 0.328102 +v -162.915268 -139.832443 38.368378 1.000000 1.000000 1.000000 +vn 0.750752 -0.486635 -0.446719 +v -162.557343 -139.247787 36.808380 1.000000 1.000000 1.000000 +vn 0.600577 -0.648705 -0.467428 +v -161.617477 -138.298965 37.039581 1.000000 1.000000 1.000000 +vn 0.355268 -0.737333 -0.574565 +v -160.535995 -137.694794 37.258377 1.000000 1.000000 1.000000 +vn 0.431111 -0.583701 -0.688067 +v -161.241531 -137.749207 36.807178 1.000000 1.000000 1.000000 +vn 0.150286 -0.713807 -0.684027 +v -159.292297 -137.160385 37.154778 1.000000 1.000000 1.000000 +vn -0.033863 -0.658256 -0.752032 +v -157.948166 -137.277588 37.385578 1.000000 1.000000 1.000000 +vn -0.251503 -0.705998 -0.662052 +v -156.687714 -137.795258 37.616379 1.000000 1.000000 1.000000 +vn -0.153382 -0.858372 -0.489562 +v -157.999664 -137.528748 37.720379 1.000000 1.000000 1.000000 +vn -0.412044 -0.544224 -0.730780 +v -155.599808 -138.681290 37.848976 1.000000 1.000000 1.000000 +vn -0.607431 -0.417629 -0.675732 +v -154.829895 -139.776627 38.066376 1.000000 1.000000 1.000000 +vn -0.633440 -0.252906 -0.731295 +v -154.330338 -141.146851 38.298779 1.000000 1.000000 1.000000 +vn -0.674765 -0.088918 -0.732657 +v -154.204178 -142.604980 38.530178 1.000000 1.000000 1.000000 +vn -0.853667 -0.236569 -0.463992 +v -154.562088 -141.206848 38.633579 1.000000 1.000000 1.000000 +vn -0.886347 -0.039252 -0.461354 +v -154.442352 -142.592407 38.864979 1.000000 1.000000 1.000000 +vn -0.974777 0.003393 -0.223156 +v -154.580124 -142.585449 39.262379 1.000000 1.000000 1.000000 +vn -0.361689 0.095048 0.927441 +v -163.107101 -138.766403 38.983379 1.000000 1.000000 1.000000 +vn -0.329701 -0.060043 0.942174 +v -164.107468 -140.912430 38.636177 1.000000 1.000000 1.000000 +vn -0.318237 -0.185211 0.929743 +v -164.206604 -143.305435 38.290176 1.000000 1.000000 1.000000 +vn -0.687308 0.064992 0.723452 +v -164.323776 -140.851044 38.495579 1.000000 1.000000 1.000000 +vn -0.639128 -0.110051 0.761186 +v -164.500153 -142.512878 38.264778 1.000000 1.000000 1.000000 +vn -0.841049 0.258349 0.475282 +v -164.294159 -139.958023 38.273178 1.000000 1.000000 1.000000 +vn -0.882912 0.154061 0.443545 +v -164.552933 -140.785461 38.157978 1.000000 1.000000 1.000000 +vn -0.880427 0.032032 0.473098 +v -164.701004 -141.639404 38.043179 1.000000 1.000000 1.000000 +vn -0.965631 0.214132 0.147321 +v -164.699722 -140.743591 37.689579 1.000000 1.000000 1.000000 +vn -0.985335 0.086278 0.147209 +v -164.851639 -141.621262 37.574978 1.000000 1.000000 1.000000 +vn -0.892994 -0.078884 0.443101 +v -164.737061 -142.519852 37.926979 1.000000 1.000000 1.000000 +vn -0.988155 -0.042512 0.147455 +v -164.888977 -142.524033 37.458778 1.000000 1.000000 1.000000 +vn -0.858243 -0.195578 0.474518 +v -164.659805 -143.387756 37.811981 1.000000 1.000000 1.000000 +vn -0.974215 -0.170653 0.147591 +v -164.809158 -143.415649 37.343578 1.000000 1.000000 1.000000 +vn -0.839836 -0.308383 0.446739 +v -164.469254 -144.241699 37.695976 1.000000 1.000000 1.000000 +vn -0.582834 -0.283058 0.761698 +v -164.243942 -144.164948 38.033779 1.000000 1.000000 1.000000 +vn -0.951466 -0.257002 -0.169299 +v -164.601868 -144.287735 36.412178 1.000000 1.000000 1.000000 +vn -0.943159 -0.297046 0.149045 +v -164.614746 -144.291931 37.227779 1.000000 1.000000 1.000000 +vn -0.977162 -0.129573 -0.168420 +v -164.796280 -143.412872 36.528179 1.000000 1.000000 1.000000 +vn -0.896078 -0.417901 0.149678 +v -164.304459 -145.134705 37.111179 1.000000 1.000000 1.000000 +vn -0.778163 -0.431520 0.456348 +v -164.167984 -145.062149 37.579376 1.000000 1.000000 1.000000 +vn -0.899345 -0.384311 -0.208529 +v -164.292877 -145.127731 36.295578 1.000000 1.000000 1.000000 +vn -0.832649 -0.528613 0.165120 +v -163.943954 -145.826797 37.008980 1.000000 1.000000 1.000000 +vn -0.661861 -0.590613 0.461645 +v -163.333694 -146.435165 37.361977 1.000000 1.000000 1.000000 +vn -0.543467 -0.360527 0.758066 +v -163.954269 -144.950531 37.917179 1.000000 1.000000 1.000000 +vn -0.453829 -0.484257 0.748020 +v -163.154739 -146.267731 37.699776 1.000000 1.000000 1.000000 +vn -0.788615 -0.590475 -0.171538 +v -163.437988 -146.534225 36.078178 1.000000 1.000000 1.000000 +vn -0.757752 -0.634522 0.152292 +v -163.446991 -146.544006 36.893776 1.000000 1.000000 1.000000 +vn -0.546139 -0.679402 0.490047 +v -162.758194 -147.057480 37.245979 1.000000 1.000000 1.000000 +vn -0.253612 -0.574241 0.778414 +v -161.977982 -147.370026 37.467178 1.000000 1.000000 1.000000 +vn -0.206941 -0.283208 0.936466 +v -163.430267 -145.466797 37.955578 1.000000 1.000000 1.000000 +vn -0.119391 -0.336357 0.934136 +v -162.456924 -146.680740 37.724178 1.000000 1.000000 1.000000 +vn -0.660001 -0.735333 0.153894 +v -162.857330 -147.181671 36.777580 1.000000 1.000000 1.000000 +vn -0.453025 -0.761705 0.463222 +v -162.105438 -147.586319 37.129379 1.000000 1.000000 1.000000 +vn -0.689375 -0.702975 -0.174896 +v -162.848312 -147.171890 35.961979 1.000000 1.000000 1.000000 +vn -0.547013 -0.822604 0.155237 +v -162.187836 -147.724457 36.661179 1.000000 1.000000 1.000000 +vn -0.324974 -0.805398 0.495707 +v -161.398605 -148.006302 37.013977 1.000000 1.000000 1.000000 +vn -0.459567 -0.869838 -0.179389 +v -161.456543 -148.143051 35.730179 1.000000 1.000000 1.000000 +vn -0.420346 -0.893733 0.156688 +v -161.461700 -148.155609 36.545776 1.000000 1.000000 1.000000 +vn -0.581748 -0.793891 -0.176934 +v -162.180115 -147.711899 35.845581 1.000000 1.000000 1.000000 +vn -0.721440 -0.495466 -0.483774 +v -163.337555 -146.439346 35.685181 1.000000 1.000000 1.000000 +vn -0.651451 -0.605137 -0.457626 +v -162.762054 -147.063065 35.569000 1.000000 1.000000 1.000000 +vn -0.558001 -0.690048 -0.460943 +v -162.108017 -147.591904 35.452599 1.000000 1.000000 1.000000 +vn -0.546110 -0.413145 -0.728749 +v -162.606262 -146.867722 35.224396 1.000000 1.000000 1.000000 +vn -0.814280 -0.403239 -0.417549 +v -163.821640 -145.741684 35.800377 1.000000 1.000000 1.000000 +vn -0.642990 -0.249087 -0.724238 +v -163.622086 -145.602142 35.455799 1.000000 1.000000 1.000000 +vn -0.866671 -0.208087 -0.453412 +v -164.475693 -144.244492 36.019180 1.000000 1.000000 1.000000 +vn -0.625730 -0.107224 -0.772635 +v -164.249084 -144.166351 35.674576 1.000000 1.000000 1.000000 +vn -0.892562 -0.079286 -0.443900 +v -164.666245 -143.389145 36.134979 1.000000 1.000000 1.000000 +vn -0.878823 0.040902 -0.475393 +v -164.742203 -142.519852 36.250179 1.000000 1.000000 1.000000 +vn -0.881605 0.152578 -0.446646 +v -164.706146 -141.639404 36.366379 1.000000 1.000000 1.000000 +vn -0.985422 -0.002082 -0.170115 +v -164.876099 -142.524033 36.643181 1.000000 1.000000 1.000000 +vn -0.977353 0.126213 -0.169857 +v -164.838760 -141.622665 36.759377 1.000000 1.000000 1.000000 +vn -0.952442 0.253328 -0.169347 +v -164.686844 -140.747787 36.874176 1.000000 1.000000 1.000000 +vn -0.422905 -0.450183 -0.786439 +v -161.980545 -147.375626 35.107998 1.000000 1.000000 1.000000 +vn -0.325263 -0.586859 -0.741485 +v -160.577194 -148.074677 34.877396 1.000000 1.000000 1.000000 +vn -0.447414 -0.745484 -0.494039 +v -161.399902 -148.011902 35.337196 1.000000 1.000000 1.000000 +vn -0.333423 -0.818728 -0.467454 +v -160.645432 -148.321655 35.221798 1.000000 1.000000 1.000000 +vn -0.325840 -0.928297 -0.179143 +v -160.682770 -148.458405 35.614979 1.000000 1.000000 1.000000 +vn -0.187730 -0.580009 -0.792683 +v -159.826599 -148.256073 34.762596 1.000000 1.000000 1.000000 +vn -0.206556 -0.857748 -0.470748 +v -159.861359 -148.510025 35.107201 1.000000 1.000000 1.000000 +vn -0.036535 -0.663978 -0.746859 +v -158.277756 -148.271423 34.531197 1.000000 1.000000 1.000000 +vn -0.124803 -0.284510 -0.950515 +v -158.309937 -148.006302 34.380196 1.000000 1.000000 1.000000 +vn -0.078226 -0.862347 -0.500238 +v -159.050247 -148.579788 34.990997 1.000000 1.000000 1.000000 +vn -0.182235 -0.966433 -0.181103 +v -159.881958 -148.652359 35.500198 1.000000 1.000000 1.000000 +vn -0.034648 -0.982794 -0.181427 +v -159.051544 -148.723511 35.383999 1.000000 1.000000 1.000000 +vn -0.136575 -0.977981 0.157796 +v -159.883240 -148.666306 36.315781 1.000000 1.000000 1.000000 +vn 0.012261 -0.987280 0.158518 +v -159.051544 -148.737457 36.199577 1.000000 1.000000 1.000000 +vn -0.282843 -0.946155 0.157452 +v -160.686630 -148.472351 36.430378 1.000000 1.000000 1.000000 +vn 0.114875 -0.976481 -0.182453 +v -158.228836 -148.669083 35.268997 1.000000 1.000000 1.000000 +vn 0.060269 -0.879547 -0.471980 +v -158.245575 -148.525375 34.875801 1.000000 1.000000 1.000000 +vn 0.262640 -0.947636 -0.181674 +v -157.415146 -148.487701 35.153000 1.000000 1.000000 1.000000 +vn 0.162050 -0.974052 0.157993 +v -158.226257 -148.683044 36.084381 1.000000 1.000000 1.000000 +vn 0.057666 -0.880961 0.469662 +v -159.050247 -148.572815 36.667778 1.000000 1.000000 1.000000 +vn 0.191826 -0.845652 0.498072 +v -158.246857 -148.519791 36.552780 1.000000 1.000000 1.000000 +vn 0.308733 -0.938097 0.157029 +v -157.412567 -148.500259 35.968578 1.000000 1.000000 1.000000 +vn 0.320579 -0.824842 0.465688 +v -157.452484 -148.342590 36.436779 1.000000 1.000000 1.000000 +vn 0.100057 -0.617660 0.780054 +v -159.048965 -148.316071 37.005577 1.000000 1.000000 1.000000 +vn 0.292307 -0.563214 0.772882 +v -157.516861 -148.095612 36.774578 1.000000 1.000000 1.000000 +vn -0.069638 -0.864050 0.498566 +v -159.860077 -148.504440 36.783981 1.000000 1.000000 1.000000 +vn -0.097474 -0.656573 0.747937 +v -160.575912 -148.069092 37.236378 1.000000 1.000000 1.000000 +vn 0.050522 -0.313175 0.948351 +v -160.511536 -147.836075 37.376976 1.000000 1.000000 1.000000 +vn 0.379905 -0.522043 0.763638 +v -156.781708 -147.808167 36.657978 1.000000 1.000000 1.000000 +vn 0.453802 -0.757677 0.469030 +v -156.686432 -148.042587 36.320179 1.000000 1.000000 1.000000 +vn 0.508469 -0.433245 0.744149 +v -155.540573 -146.986328 36.440578 1.000000 1.000000 1.000000 +vn 0.617922 -0.634444 0.464385 +v -155.391220 -147.185852 36.102779 1.000000 1.000000 1.000000 +vn 0.706147 -0.518235 0.482482 +v -154.797699 -146.584457 35.986778 1.000000 1.000000 1.000000 +vn 0.559801 -0.811218 0.168964 +v -155.973175 -147.827713 35.749779 1.000000 1.000000 1.000000 +vn 0.666857 -0.729286 0.153117 +v -155.295959 -147.314224 35.634579 1.000000 1.000000 1.000000 +vn 0.763721 -0.627616 0.151092 +v -154.686981 -146.696091 35.518398 1.000000 1.000000 1.000000 +vn 0.783238 -0.430301 0.448753 +v -154.289139 -145.896561 35.870178 1.000000 1.000000 1.000000 +vn 0.843128 -0.516366 0.150003 +v -154.164246 -145.990051 35.402000 1.000000 1.000000 1.000000 +vn 0.622484 -0.762934 -0.174487 +v -155.303680 -147.303055 34.819000 1.000000 1.000000 1.000000 +vn 0.732587 -0.657710 -0.175311 +v -154.695984 -146.686325 34.702797 1.000000 1.000000 1.000000 +vn 0.405598 -0.887493 -0.218739 +v -156.629776 -148.180725 35.036400 1.000000 1.000000 1.000000 +vn 0.422502 -0.796177 -0.433122 +v -156.047852 -147.692352 34.541199 1.000000 1.000000 1.000000 +vn 0.522975 -0.695575 -0.492618 +v -155.387360 -147.191437 34.425999 1.000000 1.000000 1.000000 +vn 0.206295 -0.853213 -0.479030 +v -157.451187 -148.348160 34.759998 1.000000 1.000000 1.000000 +vn 0.440773 -0.883863 0.156539 +v -156.624634 -148.193283 35.851978 1.000000 1.000000 1.000000 +vn 0.101331 -0.605474 -0.789388 +v -157.515579 -148.101196 34.415398 1.000000 1.000000 1.000000 +vn 0.253716 -0.619236 -0.743085 +v -156.170151 -147.471893 34.196598 1.000000 1.000000 1.000000 +vn 0.017167 -0.306986 -0.951559 +v -156.297623 -147.243057 34.045601 1.000000 1.000000 1.000000 +vn 0.432210 -0.522812 -0.734753 +v -154.967636 -146.414230 33.965199 1.000000 1.000000 1.000000 +vn 0.103196 -0.280118 -0.954403 +v -155.147888 -146.232849 33.814198 1.000000 1.000000 1.000000 +vn 0.470378 -0.401751 -0.785710 +v -154.478409 -145.752838 33.848801 1.000000 1.000000 1.000000 +vn -0.191865 -0.174816 -0.965726 +v -154.003311 -141.823578 33.126198 1.000000 1.000000 1.000000 +vn -0.139200 -0.237994 -0.961240 +v -154.611008 -139.715225 32.791397 1.000000 1.000000 1.000000 +vn -0.056561 -0.265825 -0.962361 +v -155.463318 -138.494308 32.560196 1.000000 1.000000 1.000000 +vn 0.766737 -0.424981 -0.481150 +v -153.871994 -145.147278 34.077999 1.000000 1.000000 1.000000 +vn 0.715281 -0.530163 -0.455303 +v -154.283997 -145.899353 34.193398 1.000000 1.000000 1.000000 +vn 0.633624 -0.623051 -0.458615 +v -154.793839 -146.588654 34.309799 1.000000 1.000000 1.000000 +vn 0.817049 -0.549730 -0.173863 +v -154.174561 -145.981674 34.586399 1.000000 1.000000 1.000000 +vn -0.208886 -0.858604 0.468151 +v -160.642868 -148.314682 36.898781 1.000000 1.000000 1.000000 +vn 0.595383 -0.802768 0.032888 +v -161.522217 -138.477585 32.739998 1.000000 1.000000 1.000000 +vn 0.400641 -0.916210 0.006784 +v -160.496078 -137.898514 32.957397 1.000000 1.000000 1.000000 +vn 0.205808 -0.923687 0.323181 +v -159.933456 -137.525955 33.898201 1.000000 1.000000 1.000000 +vn 0.503637 -0.829130 -0.242679 +v -161.018814 -138.085480 32.400398 1.000000 1.000000 1.000000 +vn 0.307085 -0.833673 0.459008 +v -161.076736 -137.964096 33.679398 1.000000 1.000000 1.000000 +vn 0.719194 -0.694790 0.005085 +v -162.002441 -138.903152 32.623798 1.000000 1.000000 1.000000 +vn 0.696208 -0.681233 -0.226311 +v -162.038498 -138.862686 32.168999 1.000000 1.000000 1.000000 +vn -0.029105 -0.888134 0.458661 +v -159.296158 -137.432480 34.014198 1.000000 1.000000 1.000000 +vn -0.080335 -0.674517 0.733875 +v -159.310318 -137.177124 34.361801 1.000000 1.000000 1.000000 +vn 0.482965 -0.768410 0.419871 +v -161.623932 -138.321304 33.564400 1.000000 1.000000 1.000000 +vn 0.176696 -0.646368 0.742285 +v -161.183609 -137.736649 34.027199 1.000000 1.000000 1.000000 +vn 0.816565 -0.577170 0.009851 +v -162.423447 -139.398499 32.507401 1.000000 1.000000 1.000000 +vn 0.573403 -0.688294 0.444366 +v -162.124756 -138.763611 33.448196 1.000000 1.000000 1.000000 +vn 0.408425 -0.549052 0.729199 +v -162.285690 -138.576645 33.795799 1.000000 1.000000 1.000000 +vn -0.147927 -0.224985 0.963068 +v -159.327057 -136.910614 34.516399 1.000000 1.000000 1.000000 +vn -0.041185 -0.269543 0.962107 +v -161.295609 -137.498047 34.181599 1.000000 1.000000 1.000000 +vn -0.231868 -0.148623 0.961326 +v -157.238754 -137.245499 34.862396 1.000000 1.000000 1.000000 +vn -0.370526 -0.579789 0.725642 +v -157.325027 -137.496658 34.707798 1.000000 1.000000 1.000000 +vn -0.573197 -0.390494 0.720389 +v -155.629410 -138.674316 35.055000 1.000000 1.000000 1.000000 +vn -0.671604 -0.179358 0.718874 +v -154.815720 -139.839417 35.286400 1.000000 1.000000 1.000000 +vn -0.790584 -0.457779 0.406712 +v -155.370621 -139.381744 34.823601 1.000000 1.000000 1.000000 +vn -0.715594 -0.545027 0.436888 +v -155.795502 -138.855713 34.707397 1.000000 1.000000 1.000000 +vn -0.613928 -0.714185 0.336202 +v -156.286026 -138.399445 34.590797 1.000000 1.000000 1.000000 +vn -0.558595 -0.747052 0.360396 +v -156.825485 -138.024094 34.475601 1.000000 1.000000 1.000000 +vn -0.704387 0.049183 0.708110 +v -154.237640 -141.848709 35.620979 1.000000 1.000000 1.000000 +vn -0.941835 0.104546 0.319401 +v -154.453949 -142.567307 35.388397 1.000000 1.000000 1.000000 +vn -0.903277 -0.003899 0.429040 +v -154.471970 -141.873825 35.273399 1.000000 1.000000 1.000000 +vn -0.930781 -0.208842 0.300053 +v -154.580124 -141.185913 35.157398 1.000000 1.000000 1.000000 +vn -0.849442 -0.294403 0.437922 +v -155.022995 -139.963608 34.938599 1.000000 1.000000 1.000000 +vn -0.912972 0.208986 0.350439 +v -154.527328 -143.260773 35.504601 1.000000 1.000000 1.000000 +vn -0.998590 0.018241 0.049843 +v -154.631607 -142.558929 34.564198 1.000000 1.000000 1.000000 +vn -0.976104 -0.217145 -0.008359 +v -154.751343 -141.231964 34.333199 1.000000 1.000000 1.000000 +vn -0.924912 -0.380125 0.006553 +v -154.941895 -140.590118 34.216599 1.000000 1.000000 1.000000 +vn -0.911699 -0.151123 -0.382055 +v -154.457809 -141.872421 33.596798 1.000000 1.000000 1.000000 +vn -0.905118 0.074023 -0.418667 +v -154.514450 -143.263580 33.827999 1.000000 1.000000 1.000000 +vn -0.826790 -0.561579 0.032363 +v -155.512253 -139.497559 33.999199 1.000000 1.000000 1.000000 +vn -0.847880 -0.475264 -0.234997 +v -155.132431 -140.029190 33.659599 1.000000 1.000000 1.000000 +vn -0.727243 -0.686363 0.004968 +v -155.920380 -138.991058 33.882999 1.000000 1.000000 1.000000 +vn -0.712999 -0.663792 -0.225860 +v -155.883041 -138.951981 33.428200 1.000000 1.000000 1.000000 +vn -0.748062 -0.478834 -0.459479 +v -155.010132 -139.956635 33.262001 1.000000 1.000000 1.000000 +vn -0.797051 -0.240870 -0.553798 +v -154.567245 -141.183121 33.480797 1.000000 1.000000 1.000000 +vn -0.611176 -0.791443 0.009023 +v -156.391602 -138.552917 33.766598 1.000000 1.000000 1.000000 +vn -0.473013 -0.761537 -0.443080 +v -156.277023 -138.386871 32.914200 1.000000 1.000000 1.000000 +vn -0.609584 -0.650127 -0.453589 +v -155.785202 -138.845947 33.030800 1.000000 1.000000 1.000000 +vn -0.389915 -0.919479 0.050255 +v -157.469223 -137.915253 33.535797 1.000000 1.000000 1.000000 +vn -0.402041 -0.812055 0.423001 +v -157.407425 -137.735260 34.360199 1.000000 1.000000 1.000000 +vn -0.059723 -0.996867 0.051850 +v -158.669144 -137.629211 33.305000 1.000000 1.000000 1.000000 +vn -0.354988 -0.903776 -0.239108 +v -157.451187 -137.863632 33.081001 1.000000 1.000000 1.000000 +vn -0.228440 -0.928434 -0.292960 +v -158.044724 -137.672470 32.966400 1.000000 1.000000 1.000000 +vn -0.271691 -0.888460 0.369896 +v -158.017685 -137.539902 34.245399 1.000000 1.000000 1.000000 +vn -0.155473 -0.925668 0.344915 +v -158.656281 -137.438049 34.129196 1.000000 1.000000 1.000000 +vn 0.213473 -0.976915 -0.008144 +v -159.897415 -137.714325 33.073997 1.000000 1.000000 1.000000 +vn 0.142616 -0.900513 -0.410776 +v -159.296158 -137.418518 32.337601 1.000000 1.000000 1.000000 +vn -0.114790 -0.887776 -0.445731 +v -158.015121 -137.525955 32.568798 1.000000 1.000000 1.000000 +vn 0.342834 -0.634840 -0.692418 +v -160.641571 -137.461761 31.770399 1.000000 1.000000 1.000000 +vn 0.244535 -0.778720 -0.577753 +v -159.936035 -137.512009 32.221596 1.000000 1.000000 1.000000 +vn 0.043977 -0.726229 -0.686045 +v -158.636963 -137.165955 32.117996 1.000000 1.000000 1.000000 +vn 0.502940 -0.723346 -0.473099 +v -161.081894 -137.950134 32.002800 1.000000 1.000000 1.000000 +vn 0.677364 -0.581039 -0.451190 +v -162.133759 -138.752457 31.771599 1.000000 1.000000 1.000000 +vn -0.351854 -0.665029 -0.658738 +v -156.135391 -138.180359 32.579597 1.000000 1.000000 1.000000 +vn -0.130582 -0.646906 -0.751306 +v -157.318588 -137.479904 32.348801 1.000000 1.000000 1.000000 +vn -0.276742 -0.827257 -0.488936 +v -157.402267 -137.721313 32.683598 1.000000 1.000000 1.000000 +vn -0.486164 -0.484964 -0.726949 +v -155.169785 -139.217102 32.812199 1.000000 1.000000 1.000000 +vn -0.659804 -0.330526 -0.674842 +v -154.545349 -140.417099 33.029598 1.000000 1.000000 1.000000 +vn -0.752976 -0.060786 -0.655235 +v -154.202881 -142.578461 33.377197 1.000000 1.000000 1.000000 +vn -0.679421 0.094878 -0.727589 +v -154.447495 -144.015656 33.607998 1.000000 1.000000 1.000000 +vn -0.947470 0.166902 -0.272846 +v -154.650925 -143.237061 34.225601 1.000000 1.000000 1.000000 +vn 0.053250 -0.261662 0.963689 +v -162.454346 -138.382690 33.950401 1.000000 1.000000 1.000000 +vn -0.335674 -0.018126 0.941804 +v -163.878311 -140.171509 33.599396 1.000000 1.000000 1.000000 +vn 0.155113 -0.223499 0.962283 +v -163.658142 -140.270584 33.603199 1.000000 1.000000 1.000000 +vn -0.672431 0.150846 0.724625 +v -164.085587 -140.079422 33.458801 1.000000 1.000000 1.000000 +vn -0.648574 -0.028726 0.760610 +v -164.467972 -141.700790 33.227997 1.000000 1.000000 1.000000 +vn -0.340482 -0.143279 0.929270 +v -164.276138 -142.529633 33.253399 1.000000 1.000000 1.000000 +vn -0.856267 0.264151 0.443882 +v -164.304459 -139.981735 33.121201 1.000000 1.000000 1.000000 +vn -0.869460 0.142391 0.473038 +v -164.556808 -140.806381 33.006401 1.000000 1.000000 1.000000 +vn -0.966371 0.210264 0.148039 +v -164.703583 -140.764526 32.538200 1.000000 1.000000 1.000000 +vn -0.896032 0.035016 0.442606 +v -164.703583 -141.671494 32.890198 1.000000 1.000000 1.000000 +vn -0.985596 0.083174 0.147251 +v -164.854218 -141.653351 32.421997 1.000000 1.000000 1.000000 +vn -0.876508 -0.084958 0.473830 +v -164.737061 -142.543579 32.775200 1.000000 1.000000 1.000000 +vn -0.988013 -0.045642 0.147471 +v -164.888977 -142.549164 32.306801 1.000000 1.000000 1.000000 +vn -0.873348 -0.199715 0.444272 +v -164.655945 -143.418457 32.659199 1.000000 1.000000 1.000000 +vn -0.616037 -0.206650 0.760128 +v -164.422897 -143.373795 32.996998 1.000000 1.000000 1.000000 +vn -0.973308 -0.175801 0.147532 +v -164.805283 -143.446365 32.190998 1.000000 1.000000 1.000000 +vn -0.828988 -0.327781 0.453144 +v -164.458954 -144.275192 32.542599 1.000000 1.000000 1.000000 +vn -0.588231 -0.288014 0.755667 +v -164.233643 -144.195663 32.880398 1.000000 1.000000 1.000000 +vn -0.517641 -0.420401 0.745192 +v -163.606644 -145.618896 32.662998 1.000000 1.000000 1.000000 +vn -0.245333 -0.253934 0.935590 +v -163.779160 -144.784485 32.918800 1.000000 1.000000 1.000000 +vn -0.166483 -0.316989 0.933703 +v -162.966766 -146.130981 32.687401 1.000000 1.000000 1.000000 +vn -0.333725 -0.534430 0.776539 +v -162.579239 -146.884460 32.430397 1.000000 1.000000 1.000000 +vn 0.003788 -0.315868 0.948796 +v -161.186172 -147.562592 32.340199 1.000000 1.000000 1.000000 +vn -0.192785 -0.636720 0.746606 +v -161.278870 -147.784454 32.199600 1.000000 1.000000 1.000000 +vn 0.007718 -0.624960 0.780619 +v -159.796982 -148.254684 31.968798 1.000000 1.000000 1.000000 +vn 0.144150 -0.326483 0.934147 +v -159.025787 -148.074677 31.994198 1.000000 1.000000 1.000000 +vn -0.438131 -0.751782 0.492813 +v -162.084839 -147.600266 31.977198 1.000000 1.000000 1.000000 +vn -0.331942 -0.820388 0.465594 +v -161.376724 -148.017471 31.861998 1.000000 1.000000 1.000000 +vn -0.196295 -0.844998 0.497440 +v -160.624832 -148.320251 31.747198 1.000000 1.000000 1.000000 +vn -0.556327 -0.692440 0.459377 +v -162.733734 -147.079803 32.092598 1.000000 1.000000 1.000000 +vn -0.656099 -0.738870 0.153639 +v -162.831573 -147.203995 31.624399 1.000000 1.000000 1.000000 +vn -0.543952 -0.824572 0.155555 +v -162.167236 -147.738403 31.508999 1.000000 1.000000 1.000000 +vn -0.416571 -0.895520 0.156567 +v -161.439804 -148.166779 31.393599 1.000000 1.000000 1.000000 +vn -0.278177 -0.947573 0.157237 +v -160.667328 -148.477936 31.278999 1.000000 1.000000 1.000000 +vn -0.072812 -0.880273 0.468847 +v -159.830460 -148.508621 31.630999 1.000000 1.000000 1.000000 +vn -0.455494 -0.872114 -0.178724 +v -161.434662 -148.154221 30.578199 1.000000 1.000000 1.000000 +vn -0.320923 -0.929767 -0.180393 +v -160.663467 -148.463974 30.463398 1.000000 1.000000 1.000000 +vn -0.578510 -0.796320 -0.176638 +v -162.159515 -147.727249 30.693398 1.000000 1.000000 1.000000 +vn -0.549463 -0.676575 -0.490242 +v -162.088699 -147.605850 30.300398 1.000000 1.000000 1.000000 +vn -0.447035 -0.763913 -0.465400 +v -161.379303 -148.023056 30.184998 1.000000 1.000000 1.000000 +vn -0.178962 -0.967032 -0.181169 +v -159.851059 -148.656540 30.347198 1.000000 1.000000 1.000000 +vn -0.329629 -0.820021 -0.467878 +v -160.626129 -148.325836 30.070398 1.000000 1.000000 1.000000 +vn -0.406692 -0.537711 -0.738559 +v -161.281448 -147.788635 29.840599 1.000000 1.000000 1.000000 +vn -0.648519 -0.607594 -0.458534 +v -162.737595 -147.084000 30.415798 1.000000 1.000000 1.000000 +vn -0.482356 -0.389844 -0.784445 +v -162.583099 -146.888657 30.071199 1.000000 1.000000 1.000000 +vn -0.685778 -0.706455 -0.175015 +v -162.823853 -147.194214 30.808798 1.000000 1.000000 1.000000 +vn -0.728434 -0.513100 -0.453996 +v -163.318237 -146.464462 30.532198 1.000000 1.000000 1.000000 +vn -0.598310 -0.338541 -0.726234 +v -163.139282 -146.294235 30.187599 1.000000 1.000000 1.000000 +vn -0.671378 -0.164663 -0.722591 +v -163.987732 -144.889130 30.418999 1.000000 1.000000 1.000000 +vn -0.782334 -0.397294 -0.479699 +v -163.810059 -145.762604 30.648399 1.000000 1.000000 1.000000 +vn -0.778623 -0.603236 -0.172781 +v -163.417389 -146.559357 30.925198 1.000000 1.000000 1.000000 +vn -0.753895 -0.639141 0.152126 +v -163.427673 -146.567719 31.740799 1.000000 1.000000 1.000000 +vn -0.835758 -0.527916 0.151044 +v -163.932373 -145.849121 31.856998 1.000000 1.000000 1.000000 +vn -0.860210 -0.480865 -0.169728 +v -163.920792 -145.840759 31.041401 1.000000 1.000000 1.000000 +vn -0.861061 -0.295265 -0.413996 +v -164.201462 -144.999359 30.763599 1.000000 1.000000 1.000000 +vn -0.894832 -0.415104 0.164211 +v -164.334061 -145.066345 31.972198 1.000000 1.000000 1.000000 +vn -0.941426 -0.265449 -0.207975 +v -164.591553 -144.321228 31.258799 1.000000 1.000000 1.000000 +vn -0.736131 -0.497525 0.458890 +v -163.804916 -145.758423 32.325199 1.000000 1.000000 1.000000 +vn -0.635416 -0.599326 0.486883 +v -163.313095 -146.460281 32.209000 1.000000 1.000000 1.000000 +vn -0.942696 -0.298648 0.148776 +v -164.603149 -144.326813 32.074398 1.000000 1.000000 1.000000 +vn -0.976231 -0.134709 -0.169785 +v -164.792419 -143.443573 31.375399 1.000000 1.000000 1.000000 +vn -0.985458 -0.005465 -0.169833 +v -164.876099 -142.549164 31.491398 1.000000 1.000000 1.000000 +vn -0.894779 0.032774 -0.445305 +v -164.742203 -142.544968 31.098198 1.000000 1.000000 1.000000 +vn -0.886747 -0.096439 -0.452083 +v -164.661087 -143.418457 30.982397 1.000000 1.000000 1.000000 +vn -0.977987 0.122834 -0.168681 +v -164.841339 -141.656143 31.606398 1.000000 1.000000 1.000000 +vn -0.866877 0.151113 -0.475067 +v -164.710007 -141.671494 31.213398 1.000000 1.000000 1.000000 +vn -0.953642 0.248634 -0.169555 +v -164.691986 -140.768707 31.722601 1.000000 1.000000 1.000000 +vn -0.635858 -0.027697 -0.771309 +v -164.428055 -143.375198 30.637798 1.000000 1.000000 1.000000 +vn -0.270791 -0.549061 -0.790699 +v -160.559174 -148.080261 29.725798 1.000000 1.000000 1.000000 +vn -0.134160 -0.652540 -0.745784 +v -159.027069 -148.323059 29.494398 1.000000 1.000000 1.000000 +vn -0.204331 -0.842285 -0.498803 +v -159.831741 -148.514206 29.954199 1.000000 1.000000 1.000000 +vn -0.070791 -0.878632 -0.472223 +v -159.028351 -148.579788 29.838999 1.000000 1.000000 1.000000 +vn -0.030097 -0.982738 -0.182541 +v -159.028351 -148.724899 30.232199 1.000000 1.000000 1.000000 +vn 0.010842 -0.612807 -0.790158 +v -158.250717 -148.267242 29.378599 1.000000 1.000000 1.000000 +vn 0.078796 -0.873846 -0.479775 +v -158.218536 -148.522583 29.723198 1.000000 1.000000 1.000000 +vn 0.121129 -0.975883 -0.181603 +v -158.200516 -148.664902 30.116198 1.000000 1.000000 1.000000 +vn -0.132921 -0.978503 0.157686 +v -159.852341 -148.670486 31.162798 1.000000 1.000000 1.000000 +vn 0.016726 -0.987221 0.158475 +v -159.028351 -148.738861 31.047598 1.000000 1.000000 1.000000 +vn 0.065526 -0.864220 0.498829 +v -159.028351 -148.574219 31.515999 1.000000 1.000000 1.000000 +vn 0.167856 -0.973070 0.157985 +v -158.199219 -148.678864 30.931799 1.000000 1.000000 1.000000 +vn 0.196159 -0.861307 0.468692 +v -158.219818 -148.515610 31.399998 1.000000 1.000000 1.000000 +vn 0.206819 -0.597460 0.774770 +v -158.252014 -148.261658 31.737799 1.000000 1.000000 1.000000 +vn 0.340073 -0.813229 0.472239 +v -157.421585 -148.332809 31.283398 1.000000 1.000000 1.000000 +vn 0.300048 -0.567736 0.766581 +v -157.487244 -148.085846 31.621199 1.000000 1.000000 1.000000 +vn 0.309116 -0.938114 0.156174 +v -157.380386 -148.490494 30.815199 1.000000 1.000000 1.000000 +vn 0.439125 -0.882353 0.169183 +v -156.689011 -148.223969 30.712999 1.000000 1.000000 1.000000 +vn 0.523233 -0.712264 0.467874 +v -156.031113 -147.674225 31.065998 1.000000 1.000000 1.000000 +vn 0.442346 -0.496229 0.747052 +v -156.154709 -147.455154 31.403799 1.000000 1.000000 1.000000 +vn 0.628487 -0.607304 0.485990 +v -155.368057 -147.166321 30.949799 1.000000 1.000000 1.000000 +vn 0.559268 -0.319671 0.764872 +v -154.952194 -146.384933 31.171198 1.000000 1.000000 1.000000 +vn 0.558645 -0.814980 0.154023 +v -155.952560 -147.815140 30.597799 1.000000 1.000000 1.000000 +vn 0.671213 -0.725461 0.152248 +v -155.272781 -147.293289 30.481598 1.000000 1.000000 1.000000 +vn 0.718211 -0.528552 0.452555 +v -154.777100 -146.559357 30.833399 1.000000 1.000000 1.000000 +vn 0.508798 -0.842679 -0.176115 +v -155.960297 -147.802597 29.782198 1.000000 1.000000 1.000000 +vn 0.635487 -0.751549 -0.177005 +v -155.280502 -147.282135 29.665998 1.000000 1.000000 1.000000 +vn 0.766835 -0.623866 0.150850 +v -154.665085 -146.669571 30.365198 1.000000 1.000000 1.000000 +vn 0.418716 -0.761001 -0.495534 +v -156.028534 -147.679794 29.389198 1.000000 1.000000 1.000000 +vn 0.540694 -0.703110 -0.461830 +v -155.364182 -147.170502 29.272999 1.000000 1.000000 1.000000 +vn 0.735750 -0.654283 -0.174886 +v -154.675385 -146.659821 29.549599 1.000000 1.000000 1.000000 +vn 0.819104 -0.546930 -0.173023 +v -154.160385 -145.959351 29.434198 1.000000 1.000000 1.000000 +vn 0.844994 -0.513329 0.149929 +v -154.150101 -145.967728 30.249798 1.000000 1.000000 1.000000 +vn 0.773670 -0.415204 0.478581 +v -154.274979 -145.874237 30.717999 1.000000 1.000000 1.000000 +vn 0.636082 -0.620850 -0.458198 +v -154.773224 -146.563538 29.156399 1.000000 1.000000 1.000000 +vn 0.352812 -0.575314 -0.737928 +v -155.514832 -146.972366 28.928398 1.000000 1.000000 1.000000 +vn 0.409155 -0.459450 -0.788352 +v -154.947037 -146.389114 28.811998 1.000000 1.000000 1.000000 +vn 0.702560 -0.521166 -0.484557 +v -154.269821 -145.878418 29.041199 1.000000 1.000000 1.000000 +vn 0.559058 -0.389766 -0.731804 +v -154.072845 -145.009140 28.581198 1.000000 1.000000 1.000000 +vn 0.784681 -0.425419 -0.450882 +v -153.860413 -145.123550 28.925798 1.000000 1.000000 1.000000 +vn 0.061669 -0.291296 -0.954643 +v -155.670609 -146.765854 28.777399 1.000000 1.000000 1.000000 +vn 0.181264 -0.251890 -0.950629 +v -154.294296 -144.890518 28.430199 1.000000 1.000000 1.000000 +vn -0.028138 -0.307136 -0.951250 +v -156.936203 -147.596085 29.008799 1.000000 1.000000 1.000000 +vn 0.160678 -0.646878 -0.745474 +v -156.839645 -147.841660 29.159798 1.000000 1.000000 1.000000 +vn 0.303693 -0.847205 -0.435908 +v -156.745651 -148.078873 29.504198 1.000000 1.000000 1.000000 +vn 0.273509 -0.936549 -0.219245 +v -157.384247 -148.476547 29.999598 1.000000 1.000000 1.000000 +vn 0.743388 -0.582727 0.328333 +v -162.562500 -139.278503 33.331596 1.000000 1.000000 1.000000 +vn 0.771677 -0.529273 0.352682 +v -162.925568 -139.850571 33.216400 1.000000 1.000000 1.000000 +vn 0.894440 -0.391456 0.216192 +v -163.027283 -140.372437 42.539577 1.000000 1.000000 1.000000 +vn -0.234449 0.796509 -0.557322 +v -155.056473 -144.490067 16.326599 1.000000 1.000000 1.000000 +vn -0.359472 -0.563882 0.743516 +v -1.944058 159.645279 6.000000 1.000000 1.000000 1.000000 +vn -0.543791 -0.482723 0.686491 +v -6.943540 155.999268 6.000000 1.000000 1.000000 1.000000 +vn -0.442026 -0.578177 0.685801 +v -5.551734 154.701614 6.000000 1.000000 1.000000 1.000000 +vn -0.319962 -0.654239 0.685271 +v -3.958540 153.713715 6.000000 1.000000 1.000000 1.000000 +vn -0.512750 -0.432008 0.741928 +v -2.837080 160.432236 6.000000 1.000000 1.000000 1.000000 +vn -0.623434 -0.373316 0.686997 +v -8.083668 157.557861 6.000000 1.000000 1.000000 1.000000 +vn -0.616507 -0.267922 0.740363 +v -3.476198 161.470383 6.000000 1.000000 1.000000 1.000000 +vn -0.680235 -0.254288 0.687472 +v -8.930908 159.322952 6.000000 1.000000 1.000000 1.000000 +vn -0.714238 -0.129699 0.687781 +v -9.454616 161.230377 6.000000 1.000000 1.000000 1.000000 +vn -0.667449 -0.086903 0.739568 +v -3.804674 162.666183 6.000000 1.000000 1.000000 1.000000 +vn -0.725825 -0.002487 0.687875 +v -9.635908 163.210358 6.000000 1.000000 1.000000 1.000000 +vn -0.665724 0.099125 0.739585 +v -3.793280 163.913605 6.000000 1.000000 1.000000 1.000000 +vn -0.715114 0.124842 0.687770 +v -9.468174 165.191727 6.000000 1.000000 1.000000 1.000000 +vn -0.611265 0.279423 0.740458 +v -3.443058 165.102432 6.000000 1.000000 1.000000 1.000000 +vn -0.681946 0.249553 0.687512 +v -8.957532 167.101944 6.000000 1.000000 1.000000 1.000000 +vn -0.504034 0.441938 0.742052 +v -2.785104 166.126602 6.000000 1.000000 1.000000 1.000000 +vn -0.626108 0.368751 0.687031 +v -8.122408 168.874023 6.000000 1.000000 1.000000 1.000000 +vn -0.347923 0.571047 0.743542 +v -1.877894 166.894043 6.000000 1.000000 1.000000 1.000000 +vn -0.446369 0.574817 0.685814 +v -5.610082 171.751190 6.000000 1.000000 1.000000 1.000000 +vn -0.152914 0.649268 0.745029 +v -0.802052 167.339157 6.000000 1.000000 1.000000 1.000000 +vn -0.187951 0.704069 0.684807 +v -2.291162 173.410248 6.000000 1.000000 1.000000 1.000000 +vn 0.061012 0.663973 0.745264 +v 0.346860 167.420074 6.000000 1.000000 1.000000 1.000000 +vn -0.040277 0.727766 0.684642 +v -0.475094 173.700470 6.000000 1.000000 1.000000 1.000000 +vn -0.166659 -0.646079 0.744853 +v -0.876536 159.177841 6.000000 1.000000 1.000000 1.000000 +vn -0.182199 -0.705484 0.684906 +v -2.221548 153.070465 6.000000 1.000000 1.000000 1.000000 +vn -0.034722 -0.728047 0.684648 +v -0.403534 152.794189 6.000000 1.000000 1.000000 1.000000 +vn 0.046395 -0.665190 0.745231 +v 0.270668 159.071793 6.000000 1.000000 1.000000 1.000000 +vn 0.441800 0.502958 0.742864 +v 2.458084 166.496368 6.000000 1.000000 1.000000 1.000000 +vn 0.383341 0.618988 0.685495 +v 4.817148 172.331650 6.000000 1.000000 1.000000 1.000000 +vn 0.266934 0.612327 0.744178 +v 1.466736 167.129852 6.000000 1.000000 1.000000 1.000000 +vn 0.571272 0.352963 0.740989 +v 3.232800 165.572662 6.000000 1.000000 1.000000 1.000000 +vn 0.586505 0.429450 0.686720 +v 7.588154 169.748886 6.000000 1.000000 1.000000 1.000000 +vn 0.252684 0.683246 0.685074 +v 3.144480 173.150726 6.000000 1.000000 1.000000 1.000000 +vn 0.109264 0.720527 0.684764 +v 1.358884 173.612564 6.000000 1.000000 1.000000 1.000000 +vn 0.648519 0.178770 0.739908 +v 3.722068 164.443832 6.000000 1.000000 1.000000 1.000000 +vn 0.654718 0.314638 0.687275 +v 8.586364 168.078674 6.000000 1.000000 1.000000 1.000000 +vn 0.673176 -0.006180 0.739456 +v 3.882398 163.207565 6.000000 1.000000 1.000000 1.000000 +vn 0.722823 0.066277 0.687848 +v 9.629056 164.281967 6.000000 1.000000 1.000000 1.000000 +vn 0.700049 0.192510 0.687657 +v 9.274948 166.234055 6.000000 1.000000 1.000000 1.000000 +vn 0.701358 -0.187732 0.687644 +v 9.295136 160.337357 6.000000 1.000000 1.000000 1.000000 +vn 0.723257 -0.061313 0.687851 +v 9.635868 162.292221 6.000000 1.000000 1.000000 1.000000 +vn 0.645104 -0.190677 0.739921 +v 3.699550 161.975479 6.000000 1.000000 1.000000 1.000000 +vn 0.656863 -0.310019 0.687328 +v 8.619196 158.488541 6.000000 1.000000 1.000000 1.000000 +vn 0.564107 -0.363843 0.741217 +v 3.189772 160.856430 6.000000 1.000000 1.000000 1.000000 +vn 0.589602 -0.425195 0.686716 +v 7.632444 156.809952 6.000000 1.000000 1.000000 1.000000 +vn 0.499549 -0.528705 0.686237 +v 6.370572 155.365784 6.000000 1.000000 1.000000 1.000000 +vn 0.431868 -0.511711 0.742726 +v 2.398358 159.950867 6.000000 1.000000 1.000000 1.000000 +vn 0.388226 -0.615909 0.685519 +v 4.879180 154.204865 6.000000 1.000000 1.000000 1.000000 +vn 0.254070 -0.617345 0.744536 +v 1.395630 159.336914 6.000000 1.000000 1.000000 1.000000 +vn 0.258090 -0.681251 0.685045 +v 3.212162 153.371857 6.000000 1.000000 1.000000 1.000000 +vn 0.114803 -0.719682 0.684746 +v 1.429786 152.896042 6.000000 1.000000 1.000000 1.000000 +vn 0.495601 0.532489 0.686175 +v 6.316434 171.183289 6.000000 1.000000 1.000000 1.000000 +vn 0.700049 0.192510 -0.687657 +v 9.274948 166.234055 0.000000 1.000000 1.000000 1.000000 +vn 0.722823 0.066277 -0.687848 +v 9.629056 164.281967 0.000000 1.000000 1.000000 1.000000 +vn 0.654718 0.314638 -0.687275 +v 8.586364 168.078674 0.000000 1.000000 1.000000 1.000000 +vn 0.586505 0.429450 -0.686720 +v 7.588154 169.748886 0.000000 1.000000 1.000000 1.000000 +vn 0.495601 0.532489 -0.686175 +v 6.316434 171.183289 0.000000 1.000000 1.000000 1.000000 +vn 0.383341 0.618988 -0.685495 +v 4.817148 172.331650 0.000000 1.000000 1.000000 1.000000 +vn 0.252684 0.683246 -0.685074 +v 3.144480 173.150726 0.000000 1.000000 1.000000 1.000000 +vn 0.109264 0.720527 -0.684764 +v 1.358884 173.612564 0.000000 1.000000 1.000000 1.000000 +vn -0.040277 0.727766 -0.684642 +v -0.475094 173.700470 0.000000 1.000000 1.000000 1.000000 +vn -0.187951 0.704070 -0.684807 +v -2.291162 173.410248 0.000000 1.000000 1.000000 1.000000 +vn -0.325208 0.651536 -0.685376 +v -4.023700 172.751648 0.000000 1.000000 1.000000 1.000000 +vn -0.446369 0.574817 -0.685814 +v -5.610082 171.751190 0.000000 1.000000 1.000000 1.000000 +vn -0.325208 0.651536 0.685376 +v -4.023700 172.751648 6.000000 1.000000 1.000000 1.000000 +vn -0.547376 0.478648 -0.686495 +v -6.992966 170.442368 0.000000 1.000000 1.000000 1.000000 +vn -0.626108 0.368751 -0.687031 +v -8.122408 168.874023 0.000000 1.000000 1.000000 1.000000 +vn -0.547376 0.478648 0.686495 +v -6.992966 170.442368 6.000000 1.000000 1.000000 1.000000 +vn -0.681946 0.249553 -0.687512 +v -8.957532 167.101944 0.000000 1.000000 1.000000 1.000000 +vn -0.715114 0.124841 -0.687769 +v -9.468174 165.191727 0.000000 1.000000 1.000000 1.000000 +vn 0.723257 -0.061313 -0.687851 +v 9.635868 162.292221 0.000000 1.000000 1.000000 1.000000 +vn 0.701358 -0.187732 -0.687644 +v 9.295136 160.337357 0.000000 1.000000 1.000000 1.000000 +vn 0.656863 -0.310019 -0.687328 +v 8.619196 158.488541 0.000000 1.000000 1.000000 1.000000 +vn 0.589602 -0.425195 -0.686716 +v 7.632444 156.809952 0.000000 1.000000 1.000000 1.000000 +vn 0.499549 -0.528705 -0.686237 +v 6.370572 155.365784 0.000000 1.000000 1.000000 1.000000 +vn 0.388226 -0.615909 -0.685519 +v 4.879180 154.204865 0.000000 1.000000 1.000000 1.000000 +vn 0.258090 -0.681251 -0.685045 +v 3.212162 153.371857 0.000000 1.000000 1.000000 1.000000 +vn 0.114803 -0.719682 -0.684746 +v 1.429786 152.896042 0.000000 1.000000 1.000000 1.000000 +vn -0.034722 -0.728047 -0.684648 +v -0.403534 152.794189 0.000000 1.000000 1.000000 1.000000 +vn -0.182199 -0.705484 -0.684906 +v -2.221548 153.070465 0.000000 1.000000 1.000000 1.000000 +vn -0.319962 -0.654239 -0.685271 +v -3.958540 153.713715 0.000000 1.000000 1.000000 1.000000 +vn -0.442026 -0.578178 -0.685801 +v -5.551734 154.701614 0.000000 1.000000 1.000000 1.000000 +vn -0.543792 -0.482723 -0.686491 +v -6.943540 155.999268 0.000000 1.000000 1.000000 1.000000 +vn -0.623434 -0.373316 -0.686997 +v -8.083668 157.557861 0.000000 1.000000 1.000000 1.000000 +vn -0.680235 -0.254288 -0.687472 +v -8.930908 159.322952 0.000000 1.000000 1.000000 1.000000 +vn -0.714238 -0.129699 -0.687781 +v -9.454616 161.230377 0.000000 1.000000 1.000000 1.000000 +vn -0.725825 -0.002487 -0.687875 +v -9.635908 163.210358 0.000000 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 -1.000000 +v 0.020138 163.249435 0.000000 1.000000 1.000000 1.000000 +vn 0.705804 -0.208618 0.676993 +v 3.699550 161.975479 43.157181 1.000000 1.000000 1.000000 +vn 0.735598 -0.006753 0.677385 +v 3.882398 163.207565 43.157181 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 1.000000 +v 0.020140 163.249435 43.157181 1.000000 1.000000 1.000000 +vn 0.619337 -0.399466 0.675906 +v 3.189772 160.856430 43.157181 1.000000 1.000000 1.000000 +vn 0.709516 0.195584 0.677004 +v 3.722068 164.443832 43.157181 1.000000 1.000000 1.000000 +vn 0.626822 0.387284 0.676096 +v 3.232800 165.572662 43.157181 1.000000 1.000000 1.000000 +vn 0.487206 0.554649 0.674533 +v 2.458084 166.496368 43.157181 1.000000 1.000000 1.000000 +vn 0.295409 0.677647 0.673445 +v 1.466736 167.129852 43.157181 1.000000 1.000000 1.000000 +vn 0.067717 0.736945 0.672552 +v 0.346862 167.420074 43.157181 1.000000 1.000000 1.000000 +vn -0.169613 0.720171 0.672745 +v -0.802050 167.339157 43.157181 1.000000 1.000000 1.000000 +vn -0.384381 0.630885 0.673970 +v -1.877894 166.894043 43.157181 1.000000 1.000000 1.000000 +vn -0.554626 0.486297 0.675207 +v -2.785104 166.126602 43.157181 1.000000 1.000000 1.000000 +vn -0.669746 0.306156 0.676542 +v -3.443058 165.102432 43.157181 1.000000 1.000000 1.000000 +vn -0.727706 0.108354 0.677277 +v -3.793280 163.913605 43.157181 1.000000 1.000000 1.000000 +vn -0.729557 -0.094989 0.677292 +v -3.804674 162.666183 43.157181 1.000000 1.000000 1.000000 +vn -0.675317 -0.293479 0.676622 +v -3.476198 161.470383 43.157181 1.000000 1.000000 1.000000 +vn -0.564028 -0.475212 0.675312 +v -2.837080 160.432236 43.157181 1.000000 1.000000 1.000000 +vn -0.397113 -0.622926 0.673992 +v -1.944058 159.645279 43.157181 1.000000 1.000000 1.000000 +vn -0.184771 -0.716296 0.672889 +v -0.876534 159.177841 43.157181 1.000000 1.000000 1.000000 +vn 0.281442 -0.683856 0.673150 +v 1.395630 159.336914 43.157181 1.000000 1.000000 1.000000 +vn 0.476078 -0.564094 0.674647 +v 2.398358 159.950867 43.157181 1.000000 1.000000 1.000000 +vn 0.051490 -0.738232 0.672579 +v 0.270668 159.071793 43.157181 1.000000 1.000000 1.000000 +vn -0.359433 -0.563774 0.743617 +v -160.968597 -145.962143 6.000000 1.000000 1.000000 1.000000 +vn -0.543931 -0.482750 0.686361 +v -165.967880 -149.608154 6.000000 1.000000 1.000000 1.000000 +vn -0.441944 -0.578123 0.685901 +v -164.576126 -150.904419 6.000000 1.000000 1.000000 1.000000 +vn -0.320129 -0.654200 0.685230 +v -162.982208 -151.893707 6.000000 1.000000 1.000000 1.000000 +vn -0.166552 -0.646161 0.744806 +v -159.899979 -146.429581 6.000000 1.000000 1.000000 1.000000 +vn -0.512833 -0.432118 0.741806 +v -161.860825 -145.175171 6.000000 1.000000 1.000000 1.000000 +vn -0.623520 -0.373043 0.687067 +v -167.107315 -148.048172 6.000000 1.000000 1.000000 1.000000 +vn -0.616369 -0.268013 0.740444 +v -162.500702 -144.137054 6.000000 1.000000 1.000000 1.000000 +vn -0.680163 -0.254370 0.687513 +v -167.954453 -146.283066 6.000000 1.000000 1.000000 1.000000 +vn -0.667457 -0.086804 0.739572 +v -162.829010 -142.941254 6.000000 1.000000 1.000000 1.000000 +vn -0.714228 -0.129867 0.687759 +v -168.478455 -144.377045 6.000000 1.000000 1.000000 1.000000 +vn -0.665742 0.099174 0.739562 +v -162.817413 -141.693817 6.000000 1.000000 1.000000 1.000000 +vn -0.725819 -0.002599 0.687881 +v -168.660004 -142.397064 6.000000 1.000000 1.000000 1.000000 +vn -0.611276 0.279404 0.740456 +v -162.467224 -140.504990 6.000000 1.000000 1.000000 1.000000 +vn -0.681919 0.249762 0.687464 +v -167.981506 -138.504089 6.000000 1.000000 1.000000 1.000000 +vn -0.715145 0.124800 0.687745 +v -168.492630 -140.415695 6.000000 1.000000 1.000000 1.000000 +vn -0.504242 0.441821 0.741980 +v -161.809326 -139.480820 6.000000 1.000000 1.000000 1.000000 +vn -0.625983 0.368834 0.687100 +v -167.145935 -136.733414 6.000000 1.000000 1.000000 1.000000 +vn -0.347756 0.570912 0.743724 +v -160.901642 -138.711990 6.000000 1.000000 1.000000 1.000000 +vn -0.446540 0.574602 0.685882 +v -164.634048 -133.856232 6.000000 1.000000 1.000000 1.000000 +vn -0.547427 0.478605 0.686485 +v -166.016815 -135.165054 6.000000 1.000000 1.000000 1.000000 +vn -0.152651 0.649445 0.744929 +v -159.826599 -138.268280 6.000000 1.000000 1.000000 1.000000 +vn -0.187675 0.704057 0.684896 +v -161.314926 -132.197174 6.000000 1.000000 1.000000 1.000000 +vn -0.325243 0.651682 0.685221 +v -163.047867 -132.854370 6.000000 1.000000 1.000000 1.000000 +vn 0.060632 0.664181 0.745109 +v -158.676880 -138.187347 6.000000 1.000000 1.000000 1.000000 +vn -0.040579 0.727678 0.684718 +v -159.499573 -131.906952 6.000000 1.000000 1.000000 1.000000 +vn 0.266744 0.612078 0.744452 +v -157.556763 -138.476166 6.000000 1.000000 1.000000 1.000000 +vn 0.252953 0.683222 0.684998 +v -155.879181 -132.455322 6.000000 1.000000 1.000000 1.000000 +vn 0.108993 0.720646 0.684682 +v -157.664917 -131.993454 6.000000 1.000000 1.000000 1.000000 +vn 0.442239 0.502645 0.742814 +v -156.565414 -139.111053 6.000000 1.000000 1.000000 1.000000 +vn 0.383600 0.618769 0.685548 +v -154.206741 -133.275772 6.000000 1.000000 1.000000 1.000000 +vn 0.571447 0.352829 0.740918 +v -155.791626 -140.034775 6.000000 1.000000 1.000000 1.000000 +vn 0.586545 0.429449 0.686687 +v -151.436081 -135.858521 6.000000 1.000000 1.000000 1.000000 +vn 0.495601 0.532444 0.686209 +v -152.708115 -134.424118 6.000000 1.000000 1.000000 1.000000 +vn 0.648541 0.178939 0.739848 +v -155.302383 -141.163589 6.000000 1.000000 1.000000 1.000000 +vn 0.654643 0.314669 0.687333 +v -150.438293 -137.528748 6.000000 1.000000 1.000000 1.000000 +vn 0.673115 -0.006013 0.739513 +v -155.141449 -142.399857 6.000000 1.000000 1.000000 1.000000 +vn 0.722759 0.066430 0.687900 +v -149.395432 -141.324051 6.000000 1.000000 1.000000 1.000000 +vn 0.700055 0.192635 0.687616 +v -149.749481 -139.371979 6.000000 1.000000 1.000000 1.000000 +vn 0.701314 -0.187713 0.687694 +v -149.728882 -145.268661 6.000000 1.000000 1.000000 1.000000 +vn 0.723334 -0.061233 0.687778 +v -149.387695 -143.313797 6.000000 1.000000 1.000000 1.000000 +vn 0.644988 -0.190819 0.739986 +v -155.324280 -143.631943 6.000000 1.000000 1.000000 1.000000 +vn 0.656915 -0.309994 0.687289 +v -150.404816 -147.118866 6.000000 1.000000 1.000000 1.000000 +vn 0.564227 -0.363915 0.741089 +v -155.834122 -144.749603 6.000000 1.000000 1.000000 1.000000 +vn 0.589571 -0.425212 0.686732 +v -151.391022 -148.796066 6.000000 1.000000 1.000000 1.000000 +vn 0.431574 -0.511667 0.742927 +v -156.625916 -145.656570 6.000000 1.000000 1.000000 1.000000 +vn 0.499476 -0.528837 0.686189 +v -152.654037 -150.241638 6.000000 1.000000 1.000000 1.000000 +vn 0.254276 -0.617627 0.744232 +v -157.628860 -146.269119 6.000000 1.000000 1.000000 1.000000 +vn 0.388054 -0.615975 0.685557 +v -154.144943 -151.401154 6.000000 1.000000 1.000000 1.000000 +vn 0.046835 -0.664971 0.745399 +v -158.752838 -146.535629 6.000000 1.000000 1.000000 1.000000 +vn 0.115105 -0.719715 0.684661 +v -157.594101 -152.711380 6.000000 1.000000 1.000000 1.000000 +vn 0.258312 -0.681075 0.685137 +v -155.812241 -152.234161 6.000000 1.000000 1.000000 1.000000 +vn -0.034726 -0.728047 0.684647 +v -159.427475 -152.813232 6.000000 1.000000 1.000000 1.000000 +vn -0.182214 -0.705482 0.684904 +v -161.245392 -152.536957 6.000000 1.000000 1.000000 1.000000 +vn 0.700055 0.192635 -0.687616 +v -149.749481 -139.371979 0.000000 1.000000 1.000000 1.000000 +vn 0.722759 0.066430 -0.687900 +v -149.395432 -141.324051 0.000000 1.000000 1.000000 1.000000 +vn 0.654643 0.314668 -0.687333 +v -150.438293 -137.528748 0.000000 1.000000 1.000000 1.000000 +vn 0.723334 -0.061233 -0.687778 +v -149.387695 -143.313797 0.000000 1.000000 1.000000 1.000000 +vn 0.701314 -0.187713 -0.687694 +v -149.728882 -145.268661 0.000000 1.000000 1.000000 1.000000 +vn 0.586545 0.429449 -0.686687 +v -151.436081 -135.858521 0.000000 1.000000 1.000000 1.000000 +vn 0.495601 0.532444 -0.686209 +v -152.708115 -134.424118 0.000000 1.000000 1.000000 1.000000 +vn 0.383600 0.618769 -0.685548 +v -154.206741 -133.275772 0.000000 1.000000 1.000000 1.000000 +vn 0.252953 0.683222 -0.684998 +v -155.879181 -132.455322 0.000000 1.000000 1.000000 1.000000 +vn 0.108993 0.720646 -0.684682 +v -157.664917 -131.993454 0.000000 1.000000 1.000000 1.000000 +vn -0.040579 0.727678 -0.684718 +v -159.499573 -131.906952 0.000000 1.000000 1.000000 1.000000 +vn -0.187675 0.704057 -0.684896 +v -161.314926 -132.197174 0.000000 1.000000 1.000000 1.000000 +vn -0.325243 0.651682 -0.685221 +v -163.047867 -132.854370 0.000000 1.000000 1.000000 1.000000 +vn -0.446540 0.574602 -0.685882 +v -164.634048 -133.856232 0.000000 1.000000 1.000000 1.000000 +vn -0.547427 0.478605 -0.686485 +v -166.016815 -135.165054 0.000000 1.000000 1.000000 1.000000 +vn -0.625983 0.368834 -0.687100 +v -167.145935 -136.733414 0.000000 1.000000 1.000000 1.000000 +vn -0.681919 0.249762 -0.687463 +v -167.981506 -138.504089 0.000000 1.000000 1.000000 1.000000 +vn 0.656915 -0.309994 -0.687289 +v -150.404816 -147.118866 0.000000 1.000000 1.000000 1.000000 +vn 0.589571 -0.425212 -0.686732 +v -151.391022 -148.796066 0.000000 1.000000 1.000000 1.000000 +vn 0.499476 -0.528837 -0.686189 +v -152.654037 -150.241638 0.000000 1.000000 1.000000 1.000000 +vn 0.388054 -0.615975 -0.685557 +v -154.144943 -151.401154 0.000000 1.000000 1.000000 1.000000 +vn 0.258312 -0.681075 -0.685137 +v -155.812241 -152.234161 0.000000 1.000000 1.000000 1.000000 +vn 0.115105 -0.719715 -0.684661 +v -157.594101 -152.711380 0.000000 1.000000 1.000000 1.000000 +vn -0.034726 -0.728047 -0.684647 +v -159.427475 -152.813232 0.000000 1.000000 1.000000 1.000000 +vn -0.182214 -0.705482 -0.684904 +v -161.245392 -152.536957 0.000000 1.000000 1.000000 1.000000 +vn -0.320129 -0.654200 -0.685230 +v -162.982208 -151.893707 0.000000 1.000000 1.000000 1.000000 +vn -0.441944 -0.578123 -0.685901 +v -164.576126 -150.904419 0.000000 1.000000 1.000000 1.000000 +vn -0.543931 -0.482750 -0.686361 +v -165.967880 -149.608154 0.000000 1.000000 1.000000 1.000000 +vn -0.623520 -0.373043 -0.687067 +v -167.107315 -148.048172 0.000000 1.000000 1.000000 1.000000 +vn -0.680163 -0.254370 -0.687513 +v -167.954453 -146.283066 0.000000 1.000000 1.000000 1.000000 +vn -0.714228 -0.129867 -0.687759 +v -168.478455 -144.377045 0.000000 1.000000 1.000000 1.000000 +vn -0.725819 -0.002599 -0.687881 +v -168.660004 -142.397064 0.000000 1.000000 1.000000 1.000000 +vn -0.715145 0.124800 -0.687745 +v -168.492630 -140.415695 0.000000 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 -1.000000 +v -159.003891 -142.358002 0.000000 1.000000 1.000000 1.000000 +vn 0.705799 -0.208810 0.676939 +v -155.324280 -143.631943 43.157181 1.000000 1.000000 1.000000 +vn 0.735643 -0.006572 0.677337 +v -155.141449 -142.399857 43.157181 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 1.000000 +v -159.003891 -142.358002 43.157181 1.000000 1.000000 1.000000 +vn 0.619258 -0.399409 0.676012 +v -155.834122 -144.749603 43.157181 1.000000 1.000000 1.000000 +vn 0.709425 0.195738 0.677055 +v -155.302383 -141.163589 43.157181 1.000000 1.000000 1.000000 +vn 0.626894 0.387064 0.676155 +v -155.791626 -140.034775 43.157181 1.000000 1.000000 1.000000 +vn 0.487626 0.554231 0.674574 +v -156.565414 -139.111053 43.157181 1.000000 1.000000 1.000000 +vn 0.295415 0.677868 0.673220 +v -157.556763 -138.476166 43.157181 1.000000 1.000000 1.000000 +vn 0.067268 0.736870 0.672679 +v -158.676880 -138.187347 43.157181 1.000000 1.000000 1.000000 +vn -0.169276 0.720173 0.672827 +v -159.826599 -138.268280 43.157181 1.000000 1.000000 1.000000 +vn -0.384383 0.631044 0.673820 +v -160.901642 -138.711990 43.157181 1.000000 1.000000 1.000000 +vn -0.554748 0.486074 0.675268 +v -161.809326 -139.480820 43.157181 1.000000 1.000000 1.000000 +vn -0.669754 0.306134 0.676543 +v -162.467224 -140.504990 43.157181 1.000000 1.000000 1.000000 +vn -0.727681 0.108401 0.677296 +v -162.817413 -141.693817 43.157181 1.000000 1.000000 1.000000 +vn -0.729574 -0.094883 0.677288 +v -162.829010 -142.941254 43.157181 1.000000 1.000000 1.000000 +vn -0.675314 -0.293644 0.676553 +v -162.500702 -144.137054 43.157181 1.000000 1.000000 1.000000 +vn -0.563936 -0.475178 0.675412 +v -161.860825 -145.175171 43.157181 1.000000 1.000000 1.000000 +vn -0.397177 -0.622976 0.673908 +v -160.968597 -145.962143 43.157181 1.000000 1.000000 1.000000 +vn -0.184629 -0.716296 0.672927 +v -159.899979 -146.429581 43.157181 1.000000 1.000000 1.000000 +vn 0.281441 -0.683610 0.673401 +v -157.628860 -146.269119 43.157181 1.000000 1.000000 1.000000 +vn 0.476011 -0.564350 0.674480 +v -156.625916 -145.656570 43.157181 1.000000 1.000000 1.000000 +vn 0.052001 -0.738322 0.672441 +v -158.752838 -146.535629 43.157181 1.000000 1.000000 1.000000 +vn -0.260757 -0.614700 0.744412 +v 157.590240 -146.253769 6.000000 1.000000 1.000000 1.000000 +vn -0.460543 -0.563401 0.685915 +v 153.184494 -150.709076 6.000000 1.000000 1.000000 1.000000 +vn -0.341675 -0.643067 0.685363 +v 154.747482 -151.751389 6.000000 1.000000 1.000000 1.000000 +vn -0.206218 -0.698788 0.684960 +v 156.464981 -152.454636 6.000000 1.000000 1.000000 1.000000 +vn -0.054198 -0.664722 0.745122 +v 158.711639 -146.531433 6.000000 1.000000 1.000000 1.000000 +vn -0.437310 -0.506836 0.742885 +v 156.592438 -145.628662 6.000000 1.000000 1.000000 1.000000 +vn -0.558647 -0.465291 0.686599 +v 151.831345 -149.363968 6.000000 1.000000 1.000000 1.000000 +vn -0.568136 -0.358049 0.740961 +v 155.810944 -144.713318 6.000000 1.000000 1.000000 1.000000 +vn -0.634563 -0.353961 0.687053 +v 150.736984 -147.766312 6.000000 1.000000 1.000000 1.000000 +vn -0.646836 -0.184172 0.740056 +v 155.311401 -143.588684 6.000000 1.000000 1.000000 1.000000 +vn -0.687500 -0.233693 0.687554 +v 149.942596 -145.973297 6.000000 1.000000 1.000000 1.000000 +vn -0.673278 0.000741 0.739389 +v 155.141449 -142.353821 6.000000 1.000000 1.000000 1.000000 +vn -0.717689 -0.108629 0.687839 +v 149.475250 -144.049149 6.000000 1.000000 1.000000 1.000000 +vn -0.646604 0.185369 0.739960 +v 155.313980 -141.120331 6.000000 1.000000 1.000000 1.000000 +vn -0.711182 0.145841 0.687715 +v 149.576965 -140.089188 6.000000 1.000000 1.000000 1.000000 +vn -0.725591 0.018673 0.687872 +v 149.351654 -142.063583 6.000000 1.000000 1.000000 1.000000 +vn -0.567342 0.359059 0.741080 +v 155.814804 -139.997086 6.000000 1.000000 1.000000 1.000000 +vn -0.674193 0.270085 0.687399 +v 150.143448 -138.197113 6.000000 1.000000 1.000000 1.000000 +vn -0.436768 0.507655 0.742644 +v 156.598892 -139.083145 6.000000 1.000000 1.000000 1.000000 +vn -0.532101 0.495855 0.686291 +v 152.204712 -134.926453 6.000000 1.000000 1.000000 1.000000 +vn -0.614482 0.387799 0.687039 +v 151.030533 -136.455734 6.000000 1.000000 1.000000 1.000000 +vn -0.260137 0.614816 0.744534 +v 157.595398 -138.459442 6.000000 1.000000 1.000000 1.000000 +vn -0.303218 0.662268 0.685172 +v 155.240601 -132.720428 6.000000 1.000000 1.000000 1.000000 +vn -0.427388 0.589069 0.685812 +v 153.626083 -133.666458 6.000000 1.000000 1.000000 1.000000 +vn -0.052908 0.664687 0.745246 +v 158.718079 -138.183151 6.000000 1.000000 1.000000 1.000000 +vn -0.163799 0.709987 0.684900 +v 156.991562 -132.123230 6.000000 1.000000 1.000000 1.000000 +vn 0.160268 0.647739 0.744815 +v 159.866501 -138.278046 6.000000 1.000000 1.000000 1.000000 +vn 0.133828 0.716352 0.684784 +v 160.645432 -132.045090 6.000000 1.000000 1.000000 1.000000 +vn -0.015525 0.728773 0.684579 +v 158.815918 -131.894394 6.000000 1.000000 1.000000 1.000000 +vn 0.353985 0.567192 0.743632 +v 160.937698 -138.734314 6.000000 1.000000 1.000000 1.000000 +vn 0.275792 0.674239 0.685084 +v 162.417007 -132.568344 6.000000 1.000000 1.000000 1.000000 +vn 0.508881 0.436399 0.742021 +v 161.837631 -139.512909 6.000000 1.000000 1.000000 1.000000 +vn 0.512347 0.516372 0.686193 +v 165.530136 -134.644592 6.000000 1.000000 1.000000 1.000000 +vn 0.403459 0.605834 0.685701 +v 164.064987 -133.445999 6.000000 1.000000 1.000000 1.000000 +vn 0.614244 0.273215 0.740309 +v 162.485245 -140.545456 6.000000 1.000000 1.000000 1.000000 +vn 0.599507 0.410870 0.686861 +v 166.758392 -136.122253 6.000000 1.000000 1.000000 1.000000 +vn 0.666602 0.092523 0.739649 +v 162.823853 -141.737076 6.000000 1.000000 1.000000 1.000000 +vn 0.705468 0.171681 0.687634 +v 168.342010 -139.692902 6.000000 1.000000 1.000000 1.000000 +vn 0.663781 0.294793 0.687380 +v 167.707260 -137.825958 6.000000 1.000000 1.000000 1.000000 +vn 0.721156 -0.082542 0.687838 +v 168.586609 -143.644501 6.000000 1.000000 1.000000 1.000000 +vn 0.724422 0.044898 0.687893 +v 168.638123 -141.656143 6.000000 1.000000 1.000000 1.000000 +vn 0.666600 -0.093558 0.739521 +v 162.822571 -142.985901 6.000000 1.000000 1.000000 1.000000 +vn 0.695523 -0.208405 0.687616 +v 168.188797 -145.586792 6.000000 1.000000 1.000000 1.000000 +vn 0.613449 -0.274334 0.740555 +v 162.482681 -144.177521 6.000000 1.000000 1.000000 1.000000 +vn 0.647267 -0.329860 0.687195 +v 167.458786 -147.413300 6.000000 1.000000 1.000000 1.000000 +vn 0.508242 -0.437580 0.741764 +v 161.832489 -145.207275 6.000000 1.000000 1.000000 1.000000 +vn 0.576074 -0.443444 0.686656 +v 166.423645 -149.055603 6.000000 1.000000 1.000000 1.000000 +vn 0.353252 -0.567549 0.743708 +v 160.932541 -145.984467 6.000000 1.000000 1.000000 1.000000 +vn 0.482337 -0.544642 0.686087 +v 165.119431 -150.456512 6.000000 1.000000 1.000000 1.000000 +vn 0.158958 -0.647934 0.744925 +v 159.860077 -146.439346 6.000000 1.000000 1.000000 1.000000 +vn 0.235069 -0.689632 0.684945 +v 161.904587 -152.340210 6.000000 1.000000 1.000000 1.000000 +vn 0.367667 -0.628421 0.685498 +v 163.595062 -151.564407 6.000000 1.000000 1.000000 1.000000 +vn 0.090162 -0.723193 0.684736 +v 160.108551 -152.754623 6.000000 1.000000 1.000000 1.000000 +vn -0.059701 -0.726452 0.684619 +v 158.273895 -152.793701 6.000000 1.000000 1.000000 1.000000 +vn 0.663781 0.294793 -0.687380 +v 167.707260 -137.825958 0.000000 1.000000 1.000000 1.000000 +vn 0.705468 0.171681 -0.687634 +v 168.342010 -139.692902 0.000000 1.000000 1.000000 1.000000 +vn 0.724423 0.044898 -0.687892 +v 168.638123 -141.656143 0.000000 1.000000 1.000000 1.000000 +vn 0.721156 -0.082542 -0.687838 +v 168.586609 -143.644501 0.000000 1.000000 1.000000 1.000000 +vn 0.695523 -0.208405 -0.687616 +v 168.188797 -145.586792 0.000000 1.000000 1.000000 1.000000 +vn 0.647267 -0.329860 -0.687195 +v 167.458786 -147.413300 0.000000 1.000000 1.000000 1.000000 +vn 0.576074 -0.443444 -0.686656 +v 166.423645 -149.055603 0.000000 1.000000 1.000000 1.000000 +vn 0.482337 -0.544642 -0.686087 +v 165.119431 -150.456512 0.000000 1.000000 1.000000 1.000000 +vn 0.367667 -0.628421 -0.685498 +v 163.595062 -151.564407 0.000000 1.000000 1.000000 1.000000 +vn 0.235069 -0.689632 -0.684945 +v 161.904587 -152.340210 0.000000 1.000000 1.000000 1.000000 +vn 0.090162 -0.723193 -0.684736 +v 160.108551 -152.754623 0.000000 1.000000 1.000000 1.000000 +vn -0.059701 -0.726452 -0.684619 +v 158.273895 -152.793701 0.000000 1.000000 1.000000 1.000000 +vn -0.206218 -0.698788 -0.684960 +v 156.464981 -152.454636 0.000000 1.000000 1.000000 1.000000 +vn -0.341675 -0.643067 -0.685363 +v 154.747482 -151.751389 0.000000 1.000000 1.000000 1.000000 +vn -0.460543 -0.563401 -0.685915 +v 153.184494 -150.709076 0.000000 1.000000 1.000000 1.000000 +vn -0.558647 -0.465291 -0.686599 +v 151.831345 -149.363968 0.000000 1.000000 1.000000 1.000000 +vn -0.634563 -0.353961 -0.687053 +v 150.736984 -147.766312 0.000000 1.000000 1.000000 1.000000 +vn -0.687500 -0.233693 -0.687554 +v 149.942596 -145.973297 0.000000 1.000000 1.000000 1.000000 +vn -0.717689 -0.108629 -0.687839 +v 149.475250 -144.049149 0.000000 1.000000 1.000000 1.000000 +vn -0.725591 0.018673 -0.687872 +v 149.351654 -142.063583 0.000000 1.000000 1.000000 1.000000 +vn -0.711182 0.145841 -0.687715 +v 149.576965 -140.089188 0.000000 1.000000 1.000000 1.000000 +vn -0.674193 0.270085 -0.687399 +v 150.143448 -138.197113 0.000000 1.000000 1.000000 1.000000 +vn -0.614482 0.387799 -0.687039 +v 151.030533 -136.455734 0.000000 1.000000 1.000000 1.000000 +vn -0.532101 0.495855 -0.686291 +v 152.204712 -134.926453 0.000000 1.000000 1.000000 1.000000 +vn -0.427388 0.589069 -0.685812 +v 153.626083 -133.666458 0.000000 1.000000 1.000000 1.000000 +vn -0.303218 0.662268 -0.685172 +v 155.240601 -132.720428 0.000000 1.000000 1.000000 1.000000 +vn -0.163799 0.709988 -0.684900 +v 156.991562 -132.123230 0.000000 1.000000 1.000000 1.000000 +vn -0.015525 0.728773 -0.684579 +v 158.815918 -131.894394 0.000000 1.000000 1.000000 1.000000 +vn 0.133828 0.716352 -0.684784 +v 160.645432 -132.045090 0.000000 1.000000 1.000000 1.000000 +vn 0.275792 0.674239 -0.685084 +v 162.417007 -132.568344 0.000000 1.000000 1.000000 1.000000 +vn 0.403459 0.605834 -0.685701 +v 164.064987 -133.445999 0.000000 1.000000 1.000000 1.000000 +vn 0.512347 0.516372 -0.686193 +v 165.530136 -134.644592 0.000000 1.000000 1.000000 1.000000 +vn 0.599507 0.410870 -0.686861 +v 166.758392 -136.122253 0.000000 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 -1.000000 +v 159.003891 -142.358002 0.000000 1.000000 1.000000 1.000000 +vn 0.728538 -0.102251 0.677331 +v 162.822571 -142.985901 43.157120 1.000000 1.000000 1.000000 +vn 0.728792 0.101155 0.677222 +v 162.823853 -141.737076 43.157120 1.000000 1.000000 1.000000 +vn 0.000002 -0.000002 1.000000 +v 159.003891 -142.358002 43.157120 1.000000 1.000000 1.000000 +vn 0.672314 -0.300659 0.676461 +v 162.482681 -144.177521 43.157120 1.000000 1.000000 1.000000 +vn 0.672742 0.299234 0.676666 +v 162.485245 -140.545456 43.157120 1.000000 1.000000 1.000000 +vn 0.559914 0.480163 0.675234 +v 161.837631 -139.512909 43.157120 1.000000 1.000000 1.000000 +vn 0.391171 0.626776 0.673897 +v 160.937698 -138.734314 43.157120 1.000000 1.000000 1.000000 +vn 0.177673 0.718061 0.672919 +v 159.866501 -138.278046 43.157120 1.000000 1.000000 1.000000 +vn -0.058714 0.737700 0.672570 +v 158.718079 -138.183151 43.157139 1.000000 1.000000 1.000000 +vn -0.288161 0.681049 0.673154 +v 157.595398 -138.459442 43.157139 1.000000 1.000000 1.000000 +vn -0.481372 0.559498 0.674717 +v 156.598892 -139.083145 43.157139 1.000000 1.000000 1.000000 +vn -0.622660 0.394068 0.676021 +v 155.814804 -139.997086 43.157139 1.000000 1.000000 1.000000 +vn -0.707518 0.202832 0.676962 +v 155.313980 -141.120331 43.157139 1.000000 1.000000 1.000000 +vn -0.735572 0.000805 0.677446 +v 155.141449 -142.353821 43.157139 1.000000 1.000000 1.000000 +vn -0.707956 -0.201579 0.676878 +v 155.311401 -143.588684 43.157120 1.000000 1.000000 1.000000 +vn -0.623332 -0.392834 0.676120 +v 155.810944 -144.713318 43.157120 1.000000 1.000000 1.000000 +vn -0.482281 -0.558957 0.674516 +v 156.592438 -145.628662 43.157120 1.000000 1.000000 1.000000 +vn -0.288754 -0.680700 0.673253 +v 157.590240 -146.253769 43.157120 1.000000 1.000000 1.000000 +vn -0.060132 -0.737497 0.672669 +v 158.711639 -146.531433 43.157120 1.000000 1.000000 1.000000 +vn 0.390442 -0.627299 0.673834 +v 160.932541 -145.984467 43.157120 1.000000 1.000000 1.000000 +vn 0.558824 -0.481129 0.675448 +v 161.832489 -145.207275 43.157120 1.000000 1.000000 1.000000 +vn 0.176268 -0.718491 0.672830 +v 159.860077 -146.439346 43.157120 1.000000 1.000000 1.000000 +vn 0.680717 0.530875 0.504773 +v 144.822296 164.012665 45.911160 1.000000 1.000000 1.000000 +vn 0.677648 0.504397 0.535142 +v 144.980652 164.228943 45.472580 1.000000 1.000000 1.000000 +vn 0.531075 0.600886 0.597408 +v 144.710281 164.622437 45.449158 1.000000 1.000000 1.000000 +vn 0.427625 0.665301 0.611974 +v 144.503006 164.305695 46.031960 1.000000 1.000000 1.000000 +vn 0.780984 0.315656 0.538911 +v 144.826157 163.952667 45.970757 1.000000 1.000000 1.000000 +vn 0.818545 0.341869 0.461638 +v 144.854477 163.983383 45.898956 1.000000 1.000000 1.000000 +vn 0.397648 0.692953 0.601409 +v 144.675522 164.641968 45.449158 1.000000 1.000000 1.000000 +vn 0.433392 0.480417 0.762477 +v 144.733459 164.658707 45.398758 1.000000 1.000000 1.000000 +vn 0.461814 0.460010 0.758366 +v 144.477249 164.055923 46.284958 1.000000 1.000000 1.000000 +vn 0.715577 0.108841 0.690003 +v 144.822296 163.587097 46.091560 1.000000 1.000000 1.000000 +vn 0.501334 0.132126 0.855106 +v 144.477249 163.587097 46.434559 1.000000 1.000000 1.000000 +vn 0.287991 0.147529 0.946201 +v 144.474670 163.587097 46.435356 1.000000 1.000000 1.000000 +vn 0.138473 0.317358 0.938141 +v 144.071701 164.089417 46.395958 1.000000 1.000000 1.000000 +vn 0.131588 0.546324 0.827173 +v 144.071701 164.092209 46.394958 1.000000 1.000000 1.000000 +vn 0.501334 -0.132127 0.855106 +v 144.477249 162.853149 46.434559 1.000000 1.000000 1.000000 +vn 0.287880 -0.147655 0.946215 +v 144.474670 162.853149 46.435356 1.000000 1.000000 1.000000 +vn 0.141624 0.150240 0.978453 +v 144.071701 163.587097 46.556160 1.000000 1.000000 1.000000 +vn 0.141612 -0.150623 0.978396 +v 144.071701 162.853149 46.556160 1.000000 1.000000 1.000000 +vn 0.468939 -0.449532 0.760274 +v 144.477249 162.384323 46.284958 1.000000 1.000000 1.000000 +vn 0.138861 -0.266033 0.953910 +v 144.071701 162.352219 46.395958 1.000000 1.000000 1.000000 +vn 0.715576 -0.108839 0.690004 +v 144.822296 162.853149 46.091560 1.000000 1.000000 1.000000 +vn 0.822089 -0.089748 0.562241 +v 144.826157 162.853149 46.087357 1.000000 1.000000 1.000000 +vn 0.822191 0.089954 0.562059 +v 144.826157 163.587097 46.087357 1.000000 1.000000 1.000000 +vn 0.780330 -0.316525 0.539348 +v 144.826157 162.487564 45.970757 1.000000 1.000000 1.000000 +vn 0.926817 -0.059082 0.370835 +v 145.063049 162.853149 45.574558 1.000000 1.000000 1.000000 +vn 0.926744 0.065631 0.369917 +v 145.063049 163.587097 45.574558 1.000000 1.000000 1.000000 +vn 0.905774 0.148683 0.396821 +v 144.880234 163.933136 45.858559 1.000000 1.000000 1.000000 +vn 0.916485 0.097959 0.387891 +v 145.077209 163.613617 45.529358 1.000000 1.000000 1.000000 +vn 0.774880 0.359808 0.519711 +v 144.989670 164.216400 45.473358 1.000000 1.000000 1.000000 +vn 0.813970 0.076904 0.575795 +v 145.119705 163.613617 45.437958 1.000000 1.000000 1.000000 +vn 0.918675 -0.079344 0.386964 +v 145.077209 162.826645 45.529358 1.000000 1.000000 1.000000 +vn 0.657567 0.281425 0.698860 +v 145.028290 164.235931 45.410358 1.000000 1.000000 1.000000 +vn 0.499222 0.047551 0.865168 +v 145.180222 163.613617 45.377357 1.000000 1.000000 1.000000 +vn 0.815913 -0.057644 0.575294 +v 145.119705 162.826645 45.437958 1.000000 1.000000 1.000000 +vn 0.799549 -0.317299 0.509944 +v 145.016708 162.307571 45.480358 1.000000 1.000000 1.000000 +vn 0.681198 -0.258072 0.685105 +v 145.056610 162.292221 45.413757 1.000000 1.000000 1.000000 +vn 0.389209 -0.148274 0.909138 +v 145.108124 162.272690 45.370956 1.000000 1.000000 1.000000 +vn 0.502486 -0.036253 0.863825 +v 145.180222 162.826645 45.377357 1.000000 1.000000 1.000000 +vn 0.734799 -0.446424 0.510663 +v 144.969070 162.223862 45.474758 1.000000 1.000000 1.000000 +vn 0.471134 -0.452063 0.757411 +v 144.782379 161.824783 45.399361 1.000000 1.000000 1.000000 +vn 0.256363 -0.246832 0.934533 +v 144.813278 161.784317 45.367157 1.000000 1.000000 1.000000 +vn 0.903240 -0.162916 0.397010 +v 144.880234 162.507111 45.858559 1.000000 1.000000 1.000000 +vn 0.822126 -0.349934 0.449061 +v 144.854477 162.456879 45.898956 1.000000 1.000000 1.000000 +vn 0.686263 -0.528712 0.499506 +v 144.822296 162.427567 45.911160 1.000000 1.000000 1.000000 +vn 0.580786 -0.564668 0.586377 +v 144.756638 161.858276 45.450359 1.000000 1.000000 1.000000 +vn 0.424437 -0.665491 0.613983 +v 144.503006 162.134552 46.031960 1.000000 1.000000 1.000000 +vn 0.454877 -0.663500 0.594016 +v 144.674240 161.801071 45.449558 1.000000 1.000000 1.000000 +vn 0.224383 -0.753929 0.617449 +v 144.477249 162.123398 46.026958 1.000000 1.000000 1.000000 +vn 0.126837 -0.496868 0.858507 +v 144.071701 162.348038 46.394958 1.000000 1.000000 1.000000 +vn -0.132555 -0.501252 0.855088 +v 141.749084 162.348038 46.394958 1.000000 1.000000 1.000000 +vn 0.104282 -0.798993 0.592229 +v 144.071701 161.944778 45.948959 1.000000 1.000000 1.000000 +vn -0.138856 -0.266033 0.953910 +v 141.749084 162.352219 46.395958 1.000000 1.000000 1.000000 +vn -0.141607 -0.150623 0.978397 +v 141.749084 162.853149 46.556160 1.000000 1.000000 1.000000 +vn -0.287875 -0.147655 0.946217 +v 141.346100 162.853149 46.435356 1.000000 1.000000 1.000000 +vn -0.461369 -0.460243 0.758495 +v 141.343521 162.384323 46.284958 1.000000 1.000000 1.000000 +vn -0.097926 -0.793172 0.601073 +v 141.749084 161.944778 45.948959 1.000000 1.000000 1.000000 +vn 0.058392 -0.804747 0.590740 +v 144.217178 161.660141 45.463360 1.000000 1.000000 1.000000 +vn -0.082869 -0.813298 0.575916 +v 141.603592 161.660141 45.463360 1.000000 1.000000 1.000000 +vn -0.212343 -0.745694 0.631546 +v 141.343521 162.123398 46.026958 1.000000 1.000000 1.000000 +vn -0.282881 -0.738180 0.612429 +v 141.295883 161.710373 45.449558 1.000000 1.000000 1.000000 +vn -0.427464 -0.665382 0.611998 +v 141.317780 162.134552 46.031960 1.000000 1.000000 1.000000 +vn -0.501334 -0.132126 0.855106 +v 141.343521 162.853149 46.434559 1.000000 1.000000 1.000000 +vn -0.397645 -0.692950 0.601414 +v 141.145248 161.798279 45.449158 1.000000 1.000000 1.000000 +vn -0.225270 -0.596707 0.770191 +v 141.281723 161.668518 45.398956 1.000000 1.000000 1.000000 +vn -0.433458 -0.480403 0.762448 +v 141.087311 161.781540 45.398758 1.000000 1.000000 1.000000 +vn -0.531066 -0.600890 0.597411 +v 141.110489 161.817810 45.449158 1.000000 1.000000 1.000000 +vn -0.235478 -0.262341 0.935803 +v 141.058990 161.739670 45.366959 1.000000 1.000000 1.000000 +vn -0.053026 -0.558094 0.828082 +v 141.603592 161.587585 45.387157 1.000000 1.000000 1.000000 +vn -0.064698 -0.678298 0.731933 +v 141.603592 161.614090 45.405560 1.000000 1.000000 1.000000 +vn -0.123281 -0.327309 0.936841 +v 141.264984 161.619675 45.367157 1.000000 1.000000 1.000000 +vn -0.367277 -0.158155 0.916567 +v 140.744843 162.182007 45.369957 1.000000 1.000000 1.000000 +vn -0.057222 -0.066117 0.996170 +v 141.029373 161.695023 45.356159 1.000000 1.000000 1.000000 +vn -0.031363 -0.082939 0.996061 +v 141.246964 161.568054 45.356159 1.000000 1.000000 1.000000 +vn -0.034326 -0.375340 0.926251 +v 141.603592 161.559677 45.368759 1.000000 1.000000 1.000000 +vn -0.008724 -0.097133 0.995233 +v 141.603592 161.499680 45.356159 1.000000 1.000000 1.000000 +vn 0.005062 -0.099827 0.994992 +v 144.217178 161.499680 45.356159 1.000000 1.000000 1.000000 +vn 0.017940 -0.380675 0.924535 +v 144.217178 161.559677 45.368759 1.000000 1.000000 1.000000 +vn -0.653908 -0.000009 0.756574 +v 128.876846 163.220123 45.356178 1.000000 1.000000 1.000000 +vn -0.595337 0.266478 0.757999 +v 128.672897 162.251755 45.356159 1.000000 1.000000 1.000000 +vn -0.264877 -0.355999 0.896161 +v 133.254272 159.715042 45.356159 1.000000 1.000000 1.000000 +vn -0.595335 -0.266482 0.758000 +v 128.672897 164.188477 45.356178 1.000000 1.000000 1.000000 +vn -0.090063 -0.039564 0.995150 +v 140.692062 162.155487 45.356159 1.000000 1.000000 1.000000 +vn -0.421824 -0.491900 0.761642 +v 128.101257 164.965683 45.356178 1.000000 1.000000 1.000000 +vn -0.153461 -0.625649 0.764861 +v 127.275223 165.396851 45.356178 1.000000 1.000000 1.000000 +vn -0.133643 -0.012492 0.990951 +v 140.568451 162.826645 45.356159 1.000000 1.000000 1.000000 +vn -0.048745 0.720042 0.692216 +v 126.816872 170.127029 45.356178 1.000000 1.000000 1.000000 +vn 0.153461 -0.625650 0.764860 +v 126.358528 165.396851 45.356178 1.000000 1.000000 1.000000 +vn -0.135663 0.009940 0.990705 +v 140.568451 163.613617 45.356159 1.000000 1.000000 1.000000 +vn -0.195813 0.708373 0.678133 +v 125.237137 169.912155 45.356178 1.000000 1.000000 1.000000 +vn -0.098851 0.038538 0.994356 +v 140.657288 164.189880 45.356159 1.000000 1.000000 1.000000 +vn -0.379972 0.197577 0.903651 +v 133.254272 170.127029 45.356178 1.000000 1.000000 1.000000 +vn -0.374055 0.631724 0.678975 +v 123.756149 169.278671 45.356178 1.000000 1.000000 1.000000 +vn 0.421823 -0.491903 0.761641 +v 125.532486 164.965683 45.356178 1.000000 1.000000 1.000000 +vn -0.520990 0.515880 0.680027 +v 122.466087 168.267044 45.356178 1.000000 1.000000 1.000000 +vn 0.595336 -0.266480 0.758000 +v 124.960846 164.188477 45.356178 1.000000 1.000000 1.000000 +vn -0.630320 0.372872 0.680928 +v 121.447563 166.941483 45.356178 1.000000 1.000000 1.000000 +vn -0.699861 0.213329 0.681679 +v 120.764168 165.382889 45.356178 1.000000 1.000000 1.000000 +vn 0.653916 -0.000001 0.756567 +v 124.756905 163.220123 45.356178 1.000000 1.000000 1.000000 +vn -0.729893 0.045895 0.682019 +v 120.458519 163.688950 45.356178 1.000000 1.000000 1.000000 +vn 0.595333 0.266481 0.758002 +v 124.960846 162.251755 45.356178 1.000000 1.000000 1.000000 +vn -0.720995 -0.123144 0.681910 +v 120.549805 161.965714 45.356178 1.000000 1.000000 1.000000 +vn -0.669075 -0.310847 0.675065 +v 121.032089 160.322021 45.356178 1.000000 1.000000 1.000000 +vn -0.532336 -0.521487 0.666835 +v 121.244400 160.001083 45.356178 1.000000 1.000000 1.000000 +vn -0.293966 -0.686650 0.664903 +v 121.551079 159.789001 45.356178 1.000000 1.000000 1.000000 +vn -0.074188 -0.724858 0.684892 +v 121.908607 159.715042 45.356178 1.000000 1.000000 1.000000 +vn -0.077337 -0.675120 0.733643 +v 122.196495 159.715042 45.356178 1.000000 1.000000 1.000000 +vn -0.280438 -0.587642 0.758967 +v 122.587112 159.624359 45.356178 1.000000 1.000000 1.000000 +vn -0.449260 -0.535336 0.715248 +v 122.910919 159.371796 45.356178 1.000000 1.000000 1.000000 +vn 0.421817 0.491907 0.761642 +v 125.532486 161.474564 45.356178 1.000000 1.000000 1.000000 +vn -0.410124 -0.611905 0.676292 +v 124.033859 158.358780 45.356178 1.000000 1.000000 1.000000 +vn 0.153465 0.625649 0.764861 +v 126.358528 161.043411 45.356178 1.000000 1.000000 1.000000 +vn -0.216985 -0.704904 0.675298 +v 125.370003 157.718323 45.356159 1.000000 1.000000 1.000000 +vn 0.000001 -0.737898 0.674912 +v 126.816872 157.499252 45.356159 1.000000 1.000000 1.000000 +vn -0.153451 0.625656 0.764858 +v 127.275223 161.043411 45.356159 1.000000 1.000000 1.000000 +vn 0.216929 -0.704903 0.675317 +v 128.263748 157.718323 45.356159 1.000000 1.000000 1.000000 +vn -0.421818 0.491907 0.761641 +v 128.101257 161.474564 45.356159 1.000000 1.000000 1.000000 +vn 0.410133 -0.611932 0.676262 +v 129.600418 158.358780 45.356159 1.000000 1.000000 1.000000 +vn 0.449614 -0.535169 0.715152 +v 130.723083 159.371796 45.356159 1.000000 1.000000 1.000000 +vn 0.077197 -0.675192 0.733591 +v 131.437637 159.715042 45.356159 1.000000 1.000000 1.000000 +vn 0.280505 -0.587384 0.759142 +v 131.046249 159.624359 45.356159 1.000000 1.000000 1.000000 +vn 0.264877 -0.355999 0.896161 +v 152.566498 159.715042 45.356159 1.000000 1.000000 1.000000 +vn -0.669754 -0.262908 0.694485 +v 133.254272 159.461090 45.308380 1.000000 1.000000 1.000000 +vn 0.669754 -0.262908 0.694485 +v 152.566498 159.461090 45.308380 1.000000 1.000000 1.000000 +vn -0.690247 -0.417223 0.591172 +v 133.254272 159.226669 45.168556 1.000000 1.000000 1.000000 +vn 0.690247 -0.417223 0.591172 +v 152.566498 159.226669 45.168556 1.000000 1.000000 1.000000 +vn -0.717685 -0.490139 0.494664 +v 133.254272 158.406219 44.489559 1.000000 1.000000 1.000000 +vn 0.717681 -0.490151 0.494657 +v 152.566498 158.406219 44.489559 1.000000 1.000000 1.000000 +vn -0.101696 -0.973456 0.205040 +v 134.219894 157.499252 43.739559 1.000000 1.000000 1.000000 +vn -0.397548 -0.889849 0.223886 +v 133.737091 157.620651 43.840157 1.000000 1.000000 1.000000 +vn -0.652017 -0.666225 0.361964 +v 133.383026 157.952728 44.114559 1.000000 1.000000 1.000000 +vn 0.101685 -0.973452 0.205063 +v 151.600876 157.499252 43.739559 1.000000 1.000000 1.000000 +vn 0.651809 -0.666327 0.362152 +v 152.437744 157.952728 44.114559 1.000000 1.000000 1.000000 +vn 0.397526 -0.889794 0.224142 +v 152.083694 157.620651 43.840157 1.000000 1.000000 1.000000 +vn 0.061983 -0.061038 0.996209 +v 144.846756 161.741074 45.356159 1.000000 1.000000 1.000000 +vn 0.039776 -0.080442 0.995965 +v 144.635605 161.595947 45.356159 1.000000 1.000000 1.000000 +vn -0.077197 -0.675192 0.733591 +v 154.383133 159.715042 45.356159 1.000000 1.000000 1.000000 +vn 0.135664 -0.009940 0.990705 +v 145.252319 162.826645 45.356159 1.000000 1.000000 1.000000 +vn 0.098873 -0.038546 0.994353 +v 145.163483 162.250366 45.356159 1.000000 1.000000 1.000000 +vn 0.018599 -0.089662 0.995799 +v 144.398712 161.516418 45.356159 1.000000 1.000000 1.000000 +vn -0.280506 -0.587384 0.759142 +v 154.774521 159.624359 45.356159 1.000000 1.000000 1.000000 +vn 0.153387 0.625710 0.764826 +v 158.545547 161.043411 45.356159 1.000000 1.000000 1.000000 +vn -0.449612 -0.535171 0.715151 +v 155.097687 159.371796 45.356159 1.000000 1.000000 1.000000 +vn 0.421730 0.491932 0.761674 +v 157.718994 161.474564 45.356159 1.000000 1.000000 1.000000 +vn -0.410150 -0.611910 0.676271 +v 156.220367 158.358780 45.356159 1.000000 1.000000 1.000000 +vn -0.216952 -0.704906 0.675307 +v 157.556763 157.718323 45.356159 1.000000 1.000000 1.000000 +vn 0.000000 -0.737892 0.674918 +v 159.003891 157.499252 45.356159 1.000000 1.000000 1.000000 +vn -0.153387 0.625710 0.764826 +v 159.462250 161.043411 45.356159 1.000000 1.000000 1.000000 +vn 0.595334 0.266300 0.758065 +v 157.147354 162.251755 45.356159 1.000000 1.000000 1.000000 +vn 0.654062 -0.000001 0.756441 +v 156.943924 163.220123 45.356159 1.000000 1.000000 1.000000 +vn 0.133644 0.012492 0.990951 +v 145.252319 163.613617 45.356159 1.000000 1.000000 1.000000 +vn 0.595336 -0.266299 0.758063 +v 157.147354 164.188477 45.356159 1.000000 1.000000 1.000000 +vn 0.369265 0.158468 0.915714 +v 145.075928 164.258255 45.369957 1.000000 1.000000 1.000000 +vn 0.090074 0.039566 0.995149 +v 145.128708 164.284760 45.356159 1.000000 1.000000 1.000000 +vn 0.156031 -0.313336 0.936736 +v 144.615005 161.646194 45.366959 1.000000 1.000000 1.000000 +vn 0.286369 -0.571660 0.768894 +v 144.594406 161.693619 45.398560 1.000000 1.000000 1.000000 +vn 0.075573 -0.354801 0.931883 +v 144.389709 161.573624 45.367760 1.000000 1.000000 1.000000 +vn 0.158208 -0.770702 0.617243 +v 144.374252 161.668518 45.454559 1.000000 1.000000 1.000000 +vn 0.135743 -0.644220 0.752698 +v 144.380692 161.625259 45.401360 1.000000 1.000000 1.000000 +vn 0.353840 -0.705881 0.613620 +v 144.577667 161.734100 45.448776 1.000000 1.000000 1.000000 +vn 0.033995 -0.681166 0.731339 +v 144.217178 161.614090 45.405560 1.000000 1.000000 1.000000 +vn 0.027024 -0.558805 0.828859 +v 144.217178 161.587585 45.387157 1.000000 1.000000 1.000000 +vn 0.057232 0.066132 0.996168 +v 144.791397 164.745224 45.356159 1.000000 1.000000 1.000000 +vn 0.048745 0.720043 0.692215 +v 159.003891 170.127029 45.356159 1.000000 1.000000 1.000000 +vn 0.235475 0.262322 0.935809 +v 144.761795 164.700577 45.366959 1.000000 1.000000 1.000000 +vn 0.031365 0.082953 0.996060 +v 144.573807 164.872192 45.356159 1.000000 1.000000 1.000000 +vn 0.379974 0.197579 0.903650 +v 152.566498 170.127029 45.356159 1.000000 1.000000 1.000000 +vn 0.421736 -0.491928 0.761673 +v 157.718994 164.965683 45.356159 1.000000 1.000000 1.000000 +vn 0.153391 -0.625707 0.764828 +v 158.545547 165.396851 45.356159 1.000000 1.000000 1.000000 +vn 0.195848 0.708373 0.678124 +v 160.583633 169.912155 45.356159 1.000000 1.000000 1.000000 +vn -0.153391 -0.625707 0.764828 +v 159.462250 165.396851 45.356159 1.000000 1.000000 1.000000 +vn 0.374081 0.631699 0.678984 +v 162.064240 169.278671 45.356159 1.000000 1.000000 1.000000 +vn -0.421736 -0.491928 0.761673 +v 160.288803 164.965683 45.356159 1.000000 1.000000 1.000000 +vn 0.521010 0.515867 0.680022 +v 163.354294 168.267044 45.356159 1.000000 1.000000 1.000000 +vn -0.595336 -0.266294 0.758065 +v 160.860443 164.188477 45.356159 1.000000 1.000000 1.000000 +vn 0.630289 0.372888 0.680949 +v 164.372696 166.941483 45.356159 1.000000 1.000000 1.000000 +vn 0.699772 0.213522 0.681710 +v 165.056351 165.382889 45.356159 1.000000 1.000000 1.000000 +vn -0.654067 -0.000001 0.756437 +v 161.063858 163.220123 45.356159 1.000000 1.000000 1.000000 +vn 0.729934 0.046030 0.681966 +v 165.362762 163.688950 45.356159 1.000000 1.000000 1.000000 +vn 0.720993 -0.123279 0.681888 +v 165.271347 161.965714 45.356159 1.000000 1.000000 1.000000 +vn -0.595334 0.266295 0.758067 +v 160.860443 162.251755 45.356159 1.000000 1.000000 1.000000 +vn 0.668988 -0.311019 0.675072 +v 164.788544 160.322021 45.356159 1.000000 1.000000 1.000000 +vn 0.294037 -0.686674 0.664847 +v 164.269684 159.789001 45.356159 1.000000 1.000000 1.000000 +vn 0.532333 -0.521416 0.666894 +v 164.576126 160.001083 45.356159 1.000000 1.000000 1.000000 +vn 0.074109 -0.724845 0.684915 +v 163.911774 159.715042 45.356159 1.000000 1.000000 1.000000 +vn 0.077197 -0.675193 0.733591 +v 163.624664 159.715042 45.356159 1.000000 1.000000 1.000000 +vn 0.280505 -0.587384 0.759142 +v 163.233276 159.624359 45.356159 1.000000 1.000000 1.000000 +vn 0.449612 -0.535171 0.715151 +v 162.910110 159.371796 45.356159 1.000000 1.000000 1.000000 +vn -0.421730 0.491932 0.761674 +v 160.288803 161.474564 45.356159 1.000000 1.000000 1.000000 +vn 0.410149 -0.611911 0.676271 +v 161.787430 158.358780 45.356159 1.000000 1.000000 1.000000 +vn 0.216950 -0.704907 0.675307 +v 160.451019 157.718323 45.356159 1.000000 1.000000 1.000000 +vn 0.008724 0.097133 0.995233 +v 144.217178 164.940567 45.356159 1.000000 1.000000 1.000000 +vn 0.034326 0.375340 0.926251 +v 144.217178 164.880569 45.368759 1.000000 1.000000 1.000000 +vn 0.123276 0.327312 0.936840 +v 144.555786 164.820572 45.367157 1.000000 1.000000 1.000000 +vn -0.004779 0.100070 0.994969 +v 141.603592 164.940567 45.356159 1.000000 1.000000 1.000000 +vn -0.016449 0.381096 0.924389 +v 141.603592 164.880569 45.368759 1.000000 1.000000 1.000000 +vn -0.074474 0.351867 0.933083 +v 141.431061 164.868011 45.367760 1.000000 1.000000 1.000000 +vn -0.019057 0.091753 0.995599 +v 141.422058 164.923828 45.356159 1.000000 1.000000 1.000000 +vn -0.040033 0.080517 0.995949 +v 141.185165 164.844299 45.356159 1.000000 1.000000 1.000000 +vn -0.156998 0.313156 0.936635 +v 141.205765 164.794052 45.366959 1.000000 1.000000 1.000000 +vn -0.061958 0.061015 0.996212 +v 140.974014 164.699188 45.356159 1.000000 1.000000 1.000000 +vn -0.256349 0.246799 0.934546 +v 141.007492 164.655914 45.367157 1.000000 1.000000 1.000000 +vn 0.225265 0.596707 0.770193 +v 144.539047 164.771729 45.398956 1.000000 1.000000 1.000000 +vn 0.283162 0.738290 0.612166 +v 144.524887 164.729874 45.449558 1.000000 1.000000 1.000000 +vn 0.213664 0.745410 0.631437 +v 144.477249 164.316864 46.026958 1.000000 1.000000 1.000000 +vn -0.141620 0.150240 0.978454 +v 141.749084 163.587097 46.556160 1.000000 1.000000 1.000000 +vn -0.126178 0.542205 0.830718 +v 141.749084 164.092209 46.394958 1.000000 1.000000 1.000000 +vn -0.138469 0.317358 0.938142 +v 141.749084 164.089417 46.395958 1.000000 1.000000 1.000000 +vn 0.098632 0.793225 0.600888 +v 144.071701 164.496857 45.948959 1.000000 1.000000 1.000000 +vn 0.082914 0.813885 0.575080 +v 144.217178 164.780106 45.463360 1.000000 1.000000 1.000000 +vn -0.105414 0.799034 0.591973 +v 141.749084 164.496857 45.948959 1.000000 1.000000 1.000000 +vn -0.058719 0.805061 0.590279 +v 141.603592 164.780106 45.463360 1.000000 1.000000 1.000000 +vn -0.033995 0.681166 0.731339 +v 141.603592 164.826157 45.405560 1.000000 1.000000 1.000000 +vn 0.064698 0.678298 0.731933 +v 144.217178 164.826157 45.405560 1.000000 1.000000 1.000000 +vn -0.225327 0.753608 0.617497 +v 141.343521 164.316864 46.026958 1.000000 1.000000 1.000000 +vn -0.158208 0.770715 0.617226 +v 141.446518 164.771729 45.454559 1.000000 1.000000 1.000000 +vn -0.469153 0.449624 0.760088 +v 141.343521 164.055923 46.284958 1.000000 1.000000 1.000000 +vn -0.287985 0.147529 0.946203 +v 141.346100 163.587097 46.435356 1.000000 1.000000 1.000000 +vn -0.501334 0.132127 0.855106 +v 141.343521 163.587097 46.434559 1.000000 1.000000 1.000000 +vn -0.424674 0.665368 0.613953 +v 141.317780 164.305695 46.031960 1.000000 1.000000 1.000000 +vn -0.780322 0.316519 0.539364 +v 140.994614 163.952667 45.970757 1.000000 1.000000 1.000000 +vn -0.715577 0.108841 0.690003 +v 140.998474 163.587097 46.091560 1.000000 1.000000 1.000000 +vn -0.686146 0.528806 0.499568 +v 140.998474 164.012665 45.911160 1.000000 1.000000 1.000000 +vn -0.580802 0.564701 0.586330 +v 141.064133 164.581970 45.450359 1.000000 1.000000 1.000000 +vn -0.454935 0.663524 0.593945 +v 141.146530 164.639175 45.449558 1.000000 1.000000 1.000000 +vn -0.822025 0.350053 0.449151 +v 140.966293 163.983383 45.898956 1.000000 1.000000 1.000000 +vn -0.734818 0.446425 0.510634 +v 140.851700 164.216400 45.474758 1.000000 1.000000 1.000000 +vn -0.471169 0.452086 0.757376 +v 141.038391 164.615448 45.399361 1.000000 1.000000 1.000000 +vn -0.353890 0.705968 0.613491 +v 141.243103 164.706161 45.448776 1.000000 1.000000 1.000000 +vn -0.286895 0.571075 0.769132 +v 141.226364 164.746613 45.398560 1.000000 1.000000 1.000000 +vn -0.134534 0.639983 0.756520 +v 141.440079 164.814987 45.401360 1.000000 1.000000 1.000000 +vn -0.025854 0.558246 0.829273 +v 141.603592 164.852661 45.387157 1.000000 1.000000 1.000000 +vn 0.053026 0.558094 0.828082 +v 144.217178 164.852661 45.387157 1.000000 1.000000 1.000000 +vn -0.681253 0.258078 0.685048 +v 140.764160 164.148026 45.413757 1.000000 1.000000 1.000000 +vn -0.799565 0.317266 0.509939 +v 140.804062 164.132675 45.480358 1.000000 1.000000 1.000000 +vn -0.903241 0.162889 0.397017 +v 140.940536 163.933136 45.858559 1.000000 1.000000 1.000000 +vn -0.918666 0.079353 0.386982 +v 140.743561 163.613617 45.529358 1.000000 1.000000 1.000000 +vn -0.926816 0.059078 0.370840 +v 140.757721 163.587097 45.574558 1.000000 1.000000 1.000000 +vn -0.926745 -0.065647 0.369911 +v 140.757721 162.853149 45.574558 1.000000 1.000000 1.000000 +vn -0.822088 0.089752 0.562241 +v 140.994614 163.587097 46.087357 1.000000 1.000000 1.000000 +vn -0.822192 -0.089951 0.562058 +v 140.994614 162.853149 46.087357 1.000000 1.000000 1.000000 +vn -0.916490 -0.097959 0.387880 +v 140.743561 162.826645 45.529358 1.000000 1.000000 1.000000 +vn -0.905773 -0.148698 0.396817 +v 140.940536 162.507111 45.858559 1.000000 1.000000 1.000000 +vn -0.715576 -0.108839 0.690004 +v 140.998474 162.853149 46.091560 1.000000 1.000000 1.000000 +vn -0.780989 -0.315670 0.538896 +v 140.994614 162.487564 45.970757 1.000000 1.000000 1.000000 +vn -0.818647 -0.341744 0.461551 +v 140.966293 162.456879 45.898956 1.000000 1.000000 1.000000 +vn -0.680811 -0.530791 0.504735 +v 140.998474 162.427567 45.911160 1.000000 1.000000 1.000000 +vn -0.680079 -0.504927 0.531546 +v 140.840118 162.211288 45.472580 1.000000 1.000000 1.000000 +vn -0.776155 -0.361055 0.516936 +v 140.831100 162.223862 45.473358 1.000000 1.000000 1.000000 +vn -0.658632 -0.279267 0.698723 +v 140.792480 162.205719 45.410358 1.000000 1.000000 1.000000 +vn -0.813992 -0.076991 0.575751 +v 140.701065 162.826645 45.437958 1.000000 1.000000 1.000000 +vn -0.499180 -0.047610 0.865189 +v 140.640549 162.826645 45.377357 1.000000 1.000000 1.000000 +vn -0.815914 0.057650 0.575292 +v 140.701065 163.613617 45.437958 1.000000 1.000000 1.000000 +vn -0.502483 0.036258 0.863826 +v 140.640549 163.613617 45.377357 1.000000 1.000000 1.000000 +vn -0.389227 0.148286 0.909128 +v 140.712662 164.167557 45.370956 1.000000 1.000000 1.000000 +vn 0.141597 0.150036 -0.978488 +v 141.749084 162.853149 45.856159 1.000000 1.000000 1.000000 +vn -0.141606 0.150036 -0.978487 +v 144.071701 162.853149 45.856159 1.000000 1.000000 1.000000 +vn 0.138142 0.344829 -0.928445 +v 141.749084 162.557343 45.761959 1.000000 1.000000 1.000000 +vn 0.288181 0.147499 -0.946148 +v 141.512177 162.853149 45.785156 1.000000 1.000000 1.000000 +vn -0.138152 0.344828 -0.928444 +v 144.071701 162.557343 45.761959 1.000000 1.000000 1.000000 +vn -0.288190 0.147500 -0.946145 +v 144.308594 162.853149 45.785156 1.000000 1.000000 1.000000 +vn 0.125185 0.567245 -0.813979 +v 141.749084 162.555939 45.761360 1.000000 1.000000 1.000000 +vn 0.469704 0.449849 -0.759615 +v 141.510895 162.576874 45.696556 1.000000 1.000000 1.000000 +vn 0.501244 0.132199 -0.855148 +v 141.510895 162.853149 45.784760 1.000000 1.000000 1.000000 +vn 0.435697 0.659742 -0.612298 +v 141.495438 162.430359 45.547760 1.000000 1.000000 1.000000 +vn 0.231132 0.753518 -0.615458 +v 141.510895 162.423386 45.544960 1.000000 1.000000 1.000000 +vn 0.103738 0.799112 -0.592164 +v 141.749084 162.318741 45.498959 1.000000 1.000000 1.000000 +vn 0.066230 0.812590 -0.579061 +v 141.603592 162.034088 45.013359 1.000000 1.000000 1.000000 +vn 0.192237 0.766410 -0.612912 +v 141.507034 162.025726 44.984959 1.000000 1.000000 1.000000 +vn 0.417849 0.667519 -0.616296 +v 141.324203 162.094086 44.967758 1.000000 1.000000 1.000000 +vn 0.540574 0.597749 -0.592009 +v 141.277863 162.128967 44.970158 1.000000 1.000000 1.000000 +vn 0.298866 0.560057 -0.772668 +v 141.379562 162.053619 44.964558 1.000000 1.000000 1.000000 +vn 0.438413 0.482901 -0.758024 +v 141.190308 162.015945 44.800159 1.000000 1.000000 1.000000 +vn 0.288937 0.572415 -0.767369 +v 141.322922 161.921066 44.797558 1.000000 1.000000 1.000000 +vn 0.031719 0.676226 -0.736011 +v 141.603592 161.883392 44.820759 1.000000 1.000000 1.000000 +vn 0.134047 0.635814 -0.760113 +v 141.483856 161.879211 44.807159 1.000000 1.000000 1.000000 +vn 0.159693 0.314187 -0.935834 +v 141.255966 161.764786 44.692158 1.000000 1.000000 1.000000 +vn 0.237470 0.270774 -0.932893 +v 141.087311 161.882004 44.692757 1.000000 1.000000 1.000000 +vn 0.316522 0.213000 -0.924362 +v 140.950836 162.056412 44.696758 1.000000 1.000000 1.000000 +vn 0.570325 0.380891 -0.727771 +v 141.087311 162.161072 44.814957 1.000000 1.000000 1.000000 +vn 0.066736 0.066747 -0.995536 +v 140.931519 161.782928 44.656158 1.000000 1.000000 1.000000 +vn 0.060558 0.082097 -0.994783 +v 140.980453 161.745255 44.656158 1.000000 1.000000 1.000000 +vn 0.093513 0.066332 -0.993406 +v 140.813080 161.950378 44.656158 1.000000 1.000000 1.000000 +vn 0.391427 0.142058 -0.909178 +v 140.851700 162.296417 44.704376 1.000000 1.000000 1.000000 +vn 0.091182 0.049762 -0.994590 +v 140.730682 162.066193 44.656158 1.000000 1.000000 1.000000 +vn 0.115242 0.041861 -0.992455 +v 140.674026 162.222458 44.656158 1.000000 1.000000 1.000000 +vn 0.109562 0.028974 -0.993558 +v 140.618668 162.374557 44.656158 1.000000 1.000000 1.000000 +vn 0.500358 0.033212 -0.865182 +v 140.806641 162.826645 44.726776 1.000000 1.000000 1.000000 +vn 0.039260 0.077270 -0.996237 +v 141.185165 161.593155 44.656158 1.000000 1.000000 1.000000 +vn 0.077392 0.355969 -0.931288 +v 141.456818 161.704788 44.694580 1.000000 1.000000 1.000000 +vn 0.027664 0.098491 -0.994753 +v 141.428497 161.522003 44.656158 1.000000 1.000000 1.000000 +vn 0.015541 0.093984 -0.995452 +v 141.485138 161.506653 44.656158 1.000000 1.000000 1.000000 +vn 0.016803 0.383412 -0.923424 +v 141.603592 161.699219 44.698158 1.000000 1.000000 1.000000 +vn 0.020289 0.554132 -0.832182 +v 141.603592 161.791290 44.759357 1.000000 1.000000 1.000000 +vn 0.002935 0.101623 -0.994819 +v 141.603592 161.499680 44.656158 1.000000 1.000000 1.000000 +vn -0.028420 0.549925 -0.834731 +v 144.217178 161.791290 44.759357 1.000000 1.000000 1.000000 +vn -0.018442 0.385549 -0.922503 +v 144.217178 161.699219 44.698158 1.000000 1.000000 1.000000 +vn -0.029565 0.683245 -0.729590 +v 144.217178 161.883392 44.820759 1.000000 1.000000 1.000000 +vn -0.047128 0.822486 -0.566830 +v 144.217178 162.034088 45.013359 1.000000 1.000000 1.000000 +vn -0.140945 0.639069 -0.756125 +v 144.340775 161.879211 44.806759 1.000000 1.000000 1.000000 +vn -0.075106 0.354855 -0.931900 +v 144.367813 161.704788 44.694580 1.000000 1.000000 1.000000 +vn -0.007562 0.098274 -0.995131 +v 144.217178 161.499680 44.656158 1.000000 1.000000 1.000000 +vn -0.016492 0.104435 -0.994395 +v 144.397430 161.528976 44.656158 1.000000 1.000000 1.000000 +vn -0.029963 0.082852 -0.996111 +v 144.537766 161.551300 44.656158 1.000000 1.000000 1.000000 +vn -0.157706 0.313850 -0.936284 +v 144.564804 161.764786 44.692158 1.000000 1.000000 1.000000 +vn -0.285570 0.572880 -0.768283 +v 144.497849 161.921066 44.797558 1.000000 1.000000 1.000000 +vn 0.654043 -0.000001 -0.756457 +v 156.943924 163.220123 44.656158 1.000000 1.000000 1.000000 +vn 0.595338 -0.266300 -0.758062 +v 157.147354 164.188477 44.656158 1.000000 1.000000 1.000000 +vn -0.051651 0.089847 -0.994615 +v 144.631744 161.605728 44.656158 1.000000 1.000000 1.000000 +vn 0.595334 0.266300 -0.758065 +v 157.147354 162.251755 44.656158 1.000000 1.000000 1.000000 +vn 0.379973 -0.197579 -0.903650 +v 152.566498 159.715042 44.656158 1.000000 1.000000 1.000000 +vn -0.077197 -0.675193 -0.733591 +v 154.383133 159.715042 44.656158 1.000000 1.000000 1.000000 +vn -0.379974 -0.197580 -0.903649 +v 133.254272 159.715042 44.656158 1.000000 1.000000 1.000000 +vn 0.077197 -0.675192 -0.733591 +v 131.437637 159.715042 44.656158 1.000000 1.000000 1.000000 +vn 0.280506 -0.587384 -0.759142 +v 131.046249 159.624359 44.656158 1.000000 1.000000 1.000000 +vn 0.138641 0.007429 -0.990315 +v 140.568451 162.826645 44.656158 1.000000 1.000000 1.000000 +vn 0.449614 -0.535169 -0.715152 +v 130.723083 159.371796 44.656158 1.000000 1.000000 1.000000 +vn -0.595324 0.266485 -0.758008 +v 128.672897 162.251755 44.656158 1.000000 1.000000 1.000000 +vn 0.142293 -0.002075 -0.989822 +v 140.568451 163.613617 44.656158 1.000000 1.000000 1.000000 +vn 0.131666 -0.015199 -0.991178 +v 140.572311 163.744766 44.656158 1.000000 1.000000 1.000000 +vn 0.134762 -0.023246 -0.990605 +v 140.603226 163.923370 44.656158 1.000000 1.000000 1.000000 +vn 0.099836 -0.036810 -0.994323 +v 140.641846 164.148026 44.656158 1.000000 1.000000 1.000000 +vn 0.081722 -0.052254 -0.995284 +v 140.791183 164.478714 44.656158 1.000000 1.000000 1.000000 +vn 0.078350 -0.069893 -0.994473 +v 140.977875 164.693588 44.656158 1.000000 1.000000 1.000000 +vn 0.056291 -0.070464 -0.995925 +v 141.015213 164.735458 44.656158 1.000000 1.000000 1.000000 +vn 0.051641 -0.089836 -0.994617 +v 141.189026 164.834534 44.656158 1.000000 1.000000 1.000000 +vn 0.029956 -0.082823 -0.996114 +v 141.283005 164.888947 44.656158 1.000000 1.000000 1.000000 +vn -0.653899 0.000008 -0.756582 +v 128.876846 163.220123 44.656178 1.000000 1.000000 1.000000 +vn -0.595337 -0.266483 -0.757998 +v 128.672897 164.188477 44.656178 1.000000 1.000000 1.000000 +vn 0.007563 -0.098280 -0.995130 +v 141.603592 164.940567 44.656158 1.000000 1.000000 1.000000 +vn -0.421825 -0.491902 -0.761640 +v 128.101257 164.965683 44.656178 1.000000 1.000000 1.000000 +vn -0.002363 -0.102014 -0.994780 +v 144.217178 164.940567 44.656158 1.000000 1.000000 1.000000 +vn -0.230702 0.408902 -0.882936 +v 133.254272 170.127029 44.656178 1.000000 1.000000 1.000000 +vn -0.048745 0.720043 -0.692216 +v 126.816872 170.127029 44.656178 1.000000 1.000000 1.000000 +vn -0.153462 -0.625650 -0.764861 +v 127.275223 165.396851 44.656178 1.000000 1.000000 1.000000 +vn -0.195813 0.708373 -0.678133 +v 125.237137 169.912155 44.656178 1.000000 1.000000 1.000000 +vn 0.153461 -0.625650 -0.764860 +v 126.358528 165.396851 44.656178 1.000000 1.000000 1.000000 +vn -0.374055 0.631724 -0.678975 +v 123.756149 169.278671 44.656178 1.000000 1.000000 1.000000 +vn 0.421823 -0.491903 -0.761641 +v 125.532486 164.965683 44.656178 1.000000 1.000000 1.000000 +vn -0.520990 0.515880 -0.680027 +v 122.466087 168.267044 44.656178 1.000000 1.000000 1.000000 +vn 0.595336 -0.266480 -0.758000 +v 124.960846 164.188477 44.656178 1.000000 1.000000 1.000000 +vn -0.630320 0.372872 -0.680928 +v 121.447563 166.941483 44.656178 1.000000 1.000000 1.000000 +vn 0.653916 -0.000001 -0.756567 +v 124.756905 163.220123 44.656178 1.000000 1.000000 1.000000 +vn -0.699861 0.213329 -0.681679 +v 120.764168 165.382889 44.656178 1.000000 1.000000 1.000000 +vn 0.595333 0.266481 -0.758002 +v 124.960846 162.251755 44.656178 1.000000 1.000000 1.000000 +vn -0.720995 -0.123144 -0.681910 +v 120.549805 161.965714 44.656178 1.000000 1.000000 1.000000 +vn -0.729893 0.045895 -0.682019 +v 120.458519 163.688950 44.656178 1.000000 1.000000 1.000000 +vn -0.669075 -0.310847 -0.675065 +v 121.032089 160.322021 44.656178 1.000000 1.000000 1.000000 +vn -0.532336 -0.521487 -0.666835 +v 121.244400 160.001083 44.656178 1.000000 1.000000 1.000000 +vn -0.293966 -0.686650 -0.664903 +v 121.551079 159.789001 44.656178 1.000000 1.000000 1.000000 +vn -0.074188 -0.724858 -0.684892 +v 121.908607 159.715042 44.656178 1.000000 1.000000 1.000000 +vn -0.077337 -0.675120 -0.733643 +v 122.196495 159.715042 44.656178 1.000000 1.000000 1.000000 +vn -0.280438 -0.587642 -0.758967 +v 122.587112 159.624359 44.656178 1.000000 1.000000 1.000000 +vn -0.449260 -0.535336 -0.715248 +v 122.910919 159.371796 44.656178 1.000000 1.000000 1.000000 +vn -0.410132 -0.611903 -0.676289 +v 124.033859 158.358780 44.656178 1.000000 1.000000 1.000000 +vn 0.421816 0.491909 -0.761641 +v 125.532486 161.474564 44.656178 1.000000 1.000000 1.000000 +vn -0.216990 -0.704896 -0.675305 +v 125.370003 157.718323 44.656158 1.000000 1.000000 1.000000 +vn 0.153451 0.625659 -0.764856 +v 126.358528 161.043411 44.656178 1.000000 1.000000 1.000000 +vn -0.000001 -0.737896 -0.674914 +v 126.816872 157.499252 44.656158 1.000000 1.000000 1.000000 +vn -0.153465 0.625650 -0.764860 +v 127.275223 161.043411 44.656158 1.000000 1.000000 1.000000 +vn 0.216929 -0.704903 -0.675317 +v 128.263748 157.718323 44.656158 1.000000 1.000000 1.000000 +vn 0.410133 -0.611932 -0.676262 +v 129.600418 158.358780 44.656158 1.000000 1.000000 1.000000 +vn -0.421818 0.491907 -0.761641 +v 128.101257 161.474564 44.656158 1.000000 1.000000 1.000000 +vn 0.421736 -0.491928 -0.761673 +v 157.718994 164.965683 44.656158 1.000000 1.000000 1.000000 +vn 0.230708 0.408910 -0.882931 +v 152.566498 170.127029 44.656158 1.000000 1.000000 1.000000 +vn -0.029134 -0.099001 -0.994661 +v 144.392273 164.918243 44.656158 1.000000 1.000000 1.000000 +vn -0.015753 -0.092606 -0.995578 +v 144.335632 164.934998 44.656158 1.000000 1.000000 1.000000 +vn 0.153391 -0.625707 -0.764828 +v 158.545547 165.396851 44.656158 1.000000 1.000000 1.000000 +vn 0.048745 0.720043 -0.692216 +v 159.003891 170.127029 44.656158 1.000000 1.000000 1.000000 +vn -0.153391 -0.625707 -0.764828 +v 159.462250 165.396851 44.656158 1.000000 1.000000 1.000000 +vn 0.195848 0.708373 -0.678124 +v 160.583633 169.912155 44.656158 1.000000 1.000000 1.000000 +vn 0.374081 0.631699 -0.678985 +v 162.064240 169.278671 44.656158 1.000000 1.000000 1.000000 +vn -0.421736 -0.491928 -0.761673 +v 160.288803 164.965683 44.656158 1.000000 1.000000 1.000000 +vn 0.521010 0.515868 -0.680022 +v 163.354294 168.267044 44.656158 1.000000 1.000000 1.000000 +vn -0.595336 -0.266294 -0.758065 +v 160.860443 164.188477 44.656158 1.000000 1.000000 1.000000 +vn 0.630289 0.372888 -0.680949 +v 164.372696 166.941483 44.656158 1.000000 1.000000 1.000000 +vn 0.699772 0.213522 -0.681710 +v 165.056351 165.382889 44.656158 1.000000 1.000000 1.000000 +vn -0.654067 -0.000001 -0.756437 +v 161.063858 163.220123 44.656158 1.000000 1.000000 1.000000 +vn 0.729934 0.046030 -0.681966 +v 165.362762 163.688950 44.656158 1.000000 1.000000 1.000000 +vn 0.720993 -0.123279 -0.681888 +v 165.271347 161.965714 44.656158 1.000000 1.000000 1.000000 +vn -0.595334 0.266295 -0.758067 +v 160.860443 162.251755 44.656158 1.000000 1.000000 1.000000 +vn 0.668988 -0.311019 -0.675072 +v 164.788544 160.322021 44.656158 1.000000 1.000000 1.000000 +vn 0.532333 -0.521416 -0.666894 +v 164.576126 160.001083 44.656158 1.000000 1.000000 1.000000 +vn 0.294037 -0.686674 -0.664847 +v 164.269684 159.789001 44.656158 1.000000 1.000000 1.000000 +vn 0.074109 -0.724845 -0.684914 +v 163.911774 159.715042 44.656158 1.000000 1.000000 1.000000 +vn 0.077197 -0.675192 -0.733591 +v 163.624664 159.715042 44.656158 1.000000 1.000000 1.000000 +vn 0.280506 -0.587384 -0.759142 +v 163.233276 159.624359 44.656158 1.000000 1.000000 1.000000 +vn 0.449612 -0.535171 -0.715151 +v 162.910110 159.371796 44.656158 1.000000 1.000000 1.000000 +vn -0.421730 0.491932 -0.761674 +v 160.288803 161.474564 44.656158 1.000000 1.000000 1.000000 +vn 0.410149 -0.611911 -0.676271 +v 161.787430 158.358780 44.656158 1.000000 1.000000 1.000000 +vn -0.153387 0.625710 -0.764826 +v 159.462250 161.043411 44.656158 1.000000 1.000000 1.000000 +vn 0.216950 -0.704906 -0.675307 +v 160.451019 157.718323 44.656158 1.000000 1.000000 1.000000 +vn 0.000000 -0.737892 -0.674918 +v 159.003891 157.499252 44.656158 1.000000 1.000000 1.000000 +vn 0.153387 0.625710 -0.764826 +v 158.545547 161.043411 44.656158 1.000000 1.000000 1.000000 +vn -0.216951 -0.704906 -0.675307 +v 157.556763 157.718323 44.656158 1.000000 1.000000 1.000000 +vn 0.421730 0.491932 -0.761674 +v 157.718994 161.474564 44.656158 1.000000 1.000000 1.000000 +vn -0.410150 -0.611910 -0.676271 +v 156.220367 158.358780 44.656158 1.000000 1.000000 1.000000 +vn -0.449612 -0.535171 -0.715151 +v 155.097687 159.371796 44.656158 1.000000 1.000000 1.000000 +vn -0.280505 -0.587384 -0.759142 +v 154.774521 159.624359 44.656158 1.000000 1.000000 1.000000 +vn -0.039263 -0.077277 -0.996236 +v 144.635605 164.847076 44.656158 1.000000 1.000000 1.000000 +vn -0.060166 -0.083150 -0.994719 +v 144.840317 164.694992 44.656158 1.000000 1.000000 1.000000 +vn -0.159693 -0.314193 -0.935832 +v 144.564804 164.675461 44.692158 1.000000 1.000000 1.000000 +vn -0.077607 -0.355649 -0.931392 +v 144.363953 164.735458 44.694580 1.000000 1.000000 1.000000 +vn -0.065614 -0.066508 -0.995626 +v 144.889252 164.658707 44.656158 1.000000 1.000000 1.000000 +vn -0.237154 -0.270727 -0.932987 +v 144.733459 164.558243 44.692757 1.000000 1.000000 1.000000 +vn -0.134048 -0.635832 -0.760098 +v 144.336914 164.561035 44.807159 1.000000 1.000000 1.000000 +vn -0.288955 -0.572404 -0.767371 +v 144.497849 164.519180 44.797558 1.000000 1.000000 1.000000 +vn -0.016610 -0.383126 -0.923547 +v 144.217178 164.741043 44.698158 1.000000 1.000000 1.000000 +vn 0.018458 -0.385479 -0.922532 +v 141.603592 164.741043 44.698158 1.000000 1.000000 1.000000 +vn 0.016490 -0.104410 -0.994398 +v 141.423340 164.911270 44.656158 1.000000 1.000000 1.000000 +vn 0.075109 -0.354846 -0.931903 +v 141.452957 164.735458 44.694580 1.000000 1.000000 1.000000 +vn 0.157709 -0.313843 -0.936285 +v 141.255966 164.675461 44.692158 1.000000 1.000000 1.000000 +vn 0.243054 -0.269019 -0.931962 +v 141.084732 164.555450 44.692757 1.000000 1.000000 1.000000 +vn 0.327497 -0.202037 -0.922999 +v 140.949554 164.379639 44.696758 1.000000 1.000000 1.000000 +vn -0.316506 -0.212842 -0.924404 +v 144.869934 164.383835 44.696758 1.000000 1.000000 1.000000 +vn -0.438420 -0.482909 -0.758015 +v 144.630463 164.424286 44.800159 1.000000 1.000000 1.000000 +vn -0.093759 -0.066229 -0.993390 +v 145.007690 164.489883 44.656158 1.000000 1.000000 1.000000 +vn -0.091179 -0.049759 -0.994591 +v 145.090088 164.374069 44.656158 1.000000 1.000000 1.000000 +vn -0.115244 -0.041862 -0.992455 +v 145.146744 164.217789 44.656158 1.000000 1.000000 1.000000 +vn -0.391428 -0.142057 -0.909178 +v 144.969070 164.143829 44.704376 1.000000 1.000000 1.000000 +vn -0.109560 -0.028975 -0.993558 +v 145.202103 164.065704 44.656158 1.000000 1.000000 1.000000 +vn -0.817047 -0.049626 -0.574431 +v 144.809418 163.613617 44.928757 1.000000 1.000000 1.000000 +vn -0.688610 -0.243789 -0.682922 +v 144.802979 164.074066 44.844158 1.000000 1.000000 1.000000 +vn -0.500357 -0.033213 -0.865182 +v 145.014130 163.613617 44.726776 1.000000 1.000000 1.000000 +vn -0.570311 -0.380917 -0.727769 +v 144.733459 164.279190 44.814957 1.000000 1.000000 1.000000 +vn -0.138641 -0.007429 -0.990315 +v 145.252319 163.613617 44.656158 1.000000 1.000000 1.000000 +vn -0.816674 0.038577 -0.575809 +v 144.809418 162.826645 44.928757 1.000000 1.000000 1.000000 +vn -0.500905 0.024278 -0.865161 +v 145.014130 162.826645 44.726776 1.000000 1.000000 1.000000 +vn -0.142294 0.002075 -0.989822 +v 145.252319 162.826645 44.656158 1.000000 1.000000 1.000000 +vn -0.748897 0.159925 -0.643100 +v 144.826157 162.589432 44.882359 1.000000 1.000000 1.000000 +vn -0.131666 0.015199 -0.991178 +v 145.248459 162.695480 44.656158 1.000000 1.000000 1.000000 +vn -0.444687 0.090858 -0.891066 +v 145.014130 162.554550 44.714359 1.000000 1.000000 1.000000 +vn -0.134762 0.023246 -0.990605 +v 145.217545 162.516876 44.656158 1.000000 1.000000 1.000000 +vn -0.099837 0.036810 -0.994323 +v 145.178925 162.292221 44.656158 1.000000 1.000000 1.000000 +vn -0.327492 0.202034 -0.923001 +v 144.871216 162.060593 44.696758 1.000000 1.000000 1.000000 +vn -0.081727 0.052255 -0.995284 +v 145.029587 161.961533 44.656158 1.000000 1.000000 1.000000 +vn -0.078338 0.069895 -0.994474 +v 144.842896 161.746643 44.656158 1.000000 1.000000 1.000000 +vn -0.243033 0.269017 -0.931968 +v 144.736038 161.884781 44.692757 1.000000 1.000000 1.000000 +vn -0.582478 0.345709 -0.735666 +v 144.734741 162.165253 44.815376 1.000000 1.000000 1.000000 +vn -0.056288 0.070474 -0.995924 +v 144.805557 161.704788 44.656158 1.000000 1.000000 1.000000 +vn -0.433597 0.486169 -0.758705 +v 144.631744 162.017349 44.800159 1.000000 1.000000 1.000000 +vn -0.713489 0.416683 -0.563302 +v 144.621445 162.251755 45.002159 1.000000 1.000000 1.000000 +vn -0.454708 0.663423 -0.594231 +v 144.496567 162.095490 44.967758 1.000000 1.000000 1.000000 +vn -0.526415 0.604947 -0.597434 +v 144.545486 162.130371 44.970360 1.000000 1.000000 1.000000 +vn -0.442763 0.660286 -0.606616 +v 144.325333 162.430359 45.547760 1.000000 1.000000 1.000000 +vn -0.801769 0.342561 -0.489712 +v 144.644623 162.387100 45.053558 1.000000 1.000000 1.000000 +vn -0.775171 0.315982 -0.547052 +v 144.514587 162.638275 45.511757 1.000000 1.000000 1.000000 +vn -0.462029 0.460710 -0.757809 +v 144.309875 162.576874 45.696556 1.000000 1.000000 1.000000 +vn -0.218992 0.746038 -0.628864 +v 144.309875 162.423386 45.544960 1.000000 1.000000 1.000000 +vn -0.674912 0.542435 -0.500258 +v 144.513306 162.603378 45.476776 1.000000 1.000000 1.000000 +vn -0.101014 0.793904 -0.599594 +v 144.071701 162.318741 45.498959 1.000000 1.000000 1.000000 +vn -0.193884 0.775639 -0.600660 +v 144.316315 162.025726 44.984360 1.000000 1.000000 1.000000 +vn -0.359184 0.707244 -0.608927 +v 144.441208 162.053619 44.964558 1.000000 1.000000 1.000000 +vn -0.130745 0.571456 -0.810151 +v 144.071701 162.555939 45.761360 1.000000 1.000000 1.000000 +vn -0.791799 0.096460 -0.603117 +v 144.513306 162.853149 45.582760 1.000000 1.000000 1.000000 +vn -0.501244 0.132198 -0.855148 +v 144.309875 162.853149 45.784760 1.000000 1.000000 1.000000 +vn -0.141606 -0.150036 -0.978487 +v 144.071701 163.587097 45.856159 1.000000 1.000000 1.000000 +vn -0.288189 -0.147499 -0.946145 +v 144.308594 163.587097 45.785156 1.000000 1.000000 1.000000 +vn -0.501244 -0.132199 -0.855148 +v 144.309875 163.587097 45.784760 1.000000 1.000000 1.000000 +vn -0.138110 -0.346650 -0.927771 +v 144.071701 163.882904 45.761959 1.000000 1.000000 1.000000 +vn -0.469701 -0.449856 -0.759612 +v 144.309875 163.863373 45.696556 1.000000 1.000000 1.000000 +vn -0.791799 -0.096459 -0.603117 +v 144.513306 163.587097 45.582760 1.000000 1.000000 1.000000 +vn -0.435697 -0.659742 -0.612298 +v 144.325333 164.009888 45.547760 1.000000 1.000000 1.000000 +vn -0.777137 -0.313443 -0.545721 +v 144.514587 163.801971 45.511757 1.000000 1.000000 1.000000 +vn -0.125131 -0.568854 -0.812864 +v 144.071701 163.884293 45.761360 1.000000 1.000000 1.000000 +vn -0.231131 -0.753514 -0.615464 +v 144.309875 164.016861 45.544960 1.000000 1.000000 1.000000 +vn -0.891094 0.070770 -0.448266 +v 144.514587 162.853149 45.580360 1.000000 1.000000 1.000000 +vn -0.891340 -0.071354 -0.447684 +v 144.514587 163.587097 45.580360 1.000000 1.000000 1.000000 +vn -0.931188 0.068613 -0.358025 +v 144.654922 162.853149 45.278759 1.000000 1.000000 1.000000 +vn -0.900698 0.161400 -0.403352 +v 144.548065 162.649429 45.445759 1.000000 1.000000 1.000000 +vn -0.930891 -0.061472 -0.360089 +v 144.654922 163.587097 45.278759 1.000000 1.000000 1.000000 +vn -0.919079 0.078283 -0.386221 +v 144.667801 162.826645 45.233559 1.000000 1.000000 1.000000 +vn -0.813915 0.350619 -0.463258 +v 144.532608 162.620132 45.469559 1.000000 1.000000 1.000000 +vn -0.873517 0.205680 -0.441208 +v 144.684525 162.615952 45.140556 1.000000 1.000000 1.000000 +vn -0.922744 -0.080890 -0.376828 +v 144.667801 163.613617 45.233559 1.000000 1.000000 1.000000 +vn -0.796677 -0.321595 -0.511745 +v 144.670364 164.018250 45.062157 1.000000 1.000000 1.000000 +vn -0.758175 -0.393433 -0.519982 +v 144.656219 164.065704 45.045357 1.000000 1.000000 1.000000 +vn -0.901513 -0.146208 -0.407306 +v 144.548065 163.790817 45.445759 1.000000 1.000000 1.000000 +vn -0.812133 -0.344203 -0.471132 +v 144.532608 163.820114 45.469559 1.000000 1.000000 1.000000 +vn -0.675081 -0.528576 -0.514657 +v 144.513306 163.836868 45.476776 1.000000 1.000000 1.000000 +vn -0.666331 -0.482809 -0.568241 +v 144.620163 164.191269 45.001358 1.000000 1.000000 1.000000 +vn -0.540567 -0.597762 -0.592003 +v 144.542908 164.311279 44.970158 1.000000 1.000000 1.000000 +vn -0.417854 -0.667541 -0.616269 +v 144.496567 164.346161 44.967758 1.000000 1.000000 1.000000 +vn -0.192221 -0.766415 -0.612910 +v 144.313736 164.414536 44.984959 1.000000 1.000000 1.000000 +vn -0.298910 -0.560135 -0.772594 +v 144.441208 164.386612 44.964558 1.000000 1.000000 1.000000 +vn 0.141597 -0.150036 -0.978488 +v 141.749084 163.587097 45.856159 1.000000 1.000000 1.000000 +vn 0.138103 -0.346650 -0.927772 +v 141.749084 163.882904 45.761959 1.000000 1.000000 1.000000 +vn 0.130667 -0.573059 -0.809030 +v 141.749084 163.884293 45.761360 1.000000 1.000000 1.000000 +vn -0.103743 -0.799104 -0.592174 +v 144.071701 164.121506 45.498959 1.000000 1.000000 1.000000 +vn 0.100998 -0.793896 -0.599607 +v 141.749084 164.121506 45.498959 1.000000 1.000000 1.000000 +vn 0.462015 -0.460716 -0.757815 +v 141.510895 163.863373 45.696556 1.000000 1.000000 1.000000 +vn 0.047063 -0.822501 -0.566813 +v 141.603592 164.406158 45.013359 1.000000 1.000000 1.000000 +vn -0.066171 -0.812591 -0.579066 +v 144.217178 164.406158 45.013359 1.000000 1.000000 1.000000 +vn -0.031699 -0.676254 -0.735986 +v 144.217178 164.556854 44.820759 1.000000 1.000000 1.000000 +vn 0.029563 -0.683272 -0.729565 +v 141.603592 164.556854 44.820759 1.000000 1.000000 1.000000 +vn -0.020257 -0.554119 -0.832191 +v 144.217178 164.648941 44.759357 1.000000 1.000000 1.000000 +vn 0.140941 -0.639076 -0.756120 +v 141.479996 164.561035 44.806759 1.000000 1.000000 1.000000 +vn 0.028415 -0.549900 -0.834747 +v 141.603592 164.648941 44.759357 1.000000 1.000000 1.000000 +vn 0.285351 -0.573576 -0.767845 +v 141.322922 164.519180 44.797558 1.000000 1.000000 1.000000 +vn 0.434471 -0.486272 -0.758138 +v 141.189026 164.422897 44.800159 1.000000 1.000000 1.000000 +vn 0.353122 -0.710174 -0.609063 +v 141.379562 164.386612 44.964558 1.000000 1.000000 1.000000 +vn 0.454975 -0.662540 -0.595012 +v 141.324203 164.346161 44.967758 1.000000 1.000000 1.000000 +vn 0.713501 -0.416661 -0.563303 +v 141.199326 164.188477 45.002159 1.000000 1.000000 1.000000 +vn 0.582477 -0.345712 -0.735666 +v 141.086029 164.274994 44.815376 1.000000 1.000000 1.000000 +vn 0.532491 -0.600062 -0.596974 +v 141.275284 164.309875 44.970360 1.000000 1.000000 1.000000 +vn 0.218578 -0.745889 -0.629184 +v 141.510895 164.016861 45.544960 1.000000 1.000000 1.000000 +vn 0.442837 -0.659949 -0.606928 +v 141.495438 164.009888 45.547760 1.000000 1.000000 1.000000 +vn 0.193909 -0.775649 -0.600640 +v 141.504456 164.414536 44.984360 1.000000 1.000000 1.000000 +vn 0.775171 -0.315982 -0.547052 +v 141.306183 163.801971 45.511757 1.000000 1.000000 1.000000 +vn 0.791799 -0.096460 -0.603117 +v 141.307465 163.587097 45.582760 1.000000 1.000000 1.000000 +vn 0.501244 -0.132198 -0.855148 +v 141.510895 163.587097 45.784760 1.000000 1.000000 1.000000 +vn 0.288181 -0.147500 -0.946148 +v 141.512177 163.587097 45.785156 1.000000 1.000000 1.000000 +vn 0.791799 0.096459 -0.603117 +v 141.307465 162.853149 45.582760 1.000000 1.000000 1.000000 +vn 0.891094 -0.070770 -0.448266 +v 141.306183 163.587097 45.580360 1.000000 1.000000 1.000000 +vn 0.891340 0.071354 -0.447684 +v 141.306183 162.853149 45.580360 1.000000 1.000000 1.000000 +vn 0.777137 0.313443 -0.545721 +v 141.306183 162.638275 45.511757 1.000000 1.000000 1.000000 +vn 0.931186 -0.068596 -0.358032 +v 141.165848 163.587097 45.278759 1.000000 1.000000 1.000000 +vn 0.900698 -0.161402 -0.403351 +v 141.272705 163.790817 45.445759 1.000000 1.000000 1.000000 +vn 0.930892 0.061475 -0.360086 +v 141.165848 162.853149 45.278759 1.000000 1.000000 1.000000 +vn 0.919074 -0.078287 -0.386231 +v 141.152969 163.613617 45.233559 1.000000 1.000000 1.000000 +vn 0.922756 0.080872 -0.376803 +v 141.152969 162.826645 45.233559 1.000000 1.000000 1.000000 +vn 0.901513 0.146209 -0.407305 +v 141.272705 162.649429 45.445759 1.000000 1.000000 1.000000 +vn 0.796641 0.321658 -0.511761 +v 141.150406 162.421997 45.062157 1.000000 1.000000 1.000000 +vn 0.817047 0.049625 -0.574431 +v 141.011353 162.826645 44.928757 1.000000 1.000000 1.000000 +vn 0.688603 0.243799 -0.682926 +v 141.017792 162.366180 44.844158 1.000000 1.000000 1.000000 +vn 0.873514 -0.205694 -0.441207 +v 141.136246 163.824295 45.140556 1.000000 1.000000 1.000000 +vn 0.816674 -0.038579 -0.575809 +v 141.011353 163.613617 44.928757 1.000000 1.000000 1.000000 +vn 0.758165 0.393461 -0.519976 +v 141.164551 162.374557 45.045357 1.000000 1.000000 1.000000 +vn 0.812133 0.344207 -0.471128 +v 141.288162 162.620132 45.469559 1.000000 1.000000 1.000000 +vn 0.675084 0.528577 -0.514653 +v 141.307465 162.603378 45.476776 1.000000 1.000000 1.000000 +vn 0.666357 0.482792 -0.568225 +v 141.200607 162.248978 45.001358 1.000000 1.000000 1.000000 +vn 0.500905 -0.024280 -0.865161 +v 140.806641 163.613617 44.726776 1.000000 1.000000 1.000000 +vn 0.748894 -0.159931 -0.643102 +v 140.994614 163.850815 44.882359 1.000000 1.000000 1.000000 +vn 0.444686 -0.090860 -0.891066 +v 140.806641 163.885696 44.714359 1.000000 1.000000 1.000000 +vn 0.801766 -0.342568 -0.489713 +v 141.176147 164.053131 45.053558 1.000000 1.000000 1.000000 +vn 0.674913 -0.542440 -0.500251 +v 141.307465 163.836868 45.476776 1.000000 1.000000 1.000000 +vn 0.813916 -0.350624 -0.463254 +v 141.288162 163.820114 45.469559 1.000000 1.000000 1.000000 +vn 0.736183 0.333970 0.588641 +v 152.566498 162.801529 54.648766 1.000000 1.000000 1.000000 +vn 0.680189 -0.361672 -0.637602 +v 152.566498 162.576874 54.027565 1.000000 1.000000 1.000000 +vn 0.774680 0.070909 0.628365 +v 152.566498 162.987106 54.572166 1.000000 1.000000 1.000000 +vn 0.736980 0.322997 0.593746 +v 152.566498 160.606659 56.285168 1.000000 1.000000 1.000000 +vn 0.649986 -0.084999 -0.755178 +v 152.566498 162.948029 53.874367 1.000000 1.000000 1.000000 +vn 0.717924 -0.465759 -0.517353 +v 152.566498 160.380615 55.664165 1.000000 1.000000 1.000000 +vn 0.738928 -0.200846 0.643153 +v 152.566498 163.179657 54.604568 1.000000 1.000000 1.000000 +vn 0.677891 0.219344 -0.701678 +v 152.566498 163.331757 53.939167 1.000000 1.000000 1.000000 +vn 0.672540 -0.202138 0.711920 +v 152.566498 169.822845 57.721180 1.000000 1.000000 1.000000 +vn 0.745165 0.182448 -0.641438 +v 152.566498 169.974945 57.055767 1.000000 1.000000 1.000000 +vn 0.641982 0.159328 0.749982 +v 152.566498 170.277725 57.773560 1.000000 1.000000 1.000000 +vn 0.786558 -0.128474 -0.604004 +v 152.566498 170.202362 57.082169 1.000000 1.000000 1.000000 +vn 0.655553 0.532502 0.535436 +v 152.566498 170.700500 57.523968 1.000000 1.000000 1.000000 +vn 0.766657 -0.452621 -0.455379 +v 152.566498 170.413071 56.957367 1.000000 1.000000 1.000000 +vn 0.667592 0.698883 0.256677 +v 152.566498 170.997726 57.026768 1.000000 1.000000 1.000000 +vn 0.751648 -0.618898 -0.228014 +v 152.566498 170.562363 56.708767 1.000000 1.000000 1.000000 +vn 0.186660 0.893751 0.407882 +v 152.566498 171.103760 56.390568 1.000000 1.000000 1.000000 +vn 0.376631 -0.898656 0.224872 +v 152.566498 170.615402 56.390568 1.000000 1.000000 1.000000 +vn 0.701763 0.055566 0.710240 +v 152.437744 160.142014 56.631168 1.000000 1.000000 1.000000 +vn 0.652507 -0.650450 -0.388781 +v 152.437744 159.917374 56.010166 1.000000 1.000000 1.000000 +vn 0.446206 -0.231505 0.864468 +v 152.083694 159.802948 56.884567 1.000000 1.000000 1.000000 +vn 0.395595 -0.880577 -0.260939 +v 152.083694 159.576904 56.263367 1.000000 1.000000 1.000000 +vn 0.124444 -0.318491 0.939722 +v 151.600876 159.678757 56.977165 1.000000 1.000000 1.000000 +vn 0.100795 -0.963938 -0.246298 +v 151.600876 159.452728 56.356167 1.000000 1.000000 1.000000 +vn -0.124370 -0.318507 0.939726 +v 134.219894 159.678757 56.977165 1.000000 1.000000 1.000000 +vn -0.100838 -0.963925 -0.246335 +v 134.219894 159.452728 56.356167 1.000000 1.000000 1.000000 +vn -0.446053 -0.232173 0.864368 +v 133.737091 159.802948 56.884567 1.000000 1.000000 1.000000 +vn -0.395072 -0.880504 -0.261976 +v 133.737091 159.576904 56.263367 1.000000 1.000000 1.000000 +vn 0.779439 -0.386271 0.493223 +v 152.566498 170.371201 45.449959 1.000000 1.000000 1.000000 +vn 0.646671 0.470305 -0.600524 +v 152.566498 170.615402 44.843758 1.000000 1.000000 1.000000 +vn 0.757617 -0.601928 0.252389 +v 152.566498 170.549805 45.706158 1.000000 1.000000 1.000000 +vn 0.662715 0.690628 -0.289555 +v 152.566498 170.972595 45.356159 1.000000 1.000000 1.000000 +vn 0.380805 -0.898329 -0.219073 +v 152.566498 170.615402 46.056160 1.000000 1.000000 1.000000 +vn 0.182636 0.891976 -0.413549 +v 152.566498 171.103760 46.056160 1.000000 1.000000 1.000000 +vn 0.745323 0.336453 -0.575580 +v 152.566498 159.470871 44.562359 1.000000 1.000000 1.000000 +vn 0.737243 0.352946 -0.576109 +v 152.566498 158.650406 43.883358 1.000000 1.000000 1.000000 +vn 0.704403 0.092581 -0.703736 +v 152.437744 158.196915 43.508358 1.000000 1.000000 1.000000 +vn 0.451600 -0.192867 -0.871126 +v 152.083694 157.864838 43.233757 1.000000 1.000000 1.000000 +vn 0.126766 -0.278679 -0.951981 +v 151.600876 157.743439 43.133358 1.000000 1.000000 1.000000 +vn -0.126794 -0.278690 -0.951975 +v 134.219894 157.743439 43.133358 1.000000 1.000000 1.000000 +vn -0.451567 -0.192898 -0.871136 +v 133.737091 157.864838 43.233757 1.000000 1.000000 1.000000 +vn -0.745323 0.336453 -0.575580 +v 133.254272 159.470871 44.562359 1.000000 1.000000 1.000000 +vn -0.704405 0.092591 -0.703733 +v 133.383026 158.196915 43.508358 1.000000 1.000000 1.000000 +vn -0.737244 0.352946 -0.576109 +v 133.254272 158.650406 43.883358 1.000000 1.000000 1.000000 +vn -0.646673 0.470306 -0.600522 +v 133.254272 170.615402 44.843781 1.000000 1.000000 1.000000 +vn -0.662715 0.690627 -0.289557 +v 133.254272 170.972595 45.356178 1.000000 1.000000 1.000000 +vn -0.182637 0.891976 -0.413549 +v 133.254272 171.103760 46.056179 1.000000 1.000000 1.000000 +vn -0.186660 0.893751 0.407882 +v 133.254272 171.103760 56.390572 1.000000 1.000000 1.000000 +vn 0.275270 0.614408 0.739412 +v 133.028961 171.169342 56.390572 1.000000 1.000000 1.000000 +vn 0.275270 0.614408 -0.739411 +v 133.028961 171.169342 46.056179 1.000000 1.000000 1.000000 +vn -0.275271 0.614408 -0.739411 +v 152.791809 171.169342 46.056160 1.000000 1.000000 1.000000 +vn -0.667592 0.698883 0.256677 +v 133.254272 170.997726 57.026772 1.000000 1.000000 1.000000 +vn -0.275270 0.614408 0.739411 +v 152.791809 171.169342 56.390568 1.000000 1.000000 1.000000 +vn -0.223443 0.640116 -0.735068 +v 154.080566 171.975845 46.056160 1.000000 1.000000 1.000000 +vn -0.223301 0.640162 0.735071 +v 154.080566 171.975845 56.390568 1.000000 1.000000 1.000000 +vn 0.281215 0.957452 -0.064840 +v 154.917435 172.499100 47.556160 1.000000 1.000000 1.000000 +vn 0.089260 0.798546 -0.595278 +v 154.499008 172.238174 46.257156 1.000000 1.000000 1.000000 +vn 0.281210 0.957451 0.064867 +v 154.917435 172.499100 54.890568 1.000000 1.000000 1.000000 +vn 0.266450 0.921971 0.281022 +v 154.805420 172.429321 55.640568 1.000000 1.000000 1.000000 +vn 0.088747 0.798722 0.595120 +v 154.499008 172.238174 56.189568 1.000000 1.000000 1.000000 +vn 0.267159 0.921692 -0.281264 +v 154.805420 172.429321 46.806160 1.000000 1.000000 1.000000 +vn -0.655554 0.532508 0.535428 +v 133.254272 170.700500 57.523972 1.000000 1.000000 1.000000 +vn -0.641976 0.159323 0.749989 +v 133.254272 170.277725 57.773579 1.000000 1.000000 1.000000 +vn -0.672544 -0.202151 0.711912 +v 133.254272 169.822845 57.721180 1.000000 1.000000 1.000000 +vn -0.738929 -0.200846 0.643153 +v 133.254272 163.179657 54.604568 1.000000 1.000000 1.000000 +vn -0.774680 0.070909 0.628365 +v 133.254272 162.987106 54.572166 1.000000 1.000000 1.000000 +vn -0.736183 0.333970 0.588641 +v 133.254272 162.801529 54.648766 1.000000 1.000000 1.000000 +vn -0.702370 0.055555 0.709641 +v 133.383026 160.142014 56.631168 1.000000 1.000000 1.000000 +vn -0.737040 0.322897 0.593725 +v 133.254272 160.606659 56.285168 1.000000 1.000000 1.000000 +vn -0.680189 -0.361672 -0.637602 +v 133.254272 162.576874 54.027565 1.000000 1.000000 1.000000 +vn -0.651856 -0.650558 -0.389690 +v 133.383026 159.917374 56.010166 1.000000 1.000000 1.000000 +vn -0.717927 -0.465849 -0.517268 +v 133.254272 160.380615 55.664165 1.000000 1.000000 1.000000 +vn -0.649986 -0.084999 -0.755177 +v 133.254272 162.948029 53.874367 1.000000 1.000000 1.000000 +vn -0.677891 0.219344 -0.701678 +v 133.254272 163.331757 53.939167 1.000000 1.000000 1.000000 +vn -0.745165 0.182448 -0.641437 +v 133.254272 169.974945 57.055771 1.000000 1.000000 1.000000 +vn -0.786558 -0.128474 -0.604005 +v 133.254272 170.202362 57.082172 1.000000 1.000000 1.000000 +vn -0.766658 -0.452621 -0.455379 +v 133.254272 170.413071 56.957371 1.000000 1.000000 1.000000 +vn -0.751648 -0.618898 -0.228014 +v 133.254272 170.562363 56.708771 1.000000 1.000000 1.000000 +vn -0.376631 -0.898656 0.224872 +v 133.254272 170.615402 56.390572 1.000000 1.000000 1.000000 +vn 0.205032 -0.706775 -0.677076 +v 152.799530 170.648880 46.056160 1.000000 1.000000 1.000000 +vn 0.205032 -0.706775 0.677075 +v 152.799530 170.648880 56.390568 1.000000 1.000000 1.000000 +vn -0.380805 -0.898329 -0.219073 +v 133.254272 170.615402 46.056179 1.000000 1.000000 1.000000 +vn -0.205032 -0.706775 0.677076 +v 133.021240 170.648880 56.390572 1.000000 1.000000 1.000000 +vn -0.757616 -0.601928 0.252390 +v 133.254272 170.549805 45.706177 1.000000 1.000000 1.000000 +vn -0.205032 -0.706775 -0.677076 +v 133.021240 170.648880 46.056179 1.000000 1.000000 1.000000 +vn -0.340113 -0.636752 0.692004 +v 132.803665 170.746567 56.390572 1.000000 1.000000 1.000000 +vn -0.340113 -0.636752 -0.692004 +v 132.803665 170.746567 46.056179 1.000000 1.000000 1.000000 +vn -0.779439 -0.386271 0.493224 +v 133.254272 170.371201 45.449978 1.000000 1.000000 1.000000 +vn 0.340113 -0.636753 -0.692004 +v 153.017105 170.746567 46.056160 1.000000 1.000000 1.000000 +vn 0.340113 -0.636752 0.692004 +v 153.017105 170.746567 56.390568 1.000000 1.000000 1.000000 +vn 0.471444 -0.496527 -0.728836 +v 154.305878 171.553055 46.056160 1.000000 1.000000 1.000000 +vn 0.471419 -0.496468 0.728892 +v 154.305878 171.553055 56.390568 1.000000 1.000000 1.000000 +vn 0.970369 -0.233725 -0.061285 +v 155.142746 172.076309 47.556160 1.000000 1.000000 1.000000 +vn 0.935905 -0.225491 -0.270622 +v 155.030731 172.006546 46.806160 1.000000 1.000000 1.000000 +vn 0.749395 -0.314561 -0.582631 +v 154.724319 171.813995 46.257156 1.000000 1.000000 1.000000 +vn 0.970376 -0.233711 0.061236 +v 155.142746 172.076309 54.890568 1.000000 1.000000 1.000000 +vn 0.749007 -0.313899 0.583486 +v 154.724319 171.813995 56.189568 1.000000 1.000000 1.000000 +vn 0.936273 -0.224042 0.270551 +v 155.030731 172.006546 55.640568 1.000000 1.000000 1.000000 +vn 0.223438 0.640117 0.735069 +v 131.740204 171.975845 56.390572 1.000000 1.000000 1.000000 +vn -0.471447 -0.496523 0.728837 +v 131.514893 171.553055 56.390572 1.000000 1.000000 1.000000 +vn -0.471419 -0.496468 -0.728892 +v 131.514893 171.553055 46.056179 1.000000 1.000000 1.000000 +vn 0.223300 0.640162 -0.735071 +v 131.740204 171.975845 46.056179 1.000000 1.000000 1.000000 +vn -0.749010 -0.313891 -0.583487 +v 131.096451 171.813995 46.257179 1.000000 1.000000 1.000000 +vn -0.088720 0.798736 -0.595105 +v 131.321777 172.238174 46.257179 1.000000 1.000000 1.000000 +vn -0.936272 -0.224040 -0.270555 +v 130.790039 172.006546 46.806179 1.000000 1.000000 1.000000 +vn -0.266450 0.921969 -0.281028 +v 131.015350 172.429321 46.806179 1.000000 1.000000 1.000000 +vn -0.970376 -0.233711 -0.061236 +v 130.678024 172.076309 47.556179 1.000000 1.000000 1.000000 +vn -0.281210 0.957451 -0.064867 +v 130.903336 172.499100 47.556179 1.000000 1.000000 1.000000 +vn -0.970369 -0.233725 0.061285 +v 130.678024 172.076309 54.890572 1.000000 1.000000 1.000000 +vn -0.281216 0.957452 0.064839 +v 130.903336 172.499100 54.890572 1.000000 1.000000 1.000000 +vn -0.935904 -0.225491 0.270624 +v 130.790039 172.006546 55.640572 1.000000 1.000000 1.000000 +vn -0.267173 0.921687 0.281268 +v 131.015350 172.429321 55.640572 1.000000 1.000000 1.000000 +vn -0.749395 -0.314556 0.582633 +v 131.096451 171.813995 56.189571 1.000000 1.000000 1.000000 +vn -0.089234 0.798554 0.595273 +v 131.321777 172.238174 56.189571 1.000000 1.000000 1.000000 +vn 0.680701 0.530898 0.504771 +v -140.998474 164.012665 45.911198 1.000000 1.000000 1.000000 +vn 0.679609 0.505441 0.531660 +v -140.840118 164.228943 45.472599 1.000000 1.000000 1.000000 +vn 0.531083 0.600877 0.597409 +v -141.110489 164.622437 45.449200 1.000000 1.000000 1.000000 +vn 0.427707 0.665264 0.611957 +v -141.317780 164.305695 46.031998 1.000000 1.000000 1.000000 +vn 0.780983 0.315664 0.538908 +v -140.994614 163.952667 45.970798 1.000000 1.000000 1.000000 +vn 0.818541 0.341882 0.461636 +v -140.966293 163.983383 45.898998 1.000000 1.000000 1.000000 +vn 0.397649 0.692950 0.601411 +v -141.145248 164.641968 45.449200 1.000000 1.000000 1.000000 +vn 0.433470 0.480414 0.762434 +v -141.087311 164.658707 45.398800 1.000000 1.000000 1.000000 +vn 0.212528 0.745637 0.631551 +v -141.343521 164.316864 46.027000 1.000000 1.000000 1.000000 +vn 0.461368 0.460245 0.758495 +v -141.343521 164.055923 46.285000 1.000000 1.000000 1.000000 +vn 0.282873 0.738184 0.612428 +v -141.295883 164.729874 45.449600 1.000000 1.000000 1.000000 +vn 0.097908 0.793173 0.601075 +v -141.749084 164.495453 45.948997 1.000000 1.000000 1.000000 +vn 0.082864 0.813292 0.575925 +v -141.603592 164.780106 45.463398 1.000000 1.000000 1.000000 +vn 0.225272 0.596707 0.770190 +v -141.281723 164.771729 45.398998 1.000000 1.000000 1.000000 +vn -0.104255 0.798995 0.592231 +v -144.071701 164.495453 45.948997 1.000000 1.000000 1.000000 +vn -0.058386 0.804746 0.590741 +v -144.217178 164.780106 45.463398 1.000000 1.000000 1.000000 +vn 0.132551 0.501260 0.855084 +v -141.749084 164.092209 46.394997 1.000000 1.000000 1.000000 +vn -0.033994 0.681130 0.731373 +v -144.217178 164.826157 45.405598 1.000000 1.000000 1.000000 +vn 0.064691 0.678261 0.731968 +v -141.603592 164.826157 45.405598 1.000000 1.000000 1.000000 +vn -0.224580 0.753873 0.617446 +v -144.477249 164.316864 46.027000 1.000000 1.000000 1.000000 +vn -0.158218 0.770712 0.617228 +v -144.374252 164.771729 45.454597 1.000000 1.000000 1.000000 +vn -0.126828 0.496873 0.858506 +v -144.071701 164.092209 46.394997 1.000000 1.000000 1.000000 +vn 0.138852 0.266034 0.953911 +v -141.749084 164.088028 46.395996 1.000000 1.000000 1.000000 +vn -0.138857 0.266033 0.953910 +v -144.071701 164.088028 46.395996 1.000000 1.000000 1.000000 +vn 0.141603 0.150623 0.978397 +v -141.749084 163.587097 46.556198 1.000000 1.000000 1.000000 +vn 0.287871 0.147655 0.946218 +v -141.346100 163.587097 46.435398 1.000000 1.000000 1.000000 +vn 0.715432 0.108863 0.690149 +v -140.998474 163.587097 46.091599 1.000000 1.000000 1.000000 +vn 0.501336 0.132126 0.855105 +v -141.343521 163.587097 46.434601 1.000000 1.000000 1.000000 +vn 0.715431 -0.108860 0.690151 +v -140.998474 162.853149 46.091599 1.000000 1.000000 1.000000 +vn 0.822054 0.089986 0.562255 +v -140.994614 163.587097 46.087399 1.000000 1.000000 1.000000 +vn 0.501336 -0.132126 0.855105 +v -141.343521 162.853149 46.434601 1.000000 1.000000 1.000000 +vn 0.905777 0.148677 0.396816 +v -140.940536 163.933136 45.858597 1.000000 1.000000 1.000000 +vn 0.821951 -0.089779 0.562438 +v -140.994614 162.853149 46.087399 1.000000 1.000000 1.000000 +vn 0.926743 0.065632 0.369918 +v -140.757721 163.587097 45.574600 1.000000 1.000000 1.000000 +vn 0.916485 0.097960 0.387891 +v -140.743561 163.613617 45.529400 1.000000 1.000000 1.000000 +vn 0.775691 0.361849 0.517077 +v -140.831100 164.216400 45.473396 1.000000 1.000000 1.000000 +vn 0.813992 0.076991 0.575752 +v -140.701065 163.613617 45.438000 1.000000 1.000000 1.000000 +vn 0.658558 0.279291 0.698783 +v -140.792480 164.234543 45.410400 1.000000 1.000000 1.000000 +vn 0.918675 -0.079344 0.386964 +v -140.743561 162.826645 45.529400 1.000000 1.000000 1.000000 +vn 0.926817 -0.059083 0.370835 +v -140.757721 162.853149 45.574600 1.000000 1.000000 1.000000 +vn 0.799547 -0.317299 0.509946 +v -140.804062 162.307571 45.480400 1.000000 1.000000 1.000000 +vn 0.903243 -0.162917 0.397001 +v -140.940536 162.507111 45.858597 1.000000 1.000000 1.000000 +vn 0.780327 -0.316536 0.539346 +v -140.994614 162.487564 45.970798 1.000000 1.000000 1.000000 +vn 0.681245 -0.258079 0.685055 +v -140.764160 162.292221 45.413799 1.000000 1.000000 1.000000 +vn 0.815914 -0.057648 0.575291 +v -140.701065 162.826645 45.438000 1.000000 1.000000 1.000000 +vn 0.734797 -0.446426 0.510663 +v -140.851700 162.223862 45.474800 1.000000 1.000000 1.000000 +vn 0.822121 -0.349940 0.449064 +v -140.966293 162.456879 45.898998 1.000000 1.000000 1.000000 +vn 0.686244 -0.528735 0.499509 +v -140.998474 162.427567 45.911198 1.000000 1.000000 1.000000 +vn 0.580789 -0.564660 0.586381 +v -141.064133 161.858276 45.450397 1.000000 1.000000 1.000000 +vn 0.471117 -0.452053 0.757428 +v -141.038391 161.824783 45.399399 1.000000 1.000000 1.000000 +vn 0.424520 -0.665454 0.613966 +v -141.317780 162.134552 46.031998 1.000000 1.000000 1.000000 +vn 0.468935 -0.449537 0.760274 +v -141.343521 162.384323 46.285000 1.000000 1.000000 1.000000 +vn 0.256368 -0.246846 0.934528 +v -141.007492 161.784317 45.367199 1.000000 1.000000 1.000000 +vn 0.389258 -0.148293 0.909113 +v -140.712662 162.272690 45.370998 1.000000 1.000000 1.000000 +vn 0.502505 -0.036259 0.863813 +v -140.640549 162.826645 45.377399 1.000000 1.000000 1.000000 +vn 0.499202 0.047612 0.865177 +v -140.640549 163.613617 45.377399 1.000000 1.000000 1.000000 +vn 0.135687 -0.009941 0.990702 +v -140.568451 162.826645 45.356197 1.000000 1.000000 1.000000 +vn 0.133666 0.012494 0.990948 +v -140.568451 163.613617 45.356197 1.000000 1.000000 1.000000 +vn 0.367312 0.158178 0.916549 +v -140.744843 164.258255 45.369999 1.000000 1.000000 1.000000 +vn 0.235489 0.262362 0.935795 +v -141.058990 164.700577 45.366997 1.000000 1.000000 1.000000 +vn 0.123298 0.327342 0.936827 +v -141.264984 164.820572 45.367199 1.000000 1.000000 1.000000 +vn 0.053022 0.558097 0.828080 +v -141.603592 164.852661 45.387199 1.000000 1.000000 1.000000 +vn 0.034328 0.375384 0.926234 +v -141.603592 164.880569 45.368797 1.000000 1.000000 1.000000 +vn -0.027026 0.558805 0.828859 +v -144.217178 164.852661 45.387199 1.000000 1.000000 1.000000 +vn -0.017942 0.380718 0.924517 +v -144.217178 164.880569 45.368797 1.000000 1.000000 1.000000 +vn -0.075582 0.354797 0.931883 +v -144.389709 164.866623 45.367798 1.000000 1.000000 1.000000 +vn -0.135768 0.644211 0.752701 +v -144.380692 164.814987 45.401398 1.000000 1.000000 1.000000 +vn -0.286379 0.571666 0.768886 +v -144.594406 164.746613 45.398598 1.000000 1.000000 1.000000 +vn -0.353846 0.705936 0.613553 +v -144.577667 164.706161 45.448799 1.000000 1.000000 1.000000 +vn -0.424680 0.665373 0.613943 +v -144.503006 164.305695 46.031998 1.000000 1.000000 1.000000 +vn -0.468944 0.449525 0.760275 +v -144.477249 164.055923 46.285000 1.000000 1.000000 1.000000 +vn -0.454916 0.663540 0.593941 +v -144.674240 164.639175 45.449600 1.000000 1.000000 1.000000 +vn 0.098877 -0.038547 0.994353 +v -140.657288 162.250366 45.356197 1.000000 1.000000 1.000000 +vn -0.005062 0.099826 0.994992 +v -144.217178 164.940567 45.356197 1.000000 1.000000 1.000000 +vn 0.008724 0.097133 0.995233 +v -141.603592 164.940567 45.356197 1.000000 1.000000 1.000000 +vn 0.031375 0.082976 0.996058 +v -141.246964 164.872192 45.356197 1.000000 1.000000 1.000000 +vn -0.018599 0.089660 0.995799 +v -144.398712 164.923828 45.356197 1.000000 1.000000 1.000000 +vn -0.039775 0.080443 0.995965 +v -144.635605 164.844299 45.356197 1.000000 1.000000 1.000000 +vn -0.379957 0.197596 0.903653 +v -152.566498 170.127029 45.356216 1.000000 1.000000 1.000000 +vn -0.061975 0.061035 0.996210 +v -144.846756 164.699188 45.356197 1.000000 1.000000 1.000000 +vn -0.156004 0.313291 0.936756 +v -144.615005 164.794052 45.366997 1.000000 1.000000 1.000000 +vn -0.049065 0.720111 0.692122 +v -159.003891 170.127029 45.356216 1.000000 1.000000 1.000000 +vn -0.098897 0.038555 0.994351 +v -145.163483 164.189880 45.356197 1.000000 1.000000 1.000000 +vn 0.379973 0.197579 0.903650 +v -133.254272 170.127029 45.356197 1.000000 1.000000 1.000000 +vn 0.057223 0.066121 0.996170 +v -141.029373 164.745224 45.356197 1.000000 1.000000 1.000000 +vn 0.048749 0.720043 0.692215 +v -126.816872 170.127029 45.356197 1.000000 1.000000 1.000000 +vn 0.090098 0.039577 0.995146 +v -140.692062 164.284760 45.356197 1.000000 1.000000 1.000000 +vn 0.595336 -0.266483 0.757999 +v -128.672897 164.188477 45.356197 1.000000 1.000000 1.000000 +vn 0.421824 -0.491903 0.761640 +v -128.101257 164.965683 45.356197 1.000000 1.000000 1.000000 +vn 0.153462 -0.625650 0.764861 +v -127.275223 165.396851 45.356197 1.000000 1.000000 1.000000 +vn 0.195804 0.708371 0.678138 +v -125.237267 169.912155 45.356197 1.000000 1.000000 1.000000 +vn 0.653914 -0.000001 0.756569 +v -128.876846 163.220123 45.356197 1.000000 1.000000 1.000000 +vn 0.595334 0.266484 0.758000 +v -128.672897 162.251755 45.356197 1.000000 1.000000 1.000000 +vn 0.421818 0.491907 0.761641 +v -128.101257 161.474564 45.356197 1.000000 1.000000 1.000000 +vn -0.077197 -0.675192 0.733591 +v -131.437637 159.715042 45.356197 1.000000 1.000000 1.000000 +vn 0.153458 0.625653 0.764859 +v -127.275223 161.043411 45.356197 1.000000 1.000000 1.000000 +vn 0.264863 -0.356020 0.896157 +v -133.254272 159.715042 45.356197 1.000000 1.000000 1.000000 +vn -0.280506 -0.587384 0.759142 +v -131.046249 159.624359 45.356197 1.000000 1.000000 1.000000 +vn -0.449614 -0.535169 0.715152 +v -130.723083 159.371796 45.356197 1.000000 1.000000 1.000000 +vn -0.410133 -0.611932 0.676262 +v -129.600418 158.358780 45.356197 1.000000 1.000000 1.000000 +vn -0.216929 -0.704903 0.675317 +v -128.263748 157.718323 45.356197 1.000000 1.000000 1.000000 +vn 0.000000 -0.737897 0.674913 +v -126.816872 157.499252 45.356197 1.000000 1.000000 1.000000 +vn -0.153457 0.625654 0.764858 +v -126.358528 161.043411 45.356197 1.000000 1.000000 1.000000 +vn 0.216988 -0.704900 0.675302 +v -125.370003 157.718323 45.356197 1.000000 1.000000 1.000000 +vn -0.421817 0.491907 0.761642 +v -125.532486 161.474564 45.356197 1.000000 1.000000 1.000000 +vn 0.410128 -0.611904 0.676291 +v -124.033859 158.358780 45.356197 1.000000 1.000000 1.000000 +vn -0.595334 0.266481 0.758001 +v -124.960846 162.251755 45.356197 1.000000 1.000000 1.000000 +vn 0.449260 -0.535336 0.715248 +v -122.910919 159.371796 45.356197 1.000000 1.000000 1.000000 +vn 0.280438 -0.587642 0.758967 +v -122.587112 159.624359 45.356197 1.000000 1.000000 1.000000 +vn 0.077337 -0.675120 0.733643 +v -122.196495 159.715042 45.356197 1.000000 1.000000 1.000000 +vn 0.074188 -0.724858 0.684892 +v -121.908607 159.715042 45.356197 1.000000 1.000000 1.000000 +vn 0.293966 -0.686650 0.664903 +v -121.551079 159.789001 45.356197 1.000000 1.000000 1.000000 +vn 0.720995 -0.123144 0.681910 +v -120.549805 161.965714 45.356197 1.000000 1.000000 1.000000 +vn -0.653916 -0.000001 0.756567 +v -124.756905 163.220123 45.356197 1.000000 1.000000 1.000000 +vn 0.669075 -0.310847 0.675066 +v -121.032089 160.322021 45.356197 1.000000 1.000000 1.000000 +vn 0.532336 -0.521487 0.666835 +v -121.244400 160.001083 45.356197 1.000000 1.000000 1.000000 +vn 0.729893 0.045895 0.682019 +v -120.458519 163.688950 45.356197 1.000000 1.000000 1.000000 +vn 0.699856 0.213454 0.681644 +v -120.764168 165.382889 45.356197 1.000000 1.000000 1.000000 +vn -0.595336 -0.266480 0.758000 +v -124.960846 164.188477 45.356197 1.000000 1.000000 1.000000 +vn 0.630284 0.372774 0.681016 +v -121.447563 166.940079 45.356197 1.000000 1.000000 1.000000 +vn -0.421823 -0.491903 0.761641 +v -125.532486 164.965683 45.356197 1.000000 1.000000 1.000000 +vn 0.521157 0.515781 0.679975 +v -122.466087 168.267044 45.356197 1.000000 1.000000 1.000000 +vn 0.374046 0.631733 0.678972 +v -123.756149 169.278671 45.356197 1.000000 1.000000 1.000000 +vn -0.153461 -0.625650 0.764860 +v -126.358528 165.396851 45.356197 1.000000 1.000000 1.000000 +vn 0.062000 -0.061058 0.996207 +v -140.974014 161.741074 45.356197 1.000000 1.000000 1.000000 +vn 0.039776 -0.080442 0.995965 +v -141.185165 161.595947 45.356197 1.000000 1.000000 1.000000 +vn 0.018599 -0.089662 0.995799 +v -141.422058 161.516418 45.356197 1.000000 1.000000 1.000000 +vn 0.005062 -0.099827 0.994992 +v -141.603592 161.499680 45.356197 1.000000 1.000000 1.000000 +vn -0.264862 -0.356024 0.896156 +v -152.566498 159.715042 45.356197 1.000000 1.000000 1.000000 +vn -0.669769 -0.262903 0.694472 +v -152.566498 159.461090 45.308399 1.000000 1.000000 1.000000 +vn 0.669768 -0.262903 0.694473 +v -133.254272 159.461090 45.308399 1.000000 1.000000 1.000000 +vn -0.008724 -0.097133 0.995233 +v -144.217178 161.499680 45.356197 1.000000 1.000000 1.000000 +vn -0.595333 0.266298 0.758066 +v -157.147354 162.251755 45.356216 1.000000 1.000000 1.000000 +vn 0.077197 -0.675195 0.733588 +v -154.383133 159.715042 45.356197 1.000000 1.000000 1.000000 +vn 0.280506 -0.587386 0.759140 +v -154.774521 159.624359 45.356197 1.000000 1.000000 1.000000 +vn -0.421728 0.491932 0.761675 +v -157.718994 161.474564 45.356216 1.000000 1.000000 1.000000 +vn 0.410156 -0.611910 0.676268 +v -156.220367 158.358780 45.356197 1.000000 1.000000 1.000000 +vn 0.449614 -0.535172 0.715149 +v -155.097687 159.371796 45.356197 1.000000 1.000000 1.000000 +vn -0.654058 -0.000001 0.756444 +v -156.943924 163.220123 45.356216 1.000000 1.000000 1.000000 +vn -0.034328 -0.375384 0.926234 +v -144.217178 161.559677 45.368797 1.000000 1.000000 1.000000 +vn -0.031372 -0.082964 0.996059 +v -144.573807 161.568054 45.356197 1.000000 1.000000 1.000000 +vn 0.017942 -0.380718 0.924517 +v -141.603592 161.559677 45.368797 1.000000 1.000000 1.000000 +vn 0.075577 -0.354803 0.931881 +v -141.431061 161.573624 45.367798 1.000000 1.000000 1.000000 +vn -0.053022 -0.558097 0.828080 +v -144.217178 161.587585 45.387199 1.000000 1.000000 1.000000 +vn -0.123293 -0.327346 0.936826 +v -144.555786 161.619675 45.367199 1.000000 1.000000 1.000000 +vn -0.235490 -0.262338 0.935801 +v -144.761795 161.739670 45.366997 1.000000 1.000000 1.000000 +vn -0.057231 -0.066130 0.996168 +v -144.791397 161.695023 45.356197 1.000000 1.000000 1.000000 +vn -0.225267 -0.596707 0.770192 +v -144.539047 161.668518 45.398998 1.000000 1.000000 1.000000 +vn 0.027026 -0.558805 0.828859 +v -141.603592 161.587585 45.387199 1.000000 1.000000 1.000000 +vn -0.064691 -0.678261 0.731968 +v -144.217178 161.614090 45.405598 1.000000 1.000000 1.000000 +vn 0.033994 -0.681130 0.731373 +v -141.603592 161.614090 45.405598 1.000000 1.000000 1.000000 +vn 0.135747 -0.644217 0.752700 +v -141.440079 161.625259 45.401398 1.000000 1.000000 1.000000 +vn -0.082864 -0.813300 0.575914 +v -144.217178 161.660141 45.463398 1.000000 1.000000 1.000000 +vn -0.282878 -0.738182 0.612428 +v -144.524887 161.710373 45.449600 1.000000 1.000000 1.000000 +vn -0.433410 -0.480430 0.762459 +v -144.733459 161.781540 45.398800 1.000000 1.000000 1.000000 +vn 0.058392 -0.804747 0.590740 +v -141.603592 161.660141 45.463398 1.000000 1.000000 1.000000 +vn -0.097927 -0.793172 0.601073 +v -144.071701 161.944778 45.948997 1.000000 1.000000 1.000000 +vn 0.158217 -0.770698 0.617246 +v -141.446518 161.668518 45.454597 1.000000 1.000000 1.000000 +vn 0.286347 -0.571629 0.768925 +v -141.226364 161.693619 45.398598 1.000000 1.000000 1.000000 +vn 0.224463 -0.753907 0.617447 +v -141.343521 162.123398 46.027000 1.000000 1.000000 1.000000 +vn 0.353795 -0.705849 0.613682 +v -141.243103 161.734100 45.448799 1.000000 1.000000 1.000000 +vn 0.104275 -0.798993 0.592230 +v -141.749084 161.944778 45.948997 1.000000 1.000000 1.000000 +vn -0.132556 -0.501252 0.855088 +v -144.071701 162.348038 46.394997 1.000000 1.000000 1.000000 +vn 0.126828 -0.496870 0.858508 +v -141.749084 162.348038 46.394997 1.000000 1.000000 1.000000 +vn -0.138857 -0.266033 0.953910 +v -144.071701 162.352219 46.395996 1.000000 1.000000 1.000000 +vn -0.461368 -0.460239 0.758498 +v -144.477249 162.384323 46.285000 1.000000 1.000000 1.000000 +vn 0.138852 -0.266033 0.953911 +v -141.749084 162.352219 46.395996 1.000000 1.000000 1.000000 +vn -0.141608 -0.150623 0.978397 +v -144.071701 162.853149 46.556198 1.000000 1.000000 1.000000 +vn -0.287876 -0.147655 0.946216 +v -144.474670 162.853149 46.435398 1.000000 1.000000 1.000000 +vn 0.141603 -0.150623 0.978397 +v -141.749084 162.853149 46.556198 1.000000 1.000000 1.000000 +vn 0.287871 -0.147655 0.946218 +v -141.346100 162.853149 46.435398 1.000000 1.000000 1.000000 +vn 0.454859 -0.663512 0.594016 +v -141.146530 161.801071 45.449600 1.000000 1.000000 1.000000 +vn 0.156030 -0.313336 0.936736 +v -141.205765 161.646194 45.366997 1.000000 1.000000 1.000000 +vn -0.780994 -0.315667 0.538891 +v -144.826157 162.487564 45.970798 1.000000 1.000000 1.000000 +vn -0.427470 -0.665388 0.611988 +v -144.503006 162.134552 46.031998 1.000000 1.000000 1.000000 +vn -0.212327 -0.745694 0.631552 +v -144.477249 162.123398 46.027000 1.000000 1.000000 1.000000 +vn -0.715431 -0.108860 0.690150 +v -144.822296 162.853149 46.091599 1.000000 1.000000 1.000000 +vn -0.501336 -0.132126 0.855105 +v -144.477249 162.853149 46.434601 1.000000 1.000000 1.000000 +vn -0.397645 -0.692951 0.601413 +v -144.675522 161.798279 45.449200 1.000000 1.000000 1.000000 +vn -0.531079 -0.600884 0.597406 +v -144.710281 161.817810 45.449200 1.000000 1.000000 1.000000 +vn -0.680812 -0.530804 0.504720 +v -144.822296 162.427567 45.911198 1.000000 1.000000 1.000000 +vn -0.677745 -0.504268 0.535141 +v -144.980652 162.211288 45.472599 1.000000 1.000000 1.000000 +vn -0.657571 -0.281413 0.698861 +v -145.028290 162.204330 45.410400 1.000000 1.000000 1.000000 +vn -0.369289 -0.158469 0.915704 +v -145.075928 162.182007 45.369999 1.000000 1.000000 1.000000 +vn -0.818642 -0.341757 0.461549 +v -144.854477 162.456879 45.898998 1.000000 1.000000 1.000000 +vn -0.774983 -0.359640 0.519674 +v -144.989670 162.223862 45.473396 1.000000 1.000000 1.000000 +vn -0.905777 -0.148692 0.396811 +v -144.880234 162.507111 45.858597 1.000000 1.000000 1.000000 +vn -0.916489 -0.097960 0.387881 +v -145.077209 162.826645 45.529400 1.000000 1.000000 1.000000 +vn -0.813969 -0.076904 0.575795 +v -145.119705 162.826645 45.438000 1.000000 1.000000 1.000000 +vn -0.926745 -0.065648 0.369911 +v -145.063049 162.853149 45.574600 1.000000 1.000000 1.000000 +vn -0.822055 -0.089983 0.562254 +v -144.826157 162.853149 46.087399 1.000000 1.000000 1.000000 +vn -0.821951 0.089783 0.562438 +v -144.826157 163.587097 46.087399 1.000000 1.000000 1.000000 +vn -0.715432 0.108863 0.690149 +v -144.822296 163.587097 46.091599 1.000000 1.000000 1.000000 +vn -0.918666 0.079353 0.386982 +v -145.077209 163.613617 45.529400 1.000000 1.000000 1.000000 +vn -0.926816 0.059078 0.370840 +v -145.063049 163.587097 45.574600 1.000000 1.000000 1.000000 +vn -0.799564 0.317266 0.509941 +v -145.016708 164.132675 45.480400 1.000000 1.000000 1.000000 +vn -0.815913 0.057645 0.575294 +v -145.119705 163.613617 45.438000 1.000000 1.000000 1.000000 +vn -0.681205 0.258072 0.685097 +v -145.056610 164.148026 45.413799 1.000000 1.000000 1.000000 +vn -0.780325 0.316518 0.539360 +v -144.826157 163.952667 45.970798 1.000000 1.000000 1.000000 +vn -0.903244 0.162890 0.397009 +v -144.880234 163.933136 45.858597 1.000000 1.000000 1.000000 +vn -0.686144 0.528818 0.499558 +v -144.822296 164.012665 45.911198 1.000000 1.000000 1.000000 +vn -0.822021 0.350060 0.449154 +v -144.854477 163.983383 45.898998 1.000000 1.000000 1.000000 +vn -0.734816 0.446427 0.510634 +v -144.969070 164.216400 45.474800 1.000000 1.000000 1.000000 +vn -0.580810 0.564695 0.586327 +v -144.756638 164.581970 45.450397 1.000000 1.000000 1.000000 +vn -0.471153 0.452076 0.757392 +v -144.782379 164.615448 45.399399 1.000000 1.000000 1.000000 +vn -0.256353 0.246814 0.934540 +v -144.813278 164.655914 45.367199 1.000000 1.000000 1.000000 +vn -0.389237 0.148287 0.909124 +v -145.108124 164.167557 45.370998 1.000000 1.000000 1.000000 +vn -0.502508 0.036255 0.863812 +v -145.180222 163.613617 45.377399 1.000000 1.000000 1.000000 +vn -0.135686 0.009941 0.990702 +v -145.252319 163.613617 45.356197 1.000000 1.000000 1.000000 +vn -0.499245 -0.047552 0.865155 +v -145.180222 162.826645 45.377399 1.000000 1.000000 1.000000 +vn -0.133666 -0.012494 0.990948 +v -145.252319 162.826645 45.356197 1.000000 1.000000 1.000000 +vn -0.090087 -0.039574 0.995147 +v -145.128708 162.155487 45.356197 1.000000 1.000000 1.000000 +vn -0.153390 -0.625707 0.764828 +v -158.545547 165.396851 45.356216 1.000000 1.000000 1.000000 +vn 0.153391 -0.625707 0.764828 +v -159.462250 165.396851 45.356216 1.000000 1.000000 1.000000 +vn -0.421735 -0.491926 0.761675 +v -157.718994 164.965683 45.356216 1.000000 1.000000 1.000000 +vn -0.595335 -0.266299 0.758064 +v -157.147354 164.188477 45.356216 1.000000 1.000000 1.000000 +vn -0.373866 0.631915 0.678902 +v -162.064240 169.278671 45.356216 1.000000 1.000000 1.000000 +vn 0.421736 -0.491928 0.761673 +v -160.288803 164.965683 45.356216 1.000000 1.000000 1.000000 +vn -0.195830 0.708213 0.678296 +v -160.583633 169.910751 45.356216 1.000000 1.000000 1.000000 +vn -0.521176 0.515769 0.679969 +v -163.354294 168.267044 45.356216 1.000000 1.000000 1.000000 +vn 0.595336 -0.266294 0.758065 +v -160.860443 164.188477 45.356216 1.000000 1.000000 1.000000 +vn -0.630252 0.372790 0.681036 +v -164.372696 166.940079 45.356216 1.000000 1.000000 1.000000 +vn -0.699767 0.213648 0.681675 +v -165.056351 165.382889 45.356216 1.000000 1.000000 1.000000 +vn 0.654066 -0.000001 0.756437 +v -161.063858 163.220123 45.356216 1.000000 1.000000 1.000000 +vn -0.729934 0.046030 0.681966 +v -165.362762 163.688950 45.356216 1.000000 1.000000 1.000000 +vn -0.720993 -0.123279 0.681888 +v -165.271347 161.965714 45.356216 1.000000 1.000000 1.000000 +vn 0.595334 0.266295 0.758067 +v -160.860443 162.251755 45.356216 1.000000 1.000000 1.000000 +vn -0.668988 -0.311019 0.675072 +v -164.788544 160.322021 45.356216 1.000000 1.000000 1.000000 +vn -0.532333 -0.521416 0.666894 +v -164.576126 160.001083 45.356216 1.000000 1.000000 1.000000 +vn -0.294037 -0.686674 0.664847 +v -164.269684 159.789001 45.356216 1.000000 1.000000 1.000000 +vn -0.074109 -0.724845 0.684914 +v -163.911774 159.715042 45.356216 1.000000 1.000000 1.000000 +vn -0.077197 -0.675192 0.733591 +v -163.624664 159.715042 45.356216 1.000000 1.000000 1.000000 +vn -0.280506 -0.587384 0.759142 +v -163.233276 159.624359 45.356216 1.000000 1.000000 1.000000 +vn -0.449612 -0.535171 0.715151 +v -162.910110 159.371796 45.356216 1.000000 1.000000 1.000000 +vn 0.421730 0.491932 0.761674 +v -160.288803 161.474564 45.356216 1.000000 1.000000 1.000000 +vn -0.410149 -0.611911 0.676271 +v -161.787430 158.358780 45.356216 1.000000 1.000000 1.000000 +vn 0.153387 0.625710 0.764826 +v -159.462250 161.043411 45.356216 1.000000 1.000000 1.000000 +vn -0.216950 -0.704907 0.675307 +v -160.451019 157.718323 45.356216 1.000000 1.000000 1.000000 +vn 0.000000 -0.737892 0.674918 +v -159.003891 157.499252 45.356216 1.000000 1.000000 1.000000 +vn -0.153387 0.625710 0.764826 +v -158.545547 161.043411 45.356216 1.000000 1.000000 1.000000 +vn 0.216954 -0.704904 0.675308 +v -157.556763 157.718323 45.356216 1.000000 1.000000 1.000000 +vn -0.287876 0.147655 0.946217 +v -144.474670 163.587097 46.435398 1.000000 1.000000 1.000000 +vn -0.501336 0.132126 0.855105 +v -144.477249 163.587097 46.434601 1.000000 1.000000 1.000000 +vn -0.141608 0.150623 0.978397 +v -144.071701 163.587097 46.556198 1.000000 1.000000 1.000000 +vn -0.690328 -0.416912 0.591296 +v -152.566498 159.226669 45.168598 1.000000 1.000000 1.000000 +vn 0.690328 -0.416912 0.591296 +v -133.254272 159.226669 45.168598 1.000000 1.000000 1.000000 +vn -0.717546 -0.490328 0.494677 +v -152.566498 158.404831 44.489597 1.000000 1.000000 1.000000 +vn 0.717551 -0.490404 0.494595 +v -133.254272 158.404831 44.489597 1.000000 1.000000 1.000000 +vn -0.101702 -0.973531 0.204680 +v -151.600876 157.499252 43.739597 1.000000 1.000000 1.000000 +vn -0.397672 -0.889921 0.223377 +v -152.083694 157.620651 43.840199 1.000000 1.000000 1.000000 +vn -0.652701 -0.666353 0.360493 +v -152.437744 157.952728 44.114597 1.000000 1.000000 1.000000 +vn 0.101729 -0.973521 0.204716 +v -134.219894 157.499252 43.739597 1.000000 1.000000 1.000000 +vn 0.652148 -0.666580 0.361073 +v -133.383026 157.952728 44.114597 1.000000 1.000000 1.000000 +vn 0.397516 -0.889796 0.224153 +v -133.737091 157.620651 43.840199 1.000000 1.000000 1.000000 +vn 0.141599 0.150036 -0.978488 +v -144.071701 162.853149 45.856197 1.000000 1.000000 1.000000 +vn -0.141590 0.150037 -0.978489 +v -141.749084 162.853149 45.856197 1.000000 1.000000 1.000000 +vn 0.138143 0.344829 -0.928445 +v -144.071701 162.557343 45.761997 1.000000 1.000000 1.000000 +vn 0.289431 0.147424 -0.945778 +v -144.308594 162.853149 45.785198 1.000000 1.000000 1.000000 +vn -0.138136 0.344829 -0.928446 +v -141.749084 162.557343 45.761997 1.000000 1.000000 1.000000 +vn -0.289423 0.147425 -0.945780 +v -141.512177 162.853149 45.785198 1.000000 1.000000 1.000000 +vn 0.125189 0.567244 -0.813979 +v -144.071701 162.555939 45.761398 1.000000 1.000000 1.000000 +vn 0.469707 0.449850 -0.759612 +v -144.309875 162.576874 45.696598 1.000000 1.000000 1.000000 +vn 0.289431 -0.147425 -0.945778 +v -144.308594 163.587097 45.785198 1.000000 1.000000 1.000000 +vn 0.141599 -0.150036 -0.978488 +v -144.071701 163.587097 45.856197 1.000000 1.000000 1.000000 +vn 0.138104 -0.346650 -0.927772 +v -144.071701 163.882904 45.761997 1.000000 1.000000 1.000000 +vn 0.462020 -0.460714 -0.757813 +v -144.309875 163.863373 45.696598 1.000000 1.000000 1.000000 +vn -0.141590 -0.150037 -0.978489 +v -141.749084 163.587097 45.856197 1.000000 1.000000 1.000000 +vn 0.775172 -0.316029 -0.547023 +v -144.514587 163.801971 45.511799 1.000000 1.000000 1.000000 +vn 0.442772 -0.660289 -0.606606 +v -144.325333 164.009888 45.547798 1.000000 1.000000 1.000000 +vn 0.791799 -0.096455 -0.603117 +v -144.513306 163.587097 45.582798 1.000000 1.000000 1.000000 +vn 0.502436 -0.132108 -0.854463 +v -144.309875 163.587097 45.784798 1.000000 1.000000 1.000000 +vn 0.130670 -0.573056 -0.809032 +v -144.071701 163.884293 45.761398 1.000000 1.000000 1.000000 +vn -0.138095 -0.346651 -0.927773 +v -141.749084 163.882904 45.761997 1.000000 1.000000 1.000000 +vn 0.502436 0.132108 -0.854462 +v -144.309875 162.853149 45.784798 1.000000 1.000000 1.000000 +vn 0.791799 0.096455 -0.603117 +v -144.513306 162.853149 45.582798 1.000000 1.000000 1.000000 +vn 0.891095 -0.070766 -0.448266 +v -144.514587 163.587097 45.580399 1.000000 1.000000 1.000000 +vn 0.891341 0.071350 -0.447684 +v -144.514587 162.853149 45.580399 1.000000 1.000000 1.000000 +vn 0.777138 0.313490 -0.545693 +v -144.514587 162.638275 45.511799 1.000000 1.000000 1.000000 +vn 0.931187 -0.068594 -0.358031 +v -144.654922 163.587097 45.278797 1.000000 1.000000 1.000000 +vn 0.900695 -0.161413 -0.403354 +v -144.548065 163.790817 45.445801 1.000000 1.000000 1.000000 +vn 0.930892 0.061473 -0.360085 +v -144.654922 162.853149 45.278797 1.000000 1.000000 1.000000 +vn 0.919073 -0.078283 -0.386233 +v -144.667801 163.613617 45.233597 1.000000 1.000000 1.000000 +vn 0.922756 0.080870 -0.376804 +v -144.667801 162.826645 45.233597 1.000000 1.000000 1.000000 +vn 0.901510 0.146219 -0.407309 +v -144.548065 162.649429 45.445801 1.000000 1.000000 1.000000 +vn 0.796642 0.321656 -0.511760 +v -144.670364 162.421997 45.062199 1.000000 1.000000 1.000000 +vn 0.817059 0.049624 -0.574414 +v -144.809418 162.826645 44.928799 1.000000 1.000000 1.000000 +vn 0.688629 0.243798 -0.682900 +v -144.802979 162.366180 44.844200 1.000000 1.000000 1.000000 +vn 0.873513 -0.205695 -0.441208 +v -144.684525 163.824295 45.140598 1.000000 1.000000 1.000000 +vn 0.816686 -0.038576 -0.575792 +v -144.809418 163.613617 44.928799 1.000000 1.000000 1.000000 +vn 0.500351 0.033211 -0.865185 +v -145.014130 162.826645 44.726799 1.000000 1.000000 1.000000 +vn 0.391426 0.142036 -0.909182 +v -144.969070 162.296417 44.704399 1.000000 1.000000 1.000000 +vn 0.758154 0.393470 -0.519985 +v -144.656219 162.374557 45.045399 1.000000 1.000000 1.000000 +vn 0.570335 0.380890 -0.727764 +v -144.733459 162.161072 44.814999 1.000000 1.000000 1.000000 +vn 0.812056 0.344353 -0.471153 +v -144.532608 162.620132 45.469597 1.000000 1.000000 1.000000 +vn 0.675021 0.528699 -0.514611 +v -144.513306 162.603378 45.476799 1.000000 1.000000 1.000000 +vn 0.666351 0.482791 -0.568233 +v -144.620163 162.248978 45.001396 1.000000 1.000000 1.000000 +vn 0.438411 0.482897 -0.758028 +v -144.630463 162.015945 44.800198 1.000000 1.000000 1.000000 +vn 0.316526 0.212818 -0.924402 +v -144.869934 162.056412 44.696800 1.000000 1.000000 1.000000 +vn 0.540563 0.597761 -0.592009 +v -144.542908 162.128967 44.970200 1.000000 1.000000 1.000000 +vn 0.435705 0.659745 -0.612289 +v -144.325333 162.430359 45.547798 1.000000 1.000000 1.000000 +vn 0.231141 0.753518 -0.615454 +v -144.309875 162.423386 45.544998 1.000000 1.000000 1.000000 +vn 0.417845 0.667520 -0.616297 +v -144.496567 162.094086 44.967796 1.000000 1.000000 1.000000 +vn 0.192230 0.766409 -0.612916 +v -144.313736 162.025726 44.985001 1.000000 1.000000 1.000000 +vn 0.298871 0.560013 -0.772698 +v -144.441208 162.053619 44.964600 1.000000 1.000000 1.000000 +vn 0.288936 0.572415 -0.767370 +v -144.497849 161.921066 44.797600 1.000000 1.000000 1.000000 +vn 0.066221 0.812588 -0.579065 +v -144.217178 162.034088 45.013397 1.000000 1.000000 1.000000 +vn 0.031737 0.676233 -0.736004 +v -144.217178 161.883392 44.820801 1.000000 1.000000 1.000000 +vn 0.134041 0.635843 -0.760090 +v -144.336914 161.879211 44.807198 1.000000 1.000000 1.000000 +vn 0.159660 0.314223 -0.935827 +v -144.564804 161.764786 44.692200 1.000000 1.000000 1.000000 +vn 0.237163 0.270738 -0.932982 +v -144.733459 161.882004 44.692799 1.000000 1.000000 1.000000 +vn 0.077613 0.355650 -0.931391 +v -144.363953 161.704788 44.694599 1.000000 1.000000 1.000000 +vn 0.060174 0.083158 -0.994718 +v -144.840317 161.745255 44.656197 1.000000 1.000000 1.000000 +vn 0.039248 0.077270 -0.996237 +v -144.635605 161.593155 44.656197 1.000000 1.000000 1.000000 +vn 0.065621 0.066513 -0.995625 +v -144.889252 161.781540 44.656197 1.000000 1.000000 1.000000 +vn -0.379968 -0.197582 -0.903651 +v -152.566498 159.715042 44.656197 1.000000 1.000000 1.000000 +vn 0.029101 0.098952 -0.994667 +v -144.392273 161.522003 44.656197 1.000000 1.000000 1.000000 +vn 0.015758 0.092597 -0.995579 +v -144.335632 161.505264 44.656197 1.000000 1.000000 1.000000 +vn 0.002369 0.102004 -0.994781 +v -144.217178 161.499680 44.656197 1.000000 1.000000 1.000000 +vn 0.016645 0.383203 -0.923514 +v -144.217178 161.699219 44.698196 1.000000 1.000000 1.000000 +vn 0.379970 -0.197583 -0.903650 +v -133.254272 159.715042 44.656197 1.000000 1.000000 1.000000 +vn -0.007562 0.098274 -0.995131 +v -141.603592 161.499680 44.656197 1.000000 1.000000 1.000000 +vn 0.595334 0.266484 -0.758000 +v -128.672897 162.251755 44.656197 1.000000 1.000000 1.000000 +vn -0.077197 -0.675193 -0.733591 +v -131.437637 159.715042 44.656197 1.000000 1.000000 1.000000 +vn 0.653895 -0.000001 -0.756585 +v -128.876846 163.220123 44.656197 1.000000 1.000000 1.000000 +vn -0.280505 -0.587384 -0.759142 +v -131.046249 159.624359 44.656197 1.000000 1.000000 1.000000 +vn 0.421818 0.491907 -0.761641 +v -128.101257 161.474564 44.656197 1.000000 1.000000 1.000000 +vn -0.410133 -0.611932 -0.676262 +v -129.600418 158.358780 44.656197 1.000000 1.000000 1.000000 +vn -0.449614 -0.535169 -0.715152 +v -130.723083 159.371796 44.656197 1.000000 1.000000 1.000000 +vn 0.153458 0.625653 -0.764859 +v -127.275223 161.043411 44.656197 1.000000 1.000000 1.000000 +vn -0.216929 -0.704903 -0.675317 +v -128.263748 157.718323 44.656197 1.000000 1.000000 1.000000 +vn -0.153457 0.625654 -0.764859 +v -126.358528 161.043411 44.656197 1.000000 1.000000 1.000000 +vn 0.000000 -0.737897 -0.674913 +v -126.816872 157.499252 44.656197 1.000000 1.000000 1.000000 +vn -0.421817 0.491907 -0.761642 +v -125.532486 161.474564 44.656197 1.000000 1.000000 1.000000 +vn 0.410128 -0.611904 -0.676291 +v -124.033859 158.358780 44.656197 1.000000 1.000000 1.000000 +vn 0.216988 -0.704900 -0.675302 +v -125.370003 157.718323 44.656197 1.000000 1.000000 1.000000 +vn -0.595333 0.266481 -0.758002 +v -124.960846 162.251755 44.656197 1.000000 1.000000 1.000000 +vn 0.449260 -0.535336 -0.715248 +v -122.910919 159.371796 44.656197 1.000000 1.000000 1.000000 +vn 0.280438 -0.587642 -0.758967 +v -122.587112 159.624359 44.656197 1.000000 1.000000 1.000000 +vn 0.077337 -0.675120 -0.733643 +v -122.196495 159.715042 44.656197 1.000000 1.000000 1.000000 +vn 0.074188 -0.724858 -0.684892 +v -121.908607 159.715042 44.656197 1.000000 1.000000 1.000000 +vn 0.293966 -0.686650 -0.664903 +v -121.551079 159.789001 44.656197 1.000000 1.000000 1.000000 +vn 0.532336 -0.521487 -0.666835 +v -121.244400 160.001083 44.656197 1.000000 1.000000 1.000000 +vn 0.669075 -0.310847 -0.675065 +v -121.032089 160.322021 44.656197 1.000000 1.000000 1.000000 +vn 0.720995 -0.123144 -0.681910 +v -120.549805 161.965714 44.656197 1.000000 1.000000 1.000000 +vn -0.653916 -0.000001 -0.756567 +v -124.756905 163.220123 44.656197 1.000000 1.000000 1.000000 +vn 0.729893 0.045895 -0.682019 +v -120.458519 163.688950 44.656197 1.000000 1.000000 1.000000 +vn -0.595336 -0.266480 -0.758000 +v -124.960846 164.188477 44.656197 1.000000 1.000000 1.000000 +vn 0.699856 0.213454 -0.681644 +v -120.764168 165.382889 44.656197 1.000000 1.000000 1.000000 +vn -0.421823 -0.491903 -0.761641 +v -125.532486 164.965683 44.656197 1.000000 1.000000 1.000000 +vn 0.521157 0.515781 -0.679975 +v -122.466087 168.267044 44.656197 1.000000 1.000000 1.000000 +vn 0.630284 0.372774 -0.681016 +v -121.447563 166.940079 44.656197 1.000000 1.000000 1.000000 +vn -0.153461 -0.625650 -0.764860 +v -126.358528 165.396851 44.656197 1.000000 1.000000 1.000000 +vn 0.374046 0.631733 -0.678972 +v -123.756149 169.278671 44.656197 1.000000 1.000000 1.000000 +vn 0.153462 -0.625650 -0.764861 +v -127.275223 165.396851 44.656197 1.000000 1.000000 1.000000 +vn 0.048749 0.720044 -0.692214 +v -126.816872 170.127029 44.656197 1.000000 1.000000 1.000000 +vn 0.195804 0.708371 -0.678138 +v -125.237267 169.912155 44.656197 1.000000 1.000000 1.000000 +vn 0.421825 -0.491902 -0.761640 +v -128.101257 164.965683 44.656197 1.000000 1.000000 1.000000 +vn 0.230707 0.408912 -0.882930 +v -133.254272 170.127029 44.656197 1.000000 1.000000 1.000000 +vn 0.595333 -0.266481 -0.758002 +v -128.672897 164.188477 44.656197 1.000000 1.000000 1.000000 +vn -0.230705 0.408908 -0.882932 +v -152.566498 170.127029 44.656197 1.000000 1.000000 1.000000 +vn -0.029946 0.082841 -0.996113 +v -141.283005 161.551300 44.656197 1.000000 1.000000 1.000000 +vn -0.051657 0.089856 -0.994614 +v -141.189026 161.605728 44.656197 1.000000 1.000000 1.000000 +vn -0.093514 -0.066336 -0.993406 +v -140.813080 164.489883 44.656197 1.000000 1.000000 1.000000 +vn -0.066743 -0.066754 -0.995535 +v -140.931519 164.657318 44.656197 1.000000 1.000000 1.000000 +vn -0.027653 -0.098441 -0.994759 +v -141.428497 164.918243 44.656197 1.000000 1.000000 1.000000 +vn -0.060563 -0.082106 -0.994782 +v -140.980453 164.694992 44.656197 1.000000 1.000000 1.000000 +vn -0.039251 -0.077277 -0.996237 +v -141.185165 164.847076 44.656197 1.000000 1.000000 1.000000 +vn -0.056293 0.070481 -0.995923 +v -141.015213 161.704788 44.656197 1.000000 1.000000 1.000000 +vn -0.078346 0.069902 -0.994473 +v -140.977875 161.746643 44.656197 1.000000 1.000000 1.000000 +vn -0.081735 0.052260 -0.995283 +v -140.791183 161.961533 44.656197 1.000000 1.000000 1.000000 +vn -0.109530 -0.028970 -0.993561 +v -140.618668 164.065704 44.656197 1.000000 1.000000 1.000000 +vn -0.115209 -0.041849 -0.992459 +v -140.674026 164.217789 44.656197 1.000000 1.000000 1.000000 +vn -0.091174 -0.049745 -0.994592 +v -140.730682 164.374069 44.656197 1.000000 1.000000 1.000000 +vn -0.099841 0.036809 -0.994322 +v -140.641846 162.292221 44.656197 1.000000 1.000000 1.000000 +vn -0.134762 0.023246 -0.990605 +v -140.603226 162.516876 44.656197 1.000000 1.000000 1.000000 +vn -0.131651 0.015189 -0.991180 +v -140.572311 162.695480 44.656197 1.000000 1.000000 1.000000 +vn -0.142265 0.002075 -0.989827 +v -140.568451 162.826645 44.656197 1.000000 1.000000 1.000000 +vn -0.138613 -0.007428 -0.990319 +v -140.568451 163.613617 44.656197 1.000000 1.000000 1.000000 +vn -0.075128 0.354835 -0.931906 +v -141.452957 161.704788 44.694599 1.000000 1.000000 1.000000 +vn -0.157670 0.313866 -0.936284 +v -141.255966 161.764786 44.692200 1.000000 1.000000 1.000000 +vn -0.243036 0.269011 -0.931969 +v -141.084732 161.884781 44.692799 1.000000 1.000000 1.000000 +vn -0.285360 0.573593 -0.767828 +v -141.322922 161.921066 44.797600 1.000000 1.000000 1.000000 +vn -0.327474 0.202030 -0.923008 +v -140.949554 162.060593 44.696800 1.000000 1.000000 1.000000 +vn -0.434488 0.486249 -0.758144 +v -141.189026 162.017349 44.800198 1.000000 1.000000 1.000000 +vn -0.444692 0.090838 -0.891065 +v -140.806641 162.554550 44.714397 1.000000 1.000000 1.000000 +vn -0.582464 0.345703 -0.735680 +v -141.086029 162.165253 44.815399 1.000000 1.000000 1.000000 +vn -0.455048 0.662500 -0.595000 +v -141.324203 162.094086 44.967796 1.000000 1.000000 1.000000 +vn -0.532468 0.600082 -0.596975 +v -141.275284 162.130371 44.970398 1.000000 1.000000 1.000000 +vn -0.353134 0.710162 -0.609070 +v -141.379562 162.053619 44.964600 1.000000 1.000000 1.000000 +vn -0.218584 0.745895 -0.629176 +v -141.510895 162.423386 45.544998 1.000000 1.000000 1.000000 +vn -0.442841 0.659952 -0.606923 +v -141.495438 162.430359 45.547798 1.000000 1.000000 1.000000 +vn -0.193877 0.775637 -0.600666 +v -141.504456 162.025726 44.984398 1.000000 1.000000 1.000000 +vn -0.140959 0.639095 -0.756101 +v -141.479996 161.879211 44.806801 1.000000 1.000000 1.000000 +vn -0.462020 0.460712 -0.757814 +v -141.510895 162.576874 45.696598 1.000000 1.000000 1.000000 +vn -0.101009 0.793903 -0.599595 +v -141.749084 162.318741 45.499001 1.000000 1.000000 1.000000 +vn -0.047129 0.822484 -0.566833 +v -141.603592 162.034088 45.013397 1.000000 1.000000 1.000000 +vn -0.029565 0.683241 -0.729594 +v -141.603592 161.883392 44.820801 1.000000 1.000000 1.000000 +vn -0.028450 0.549948 -0.834714 +v -141.603592 161.791290 44.759399 1.000000 1.000000 1.000000 +vn 0.103749 0.799110 -0.592164 +v -144.071701 162.318741 45.499001 1.000000 1.000000 1.000000 +vn -0.130732 0.571455 -0.810154 +v -141.749084 162.555939 45.761398 1.000000 1.000000 1.000000 +vn -0.502436 0.132108 -0.854463 +v -141.510895 162.853149 45.784798 1.000000 1.000000 1.000000 +vn 0.020350 0.554140 -0.832174 +v -144.217178 161.791290 44.759399 1.000000 1.000000 1.000000 +vn -0.018484 0.385550 -0.922502 +v -141.603592 161.699219 44.698196 1.000000 1.000000 1.000000 +vn -0.016500 0.104397 -0.994399 +v -141.423340 161.528976 44.656197 1.000000 1.000000 1.000000 +vn -0.015552 -0.093961 -0.995454 +v -141.485138 164.933594 44.656197 1.000000 1.000000 1.000000 +vn -0.002936 -0.101630 -0.994818 +v -141.603592 164.940567 44.656197 1.000000 1.000000 1.000000 +vn 0.007563 -0.098281 -0.995130 +v -144.217178 164.940567 44.656197 1.000000 1.000000 1.000000 +vn -0.421736 -0.491928 -0.761673 +v -157.718994 164.965683 44.656197 1.000000 1.000000 1.000000 +vn -0.049065 0.720111 -0.692122 +v -159.003891 170.127029 44.656197 1.000000 1.000000 1.000000 +vn -0.595336 -0.266299 -0.758063 +v -157.147354 164.188477 44.656197 1.000000 1.000000 1.000000 +vn -0.654043 -0.000001 -0.756457 +v -156.943924 163.220123 44.656197 1.000000 1.000000 1.000000 +vn 0.018501 -0.385480 -0.922531 +v -144.217178 164.741043 44.698196 1.000000 1.000000 1.000000 +vn 0.016502 -0.104399 -0.994399 +v -144.397430 164.911270 44.656197 1.000000 1.000000 1.000000 +vn -0.153391 -0.625707 -0.764828 +v -158.545547 165.396851 44.656197 1.000000 1.000000 1.000000 +vn -0.195830 0.708213 -0.678296 +v -160.583633 169.910751 44.656197 1.000000 1.000000 1.000000 +vn 0.153391 -0.625707 -0.764828 +v -159.462250 165.396851 44.656197 1.000000 1.000000 1.000000 +vn -0.373866 0.631915 -0.678902 +v -162.064240 169.278671 44.656197 1.000000 1.000000 1.000000 +vn 0.421736 -0.491928 -0.761673 +v -160.288803 164.965683 44.656197 1.000000 1.000000 1.000000 +vn -0.521176 0.515769 -0.679969 +v -163.354294 168.267044 44.656197 1.000000 1.000000 1.000000 +vn 0.595336 -0.266294 -0.758065 +v -160.860443 164.188477 44.656197 1.000000 1.000000 1.000000 +vn -0.630252 0.372790 -0.681036 +v -164.372696 166.940079 44.656197 1.000000 1.000000 1.000000 +vn 0.654067 -0.000001 -0.756437 +v -161.063858 163.220123 44.656197 1.000000 1.000000 1.000000 +vn -0.699767 0.213648 -0.681675 +v -165.056351 165.382889 44.656197 1.000000 1.000000 1.000000 +vn 0.595334 0.266295 -0.758067 +v -160.860443 162.251755 44.656197 1.000000 1.000000 1.000000 +vn -0.720993 -0.123279 -0.681888 +v -165.271347 161.965714 44.656197 1.000000 1.000000 1.000000 +vn -0.729934 0.046030 -0.681966 +v -165.362762 163.688950 44.656197 1.000000 1.000000 1.000000 +vn -0.668988 -0.311019 -0.675072 +v -164.788544 160.322021 44.656197 1.000000 1.000000 1.000000 +vn -0.532333 -0.521416 -0.666894 +v -164.576126 160.001083 44.656197 1.000000 1.000000 1.000000 +vn -0.294037 -0.686674 -0.664847 +v -164.269684 159.789001 44.656197 1.000000 1.000000 1.000000 +vn -0.074109 -0.724845 -0.684914 +v -163.911774 159.715042 44.656197 1.000000 1.000000 1.000000 +vn -0.077197 -0.675192 -0.733591 +v -163.624664 159.715042 44.656197 1.000000 1.000000 1.000000 +vn -0.280505 -0.587384 -0.759142 +v -163.233276 159.624359 44.656197 1.000000 1.000000 1.000000 +vn -0.449612 -0.535171 -0.715151 +v -162.910110 159.371796 44.656197 1.000000 1.000000 1.000000 +vn -0.410149 -0.611911 -0.676271 +v -161.787430 158.358780 44.656197 1.000000 1.000000 1.000000 +vn 0.421730 0.491932 -0.761674 +v -160.288803 161.474564 44.656197 1.000000 1.000000 1.000000 +vn -0.216950 -0.704906 -0.675307 +v -160.451019 157.718323 44.656197 1.000000 1.000000 1.000000 +vn 0.153387 0.625710 -0.764826 +v -159.462250 161.043411 44.656197 1.000000 1.000000 1.000000 +vn 0.000000 -0.737892 -0.674918 +v -159.003891 157.499252 44.656197 1.000000 1.000000 1.000000 +vn -0.153387 0.625710 -0.764826 +v -158.545547 161.043411 44.656197 1.000000 1.000000 1.000000 +vn 0.216951 -0.704906 -0.675307 +v -157.556763 157.718323 44.656197 1.000000 1.000000 1.000000 +vn 0.410150 -0.611910 -0.676271 +v -156.220367 158.358780 44.656197 1.000000 1.000000 1.000000 +vn -0.421730 0.491932 -0.761674 +v -157.718994 161.474564 44.656197 1.000000 1.000000 1.000000 +vn 0.449612 -0.535171 -0.715151 +v -155.097687 159.371796 44.656197 1.000000 1.000000 1.000000 +vn -0.595335 0.266301 -0.758064 +v -157.147354 162.251755 44.656197 1.000000 1.000000 1.000000 +vn 0.280506 -0.587384 -0.759142 +v -154.774521 159.624359 44.656197 1.000000 1.000000 1.000000 +vn 0.138613 0.007428 -0.990319 +v -145.252319 162.826645 44.656197 1.000000 1.000000 1.000000 +vn 0.109532 0.028969 -0.993561 +v -145.202103 162.374557 44.656197 1.000000 1.000000 1.000000 +vn 0.142265 -0.002075 -0.989827 +v -145.252319 163.613617 44.656197 1.000000 1.000000 1.000000 +vn 0.500900 -0.024263 -0.865165 +v -145.014130 163.613617 44.726799 1.000000 1.000000 1.000000 +vn 0.077197 -0.675192 -0.733591 +v -154.383133 159.715042 44.656197 1.000000 1.000000 1.000000 +vn 0.115207 0.041848 -0.992460 +v -145.146744 162.222458 44.656197 1.000000 1.000000 1.000000 +vn 0.748901 -0.159928 -0.643094 +v -144.826157 163.850815 44.882401 1.000000 1.000000 1.000000 +vn 0.801763 -0.342570 -0.489715 +v -144.644623 164.053131 45.053596 1.000000 1.000000 1.000000 +vn 0.674850 -0.542559 -0.500207 +v -144.513306 163.836868 45.476799 1.000000 1.000000 1.000000 +vn 0.713507 -0.416664 -0.563293 +v -144.621445 164.188477 45.002197 1.000000 1.000000 1.000000 +vn 0.813840 -0.350768 -0.463278 +v -144.532608 163.820114 45.469597 1.000000 1.000000 1.000000 +vn 0.454663 -0.663443 -0.594243 +v -144.496567 164.344757 44.967796 1.000000 1.000000 1.000000 +vn 0.526437 -0.604928 -0.597433 +v -144.545486 164.309875 44.970398 1.000000 1.000000 1.000000 +vn 0.582462 -0.345706 -0.735680 +v -144.734741 164.274994 44.815399 1.000000 1.000000 1.000000 +vn 0.433635 -0.486145 -0.758699 +v -144.631744 164.422897 44.800198 1.000000 1.000000 1.000000 +vn 0.359191 -0.707244 -0.608923 +v -144.441208 164.386612 44.964600 1.000000 1.000000 1.000000 +vn 0.219001 -0.746039 -0.628860 +v -144.309875 164.016861 45.544998 1.000000 1.000000 1.000000 +vn 0.285559 -0.572884 -0.768284 +v -144.497849 164.519180 44.797600 1.000000 1.000000 1.000000 +vn 0.243056 -0.269013 -0.931963 +v -144.736038 164.555450 44.692799 1.000000 1.000000 1.000000 +vn 0.157672 -0.313860 -0.936286 +v -144.564804 164.675461 44.692200 1.000000 1.000000 1.000000 +vn 0.327479 -0.202033 -0.923006 +v -144.871216 164.379639 44.696800 1.000000 1.000000 1.000000 +vn 0.078358 -0.069900 -0.994472 +v -144.842896 164.693588 44.656197 1.000000 1.000000 1.000000 +vn 0.056296 -0.070471 -0.995924 +v -144.805557 164.735458 44.656197 1.000000 1.000000 1.000000 +vn 0.444691 -0.090840 -0.891066 +v -145.014130 163.885696 44.714397 1.000000 1.000000 1.000000 +vn 0.099839 -0.036809 -0.994322 +v -145.178925 164.148026 44.656197 1.000000 1.000000 1.000000 +vn 0.081729 -0.052259 -0.995284 +v -145.029587 164.478714 44.656197 1.000000 1.000000 1.000000 +vn 0.131651 -0.015190 -0.991180 +v -145.248459 163.744766 44.656197 1.000000 1.000000 1.000000 +vn 0.134762 -0.023246 -0.990605 +v -145.217545 163.923370 44.656197 1.000000 1.000000 1.000000 +vn 0.051646 -0.089845 -0.994616 +v -144.631744 164.834534 44.656197 1.000000 1.000000 1.000000 +vn 0.029943 -0.082843 -0.996113 +v -144.537766 164.888947 44.656197 1.000000 1.000000 1.000000 +vn 0.075131 -0.354826 -0.931909 +v -144.367813 164.735458 44.694599 1.000000 1.000000 1.000000 +vn 0.140954 -0.639101 -0.756096 +v -144.340775 164.561035 44.806801 1.000000 1.000000 1.000000 +vn -0.016869 -0.383346 -0.923451 +v -141.603592 164.741043 44.698196 1.000000 1.000000 1.000000 +vn -0.077413 -0.355959 -0.931290 +v -141.456818 164.735458 44.694599 1.000000 1.000000 1.000000 +vn -0.159661 -0.314229 -0.935825 +v -141.255966 164.675461 44.692200 1.000000 1.000000 1.000000 +vn -0.237471 -0.270769 -0.932894 +v -141.087311 164.558243 44.692799 1.000000 1.000000 1.000000 +vn -0.316533 -0.212986 -0.924362 +v -140.950836 164.383835 44.696800 1.000000 1.000000 1.000000 +vn 0.091178 0.049748 -0.994591 +v -145.090088 162.066193 44.656197 1.000000 1.000000 1.000000 +vn 0.093775 0.066237 -0.993388 +v -145.007690 161.950378 44.656197 1.000000 1.000000 1.000000 +vn -0.125120 -0.568854 -0.812865 +v -141.749084 163.884293 45.761398 1.000000 1.000000 1.000000 +vn -0.469689 -0.449862 -0.759616 +v -141.510895 163.863373 45.696598 1.000000 1.000000 1.000000 +vn -0.289422 -0.147425 -0.945780 +v -141.512177 163.587097 45.785198 1.000000 1.000000 1.000000 +vn -0.103739 -0.799102 -0.592177 +v -141.749084 164.121506 45.499001 1.000000 1.000000 1.000000 +vn -0.231127 -0.753516 -0.615462 +v -141.510895 164.016861 45.544998 1.000000 1.000000 1.000000 +vn 0.101007 -0.793895 -0.599607 +v -144.071701 164.121506 45.499001 1.000000 1.000000 1.000000 +vn 0.047062 -0.822500 -0.566814 +v -144.217178 164.406158 45.013397 1.000000 1.000000 1.000000 +vn -0.066162 -0.812588 -0.579071 +v -141.603592 164.406158 45.013397 1.000000 1.000000 1.000000 +vn 0.193902 -0.775647 -0.600644 +v -144.316315 164.414536 44.984398 1.000000 1.000000 1.000000 +vn 0.029563 -0.683269 -0.729568 +v -144.217178 164.556854 44.820801 1.000000 1.000000 1.000000 +vn 0.028445 -0.549924 -0.834730 +v -144.217178 164.648941 44.759399 1.000000 1.000000 1.000000 +vn -0.020319 -0.554128 -0.832183 +v -141.603592 164.648941 44.759399 1.000000 1.000000 1.000000 +vn -0.031716 -0.676261 -0.735979 +v -141.603592 164.556854 44.820801 1.000000 1.000000 1.000000 +vn -0.134042 -0.635861 -0.760075 +v -141.483856 164.561035 44.807198 1.000000 1.000000 1.000000 +vn -0.192214 -0.766414 -0.612914 +v -141.507034 164.414536 44.985001 1.000000 1.000000 1.000000 +vn -0.288953 -0.572404 -0.767372 +v -141.322922 164.519180 44.797600 1.000000 1.000000 1.000000 +vn -0.438418 -0.482905 -0.758018 +v -141.190308 164.424286 44.800198 1.000000 1.000000 1.000000 +vn -0.417850 -0.667542 -0.616271 +v -141.324203 164.346161 44.967796 1.000000 1.000000 1.000000 +vn -0.298915 -0.560091 -0.772624 +v -141.379562 164.386612 44.964600 1.000000 1.000000 1.000000 +vn -0.570321 -0.380916 -0.727762 +v -141.087311 164.279190 44.814999 1.000000 1.000000 1.000000 +vn -0.540556 -0.597774 -0.592002 +v -141.277863 164.311279 44.970200 1.000000 1.000000 1.000000 +vn -0.391428 -0.142035 -0.909181 +v -140.851700 164.143829 44.704399 1.000000 1.000000 1.000000 +vn -0.758164 -0.393442 -0.519991 +v -141.164551 164.065704 45.045399 1.000000 1.000000 1.000000 +vn -0.666325 -0.482808 -0.568249 +v -141.200607 164.191269 45.001396 1.000000 1.000000 1.000000 +vn -0.688637 -0.243788 -0.682896 +v -141.017792 164.074066 44.844200 1.000000 1.000000 1.000000 +vn -0.435705 -0.659745 -0.612289 +v -141.495438 164.009888 45.547798 1.000000 1.000000 1.000000 +vn -0.675018 -0.528699 -0.514615 +v -141.307465 163.836868 45.476799 1.000000 1.000000 1.000000 +vn -0.777138 -0.313490 -0.545692 +v -141.306183 163.801971 45.511799 1.000000 1.000000 1.000000 +vn -0.812056 -0.344349 -0.471157 +v -141.288162 163.820114 45.469597 1.000000 1.000000 1.000000 +vn -0.901510 -0.146217 -0.407310 +v -141.272705 163.790817 45.445801 1.000000 1.000000 1.000000 +vn -0.930891 -0.061470 -0.360088 +v -141.165848 163.587097 45.278797 1.000000 1.000000 1.000000 +vn -0.796678 -0.321592 -0.511744 +v -141.150406 164.018250 45.062199 1.000000 1.000000 1.000000 +vn -0.922744 -0.080889 -0.376829 +v -141.152969 163.613617 45.233597 1.000000 1.000000 1.000000 +vn -0.919078 0.078280 -0.386222 +v -141.152969 162.826645 45.233597 1.000000 1.000000 1.000000 +vn -0.817059 -0.049626 -0.574414 +v -141.011353 163.613617 44.928799 1.000000 1.000000 1.000000 +vn -0.500351 -0.033212 -0.865185 +v -140.806641 163.613617 44.726799 1.000000 1.000000 1.000000 +vn -0.816686 0.038574 -0.575792 +v -141.011353 162.826645 44.928799 1.000000 1.000000 1.000000 +vn -0.500900 0.024262 -0.865165 +v -140.806641 162.826645 44.726799 1.000000 1.000000 1.000000 +vn -0.748904 0.159922 -0.643092 +v -140.994614 162.589432 44.882401 1.000000 1.000000 1.000000 +vn -0.873516 0.205681 -0.441209 +v -141.136246 162.615952 45.140598 1.000000 1.000000 1.000000 +vn -0.713495 0.416686 -0.563292 +v -141.199326 162.251755 45.002197 1.000000 1.000000 1.000000 +vn -0.801767 0.342564 -0.489715 +v -141.176147 162.387100 45.053596 1.000000 1.000000 1.000000 +vn -0.775172 0.316029 -0.547023 +v -141.306183 162.638275 45.511799 1.000000 1.000000 1.000000 +vn -0.674849 0.542554 -0.500214 +v -141.307465 162.603378 45.476799 1.000000 1.000000 1.000000 +vn -0.791799 0.096455 -0.603118 +v -141.307465 162.853149 45.582798 1.000000 1.000000 1.000000 +vn -0.502436 -0.132108 -0.854462 +v -141.510895 163.587097 45.784798 1.000000 1.000000 1.000000 +vn -0.791799 -0.096455 -0.603117 +v -141.307465 163.587097 45.582798 1.000000 1.000000 1.000000 +vn -0.891095 0.070766 -0.448266 +v -141.306183 162.853149 45.580399 1.000000 1.000000 1.000000 +vn -0.891340 -0.071350 -0.447684 +v -141.306183 163.587097 45.580399 1.000000 1.000000 1.000000 +vn -0.931188 0.068611 -0.358025 +v -141.165848 162.853149 45.278797 1.000000 1.000000 1.000000 +vn -0.900695 0.161410 -0.403355 +v -141.272705 162.649429 45.445801 1.000000 1.000000 1.000000 +vn -0.813840 0.350763 -0.463282 +v -141.288162 162.620132 45.469597 1.000000 1.000000 1.000000 +vn 0.736183 0.333970 0.588641 +v -133.254272 162.801529 54.648804 1.000000 1.000000 1.000000 +vn 0.680189 -0.361672 -0.637602 +v -133.254272 162.576874 54.027603 1.000000 1.000000 1.000000 +vn 0.774680 0.070909 0.628365 +v -133.254272 162.987106 54.572205 1.000000 1.000000 1.000000 +vn 0.736980 0.322997 0.593746 +v -133.254272 160.606659 56.285206 1.000000 1.000000 1.000000 +vn 0.649986 -0.084999 -0.755178 +v -133.254272 162.948029 53.874405 1.000000 1.000000 1.000000 +vn 0.717924 -0.465759 -0.517353 +v -133.254272 160.380615 55.664204 1.000000 1.000000 1.000000 +vn 0.738928 -0.200846 0.643153 +v -133.254272 163.179657 54.604607 1.000000 1.000000 1.000000 +vn 0.677891 0.219344 -0.701678 +v -133.254272 163.331757 53.939205 1.000000 1.000000 1.000000 +vn 0.672545 -0.202151 0.711912 +v -133.254272 169.822845 57.721199 1.000000 1.000000 1.000000 +vn 0.745165 0.182448 -0.641438 +v -133.254272 169.974945 57.055805 1.000000 1.000000 1.000000 +vn 0.641979 0.159313 0.749988 +v -133.254272 170.277725 57.773598 1.000000 1.000000 1.000000 +vn 0.786558 -0.128474 -0.604004 +v -133.254272 170.202362 57.082207 1.000000 1.000000 1.000000 +vn 0.655355 0.533187 0.534997 +v -133.254272 170.700500 57.524006 1.000000 1.000000 1.000000 +vn 0.766657 -0.452621 -0.455379 +v -133.254272 170.413071 56.957405 1.000000 1.000000 1.000000 +vn 0.668015 0.698519 0.256569 +v -133.254272 170.996307 57.026806 1.000000 1.000000 1.000000 +vn 0.751648 -0.618898 -0.228014 +v -133.254272 170.562363 56.708805 1.000000 1.000000 1.000000 +vn 0.186224 0.893562 0.408495 +v -133.254272 171.103760 56.390606 1.000000 1.000000 1.000000 +vn 0.376631 -0.898656 0.224872 +v -133.254272 170.615402 56.390606 1.000000 1.000000 1.000000 +vn 0.701760 0.055557 0.710244 +v -133.383026 160.142014 56.631207 1.000000 1.000000 1.000000 +vn 0.652505 -0.650454 -0.388776 +v -133.383026 159.917374 56.010204 1.000000 1.000000 1.000000 +vn 0.446202 -0.231504 0.864471 +v -133.737091 159.802948 56.884605 1.000000 1.000000 1.000000 +vn 0.395588 -0.880579 -0.260941 +v -133.737091 159.576904 56.263405 1.000000 1.000000 1.000000 +vn 0.779440 -0.386272 0.493221 +v -133.254272 170.371201 45.449997 1.000000 1.000000 1.000000 +vn 0.646672 0.470306 -0.600523 +v -133.254272 170.615402 44.843800 1.000000 1.000000 1.000000 +vn 0.757615 -0.601929 0.252388 +v -133.254272 170.549805 45.706200 1.000000 1.000000 1.000000 +vn 0.662715 0.690627 -0.289557 +v -133.254272 170.972595 45.356197 1.000000 1.000000 1.000000 +vn 0.380805 -0.898329 -0.219073 +v -133.254272 170.615402 46.056198 1.000000 1.000000 1.000000 +vn 0.182636 0.891976 -0.413549 +v -133.254272 171.103760 46.056198 1.000000 1.000000 1.000000 +vn 0.745325 0.336448 -0.575581 +v -133.254272 159.470871 44.562401 1.000000 1.000000 1.000000 +vn 0.737199 0.352982 -0.576144 +v -133.254272 158.650406 43.883400 1.000000 1.000000 1.000000 +vn 0.704401 0.092571 -0.703740 +v -133.383026 158.196915 43.508400 1.000000 1.000000 1.000000 +vn 0.451596 -0.192865 -0.871128 +v -133.737091 157.864838 43.233799 1.000000 1.000000 1.000000 +vn 0.126769 -0.278678 -0.951981 +v -134.219894 157.743439 43.133400 1.000000 1.000000 1.000000 +vn -0.126790 -0.278688 -0.951975 +v -151.600876 157.743439 43.133400 1.000000 1.000000 1.000000 +vn -0.745325 0.336448 -0.575581 +v -152.566498 159.470871 44.562401 1.000000 1.000000 1.000000 +vn -0.451570 -0.192899 -0.871134 +v -152.083694 157.864838 43.233799 1.000000 1.000000 1.000000 +vn -0.704356 0.092573 -0.703785 +v -152.437744 158.196915 43.508400 1.000000 1.000000 1.000000 +vn -0.737150 0.353108 -0.576129 +v -152.566498 158.650406 43.883400 1.000000 1.000000 1.000000 +vn -0.646671 0.470312 -0.600519 +v -152.566498 170.615402 44.843800 1.000000 1.000000 1.000000 +vn -0.662716 0.690629 -0.289550 +v -152.566498 170.972595 45.356216 1.000000 1.000000 1.000000 +vn -0.182637 0.891976 -0.413549 +v -152.566498 171.103760 46.056217 1.000000 1.000000 1.000000 +vn -0.186225 0.893562 0.408495 +v -152.566498 171.103760 56.390610 1.000000 1.000000 1.000000 +vn 0.275270 0.614408 0.739412 +v -152.791809 171.169342 56.390610 1.000000 1.000000 1.000000 +vn 0.275270 0.614408 -0.739411 +v -152.791809 171.169342 46.056217 1.000000 1.000000 1.000000 +vn -0.275271 0.614408 -0.739411 +v -133.028961 171.169342 46.056198 1.000000 1.000000 1.000000 +vn -0.668015 0.698519 0.256569 +v -152.566498 170.996307 57.026810 1.000000 1.000000 1.000000 +vn -0.275270 0.614408 0.739411 +v -133.028961 171.169342 56.390606 1.000000 1.000000 1.000000 +vn -0.655357 0.533192 0.534989 +v -152.566498 170.700500 57.524010 1.000000 1.000000 1.000000 +vn -0.641976 0.159323 0.749989 +v -152.566498 170.277725 57.773617 1.000000 1.000000 1.000000 +vn 0.223301 0.640162 -0.735071 +v -154.080566 171.975845 46.056217 1.000000 1.000000 1.000000 +vn 0.223038 0.640381 0.734960 +v -154.080566 171.975845 56.390610 1.000000 1.000000 1.000000 +vn -0.281210 0.957451 -0.064867 +v -154.917435 172.499100 47.556217 1.000000 1.000000 1.000000 +vn -0.266450 0.921971 -0.281022 +v -154.805420 172.429321 46.806217 1.000000 1.000000 1.000000 +vn -0.088747 0.798722 -0.595120 +v -154.499008 172.238174 46.257217 1.000000 1.000000 1.000000 +vn -0.281195 0.957452 0.064919 +v -154.917435 172.499100 54.890610 1.000000 1.000000 1.000000 +vn -0.090369 0.797951 0.595910 +v -154.499008 172.236771 56.189610 1.000000 1.000000 1.000000 +vn -0.264895 0.922319 0.281352 +v -154.805420 172.429321 55.640610 1.000000 1.000000 1.000000 +vn -0.672544 -0.202151 0.711913 +v -152.566498 169.822845 57.721218 1.000000 1.000000 1.000000 +vn -0.738929 -0.200846 0.643153 +v -152.566498 163.179657 54.604610 1.000000 1.000000 1.000000 +vn -0.774680 0.070909 0.628365 +v -152.566498 162.987106 54.572208 1.000000 1.000000 1.000000 +vn -0.736183 0.333970 0.588642 +v -152.566498 162.801529 54.648808 1.000000 1.000000 1.000000 +vn -0.702373 0.055564 0.709637 +v -152.437744 160.142014 56.631207 1.000000 1.000000 1.000000 +vn -0.446057 -0.232174 0.864366 +v -152.083694 159.802948 56.884605 1.000000 1.000000 1.000000 +vn -0.737040 0.322896 0.593725 +v -152.566498 160.606659 56.285206 1.000000 1.000000 1.000000 +vn -0.124366 -0.318507 0.939727 +v -151.600876 159.678757 56.977203 1.000000 1.000000 1.000000 +vn 0.124447 -0.318491 0.939721 +v -134.219894 159.678757 56.977203 1.000000 1.000000 1.000000 +vn -0.100835 -0.963925 -0.246336 +v -151.600876 159.452728 56.356205 1.000000 1.000000 1.000000 +vn 0.100798 -0.963938 -0.246297 +v -134.219894 159.452728 56.356205 1.000000 1.000000 1.000000 +vn -0.395078 -0.880501 -0.261974 +v -152.083694 159.576904 56.263405 1.000000 1.000000 1.000000 +vn -0.651857 -0.650554 -0.389695 +v -152.437744 159.917374 56.010204 1.000000 1.000000 1.000000 +vn -0.717927 -0.465849 -0.517268 +v -152.566498 160.380615 55.664204 1.000000 1.000000 1.000000 +vn -0.680188 -0.361670 -0.637604 +v -152.566498 162.576874 54.027603 1.000000 1.000000 1.000000 +vn -0.649987 -0.084996 -0.755177 +v -152.566498 162.948029 53.874409 1.000000 1.000000 1.000000 +vn -0.677891 0.219344 -0.701678 +v -152.566498 163.331757 53.939209 1.000000 1.000000 1.000000 +vn -0.745165 0.182448 -0.641437 +v -152.566498 169.974945 57.055809 1.000000 1.000000 1.000000 +vn -0.786558 -0.128474 -0.604005 +v -152.566498 170.202362 57.082211 1.000000 1.000000 1.000000 +vn -0.766658 -0.452621 -0.455379 +v -152.566498 170.413071 56.957409 1.000000 1.000000 1.000000 +vn -0.751648 -0.618898 -0.228014 +v -152.566498 170.562363 56.708809 1.000000 1.000000 1.000000 +vn -0.376631 -0.898656 0.224872 +v -152.566498 170.615402 56.390610 1.000000 1.000000 1.000000 +vn 0.205032 -0.706775 -0.677076 +v -133.021240 170.648880 46.056198 1.000000 1.000000 1.000000 +vn 0.205032 -0.706775 0.677075 +v -133.021240 170.648880 56.390606 1.000000 1.000000 1.000000 +vn -0.380803 -0.898329 -0.219075 +v -152.566498 170.615402 46.056217 1.000000 1.000000 1.000000 +vn -0.205032 -0.706775 0.677076 +v -152.799530 170.648880 56.390610 1.000000 1.000000 1.000000 +vn -0.757616 -0.601930 0.252385 +v -152.566498 170.549805 45.706200 1.000000 1.000000 1.000000 +vn -0.205032 -0.706775 -0.677076 +v -152.799530 170.648880 46.056217 1.000000 1.000000 1.000000 +vn -0.340113 -0.636752 0.692004 +v -153.017105 170.746567 56.390610 1.000000 1.000000 1.000000 +vn -0.340113 -0.636752 -0.692004 +v -153.017105 170.746567 46.056217 1.000000 1.000000 1.000000 +vn -0.471419 -0.496468 -0.728892 +v -154.305878 171.553055 46.056217 1.000000 1.000000 1.000000 +vn -0.471505 -0.496444 0.728853 +v -154.305878 171.553055 56.390610 1.000000 1.000000 1.000000 +vn -0.970376 -0.233711 -0.061236 +v -155.142746 172.076309 47.556217 1.000000 1.000000 1.000000 +vn -0.749007 -0.313899 -0.583486 +v -154.724319 171.813995 46.257217 1.000000 1.000000 1.000000 +vn -0.970369 -0.233725 0.061285 +v -155.142746 172.076309 54.890610 1.000000 1.000000 1.000000 +vn -0.935904 -0.225491 0.270624 +v -155.030731 172.006546 55.640610 1.000000 1.000000 1.000000 +vn -0.749361 -0.314295 0.582817 +v -154.724319 171.813995 56.189610 1.000000 1.000000 1.000000 +vn -0.936273 -0.224042 -0.270551 +v -155.030731 172.006546 46.806217 1.000000 1.000000 1.000000 +vn -0.779449 -0.386249 0.493226 +v -152.566498 170.371201 45.449997 1.000000 1.000000 1.000000 +vn 0.340113 -0.636753 -0.692004 +v -132.803665 170.746567 46.056198 1.000000 1.000000 1.000000 +vn 0.340113 -0.636752 0.692004 +v -132.803665 170.746567 56.390606 1.000000 1.000000 1.000000 +vn 0.471419 -0.496468 0.728892 +v -131.514893 171.553055 56.390606 1.000000 1.000000 1.000000 +vn -0.223300 0.640162 0.735071 +v -131.740204 171.975845 56.390606 1.000000 1.000000 1.000000 +vn -0.223438 0.640117 -0.735069 +v -131.740204 171.975845 46.056198 1.000000 1.000000 1.000000 +vn 0.471447 -0.496523 -0.728837 +v -131.514893 171.553055 46.056198 1.000000 1.000000 1.000000 +vn 0.089234 0.798554 -0.595273 +v -131.321777 172.238174 46.257198 1.000000 1.000000 1.000000 +vn 0.749395 -0.314556 -0.582633 +v -131.096451 171.813995 46.257198 1.000000 1.000000 1.000000 +vn 0.267173 0.921687 -0.281268 +v -131.015350 172.429321 46.806198 1.000000 1.000000 1.000000 +vn 0.935904 -0.225491 -0.270624 +v -130.790039 172.006546 46.806198 1.000000 1.000000 1.000000 +vn 0.281216 0.957452 -0.064839 +v -130.903336 172.499100 47.556198 1.000000 1.000000 1.000000 +vn 0.970369 -0.233725 -0.061285 +v -130.678024 172.076309 47.556198 1.000000 1.000000 1.000000 +vn 0.281210 0.957451 0.064867 +v -130.903336 172.499100 54.890606 1.000000 1.000000 1.000000 +vn 0.970376 -0.233711 0.061236 +v -130.678024 172.076309 54.890606 1.000000 1.000000 1.000000 +vn 0.266450 0.921970 0.281028 +v -131.015350 172.429321 55.640606 1.000000 1.000000 1.000000 +vn 0.936272 -0.224040 0.270555 +v -130.790039 172.006546 55.640606 1.000000 1.000000 1.000000 +vn 0.088720 0.798736 0.595105 +v -131.321777 172.238174 56.189606 1.000000 1.000000 1.000000 +vn 0.749010 -0.313891 0.583487 +v -131.096451 171.813995 56.189606 1.000000 1.000000 1.000000 +vn -0.980379 -0.023898 -0.195666 +v 120.148102 -156.477371 47.908119 1.000000 1.000000 1.000000 +vn -0.021751 -0.978030 -0.207328 +v 120.512337 -156.872269 47.908119 1.000000 1.000000 1.000000 +vn -0.019355 -0.998582 -0.049589 +v 120.408310 -156.985291 49.056137 1.000000 1.000000 1.000000 +vn -0.998749 -0.019272 -0.046145 +v 120.044212 -156.590408 49.056137 1.000000 1.000000 1.000000 +vn -0.909915 0.035107 -0.413306 +v 120.444229 -156.156464 46.934738 1.000000 1.000000 1.000000 +vn 0.044261 -0.900837 -0.431896 +v 120.808327 -156.551331 46.934738 1.000000 1.000000 1.000000 +vn -0.744964 0.181872 -0.641834 +v 120.887253 -155.676453 46.284519 1.000000 1.000000 1.000000 +vn 0.199999 -0.727520 -0.656289 +v 121.251350 -156.071335 46.284519 1.000000 1.000000 1.000000 +vn -0.567699 0.387884 -0.726129 +v 121.409843 -155.109955 46.056137 1.000000 1.000000 1.000000 +vn 0.417870 -0.537561 -0.732402 +v 121.773941 -155.504837 46.056137 1.000000 1.000000 1.000000 +vn -0.998748 -0.019282 0.046168 +v 120.044212 -156.590408 53.392719 1.000000 1.000000 1.000000 +vn -0.019302 -0.998583 0.049596 +v 120.408310 -156.985291 53.392719 1.000000 1.000000 1.000000 +vn -0.021849 -0.978029 0.207321 +v 120.512337 -156.872269 54.540730 1.000000 1.000000 1.000000 +vn -0.980386 -0.023767 0.195650 +v 120.148102 -156.477371 54.540730 1.000000 1.000000 1.000000 +vn 0.044102 -0.900834 0.431919 +v 120.808327 -156.551331 55.513927 1.000000 1.000000 1.000000 +vn -0.909950 0.035232 0.413219 +v 120.444229 -156.156464 55.513927 1.000000 1.000000 1.000000 +vn 0.199819 -0.727471 0.656398 +v 121.251350 -156.071335 56.164330 1.000000 1.000000 1.000000 +vn -0.744996 0.181826 0.641810 +v 120.887253 -155.676453 56.164330 1.000000 1.000000 1.000000 +vn 0.417896 -0.537558 0.732390 +v 121.773941 -155.504837 56.392727 1.000000 1.000000 1.000000 +vn -0.567702 0.387878 0.726130 +v 121.409843 -155.109955 56.392727 1.000000 1.000000 1.000000 +vn 0.074499 0.966175 -0.246894 +v 144.197861 -138.559906 56.411129 1.000000 1.000000 1.000000 +vn 0.093916 0.304704 0.947805 +v 144.197861 -138.822220 57.117329 1.000000 1.000000 1.000000 +vn 0.353080 0.261198 0.898393 +v 144.936874 -138.961761 57.010128 1.000000 1.000000 1.000000 +vn 0.299936 0.921468 -0.246852 +v 144.936874 -138.700821 56.303928 1.000000 1.000000 1.000000 +vn -0.074770 0.966196 -0.246728 +v 128.748093 -138.559906 56.411133 1.000000 1.000000 1.000000 +vn -0.094290 0.304835 0.947726 +v 128.748093 -138.822220 57.117332 1.000000 1.000000 1.000000 +vn -0.299935 0.921583 -0.246421 +v 128.009079 -138.700821 56.303932 1.000000 1.000000 1.000000 +vn -0.352902 0.261332 0.898424 +v 128.009079 -138.961761 57.010132 1.000000 1.000000 1.000000 +vn -0.532002 0.781328 -0.326345 +v 127.382462 -139.101288 55.998531 1.000000 1.000000 1.000000 +vn -0.603390 0.069735 0.794392 +v 127.382462 -139.362213 56.704933 1.000000 1.000000 1.000000 +vn -0.677664 0.596065 -0.430671 +v 126.963898 -139.699890 55.541531 1.000000 1.000000 1.000000 +vn -0.725319 -0.161384 0.669229 +v 126.963898 -139.962204 56.247932 1.000000 1.000000 1.000000 +vn -0.715955 0.460083 -0.525102 +v 126.816872 -140.407318 55.002731 1.000000 1.000000 1.000000 +vn -0.731272 -0.354389 0.582795 +v 126.816872 -140.669647 55.708931 1.000000 1.000000 1.000000 +vn -0.680071 0.368179 -0.633993 +v 126.816872 -141.617081 54.080933 1.000000 1.000000 1.000000 +vn -0.735885 -0.340917 0.585021 +v 126.816872 -141.879395 54.787331 1.000000 1.000000 1.000000 +vn -0.775654 -0.076412 0.626516 +v 126.816872 -142.064987 54.707932 1.000000 1.000000 1.000000 +vn -0.649623 0.090766 -0.754819 +v 126.816872 -142.017532 53.911133 1.000000 1.000000 1.000000 +vn -0.739221 0.198185 0.643642 +v 126.816872 -142.258926 54.739532 1.000000 1.000000 1.000000 +vn -0.677604 -0.216472 -0.702846 +v 126.816872 -142.431961 53.978733 1.000000 1.000000 1.000000 +vn -0.672564 0.200236 0.712435 +v 126.816872 -148.871414 57.819317 1.000000 1.000000 1.000000 +vn -0.745143 -0.180710 -0.641954 +v 126.816872 -149.044434 57.058331 1.000000 1.000000 1.000000 +vn -0.642047 -0.160946 0.749581 +v 126.816872 -149.358383 57.874138 1.000000 1.000000 1.000000 +vn -0.786403 0.129743 -0.603934 +v 126.816872 -149.271881 57.084129 1.000000 1.000000 1.000000 +vn -0.655522 -0.533571 0.534408 +v 126.816872 -149.810471 57.606140 1.000000 1.000000 1.000000 +vn -0.766951 0.453554 -0.453954 +v 126.816872 -149.482574 56.958927 1.000000 1.000000 1.000000 +vn -0.667933 -0.698699 0.256292 +v 126.816872 -150.127213 57.073730 1.000000 1.000000 1.000000 +vn -0.751162 0.619827 -0.227089 +v 126.816872 -149.630478 56.710529 1.000000 1.000000 1.000000 +vn -0.205747 -0.895855 0.393843 +v 126.816872 -150.241638 56.392727 1.000000 1.000000 1.000000 +vn -0.396564 0.893398 0.211134 +v 126.816872 -149.683502 56.392727 1.000000 1.000000 1.000000 +vn 0.603531 0.069913 0.794269 +v 145.563873 -139.362213 56.704929 1.000000 1.000000 1.000000 +vn 0.532268 0.781215 -0.326182 +v 145.563873 -139.101288 55.998528 1.000000 1.000000 1.000000 +vn 0.725642 -0.161060 0.668957 +v 145.982315 -139.962204 56.247929 1.000000 1.000000 1.000000 +vn 0.677514 0.596109 -0.430847 +v 145.982315 -139.699890 55.541527 1.000000 1.000000 1.000000 +vn 0.731247 -0.354527 0.582742 +v 146.129089 -140.669647 55.708927 1.000000 1.000000 1.000000 +vn 0.716018 0.460038 -0.525055 +v 146.129089 -140.407318 55.002728 1.000000 1.000000 1.000000 +vn 0.735886 -0.340917 0.585020 +v 146.129089 -141.879395 54.787327 1.000000 1.000000 1.000000 +vn 0.680085 0.368140 -0.634002 +v 146.129089 -141.617081 54.080929 1.000000 1.000000 1.000000 +vn 0.775653 -0.076413 0.626517 +v 146.129089 -142.064987 54.707928 1.000000 1.000000 1.000000 +vn 0.649622 0.090766 -0.754820 +v 146.129089 -142.017532 53.911129 1.000000 1.000000 1.000000 +vn 0.739221 0.198185 0.643642 +v 146.129089 -142.258926 54.739529 1.000000 1.000000 1.000000 +vn 0.677604 -0.216472 -0.702846 +v 146.129089 -142.431961 53.978729 1.000000 1.000000 1.000000 +vn 0.672564 0.200236 0.712434 +v 146.129089 -148.871414 57.819317 1.000000 1.000000 1.000000 +vn 0.745144 -0.180710 -0.641954 +v 146.129089 -149.044434 57.058331 1.000000 1.000000 1.000000 +vn 0.786402 0.129744 -0.603935 +v 146.129089 -149.271881 57.084129 1.000000 1.000000 1.000000 +vn 0.642047 -0.160945 0.749581 +v 146.129089 -149.358383 57.874138 1.000000 1.000000 1.000000 +vn 0.766952 0.453554 -0.453953 +v 146.129089 -149.482574 56.958927 1.000000 1.000000 1.000000 +vn 0.655522 -0.533571 0.534409 +v 146.129089 -149.810471 57.606140 1.000000 1.000000 1.000000 +vn 0.751163 0.619827 -0.227089 +v 146.129089 -149.630478 56.710529 1.000000 1.000000 1.000000 +vn 0.667932 -0.698699 0.256292 +v 146.129089 -150.127213 57.073730 1.000000 1.000000 1.000000 +vn 0.726172 0.685165 -0.056767 +v 146.129089 -149.683502 56.392727 1.000000 1.000000 1.000000 +vn 0.688864 -0.722381 0.060267 +v 146.129089 -150.241638 56.392727 1.000000 1.000000 1.000000 +vn 0.687007 -0.723580 -0.066740 +v 146.129089 -150.241638 46.056137 1.000000 1.000000 1.000000 +vn 0.728527 0.682082 0.063349 +v 146.129089 -149.683502 46.056137 1.000000 1.000000 1.000000 +vn 0.757622 0.601928 0.252372 +v 146.129089 -149.617920 45.706120 1.000000 1.000000 1.000000 +vn 0.662472 -0.690832 -0.289623 +v 146.129089 -150.102097 45.306137 1.000000 1.000000 1.000000 +vn 0.779448 0.386248 0.493228 +v 146.129089 -149.439316 45.449921 1.000000 1.000000 1.000000 +vn 0.646784 -0.469880 -0.600736 +v 146.129089 -149.718384 44.757137 1.000000 1.000000 1.000000 +vn 0.379958 -0.197595 0.903653 +v 146.129089 -149.195145 45.356140 1.000000 1.000000 1.000000 +vn 0.230706 -0.408915 -0.882929 +v 146.129089 -149.195145 44.556137 1.000000 1.000000 1.000000 +vn 0.715714 0.480105 0.507202 +v 146.129089 -137.191071 44.256138 1.000000 1.000000 1.000000 +vn 0.731584 -0.377594 -0.567634 +v 146.129089 -137.470154 43.563316 1.000000 1.000000 1.000000 +vn 0.727146 -0.188362 -0.660136 +v 145.982315 -136.776657 42.989338 1.000000 1.000000 1.000000 +vn 0.677419 0.611002 0.409610 +v 145.982315 -136.497589 43.682137 1.000000 1.000000 1.000000 +vn 0.672516 0.373434 0.638960 +v 146.129089 -138.278046 45.155136 1.000000 1.000000 1.000000 +vn 0.745329 -0.336445 -0.575578 +v 146.129089 -138.557114 44.462337 1.000000 1.000000 1.000000 +vn 0.379973 0.197580 -0.903650 +v 146.129089 -138.801285 44.556137 1.000000 1.000000 1.000000 +vn 0.230706 0.408914 0.882929 +v 146.129089 -138.801285 45.356140 1.000000 1.000000 1.000000 +vn 0.607095 0.037344 -0.793751 +v 145.563873 -136.189224 42.502720 1.000000 1.000000 1.000000 +vn 0.533555 0.790868 0.299746 +v 145.563873 -135.910156 43.195538 1.000000 1.000000 1.000000 +vn 0.356941 0.228233 -0.905816 +v 144.936874 -135.795746 42.177521 1.000000 1.000000 1.000000 +vn 0.301895 0.928798 0.214928 +v 144.936874 -135.516678 42.870319 1.000000 1.000000 1.000000 +vn 0.095875 0.272971 -0.957233 +v 144.197861 -135.657608 42.063316 1.000000 1.000000 1.000000 +vn 0.075176 0.973973 0.213833 +v 144.197861 -135.378540 42.756138 1.000000 1.000000 1.000000 +vn -0.095877 0.272969 -0.957233 +v 128.748093 -135.657608 42.063339 1.000000 1.000000 1.000000 +vn -0.075177 0.973975 0.213825 +v 128.748093 -135.378540 42.756138 1.000000 1.000000 1.000000 +vn -0.357043 0.228218 -0.905780 +v 128.009079 -135.795746 42.177540 1.000000 1.000000 1.000000 +vn -0.302000 0.928764 0.214927 +v 128.009079 -135.516678 42.870338 1.000000 1.000000 1.000000 +vn -0.607126 0.037249 -0.793732 +v 127.382462 -136.189224 42.502739 1.000000 1.000000 1.000000 +vn -0.533563 0.790845 0.299792 +v 127.382462 -135.910156 43.195538 1.000000 1.000000 1.000000 +vn -0.727090 -0.188270 -0.660223 +v 126.963898 -136.776657 42.989338 1.000000 1.000000 1.000000 +vn -0.677339 0.611129 0.409553 +v 126.963898 -136.497589 43.682137 1.000000 1.000000 1.000000 +vn -0.731622 -0.377461 -0.567673 +v 126.816872 -137.470154 43.563339 1.000000 1.000000 1.000000 +vn -0.715725 0.480155 0.507138 +v 126.816872 -137.191071 44.256138 1.000000 1.000000 1.000000 +vn -0.745329 -0.336443 -0.575579 +v 126.816872 -138.557114 44.462337 1.000000 1.000000 1.000000 +vn -0.672516 0.373434 0.638960 +v 126.816872 -138.278046 45.155136 1.000000 1.000000 1.000000 +vn -0.750549 -0.120507 -0.649734 +v 126.816872 -138.801285 44.556137 1.000000 1.000000 1.000000 +vn -0.668272 0.135660 0.731443 +v 126.816872 -138.801285 45.356140 1.000000 1.000000 1.000000 +vn -0.668273 -0.135658 -0.731442 +v 126.816872 -149.195145 44.556137 1.000000 1.000000 1.000000 +vn -0.750540 0.120486 0.649748 +v 126.816872 -149.195145 45.356140 1.000000 1.000000 1.000000 +vn -0.779448 0.386248 0.493228 +v 126.816872 -149.439316 45.449921 1.000000 1.000000 1.000000 +vn -0.646784 -0.469880 -0.600736 +v 126.816872 -149.718384 44.757137 1.000000 1.000000 1.000000 +vn -0.757623 0.601927 0.252372 +v 126.816872 -149.617920 45.706120 1.000000 1.000000 1.000000 +vn -0.662472 -0.690832 -0.289623 +v 126.816872 -150.102097 45.306137 1.000000 1.000000 1.000000 +vn -0.400639 0.892925 -0.205360 +v 126.816872 -149.683502 46.056137 1.000000 1.000000 1.000000 +vn -0.202270 -0.894440 -0.398828 +v 126.816872 -150.241638 46.056137 1.000000 1.000000 1.000000 +vn 0.068640 0.723916 -0.686465 +v 164.245224 -138.801285 44.556118 1.000000 1.000000 1.000000 +vn 0.068640 0.723916 0.686465 +v 164.245224 -138.801285 45.356117 1.000000 1.000000 1.000000 +vn 0.273723 0.692486 0.667487 +v 164.332779 -138.818039 45.356117 1.000000 1.000000 1.000000 +vn 0.273723 0.692486 -0.667487 +v 164.332779 -138.818039 44.556118 1.000000 1.000000 1.000000 +vn 0.081268 0.673059 -0.735110 +v 163.260315 -138.801285 44.556118 1.000000 1.000000 1.000000 +vn 0.081268 0.673059 0.735110 +v 163.260315 -138.801285 45.356117 1.000000 1.000000 1.000000 +vn 0.292015 0.578743 -0.761436 +v 163.152161 -138.774780 44.556118 1.000000 1.000000 1.000000 +vn 0.292015 0.578743 0.761436 +v 163.152161 -138.774780 45.356117 1.000000 1.000000 1.000000 +vn 0.467028 0.519079 -0.715850 +v 163.063324 -138.700821 44.556118 1.000000 1.000000 1.000000 +vn 0.467028 0.519079 0.715850 +v 163.063324 -138.700821 45.356117 1.000000 1.000000 1.000000 +vn 0.429153 0.600294 -0.674889 +v 161.917465 -137.587357 44.556118 1.000000 1.000000 1.000000 +vn 0.429162 0.600291 0.674886 +v 161.917465 -137.587357 45.356117 1.000000 1.000000 1.000000 +vn 0.228404 0.702782 -0.673742 +v 160.525696 -136.879913 44.556137 1.000000 1.000000 1.000000 +vn 0.228410 0.702774 0.673749 +v 160.525696 -136.879913 45.356140 1.000000 1.000000 1.000000 +vn -0.000000 0.739365 -0.673304 +v 159.003891 -136.637131 44.556137 1.000000 1.000000 1.000000 +vn -0.000000 0.739362 0.673309 +v 159.003891 -136.637131 45.356140 1.000000 1.000000 1.000000 +vn -0.228408 0.702780 -0.673743 +v 157.482101 -136.879913 44.556137 1.000000 1.000000 1.000000 +vn -0.228406 0.702777 0.673747 +v 157.482101 -136.879913 45.356140 1.000000 1.000000 1.000000 +vn -0.429158 0.600294 -0.674885 +v 156.090332 -137.587357 44.556137 1.000000 1.000000 1.000000 +vn -0.429156 0.600291 0.674889 +v 156.090332 -137.587357 45.356140 1.000000 1.000000 1.000000 +vn -0.467030 0.519081 -0.715848 +v 154.944473 -138.700821 44.556137 1.000000 1.000000 1.000000 +vn -0.467027 0.519077 0.715853 +v 154.944473 -138.700821 45.356140 1.000000 1.000000 1.000000 +vn -0.292016 0.578745 -0.761434 +v 154.855637 -138.774780 44.556137 1.000000 1.000000 1.000000 +vn -0.292014 0.578740 0.761438 +v 154.855637 -138.774780 45.356140 1.000000 1.000000 1.000000 +vn -0.081268 0.673062 -0.735108 +v 154.747482 -138.801285 44.556137 1.000000 1.000000 1.000000 +vn -0.081268 0.673056 0.735113 +v 154.747482 -138.801285 45.356140 1.000000 1.000000 1.000000 +vn 0.497385 0.550249 0.670697 +v 164.410034 -138.866882 45.356117 1.000000 1.000000 1.000000 +vn 0.497385 0.550249 -0.670697 +v 164.410034 -138.866882 44.556118 1.000000 1.000000 1.000000 +vn 0.642272 0.363181 0.674971 +v 164.467972 -138.940826 45.356117 1.000000 1.000000 1.000000 +vn 0.642272 0.363181 -0.674971 +v 164.467972 -138.940826 44.556118 1.000000 1.000000 1.000000 +vn -0.305109 0.683193 -0.663442 +v 126.447365 -149.763031 46.056137 1.000000 1.000000 1.000000 +vn -0.305109 0.683193 0.663442 +v 126.447365 -149.763031 56.392727 1.000000 1.000000 1.000000 +vn -0.483745 0.544043 -0.685572 +v 126.134125 -149.990479 46.056137 1.000000 1.000000 1.000000 +vn -0.483745 0.544042 0.685572 +v 126.134125 -149.990479 56.392727 1.000000 1.000000 1.000000 +vn 0.389096 -0.623860 0.677792 +v 162.158218 -148.279785 45.356117 1.000000 1.000000 1.000000 +vn 0.538928 -0.498563 0.678964 +v 163.465012 -147.192825 45.356117 1.000000 1.000000 1.000000 +vn -0.314378 0.558138 0.767886 +v 159.961792 -144.335190 45.356117 1.000000 1.000000 1.000000 +vn 0.204544 -0.706954 0.677036 +v 160.636414 -148.962112 45.356117 1.000000 1.000000 1.000000 +vn -0.543587 0.348944 0.763381 +v 160.699509 -143.626358 45.356117 1.000000 1.000000 1.000000 +vn 0.646681 -0.345509 0.680020 +v 164.466675 -145.777954 45.356117 1.000000 1.000000 1.000000 +vn 0.000001 0.638125 0.769933 +v 159.003891 -144.590530 45.356117 1.000000 1.000000 1.000000 +vn 0.051169 -0.720556 0.691506 +v 159.003891 -149.195145 45.356117 1.000000 1.000000 1.000000 +vn 0.314380 0.558138 0.767885 +v 158.046005 -144.335190 45.356117 1.000000 1.000000 1.000000 +vn 0.543588 0.348944 0.763381 +v 157.308289 -143.626358 45.356117 1.000000 1.000000 1.000000 +vn 0.645137 0.072811 0.760590 +v 156.959381 -142.627304 45.356117 1.000000 1.000000 1.000000 +vn 0.611182 -0.215431 0.761608 +v 157.077820 -141.566849 45.356117 1.000000 1.000000 1.000000 +vn 0.443169 -0.466080 0.765749 +v 157.637878 -140.686386 45.356117 1.000000 1.000000 1.000000 +vn 0.163055 -0.617716 0.769311 +v 158.510788 -140.191040 45.356117 1.000000 1.000000 1.000000 +vn -0.163054 -0.617714 0.769313 +v 159.497009 -140.191040 45.356117 1.000000 1.000000 1.000000 +vn -0.443167 -0.466081 0.765749 +v 160.369904 -140.686386 45.356117 1.000000 1.000000 1.000000 +vn -0.611178 -0.215432 0.761610 +v 160.929977 -141.566849 45.356117 1.000000 1.000000 1.000000 +vn 0.711040 0.176107 0.680742 +v 165.097549 -140.590118 45.356117 1.000000 1.000000 1.000000 +vn 0.732342 0.000000 0.680937 +v 165.312546 -142.359390 45.356117 1.000000 1.000000 1.000000 +vn -0.645137 0.072810 0.760590 +v 161.048416 -142.627304 45.356117 1.000000 1.000000 1.000000 +vn 0.711043 -0.176367 0.680670 +v 165.097549 -144.128677 45.356117 1.000000 1.000000 1.000000 +vn -0.645137 0.072810 -0.760590 +v 161.048416 -142.627304 44.556118 1.000000 1.000000 1.000000 +vn -0.611178 -0.215432 -0.761610 +v 160.929977 -141.566849 44.556118 1.000000 1.000000 1.000000 +vn 0.711039 0.176107 -0.680742 +v 165.097549 -140.590118 44.556118 1.000000 1.000000 1.000000 +vn 0.732342 0.000000 -0.680937 +v 165.312546 -142.359390 44.556118 1.000000 1.000000 1.000000 +vn 0.711043 -0.176367 -0.680670 +v 165.097549 -144.128677 44.556118 1.000000 1.000000 1.000000 +vn -0.543587 0.348944 -0.763381 +v 160.699509 -143.626358 44.556118 1.000000 1.000000 1.000000 +vn -0.443168 -0.466080 -0.765749 +v 160.369904 -140.686386 44.556118 1.000000 1.000000 1.000000 +vn -0.163055 -0.617710 -0.769316 +v 159.497009 -140.191040 44.556118 1.000000 1.000000 1.000000 +vn 0.163053 -0.617711 -0.769316 +v 158.510788 -140.191040 44.556118 1.000000 1.000000 1.000000 +vn 0.443165 -0.466076 -0.765753 +v 157.637878 -140.686386 44.556118 1.000000 1.000000 1.000000 +vn 0.611180 -0.215427 -0.761610 +v 157.077820 -141.566849 44.556118 1.000000 1.000000 1.000000 +vn 0.645136 0.072810 -0.760591 +v 156.959381 -142.627304 44.556118 1.000000 1.000000 1.000000 +vn 0.543587 0.348944 -0.763382 +v 157.308289 -143.626358 44.556118 1.000000 1.000000 1.000000 +vn 0.051168 -0.720556 -0.691506 +v 159.003891 -149.195145 44.556118 1.000000 1.000000 1.000000 +vn 0.314380 0.558137 -0.767885 +v 158.046005 -144.335190 44.556118 1.000000 1.000000 1.000000 +vn 0.000001 0.638125 -0.769933 +v 159.003891 -144.590530 44.556118 1.000000 1.000000 1.000000 +vn 0.204544 -0.706954 -0.677036 +v 160.636414 -148.962112 44.556118 1.000000 1.000000 1.000000 +vn -0.314378 0.558138 -0.767886 +v 159.961792 -144.335190 44.556118 1.000000 1.000000 1.000000 +vn 0.389096 -0.623860 -0.677792 +v 162.158218 -148.279785 44.556118 1.000000 1.000000 1.000000 +vn 0.538928 -0.498563 -0.678964 +v 163.465012 -147.192825 44.556118 1.000000 1.000000 1.000000 +vn 0.646681 -0.345509 -0.680020 +v 164.466675 -145.777954 44.556118 1.000000 1.000000 1.000000 +vn 0.267550 -0.597151 -0.756193 +v 126.644478 -150.279312 46.056137 1.000000 1.000000 1.000000 +vn 0.267550 -0.597151 0.756193 +v 126.644478 -150.279312 56.392727 1.000000 1.000000 1.000000 +vn 0.453894 -0.510850 -0.730077 +v 126.498222 -150.385345 46.056137 1.000000 1.000000 1.000000 +vn 0.453892 -0.510853 0.730076 +v 126.498222 -150.385345 56.392727 1.000000 1.000000 1.000000 +vn 0.744929 0.181809 -0.641892 +v -120.887253 -155.676453 46.284557 1.000000 1.000000 1.000000 +vn -0.199872 -0.727438 -0.656418 +v -121.251350 -156.071335 46.284557 1.000000 1.000000 1.000000 +vn -0.417912 -0.537559 -0.732380 +v -121.773941 -155.504837 46.056160 1.000000 1.000000 1.000000 +vn 0.567680 0.387845 -0.726165 +v -121.409843 -155.109955 46.056160 1.000000 1.000000 1.000000 +vn 0.909909 0.035120 -0.413318 +v -120.444229 -156.156464 46.934757 1.000000 1.000000 1.000000 +vn -0.044085 -0.900819 -0.431952 +v -120.808327 -156.551331 46.934757 1.000000 1.000000 1.000000 +vn 0.980380 -0.024050 -0.195645 +v -120.148102 -156.477371 47.908157 1.000000 1.000000 1.000000 +vn 0.021844 -0.978035 -0.207291 +v -120.512337 -156.872269 47.908157 1.000000 1.000000 1.000000 +vn 0.998746 -0.019352 -0.046174 +v -120.044212 -156.590408 49.056160 1.000000 1.000000 1.000000 +vn 0.019302 -0.998583 -0.049597 +v -120.408310 -156.985291 49.056160 1.000000 1.000000 1.000000 +vn 0.998747 -0.019340 0.046161 +v -120.044212 -156.590408 53.392757 1.000000 1.000000 1.000000 +vn 0.019291 -0.998584 0.049580 +v -120.408310 -156.985291 53.392757 1.000000 1.000000 1.000000 +vn 0.980379 -0.023759 0.195686 +v -120.148102 -156.477371 54.540764 1.000000 1.000000 1.000000 +vn 0.021757 -0.978025 0.207350 +v -120.512337 -156.872269 54.540764 1.000000 1.000000 1.000000 +vn 0.909952 0.035080 0.413227 +v -120.444229 -156.156464 55.513962 1.000000 1.000000 1.000000 +vn -0.044086 -0.900839 0.431908 +v -120.808327 -156.551331 55.513962 1.000000 1.000000 1.000000 +vn 0.744918 0.181704 0.641935 +v -120.887253 -155.676453 56.164364 1.000000 1.000000 1.000000 +vn -0.199856 -0.727492 0.656363 +v -121.251350 -156.071335 56.164364 1.000000 1.000000 1.000000 +vn 0.567679 0.387846 0.726165 +v -121.409843 -155.109955 56.392761 1.000000 1.000000 1.000000 +vn -0.417909 -0.537566 0.732377 +v -121.773941 -155.504837 56.392761 1.000000 1.000000 1.000000 +vn -0.715944 0.460028 -0.525165 +v -146.129089 -140.407318 55.002766 1.000000 1.000000 1.000000 +vn -0.731349 -0.354400 0.582691 +v -146.129089 -140.669647 55.708965 1.000000 1.000000 1.000000 +vn -0.725367 -0.161494 0.669151 +v -145.982315 -139.962204 56.247967 1.000000 1.000000 1.000000 +vn -0.677745 0.595936 -0.430723 +v -145.982315 -139.699890 55.541565 1.000000 1.000000 1.000000 +vn -0.680069 0.368181 -0.633994 +v -146.129089 -141.617081 54.080967 1.000000 1.000000 1.000000 +vn -0.735907 -0.340948 0.584975 +v -146.129089 -141.879395 54.787365 1.000000 1.000000 1.000000 +vn -0.775654 -0.076412 0.626516 +v -146.129089 -142.064987 54.707966 1.000000 1.000000 1.000000 +vn -0.649622 0.090766 -0.754819 +v -146.129089 -142.017532 53.911167 1.000000 1.000000 1.000000 +vn -0.739221 0.198185 0.643642 +v -146.129089 -142.258926 54.739567 1.000000 1.000000 1.000000 +vn -0.677604 -0.216472 -0.702846 +v -146.129089 -142.431961 53.978767 1.000000 1.000000 1.000000 +vn -0.672559 0.200221 0.712443 +v -146.129089 -148.871414 57.819359 1.000000 1.000000 1.000000 +vn -0.745143 -0.180710 -0.641954 +v -146.129089 -149.044434 57.058369 1.000000 1.000000 1.000000 +vn -0.642051 -0.160962 0.749574 +v -146.129089 -149.358383 57.874157 1.000000 1.000000 1.000000 +vn -0.786403 0.129743 -0.603934 +v -146.129089 -149.271881 57.084167 1.000000 1.000000 1.000000 +vn -0.655524 -0.533566 0.534411 +v -146.129089 -149.810471 57.606159 1.000000 1.000000 1.000000 +vn -0.766951 0.453554 -0.453954 +v -146.129089 -149.482574 56.958965 1.000000 1.000000 1.000000 +vn -0.667931 -0.698699 0.256298 +v -146.129089 -150.127213 57.073769 1.000000 1.000000 1.000000 +vn -0.751162 0.619827 -0.227089 +v -146.129089 -149.630478 56.710567 1.000000 1.000000 1.000000 +vn -0.688864 -0.722381 0.060267 +v -146.129089 -150.241638 56.392765 1.000000 1.000000 1.000000 +vn -0.726172 0.685165 -0.056767 +v -146.129089 -149.683502 56.392765 1.000000 1.000000 1.000000 +vn -0.687007 -0.723580 -0.066740 +v -146.129089 -150.241638 46.056160 1.000000 1.000000 1.000000 +vn -0.728527 0.682081 0.063352 +v -146.129089 -149.683502 46.056160 1.000000 1.000000 1.000000 +vn -0.662472 -0.690832 -0.289622 +v -146.129089 -150.102097 45.306160 1.000000 1.000000 1.000000 +vn -0.757622 0.601927 0.252374 +v -146.129089 -149.617920 45.706158 1.000000 1.000000 1.000000 +vn -0.646783 -0.469880 -0.600737 +v -146.129089 -149.718384 44.757156 1.000000 1.000000 1.000000 +vn -0.779439 0.386271 0.493224 +v -146.129089 -149.439316 45.449959 1.000000 1.000000 1.000000 +vn -0.230707 -0.408910 -0.882931 +v -146.129089 -149.195145 44.556160 1.000000 1.000000 1.000000 +vn -0.379973 -0.197581 0.903650 +v -146.129089 -149.195145 45.356159 1.000000 1.000000 1.000000 +vn -0.603538 0.069967 0.794258 +v -145.563873 -139.362213 56.704967 1.000000 1.000000 1.000000 +vn -0.532007 0.781349 -0.326286 +v -145.563873 -139.101288 55.998566 1.000000 1.000000 1.000000 +vn -0.352829 0.261753 0.898330 +v -144.936874 -138.961761 57.010166 1.000000 1.000000 1.000000 +vn -0.299820 0.921617 -0.246436 +v -144.936874 -138.700821 56.303967 1.000000 1.000000 1.000000 +vn -0.094277 0.304900 0.947707 +v -144.197861 -138.822220 57.117367 1.000000 1.000000 1.000000 +vn -0.074766 0.966195 -0.246732 +v -144.197861 -138.559906 56.411167 1.000000 1.000000 1.000000 +vn 0.093935 0.304758 0.947786 +v -128.748093 -138.822220 57.117367 1.000000 1.000000 1.000000 +vn 0.074476 0.966167 -0.246930 +v -128.748093 -138.559906 56.411167 1.000000 1.000000 1.000000 +vn 0.353185 0.261185 0.898355 +v -128.009079 -138.961761 57.010166 1.000000 1.000000 1.000000 +vn 0.300105 0.921466 -0.246653 +v -128.009079 -138.700821 56.303967 1.000000 1.000000 1.000000 +vn 0.603563 0.069807 0.794254 +v -127.382462 -139.362213 56.704967 1.000000 1.000000 1.000000 +vn 0.532052 0.781109 -0.326788 +v -127.382462 -139.101288 55.998566 1.000000 1.000000 1.000000 +vn 0.725594 -0.160950 0.669035 +v -126.963898 -139.962204 56.247967 1.000000 1.000000 1.000000 +vn 0.676888 0.596512 -0.431273 +v -126.963898 -139.699890 55.541565 1.000000 1.000000 1.000000 +vn 0.731387 -0.354279 0.582717 +v -126.816872 -140.669647 55.708965 1.000000 1.000000 1.000000 +vn 0.715946 0.460123 -0.525080 +v -126.816872 -140.407318 55.002766 1.000000 1.000000 1.000000 +vn 0.735908 -0.340948 0.584974 +v -126.816872 -141.879395 54.787365 1.000000 1.000000 1.000000 +vn 0.680069 0.368181 -0.633994 +v -126.816872 -141.617081 54.080967 1.000000 1.000000 1.000000 +vn 0.775653 -0.076413 0.626517 +v -126.816872 -142.064987 54.707966 1.000000 1.000000 1.000000 +vn 0.649622 0.090766 -0.754819 +v -126.816872 -142.017532 53.911167 1.000000 1.000000 1.000000 +vn 0.739221 0.198185 0.643642 +v -126.816872 -142.258926 54.739567 1.000000 1.000000 1.000000 +vn 0.677604 -0.216472 -0.702846 +v -126.816872 -142.431961 53.978767 1.000000 1.000000 1.000000 +vn 0.672560 0.200221 0.712443 +v -126.816872 -148.871414 57.819359 1.000000 1.000000 1.000000 +vn 0.745144 -0.180710 -0.641954 +v -126.816872 -149.044434 57.058365 1.000000 1.000000 1.000000 +vn 0.786402 0.129744 -0.603935 +v -126.816872 -149.271881 57.084164 1.000000 1.000000 1.000000 +vn 0.642051 -0.160962 0.749574 +v -126.816872 -149.358383 57.874157 1.000000 1.000000 1.000000 +vn 0.766952 0.453554 -0.453953 +v -126.816872 -149.482574 56.958961 1.000000 1.000000 1.000000 +vn 0.655523 -0.533567 0.534411 +v -126.816872 -149.810471 57.606159 1.000000 1.000000 1.000000 +vn 0.751163 0.619827 -0.227089 +v -126.816872 -149.630478 56.710564 1.000000 1.000000 1.000000 +vn 0.667931 -0.698699 0.256297 +v -126.816872 -150.127213 57.073765 1.000000 1.000000 1.000000 +vn 0.396564 0.893398 0.211134 +v -126.816872 -149.683502 56.392761 1.000000 1.000000 1.000000 +vn 0.205747 -0.895855 0.393843 +v -126.816872 -150.241638 56.392761 1.000000 1.000000 1.000000 +vn -0.075180 0.973963 0.213877 +v -144.197861 -135.378540 42.756157 1.000000 1.000000 1.000000 +vn -0.095900 0.272962 -0.957233 +v -144.197861 -135.657608 42.063358 1.000000 1.000000 1.000000 +vn -0.356919 0.227800 -0.905934 +v -144.936874 -135.795746 42.177559 1.000000 1.000000 1.000000 +vn -0.301805 0.928729 0.215351 +v -144.936874 -135.516678 42.870358 1.000000 1.000000 1.000000 +vn 0.075163 0.973966 0.213871 +v -128.748093 -135.378540 42.756157 1.000000 1.000000 1.000000 +vn 0.095877 0.272969 -0.957233 +v -128.748093 -135.657608 42.063358 1.000000 1.000000 1.000000 +vn 0.301991 0.928771 0.214909 +v -128.009079 -135.516678 42.870358 1.000000 1.000000 1.000000 +vn 0.357043 0.228218 -0.905780 +v -128.009079 -135.795746 42.177559 1.000000 1.000000 1.000000 +vn 0.533778 0.790868 0.299348 +v -127.382462 -135.910156 43.195557 1.000000 1.000000 1.000000 +vn 0.607126 0.037249 -0.793732 +v -127.382462 -136.189224 42.502758 1.000000 1.000000 1.000000 +vn 0.677730 0.610919 0.409219 +v -126.963898 -136.497589 43.682159 1.000000 1.000000 1.000000 +vn 0.727090 -0.188269 -0.660223 +v -126.963898 -136.776657 42.989357 1.000000 1.000000 1.000000 +vn 0.715630 0.480168 0.507260 +v -126.816872 -137.191071 44.256157 1.000000 1.000000 1.000000 +vn 0.731622 -0.377462 -0.567673 +v -126.816872 -137.470154 43.563358 1.000000 1.000000 1.000000 +vn 0.672496 0.373483 0.638952 +v -126.816872 -138.278046 45.155159 1.000000 1.000000 1.000000 +vn 0.745327 -0.336448 -0.575579 +v -126.816872 -138.557114 44.462357 1.000000 1.000000 1.000000 +vn 0.668273 0.135658 0.731443 +v -126.816872 -138.801285 45.356159 1.000000 1.000000 1.000000 +vn 0.750550 -0.120510 -0.649732 +v -126.816872 -138.801285 44.556160 1.000000 1.000000 1.000000 +vn 0.750549 0.120506 0.649734 +v -126.816872 -149.195145 45.356159 1.000000 1.000000 1.000000 +vn 0.668274 -0.135655 -0.731442 +v -126.816872 -149.195145 44.556160 1.000000 1.000000 1.000000 +vn 0.779439 0.386271 0.493224 +v -126.816872 -149.439316 45.449959 1.000000 1.000000 1.000000 +vn 0.646783 -0.469880 -0.600737 +v -126.816872 -149.718384 44.757156 1.000000 1.000000 1.000000 +vn 0.757621 0.601928 0.252375 +v -126.816872 -149.617920 45.706158 1.000000 1.000000 1.000000 +vn 0.662472 -0.690832 -0.289622 +v -126.816872 -150.102097 45.306160 1.000000 1.000000 1.000000 +vn 0.400641 0.892925 -0.205358 +v -126.816872 -149.683502 46.056160 1.000000 1.000000 1.000000 +vn 0.202270 -0.894440 -0.398828 +v -126.816872 -150.241638 46.056160 1.000000 1.000000 1.000000 +vn -0.606790 0.037025 -0.794000 +v -145.563873 -136.189224 42.502758 1.000000 1.000000 1.000000 +vn -0.533454 0.790967 0.299663 +v -145.563873 -135.910156 43.195557 1.000000 1.000000 1.000000 +vn -0.727129 -0.188366 -0.660153 +v -145.982315 -136.776657 42.989357 1.000000 1.000000 1.000000 +vn -0.677803 0.610804 0.409269 +v -145.982315 -136.497589 43.682159 1.000000 1.000000 1.000000 +vn -0.731589 -0.377587 -0.567632 +v -146.129089 -137.470154 43.563358 1.000000 1.000000 1.000000 +vn -0.715619 0.480118 0.507323 +v -146.129089 -137.191071 44.256157 1.000000 1.000000 1.000000 +vn -0.745327 -0.336448 -0.575578 +v -146.129089 -138.557114 44.462357 1.000000 1.000000 1.000000 +vn -0.672496 0.373483 0.638952 +v -146.129089 -138.278046 45.155159 1.000000 1.000000 1.000000 +vn -0.230705 0.408915 0.882929 +v -146.129089 -138.801285 45.356159 1.000000 1.000000 1.000000 +vn -0.379977 0.197574 -0.903649 +v -146.129089 -138.801285 44.556160 1.000000 1.000000 1.000000 +vn -0.642272 0.363181 -0.674971 +v -164.467972 -138.940826 44.556179 1.000000 1.000000 1.000000 +vn -0.642272 0.363181 0.674971 +v -164.467972 -138.940826 45.356178 1.000000 1.000000 1.000000 +vn -0.497385 0.550249 0.670697 +v -164.410034 -138.866882 45.356178 1.000000 1.000000 1.000000 +vn -0.497385 0.550249 -0.670697 +v -164.410034 -138.866882 44.556179 1.000000 1.000000 1.000000 +vn -0.273723 0.692486 0.667487 +v -164.332779 -138.818039 45.356178 1.000000 1.000000 1.000000 +vn -0.273723 0.692486 -0.667487 +v -164.332779 -138.818039 44.556179 1.000000 1.000000 1.000000 +vn -0.068640 0.723916 0.686465 +v -164.245224 -138.801285 45.356178 1.000000 1.000000 1.000000 +vn -0.068640 0.723916 -0.686465 +v -164.245224 -138.801285 44.556179 1.000000 1.000000 1.000000 +vn -0.081268 0.673059 0.735110 +v -163.260315 -138.801285 45.356178 1.000000 1.000000 1.000000 +vn -0.081268 0.673059 -0.735110 +v -163.260315 -138.801285 44.556179 1.000000 1.000000 1.000000 +vn -0.292015 0.578743 -0.761436 +v -163.152161 -138.774780 44.556179 1.000000 1.000000 1.000000 +vn -0.292015 0.578743 0.761436 +v -163.152161 -138.774780 45.356178 1.000000 1.000000 1.000000 +vn -0.467028 0.519079 -0.715850 +v -163.063324 -138.700821 44.556179 1.000000 1.000000 1.000000 +vn -0.467028 0.519079 0.715850 +v -163.063324 -138.700821 45.356178 1.000000 1.000000 1.000000 +vn -0.429158 0.600293 0.674887 +v -161.917465 -137.587357 45.356178 1.000000 1.000000 1.000000 +vn -0.429158 0.600293 -0.674887 +v -161.917465 -137.587357 44.556179 1.000000 1.000000 1.000000 +vn -0.228407 0.702779 0.673745 +v -160.525696 -136.879913 45.356178 1.000000 1.000000 1.000000 +vn -0.228407 0.702779 -0.673745 +v -160.525696 -136.879913 44.556179 1.000000 1.000000 1.000000 +vn 0.000000 0.739364 0.673306 +v -159.003891 -136.637131 45.356178 1.000000 1.000000 1.000000 +vn 0.000000 0.739364 -0.673306 +v -159.003891 -136.637131 44.556179 1.000000 1.000000 1.000000 +vn 0.228407 0.702779 0.673745 +v -157.482101 -136.879913 45.356178 1.000000 1.000000 1.000000 +vn 0.228407 0.702779 -0.673745 +v -157.482101 -136.879913 44.556179 1.000000 1.000000 1.000000 +vn 0.429158 0.600293 0.674887 +v -156.090332 -137.587357 45.356178 1.000000 1.000000 1.000000 +vn 0.429158 0.600293 -0.674887 +v -156.090332 -137.587357 44.556179 1.000000 1.000000 1.000000 +vn 0.467028 0.519079 0.715850 +v -154.944473 -138.700821 45.356178 1.000000 1.000000 1.000000 +vn 0.467028 0.519079 -0.715850 +v -154.944473 -138.700821 44.556179 1.000000 1.000000 1.000000 +vn 0.292015 0.578743 -0.761436 +v -154.855637 -138.774780 44.556179 1.000000 1.000000 1.000000 +vn 0.292015 0.578743 0.761436 +v -154.855637 -138.774780 45.356178 1.000000 1.000000 1.000000 +vn 0.081267 0.673060 -0.735110 +v -154.747482 -138.801285 44.556179 1.000000 1.000000 1.000000 +vn 0.081270 0.673058 0.735111 +v -154.747482 -138.801285 45.356178 1.000000 1.000000 1.000000 +vn 0.305109 0.683193 0.663442 +v -126.447365 -149.763031 56.392761 1.000000 1.000000 1.000000 +vn 0.305109 0.683193 -0.663442 +v -126.447365 -149.763031 46.056160 1.000000 1.000000 1.000000 +vn 0.483732 0.544048 0.685576 +v -126.134125 -149.990479 56.392761 1.000000 1.000000 1.000000 +vn 0.483732 0.544048 -0.685576 +v -126.134125 -149.990479 46.056160 1.000000 1.000000 1.000000 +vn -0.051164 -0.720559 0.691503 +v -159.003891 -149.195145 45.356159 1.000000 1.000000 1.000000 +vn 0.000000 0.638124 0.769934 +v -159.003891 -144.590530 45.356178 1.000000 1.000000 1.000000 +vn -0.204540 -0.706954 0.677037 +v -160.636414 -148.962112 45.356178 1.000000 1.000000 1.000000 +vn -0.543587 0.348943 0.763382 +v -157.308289 -143.626358 45.356178 1.000000 1.000000 1.000000 +vn -0.314378 0.558136 0.767888 +v -158.046005 -144.335190 45.356178 1.000000 1.000000 1.000000 +vn 0.314378 0.558138 0.767886 +v -159.961792 -144.335190 45.356178 1.000000 1.000000 1.000000 +vn -0.389096 -0.623860 0.677792 +v -162.158218 -148.279785 45.356178 1.000000 1.000000 1.000000 +vn 0.543587 0.348944 0.763381 +v -160.699509 -143.626358 45.356178 1.000000 1.000000 1.000000 +vn -0.538928 -0.498563 0.678964 +v -163.465012 -147.192825 45.356178 1.000000 1.000000 1.000000 +vn 0.645137 0.072810 0.760590 +v -161.048416 -142.627304 45.356178 1.000000 1.000000 1.000000 +vn -0.711043 -0.176367 0.680670 +v -165.097549 -144.128677 45.356178 1.000000 1.000000 1.000000 +vn -0.646681 -0.345509 0.680020 +v -164.466675 -145.777954 45.356178 1.000000 1.000000 1.000000 +vn 0.611178 -0.215432 0.761610 +v -160.929977 -141.566849 45.356178 1.000000 1.000000 1.000000 +vn -0.711039 0.176107 0.680742 +v -165.097549 -140.590118 45.356178 1.000000 1.000000 1.000000 +vn -0.732342 0.000000 0.680937 +v -165.312546 -142.359390 45.356178 1.000000 1.000000 1.000000 +vn 0.443167 -0.466081 0.765749 +v -160.369904 -140.686386 45.356178 1.000000 1.000000 1.000000 +vn 0.163056 -0.617712 0.769314 +v -159.497009 -140.191040 45.356178 1.000000 1.000000 1.000000 +vn -0.163054 -0.617714 0.769314 +v -158.510788 -140.191040 45.356178 1.000000 1.000000 1.000000 +vn -0.443166 -0.466078 0.765751 +v -157.637878 -140.686386 45.356178 1.000000 1.000000 1.000000 +vn -0.611180 -0.215429 0.761609 +v -157.077820 -141.566849 45.356178 1.000000 1.000000 1.000000 +vn -0.645136 0.072810 0.760591 +v -156.959381 -142.627304 45.356178 1.000000 1.000000 1.000000 +vn -0.645137 0.072811 -0.760590 +v -156.959381 -142.627304 44.556179 1.000000 1.000000 1.000000 +vn -0.611181 -0.215429 -0.761609 +v -157.077820 -141.566849 44.556179 1.000000 1.000000 1.000000 +vn -0.543588 0.348944 -0.763381 +v -157.308289 -143.626358 44.556179 1.000000 1.000000 1.000000 +vn -0.443166 -0.466078 -0.765751 +v -157.637878 -140.686386 44.556179 1.000000 1.000000 1.000000 +vn -0.163054 -0.617714 -0.769314 +v -158.510788 -140.191040 44.556179 1.000000 1.000000 1.000000 +vn 0.163056 -0.617712 -0.769314 +v -159.497009 -140.191040 44.556179 1.000000 1.000000 1.000000 +vn 0.443167 -0.466081 -0.765749 +v -160.369904 -140.686386 44.556179 1.000000 1.000000 1.000000 +vn 0.611178 -0.215432 -0.761610 +v -160.929977 -141.566849 44.556179 1.000000 1.000000 1.000000 +vn -0.711040 0.176107 -0.680742 +v -165.097549 -140.590118 44.556179 1.000000 1.000000 1.000000 +vn -0.732342 0.000000 -0.680937 +v -165.312546 -142.359390 44.556179 1.000000 1.000000 1.000000 +vn 0.645137 0.072810 -0.760590 +v -161.048416 -142.627304 44.556179 1.000000 1.000000 1.000000 +vn -0.711043 -0.176367 -0.680670 +v -165.097549 -144.128677 44.556179 1.000000 1.000000 1.000000 +vn 0.543587 0.348944 -0.763381 +v -160.699509 -143.626358 44.556179 1.000000 1.000000 1.000000 +vn -0.646681 -0.345509 -0.680020 +v -164.466675 -145.777954 44.556179 1.000000 1.000000 1.000000 +vn -0.538928 -0.498563 -0.678964 +v -163.465012 -147.192825 44.556179 1.000000 1.000000 1.000000 +vn 0.314378 0.558138 -0.767886 +v -159.961792 -144.335190 44.556179 1.000000 1.000000 1.000000 +vn -0.389096 -0.623860 -0.677792 +v -162.158218 -148.279785 44.556179 1.000000 1.000000 1.000000 +vn -0.000003 0.638126 -0.769932 +v -159.003891 -144.590530 44.556179 1.000000 1.000000 1.000000 +vn -0.204548 -0.706954 -0.677035 +v -160.636414 -148.962112 44.556179 1.000000 1.000000 1.000000 +vn -0.314380 0.558139 -0.767884 +v -158.046005 -144.335190 44.556179 1.000000 1.000000 1.000000 +vn -0.051172 -0.720554 -0.691509 +v -159.003891 -149.195145 44.556160 1.000000 1.000000 1.000000 +vn -0.267550 -0.597151 -0.756193 +v -126.644478 -150.279312 46.056160 1.000000 1.000000 1.000000 +vn -0.267550 -0.597151 0.756193 +v -126.644478 -150.279312 56.392761 1.000000 1.000000 1.000000 +vn -0.453889 -0.510862 0.730072 +v -126.498222 -150.385345 56.392761 1.000000 1.000000 1.000000 +vn -0.453889 -0.510862 -0.730072 +v -126.498222 -150.385345 46.056160 1.000000 1.000000 1.000000 +vn 0.727024 0.088557 0.680877 +v 165.441299 163.220123 54.399963 1.000000 1.000000 1.000000 +vn 0.727024 -0.088557 0.680877 +v 165.441299 -142.358002 54.399925 1.000000 1.000000 1.000000 +vn 0.727024 0.088557 -0.680877 +v 165.441299 163.220123 46.399960 1.000000 1.000000 1.000000 +vn 0.665225 0.358094 -0.655167 +v 164.578690 166.708450 46.399960 1.000000 1.000000 1.000000 +vn 0.665226 0.358094 0.655166 +v 164.578690 166.708450 54.399963 1.000000 1.000000 1.000000 +vn 0.727024 -0.088557 -0.680878 +v 165.441299 -142.358002 46.399918 1.000000 1.000000 1.000000 +vn 0.665225 -0.358094 0.655167 +v 164.578690 -145.846329 54.399925 1.000000 1.000000 1.000000 +vn 0.665225 -0.358094 -0.655167 +v 164.578690 -145.846329 46.399918 1.000000 1.000000 1.000000 +vn 0.399227 -0.645168 0.651441 +v 162.222595 -148.399796 54.399925 1.000000 1.000000 1.000000 +vn 0.399228 -0.645168 -0.651441 +v 162.222595 -148.399796 46.399918 1.000000 1.000000 1.000000 +vn 0.103710 -0.728888 0.676733 +v 159.003891 -149.334671 54.399925 1.000000 1.000000 1.000000 +vn 0.103710 -0.728888 -0.676732 +v 159.003891 -149.334671 46.399918 1.000000 1.000000 1.000000 +vn 0.399228 0.645168 -0.651441 +v 162.222595 169.261917 46.399960 1.000000 1.000000 1.000000 +vn 0.399228 0.645168 0.651441 +v 162.222595 169.261917 54.399967 1.000000 1.000000 1.000000 +vn 0.103710 0.728888 -0.676733 +v 159.003891 170.196793 46.399960 1.000000 1.000000 1.000000 +vn -0.103710 0.728888 -0.676732 +v -159.003891 170.196793 46.400017 1.000000 1.000000 1.000000 +vn 0.103710 0.728888 0.676732 +v 159.003891 170.196793 54.399967 1.000000 1.000000 1.000000 +vn -0.103710 0.728888 0.676733 +v -159.003891 170.196793 54.400009 1.000000 1.000000 1.000000 +vn -0.103710 -0.728888 0.676732 +v -159.003891 -149.334671 54.399967 1.000000 1.000000 1.000000 +vn -0.727024 -0.088557 0.680878 +v -165.441299 -142.358002 54.399971 1.000000 1.000000 1.000000 +vn -0.727024 0.088557 0.680877 +v -165.441299 163.220123 54.400009 1.000000 1.000000 1.000000 +vn -0.665225 0.358094 0.655167 +v -164.578690 166.708450 54.400009 1.000000 1.000000 1.000000 +vn -0.399228 0.645168 0.651441 +v -162.222595 169.261917 54.400009 1.000000 1.000000 1.000000 +vn -0.665225 -0.358094 0.655167 +v -164.578690 -145.846329 54.399971 1.000000 1.000000 1.000000 +vn -0.399227 -0.645168 0.651442 +v -162.222595 -148.399796 54.399971 1.000000 1.000000 1.000000 +vn -0.103711 -0.728887 -0.676733 +v -159.003891 -149.334671 46.399960 1.000000 1.000000 1.000000 +vn -0.727024 0.088557 -0.680877 +v -165.441299 163.220123 46.400017 1.000000 1.000000 1.000000 +vn -0.399228 0.645168 -0.651441 +v -162.222595 169.261917 46.400017 1.000000 1.000000 1.000000 +vn -0.727025 -0.088557 -0.680876 +v -165.441299 -142.358002 46.399979 1.000000 1.000000 1.000000 +vn -0.665225 0.358094 -0.655167 +v -164.578690 166.708450 46.400017 1.000000 1.000000 1.000000 +vn -0.665227 -0.358094 -0.655166 +v -164.578690 -145.846329 46.399979 1.000000 1.000000 1.000000 +vn -0.399231 -0.645170 -0.651437 +v -162.222595 -148.399796 46.399979 1.000000 1.000000 1.000000 +vn 0.618988 -0.381308 0.686628 +v 164.355957 -146.234238 46.399918 1.000000 1.000000 1.000000 +vn 0.535122 -0.493764 0.685450 +v 163.557724 -147.293289 46.399918 1.000000 1.000000 1.000000 +vn 0.618988 -0.381308 -0.686628 +v 164.355957 -146.234238 43.199921 1.000000 1.000000 1.000000 +vn 0.678580 -0.260099 0.686934 +v 164.950775 -145.028671 46.399918 1.000000 1.000000 1.000000 +vn 0.678580 -0.260099 -0.686934 +v 164.950775 -145.028671 43.199921 1.000000 1.000000 1.000000 +vn 0.535122 -0.493764 -0.685450 +v 163.557724 -147.293289 43.199921 1.000000 1.000000 1.000000 +vn 0.426137 -0.590908 0.685007 +v 162.580521 -148.161194 46.399918 1.000000 1.000000 1.000000 +vn 0.426137 -0.590908 -0.685007 +v 162.580521 -148.161194 43.199921 1.000000 1.000000 1.000000 +vn 0.298346 -0.664639 0.685014 +v 161.468140 -148.803040 46.399918 1.000000 1.000000 1.000000 +vn 0.298346 -0.664639 -0.685014 +v 161.468140 -148.803040 43.199921 1.000000 1.000000 1.000000 +vn 0.153656 -0.713552 0.683545 +v 160.261765 -149.203506 46.399918 1.000000 1.000000 1.000000 +vn 0.153656 -0.713552 -0.683545 +v 160.261765 -149.203506 43.199921 1.000000 1.000000 1.000000 +vn 0.037229 -0.717438 0.695627 +v 159.001328 -149.334671 46.399918 1.000000 1.000000 1.000000 +vn 0.037229 -0.717438 -0.695627 +v 159.001328 -149.334671 43.199921 1.000000 1.000000 1.000000 +vn 0.000000 -0.707107 -0.707107 +v 151.600876 -149.334671 43.199921 1.000000 1.000000 1.000000 +vn 0.000001 -0.707108 0.707106 +v 151.600876 -149.334671 46.399918 1.000000 1.000000 1.000000 +vn -0.000000 -0.707107 -0.707107 +v 134.219894 -149.334671 43.199921 1.000000 1.000000 1.000000 +vn 0.000000 -0.707106 0.707107 +v 134.219894 -149.334671 46.399940 1.000000 1.000000 1.000000 +vn -0.000000 -0.707107 -0.707107 +v 63.408436 -149.334671 43.199940 1.000000 1.000000 1.000000 +vn 0.000000 -0.707107 0.707107 +v 63.408436 -149.334671 46.399940 1.000000 1.000000 1.000000 +vn 0.681268 -0.190397 0.706840 +v 165.161926 -144.276581 46.399918 1.000000 1.000000 1.000000 +vn 0.681268 -0.190397 -0.706840 +v 165.161926 -144.276581 43.199921 1.000000 1.000000 1.000000 +vn 0.714329 -0.131012 0.687437 +v 165.316422 -143.721237 46.399918 1.000000 1.000000 1.000000 +vn 0.714329 -0.131012 -0.687437 +v 165.316422 -143.721237 43.199921 1.000000 1.000000 1.000000 +vn 0.716358 -0.032775 0.696963 +v 165.441299 -142.359390 46.399918 1.000000 1.000000 1.000000 +vn 0.716358 -0.032775 -0.696963 +v 165.441299 -142.359390 43.199921 1.000000 1.000000 1.000000 +vn 0.707105 0.000000 0.707109 +v 165.441299 10.431098 46.399940 1.000000 1.000000 1.000000 +vn 0.707104 0.000000 -0.707109 +v 165.441299 10.431098 43.199940 1.000000 1.000000 1.000000 +vn 0.707107 0.000000 0.707107 +v 165.441299 161.301544 46.399960 1.000000 1.000000 1.000000 +vn 0.707107 0.000000 -0.707107 +v 165.441299 161.301544 43.199959 1.000000 1.000000 1.000000 +vn 0.723412 0.065810 0.687273 +v 165.441299 163.222916 46.399960 1.000000 1.000000 1.000000 +vn 0.723412 0.065810 -0.687273 +v 165.441299 163.222916 43.199959 1.000000 1.000000 1.000000 +vn 0.695533 0.127862 0.707026 +v 165.089828 165.138702 46.399960 1.000000 1.000000 1.000000 +vn 0.695533 0.127862 -0.707026 +v 165.089828 165.138702 43.199959 1.000000 1.000000 1.000000 +vn 0.694581 0.267302 0.667912 +v 164.950775 165.893585 46.399960 1.000000 1.000000 1.000000 +vn 0.694581 0.267302 -0.667912 +v 164.950775 165.893585 43.199959 1.000000 1.000000 1.000000 +vn 0.546648 0.507855 -0.665777 +v 163.555145 168.156815 43.199959 1.000000 1.000000 1.000000 +vn 0.546648 0.507855 0.665777 +v 163.555145 168.156815 46.399960 1.000000 1.000000 1.000000 +vn 0.304399 0.683325 -0.663633 +v 161.465561 169.667969 43.199959 1.000000 1.000000 1.000000 +vn 0.304399 0.683325 0.663633 +v 161.465561 169.667969 46.399960 1.000000 1.000000 1.000000 +vn 0.077190 0.725343 -0.684047 +v 159.002609 170.198181 43.199959 1.000000 1.000000 1.000000 +vn 0.077190 0.725343 0.684046 +v 159.002609 170.198181 46.399960 1.000000 1.000000 1.000000 +vn -0.000000 0.707107 -0.707107 +v 151.600876 170.198181 43.199959 1.000000 1.000000 1.000000 +vn 0.000000 0.707107 0.707107 +v 151.600876 170.198181 46.399960 1.000000 1.000000 1.000000 +vn -0.000001 0.707108 -0.707105 +v 134.219894 170.198181 43.199978 1.000000 1.000000 1.000000 +vn 0.000001 0.707106 0.707107 +v 134.219894 170.198181 46.399979 1.000000 1.000000 1.000000 +vn 0.000000 0.707105 -0.707108 +v 63.408436 170.198181 43.199978 1.000000 1.000000 1.000000 +vn 0.000000 0.707105 0.707108 +v 63.408436 170.198181 46.399979 1.000000 1.000000 1.000000 +vn -0.077150 0.725336 -0.684058 +v -159.001328 170.198181 43.199997 1.000000 1.000000 1.000000 +vn -0.077150 0.725336 0.684058 +v -159.001328 170.198181 46.400017 1.000000 1.000000 1.000000 +vn 0.000000 0.707107 -0.707107 +v -151.600876 170.198181 43.199997 1.000000 1.000000 1.000000 +vn -0.304400 0.683343 -0.663614 +v -161.465561 169.667969 43.199997 1.000000 1.000000 1.000000 +vn 0.000000 0.707107 0.707107 +v -151.600876 170.198181 46.400017 1.000000 1.000000 1.000000 +vn -0.304400 0.683343 0.663614 +v -161.465561 169.667969 46.400017 1.000000 1.000000 1.000000 +vn 0.000000 0.707107 -0.707106 +v -134.219894 170.198181 43.199997 1.000000 1.000000 1.000000 +vn 0.000000 0.707107 0.707106 +v -134.219894 170.198181 46.399998 1.000000 1.000000 1.000000 +vn 0.000000 0.707105 -0.707108 +v -63.408436 170.198181 43.199997 1.000000 1.000000 1.000000 +vn 0.000000 0.707105 0.707108 +v -63.408436 170.198181 46.399998 1.000000 1.000000 1.000000 +vn -0.414238 0.572997 0.707164 +v -163.188217 168.421936 46.400017 1.000000 1.000000 1.000000 +vn -0.414238 0.572997 -0.707164 +v -163.188217 168.421936 43.199997 1.000000 1.000000 1.000000 +vn -0.546568 0.507995 0.665736 +v -163.555145 168.156815 46.400017 1.000000 1.000000 1.000000 +vn -0.546568 0.507995 -0.665736 +v -163.555145 168.156815 43.199997 1.000000 1.000000 1.000000 +vn -0.694581 0.267303 -0.667912 +v -164.950775 165.893585 43.199997 1.000000 1.000000 1.000000 +vn -0.694581 0.267302 0.667912 +v -164.950775 165.893585 46.400017 1.000000 1.000000 1.000000 +vn -0.695533 0.127862 -0.707026 +v -165.089828 165.138702 43.199997 1.000000 1.000000 1.000000 +vn -0.695533 0.127862 0.707026 +v -165.089828 165.138702 46.400017 1.000000 1.000000 1.000000 +vn -0.723412 0.065810 -0.687273 +v -165.441299 163.222916 43.199997 1.000000 1.000000 1.000000 +vn -0.723412 0.065810 0.687273 +v -165.441299 163.222916 46.400017 1.000000 1.000000 1.000000 +vn -0.707107 0.000000 0.707107 +v -165.441299 161.301544 46.400017 1.000000 1.000000 1.000000 +vn -0.707107 0.000000 -0.707106 +v -165.441299 161.301544 43.199997 1.000000 1.000000 1.000000 +vn -0.707107 0.000000 0.707106 +v -165.441299 10.431056 46.399998 1.000000 1.000000 1.000000 +vn -0.707107 0.000000 -0.707107 +v -165.441299 10.431056 43.199997 1.000000 1.000000 1.000000 +vn -0.716358 -0.032776 0.696963 +v -165.441299 -142.359390 46.399979 1.000000 1.000000 1.000000 +vn -0.716358 -0.032775 -0.696963 +v -165.441299 -142.359390 43.199978 1.000000 1.000000 1.000000 +vn -0.714401 -0.131825 0.687207 +v -165.316422 -143.721237 46.399979 1.000000 1.000000 1.000000 +vn -0.714401 -0.131825 -0.687207 +v -165.316422 -143.721237 43.199978 1.000000 1.000000 1.000000 +vn -0.680806 -0.190476 0.707264 +v -165.160629 -144.276581 46.399979 1.000000 1.000000 1.000000 +vn -0.680806 -0.190476 -0.707264 +v -165.160629 -144.276581 43.199978 1.000000 1.000000 1.000000 +vn -0.678905 -0.259938 0.686673 +v -164.950775 -145.028671 46.399979 1.000000 1.000000 1.000000 +vn -0.678905 -0.259938 -0.686673 +v -164.950775 -145.028671 43.199978 1.000000 1.000000 1.000000 +vn -0.618586 -0.382092 0.686555 +v -164.354660 -146.234238 46.399979 1.000000 1.000000 1.000000 +vn -0.618586 -0.382092 -0.686555 +v -164.354660 -146.234238 43.199978 1.000000 1.000000 1.000000 +vn -0.535095 -0.493169 0.685899 +v -163.553848 -147.293289 46.399979 1.000000 1.000000 1.000000 +vn -0.535095 -0.493170 -0.685899 +v -163.553848 -147.293289 43.199978 1.000000 1.000000 1.000000 +vn -0.470567 -0.528128 0.706858 +v -163.188217 -147.619797 46.399979 1.000000 1.000000 1.000000 +vn -0.470567 -0.528128 -0.706858 +v -163.188217 -147.619797 43.199978 1.000000 1.000000 1.000000 +vn -0.426428 -0.590697 0.685008 +v -162.579239 -148.161194 46.399979 1.000000 1.000000 1.000000 +vn -0.426428 -0.590697 -0.685008 +v -162.579239 -148.161194 43.199978 1.000000 1.000000 1.000000 +vn -0.298439 -0.664686 0.684929 +v -161.468140 -148.803040 46.399979 1.000000 1.000000 1.000000 +vn -0.298439 -0.664686 -0.684929 +v -161.468140 -148.803040 43.199978 1.000000 1.000000 1.000000 +vn -0.153567 -0.713527 0.683591 +v -160.260483 -149.203506 46.399979 1.000000 1.000000 1.000000 +vn -0.153577 -0.713528 -0.683588 +v -160.260483 -149.203506 43.199978 1.000000 1.000000 1.000000 +vn -0.037262 -0.717450 0.695612 +v -159.001328 -149.334671 46.399960 1.000000 1.000000 1.000000 +vn -0.037272 -0.717444 -0.695618 +v -159.001328 -149.334671 43.199959 1.000000 1.000000 1.000000 +vn 0.000001 -0.707107 0.707107 +v -151.600876 -149.334671 46.399960 1.000000 1.000000 1.000000 +vn -0.000001 -0.707106 -0.707107 +v -151.600876 -149.334671 43.199959 1.000000 1.000000 1.000000 +vn 0.000000 -0.707107 0.707107 +v -134.219894 -149.334671 46.399960 1.000000 1.000000 1.000000 +vn 0.000000 -0.707107 -0.707107 +v -134.219894 -149.334671 43.199959 1.000000 1.000000 1.000000 +vn 0.000000 -0.707107 0.707107 +v -63.408436 -149.334671 46.399960 1.000000 1.000000 1.000000 +vn -0.000000 -0.707107 -0.707107 +v -63.408436 -149.334671 43.199959 1.000000 1.000000 1.000000 +vn 0.333951 -0.539761 0.772745 +v 125.851265 165.032669 46.399979 1.000000 1.000000 1.000000 +vn 0.197214 -0.679074 0.707082 +v 126.216522 165.138702 46.399979 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 1.000000 +v 63.408436 165.138702 46.399979 1.000000 1.000000 1.000000 +vn 0.564342 -0.303786 0.767615 +v 125.144432 164.266617 46.399979 1.000000 1.000000 1.000000 +vn 0.000001 -0.631202 0.775619 +v 126.816872 165.313126 46.399979 1.000000 1.000000 1.000000 +vn -0.197213 -0.679074 0.707082 +v 127.417229 165.138702 46.399979 1.000000 1.000000 1.000000 +vn 0.000002 -0.000002 1.000000 +v 134.219894 165.138702 46.399960 1.000000 1.000000 1.000000 +vn 0.000000 -0.000000 1.000000 +v 151.600876 165.138702 46.399960 1.000000 1.000000 1.000000 +vn -0.333951 -0.539757 0.772748 +v 127.782486 165.032669 46.399979 1.000000 1.000000 1.000000 +vn -0.564340 -0.303783 0.767617 +v 128.489319 164.266617 46.399979 1.000000 1.000000 1.000000 +vn 0.000001 -0.000001 1.000000 +v 134.219894 161.301544 46.399960 1.000000 1.000000 1.000000 +vn -0.643628 -0.000007 0.765338 +v 128.748093 163.220123 46.399979 1.000000 1.000000 1.000000 +vn -0.564340 0.303782 0.767618 +v 128.489319 162.173615 46.399960 1.000000 1.000000 1.000000 +vn -0.334026 0.539760 0.772713 +v 127.782486 161.407593 46.399960 1.000000 1.000000 1.000000 +vn -0.197232 0.679031 0.707118 +v 127.417480 161.301544 46.399960 1.000000 1.000000 1.000000 +vn 0.000014 0.631234 0.775593 +v 126.816872 161.127121 46.399979 1.000000 1.000000 1.000000 +vn 0.000000 -0.000000 1.000000 +v 134.219894 10.431098 46.399940 1.000000 1.000000 1.000000 +vn 0.197242 0.679026 0.707121 +v 126.216263 161.301544 46.399979 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 1.000000 +v 63.408436 161.301544 46.399979 1.000000 1.000000 1.000000 +vn 0.000000 -0.000000 1.000000 +v 63.408436 10.431076 46.399960 1.000000 1.000000 1.000000 +vn 0.000002 0.631240 0.775588 +v 0.000000 161.127121 46.399979 1.000000 1.000000 1.000000 +vn -0.197239 0.679025 0.707122 +v 0.600632 161.301544 46.399979 1.000000 1.000000 1.000000 +vn 0.000000 -0.000000 1.000000 +v 134.219894 -144.276581 46.399940 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 1.000000 +v 63.408436 -144.276581 46.399940 1.000000 1.000000 1.000000 +vn 0.197283 0.678924 0.707207 +v 158.402634 -144.276581 46.399918 1.000000 1.000000 1.000000 +vn 0.000002 -0.000002 1.000000 +v 151.600876 -144.276581 46.399940 1.000000 1.000000 1.000000 +vn 0.000000 0.631328 0.775516 +v 159.003891 -144.451004 46.399918 1.000000 1.000000 1.000000 +vn 0.334199 0.539745 0.772649 +v 158.038284 -144.170532 46.399918 1.000000 1.000000 1.000000 +vn 0.564341 0.303787 0.767615 +v 157.331451 -143.404495 46.399918 1.000000 1.000000 1.000000 +vn 0.643633 0.000001 0.765335 +v 157.072678 -142.358002 46.399918 1.000000 1.000000 1.000000 +vn 0.564341 -0.303784 0.767616 +v 157.331451 -141.311493 46.399918 1.000000 1.000000 1.000000 +vn 0.333998 -0.539760 0.772726 +v 158.038284 -140.545456 46.399918 1.000000 1.000000 1.000000 +vn 0.000000 -0.000000 1.000000 +v 151.600876 10.431098 46.399940 1.000000 1.000000 1.000000 +vn 0.000001 -0.631228 0.775598 +v 159.003891 -140.264999 46.399918 1.000000 1.000000 1.000000 +vn -0.333996 -0.539760 0.772726 +v 159.969513 -140.545456 46.399918 1.000000 1.000000 1.000000 +vn -0.564339 -0.303784 0.767617 +v 160.676346 -141.311493 46.399918 1.000000 1.000000 1.000000 +vn -0.643631 0.000001 0.765336 +v 160.935120 -142.358002 46.399918 1.000000 1.000000 1.000000 +vn -0.564339 0.303786 0.767617 +v 160.676346 -143.404495 46.399918 1.000000 1.000000 1.000000 +vn -0.334194 0.539740 0.772654 +v 159.969513 -144.170532 46.399918 1.000000 1.000000 1.000000 +vn -0.197279 0.678927 0.707206 +v 159.605148 -144.276581 46.399918 1.000000 1.000000 1.000000 +vn -0.197278 0.678926 0.707206 +v 159.605148 161.301544 46.399960 1.000000 1.000000 1.000000 +vn 0.000000 0.631328 0.775516 +v 159.003891 161.127121 46.399960 1.000000 1.000000 1.000000 +vn 0.197282 0.678924 0.707207 +v 158.402634 161.301544 46.399960 1.000000 1.000000 1.000000 +vn -0.334192 0.539743 0.772653 +v 159.969513 161.407593 46.399960 1.000000 1.000000 1.000000 +vn -0.564336 0.303787 0.767618 +v 160.676346 162.173615 46.399960 1.000000 1.000000 1.000000 +vn -0.643631 -0.000001 0.765336 +v 160.935120 163.220123 46.399960 1.000000 1.000000 1.000000 +vn -0.564342 -0.303784 0.767616 +v 160.676346 164.266617 46.399960 1.000000 1.000000 1.000000 +vn -0.333851 -0.539771 0.772781 +v 159.969513 165.032669 46.399960 1.000000 1.000000 1.000000 +vn -0.197189 -0.679134 0.707031 +v 159.603867 165.138702 46.399960 1.000000 1.000000 1.000000 +vn 0.000002 -0.631147 0.775663 +v 159.003891 165.313126 46.399960 1.000000 1.000000 1.000000 +vn 0.197191 -0.679134 0.707030 +v 158.403931 165.138702 46.399960 1.000000 1.000000 1.000000 +vn 0.333851 -0.539771 0.772781 +v 158.038284 165.032669 46.399960 1.000000 1.000000 1.000000 +vn 0.564342 -0.303784 0.767616 +v 157.331451 164.266617 46.399960 1.000000 1.000000 1.000000 +vn 0.643631 -0.000001 0.765336 +v 157.072678 163.220123 46.399960 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 1.000000 +v 151.600876 161.301544 46.399960 1.000000 1.000000 1.000000 +vn 0.564336 0.303787 0.767618 +v 157.331451 162.173615 46.399960 1.000000 1.000000 1.000000 +vn 0.334196 0.539743 0.772652 +v 158.038284 161.407593 46.399960 1.000000 1.000000 1.000000 +vn -0.682729 -0.061990 0.728038 +v 146.127808 163.568954 46.399960 1.000000 1.000000 1.000000 +vn -0.682728 0.061991 0.728038 +v 146.127808 162.871292 46.399960 1.000000 1.000000 1.000000 +vn -0.616511 0.236486 0.750992 +v 146.029953 162.336884 46.399960 1.000000 1.000000 1.000000 +vn -0.481726 0.446910 0.753798 +v 145.751862 161.884781 46.399960 1.000000 1.000000 1.000000 +vn -0.266340 0.597394 0.756428 +v 145.333435 161.582001 46.399960 1.000000 1.000000 1.000000 +vn -0.072237 0.677724 0.731759 +v 144.841614 161.475952 46.399960 1.000000 1.000000 1.000000 +vn -0.616503 -0.236492 0.750996 +v 146.029953 164.103378 46.399960 1.000000 1.000000 1.000000 +vn -0.266346 -0.597388 0.756431 +v 145.333435 164.858246 46.399960 1.000000 1.000000 1.000000 +vn -0.481730 -0.446917 0.753791 +v 145.751862 164.555450 46.399960 1.000000 1.000000 1.000000 +vn -0.072237 -0.677725 0.731759 +v 144.841614 164.964294 46.399960 1.000000 1.000000 1.000000 +vn -0.582116 -0.360470 0.728836 +v 145.911499 -141.233368 46.399940 1.000000 1.000000 1.000000 +vn -0.143838 -0.667425 0.730654 +v 145.092667 -140.641739 46.399940 1.000000 1.000000 1.000000 +vn -0.278269 -0.621980 0.731921 +v 145.333435 -140.719879 46.399940 1.000000 1.000000 1.000000 +vn -0.400386 -0.554079 0.729854 +v 145.556152 -140.849640 46.399940 1.000000 1.000000 1.000000 +vn -0.501102 -0.464591 0.730104 +v 145.751862 -141.022659 46.399940 1.000000 1.000000 1.000000 +vn 0.400830 -0.552325 0.730939 +v 140.262039 -140.849640 46.399940 1.000000 1.000000 1.000000 +vn 0.277616 -0.622626 0.731619 +v 140.486053 -140.719879 46.399940 1.000000 1.000000 1.000000 +vn 0.143637 -0.667395 0.730720 +v 140.726822 -140.641739 46.399940 1.000000 1.000000 1.000000 +vn 0.038219 -0.693222 0.719710 +v 140.979156 -140.613831 46.399940 1.000000 1.000000 1.000000 +vn -0.038409 -0.693145 0.719774 +v 144.841614 -140.613831 46.399940 1.000000 1.000000 1.000000 +vn -0.639187 -0.245451 0.728830 +v 146.031250 -141.474747 46.399940 1.000000 1.000000 1.000000 +vn -0.673772 -0.121816 0.728830 +v 146.104630 -141.737076 46.399940 1.000000 1.000000 1.000000 +vn -0.696656 -0.029618 0.716794 +v 146.127808 -142.009171 46.399940 1.000000 1.000000 1.000000 +vn -0.696656 0.029618 0.716794 +v 146.127808 -142.706833 46.399940 1.000000 1.000000 1.000000 +vn -0.673769 0.121821 0.728831 +v 146.104630 -142.978928 46.399940 1.000000 1.000000 1.000000 +vn -0.638639 0.246080 0.729099 +v 146.031250 -143.241241 46.399940 1.000000 1.000000 1.000000 +vn -0.581940 0.361291 0.728570 +v 145.911499 -143.481247 46.399940 1.000000 1.000000 1.000000 +vn -0.503683 0.463290 0.729154 +v 145.751862 -143.691940 46.399940 1.000000 1.000000 1.000000 +vn -0.400333 0.552123 0.731364 +v 145.556152 -143.867752 46.399940 1.000000 1.000000 1.000000 +vn -0.278961 0.623070 0.730729 +v 145.333435 -143.996109 46.399940 1.000000 1.000000 1.000000 +vn -0.143482 0.666097 0.731935 +v 145.092667 -144.075653 46.399940 1.000000 1.000000 1.000000 +vn -0.036548 0.693904 0.719139 +v 144.841614 -144.102173 46.399940 1.000000 1.000000 1.000000 +vn 0.502165 -0.466111 0.728403 +v 140.068909 -141.022659 46.399940 1.000000 1.000000 1.000000 +vn 0.640242 -0.242608 0.728856 +v 139.788239 -141.474747 46.399940 1.000000 1.000000 1.000000 +vn 0.580203 -0.360655 0.730269 +v 139.906693 -141.233368 46.399940 1.000000 1.000000 1.000000 +vn 0.675195 -0.123751 0.727184 +v 139.716141 -141.737076 46.399940 1.000000 1.000000 1.000000 +vn 0.695399 -0.032821 0.717874 +v 139.690399 -142.009171 46.399940 1.000000 1.000000 1.000000 +vn 0.695399 0.032821 0.717874 +v 139.690399 -142.706833 46.399940 1.000000 1.000000 1.000000 +vn 0.675193 0.123755 0.727186 +v 139.716141 -142.978928 46.399940 1.000000 1.000000 1.000000 +vn 0.639701 0.243235 0.729123 +v 139.788239 -143.241241 46.399940 1.000000 1.000000 1.000000 +vn 0.580029 0.361470 0.730004 +v 139.906693 -143.481247 46.399940 1.000000 1.000000 1.000000 +vn 0.504749 0.464798 0.727455 +v 140.068909 -143.691940 46.399940 1.000000 1.000000 1.000000 +vn 0.400773 0.550358 0.732452 +v 140.262039 -143.867752 46.399940 1.000000 1.000000 1.000000 +vn 0.278310 0.623711 0.730430 +v 140.486053 -143.996109 46.399940 1.000000 1.000000 1.000000 +vn 0.143291 0.666068 0.731998 +v 140.726822 -144.075653 46.399940 1.000000 1.000000 1.000000 +vn 0.036368 0.693977 0.719078 +v 140.979156 -144.102173 46.399940 1.000000 1.000000 1.000000 +vn 0.672405 0.082498 0.735572 +v 139.690399 162.871292 46.399960 1.000000 1.000000 1.000000 +vn 0.564309 0.304403 0.767394 +v 139.864212 162.173615 46.399960 1.000000 1.000000 1.000000 +vn 0.094715 0.665647 0.740232 +v 140.979156 161.475952 46.399960 1.000000 1.000000 1.000000 +vn 0.334004 0.539757 0.772725 +v 140.335419 161.662933 46.399960 1.000000 1.000000 1.000000 +vn 0.672404 -0.082499 0.735572 +v 139.690399 163.568954 46.399960 1.000000 1.000000 1.000000 +vn 0.564318 -0.304399 0.767390 +v 139.864212 164.266617 46.399960 1.000000 1.000000 1.000000 +vn 0.334002 -0.539749 0.772731 +v 140.335419 164.777328 46.399960 1.000000 1.000000 1.000000 +vn 0.094708 -0.665651 0.740229 +v 140.979156 164.964294 46.399960 1.000000 1.000000 1.000000 +vn -0.564334 -0.303773 0.767626 +v 1.672502 164.266617 46.399979 1.000000 1.000000 1.000000 +vn -0.643645 -0.000001 0.765324 +v 1.931222 163.220123 46.399979 1.000000 1.000000 1.000000 +vn 0.334028 0.539759 0.772713 +v 125.851265 161.407593 46.399979 1.000000 1.000000 1.000000 +vn 0.564336 0.303789 0.767618 +v 125.144432 162.173615 46.399979 1.000000 1.000000 1.000000 +vn 0.643629 -0.000001 0.765338 +v 124.885651 163.220123 46.399979 1.000000 1.000000 1.000000 +vn -0.197211 -0.679075 0.707082 +v 0.600362 165.138702 46.399979 1.000000 1.000000 1.000000 +vn -0.333944 -0.539771 0.772741 +v 0.965626 165.032669 46.399979 1.000000 1.000000 1.000000 +vn 0.000002 -0.631202 0.775618 +v 0.000000 165.313126 46.399979 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 1.000000 +v -63.408436 165.138702 46.399998 1.000000 1.000000 1.000000 +vn -0.197215 -0.679074 0.707082 +v -126.216522 165.138702 46.399998 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 1.000000 +v -63.408436 161.301544 46.399998 1.000000 1.000000 1.000000 +vn 0.643642 -0.000001 0.765326 +v -1.931208 163.220123 46.399979 1.000000 1.000000 1.000000 +vn 0.564336 -0.303775 0.767623 +v -1.672476 164.266617 46.399979 1.000000 1.000000 1.000000 +vn -0.333951 -0.539761 0.772745 +v -125.851265 165.032669 46.399998 1.000000 1.000000 1.000000 +vn -0.564342 -0.303786 0.767615 +v -125.144432 164.266617 46.399998 1.000000 1.000000 1.000000 +vn 0.197214 -0.679075 0.707081 +v -0.600348 165.138702 46.399979 1.000000 1.000000 1.000000 +vn 0.333946 -0.539769 0.772742 +v -0.965610 165.032669 46.399979 1.000000 1.000000 1.000000 +vn 0.000000 -0.000000 1.000000 +v -134.219894 165.138702 46.399998 1.000000 1.000000 1.000000 +vn 0.197213 -0.679074 0.707082 +v -127.417229 165.138702 46.399998 1.000000 1.000000 1.000000 +vn -0.000001 -0.631201 0.775619 +v -126.816872 165.313126 46.399998 1.000000 1.000000 1.000000 +vn 0.333951 -0.539761 0.772745 +v -127.782486 165.032669 46.399998 1.000000 1.000000 1.000000 +vn 0.564342 -0.303784 0.767616 +v -128.489319 164.266617 46.399998 1.000000 1.000000 1.000000 +vn 0.643631 -0.000001 0.765336 +v -128.748093 163.220123 46.399998 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 1.000000 +v -134.219894 161.301544 46.399998 1.000000 1.000000 1.000000 +vn 0.564336 0.303787 0.767618 +v -128.489319 162.173615 46.399998 1.000000 1.000000 1.000000 +vn 0.334026 0.539760 0.772714 +v -127.782486 161.407593 46.399998 1.000000 1.000000 1.000000 +vn 0.197241 0.679027 0.707120 +v -127.417480 161.301544 46.399998 1.000000 1.000000 1.000000 +vn 0.000000 -0.000000 1.000000 +v -134.219894 10.431056 46.399979 1.000000 1.000000 1.000000 +vn 0.000000 0.631237 0.775590 +v -126.816872 161.127121 46.399998 1.000000 1.000000 1.000000 +vn -0.197242 0.679026 0.707121 +v -126.216263 161.301544 46.399998 1.000000 1.000000 1.000000 +vn 0.000000 -0.000000 1.000000 +v -63.408436 10.431076 46.399979 1.000000 1.000000 1.000000 +vn 0.197242 0.679025 0.707121 +v -0.600616 161.301544 46.399979 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 1.000000 +v -63.408436 -144.276581 46.399960 1.000000 1.000000 1.000000 +vn -0.643629 -0.000001 0.765338 +v -124.885651 163.220123 46.399998 1.000000 1.000000 1.000000 +vn -0.564336 0.303789 0.767618 +v -125.144432 162.173615 46.399998 1.000000 1.000000 1.000000 +vn -0.334028 0.539759 0.772713 +v -125.851265 161.407593 46.399998 1.000000 1.000000 1.000000 +vn 0.000001 -0.000002 1.000000 +v -151.600876 161.301544 46.399998 1.000000 1.000000 1.000000 +vn 0.000001 -0.000000 1.000000 +v -151.600876 10.431056 46.399979 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 1.000000 +v -134.219894 -144.276581 46.399960 1.000000 1.000000 1.000000 +vn -0.582116 -0.360470 0.728836 +v -139.909271 -141.233368 46.399960 1.000000 1.000000 1.000000 +vn -0.143838 -0.667425 0.730654 +v -140.728104 -140.641739 46.399960 1.000000 1.000000 1.000000 +vn -0.278269 -0.621980 0.731921 +v -140.487335 -140.719879 46.399960 1.000000 1.000000 1.000000 +vn -0.400386 -0.554079 0.729854 +v -140.264618 -140.849640 46.399960 1.000000 1.000000 1.000000 +vn -0.501102 -0.464591 0.730104 +v -140.068909 -141.022659 46.399960 1.000000 1.000000 1.000000 +vn 0.400830 -0.552326 0.730939 +v -145.558731 -140.849640 46.399960 1.000000 1.000000 1.000000 +vn 0.277616 -0.622626 0.731619 +v -145.334717 -140.719879 46.399960 1.000000 1.000000 1.000000 +vn 0.143637 -0.667395 0.730720 +v -145.093948 -140.641739 46.399960 1.000000 1.000000 1.000000 +vn 0.038219 -0.693223 0.719710 +v -144.841614 -140.613831 46.399960 1.000000 1.000000 1.000000 +vn -0.038409 -0.693145 0.719774 +v -140.979156 -140.613831 46.399960 1.000000 1.000000 1.000000 +vn 0.502165 -0.466111 0.728403 +v -145.751862 -141.022659 46.399960 1.000000 1.000000 1.000000 +vn 0.580203 -0.360655 0.730269 +v -145.914078 -141.233368 46.399960 1.000000 1.000000 1.000000 +vn 0.640242 -0.242608 0.728856 +v -146.032532 -141.474747 46.399960 1.000000 1.000000 1.000000 +vn 0.675195 -0.123751 0.727184 +v -146.104630 -141.737076 46.399960 1.000000 1.000000 1.000000 +vn 0.000001 -0.000000 1.000000 +v -151.600876 -144.276581 46.399960 1.000000 1.000000 1.000000 +vn 0.695399 -0.032821 0.717874 +v -146.130371 -142.009171 46.399960 1.000000 1.000000 1.000000 +vn 0.695399 0.032821 0.717874 +v -146.130371 -142.706833 46.399960 1.000000 1.000000 1.000000 +vn 0.675193 0.123755 0.727186 +v -146.104630 -142.978928 46.399960 1.000000 1.000000 1.000000 +vn 0.639701 0.243235 0.729123 +v -146.032532 -143.241241 46.399960 1.000000 1.000000 1.000000 +vn 0.580029 0.361470 0.730004 +v -145.914078 -143.481247 46.399960 1.000000 1.000000 1.000000 +vn 0.504749 0.464798 0.727455 +v -145.751862 -143.691940 46.399960 1.000000 1.000000 1.000000 +vn 0.400773 0.550358 0.732453 +v -145.558731 -143.867752 46.399960 1.000000 1.000000 1.000000 +vn 0.278310 0.623711 0.730430 +v -145.334717 -143.996109 46.399960 1.000000 1.000000 1.000000 +vn 0.143291 0.666068 0.731998 +v -145.093948 -144.075653 46.399960 1.000000 1.000000 1.000000 +vn 0.036368 0.693977 0.719078 +v -144.841614 -144.102173 46.399960 1.000000 1.000000 1.000000 +vn -0.333996 -0.539760 0.772726 +v -158.038284 -140.545456 46.399979 1.000000 1.000000 1.000000 +vn -0.564337 -0.303782 0.767620 +v -157.331451 -141.311493 46.399979 1.000000 1.000000 1.000000 +vn -0.643629 0.000001 0.765337 +v -157.072678 -142.358002 46.399979 1.000000 1.000000 1.000000 +vn -0.564338 0.303785 0.767618 +v -157.331451 -143.404495 46.399979 1.000000 1.000000 1.000000 +vn -0.333862 0.539769 0.772778 +v -158.038284 -144.170532 46.399979 1.000000 1.000000 1.000000 +vn -0.197203 0.679125 0.707036 +v -158.403931 -144.276581 46.399979 1.000000 1.000000 1.000000 +vn -0.000001 0.631146 0.775664 +v -159.003891 -144.451004 46.399979 1.000000 1.000000 1.000000 +vn 0.197200 0.679127 0.707036 +v -159.603867 -144.276581 46.399979 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 1.000000 +v -163.188217 -144.276581 46.399979 1.000000 1.000000 1.000000 +vn 0.333863 0.539773 0.772775 +v -159.969513 -144.170532 46.399979 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 1.000000 +v -163.188217 161.301544 46.400017 1.000000 1.000000 1.000000 +vn 0.000001 -0.000000 1.000000 +v -163.188217 10.431056 46.399998 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 1.000000 +v -163.188217 165.138702 46.400017 1.000000 1.000000 1.000000 +vn 0.197189 -0.679134 0.707031 +v -159.603867 165.138702 46.400017 1.000000 1.000000 1.000000 +vn 0.333851 -0.539771 0.772781 +v -159.969513 165.032669 46.400017 1.000000 1.000000 1.000000 +vn -0.000002 -0.631147 0.775663 +v -159.003891 165.313126 46.400017 1.000000 1.000000 1.000000 +vn -0.197191 -0.679134 0.707030 +v -158.403931 165.138702 46.400017 1.000000 1.000000 1.000000 +vn -0.333851 -0.539771 0.772781 +v -158.038284 165.032669 46.400017 1.000000 1.000000 1.000000 +vn 0.000001 -0.000002 1.000000 +v -151.600876 165.138702 46.400017 1.000000 1.000000 1.000000 +vn -0.094708 -0.665651 0.740229 +v -140.979156 164.964294 46.399998 1.000000 1.000000 1.000000 +vn -0.334002 -0.539749 0.772731 +v -140.335419 164.777328 46.399998 1.000000 1.000000 1.000000 +vn -0.564380 -0.303172 0.767830 +v -139.864212 164.266617 46.399998 1.000000 1.000000 1.000000 +vn -0.672995 -0.081389 0.735156 +v -139.692963 163.568954 46.399998 1.000000 1.000000 1.000000 +vn -0.682728 0.061991 0.728038 +v -139.692963 162.871292 46.399998 1.000000 1.000000 1.000000 +vn -0.616511 0.236486 0.750992 +v -139.790817 162.336884 46.399998 1.000000 1.000000 1.000000 +vn -0.481726 0.446910 0.753798 +v -140.068909 161.884781 46.399998 1.000000 1.000000 1.000000 +vn -0.266340 0.597394 0.756428 +v -140.487335 161.582001 46.399998 1.000000 1.000000 1.000000 +vn -0.072237 0.677724 0.731759 +v -140.979156 161.475952 46.399998 1.000000 1.000000 1.000000 +vn -0.564341 -0.303784 0.767616 +v -157.331451 164.266617 46.400017 1.000000 1.000000 1.000000 +vn 0.564319 -0.304400 0.767388 +v -145.956558 164.266617 46.399998 1.000000 1.000000 1.000000 +vn 0.334003 -0.539753 0.772728 +v -145.485352 164.777328 46.399998 1.000000 1.000000 1.000000 +vn 0.094706 -0.665676 0.740207 +v -144.841614 164.964294 46.399998 1.000000 1.000000 1.000000 +vn 0.682370 0.062746 0.728309 +v -146.130371 162.871292 46.399998 1.000000 1.000000 1.000000 +vn 0.672405 -0.082499 0.735571 +v -146.130371 163.568954 46.399998 1.000000 1.000000 1.000000 +vn -0.643629 -0.000001 0.765337 +v -157.072678 163.220123 46.400017 1.000000 1.000000 1.000000 +vn -0.564335 0.303786 0.767620 +v -157.331451 162.173615 46.400017 1.000000 1.000000 1.000000 +vn -0.333860 0.539772 0.772777 +v -158.038284 161.407593 46.400017 1.000000 1.000000 1.000000 +vn -0.197202 0.679126 0.707035 +v -158.403931 161.301544 46.400017 1.000000 1.000000 1.000000 +vn -0.000002 0.631147 0.775663 +v -159.003891 161.127121 46.400017 1.000000 1.000000 1.000000 +vn 0.197200 0.679127 0.707036 +v -159.603867 161.301544 46.400017 1.000000 1.000000 1.000000 +vn 0.333861 0.539776 0.772774 +v -159.969513 161.407593 46.400017 1.000000 1.000000 1.000000 +vn 0.564336 0.303787 0.767618 +v -160.676346 162.173615 46.400017 1.000000 1.000000 1.000000 +vn 0.643631 -0.000001 0.765336 +v -160.935120 163.220123 46.400017 1.000000 1.000000 1.000000 +vn 0.564342 -0.303784 0.767615 +v -160.676346 164.266617 46.400017 1.000000 1.000000 1.000000 +vn 0.564339 -0.303785 0.767617 +v -160.676346 -141.311493 46.399979 1.000000 1.000000 1.000000 +vn -0.000001 -0.631228 0.775597 +v -159.003891 -140.264999 46.399979 1.000000 1.000000 1.000000 +vn 0.333996 -0.539760 0.772726 +v -159.969513 -140.545456 46.399979 1.000000 1.000000 1.000000 +vn 0.564339 0.303786 0.767617 +v -160.676346 -143.404495 46.399979 1.000000 1.000000 1.000000 +vn 0.643631 0.000001 0.765336 +v -160.935120 -142.358002 46.399979 1.000000 1.000000 1.000000 +vn 0.481957 0.447403 0.753358 +v -145.751862 161.884781 46.399998 1.000000 1.000000 1.000000 +vn 0.616021 0.237843 0.750966 +v -146.031250 162.336884 46.399998 1.000000 1.000000 1.000000 +vn 0.072063 0.677812 0.731695 +v -144.841614 161.475952 46.399998 1.000000 1.000000 1.000000 +vn 0.266498 0.597008 0.756677 +v -145.334717 161.582001 46.399998 1.000000 1.000000 1.000000 +vn -0.639187 -0.245451 0.728830 +v -139.789520 -141.474747 46.399960 1.000000 1.000000 1.000000 +vn -0.673772 -0.121816 0.728830 +v -139.716141 -141.737076 46.399960 1.000000 1.000000 1.000000 +vn -0.696656 -0.029618 0.716794 +v -139.692963 -142.009171 46.399960 1.000000 1.000000 1.000000 +vn -0.696656 0.029618 0.716794 +v -139.692963 -142.706833 46.399960 1.000000 1.000000 1.000000 +vn -0.673769 0.121821 0.728831 +v -139.716141 -142.978928 46.399960 1.000000 1.000000 1.000000 +vn -0.638639 0.246080 0.729099 +v -139.789520 -143.241241 46.399960 1.000000 1.000000 1.000000 +vn -0.581940 0.361291 0.728570 +v -139.909271 -143.481247 46.399960 1.000000 1.000000 1.000000 +vn -0.503683 0.463290 0.729154 +v -140.068909 -143.691940 46.399960 1.000000 1.000000 1.000000 +vn -0.400333 0.552123 0.731364 +v -140.264618 -143.867752 46.399960 1.000000 1.000000 1.000000 +vn -0.278961 0.623069 0.730729 +v -140.487335 -143.996109 46.399960 1.000000 1.000000 1.000000 +vn -0.143482 0.666097 0.731935 +v -140.728104 -144.075653 46.399960 1.000000 1.000000 1.000000 +vn -0.036548 0.693904 0.719139 +v -140.979156 -144.102173 46.399960 1.000000 1.000000 1.000000 +vn -0.564328 0.303776 0.767629 +v 1.672502 162.173615 46.399979 1.000000 1.000000 1.000000 +vn -0.334023 0.539768 0.772709 +v 0.965626 161.407593 46.399979 1.000000 1.000000 1.000000 +vn 0.334025 0.539767 0.772709 +v -0.965610 161.407593 46.399979 1.000000 1.000000 1.000000 +vn 0.564331 0.303778 0.767626 +v -1.672476 162.173615 46.399979 1.000000 1.000000 1.000000 +vn 0.564318 -0.304399 -0.767390 +v -145.956558 164.266617 43.199997 1.000000 1.000000 1.000000 +vn 0.672404 -0.082499 -0.735572 +v -146.130371 163.568954 43.199997 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 -1.000000 +v -151.600876 165.138702 43.199997 1.000000 1.000000 1.000000 +vn 0.334002 -0.539749 -0.772731 +v -145.485352 164.777328 43.199997 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 -1.000000 +v -151.600876 161.301544 43.199997 1.000000 1.000000 1.000000 +vn 0.682369 0.062747 -0.728310 +v -146.130371 162.871292 43.199997 1.000000 1.000000 1.000000 +vn 0.616021 0.237843 -0.750966 +v -146.031250 162.336884 43.199997 1.000000 1.000000 1.000000 +vn 0.481957 0.447403 -0.753358 +v -145.751862 161.884781 43.199997 1.000000 1.000000 1.000000 +vn 0.266498 0.597008 -0.756677 +v -145.334717 161.582001 43.199997 1.000000 1.000000 1.000000 +vn 0.072063 0.677812 -0.731695 +v -144.841614 161.475952 43.199997 1.000000 1.000000 1.000000 +vn -0.333861 0.539776 -0.772774 +v -158.038284 161.407593 43.199997 1.000000 1.000000 1.000000 +vn -0.564336 0.303787 -0.767618 +v -157.331451 162.173615 43.199997 1.000000 1.000000 1.000000 +vn -0.643631 -0.000001 -0.765336 +v -157.072678 163.220123 43.199997 1.000000 1.000000 1.000000 +vn -0.197203 0.679127 -0.707035 +v -158.403931 161.301544 43.199997 1.000000 1.000000 1.000000 +vn -0.000001 0.000000 -1.000000 +v -151.600876 10.431056 43.199978 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 -1.000000 +v -134.219894 10.431056 43.199978 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 -1.000000 +v -134.219894 161.301544 43.199997 1.000000 1.000000 1.000000 +vn -0.564342 -0.303784 -0.767615 +v -157.331451 164.266617 43.199997 1.000000 1.000000 1.000000 +vn -0.333851 -0.539771 -0.772781 +v -158.038284 165.032669 43.199997 1.000000 1.000000 1.000000 +vn 0.094708 -0.665651 -0.740229 +v -144.841614 164.964294 43.199997 1.000000 1.000000 1.000000 +vn -0.197191 -0.679134 -0.707030 +v -158.403931 165.138702 43.199997 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 -1.000000 +v -134.219894 165.138702 43.199997 1.000000 1.000000 1.000000 +vn -0.000002 -0.631147 -0.775663 +v -159.003891 165.313126 43.199997 1.000000 1.000000 1.000000 +vn -0.000000 0.000000 -1.000000 +v -63.408436 165.138702 43.199997 1.000000 1.000000 1.000000 +vn -0.197214 -0.679074 -0.707082 +v -126.216522 165.138702 43.199997 1.000000 1.000000 1.000000 +vn -0.000001 -0.631202 -0.775619 +v -126.816872 165.313126 43.199997 1.000000 1.000000 1.000000 +vn 0.197213 -0.679074 -0.707082 +v -127.417229 165.138702 43.199997 1.000000 1.000000 1.000000 +vn 0.000002 -0.631201 -0.775619 +v 0.000000 165.313126 43.199978 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 -1.000000 +v 63.408436 165.138702 43.199978 1.000000 1.000000 1.000000 +vn 0.197215 -0.679074 -0.707082 +v 126.216522 165.138702 43.199978 1.000000 1.000000 1.000000 +vn 0.000001 -0.631201 -0.775619 +v 126.816872 165.313126 43.199978 1.000000 1.000000 1.000000 +vn -0.197214 -0.679074 -0.707082 +v 127.417229 165.138702 43.199978 1.000000 1.000000 1.000000 +vn -0.000002 0.000002 -1.000000 +v 134.219894 165.138702 43.199959 1.000000 1.000000 1.000000 +vn -0.000000 0.000000 -1.000000 +v 151.600876 165.138702 43.199959 1.000000 1.000000 1.000000 +vn 0.333951 -0.539761 -0.772745 +v 125.851265 165.032669 43.199978 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 -1.000000 +v 63.408436 161.301544 43.199978 1.000000 1.000000 1.000000 +vn 0.564342 -0.303786 -0.767615 +v 125.144432 164.266617 43.199978 1.000000 1.000000 1.000000 +vn 0.643629 -0.000001 -0.765338 +v 124.885651 163.220123 43.199978 1.000000 1.000000 1.000000 +vn 0.564336 0.303789 -0.767618 +v 125.144432 162.173615 43.199978 1.000000 1.000000 1.000000 +vn 0.334028 0.539759 -0.772713 +v 125.851265 161.407593 43.199978 1.000000 1.000000 1.000000 +vn 0.197242 0.679026 -0.707121 +v 126.216263 161.301544 43.199978 1.000000 1.000000 1.000000 +vn -0.334023 0.539768 -0.772709 +v 0.965626 161.407593 43.199978 1.000000 1.000000 1.000000 +vn -0.197239 0.679025 -0.707122 +v 0.600632 161.301544 43.199978 1.000000 1.000000 1.000000 +vn -0.000000 0.000000 -1.000000 +v 63.408436 10.431076 43.199959 1.000000 1.000000 1.000000 +vn -0.643645 -0.000001 -0.765324 +v 1.931222 163.220123 43.199978 1.000000 1.000000 1.000000 +vn -0.564334 -0.303773 -0.767626 +v 1.672502 164.266617 43.199978 1.000000 1.000000 1.000000 +vn -0.333944 -0.539771 -0.772741 +v 0.965626 165.032669 43.199978 1.000000 1.000000 1.000000 +vn -0.197211 -0.679075 -0.707082 +v 0.600362 165.138702 43.199978 1.000000 1.000000 1.000000 +vn -0.000000 0.000000 -1.000000 +v 134.219894 10.431098 43.199940 1.000000 1.000000 1.000000 +vn -0.000014 0.631241 -0.775587 +v 126.816872 161.127121 43.199978 1.000000 1.000000 1.000000 +vn -0.000000 0.000000 -1.000000 +v 134.219894 -144.276581 43.199921 1.000000 1.000000 1.000000 +vn -0.000000 0.000000 -1.000000 +v 63.408436 -144.276581 43.199940 1.000000 1.000000 1.000000 +vn 0.197282 0.678924 -0.707207 +v 158.402634 -144.276581 43.199921 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 -1.000000 +v 151.600876 -144.276581 43.199921 1.000000 1.000000 1.000000 +vn 0.334198 0.539740 -0.772653 +v 158.038284 -144.170532 43.199921 1.000000 1.000000 1.000000 +vn 0.000000 0.631328 -0.775516 +v 159.003891 -144.451004 43.199921 1.000000 1.000000 1.000000 +vn -0.197279 0.678927 -0.707206 +v 159.605148 -144.276581 43.199921 1.000000 1.000000 1.000000 +vn -0.334194 0.539740 -0.772655 +v 159.969513 -144.170532 43.199921 1.000000 1.000000 1.000000 +vn -0.564339 0.303786 -0.767617 +v 160.676346 -143.404495 43.199921 1.000000 1.000000 1.000000 +vn -0.643631 0.000001 -0.765336 +v 160.935120 -142.358002 43.199921 1.000000 1.000000 1.000000 +vn -0.564339 -0.303784 -0.767617 +v 160.676346 -141.311493 43.199921 1.000000 1.000000 1.000000 +vn -0.333996 -0.539760 -0.772726 +v 159.969513 -140.545456 43.199921 1.000000 1.000000 1.000000 +vn 0.000001 -0.631228 -0.775598 +v 159.003891 -140.264999 43.199921 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 -1.000000 +v 151.600876 10.431098 43.199940 1.000000 1.000000 1.000000 +vn 0.333998 -0.539760 -0.772726 +v 158.038284 -140.545456 43.199921 1.000000 1.000000 1.000000 +vn 0.564339 -0.303784 -0.767617 +v 157.331451 -141.311493 43.199921 1.000000 1.000000 1.000000 +vn 0.643631 0.000001 -0.765336 +v 157.072678 -142.358002 43.199921 1.000000 1.000000 1.000000 +vn 0.564339 0.303786 -0.767617 +v 157.331451 -143.404495 43.199921 1.000000 1.000000 1.000000 +vn -0.278961 0.623070 -0.730729 +v 145.333435 -143.996109 43.199921 1.000000 1.000000 1.000000 +vn -0.400333 0.552123 -0.731364 +v 145.556152 -143.867752 43.199921 1.000000 1.000000 1.000000 +vn -0.503683 0.463290 -0.729154 +v 145.751862 -143.691940 43.199921 1.000000 1.000000 1.000000 +vn -0.581940 0.361292 -0.728570 +v 145.911499 -143.481247 43.199921 1.000000 1.000000 1.000000 +vn -0.638639 0.246080 -0.729099 +v 146.031250 -143.241241 43.199921 1.000000 1.000000 1.000000 +vn -0.673769 0.121821 -0.728831 +v 146.104630 -142.978928 43.199921 1.000000 1.000000 1.000000 +vn -0.696656 0.029618 -0.716794 +v 146.127808 -142.706833 43.199921 1.000000 1.000000 1.000000 +vn -0.696656 -0.029618 -0.716794 +v 146.127808 -142.009171 43.199921 1.000000 1.000000 1.000000 +vn -0.036548 0.693904 -0.719139 +v 144.841614 -144.102173 43.199921 1.000000 1.000000 1.000000 +vn -0.143482 0.666096 -0.731935 +v 145.092667 -144.075653 43.199921 1.000000 1.000000 1.000000 +vn -0.673772 -0.121816 -0.728830 +v 146.104630 -141.737076 43.199921 1.000000 1.000000 1.000000 +vn -0.639187 -0.245451 -0.728830 +v 146.031250 -141.474747 43.199921 1.000000 1.000000 1.000000 +vn -0.582116 -0.360470 -0.728836 +v 145.911499 -141.233368 43.199921 1.000000 1.000000 1.000000 +vn -0.000001 0.000001 -1.000000 +v 134.219894 161.301544 43.199959 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 -1.000000 +v 151.600876 161.301544 43.199959 1.000000 1.000000 1.000000 +vn 0.197282 0.678924 -0.707207 +v 158.402634 161.301544 43.199959 1.000000 1.000000 1.000000 +vn -0.501102 -0.464591 -0.730104 +v 145.751862 -141.022659 43.199921 1.000000 1.000000 1.000000 +vn -0.400386 -0.554079 -0.729854 +v 145.556152 -140.849640 43.199921 1.000000 1.000000 1.000000 +vn -0.278269 -0.621980 -0.731921 +v 145.333435 -140.719879 43.199921 1.000000 1.000000 1.000000 +vn -0.143838 -0.667425 -0.730654 +v 145.092667 -140.641739 43.199921 1.000000 1.000000 1.000000 +vn -0.038409 -0.693145 -0.719774 +v 144.841614 -140.613831 43.199921 1.000000 1.000000 1.000000 +vn 0.038219 -0.693222 -0.719710 +v 140.979156 -140.613831 43.199921 1.000000 1.000000 1.000000 +vn 0.143637 -0.667395 -0.730720 +v 140.726822 -140.641739 43.199921 1.000000 1.000000 1.000000 +vn 0.277616 -0.622625 -0.731619 +v 140.486053 -140.719879 43.199921 1.000000 1.000000 1.000000 +vn 0.400830 -0.552325 -0.730939 +v 140.262039 -140.849640 43.199921 1.000000 1.000000 1.000000 +vn -0.197249 0.679022 -0.707122 +v 127.417480 161.301544 43.199959 1.000000 1.000000 1.000000 +vn 0.502165 -0.466111 -0.728403 +v 140.068909 -141.022659 43.199921 1.000000 1.000000 1.000000 +vn -0.334026 0.539760 -0.772714 +v 127.782486 161.407593 43.199959 1.000000 1.000000 1.000000 +vn -0.564332 0.303792 -0.767619 +v 128.489319 162.173615 43.199959 1.000000 1.000000 1.000000 +vn -0.643633 0.000005 -0.765334 +v 128.748093 163.220123 43.199978 1.000000 1.000000 1.000000 +vn -0.564343 -0.303785 -0.767614 +v 128.489319 164.266617 43.199978 1.000000 1.000000 1.000000 +vn -0.333952 -0.539765 -0.772741 +v 127.782486 165.032669 43.199978 1.000000 1.000000 1.000000 +vn 0.564318 -0.304399 -0.767390 +v 139.864212 164.266617 43.199959 1.000000 1.000000 1.000000 +vn 0.672404 -0.082499 -0.735572 +v 139.690399 163.568954 43.199959 1.000000 1.000000 1.000000 +vn 0.094708 -0.665651 -0.740229 +v 140.979156 164.964294 43.199959 1.000000 1.000000 1.000000 +vn 0.334002 -0.539749 -0.772731 +v 140.335419 164.777328 43.199959 1.000000 1.000000 1.000000 +vn 0.672405 0.082498 -0.735572 +v 139.690399 162.871292 43.199959 1.000000 1.000000 1.000000 +vn 0.564309 0.304403 -0.767394 +v 139.864212 162.173615 43.199959 1.000000 1.000000 1.000000 +vn 0.334004 0.539757 -0.772725 +v 140.335419 161.662933 43.199959 1.000000 1.000000 1.000000 +vn 0.094715 0.665647 -0.740232 +v 140.979156 161.475952 43.199959 1.000000 1.000000 1.000000 +vn 0.695399 0.032821 -0.717874 +v 139.690399 -142.706833 43.199921 1.000000 1.000000 1.000000 +vn 0.675192 0.123756 -0.727186 +v 139.716141 -142.978928 43.199921 1.000000 1.000000 1.000000 +vn 0.639701 0.243235 -0.729123 +v 139.788239 -143.241241 43.199921 1.000000 1.000000 1.000000 +vn 0.580029 0.361470 -0.730004 +v 139.906693 -143.481247 43.199921 1.000000 1.000000 1.000000 +vn 0.504749 0.464798 -0.727455 +v 140.068909 -143.691940 43.199921 1.000000 1.000000 1.000000 +vn 0.580203 -0.360655 -0.730269 +v 139.906693 -141.233368 43.199921 1.000000 1.000000 1.000000 +vn 0.640242 -0.242608 -0.728856 +v 139.788239 -141.474747 43.199921 1.000000 1.000000 1.000000 +vn 0.675195 -0.123751 -0.727184 +v 139.716141 -141.737076 43.199921 1.000000 1.000000 1.000000 +vn 0.695399 -0.032821 -0.717874 +v 139.690399 -142.009171 43.199921 1.000000 1.000000 1.000000 +vn 0.400773 0.550358 -0.732452 +v 140.262039 -143.867752 43.199921 1.000000 1.000000 1.000000 +vn 0.278310 0.623711 -0.730430 +v 140.486053 -143.996109 43.199921 1.000000 1.000000 1.000000 +vn 0.143291 0.666068 -0.731998 +v 140.726822 -144.075653 43.199921 1.000000 1.000000 1.000000 +vn 0.036368 0.693977 -0.719078 +v 140.979156 -144.102173 43.199921 1.000000 1.000000 1.000000 +vn -0.197279 0.678927 -0.707206 +v 159.605148 161.301544 43.199959 1.000000 1.000000 1.000000 +vn 0.000000 0.631329 -0.775515 +v 159.003891 161.127121 43.199959 1.000000 1.000000 1.000000 +vn -0.334192 0.539743 -0.772653 +v 159.969513 161.407593 43.199959 1.000000 1.000000 1.000000 +vn -0.564336 0.303787 -0.767618 +v 160.676346 162.173615 43.199959 1.000000 1.000000 1.000000 +vn -0.643631 -0.000001 -0.765336 +v 160.935120 163.220123 43.199959 1.000000 1.000000 1.000000 +vn -0.564342 -0.303784 -0.767616 +v 160.676346 164.266617 43.199959 1.000000 1.000000 1.000000 +vn -0.333851 -0.539771 -0.772781 +v 159.969513 165.032669 43.199959 1.000000 1.000000 1.000000 +vn -0.197189 -0.679134 -0.707031 +v 159.603867 165.138702 43.199959 1.000000 1.000000 1.000000 +vn 0.000002 -0.631147 -0.775663 +v 159.003891 165.313126 43.199959 1.000000 1.000000 1.000000 +vn 0.197191 -0.679134 -0.707030 +v 158.403931 165.138702 43.199959 1.000000 1.000000 1.000000 +vn 0.333851 -0.539771 -0.772781 +v 158.038284 165.032669 43.199959 1.000000 1.000000 1.000000 +vn 0.564342 -0.303784 -0.767616 +v 157.331451 164.266617 43.199959 1.000000 1.000000 1.000000 +vn 0.643631 -0.000001 -0.765336 +v 157.072678 163.220123 43.199959 1.000000 1.000000 1.000000 +vn 0.564336 0.303787 -0.767618 +v 157.331451 162.173615 43.199959 1.000000 1.000000 1.000000 +vn 0.334196 0.539743 -0.772652 +v 158.038284 161.407593 43.199959 1.000000 1.000000 1.000000 +vn -0.072237 0.677725 -0.731759 +v 144.841614 161.475952 43.199959 1.000000 1.000000 1.000000 +vn -0.266340 0.597394 -0.756428 +v 145.333435 161.582001 43.199959 1.000000 1.000000 1.000000 +vn -0.481726 0.446911 -0.753798 +v 145.751862 161.884781 43.199959 1.000000 1.000000 1.000000 +vn -0.616511 0.236486 -0.750992 +v 146.029953 162.336884 43.199959 1.000000 1.000000 1.000000 +vn -0.682728 0.061991 -0.728038 +v 146.127808 162.871292 43.199959 1.000000 1.000000 1.000000 +vn -0.682729 -0.061990 -0.728038 +v 146.127808 163.568954 43.199959 1.000000 1.000000 1.000000 +vn -0.616503 -0.236492 -0.750996 +v 146.029953 164.103378 43.199959 1.000000 1.000000 1.000000 +vn -0.266346 -0.597388 -0.756431 +v 145.333435 164.858246 43.199959 1.000000 1.000000 1.000000 +vn -0.481730 -0.446917 -0.753791 +v 145.751862 164.555450 43.199959 1.000000 1.000000 1.000000 +vn -0.072237 -0.677724 -0.731759 +v 144.841614 164.964294 43.199959 1.000000 1.000000 1.000000 +vn 0.333951 -0.539761 -0.772745 +v -127.782486 165.032669 43.199997 1.000000 1.000000 1.000000 +vn 0.564342 -0.303784 -0.767616 +v -128.489319 164.266617 43.199997 1.000000 1.000000 1.000000 +vn 0.643631 -0.000001 -0.765336 +v -128.748093 163.220123 43.199997 1.000000 1.000000 1.000000 +vn 0.564336 0.303787 -0.767618 +v -128.489319 162.173615 43.199997 1.000000 1.000000 1.000000 +vn 0.334026 0.539760 -0.772713 +v -127.782486 161.407593 43.199997 1.000000 1.000000 1.000000 +vn 0.197241 0.679027 -0.707120 +v -127.417480 161.301544 43.199997 1.000000 1.000000 1.000000 +vn 0.000000 0.631238 -0.775590 +v -126.816872 161.127121 43.199997 1.000000 1.000000 1.000000 +vn -0.197242 0.679026 -0.707121 +v -126.216263 161.301544 43.199997 1.000000 1.000000 1.000000 +vn -0.000000 0.000000 -1.000000 +v -63.408436 161.301544 43.199997 1.000000 1.000000 1.000000 +vn -0.000000 0.000000 -1.000000 +v -63.408436 10.431076 43.199978 1.000000 1.000000 1.000000 +vn 0.197242 0.679025 -0.707121 +v -0.600616 161.301544 43.199978 1.000000 1.000000 1.000000 +vn 0.333946 -0.539768 -0.772743 +v -0.965610 165.032669 43.199978 1.000000 1.000000 1.000000 +vn 0.564336 -0.303775 -0.767624 +v -1.672476 164.266617 43.199978 1.000000 1.000000 1.000000 +vn 0.643642 -0.000001 -0.765327 +v -1.931208 163.220123 43.199978 1.000000 1.000000 1.000000 +vn -0.334028 0.539759 -0.772713 +v -125.851265 161.407593 43.199997 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 -1.000000 +v -63.408436 -144.276581 43.199959 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 -1.000000 +v -134.219894 -144.276581 43.199959 1.000000 1.000000 1.000000 +vn -0.000002 0.000000 -1.000000 +v -151.600876 -144.276581 43.199959 1.000000 1.000000 1.000000 +vn -0.197204 0.679128 -0.707033 +v -158.403931 -144.276581 43.199978 1.000000 1.000000 1.000000 +vn -0.000003 0.631148 -0.775662 +v -159.003891 -144.451004 43.199978 1.000000 1.000000 1.000000 +vn -0.333864 0.539777 -0.772772 +v -158.038284 -144.170532 43.199978 1.000000 1.000000 1.000000 +vn -0.564341 0.303787 -0.767615 +v -157.331451 -143.404495 43.199978 1.000000 1.000000 1.000000 +vn -0.643632 0.000001 -0.765335 +v -157.072678 -142.358002 43.199978 1.000000 1.000000 1.000000 +vn -0.564341 -0.303784 -0.767616 +v -157.331451 -141.311493 43.199978 1.000000 1.000000 1.000000 +vn -0.333998 -0.539760 -0.772726 +v -158.038284 -140.545456 43.199978 1.000000 1.000000 1.000000 +vn -0.000001 0.000000 -1.000000 +v -163.188217 10.431056 43.199997 1.000000 1.000000 1.000000 +vn -0.000001 -0.631228 -0.775598 +v -159.003891 -140.264999 43.199978 1.000000 1.000000 1.000000 +vn 0.333996 -0.539760 -0.772726 +v -159.969513 -140.545456 43.199978 1.000000 1.000000 1.000000 +vn 0.564339 -0.303785 -0.767617 +v -160.676346 -141.311493 43.199978 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 -1.000000 +v -163.188217 -144.276581 43.199978 1.000000 1.000000 1.000000 +vn 0.643631 0.000001 -0.765336 +v -160.935120 -142.358002 43.199978 1.000000 1.000000 1.000000 +vn 0.564339 0.303786 -0.767617 +v -160.676346 -143.404495 43.199978 1.000000 1.000000 1.000000 +vn 0.333863 0.539773 -0.772775 +v -159.969513 -144.170532 43.199978 1.000000 1.000000 1.000000 +vn 0.197200 0.679127 -0.707036 +v -159.603867 -144.276581 43.199978 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 -1.000000 +v -163.188217 161.301544 43.199997 1.000000 1.000000 1.000000 +vn 0.000000 0.000000 -1.000000 +v -163.188217 165.138702 43.199997 1.000000 1.000000 1.000000 +vn 0.197189 -0.679134 -0.707031 +v -159.603867 165.138702 43.199997 1.000000 1.000000 1.000000 +vn 0.333851 -0.539771 -0.772781 +v -159.969513 165.032669 43.199997 1.000000 1.000000 1.000000 +vn 0.564342 -0.303784 -0.767615 +v -160.676346 164.266617 43.199997 1.000000 1.000000 1.000000 +vn 0.564336 0.303787 -0.767618 +v -160.676346 162.173615 43.199997 1.000000 1.000000 1.000000 +vn 0.333861 0.539776 -0.772774 +v -159.969513 161.407593 43.199997 1.000000 1.000000 1.000000 +vn 0.197200 0.679126 -0.707036 +v -159.603867 161.301544 43.199997 1.000000 1.000000 1.000000 +vn 0.643631 -0.000001 -0.765336 +v -160.935120 163.220123 43.199997 1.000000 1.000000 1.000000 +vn -0.000002 0.631147 -0.775663 +v -159.003891 161.127121 43.199997 1.000000 1.000000 1.000000 +vn 0.502165 -0.466111 -0.728403 +v -145.751862 -141.022659 43.199959 1.000000 1.000000 1.000000 +vn -0.582116 -0.360470 -0.728836 +v -139.909271 -141.233368 43.199959 1.000000 1.000000 1.000000 +vn -0.501102 -0.464591 -0.730104 +v -140.068909 -141.022659 43.199959 1.000000 1.000000 1.000000 +vn 0.143637 -0.667395 -0.730720 +v -145.093948 -140.641739 43.199959 1.000000 1.000000 1.000000 +vn 0.277616 -0.622625 -0.731619 +v -145.334717 -140.719879 43.199959 1.000000 1.000000 1.000000 +vn 0.400830 -0.552325 -0.730939 +v -145.558731 -140.849640 43.199959 1.000000 1.000000 1.000000 +vn -0.400386 -0.554079 -0.729854 +v -140.264618 -140.849640 43.199959 1.000000 1.000000 1.000000 +vn -0.278269 -0.621980 -0.731921 +v -140.487335 -140.719879 43.199959 1.000000 1.000000 1.000000 +vn -0.143838 -0.667425 -0.730654 +v -140.728104 -140.641739 43.199959 1.000000 1.000000 1.000000 +vn -0.038409 -0.693145 -0.719775 +v -140.979156 -140.613831 43.199959 1.000000 1.000000 1.000000 +vn 0.038219 -0.693222 -0.719710 +v -144.841614 -140.613831 43.199959 1.000000 1.000000 1.000000 +vn -0.639187 -0.245451 -0.728830 +v -139.789520 -141.474747 43.199959 1.000000 1.000000 1.000000 +vn -0.673772 -0.121816 -0.728830 +v -139.716141 -141.737076 43.199959 1.000000 1.000000 1.000000 +vn -0.696656 -0.029618 -0.716794 +v -139.692963 -142.009171 43.199959 1.000000 1.000000 1.000000 +vn -0.696656 0.029618 -0.716794 +v -139.692963 -142.706833 43.199959 1.000000 1.000000 1.000000 +vn -0.673769 0.121821 -0.728831 +v -139.716141 -142.978928 43.199959 1.000000 1.000000 1.000000 +vn -0.638639 0.246080 -0.729099 +v -139.789520 -143.241241 43.199959 1.000000 1.000000 1.000000 +vn -0.581940 0.361291 -0.728570 +v -139.909271 -143.481247 43.199959 1.000000 1.000000 1.000000 +vn -0.503683 0.463290 -0.729154 +v -140.068909 -143.691940 43.199959 1.000000 1.000000 1.000000 +vn -0.400333 0.552123 -0.731364 +v -140.264618 -143.867752 43.199959 1.000000 1.000000 1.000000 +vn -0.278961 0.623070 -0.730729 +v -140.487335 -143.996109 43.199959 1.000000 1.000000 1.000000 +vn -0.143482 0.666096 -0.731935 +v -140.728104 -144.075653 43.199959 1.000000 1.000000 1.000000 +vn -0.036548 0.693904 -0.719140 +v -140.979156 -144.102173 43.199959 1.000000 1.000000 1.000000 +vn 0.580203 -0.360655 -0.730269 +v -145.914078 -141.233368 43.199959 1.000000 1.000000 1.000000 +vn 0.640242 -0.242608 -0.728856 +v -146.032532 -141.474747 43.199959 1.000000 1.000000 1.000000 +vn 0.675195 -0.123751 -0.727184 +v -146.104630 -141.737076 43.199959 1.000000 1.000000 1.000000 +vn 0.695399 -0.032821 -0.717874 +v -146.130371 -142.009171 43.199959 1.000000 1.000000 1.000000 +vn 0.695399 0.032821 -0.717874 +v -146.130371 -142.706833 43.199959 1.000000 1.000000 1.000000 +vn 0.675193 0.123755 -0.727186 +v -146.104630 -142.978928 43.199959 1.000000 1.000000 1.000000 +vn 0.639701 0.243235 -0.729123 +v -146.032532 -143.241241 43.199959 1.000000 1.000000 1.000000 +vn 0.580029 0.361470 -0.730004 +v -145.914078 -143.481247 43.199959 1.000000 1.000000 1.000000 +vn 0.504749 0.464798 -0.727455 +v -145.751862 -143.691940 43.199959 1.000000 1.000000 1.000000 +vn 0.400773 0.550358 -0.732452 +v -145.558731 -143.867752 43.199959 1.000000 1.000000 1.000000 +vn 0.278310 0.623711 -0.730430 +v -145.334717 -143.996109 43.199959 1.000000 1.000000 1.000000 +vn 0.143291 0.666068 -0.731998 +v -145.093948 -144.075653 43.199959 1.000000 1.000000 1.000000 +vn 0.036368 0.693977 -0.719078 +v -144.841614 -144.102173 43.199959 1.000000 1.000000 1.000000 +vn -0.564336 0.303789 -0.767618 +v -125.144432 162.173615 43.199997 1.000000 1.000000 1.000000 +vn -0.643629 -0.000001 -0.765338 +v -124.885651 163.220123 43.199997 1.000000 1.000000 1.000000 +vn -0.564342 -0.303786 -0.767615 +v -125.144432 164.266617 43.199997 1.000000 1.000000 1.000000 +vn -0.333951 -0.539761 -0.772745 +v -125.851265 165.032669 43.199997 1.000000 1.000000 1.000000 +vn 0.197214 -0.679074 -0.707082 +v -0.600348 165.138702 43.199978 1.000000 1.000000 1.000000 +vn -0.266340 0.597394 -0.756428 +v -140.487335 161.582001 43.199997 1.000000 1.000000 1.000000 +vn -0.481726 0.446911 -0.753798 +v -140.068909 161.884781 43.199997 1.000000 1.000000 1.000000 +vn -0.072237 0.677725 -0.731759 +v -140.979156 161.475952 43.199997 1.000000 1.000000 1.000000 +vn -0.616511 0.236486 -0.750992 +v -139.790817 162.336884 43.199997 1.000000 1.000000 1.000000 +vn -0.682728 0.061991 -0.728038 +v -139.692963 162.871292 43.199997 1.000000 1.000000 1.000000 +vn -0.672995 -0.081389 -0.735155 +v -139.692963 163.568954 43.199997 1.000000 1.000000 1.000000 +vn -0.564380 -0.303172 -0.767830 +v -139.864212 164.266617 43.199997 1.000000 1.000000 1.000000 +vn -0.334002 -0.539749 -0.772731 +v -140.335419 164.777328 43.199997 1.000000 1.000000 1.000000 +vn -0.094708 -0.665651 -0.740229 +v -140.979156 164.964294 43.199997 1.000000 1.000000 1.000000 +vn -0.564328 0.303776 -0.767629 +v 1.672502 162.173615 43.199978 1.000000 1.000000 1.000000 +vn 0.000002 0.631240 -0.775588 +v 0.000000 161.127121 43.199978 1.000000 1.000000 1.000000 +vn 0.564330 0.303778 -0.767626 +v -1.672476 162.173615 43.199978 1.000000 1.000000 1.000000 +vn 0.334025 0.539766 -0.772710 +v -0.965610 161.407593 43.199978 1.000000 1.000000 1.000000 +vn 0.693900 -0.626816 -0.354408 +v 157.119034 -121.045662 11.835998 1.000000 1.000000 1.000000 +vn 0.600489 0.687975 -0.407557 +v 130.520950 231.797989 11.835998 1.000000 1.000000 1.000000 +vn 0.687634 0.703576 -0.179280 +v 131.863800 231.797989 15.085000 1.000000 1.000000 1.000000 +vn 0.765571 -0.616716 -0.183202 +v 158.454147 -120.927055 15.084796 1.000000 1.000000 1.000000 +vn 0.610895 -0.617489 -0.495495 +v 156.636230 -121.088905 11.163398 1.000000 1.000000 1.000000 +vn 0.366245 0.668053 -0.647742 +v 128.421967 231.797989 9.756198 1.000000 1.000000 1.000000 +vn 0.691829 0.720960 -0.039867 +v 132.223007 231.797989 18.199997 1.000000 1.000000 1.000000 +vn 0.772639 -0.633522 -0.040973 +v 158.810776 -120.896355 18.199997 1.000000 1.000000 1.000000 +vn 0.553263 0.596541 0.581411 +v 132.223007 231.797989 35.299999 1.000000 1.000000 1.000000 +vn 0.677341 -0.083755 0.730886 +v 157.971329 -109.769966 35.299999 1.000000 1.000000 1.000000 +vn 0.743710 -0.665166 0.066706 +v 158.810776 -120.896355 19.299999 1.000000 1.000000 1.000000 +vn 0.682952 -0.417376 0.599478 +v 158.391052 -115.333160 33.156399 1.000000 1.000000 1.000000 +vn 0.717009 -0.634643 0.288315 +v 158.698761 -119.404747 27.299999 1.000000 1.000000 1.000000 +vn 0.542170 -0.653685 -0.527966 +v 155.012711 -121.365196 9.851200 1.000000 1.000000 1.000000 +vn 0.093822 0.681533 -0.725749 +v 126.410027 231.797989 9.199996 1.000000 1.000000 1.000000 +vn 0.440065 -0.601422 -0.666809 +v 154.638046 -121.429375 9.547398 1.000000 1.000000 1.000000 +vn 0.348181 -0.549715 -0.759331 +v 153.067322 -121.813103 9.199996 1.000000 1.000000 1.000000 +vn -0.631352 -0.774447 0.040322 +v 154.961212 -121.236824 18.199997 1.000000 1.000000 1.000000 +vn -0.719085 0.693685 0.041436 +v 128.347687 231.797989 18.199997 1.000000 1.000000 1.000000 +vn -0.676833 0.714661 0.176511 +v 128.227951 231.797989 17.161598 1.000000 1.000000 1.000000 +vn -0.588693 -0.790272 0.170030 +v 154.841476 -121.247993 17.161598 1.000000 1.000000 1.000000 +vn -0.625556 -0.777262 0.067400 +v 154.961212 -121.236824 19.299999 1.000000 1.000000 1.000000 +vn -0.600644 0.557071 0.573497 +v 128.347687 231.797989 35.299999 1.000000 1.000000 1.000000 +vn -0.655187 -0.186768 0.732016 +v 154.121765 -110.111824 35.299999 1.000000 1.000000 1.000000 +vn -0.606304 -0.520042 0.601625 +v 154.541489 -115.673622 33.156399 1.000000 1.000000 1.000000 +vn -0.603884 -0.742237 0.290530 +v 154.849197 -119.746605 27.299999 1.000000 1.000000 1.000000 +vn -0.562084 0.733825 0.381526 +v 127.780167 231.797989 16.078598 1.000000 1.000000 1.000000 +vn -0.530160 -0.780255 0.331862 +v 154.397293 -121.287056 16.078598 1.000000 1.000000 1.000000 +vn -0.321728 0.756931 0.568811 +v 127.080681 231.797989 15.385398 1.000000 1.000000 1.000000 +vn -0.260098 -0.749874 0.608308 +v 153.704636 -121.478203 15.408798 1.000000 1.000000 1.000000 +vn -0.403077 -0.763706 0.504264 +v 154.236359 -121.301003 15.854396 1.000000 1.000000 1.000000 +vn -0.086815 0.735410 0.672039 +v 126.410027 231.797989 15.199996 1.000000 1.000000 1.000000 +vn 0.342196 -0.612538 0.712530 +v 153.067322 -121.813103 15.199996 1.000000 1.000000 1.000000 +vn -0.010650 -0.743077 0.669122 +v 153.611923 -121.508904 15.331996 1.000000 1.000000 1.000000 +vn 0.495698 -0.433386 -0.752635 +v 151.761810 -122.827507 9.199996 1.000000 1.000000 1.000000 +vn 0.495698 -0.433386 0.752635 +v 151.761810 -122.827507 15.199996 1.000000 1.000000 1.000000 +vn 0.620279 -0.199057 -0.758703 +v 150.511673 -124.977715 9.199996 1.000000 1.000000 1.000000 +vn 0.620278 -0.199057 0.758704 +v 150.511673 -124.977715 15.199996 1.000000 1.000000 1.000000 +vn 0.647930 0.076881 -0.757810 +v 150.272202 -127.506050 9.199996 1.000000 1.000000 1.000000 +vn 0.647930 0.076881 0.757810 +v 150.272202 -127.506050 15.199996 1.000000 1.000000 1.000000 +vn 0.552632 0.341299 -0.760337 +v 151.089752 -129.887894 9.199996 1.000000 1.000000 1.000000 +vn 0.552632 0.341299 0.760337 +v 151.089752 -129.887894 15.199996 1.000000 1.000000 1.000000 +vn 0.086842 0.735407 0.672038 +v -126.410027 231.796585 15.199996 1.000000 1.000000 1.000000 +vn -0.093793 0.681549 -0.725736 +v -126.410027 231.796585 9.199996 1.000000 1.000000 1.000000 +vn 0.321712 0.756926 0.568828 +v -127.080681 231.796585 15.385398 1.000000 1.000000 1.000000 +vn -0.366299 0.668048 -0.647717 +v -128.421967 231.796585 9.756198 1.000000 1.000000 1.000000 +vn 0.562114 0.733798 0.381533 +v -127.780167 231.796585 16.078598 1.000000 1.000000 1.000000 +vn -0.600488 0.687943 -0.407614 +v -130.520950 231.796585 11.835998 1.000000 1.000000 1.000000 +vn 0.676837 0.714658 0.176509 +v -128.227951 231.796585 17.161598 1.000000 1.000000 1.000000 +vn -0.687632 0.703578 -0.179279 +v -131.863800 231.796585 15.085000 1.000000 1.000000 1.000000 +vn 0.719087 0.693683 0.041436 +v -128.347687 231.796585 18.199997 1.000000 1.000000 1.000000 +vn -0.691826 0.720963 -0.039867 +v -132.223007 231.796585 18.199997 1.000000 1.000000 1.000000 +vn 0.600645 0.557070 0.573496 +v -128.347687 231.796585 35.299999 1.000000 1.000000 1.000000 +vn -0.553264 0.596541 0.581410 +v -132.223007 231.796585 35.299999 1.000000 1.000000 1.000000 +vn 0.004940 -0.722172 0.691696 +v -153.611923 -121.508904 15.332200 1.000000 1.000000 1.000000 +vn -0.365424 -0.662299 -0.654084 +v -155.035873 -121.361000 9.819798 1.000000 1.000000 1.000000 +vn -0.310082 -0.612032 0.727506 +v -153.067322 -121.813103 15.199996 1.000000 1.000000 1.000000 +vn 0.275921 -0.740888 0.612333 +v -153.704636 -121.478203 15.408798 1.000000 1.000000 1.000000 +vn -0.480635 -0.600574 -0.638985 +v -155.262482 -121.309380 9.890998 1.000000 1.000000 1.000000 +vn -0.363049 -0.532301 -0.764756 +v -153.067322 -121.813103 9.199996 1.000000 1.000000 1.000000 +vn -0.495698 -0.433386 0.752635 +v -151.761810 -122.827507 15.199996 1.000000 1.000000 1.000000 +vn -0.495698 -0.433386 -0.752635 +v -151.761810 -122.827507 9.199996 1.000000 1.000000 1.000000 +vn -0.620279 -0.199057 0.758703 +v -150.511673 -124.977715 15.199996 1.000000 1.000000 1.000000 +vn -0.620279 -0.199057 -0.758703 +v -150.511673 -124.977715 9.199996 1.000000 1.000000 1.000000 +vn -0.647930 0.076881 0.757810 +v -150.272202 -127.506050 15.199996 1.000000 1.000000 1.000000 +vn -0.647931 0.076881 -0.757809 +v -150.272202 -127.506050 9.199996 1.000000 1.000000 1.000000 +vn -0.552631 0.341299 0.760338 +v -151.089752 -129.887894 15.199996 1.000000 1.000000 1.000000 +vn -0.552631 0.341299 -0.760338 +v -151.089752 -129.887894 9.199996 1.000000 1.000000 1.000000 +vn -0.624597 -0.620700 -0.473930 +v -156.636230 -121.088905 11.163398 1.000000 1.000000 1.000000 +vn 0.399881 -0.758842 0.514056 +v -154.236359 -121.301003 15.854396 1.000000 1.000000 1.000000 +vn -0.693850 -0.627102 -0.353999 +v -157.119034 -121.045662 11.835998 1.000000 1.000000 1.000000 +vn 0.529942 -0.780397 0.331877 +v -154.397293 -121.287056 16.078598 1.000000 1.000000 1.000000 +vn -0.765556 -0.616721 -0.183246 +v -158.454147 -120.927055 15.085000 1.000000 1.000000 1.000000 +vn 0.588852 -0.790195 0.169839 +v -154.841476 -121.247993 17.161598 1.000000 1.000000 1.000000 +vn -0.772664 -0.633493 -0.040942 +v -158.810776 -120.896355 18.199997 1.000000 1.000000 1.000000 +vn 0.631430 -0.774377 0.040468 +v -154.961212 -121.236824 18.199997 1.000000 1.000000 1.000000 +vn 0.625574 -0.777251 0.067358 +v -154.961212 -121.236824 19.299999 1.000000 1.000000 1.000000 +vn -0.743709 -0.665170 0.066673 +v -158.810776 -120.896355 19.299999 1.000000 1.000000 1.000000 +vn 0.603938 -0.742164 0.290604 +v -154.849197 -119.746605 27.299999 1.000000 1.000000 1.000000 +vn -0.717067 -0.634545 0.288387 +v -158.698761 -119.404747 27.299999 1.000000 1.000000 1.000000 +vn 0.606327 -0.520088 0.601561 +v -154.541489 -115.673622 33.156399 1.000000 1.000000 1.000000 +vn -0.682995 -0.417412 0.599404 +v -158.391052 -115.333160 33.156399 1.000000 1.000000 1.000000 +vn 0.655198 -0.186750 0.732011 +v -154.121765 -110.111824 35.299999 1.000000 1.000000 1.000000 +vn -0.677349 -0.083738 0.730880 +v -157.971329 -109.769966 35.299999 1.000000 1.000000 1.000000 +vn 0.725227 0.076461 0.684251 +v 168.660004 -142.358002 15.199996 1.000000 1.000000 1.000000 +vn 0.682513 0.310106 0.661824 +v 167.680237 -137.763168 15.199996 1.000000 1.000000 1.000000 +vn 0.482727 0.576790 0.659006 +v 164.937881 -134.101807 15.199996 1.000000 1.000000 1.000000 +vn 0.166167 0.735681 0.656629 +v 160.990479 -132.117645 15.199996 1.000000 1.000000 1.000000 +vn -0.042827 0.714263 0.698566 +v 156.640091 -132.211121 15.199996 1.000000 1.000000 1.000000 +vn 0.750539 0.120483 0.649750 +v 168.660004 -149.334671 15.199996 1.000000 1.000000 1.000000 +vn 0.071830 0.649717 0.756775 +v 155.041031 -132.368805 15.199996 1.000000 1.000000 1.000000 +vn -0.750540 0.120484 0.649748 +v -168.660004 -149.334671 15.199996 1.000000 1.000000 1.000000 +vn -0.340765 0.547509 0.764273 +v -152.798233 -131.629272 15.199996 1.000000 1.000000 1.000000 +vn 0.340765 0.547509 0.764273 +v 152.798233 -131.629272 15.199996 1.000000 1.000000 1.000000 +vn -0.482726 0.576790 0.659006 +v -164.937881 -134.101807 15.199996 1.000000 1.000000 1.000000 +vn -0.682513 0.310106 0.661824 +v -167.680237 -137.763168 15.199996 1.000000 1.000000 1.000000 +vn -0.166167 0.735681 0.656629 +v -160.990479 -132.117645 15.199996 1.000000 1.000000 1.000000 +vn -0.725227 0.076461 0.684251 +v -168.660004 -142.358002 15.199996 1.000000 1.000000 1.000000 +vn 0.042827 0.714263 0.698566 +v -156.640091 -132.211121 15.199996 1.000000 1.000000 1.000000 +vn -0.071830 0.649717 0.756775 +v -155.041031 -132.368805 15.199996 1.000000 1.000000 1.000000 +vn 0.340765 0.547509 -0.764273 +v 152.798233 -131.629272 9.199996 1.000000 1.000000 1.000000 +vn 0.071830 0.649717 -0.756775 +v 155.041031 -132.368805 9.199996 1.000000 1.000000 1.000000 +vn -0.042827 0.714263 -0.698566 +v 156.640091 -132.211121 9.199996 1.000000 1.000000 1.000000 +vn 0.166167 0.735681 -0.656629 +v 160.990479 -132.117645 9.199996 1.000000 1.000000 1.000000 +vn 0.482726 0.576790 -0.659006 +v 164.937881 -134.101807 9.199996 1.000000 1.000000 1.000000 +vn 0.682513 0.310106 -0.661824 +v 167.680237 -137.763168 9.199996 1.000000 1.000000 1.000000 +vn -0.668282 -0.135628 -0.731440 +v -168.660004 -149.334671 9.199996 1.000000 1.000000 1.000000 +vn 0.668281 -0.135628 -0.731441 +v 168.660004 -149.334671 9.199996 1.000000 1.000000 1.000000 +vn -0.340765 0.547509 -0.764273 +v -152.798233 -131.629272 9.199996 1.000000 1.000000 1.000000 +vn 0.725227 0.076461 -0.684251 +v 168.660004 -142.358002 9.199996 1.000000 1.000000 1.000000 +vn -0.725227 0.076461 -0.684251 +v -168.660004 -142.358002 9.199996 1.000000 1.000000 1.000000 +vn -0.682513 0.310106 -0.661824 +v -167.680237 -137.763168 9.199996 1.000000 1.000000 1.000000 +vn -0.482727 0.576790 -0.659006 +v -164.937881 -134.101807 9.199996 1.000000 1.000000 1.000000 +vn -0.166167 0.735681 -0.656629 +v -160.990479 -132.117645 9.199996 1.000000 1.000000 1.000000 +vn 0.042827 0.714263 -0.698566 +v -156.640091 -132.211121 9.199996 1.000000 1.000000 1.000000 +vn -0.071830 0.649717 -0.756775 +v -155.041031 -132.368805 9.199996 1.000000 1.000000 1.000000 +vn 0.728481 0.682143 0.063224 +v 168.660004 -154.916000 23.199997 1.000000 1.000000 1.000000 +vn 0.722688 0.688399 0.061881 +v 168.660004 -154.916000 23.260597 1.000000 1.000000 1.000000 +vn 0.686933 -0.723626 -0.066999 +v 168.660004 -159.102005 23.199997 1.000000 1.000000 1.000000 +vn 0.757712 0.601838 0.252316 +v 168.660004 -154.168106 19.199997 1.000000 1.000000 1.000000 +vn 0.722688 -0.688399 0.061881 +v 168.660004 -159.102005 23.260597 1.000000 1.000000 1.000000 +vn 0.696013 0.664897 0.271070 +v 167.624863 -154.916000 29.260799 1.000000 1.000000 1.000000 +vn 0.662608 -0.690723 -0.289574 +v 168.660004 -157.794571 16.199997 1.000000 1.000000 1.000000 +vn 0.779407 0.386196 0.493334 +v 168.660004 -152.125336 16.271797 1.000000 1.000000 1.000000 +vn 0.646713 -0.470105 -0.600636 +v 168.660004 -154.218338 11.075600 1.000000 1.000000 1.000000 +vn 0.696013 -0.664897 0.271070 +v 167.624863 -159.102005 29.260799 1.000000 1.000000 1.000000 +vn 0.489880 0.645850 0.585573 +v 164.797562 -154.916000 33.653000 1.000000 1.000000 1.000000 +vn 0.489880 -0.645850 0.585573 +v 164.797562 -159.102005 33.653000 1.000000 1.000000 1.000000 +vn 0.146248 0.665541 0.731893 +v 160.935120 -154.916000 35.260799 1.000000 1.000000 1.000000 +vn 0.146248 -0.665540 0.731893 +v 160.935120 -159.102005 35.260799 1.000000 1.000000 1.000000 +vn 0.107547 0.745279 0.658022 +v 113.942062 -154.916000 35.260799 1.000000 1.000000 1.000000 +vn 0.107547 -0.745279 0.658022 +v 113.942062 -159.102005 35.260799 1.000000 1.000000 1.000000 +vn 0.268001 -0.724436 0.635113 +v 111.814507 -159.102005 35.975338 1.000000 1.000000 1.000000 +vn 0.268001 0.724436 0.635113 +v 111.814507 -154.916000 35.975338 1.000000 1.000000 1.000000 +vn 0.232086 0.673947 0.701379 +v 101.219696 -154.916000 41.418537 1.000000 1.000000 1.000000 +vn 0.232086 -0.673946 0.701379 +v 101.219696 -159.102005 41.418537 1.000000 1.000000 1.000000 +vn 0.059547 0.689072 0.722242 +v 90.123665 -154.916000 43.260738 1.000000 1.000000 1.000000 +vn 0.059547 -0.689072 0.722243 +v 90.123665 -159.102005 43.260738 1.000000 1.000000 1.000000 +vn -0.686933 -0.723626 -0.066999 +v -168.660004 -159.102005 23.199997 1.000000 1.000000 1.000000 +vn -0.722688 -0.688398 0.061883 +v -168.660004 -159.102005 23.260799 1.000000 1.000000 1.000000 +vn -0.728482 0.682142 0.063224 +v -168.660004 -154.916000 23.199997 1.000000 1.000000 1.000000 +vn -0.662607 -0.690723 -0.289574 +v -168.660004 -157.794571 16.199997 1.000000 1.000000 1.000000 +vn -0.722688 0.688399 0.061883 +v -168.660004 -154.916000 23.260799 1.000000 1.000000 1.000000 +vn -0.696011 -0.664897 0.271072 +v -167.624863 -159.102005 29.260799 1.000000 1.000000 1.000000 +vn -0.757711 0.601840 0.252316 +v -168.660004 -154.168106 19.199997 1.000000 1.000000 1.000000 +vn -0.646714 -0.470104 -0.600636 +v -168.660004 -154.218338 11.075600 1.000000 1.000000 1.000000 +vn -0.779407 0.386195 0.493333 +v -168.660004 -152.125336 16.271797 1.000000 1.000000 1.000000 +vn -0.696011 0.664897 0.271072 +v -167.624863 -154.916000 29.260799 1.000000 1.000000 1.000000 +vn -0.489880 -0.645850 0.585573 +v -164.797562 -159.102005 33.653000 1.000000 1.000000 1.000000 +vn -0.489880 0.645850 0.585573 +v -164.797562 -154.916000 33.653000 1.000000 1.000000 1.000000 +vn -0.146248 -0.665539 0.731894 +v -160.935120 -159.102005 35.260799 1.000000 1.000000 1.000000 +vn -0.146248 0.665539 0.731894 +v -160.935120 -154.916000 35.260799 1.000000 1.000000 1.000000 +vn -0.107549 0.745280 0.658021 +v -113.942062 -154.916000 35.260799 1.000000 1.000000 1.000000 +vn -0.107549 -0.745280 0.658021 +v -113.942062 -159.102005 35.260799 1.000000 1.000000 1.000000 +vn -0.268004 0.724435 0.635112 +v -111.814507 -154.916000 35.975357 1.000000 1.000000 1.000000 +vn -0.268004 -0.724435 0.635113 +v -111.814507 -159.102005 35.975357 1.000000 1.000000 1.000000 +vn -0.232086 -0.673947 0.701379 +v -101.219696 -159.102005 41.418556 1.000000 1.000000 1.000000 +vn -0.232086 0.673946 0.701379 +v -101.219696 -154.916000 41.418556 1.000000 1.000000 1.000000 +vn -0.059547 -0.689072 0.722242 +v -90.123665 -159.102005 43.260757 1.000000 1.000000 1.000000 +vn -0.059547 0.689072 0.722243 +v -90.123665 -154.916000 43.260757 1.000000 1.000000 1.000000 +# 10222 vertices, 0 vertices normals + + +usemtl material_0 +vt 0.000000 1.000000 +f 1/1/1 2/1/2 3/1/3 +f 3/1/3 59/1/59 1/1/1 +f 1/1/1 59/1/59 4/1/4 +f 4/1/4 59/1/59 57/1/57 +f 4/1/4 57/1/57 8/1/8 +f 7/1/7 4/1/4 8/1/8 +f 8/1/8 55/1/55 7/1/7 +f 55/1/55 12/1/12 7/1/7 +f 12/1/12 5/1/5 7/1/7 +f 5/1/5 2/1/2 7/1/7 +f 5/1/5 6/1/6 2/1/2 +vt 1.000000 0.799992 +vt 0.002138 1.799990 +vt 0.000000 0.799992 +f 6/2/6 37/3/37 2/4/2 +vt 0.997862 1.799990 +f 35/5/35 37/3/37 6/2/6 +f 49/1/49 35/1/35 6/1/6 +f 6/1/6 48/1/48 49/1/49 +f 48/1/48 40/1/40 49/1/49 +f 11/1/11 40/1/40 48/1/48 +f 11/1/11 42/1/42 40/1/40 +f 41/1/41 40/1/40 42/1/42 +f 41/1/41 42/1/42 22/1/22 +f 21/1/21 41/1/41 22/1/22 +f 13/1/13 21/1/21 22/1/22 +f 13/1/13 22/1/22 15/1/15 +f 15/1/15 9/1/9 13/1/13 +f 5/1/5 13/1/13 9/1/9 +f 14/1/14 9/1/9 15/1/15 +f 15/1/15 42/1/42 14/1/14 +f 14/1/14 42/1/42 10/1/10 +f 6/1/6 14/1/14 10/1/10 +f 10/1/10 11/1/11 6/1/6 +f 9/1/9 14/1/14 6/1/6 +f 18/1/18 21/1/21 13/1/13 +f 13/1/13 23/1/23 18/1/18 +f 18/1/18 23/1/23 24/1/24 +f 18/1/18 24/1/24 16/1/16 +f 16/1/16 17/1/17 18/1/18 +f 45/1/45 17/1/17 16/1/16 +f 45/1/45 16/1/16 46/1/46 +f 39/1/39 45/1/45 46/1/46 +f 39/1/39 46/1/46 43/1/43 +f 43/1/43 44/1/44 39/1/39 +f 39/1/39 44/1/44 28/1/28 +f 28/1/28 29/1/29 39/1/39 +f 29/1/29 32/1/32 39/1/39 +f 39/1/39 32/1/32 38/1/38 +f 39/1/39 38/1/38 20/1/20 +f 20/1/20 38/1/38 41/1/41 +f 32/1/32 34/1/34 38/1/38 +f 34/1/34 35/1/35 38/1/38 +f 38/1/38 35/1/35 40/1/40 +f 34/1/34 33/1/33 35/1/35 +f 35/1/35 33/1/33 36/1/36 +f 33/1/33 58/1/58 36/1/36 +f 58/1/58 59/1/59 36/1/36 +f 36/1/36 59/1/59 37/1/37 +f 60/1/60 58/1/58 33/1/33 +f 33/1/33 31/1/31 60/1/60 +f 60/1/60 31/1/31 26/1/26 +f 26/1/26 64/1/64 60/1/60 +f 60/1/60 64/1/64 63/1/63 +f 60/1/60 63/1/63 61/1/61 +f 60/1/60 61/1/61 54/1/54 +f 54/1/54 56/1/56 60/1/60 +f 54/1/54 52/1/52 56/1/56 +f 52/1/52 55/1/55 56/1/56 +f 56/1/56 55/1/55 57/1/57 +f 56/1/56 57/1/57 58/1/58 +f 51/1/51 52/1/52 54/1/54 +f 53/1/53 51/1/51 54/1/54 +f 54/1/54 62/1/62 53/1/53 +f 53/1/53 62/1/62 50/1/50 +f 50/1/50 62/1/62 16/1/16 +f 25/1/25 16/1/16 62/1/62 +f 25/1/25 62/1/62 63/1/63 +f 25/1/25 63/1/63 30/1/30 +f 25/1/25 30/1/30 26/1/26 +f 25/1/25 26/1/26 27/1/27 +f 27/1/27 26/1/26 28/1/28 +f 28/1/28 47/1/47 27/1/27 +f 47/1/47 44/1/44 27/1/27 +f 27/1/27 44/1/44 16/1/16 +f 27/1/27 16/1/16 25/1/25 +f 50/1/50 51/1/51 53/1/53 +f 50/1/50 24/1/24 51/1/51 +f 51/1/51 23/1/23 52/1/52 +f 52/1/52 23/1/23 12/1/12 +f 54/1/54 61/1/61 62/1/62 +f 63/1/63 62/1/62 61/1/61 +f 30/1/30 63/1/63 64/1/64 +f 26/1/26 30/1/30 64/1/64 +f 29/1/29 26/1/26 31/1/31 +f 32/1/32 31/1/31 33/1/33 +f 60/1/60 56/1/56 58/1/58 +f 32/1/32 33/1/33 34/1/34 +f 29/1/29 31/1/31 32/1/32 +f 28/1/28 26/1/26 29/1/29 +f 28/1/28 44/1/44 47/1/47 +f 16/1/16 44/1/44 43/1/43 +f 20/1/20 45/1/45 39/1/39 +f 20/1/20 19/1/19 45/1/45 +f 17/1/17 19/1/19 20/1/20 +f 20/1/20 21/1/21 17/1/17 +f 46/1/46 16/1/16 43/1/43 +f 19/1/19 17/1/17 45/1/45 +f 50/1/50 16/1/16 24/1/24 +f 51/1/51 24/1/24 23/1/23 +f 13/1/13 12/1/12 23/1/23 +f 18/1/18 17/1/17 21/1/21 +f 20/1/20 41/1/41 21/1/21 +f 22/1/22 42/1/42 15/1/15 +f 38/1/38 40/1/40 41/1/41 +f 10/1/10 42/1/42 11/1/11 +f 6/1/6 11/1/11 48/1/48 +f 49/1/49 40/1/40 35/1/35 +f 35/1/35 36/1/36 37/1/37 +f 9/1/9 6/1/6 5/1/5 +f 12/1/12 13/1/13 5/1/5 +f 52/1/52 12/1/12 55/1/55 +f 7/1/7 2/1/2 4/1/4 +f 8/1/8 57/1/57 55/1/55 +f 58/1/58 57/1/57 59/1/59 +f 3/1/3 37/1/37 59/1/59 +f 2/1/2 37/1/37 3/1/3 +f 4/1/4 2/1/2 1/1/1 +f 65/1/65 66/1/66 67/1/67 +f 70/1/70 65/1/65 67/1/67 +f 70/1/70 67/1/67 75/1/75 +f 70/1/70 75/1/75 434/1/434 +f 2287/1/2287 70/1/70 434/1/434 +f 2287/1/2287 434/1/434 2303/1/2303 +f 2288/1/2288 2287/1/2287 2303/1/2303 +f 2288/1/2288 2303/1/2303 2304/1/2304 +f 2300/1/2300 2288/1/2288 2304/1/2304 +f 2300/1/2300 2304/1/2304 2480/1/2480 +f 2480/1/2480 2502/1/2502 2300/1/2300 +f 2300/1/2300 2502/1/2502 2302/1/2302 +f 2300/1/2300 2302/1/2302 2299/1/2299 +f 2300/1/2300 2299/1/2299 2301/1/2301 +f 2301/1/2301 2299/1/2299 2291/1/2291 +f 2291/1/2291 2288/1/2288 2301/1/2301 +f 2291/1/2291 2286/1/2286 2288/1/2288 +f 2290/1/2290 2286/1/2286 2291/1/2291 +f 2291/1/2291 2298/1/2298 2290/1/2290 +f 2298/1/2298 2292/1/2292 2290/1/2290 +f 2290/1/2290 2292/1/2292 2289/1/2289 +f 2289/1/2289 2292/1/2292 2293/1/2293 +f 2289/1/2289 2293/1/2293 2283/1/2283 +f 2289/1/2289 2283/1/2283 2282/1/2282 +f 2282/1/2282 2281/1/2281 2289/1/2289 +f 2289/1/2289 2281/1/2281 2286/1/2286 +f 2281/1/2281 2285/1/2285 2286/1/2286 +f 2286/1/2286 2285/1/2285 2287/1/2287 +f 2281/1/2281 2284/1/2284 2285/1/2285 +f 2284/1/2284 70/1/70 2285/1/2285 +f 2284/1/2284 68/1/68 70/1/70 +f 2280/1/2280 68/1/68 2284/1/2284 +f 2263/1/2263 2280/1/2280 2284/1/2284 +f 2262/1/2262 2280/1/2280 2263/1/2263 +f 2259/1/2259 2262/1/2262 2263/1/2263 +f 2259/1/2259 2263/1/2263 2261/1/2261 +f 2261/1/2261 2258/1/2258 2259/1/2259 +f 2258/1/2258 2253/1/2253 2259/1/2259 +f 2259/1/2259 2253/1/2253 2260/1/2260 +f 2260/1/2260 2253/1/2253 2247/1/2247 +f 2260/1/2260 2247/1/2247 2264/1/2264 +f 2264/1/2264 2262/1/2262 2260/1/2260 +f 2265/1/2265 2262/1/2262 2264/1/2264 +f 2265/1/2265 2266/1/2266 2262/1/2262 +f 2266/1/2266 115/1/115 2262/1/2262 +f 2266/1/2266 114/1/114 115/1/115 +f 114/1/114 111/1/111 115/1/115 +f 115/1/115 111/1/111 110/1/110 +f 115/1/115 110/1/110 2280/1/2280 +f 111/1/111 108/1/108 110/1/110 +f 110/1/110 108/1/108 69/1/69 +f 110/1/110 69/1/69 68/1/68 +f 68/1/68 69/1/69 65/1/65 +f 69/1/69 71/1/71 65/1/65 +f 65/1/65 71/1/71 72/1/72 +f 71/1/71 97/1/97 72/1/72 +f 72/1/72 97/1/97 92/1/92 +f 72/1/72 92/1/92 66/1/66 +f 66/1/66 92/1/92 76/1/76 +f 66/1/66 76/1/76 73/1/73 +f 73/1/73 76/1/76 77/1/77 +f 73/1/73 77/1/77 74/1/74 +f 67/1/67 73/1/73 74/1/74 +f 74/1/74 77/1/77 79/1/79 +f 74/1/74 79/1/79 78/1/78 +f 75/1/75 74/1/74 78/1/78 +f 75/1/75 78/1/78 84/1/84 +f 75/1/75 84/1/84 433/1/433 +f 435/1/435 75/1/75 433/1/433 +f 435/1/435 433/1/433 2306/1/2306 +f 435/1/435 2306/1/2306 2307/1/2307 +f 2305/1/2305 435/1/435 2307/1/2307 +f 2305/1/2305 2307/1/2307 2309/1/2309 +f 2308/1/2308 2305/1/2305 2309/1/2309 +f 2308/1/2308 2309/1/2309 2479/1/2479 +f 2481/1/2481 2308/1/2308 2479/1/2479 +f 2481/1/2481 2479/1/2479 2483/1/2483 +f 2483/1/2483 2488/1/2488 2481/1/2481 +f 2481/1/2481 2488/1/2488 2499/1/2499 +f 2481/1/2481 2499/1/2499 2500/1/2500 +f 2481/1/2481 2500/1/2500 2480/1/2480 +f 2500/1/2500 2499/1/2499 2501/1/2501 +f 2500/1/2500 2501/1/2501 2502/1/2502 +f 2501/1/2501 2503/1/2503 2502/1/2502 +f 2501/1/2501 2324/1/2324 2503/1/2503 +f 2324/1/2324 2323/1/2323 2503/1/2503 +f 2503/1/2503 2323/1/2323 427/1/427 +f 427/1/427 2297/1/2297 2503/1/2503 +f 2302/1/2302 2503/1/2503 2297/1/2297 +f 2302/1/2302 2297/1/2297 2296/1/2296 +f 2296/1/2296 2297/1/2297 2295/1/2295 +f 2296/1/2296 2295/1/2295 2298/1/2298 +f 427/1/427 2295/1/2295 2297/1/2297 +f 87/1/87 2295/1/2295 427/1/427 +f 427/1/427 428/1/428 87/1/87 +f 87/1/87 428/1/428 426/1/426 +f 426/1/426 85/1/85 87/1/87 +f 87/1/87 85/1/85 83/1/83 +f 83/1/83 88/1/88 87/1/87 +f 2294/1/2294 87/1/87 88/1/88 +f 2294/1/2294 88/1/88 2255/1/2255 +f 2255/1/2255 2257/1/2257 2294/1/2294 +f 2294/1/2294 2257/1/2257 2293/1/2293 +f 2293/1/2293 2257/1/2257 2256/1/2256 +f 2256/1/2256 2257/1/2257 2254/1/2254 +f 2256/1/2256 2254/1/2254 2258/1/2258 +f 2255/1/2255 2254/1/2254 2257/1/2257 +f 2252/1/2252 2254/1/2254 2255/1/2255 +f 2255/1/2255 89/1/89 2252/1/2252 +f 2252/1/2252 89/1/89 91/1/91 +f 2252/1/2252 91/1/91 2250/1/2250 +f 2250/1/2250 2249/1/2249 2252/1/2252 +f 2249/1/2249 2251/1/2251 2252/1/2252 +f 2249/1/2249 2246/1/2246 2251/1/2251 +f 2247/1/2247 2251/1/2251 2246/1/2246 +f 2247/1/2247 2246/1/2246 2243/1/2243 +f 2247/1/2247 2243/1/2243 2248/1/2248 +f 2265/1/2265 2247/1/2247 2248/1/2248 +f 2265/1/2265 2248/1/2248 2267/1/2267 +f 2267/1/2267 2248/1/2248 2268/1/2268 +f 2268/1/2268 2266/1/2266 2267/1/2267 +f 2269/1/2269 2266/1/2266 2268/1/2268 +f 2268/1/2268 2240/1/2240 2269/1/2269 +f 2269/1/2269 2240/1/2240 2241/1/2241 +f 2269/1/2269 2241/1/2241 2271/1/2271 +f 2271/1/2271 2270/1/2270 2269/1/2269 +f 2272/1/2272 2270/1/2270 2271/1/2271 +f 2271/1/2271 2236/1/2236 2272/1/2272 +f 2272/1/2272 2236/1/2236 2273/1/2273 +f 2272/1/2272 2273/1/2273 2274/1/2274 +f 2274/1/2274 2273/1/2273 2276/1/2276 +f 2276/1/2276 128/1/128 2274/1/2274 +f 128/1/128 123/1/123 2274/1/2274 +f 2274/1/2274 123/1/123 124/1/124 +f 2274/1/2274 124/1/124 2270/1/2270 +f 2270/1/2270 124/1/124 114/1/114 +f 124/1/124 112/1/112 114/1/114 +f 124/1/124 120/1/120 112/1/112 +f 120/1/120 117/1/117 112/1/112 +f 112/1/112 117/1/117 113/1/113 +f 112/1/112 113/1/113 111/1/111 +f 117/1/117 118/1/118 113/1/113 +f 113/1/113 118/1/118 119/1/119 +f 113/1/113 119/1/119 116/1/116 +f 113/1/113 116/1/116 108/1/108 +f 108/1/108 116/1/116 387/1/387 +f 108/1/108 387/1/387 109/1/109 +f 108/1/108 109/1/109 105/1/105 +f 109/1/109 107/1/107 105/1/105 +f 105/1/105 107/1/107 104/1/104 +f 105/1/105 104/1/104 103/1/103 +f 69/1/69 105/1/105 103/1/103 +f 69/1/69 103/1/103 102/1/102 +f 103/1/103 100/1/100 102/1/102 +f 102/1/102 100/1/100 101/1/101 +f 102/1/102 101/1/101 71/1/71 +f 100/1/100 96/1/96 101/1/101 +f 101/1/101 96/1/96 97/1/97 +f 93/1/93 97/1/97 96/1/96 +f 94/1/94 93/1/93 96/1/96 +f 94/1/94 96/1/96 98/1/98 +f 95/1/95 94/1/94 98/1/98 +f 95/1/95 98/1/98 395/1/395 +f 395/1/395 397/1/397 95/1/95 +f 401/1/401 95/1/95 397/1/397 +f 396/1/396 401/1/401 397/1/397 +f 396/1/396 400/1/400 401/1/401 +f 400/1/400 2242/1/2242 401/1/401 +f 401/1/401 2242/1/2242 2245/1/2245 +f 2250/1/2250 401/1/401 2245/1/2245 +f 2246/1/2246 2250/1/2250 2245/1/2245 +f 2246/1/2246 2245/1/2245 2244/1/2244 +f 2244/1/2244 2245/1/2245 2242/1/2242 +f 2244/1/2244 2242/1/2242 2239/1/2239 +f 2244/1/2244 2239/1/2239 2243/1/2243 +f 2240/1/2240 2243/1/2243 2239/1/2239 +f 2240/1/2240 2239/1/2239 2237/1/2237 +f 2238/1/2238 2237/1/2237 2239/1/2239 +f 2239/1/2239 2232/1/2232 2238/1/2238 +f 2238/1/2238 2232/1/2232 2231/1/2231 +f 2231/1/2231 2234/1/2234 2238/1/2238 +f 2231/1/2231 2230/1/2230 2234/1/2234 +f 2233/1/2233 2234/1/2234 2230/1/2230 +f 2233/1/2233 2230/1/2230 2279/1/2279 +f 2233/1/2233 2279/1/2279 2278/1/2278 +f 2277/1/2277 2233/1/2233 2278/1/2278 +f 2277/1/2277 2278/1/2278 133/1/133 +f 2275/1/2275 2277/1/2277 133/1/133 +f 133/1/133 128/1/128 2275/1/2275 +f 132/1/132 128/1/128 133/1/133 +f 133/1/133 206/1/206 132/1/132 +f 132/1/132 206/1/206 134/1/134 +f 134/1/134 129/1/129 132/1/132 +f 136/1/136 129/1/129 134/1/134 +f 134/1/134 201/1/201 136/1/136 +f 136/1/136 201/1/201 141/1/141 +f 141/1/141 135/1/135 136/1/136 +f 140/1/140 135/1/135 141/1/141 +f 141/1/141 146/1/146 140/1/140 +f 140/1/140 146/1/146 145/1/145 +f 140/1/140 145/1/145 144/1/144 +f 144/1/144 139/1/139 140/1/140 +f 143/1/143 139/1/139 144/1/144 +f 143/1/143 142/1/142 139/1/139 +f 142/1/142 137/1/137 139/1/139 +f 139/1/139 137/1/137 135/1/135 +f 135/1/135 137/1/137 130/1/130 +f 135/1/135 130/1/130 129/1/129 +f 129/1/129 130/1/130 127/1/127 +f 129/1/129 127/1/127 128/1/128 +f 130/1/130 131/1/131 127/1/127 +f 127/1/127 131/1/131 122/1/122 +f 127/1/127 122/1/122 123/1/123 +f 123/1/123 122/1/122 120/1/120 +f 122/1/122 121/1/121 120/1/120 +f 122/1/122 125/1/125 121/1/121 +f 125/1/125 126/1/126 121/1/121 +f 121/1/121 126/1/126 422/1/422 +f 121/1/121 422/1/422 117/1/117 +f 117/1/117 422/1/422 421/1/421 +f 422/1/422 420/1/420 421/1/421 +f 421/1/421 420/1/420 382/1/382 +f 421/1/421 382/1/382 118/1/118 +f 118/1/118 382/1/382 380/1/380 +f 382/1/382 383/1/383 380/1/380 +f 380/1/380 383/1/383 384/1/384 +f 380/1/380 384/1/384 381/1/381 +f 119/1/119 380/1/380 381/1/381 +f 381/1/381 384/1/384 386/1/386 +f 381/1/381 386/1/386 385/1/385 +f 116/1/116 381/1/381 385/1/385 +f 385/1/385 386/1/386 389/1/389 +f 385/1/385 389/1/389 388/1/388 +f 387/1/387 385/1/385 388/1/388 +f 388/1/388 389/1/389 107/1/107 +f 106/1/106 107/1/107 389/1/389 +f 392/1/392 106/1/106 389/1/389 +f 392/1/392 389/1/389 391/1/391 +f 394/1/394 392/1/392 391/1/391 +f 394/1/394 391/1/391 398/1/398 +f 398/1/398 399/1/399 394/1/394 +f 394/1/394 399/1/399 396/1/396 +f 394/1/394 396/1/396 395/1/395 +f 395/1/395 393/1/393 394/1/394 +f 403/1/403 399/1/399 398/1/398 +f 398/1/398 390/1/390 403/1/403 +f 403/1/403 390/1/390 406/1/406 +f 403/1/403 406/1/406 407/1/407 +f 403/1/403 407/1/407 405/1/405 +f 405/1/405 404/1/404 403/1/403 +f 405/1/405 408/1/408 404/1/404 +f 404/1/404 408/1/408 402/1/402 +f 404/1/404 402/1/402 399/1/399 +f 399/1/399 402/1/402 400/1/400 +f 402/1/402 2232/1/2232 400/1/400 +f 402/1/402 2229/1/2229 2232/1/2232 +f 408/1/408 2229/1/2229 402/1/402 +f 408/1/408 411/1/411 2229/1/2229 +f 2230/1/2230 2229/1/2229 411/1/411 +f 2230/1/2230 411/1/411 2235/1/2235 +f 2235/1/2235 411/1/411 209/1/209 +f 2235/1/2235 209/1/209 207/1/207 +f 207/1/207 2278/1/2278 2235/1/2235 +f 207/1/207 205/1/205 2278/1/2278 +f 206/1/206 2278/1/2278 205/1/205 +f 206/1/206 205/1/205 201/1/201 +f 201/1/201 205/1/205 202/1/202 +f 201/1/201 202/1/202 146/1/146 +f 203/1/203 146/1/146 202/1/202 +f 203/1/203 202/1/202 204/1/204 +f 204/1/204 211/1/211 203/1/203 +f 203/1/203 211/1/211 210/1/210 +f 203/1/203 210/1/210 200/1/200 +f 200/1/200 199/1/199 203/1/203 +f 200/1/200 197/1/197 199/1/199 +f 149/1/149 199/1/199 197/1/197 +f 149/1/149 197/1/197 196/1/196 +f 149/1/149 196/1/196 153/1/153 +f 148/1/148 149/1/149 153/1/153 +f 148/1/148 153/1/153 150/1/150 +f 147/1/147 148/1/148 150/1/150 +f 147/1/147 150/1/150 151/1/151 +f 151/1/151 152/1/152 147/1/147 +f 147/1/147 152/1/152 142/1/142 +f 152/1/152 158/1/158 142/1/142 +f 158/1/158 379/1/379 142/1/142 +f 158/1/158 2135/1/2135 379/1/379 +f 2135/1/2135 2137/1/2137 379/1/379 +f 379/1/379 2137/1/2137 2140/1/2140 +f 379/1/379 2140/1/2140 138/1/138 +f 137/1/137 379/1/379 138/1/138 +f 138/1/138 2140/1/2140 2143/1/2143 +f 138/1/138 2143/1/2143 131/1/131 +f 131/1/131 2143/1/2143 2146/1/2146 +f 2143/1/2143 2147/1/2147 2146/1/2146 +f 2146/1/2146 2147/1/2147 2149/1/2149 +f 2146/1/2146 2149/1/2149 2148/1/2148 +f 2146/1/2146 2148/1/2148 125/1/125 +f 125/1/125 2148/1/2148 424/1/424 +f 2148/1/2148 2152/1/2152 424/1/424 +f 424/1/424 2152/1/2152 423/1/423 +f 424/1/424 423/1/423 126/1/126 +f 126/1/126 423/1/423 419/1/419 +f 423/1/423 418/1/418 419/1/419 +f 419/1/419 418/1/418 417/1/417 +f 419/1/419 417/1/417 420/1/420 +f 415/1/415 417/1/417 418/1/418 +f 414/1/414 415/1/415 418/1/418 +f 414/1/414 418/1/418 416/1/416 +f 412/1/412 414/1/414 416/1/416 +f 412/1/412 416/1/416 2153/1/2153 +f 412/1/412 2153/1/2153 2158/1/2158 +f 2158/1/2158 211/1/211 412/1/412 +f 412/1/412 211/1/211 408/1/408 +f 412/1/412 408/1/408 409/1/409 +f 211/1/211 410/1/410 408/1/408 +f 211/1/211 208/1/208 410/1/410 +f 410/1/410 208/1/208 209/1/209 +f 2158/1/2158 213/1/213 211/1/211 +f 213/1/213 212/1/212 211/1/211 +f 215/1/215 212/1/212 213/1/213 +f 2168/1/2168 215/1/215 213/1/213 +f 2169/1/2169 215/1/215 2168/1/2168 +f 2168/1/2168 2161/1/2161 2169/1/2169 +f 2169/1/2169 2161/1/2161 2166/1/2166 +f 2169/1/2169 2166/1/2166 2173/1/2173 +f 2169/1/2169 2173/1/2173 2170/1/2170 +f 2170/1/2170 214/1/214 2169/1/2169 +f 214/1/214 2170/1/2170 216/1/216 +f 195/1/195 214/1/214 216/1/216 +f 195/1/195 216/1/216 370/1/370 +f 195/1/195 370/1/370 192/1/192 +f 193/1/193 195/1/195 192/1/192 +f 193/1/193 192/1/192 191/1/191 +f 191/1/191 166/1/166 193/1/193 +f 193/1/193 166/1/166 155/1/155 +f 193/1/193 155/1/155 194/1/194 +f 194/1/194 155/1/155 196/1/196 +f 154/1/154 155/1/155 166/1/166 +f 154/1/154 166/1/166 163/1/163 +f 154/1/154 163/1/163 156/1/156 +f 151/1/151 154/1/154 156/1/156 +f 156/1/156 157/1/157 151/1/151 +f 160/1/160 157/1/157 156/1/156 +f 160/1/160 161/1/161 157/1/157 +f 161/1/161 162/1/162 157/1/157 +f 157/1/157 162/1/162 159/1/159 +f 157/1/157 159/1/159 152/1/152 +f 162/1/162 2134/1/2134 159/1/159 +f 159/1/159 2134/1/2134 2135/1/2135 +f 2134/1/2134 2136/1/2136 2135/1/2135 +f 2134/1/2134 2133/1/2133 2136/1/2136 +f 2133/1/2133 2139/1/2139 2136/1/2136 +f 2136/1/2136 2139/1/2139 2138/1/2138 +f 2136/1/2136 2138/1/2138 2137/1/2137 +f 2138/1/2138 2141/1/2141 2137/1/2137 +f 2137/1/2137 2141/1/2141 2142/1/2142 +f 2141/1/2141 2181/1/2181 2142/1/2142 +f 2142/1/2142 2181/1/2181 2225/1/2225 +f 2142/1/2142 2225/1/2225 2227/1/2227 +f 2142/1/2142 2227/1/2227 2145/1/2145 +f 2140/1/2140 2142/1/2142 2145/1/2145 +f 2140/1/2140 2145/1/2145 2144/1/2144 +f 2145/1/2145 2165/1/2165 2144/1/2144 +f 2144/1/2144 2165/1/2165 2163/1/2163 +f 2144/1/2144 2163/1/2163 2164/1/2164 +f 2143/1/2143 2144/1/2144 2164/1/2164 +f 2164/1/2164 2163/1/2163 2160/1/2160 +f 2164/1/2164 2160/1/2160 2147/1/2147 +f 2147/1/2147 2160/1/2160 2150/1/2150 +f 2160/1/2160 2156/1/2156 2150/1/2150 +f 2150/1/2150 2156/1/2156 2151/1/2151 +f 2149/1/2149 2150/1/2150 2151/1/2151 +f 2154/1/2154 2151/1/2151 2156/1/2156 +f 2155/1/2155 2154/1/2154 2156/1/2156 +f 2155/1/2155 2156/1/2156 2157/1/2157 +f 2168/1/2168 2155/1/2155 2157/1/2157 +f 2158/1/2158 2155/1/2155 2168/1/2168 +f 2157/1/2157 2156/1/2156 2159/1/2159 +f 2157/1/2157 2159/1/2159 2161/1/2161 +f 2161/1/2161 2159/1/2159 2162/1/2162 +f 2163/1/2163 2162/1/2162 2159/1/2159 +f 2158/1/2158 2154/1/2154 2155/1/2155 +f 2153/1/2153 2151/1/2151 2154/1/2154 +f 2153/1/2153 2152/1/2152 2151/1/2151 +f 425/1/425 2152/1/2152 2153/1/2153 +f 2160/1/2160 2159/1/2159 2156/1/2156 +f 2163/1/2163 2159/1/2159 2160/1/2160 +f 2165/1/2165 2162/1/2162 2163/1/2163 +f 2165/1/2165 2167/1/2167 2162/1/2162 +f 2166/1/2166 2162/1/2162 2167/1/2167 +f 2227/1/2227 2167/1/2167 2165/1/2165 +f 2227/1/2227 2228/1/2228 2167/1/2167 +f 2173/1/2173 2167/1/2167 2228/1/2228 +f 2173/1/2173 2228/1/2228 2180/1/2180 +f 2173/1/2173 2180/1/2180 2171/1/2171 +f 2171/1/2171 2180/1/2180 2176/1/2176 +f 2171/1/2171 2176/1/2176 2174/1/2174 +f 2172/1/2172 2171/1/2171 2174/1/2174 +f 2172/1/2172 2174/1/2174 2175/1/2175 +f 370/1/370 2172/1/2172 2175/1/2175 +f 370/1/370 2175/1/2175 368/1/368 +f 369/1/369 370/1/370 368/1/368 +f 369/1/369 368/1/368 189/1/189 +f 192/1/192 369/1/369 189/1/189 +f 228/1/228 189/1/189 368/1/368 +f 2224/1/2224 228/1/228 368/1/368 +f 230/1/230 228/1/228 2224/1/2224 +f 2193/1/2193 230/1/230 2224/1/2224 +f 2193/1/2193 2224/1/2224 2191/1/2191 +f 2190/1/2190 2193/1/2193 2191/1/2191 +f 2190/1/2190 2191/1/2191 2186/1/2186 +f 2190/1/2190 2186/1/2186 2187/1/2187 +f 2189/1/2189 2190/1/2190 2187/1/2187 +f 2188/1/2188 2189/1/2189 2187/1/2187 +f 2188/1/2188 2187/1/2187 2139/1/2139 +f 2139/1/2139 2187/1/2187 2185/1/2185 +f 2187/1/2187 2182/1/2182 2185/1/2185 +f 2182/1/2182 2183/1/2183 2185/1/2185 +f 2185/1/2185 2183/1/2183 2138/1/2138 +f 2138/1/2138 2183/1/2183 2179/1/2179 +f 2177/1/2177 2179/1/2179 2183/1/2183 +f 2176/1/2176 2179/1/2179 2177/1/2177 +f 2176/1/2176 2181/1/2181 2179/1/2179 +f 2182/1/2182 2177/1/2177 2183/1/2183 +f 2182/1/2182 2178/1/2178 2177/1/2177 +f 2174/1/2174 2177/1/2177 2178/1/2178 +f 2184/1/2184 2178/1/2178 2182/1/2182 +f 2186/1/2186 2184/1/2184 2182/1/2182 +f 2184/1/2184 2175/1/2175 2178/1/2178 +f 2224/1/2224 2175/1/2175 2184/1/2184 +f 2195/1/2195 2189/1/2189 2188/1/2188 +f 2133/1/2133 2195/1/2195 2188/1/2188 +f 2131/1/2131 2195/1/2195 2133/1/2133 +f 2132/1/2132 2131/1/2131 2133/1/2133 +f 2129/1/2129 2131/1/2131 2132/1/2132 +f 177/1/177 2129/1/2129 2132/1/2132 +f 177/1/177 2132/1/2132 162/1/162 +f 176/1/176 2129/1/2129 177/1/177 +f 173/1/173 176/1/176 177/1/177 +f 173/1/173 177/1/177 161/1/161 +f 169/1/169 173/1/173 161/1/161 +f 169/1/169 161/1/161 165/1/165 +f 165/1/165 168/1/168 169/1/169 +f 169/1/169 168/1/168 170/1/170 +f 170/1/170 168/1/168 171/1/171 +f 170/1/170 171/1/171 174/1/174 +f 174/1/174 175/1/175 170/1/170 +f 170/1/170 175/1/175 173/1/173 +f 178/1/178 175/1/175 174/1/174 +f 174/1/174 180/1/180 178/1/178 +f 178/1/178 180/1/180 181/1/181 +f 178/1/178 181/1/181 179/1/179 +f 179/1/179 181/1/181 182/1/182 +f 182/1/182 378/1/378 179/1/179 +f 179/1/179 378/1/378 175/1/175 +f 378/1/378 2125/1/2125 175/1/175 +f 175/1/175 2125/1/2125 176/1/176 +f 2125/1/2125 2126/1/2126 176/1/176 +f 2125/1/2125 2124/1/2124 2126/1/2126 +f 2124/1/2124 2128/1/2128 2126/1/2126 +f 2126/1/2126 2128/1/2128 2206/1/2206 +f 2126/1/2126 2206/1/2206 2130/1/2130 +f 2126/1/2126 2130/1/2130 2129/1/2129 +f 2206/1/2206 2200/1/2200 2130/1/2130 +f 2130/1/2130 2200/1/2200 2198/1/2198 +f 2130/1/2130 2198/1/2198 2131/1/2131 +f 2131/1/2131 2198/1/2198 2196/1/2196 +f 2198/1/2198 2197/1/2197 2196/1/2196 +f 2196/1/2196 2197/1/2197 2194/1/2194 +f 2196/1/2196 2194/1/2194 2195/1/2195 +f 2197/1/2197 2192/1/2192 2194/1/2194 +f 2194/1/2194 2192/1/2192 2190/1/2190 +f 2197/1/2197 2202/1/2202 2192/1/2192 +f 2202/1/2202 2222/1/2222 2192/1/2192 +f 2222/1/2222 2223/1/2223 2192/1/2192 +f 2192/1/2192 2223/1/2223 2193/1/2193 +f 2222/1/2222 2221/1/2221 2223/1/2223 +f 2221/1/2221 229/1/229 2223/1/2223 +f 2223/1/2223 229/1/229 230/1/230 +f 229/1/229 227/1/227 230/1/230 +f 232/1/232 227/1/227 229/1/229 +f 232/1/232 231/1/231 227/1/227 +f 231/1/231 223/1/223 227/1/227 +f 227/1/227 223/1/223 226/1/226 +f 227/1/227 226/1/226 228/1/228 +f 223/1/223 190/1/190 226/1/226 +f 226/1/226 190/1/190 189/1/189 +f 190/1/190 187/1/187 189/1/189 +f 187/1/187 188/1/188 189/1/189 +f 191/1/191 189/1/189 188/1/188 +f 188/1/188 167/1/167 191/1/191 +f 188/1/188 172/1/172 167/1/167 +f 168/1/168 167/1/167 172/1/172 +f 164/1/164 167/1/167 168/1/168 +f 163/1/163 167/1/167 164/1/164 +f 160/1/160 163/1/163 164/1/164 +f 160/1/160 164/1/164 165/1/165 +f 187/1/187 172/1/172 188/1/188 +f 186/1/186 172/1/172 187/1/187 +f 185/1/185 186/1/186 187/1/187 +f 185/1/185 180/1/180 186/1/186 +f 180/1/180 171/1/171 186/1/186 +f 186/1/186 171/1/171 172/1/172 +f 190/1/190 185/1/185 187/1/187 +f 218/1/218 185/1/185 190/1/190 +f 218/1/218 217/1/217 185/1/185 +f 217/1/217 184/1/184 185/1/185 +f 184/1/184 181/1/181 185/1/185 +f 184/1/184 183/1/183 181/1/181 +f 221/1/221 183/1/183 184/1/184 +f 219/1/219 221/1/221 184/1/184 +f 220/1/220 221/1/221 219/1/219 +f 220/1/220 219/1/219 217/1/217 +f 225/1/225 221/1/221 220/1/220 +f 222/1/222 225/1/225 220/1/220 +f 222/1/222 220/1/220 223/1/223 +f 223/1/223 220/1/220 218/1/218 +f 224/1/224 225/1/225 222/1/222 +f 234/1/234 224/1/224 222/1/222 +f 234/1/234 222/1/222 231/1/231 +f 233/1/233 234/1/234 231/1/231 +f 233/1/233 231/1/231 235/1/235 +f 2218/1/2218 233/1/233 235/1/235 +f 2218/1/2218 235/1/235 2219/1/2219 +f 2211/1/2211 2218/1/2218 2219/1/2219 +f 2211/1/2211 2219/1/2219 2209/1/2209 +f 2208/1/2208 2211/1/2211 2209/1/2209 +f 2208/1/2208 2209/1/2209 2203/1/2203 +f 2205/1/2205 2208/1/2208 2203/1/2203 +f 2205/1/2205 2203/1/2203 2200/1/2200 +f 2200/1/2200 2203/1/2203 2199/1/2199 +f 2203/1/2203 2204/1/2204 2199/1/2199 +f 2199/1/2199 2204/1/2204 2201/1/2201 +f 2199/1/2199 2201/1/2201 2197/1/2197 +f 2204/1/2204 2222/1/2222 2201/1/2201 +f 2207/1/2207 2208/1/2208 2205/1/2205 +f 2206/1/2206 2207/1/2207 2205/1/2205 +f 2207/1/2207 2212/1/2212 2208/1/2208 +f 2212/1/2212 2210/1/2210 2208/1/2208 +f 2214/1/2214 2210/1/2210 2212/1/2212 +f 2213/1/2213 2214/1/2214 2212/1/2212 +f 2215/1/2215 2214/1/2214 2213/1/2213 +f 2128/1/2128 2215/1/2215 2213/1/2213 +f 2128/1/2128 2213/1/2213 2207/1/2207 +f 2127/1/2127 2215/1/2215 2128/1/2128 +f 2127/1/2127 2217/1/2217 2215/1/2215 +f 2217/1/2217 358/1/358 2215/1/2215 +f 2217/1/2217 354/1/354 358/1/358 +f 354/1/354 357/1/357 358/1/358 +f 358/1/358 357/1/357 2216/1/2216 +f 358/1/358 2216/1/2216 2214/1/2214 +f 357/1/357 239/1/239 2216/1/2216 +f 2216/1/2216 239/1/239 240/1/240 +f 2216/1/2216 240/1/240 2210/1/2210 +f 2210/1/2210 240/1/240 2218/1/2218 +f 239/1/239 233/1/233 240/1/240 +f 239/1/239 236/1/236 233/1/233 +f 241/1/241 236/1/236 239/1/239 +f 241/1/241 238/1/238 236/1/236 +f 238/1/238 234/1/234 236/1/236 +f 238/1/238 237/1/237 234/1/234 +f 244/1/244 237/1/237 238/1/238 +f 243/1/243 244/1/244 238/1/238 +f 243/1/243 238/1/238 242/1/242 +f 247/1/247 243/1/243 242/1/242 +f 247/1/247 242/1/242 353/1/353 +f 247/1/247 353/1/353 354/1/354 +f 351/1/351 247/1/247 354/1/354 +f 355/1/355 351/1/351 354/1/354 +f 352/1/352 351/1/351 355/1/355 +f 2123/1/2123 352/1/352 355/1/355 +f 2123/1/2123 355/1/355 2217/1/2217 +f 356/1/356 352/1/352 2123/1/2123 +f 2122/1/2122 356/1/356 2123/1/2123 +f 2122/1/2122 2123/1/2123 2124/1/2124 +f 2121/1/2121 2122/1/2122 2124/1/2124 +f 2117/1/2117 2122/1/2122 2121/1/2121 +f 2120/1/2120 2117/1/2117 2121/1/2121 +f 2120/1/2120 2121/1/2121 378/1/378 +f 372/1/372 2120/1/2120 378/1/378 +f 372/1/372 378/1/378 371/1/371 +f 371/1/371 183/1/183 372/1/372 +f 372/1/372 183/1/183 373/1/373 +f 372/1/372 373/1/373 2350/1/2350 +f 2350/1/2350 373/1/373 375/1/375 +f 2350/1/2350 375/1/375 2349/1/2349 +f 2349/1/2349 2120/1/2120 2350/1/2350 +f 2119/1/2119 2120/1/2120 2349/1/2349 +f 2119/1/2119 2115/1/2115 2120/1/2120 +f 2118/1/2118 2115/1/2115 2119/1/2119 +f 2119/1/2119 2351/1/2351 2118/1/2118 +f 2118/1/2118 2351/1/2351 2352/1/2352 +f 2118/1/2118 2352/1/2352 2353/1/2353 +f 2353/1/2353 2113/1/2113 2118/1/2118 +f 2357/1/2357 2113/1/2113 2353/1/2353 +f 2353/1/2353 2354/1/2354 2357/1/2357 +f 2357/1/2357 2354/1/2354 2109/1/2109 +f 2357/1/2357 2109/1/2109 2108/1/2108 +f 2108/1/2108 2109/1/2109 2106/1/2106 +f 2108/1/2108 2106/1/2106 2110/1/2110 +f 2110/1/2110 2111/1/2111 2108/1/2108 +f 2108/1/2108 2111/1/2111 2113/1/2113 +f 2111/1/2111 2112/1/2112 2113/1/2113 +f 2113/1/2113 2112/1/2112 2114/1/2114 +f 2113/1/2113 2114/1/2114 2115/1/2115 +f 2115/1/2115 2114/1/2114 2117/1/2117 +f 2114/1/2114 2116/1/2116 2117/1/2117 +f 2114/1/2114 330/1/330 2116/1/2116 +f 330/1/330 336/1/336 2116/1/2116 +f 2116/1/2116 336/1/336 356/1/356 +f 336/1/336 347/1/347 356/1/356 +f 356/1/356 347/1/347 350/1/350 +f 347/1/347 348/1/348 350/1/350 +f 350/1/350 348/1/348 349/1/349 +f 350/1/350 349/1/349 352/1/352 +f 348/1/348 245/1/245 349/1/349 +f 349/1/349 245/1/245 247/1/247 +f 348/1/348 346/1/346 245/1/245 +f 346/1/346 246/1/246 245/1/245 +f 245/1/245 246/1/246 243/1/243 +f 346/1/346 250/1/250 246/1/246 +f 250/1/250 248/1/248 246/1/246 +f 246/1/246 248/1/248 244/1/244 +f 248/1/248 249/1/249 244/1/244 +f 251/1/251 249/1/249 248/1/248 +f 251/1/251 252/1/252 249/1/249 +f 252/1/252 253/1/253 249/1/249 +f 249/1/249 253/1/253 254/1/254 +f 249/1/249 254/1/254 237/1/237 +f 237/1/237 254/1/254 224/1/224 +f 254/1/254 256/1/256 224/1/224 +f 254/1/254 255/1/255 256/1/256 +f 255/1/255 2361/1/2361 256/1/256 +f 256/1/256 2361/1/2361 377/1/377 +f 256/1/256 377/1/377 225/1/225 +f 225/1/225 377/1/377 376/1/376 +f 377/1/377 2356/1/2356 376/1/376 +f 2356/1/2356 375/1/375 376/1/376 +f 376/1/376 375/1/375 374/1/374 +f 376/1/376 374/1/374 221/1/221 +f 2356/1/2356 2351/1/2351 375/1/375 +f 2361/1/2361 2356/1/2356 377/1/377 +f 2361/1/2361 2355/1/2355 2356/1/2356 +f 2355/1/2355 2352/1/2352 2356/1/2356 +f 2355/1/2355 2354/1/2354 2352/1/2352 +f 2358/1/2358 2354/1/2354 2355/1/2355 +f 2360/1/2360 2358/1/2358 2355/1/2355 +f 255/1/255 2358/1/2358 2360/1/2360 +f 2359/1/2359 2358/1/2358 255/1/255 +f 253/1/253 2359/1/2359 255/1/255 +f 257/1/257 2359/1/2359 253/1/253 +f 257/1/257 2100/1/2100 2359/1/2359 +f 2100/1/2100 2102/1/2102 2359/1/2359 +f 2100/1/2100 2099/1/2099 2102/1/2102 +f 2099/1/2099 2101/1/2101 2102/1/2102 +f 2101/1/2101 2106/1/2106 2102/1/2102 +f 2101/1/2101 2103/1/2103 2106/1/2106 +f 2105/1/2105 2106/1/2106 2103/1/2103 +f 2105/1/2105 2103/1/2103 2107/1/2107 +f 2107/1/2107 2111/1/2111 2105/1/2105 +f 2107/1/2107 2074/1/2074 2111/1/2111 +f 2074/1/2074 2075/1/2075 2111/1/2111 +f 2074/1/2074 2073/1/2073 2075/1/2075 +f 2073/1/2073 325/1/325 2075/1/2075 +f 2075/1/2075 325/1/325 326/1/326 +f 2075/1/2075 326/1/326 2112/1/2112 +f 2112/1/2112 326/1/326 330/1/330 +f 326/1/326 329/1/329 330/1/330 +f 330/1/330 329/1/329 335/1/335 +f 329/1/329 334/1/334 335/1/335 +f 335/1/335 334/1/334 337/1/337 +f 335/1/335 337/1/337 336/1/336 +f 334/1/334 339/1/339 337/1/337 +f 337/1/337 339/1/339 342/1/342 +f 337/1/337 342/1/342 347/1/347 +f 347/1/347 342/1/342 345/1/345 +f 342/1/342 343/1/343 345/1/345 +f 343/1/343 346/1/346 345/1/345 +f 339/1/339 343/1/343 342/1/342 +f 339/1/339 341/1/341 343/1/343 +f 341/1/341 344/1/344 343/1/343 +f 343/1/343 344/1/344 250/1/250 +f 344/1/344 251/1/251 250/1/250 +f 260/1/260 251/1/251 344/1/344 +f 260/1/260 258/1/258 251/1/251 +f 261/1/261 258/1/258 260/1/260 +f 266/1/266 261/1/261 260/1/260 +f 266/1/266 260/1/260 341/1/341 +f 338/1/338 266/1/266 341/1/341 +f 265/1/265 266/1/266 338/1/338 +f 340/1/340 265/1/265 338/1/338 +f 333/1/333 340/1/340 338/1/338 +f 333/1/333 338/1/338 334/1/334 +f 332/1/332 340/1/340 333/1/333 +f 329/1/329 332/1/332 333/1/333 +f 328/1/328 332/1/332 329/1/329 +f 328/1/328 331/1/331 332/1/332 +f 331/1/331 271/1/271 332/1/332 +f 331/1/331 270/1/270 271/1/271 +f 270/1/270 267/1/267 271/1/271 +f 271/1/271 267/1/267 265/1/265 +f 267/1/267 264/1/264 265/1/265 +f 265/1/265 264/1/264 261/1/261 +f 264/1/264 259/1/259 261/1/261 +f 262/1/262 259/1/259 264/1/264 +f 262/1/262 263/1/263 259/1/259 +f 263/1/263 276/1/276 259/1/259 +f 259/1/259 276/1/276 252/1/252 +f 259/1/259 252/1/252 258/1/258 +f 276/1/276 257/1/257 252/1/252 +f 276/1/276 367/1/367 257/1/257 +f 367/1/367 2096/1/2096 257/1/257 +f 367/1/367 2095/1/2095 2096/1/2096 +f 2095/1/2095 2094/1/2094 2096/1/2096 +f 2096/1/2096 2094/1/2094 2097/1/2097 +f 2096/1/2096 2097/1/2097 2099/1/2099 +f 2097/1/2097 2098/1/2098 2099/1/2099 +f 2097/1/2097 2082/1/2082 2098/1/2098 +f 2098/1/2098 2082/1/2082 2103/1/2103 +f 2104/1/2104 2103/1/2103 2082/1/2082 +f 2104/1/2104 2082/1/2082 2081/1/2081 +f 2081/1/2081 2074/1/2074 2104/1/2104 +f 2077/1/2077 2074/1/2074 2081/1/2081 +f 2077/1/2077 2072/1/2072 2074/1/2074 +f 2076/1/2076 2072/1/2072 2077/1/2077 +f 2077/1/2077 2078/1/2078 2076/1/2076 +f 2076/1/2076 2078/1/2078 2079/1/2079 +f 2076/1/2076 2079/1/2079 2080/1/2080 +f 2080/1/2080 2070/1/2070 2076/1/2076 +f 2086/1/2086 2070/1/2070 2080/1/2080 +f 2080/1/2080 2084/1/2084 2086/1/2086 +f 2086/1/2086 2084/1/2084 2087/1/2087 +f 2086/1/2086 2087/1/2087 2366/1/2366 +f 2366/1/2366 2087/1/2087 2363/1/2363 +f 2366/1/2366 2363/1/2363 2365/1/2365 +f 2365/1/2365 489/1/489 2366/1/2366 +f 2366/1/2366 489/1/489 2070/1/2070 +f 489/1/489 492/1/492 2070/1/2070 +f 2070/1/2070 492/1/492 2071/1/2071 +f 2070/1/2070 2071/1/2071 2072/1/2072 +f 2072/1/2072 2071/1/2071 2073/1/2073 +f 2071/1/2071 324/1/324 2073/1/2073 +f 2071/1/2071 323/1/323 324/1/324 +f 323/1/323 295/1/295 324/1/324 +f 324/1/324 295/1/295 290/1/290 +f 324/1/324 290/1/290 325/1/325 +f 325/1/325 290/1/290 291/1/291 +f 290/1/290 288/1/288 291/1/291 +f 291/1/291 288/1/288 289/1/289 +f 291/1/291 289/1/289 327/1/327 +f 291/1/291 327/1/327 328/1/328 +f 326/1/326 291/1/291 328/1/328 +f 289/1/289 273/1/273 327/1/327 +f 327/1/327 273/1/273 270/1/270 +f 273/1/273 268/1/268 270/1/270 +f 273/1/273 272/1/272 268/1/268 +f 272/1/272 269/1/269 268/1/268 +f 268/1/268 269/1/269 262/1/262 +f 268/1/268 262/1/262 267/1/267 +f 272/1/272 274/1/274 269/1/269 +f 274/1/274 275/1/275 269/1/269 +f 269/1/269 275/1/275 263/1/263 +f 277/1/277 275/1/275 274/1/274 +f 280/1/280 277/1/277 274/1/274 +f 282/1/282 277/1/277 280/1/280 +f 281/1/281 282/1/282 280/1/280 +f 281/1/281 280/1/280 283/1/283 +f 288/1/288 281/1/281 283/1/283 +f 287/1/287 281/1/281 288/1/288 +f 287/1/287 286/1/286 281/1/281 +f 292/1/292 286/1/286 287/1/287 +f 290/1/290 292/1/292 287/1/287 +f 292/1/292 293/1/293 286/1/286 +f 293/1/293 285/1/285 286/1/286 +f 286/1/286 285/1/285 282/1/282 +f 285/1/285 284/1/284 282/1/282 +f 285/1/285 302/1/302 284/1/284 +f 302/1/302 305/1/305 284/1/284 +f 284/1/284 305/1/305 278/1/278 +f 284/1/284 278/1/278 277/1/277 +f 305/1/305 362/1/362 278/1/278 +f 278/1/278 362/1/362 279/1/279 +f 278/1/278 279/1/279 275/1/275 +f 275/1/275 279/1/279 276/1/276 +f 362/1/362 366/1/366 279/1/279 +f 279/1/279 366/1/366 367/1/367 +f 362/1/362 365/1/365 366/1/366 +f 365/1/365 2093/1/2093 366/1/366 +f 366/1/366 2093/1/2093 2095/1/2095 +f 2093/1/2093 2090/1/2090 2095/1/2095 +f 2093/1/2093 2089/1/2089 2090/1/2090 +f 2089/1/2089 2085/1/2085 2090/1/2090 +f 2090/1/2090 2085/1/2085 2083/1/2083 +f 2090/1/2090 2083/1/2083 2094/1/2094 +f 2085/1/2085 2079/1/2079 2083/1/2083 +f 2085/1/2085 2084/1/2084 2079/1/2079 +f 2088/1/2088 2084/1/2084 2085/1/2085 +f 2089/1/2089 2088/1/2088 2085/1/2085 +f 2093/1/2093 2088/1/2088 2089/1/2089 +f 2091/1/2091 2088/1/2088 2093/1/2093 +f 2091/1/2091 2092/1/2092 2088/1/2088 +f 2088/1/2088 2092/1/2092 2087/1/2087 +f 477/1/477 2092/1/2092 2091/1/2091 +f 364/1/364 477/1/477 2091/1/2091 +f 364/1/364 2091/1/2091 365/1/365 +f 361/1/361 364/1/364 365/1/365 +f 2055/1/2055 364/1/364 361/1/361 +f 363/1/363 2055/1/2055 361/1/361 +f 363/1/363 361/1/361 360/1/360 +f 308/1/308 363/1/363 360/1/360 +f 308/1/308 360/1/360 306/1/306 +f 307/1/307 308/1/308 306/1/306 +f 307/1/307 306/1/306 301/1/301 +f 300/1/300 307/1/307 301/1/301 +f 300/1/300 301/1/301 298/1/298 +f 299/1/299 300/1/300 298/1/298 +f 299/1/299 298/1/298 296/1/296 +f 295/1/295 299/1/299 296/1/296 +f 295/1/295 296/1/296 292/1/292 +f 296/1/296 294/1/294 292/1/292 +f 321/1/321 299/1/299 295/1/295 +f 321/1/321 322/1/322 299/1/299 +f 321/1/321 320/1/320 322/1/322 +f 320/1/320 313/1/313 322/1/322 +f 322/1/322 313/1/313 300/1/300 +f 313/1/313 309/1/309 300/1/300 +f 312/1/312 309/1/309 313/1/313 +f 312/1/312 311/1/311 309/1/309 +f 311/1/311 310/1/310 309/1/309 +f 309/1/309 310/1/310 308/1/308 +f 311/1/311 314/1/314 310/1/310 +f 314/1/314 363/1/363 310/1/310 +f 314/1/314 2056/1/2056 363/1/363 +f 2057/1/2057 2056/1/2056 314/1/314 +f 315/1/315 2057/1/2057 314/1/314 +f 2068/1/2068 2057/1/2057 315/1/315 +f 2067/1/2067 2068/1/2068 315/1/315 +f 2067/1/2067 315/1/315 316/1/316 +f 317/1/317 2067/1/2067 316/1/316 +f 317/1/317 316/1/316 318/1/318 +f 319/1/319 317/1/317 318/1/318 +f 319/1/319 318/1/318 320/1/320 +f 318/1/318 312/1/312 320/1/320 +f 2066/1/2066 317/1/317 319/1/319 +f 359/1/359 2066/1/2066 319/1/319 +f 359/1/359 319/1/319 321/1/321 +f 359/1/359 321/1/321 323/1/323 +f 492/1/492 359/1/359 323/1/323 +f 490/1/490 359/1/359 492/1/492 +f 490/1/490 2069/1/2069 359/1/359 +f 491/1/491 2069/1/2069 490/1/490 +f 487/1/487 491/1/491 490/1/490 +f 487/1/487 490/1/490 489/1/489 +f 488/1/488 487/1/487 489/1/489 +f 488/1/488 489/1/489 2364/1/2364 +f 2364/1/2364 479/1/479 488/1/488 +f 488/1/488 479/1/479 480/1/480 +f 480/1/480 479/1/479 474/1/474 +f 480/1/480 474/1/474 485/1/485 +f 485/1/485 487/1/487 480/1/480 +f 481/1/481 487/1/487 485/1/485 +f 481/1/481 486/1/486 487/1/487 +f 482/1/482 486/1/486 481/1/481 +f 481/1/481 473/1/473 482/1/482 +f 482/1/482 473/1/473 472/1/472 +f 482/1/482 472/1/472 484/1/484 +f 484/1/484 495/1/495 482/1/482 +f 499/1/499 495/1/495 484/1/484 +f 484/1/484 483/1/483 499/1/499 +f 499/1/499 483/1/483 500/1/500 +f 499/1/499 500/1/500 497/1/497 +f 497/1/497 500/1/500 501/1/501 +f 497/1/497 501/1/501 502/1/502 +f 502/1/502 498/1/498 497/1/497 +f 497/1/497 498/1/498 495/1/495 +f 498/1/498 496/1/496 495/1/495 +f 495/1/495 496/1/496 493/1/493 +f 495/1/495 493/1/493 486/1/486 +f 486/1/486 493/1/493 491/1/491 +f 493/1/493 494/1/494 491/1/491 +f 493/1/493 2029/1/2029 494/1/494 +f 2029/1/2029 2031/1/2031 494/1/494 +f 494/1/494 2031/1/2031 2035/1/2035 +f 494/1/494 2035/1/2035 2069/1/2069 +f 2069/1/2069 2035/1/2035 2066/1/2066 +f 2035/1/2035 2063/1/2063 2066/1/2066 +f 2066/1/2066 2063/1/2063 2065/1/2065 +f 2063/1/2063 2064/1/2064 2065/1/2065 +f 2065/1/2065 2064/1/2064 2067/1/2067 +f 2064/1/2064 2059/1/2059 2067/1/2067 +f 2061/1/2061 2059/1/2059 2064/1/2064 +f 2061/1/2061 2053/1/2053 2059/1/2059 +f 2053/1/2053 2052/1/2052 2059/1/2059 +f 2059/1/2059 2052/1/2052 2058/1/2058 +f 2059/1/2059 2058/1/2058 2068/1/2068 +f 2052/1/2052 2054/1/2054 2058/1/2058 +f 2058/1/2058 2054/1/2054 2057/1/2057 +f 2052/1/2052 2051/1/2051 2054/1/2054 +f 2051/1/2051 550/1/550 2054/1/2054 +f 2054/1/2054 550/1/550 2055/1/2055 +f 2054/1/2054 2055/1/2055 2056/1/2056 +f 550/1/550 478/1/478 2055/1/2055 +f 550/1/550 463/1/463 478/1/478 +f 463/1/463 465/1/465 478/1/478 +f 478/1/478 465/1/465 470/1/470 +f 478/1/478 470/1/470 364/1/364 +f 465/1/465 469/1/469 470/1/470 +f 470/1/470 469/1/469 471/1/471 +f 470/1/470 471/1/471 475/1/475 +f 470/1/470 475/1/475 477/1/477 +f 471/1/471 476/1/476 475/1/475 +f 475/1/475 476/1/476 2362/1/2362 +f 475/1/475 2362/1/2362 2092/1/2092 +f 2362/1/2362 2363/1/2363 2092/1/2092 +f 2362/1/2362 479/1/479 2363/1/2363 +f 476/1/476 479/1/479 2362/1/2362 +f 471/1/471 474/1/474 476/1/476 +f 468/1/468 474/1/474 471/1/471 +f 468/1/468 473/1/473 474/1/474 +f 469/1/469 468/1/468 471/1/471 +f 464/1/464 468/1/468 469/1/469 +f 464/1/464 467/1/467 468/1/468 +f 467/1/467 472/1/472 468/1/468 +f 467/1/467 483/1/483 472/1/472 +f 461/1/461 483/1/483 467/1/467 +f 466/1/466 461/1/461 467/1/467 +f 462/1/462 461/1/461 466/1/466 +f 462/1/462 466/1/466 464/1/464 +f 462/1/462 464/1/464 465/1/465 +f 457/1/457 461/1/461 462/1/462 +f 458/1/458 457/1/457 462/1/462 +f 458/1/458 462/1/462 463/1/463 +f 549/1/549 458/1/458 463/1/463 +f 453/1/453 458/1/458 549/1/549 +f 552/1/552 453/1/453 549/1/549 +f 552/1/552 549/1/549 2049/1/2049 +f 2045/1/2045 552/1/552 2049/1/2049 +f 2045/1/2045 2049/1/2049 2050/1/2050 +f 2044/1/2044 2045/1/2045 2050/1/2050 +f 2044/1/2044 2050/1/2050 2053/1/2053 +f 2060/1/2060 2044/1/2044 2053/1/2053 +f 2043/1/2043 2044/1/2044 2060/1/2060 +f 2034/1/2034 2043/1/2043 2060/1/2060 +f 2034/1/2034 2060/1/2060 2062/1/2062 +f 2035/1/2035 2034/1/2034 2062/1/2062 +f 2062/1/2062 2060/1/2060 2061/1/2061 +f 2062/1/2062 2061/1/2061 2063/1/2063 +f 2034/1/2034 2038/1/2038 2043/1/2043 +f 2038/1/2038 2042/1/2042 2043/1/2043 +f 2037/1/2037 2042/1/2042 2038/1/2038 +f 2033/1/2033 2037/1/2037 2038/1/2038 +f 2036/1/2036 2037/1/2037 2033/1/2033 +f 2032/1/2032 2036/1/2036 2033/1/2033 +f 2032/1/2032 2033/1/2033 2031/1/2031 +f 2031/1/2031 2033/1/2033 2034/1/2034 +f 2028/1/2028 2036/1/2036 2032/1/2032 +f 2029/1/2029 2028/1/2028 2032/1/2032 +f 2026/1/2026 2028/1/2028 2029/1/2029 +f 496/1/496 2026/1/2026 2029/1/2029 +f 515/1/515 2026/1/2026 496/1/496 +f 515/1/515 2025/1/2025 2026/1/2026 +f 2025/1/2025 2027/1/2027 2026/1/2026 +f 2026/1/2026 2027/1/2027 2030/1/2030 +f 2027/1/2027 2417/1/2417 2030/1/2030 +f 2030/1/2030 2417/1/2417 2418/1/2418 +f 2030/1/2030 2418/1/2418 2419/1/2419 +f 2030/1/2030 2419/1/2419 2028/1/2028 +f 2028/1/2028 2419/1/2419 2039/1/2039 +f 2419/1/2419 2372/1/2372 2039/1/2039 +f 2039/1/2039 2372/1/2372 2040/1/2040 +f 2039/1/2039 2040/1/2040 2036/1/2036 +f 2372/1/2372 2368/1/2368 2040/1/2040 +f 2368/1/2368 2047/1/2047 2040/1/2040 +f 2040/1/2040 2047/1/2047 2041/1/2041 +f 2040/1/2040 2041/1/2041 2037/1/2037 +f 2047/1/2047 2048/1/2048 2041/1/2041 +f 2041/1/2041 2048/1/2048 2046/1/2046 +f 2041/1/2041 2046/1/2046 2042/1/2042 +f 2042/1/2042 2046/1/2046 2045/1/2045 +f 2048/1/2048 552/1/552 2046/1/2046 +f 2048/1/2048 551/1/551 552/1/552 +f 2367/1/2367 551/1/551 2048/1/2048 +f 2367/1/2367 455/1/455 551/1/551 +f 455/1/455 453/1/453 551/1/551 +f 455/1/455 451/1/451 453/1/453 +f 451/1/451 452/1/452 453/1/453 +f 451/1/451 447/1/447 452/1/452 +f 447/1/447 450/1/450 452/1/452 +f 452/1/452 450/1/450 456/1/456 +f 452/1/452 456/1/456 457/1/457 +f 456/1/456 460/1/460 457/1/457 +f 456/1/456 459/1/459 460/1/460 +f 459/1/459 505/1/505 460/1/460 +f 505/1/505 501/1/501 460/1/460 +f 505/1/505 504/1/504 501/1/501 +f 503/1/503 501/1/501 504/1/504 +f 503/1/503 504/1/504 507/1/507 +f 507/1/507 498/1/498 503/1/503 +f 507/1/507 510/1/510 498/1/498 +f 510/1/510 515/1/515 498/1/498 +f 510/1/510 514/1/514 515/1/515 +f 513/1/513 514/1/514 510/1/510 +f 512/1/512 513/1/513 510/1/510 +f 512/1/512 510/1/510 511/1/511 +f 511/1/511 509/1/509 512/1/512 +f 512/1/512 509/1/509 516/1/516 +f 512/1/512 516/1/516 517/1/517 +f 517/1/517 516/1/516 520/1/520 +f 517/1/517 520/1/520 521/1/521 +f 521/1/521 518/1/518 517/1/517 +f 517/1/517 518/1/518 513/1/513 +f 518/1/518 519/1/519 513/1/513 +f 518/1/518 2016/1/2016 519/1/519 +f 2016/1/2016 2018/1/2018 519/1/519 +f 519/1/519 2018/1/2018 2022/1/2022 +f 519/1/519 2022/1/2022 514/1/514 +f 514/1/514 2022/1/2022 2025/1/2025 +f 2022/1/2022 2024/1/2024 2025/1/2025 +f 2022/1/2022 2023/1/2023 2024/1/2024 +f 2023/1/2023 2391/1/2391 2024/1/2024 +f 2024/1/2024 2391/1/2391 2386/1/2386 +f 2024/1/2024 2386/1/2386 2388/1/2388 +f 2024/1/2024 2388/1/2388 2027/1/2027 +f 2027/1/2027 2388/1/2388 2416/1/2416 +f 2388/1/2388 2385/1/2385 2416/1/2416 +f 2416/1/2416 2385/1/2385 2382/1/2382 +f 2416/1/2416 2382/1/2382 2417/1/2417 +f 2417/1/2417 2382/1/2382 2375/1/2375 +f 2382/1/2382 2374/1/2374 2375/1/2375 +f 2375/1/2375 2374/1/2374 2371/1/2371 +f 2375/1/2375 2371/1/2371 2370/1/2370 +f 2418/1/2418 2375/1/2375 2370/1/2370 +f 2370/1/2370 2371/1/2371 2368/1/2368 +f 2371/1/2371 2369/1/2369 2368/1/2368 +f 2368/1/2368 2369/1/2369 2367/1/2367 +f 2371/1/2371 2373/1/2373 2369/1/2369 +f 2373/1/2373 455/1/455 2369/1/2369 +f 2373/1/2373 454/1/454 455/1/455 +f 2376/1/2376 454/1/454 2373/1/2373 +f 2374/1/2374 2376/1/2376 2373/1/2373 +f 2378/1/2378 2376/1/2376 2374/1/2374 +f 2378/1/2378 2379/1/2379 2376/1/2376 +f 2379/1/2379 2377/1/2377 2376/1/2376 +f 2380/1/2380 2377/1/2377 2379/1/2379 +f 2381/1/2381 2380/1/2380 2379/1/2379 +f 2384/1/2384 2380/1/2380 2381/1/2381 +f 2383/1/2383 2384/1/2384 2381/1/2381 +f 2383/1/2383 2381/1/2381 2385/1/2385 +f 2387/1/2387 2384/1/2384 2383/1/2383 +f 2386/1/2386 2387/1/2387 2383/1/2383 +f 2387/1/2387 2389/1/2389 2384/1/2384 +f 2389/1/2389 2390/1/2390 2384/1/2384 +f 2389/1/2389 2415/1/2415 2390/1/2390 +f 2415/1/2415 555/1/555 2390/1/2390 +f 2390/1/2390 555/1/555 556/1/556 +f 2390/1/2390 556/1/556 2380/1/2380 +f 555/1/555 448/1/448 556/1/556 +f 556/1/556 448/1/448 449/1/449 +f 556/1/556 449/1/449 2377/1/2377 +f 2377/1/2377 449/1/449 451/1/451 +f 2377/1/2377 451/1/451 454/1/454 +f 448/1/448 445/1/445 449/1/449 +f 449/1/449 445/1/445 447/1/447 +f 445/1/445 446/1/446 447/1/447 +f 445/1/445 442/1/442 446/1/446 +f 442/1/442 528/1/528 446/1/446 +f 446/1/446 528/1/528 547/1/547 +f 446/1/446 547/1/547 450/1/450 +f 450/1/450 547/1/547 548/1/548 +f 450/1/450 548/1/548 459/1/459 +f 548/1/548 506/1/506 459/1/459 +f 548/1/548 509/1/509 506/1/506 +f 506/1/506 509/1/509 504/1/504 +f 508/1/508 504/1/504 509/1/509 +f 522/1/522 509/1/509 548/1/548 +f 547/1/547 522/1/522 548/1/548 +f 528/1/528 522/1/522 547/1/547 +f 528/1/528 524/1/524 522/1/522 +f 524/1/524 520/1/520 522/1/522 +f 524/1/524 523/1/523 520/1/520 +f 441/1/441 523/1/523 524/1/524 +f 527/1/527 441/1/441 524/1/524 +f 442/1/442 441/1/441 527/1/527 +f 438/1/438 441/1/441 442/1/442 +f 444/1/444 438/1/438 442/1/442 +f 443/1/443 438/1/438 444/1/444 +f 553/1/553 443/1/443 444/1/444 +f 553/1/553 444/1/444 448/1/448 +f 554/1/554 553/1/553 448/1/448 +f 1479/1/1479 553/1/553 554/1/554 +f 2413/1/2413 1479/1/1479 554/1/554 +f 2413/1/2413 554/1/554 2414/1/2414 +f 2400/1/2400 2413/1/2413 2414/1/2414 +f 2400/1/2400 2414/1/2414 2395/1/2395 +f 2396/1/2396 2400/1/2400 2395/1/2395 +f 2396/1/2396 2395/1/2395 2393/1/2393 +f 2394/1/2394 2396/1/2396 2393/1/2393 +f 2394/1/2394 2393/1/2393 2391/1/2391 +f 2391/1/2391 2393/1/2393 2392/1/2392 +f 2391/1/2391 2392/1/2392 2387/1/2387 +f 2397/1/2397 2396/1/2396 2394/1/2394 +f 2023/1/2023 2397/1/2397 2394/1/2394 +f 2020/1/2020 2397/1/2397 2023/1/2023 +f 2018/1/2018 2020/1/2020 2023/1/2023 +f 2017/1/2017 2020/1/2020 2018/1/2018 +f 2017/1/2017 2019/1/2019 2020/1/2020 +f 2019/1/2019 2404/1/2404 2020/1/2020 +f 2020/1/2020 2404/1/2404 2398/1/2398 +f 2404/1/2404 2401/1/2401 2398/1/2398 +f 2398/1/2398 2401/1/2401 2399/1/2399 +f 2398/1/2398 2399/1/2399 2397/1/2397 +f 2401/1/2401 2402/1/2402 2399/1/2399 +f 2402/1/2402 2403/1/2403 2399/1/2399 +f 2399/1/2399 2403/1/2403 2400/1/2400 +f 2402/1/2402 2412/1/2412 2403/1/2403 +f 2403/1/2403 2412/1/2412 2413/1/2413 +f 2402/1/2402 2411/1/2411 2412/1/2412 +f 2411/1/2411 561/1/561 2412/1/2412 +f 2412/1/2412 561/1/561 1479/1/1479 +f 628/1/628 561/1/561 2411/1/2411 +f 2408/1/2408 628/1/628 2411/1/2411 +f 627/1/627 628/1/628 2408/1/2408 +f 2407/1/2407 627/1/627 2408/1/2408 +f 2407/1/2407 2408/1/2408 2405/1/2405 +f 2406/1/2406 2407/1/2407 2405/1/2405 +f 2406/1/2406 2405/1/2405 2404/1/2404 +f 2409/1/2409 2407/1/2407 2406/1/2406 +f 2019/1/2019 2409/1/2409 2406/1/2406 +f 2021/1/2021 2409/1/2409 2019/1/2019 +f 2021/1/2021 2410/1/2410 2409/1/2409 +f 2410/1/2410 626/1/626 2409/1/2409 +f 2410/1/2410 622/1/622 626/1/626 +f 622/1/622 621/1/621 626/1/626 +f 621/1/621 624/1/624 626/1/626 +f 626/1/626 624/1/624 627/1/627 +f 624/1/624 625/1/625 627/1/627 +f 624/1/624 623/1/623 625/1/625 +f 623/1/623 558/1/558 625/1/625 +f 625/1/625 558/1/558 559/1/559 +f 625/1/625 559/1/559 628/1/628 +f 558/1/558 557/1/557 559/1/559 +f 559/1/559 557/1/557 561/1/561 +f 561/1/561 557/1/557 553/1/553 +f 558/1/558 560/1/560 557/1/557 +f 560/1/560 545/1/545 557/1/557 +f 557/1/557 545/1/545 443/1/443 +f 545/1/545 439/1/439 443/1/443 +f 443/1/443 439/1/439 436/1/436 +f 439/1/439 440/1/440 436/1/436 +f 436/1/436 440/1/440 437/1/437 +f 436/1/436 437/1/437 438/1/438 +f 440/1/440 542/1/542 437/1/437 +f 542/1/542 530/1/530 437/1/437 +f 437/1/437 530/1/530 526/1/526 +f 441/1/441 437/1/437 526/1/526 +f 529/1/529 526/1/526 530/1/530 +f 529/1/529 530/1/530 532/1/532 +f 532/1/532 531/1/531 529/1/529 +f 529/1/529 531/1/531 518/1/518 +f 529/1/529 518/1/518 525/1/525 +f 533/1/533 531/1/531 532/1/532 +f 535/1/535 531/1/531 533/1/533 +f 533/1/533 534/1/534 535/1/535 +f 535/1/535 534/1/534 536/1/536 +f 536/1/536 2002/1/2002 535/1/535 +f 2009/1/2009 2002/1/2002 536/1/536 +f 536/1/536 537/1/537 2009/1/2009 +f 2009/1/2009 537/1/537 2005/1/2005 +f 2005/1/2005 537/1/537 2006/1/2006 +f 2005/1/2005 2006/1/2006 2004/1/2004 +f 2004/1/2004 2000/1/2000 2005/1/2005 +f 2005/1/2005 2000/1/2000 2002/1/2002 +f 2000/1/2000 1999/1/1999 2002/1/2002 +f 2002/1/2002 1999/1/1999 2003/1/2003 +f 2002/1/2002 2003/1/2003 531/1/531 +f 531/1/531 2003/1/2003 2016/1/2016 +f 2003/1/2003 2017/1/2017 2016/1/2016 +f 2003/1/2003 2001/1/2001 2017/1/2017 +f 2001/1/2001 2021/1/2021 2017/1/2017 +f 2001/1/2001 616/1/616 2021/1/2021 +f 616/1/616 620/1/620 2021/1/2021 +f 616/1/616 617/1/617 620/1/620 +f 617/1/617 619/1/619 620/1/620 +f 620/1/620 619/1/619 622/1/622 +f 617/1/617 618/1/618 619/1/619 +f 618/1/618 572/1/572 619/1/619 +f 619/1/619 572/1/572 621/1/621 +f 572/1/572 570/1/570 621/1/621 +f 621/1/621 570/1/570 623/1/623 +f 572/1/572 569/1/569 570/1/570 +f 569/1/569 563/1/563 570/1/570 +f 570/1/570 563/1/563 558/1/558 +f 569/1/569 568/1/568 563/1/563 +f 568/1/568 562/1/562 563/1/563 +f 563/1/563 562/1/562 560/1/560 +f 562/1/562 546/1/546 560/1/560 +f 562/1/562 565/1/565 546/1/546 +f 565/1/565 564/1/564 546/1/546 +f 546/1/546 564/1/564 543/1/543 +f 546/1/546 543/1/543 545/1/545 +f 564/1/564 544/1/544 543/1/543 +f 543/1/543 544/1/544 540/1/540 +f 543/1/543 540/1/540 439/1/439 +f 439/1/439 540/1/540 538/1/538 +f 540/1/540 541/1/541 538/1/538 +f 541/1/541 537/1/537 538/1/538 +f 538/1/538 537/1/537 539/1/539 +f 538/1/538 539/1/539 440/1/440 +f 539/1/539 537/1/537 534/1/534 +f 539/1/539 534/1/534 542/1/542 +f 544/1/544 541/1/541 540/1/540 +f 544/1/544 2011/1/2011 541/1/541 +f 2011/1/2011 2007/1/2007 541/1/541 +f 541/1/541 2007/1/2007 2006/1/2006 +f 2011/1/2011 2010/1/2010 2007/1/2007 +f 2007/1/2007 2010/1/2010 2008/1/2008 +f 2004/1/2004 2007/1/2007 2008/1/2008 +f 2008/1/2008 1996/1/1996 2004/1/2004 +f 2015/1/2015 1996/1/1996 2008/1/2008 +f 1991/1/1991 1996/1/1996 2015/1/2015 +f 2015/1/2015 1992/1/1992 1991/1/1991 +f 1991/1/1991 1992/1/1992 1989/1/1989 +f 1991/1/1991 1989/1/1989 1993/1/1993 +f 1993/1/1993 1994/1/1994 1991/1/1991 +f 1988/1/1988 1994/1/1994 1993/1/1993 +f 1990/1/1990 1994/1/1994 1988/1/1988 +f 1988/1/1988 1986/1/1986 1990/1/1990 +f 1990/1/1990 1986/1/1986 1987/1/1987 +f 1987/1/1987 1957/1/1957 1990/1/1990 +f 1964/1/1964 1957/1/1957 1987/1/1987 +f 1987/1/1987 1965/1/1965 1964/1/1964 +f 1964/1/1964 1965/1/1965 1960/1/1960 +f 1960/1/1960 1965/1/1965 1961/1/1961 +f 1960/1/1960 1961/1/1961 1959/1/1959 +f 1959/1/1959 1955/1/1955 1960/1/1960 +f 1960/1/1960 1955/1/1955 1957/1/1957 +f 1955/1/1955 1956/1/1956 1957/1/1957 +f 1957/1/1957 1956/1/1956 1958/1/1958 +f 1957/1/1957 1958/1/1958 1994/1/1994 +f 1994/1/1994 1958/1/1958 1995/1/1995 +f 1994/1/1994 1995/1/1995 1996/1/1996 +f 1996/1/1996 1995/1/1995 1997/1/1997 +f 1996/1/1996 1997/1/1997 2000/1/2000 +f 1995/1/1995 608/1/608 1997/1/1997 +f 1997/1/1997 608/1/608 1998/1/1998 +f 1997/1/1997 1998/1/1998 1999/1/1999 +f 1999/1/1999 1998/1/1998 2001/1/2001 +f 608/1/608 612/1/612 1998/1/1998 +f 1998/1/1998 612/1/612 616/1/616 +f 612/1/612 613/1/613 616/1/616 +f 612/1/612 611/1/611 613/1/613 +f 611/1/611 614/1/614 613/1/613 +f 613/1/613 614/1/614 615/1/615 +f 613/1/613 615/1/615 618/1/618 +f 615/1/615 573/1/573 618/1/618 +f 574/1/574 573/1/573 615/1/615 +f 574/1/574 571/1/571 573/1/573 +f 573/1/573 571/1/571 569/1/569 +f 574/1/574 575/1/575 571/1/571 +f 575/1/575 566/1/566 571/1/571 +f 571/1/571 566/1/566 568/1/568 +f 577/1/577 566/1/566 575/1/575 +f 576/1/576 577/1/577 575/1/575 +f 579/1/579 577/1/577 576/1/576 +f 581/1/581 579/1/579 576/1/576 +f 581/1/581 576/1/576 582/1/582 +f 609/1/609 581/1/581 582/1/582 +f 609/1/609 582/1/582 611/1/611 +f 610/1/610 609/1/609 611/1/611 +f 605/1/605 609/1/609 610/1/610 +f 608/1/608 605/1/605 610/1/610 +f 606/1/606 605/1/605 608/1/608 +f 606/1/606 604/1/604 605/1/605 +f 604/1/604 601/1/601 605/1/605 +f 605/1/605 601/1/601 603/1/603 +f 601/1/601 602/1/602 603/1/603 +f 603/1/603 602/1/602 581/1/581 +f 602/1/602 583/1/583 581/1/581 +f 598/1/598 583/1/583 602/1/602 +f 598/1/598 590/1/590 583/1/583 +f 590/1/590 584/1/584 583/1/583 +f 583/1/583 584/1/584 580/1/580 +f 583/1/583 580/1/580 579/1/579 +f 584/1/584 585/1/585 580/1/580 +f 580/1/580 585/1/585 578/1/578 +f 580/1/580 578/1/578 577/1/577 +f 585/1/585 567/1/567 578/1/578 +f 578/1/578 567/1/567 566/1/566 +f 566/1/566 567/1/567 562/1/562 +f 585/1/585 587/1/587 567/1/567 +f 587/1/587 586/1/586 567/1/567 +f 567/1/567 586/1/586 565/1/565 +f 586/1/586 2014/1/2014 565/1/565 +f 586/1/586 1983/1/1983 2014/1/2014 +f 1983/1/1983 1985/1/1985 2014/1/2014 +f 2014/1/2014 1985/1/1985 2013/1/2013 +f 2014/1/2014 2013/1/2013 564/1/564 +f 564/1/564 2013/1/2013 2012/1/2012 +f 2012/1/2012 2013/1/2013 2011/1/2011 +f 2013/1/2013 1985/1/1985 1992/1/1992 +f 2013/1/2013 1992/1/1992 2010/1/2010 +f 1983/1/1983 1981/1/1981 1985/1/1985 +f 1981/1/1981 1984/1/1984 1985/1/1985 +f 1984/1/1984 1989/1/1989 1985/1/1985 +f 1984/1/1984 1986/1/1986 1989/1/1989 +f 1982/1/1982 1986/1/1986 1984/1/1984 +f 1982/1/1982 1965/1/1965 1986/1/1986 +f 1980/1/1980 1965/1/1965 1982/1/1982 +f 1980/1/1980 1982/1/1982 1981/1/1981 +f 1979/1/1979 1980/1/1980 1981/1/1981 +f 1979/1/1979 1978/1/1978 1980/1/1980 +f 1978/1/1978 1966/1/1966 1980/1/1980 +f 1973/1/1973 1966/1/1966 1978/1/1978 +f 1977/1/1977 1973/1/1973 1978/1/1978 +f 1974/1/1974 1973/1/1973 1977/1/1977 +f 1460/1/1460 1974/1/1974 1977/1/1977 +f 1460/1/1460 1977/1/1977 1474/1/1474 +f 1458/1/1458 1460/1/1460 1474/1/1474 +f 1458/1/1458 1474/1/1474 587/1/587 +f 593/1/593 1458/1/1458 587/1/587 +f 593/1/593 587/1/587 588/1/588 +f 592/1/592 593/1/593 588/1/588 +f 592/1/592 588/1/588 589/1/589 +f 591/1/591 592/1/592 589/1/589 +f 591/1/591 589/1/589 590/1/590 +f 597/1/597 591/1/591 590/1/590 +f 596/1/596 591/1/591 597/1/597 +f 599/1/599 596/1/596 597/1/597 +f 599/1/599 597/1/597 600/1/600 +f 604/1/604 599/1/599 600/1/600 +f 607/1/607 599/1/599 604/1/604 +f 607/1/607 633/1/633 599/1/599 +f 607/1/607 632/1/632 633/1/633 +f 632/1/632 1472/1/1472 633/1/633 +f 633/1/633 1472/1/1472 596/1/596 +f 1472/1/1472 1471/1/1471 596/1/596 +f 1471/1/1471 594/1/594 596/1/596 +f 1471/1/1471 595/1/595 594/1/594 +f 594/1/594 595/1/595 592/1/592 +f 1471/1/1471 1473/1/1473 595/1/595 +f 1473/1/1473 593/1/593 595/1/595 +f 1473/1/1473 1457/1/1457 593/1/593 +f 1462/1/1462 1457/1/1457 1473/1/1473 +f 1469/1/1469 1462/1/1462 1473/1/1473 +f 1463/1/1463 1462/1/1462 1469/1/1469 +f 1468/1/1468 1463/1/1463 1469/1/1469 +f 1468/1/1468 1469/1/1469 1470/1/1470 +f 635/1/635 1468/1/1468 1470/1/1470 +f 635/1/635 1470/1/1470 632/1/632 +f 631/1/631 635/1/635 632/1/632 +f 631/1/631 634/1/634 635/1/635 +f 636/1/636 634/1/634 631/1/631 +f 630/1/630 636/1/636 631/1/631 +f 630/1/630 631/1/631 629/1/629 +f 1956/1/1956 630/1/630 629/1/629 +f 1954/1/1954 630/1/630 1956/1/1956 +f 1954/1/1954 637/1/637 630/1/630 +f 1952/1/1952 637/1/637 1954/1/1954 +f 1953/1/1953 1952/1/1952 1954/1/1954 +f 1953/1/1953 1954/1/1954 1955/1/1955 +f 1951/1/1951 1952/1/1952 1953/1/1953 +f 2426/1/2426 1951/1/1951 1953/1/1953 +f 2426/1/2426 1953/1/1953 1969/1/1969 +f 1969/1/1969 1970/1/1970 2426/1/2426 +f 2426/1/2426 1970/1/1970 2423/1/2423 +f 2426/1/2426 2423/1/2423 2427/1/2427 +f 2427/1/2427 2423/1/2423 2428/1/2428 +f 2428/1/2428 1951/1/1951 2427/1/2427 +f 2429/1/2429 1951/1/1951 2428/1/2428 +f 2428/1/2428 2425/1/2425 2429/1/2429 +f 2429/1/2429 2425/1/2425 1450/1/1450 +f 1450/1/1450 1446/1/1446 2429/1/2429 +f 1449/1/1449 1446/1/1446 1450/1/1450 +f 1450/1/1450 685/1/685 1449/1/1449 +f 1449/1/1449 685/1/685 688/1/688 +f 688/1/688 685/1/685 687/1/687 +f 688/1/688 687/1/687 689/1/689 +f 689/1/689 1445/1/1445 688/1/688 +f 688/1/688 1445/1/1445 1446/1/1446 +f 1445/1/1445 1447/1/1447 1446/1/1446 +f 1446/1/1446 1447/1/1447 1451/1/1451 +f 1446/1/1446 1451/1/1451 1951/1/1951 +f 1447/1/1447 1919/1/1919 1451/1/1451 +f 1451/1/1451 1919/1/1919 644/1/644 +f 1451/1/1451 644/1/644 1952/1/1952 +f 1919/1/1919 650/1/650 644/1/644 +f 644/1/644 650/1/650 643/1/643 +f 644/1/644 643/1/643 638/1/638 +f 644/1/644 638/1/638 637/1/637 +f 637/1/637 638/1/638 636/1/636 +f 638/1/638 639/1/639 636/1/636 +f 636/1/636 639/1/639 640/1/640 +f 639/1/639 1466/1/1466 640/1/640 +f 640/1/640 1466/1/1466 1467/1/1467 +f 640/1/640 1467/1/1467 634/1/634 +f 634/1/634 1467/1/1467 1465/1/1465 +f 634/1/634 1465/1/1465 1468/1/1468 +f 1467/1/1467 1464/1/1464 1465/1/1465 +f 1464/1/1464 1463/1/1463 1465/1/1465 +f 1464/1/1464 1461/1/1461 1463/1/1463 +f 1464/1/1464 661/1/661 1461/1/1461 +f 661/1/661 660/1/660 1461/1/1461 +f 1461/1/1461 660/1/660 1459/1/1459 +f 1461/1/1461 1459/1/1459 1462/1/1462 +f 660/1/660 667/1/667 1459/1/1459 +f 1459/1/1459 667/1/667 1457/1/1457 +f 1457/1/1457 667/1/667 1458/1/1458 +f 660/1/660 663/1/663 667/1/667 +f 663/1/663 666/1/666 667/1/667 +f 667/1/667 666/1/666 1460/1/1460 +f 663/1/663 665/1/665 666/1/666 +f 665/1/665 1975/1/1975 666/1/666 +f 666/1/666 1975/1/1975 1974/1/1974 +f 1975/1/1975 1971/1/1971 1974/1/1974 +f 1974/1/1974 1971/1/1971 1972/1/1972 +f 1972/1/1972 1971/1/1971 1967/1/1967 +f 1972/1/1972 1967/1/1967 1973/1/1973 +f 1971/1/1971 1968/1/1968 1967/1/1967 +f 1967/1/1967 1968/1/1968 1962/1/1962 +f 1967/1/1967 1962/1/1962 1966/1/1966 +f 1966/1/1966 1962/1/1962 1961/1/1961 +f 1962/1/1962 1968/1/1968 1963/1/1963 +f 1959/1/1959 1962/1/1962 1963/1/1963 +f 1963/1/1963 1953/1/1953 1959/1/1959 +f 1963/1/1963 1968/1/1968 1969/1/1969 +f 1971/1/1971 1970/1/1970 1968/1/1968 +f 1971/1/1971 1976/1/1976 1970/1/1970 +f 1975/1/1975 1976/1/1976 1971/1/1971 +f 2420/1/2420 1976/1/1976 1975/1/1975 +f 2420/1/2420 2421/1/2421 1976/1/1976 +f 2421/1/2421 2422/1/2422 1976/1/1976 +f 2422/1/2422 2423/1/2423 1976/1/1976 +f 2422/1/2422 2425/1/2425 2423/1/2423 +f 2424/1/2424 2425/1/2425 2422/1/2422 +f 2424/1/2424 685/1/685 2425/1/2425 +f 684/1/684 685/1/685 2424/1/2424 +f 684/1/684 2424/1/2424 2421/1/2421 +f 675/1/675 684/1/684 2421/1/2421 +f 675/1/675 680/1/680 684/1/684 +f 680/1/680 683/1/683 684/1/684 +f 679/1/679 683/1/683 680/1/680 +f 674/1/674 679/1/679 680/1/680 +f 677/1/677 679/1/679 674/1/674 +f 676/1/676 677/1/677 674/1/674 +f 676/1/676 674/1/674 670/1/670 +f 669/1/669 676/1/676 670/1/670 +f 669/1/669 670/1/670 664/1/664 +f 671/1/671 669/1/669 664/1/664 +f 671/1/671 664/1/664 668/1/668 +f 672/1/672 671/1/671 668/1/668 +f 672/1/672 668/1/668 673/1/673 +f 1475/1/1475 672/1/672 673/1/673 +f 1475/1/1475 673/1/673 652/1/652 +f 651/1/651 1475/1/1475 652/1/652 +f 651/1/651 652/1/652 647/1/647 +f 648/1/648 651/1/651 647/1/647 +f 648/1/648 647/1/647 642/1/642 +f 643/1/643 648/1/648 642/1/642 +f 643/1/643 649/1/649 648/1/648 +f 642/1/642 647/1/647 645/1/645 +f 642/1/642 645/1/645 641/1/641 +f 638/1/638 642/1/642 641/1/641 +f 641/1/641 645/1/645 646/1/646 +f 641/1/641 646/1/646 639/1/639 +f 645/1/645 653/1/653 646/1/646 +f 653/1/653 655/1/655 646/1/646 +f 646/1/646 655/1/655 659/1/659 +f 646/1/646 659/1/659 1466/1/1466 +f 1466/1/1466 659/1/659 1464/1/1464 +f 655/1/655 658/1/658 659/1/659 +f 659/1/659 658/1/658 661/1/661 +f 655/1/655 654/1/654 658/1/658 +f 654/1/654 657/1/657 658/1/658 +f 658/1/658 657/1/657 660/1/660 +f 654/1/654 662/1/662 657/1/657 +f 662/1/662 663/1/663 657/1/657 +f 662/1/662 664/1/664 663/1/663 +f 656/1/656 662/1/662 654/1/654 +f 653/1/653 656/1/656 654/1/654 +f 652/1/652 656/1/656 653/1/653 +f 673/1/673 662/1/662 656/1/656 +f 653/1/653 654/1/654 655/1/655 +f 647/1/647 653/1/653 645/1/645 +f 649/1/649 651/1/651 648/1/648 +f 649/1/649 1477/1/1477 651/1/651 +f 1478/1/1478 1477/1/1477 649/1/649 +f 650/1/650 1478/1/1478 649/1/649 +f 650/1/650 1916/1/1916 1478/1/1478 +f 1916/1/1916 1915/1/1915 1478/1/1478 +f 1916/1/1916 1909/1/1909 1915/1/1915 +f 1909/1/1909 1910/1/1910 1915/1/1915 +f 1915/1/1915 1910/1/1910 1477/1/1477 +f 1910/1/1910 1476/1/1476 1477/1/1477 +f 1477/1/1477 1476/1/1476 1475/1/1475 +f 1910/1/1910 1912/1/1912 1476/1/1476 +f 1476/1/1476 1912/1/1912 672/1/672 +f 1910/1/1910 1908/1/1908 1912/1/1912 +f 1908/1/1908 671/1/671 1912/1/1912 +f 1908/1/1908 1911/1/1911 671/1/671 +f 1905/1/1905 1911/1/1911 1908/1/1908 +f 1906/1/1906 1905/1/1905 1908/1/1908 +f 1901/1/1901 1905/1/1905 1906/1/1906 +f 1907/1/1907 1901/1/1901 1906/1/1906 +f 1907/1/1907 1906/1/1906 1909/1/1909 +f 1917/1/1917 1907/1/1907 1909/1/1909 +f 1922/1/1922 1907/1/1907 1917/1/1917 +f 1918/1/1918 1922/1/1922 1917/1/1917 +f 1918/1/1918 1917/1/1917 1916/1/1916 +f 1921/1/1921 1922/1/1922 1918/1/1918 +f 1920/1/1920 1921/1/1921 1918/1/1918 +f 1920/1/1920 1918/1/1918 1919/1/1919 +f 1923/1/1923 1921/1/1921 1920/1/1920 +f 1448/1/1448 1923/1/1923 1920/1/1920 +f 1448/1/1448 1920/1/1920 1447/1/1447 +f 1452/1/1452 1923/1/1923 1448/1/1448 +f 1443/1/1443 1452/1/1452 1448/1/1448 +f 1443/1/1443 1448/1/1448 1445/1/1445 +f 1437/1/1437 1452/1/1452 1443/1/1443 +f 1442/1/1442 1437/1/1437 1443/1/1443 +f 1442/1/1442 1443/1/1443 694/1/694 +f 694/1/694 693/1/693 1442/1/1442 +f 1442/1/1442 693/1/693 696/1/696 +f 1442/1/1442 696/1/696 1441/1/1441 +f 1441/1/1441 696/1/696 1440/1/1440 +f 1440/1/1440 1437/1/1437 1441/1/1441 +f 1438/1/1438 1437/1/1437 1440/1/1440 +f 1440/1/1440 1439/1/1439 1438/1/1438 +f 1438/1/1438 1439/1/1439 1436/1/1436 +f 1436/1/1436 1433/1/1433 1438/1/1438 +f 1435/1/1435 1433/1/1433 1436/1/1436 +f 1436/1/1436 720/1/720 1435/1/1435 +f 1435/1/1435 720/1/720 724/1/724 +f 724/1/724 720/1/720 721/1/721 +f 724/1/724 721/1/721 722/1/722 +f 722/1/722 726/1/726 724/1/724 +f 724/1/724 726/1/726 1433/1/1433 +f 726/1/726 1432/1/1432 1433/1/1433 +f 1433/1/1433 1432/1/1432 1434/1/1434 +f 1433/1/1433 1434/1/1434 1437/1/1437 +f 1432/1/1432 1925/1/1925 1434/1/1434 +f 1434/1/1434 1925/1/1925 1884/1/1884 +f 1434/1/1434 1884/1/1884 1452/1/1452 +f 1925/1/1925 1877/1/1877 1884/1/1884 +f 1884/1/1884 1877/1/1877 1879/1/1879 +f 1884/1/1884 1879/1/1879 1883/1/1883 +f 1884/1/1884 1883/1/1883 1923/1/1923 +f 1923/1/1923 1883/1/1883 1924/1/1924 +f 1883/1/1883 1889/1/1889 1924/1/1924 +f 1924/1/1924 1889/1/1889 1898/1/1898 +f 1924/1/1924 1898/1/1898 1921/1/1921 +f 1889/1/1889 1892/1/1892 1898/1/1898 +f 1898/1/1898 1892/1/1892 1899/1/1899 +f 1898/1/1898 1899/1/1899 1922/1/1922 +f 1922/1/1922 1899/1/1899 1902/1/1902 +f 1899/1/1899 1897/1/1897 1902/1/1902 +f 1897/1/1897 1901/1/1901 1902/1/1902 +f 1897/1/1897 1900/1/1900 1901/1/1901 +f 1897/1/1897 1896/1/1896 1900/1/1900 +f 1896/1/1896 1903/1/1903 1900/1/1900 +f 1900/1/1900 1903/1/1903 1904/1/1904 +f 1900/1/1900 1904/1/1904 1905/1/1905 +f 1903/1/1903 1456/1/1456 1904/1/1904 +f 1904/1/1904 1456/1/1456 1911/1/1911 +f 1911/1/1911 1456/1/1456 669/1/669 +f 1903/1/1903 1453/1/1453 1456/1/1456 +f 1453/1/1453 678/1/678 1456/1/1456 +f 1456/1/1456 678/1/678 676/1/676 +f 1453/1/1453 701/1/701 678/1/678 +f 701/1/701 697/1/697 678/1/678 +f 678/1/678 697/1/697 677/1/677 +f 697/1/697 692/1/692 677/1/677 +f 677/1/677 692/1/692 681/1/681 +f 681/1/681 692/1/692 682/1/682 +f 681/1/681 682/1/682 679/1/679 +f 692/1/692 690/1/690 682/1/682 +f 682/1/682 690/1/690 686/1/686 +f 682/1/682 686/1/686 683/1/683 +f 683/1/683 686/1/686 687/1/687 +f 686/1/686 690/1/690 691/1/691 +f 689/1/689 686/1/686 691/1/691 +f 691/1/691 1443/1/1443 689/1/689 +f 691/1/691 690/1/690 694/1/694 +f 692/1/692 693/1/693 690/1/690 +f 692/1/692 695/1/695 693/1/693 +f 697/1/697 695/1/695 692/1/692 +f 700/1/700 695/1/695 697/1/697 +f 700/1/700 698/1/698 695/1/695 +f 698/1/698 699/1/699 695/1/695 +f 699/1/699 696/1/696 695/1/695 +f 699/1/699 1439/1/1439 696/1/696 +f 1444/1/1444 1439/1/1439 699/1/699 +f 1444/1/1444 720/1/720 1439/1/1439 +f 705/1/705 720/1/720 1444/1/1444 +f 705/1/705 1444/1/1444 698/1/698 +f 702/1/702 705/1/705 698/1/698 +f 702/1/702 704/1/704 705/1/705 +f 704/1/704 717/1/717 705/1/705 +f 711/1/711 717/1/717 704/1/704 +f 706/1/706 711/1/711 704/1/704 +f 710/1/710 711/1/711 706/1/706 +f 707/1/707 710/1/710 706/1/706 +f 707/1/707 706/1/706 703/1/703 +f 708/1/708 707/1/707 703/1/703 +f 708/1/708 703/1/703 709/1/709 +f 1863/1/1863 708/1/708 709/1/709 +f 1863/1/1863 709/1/709 1454/1/1454 +f 1871/1/1871 1863/1/1863 1454/1/1454 +f 1871/1/1871 1454/1/1454 1914/1/1914 +f 1872/1/1872 1871/1/1871 1914/1/1914 +f 1872/1/1872 1914/1/1914 1881/1/1881 +f 1875/1/1875 1872/1/1872 1881/1/1881 +f 1875/1/1875 1881/1/1881 1880/1/1880 +f 1878/1/1878 1875/1/1875 1880/1/1880 +f 1878/1/1878 1880/1/1880 1882/1/1882 +f 1879/1/1879 1878/1/1878 1882/1/1882 +f 1879/1/1879 1874/1/1874 1878/1/1878 +f 1882/1/1882 1880/1/1880 1885/1/1885 +f 1882/1/1882 1885/1/1885 1886/1/1886 +f 1883/1/1883 1882/1/1882 1886/1/1886 +f 1886/1/1886 1885/1/1885 1888/1/1888 +f 1886/1/1886 1888/1/1888 1889/1/1889 +f 1885/1/1885 1887/1/1887 1888/1/1888 +f 1887/1/1887 1890/1/1890 1888/1/1888 +f 1888/1/1888 1890/1/1890 1891/1/1891 +f 1888/1/1888 1891/1/1891 1892/1/1892 +f 1892/1/1892 1891/1/1891 1897/1/1897 +f 1890/1/1890 1895/1/1895 1891/1/1891 +f 1891/1/1891 1895/1/1895 1896/1/1896 +f 1890/1/1890 1894/1/1894 1895/1/1895 +f 1894/1/1894 1913/1/1913 1895/1/1895 +f 1895/1/1895 1913/1/1913 1903/1/1903 +f 1894/1/1894 1455/1/1455 1913/1/1913 +f 1455/1/1455 1453/1/1453 1913/1/1913 +f 1455/1/1455 709/1/709 1453/1/1453 +f 1893/1/1893 1455/1/1455 1894/1/1894 +f 1887/1/1887 1893/1/1893 1894/1/1894 +f 1881/1/1881 1893/1/1893 1887/1/1887 +f 1914/1/1914 1455/1/1455 1893/1/1893 +f 1887/1/1887 1894/1/1894 1890/1/1890 +f 1880/1/1880 1887/1/1887 1885/1/1885 +f 1874/1/1874 1875/1/1875 1878/1/1878 +f 1874/1/1874 1869/1/1869 1875/1/1875 +f 1873/1/1873 1869/1/1869 1874/1/1874 +f 1877/1/1877 1873/1/1873 1874/1/1874 +f 1877/1/1877 1876/1/1876 1873/1/1873 +f 1876/1/1876 1870/1/1870 1873/1/1873 +f 1876/1/1876 1867/1/1867 1870/1/1870 +f 1867/1/1867 1864/1/1864 1870/1/1870 +f 1870/1/1870 1864/1/1864 1869/1/1869 +f 1864/1/1864 1868/1/1868 1869/1/1869 +f 1869/1/1869 1868/1/1868 1872/1/1872 +f 1864/1/1864 1865/1/1865 1868/1/1868 +f 1868/1/1868 1865/1/1865 1871/1/1871 +f 1864/1/1864 1862/1/1862 1865/1/1865 +f 1862/1/1862 1863/1/1863 1865/1/1865 +f 1862/1/1862 773/1/773 1863/1/1863 +f 1859/1/1859 773/1/773 1862/1/1862 +f 1861/1/1861 1859/1/1859 1862/1/1862 +f 1860/1/1860 1859/1/1859 1861/1/1861 +f 1866/1/1866 1860/1/1860 1861/1/1861 +f 1866/1/1866 1861/1/1861 1867/1/1867 +f 1929/1/1929 1866/1/1866 1867/1/1867 +f 1928/1/1928 1866/1/1866 1929/1/1929 +f 1927/1/1927 1928/1/1928 1929/1/1929 +f 1927/1/1927 1929/1/1929 1876/1/1876 +f 1930/1/1930 1928/1/1928 1927/1/1927 +f 1926/1/1926 1930/1/1930 1927/1/1927 +f 1926/1/1926 1927/1/1927 1925/1/1925 +f 1935/1/1935 1930/1/1930 1926/1/1926 +f 730/1/730 1935/1/1935 1926/1/1926 +f 730/1/730 1926/1/1926 1432/1/1432 +f 729/1/729 1935/1/1935 730/1/730 +f 725/1/725 729/1/729 730/1/730 +f 725/1/725 730/1/730 726/1/726 +f 728/1/728 729/1/729 725/1/725 +f 731/1/731 728/1/728 725/1/725 +f 731/1/731 725/1/725 727/1/727 +f 727/1/727 732/1/732 731/1/731 +f 731/1/731 732/1/732 734/1/734 +f 731/1/731 734/1/734 733/1/733 +f 733/1/733 734/1/734 737/1/737 +f 737/1/737 728/1/728 733/1/733 +f 735/1/735 728/1/728 737/1/737 +f 737/1/737 739/1/739 735/1/735 +f 735/1/735 739/1/739 738/1/738 +f 738/1/738 736/1/736 735/1/735 +f 1950/1/1950 736/1/736 738/1/738 +f 738/1/738 744/1/744 1950/1/1950 +f 1950/1/1950 744/1/744 751/1/751 +f 751/1/751 744/1/744 750/1/750 +f 751/1/751 750/1/750 1937/1/1937 +f 1937/1/1937 1827/1/1827 751/1/751 +f 751/1/751 1827/1/1827 736/1/736 +f 1827/1/1827 1829/1/1829 736/1/736 +f 736/1/736 1829/1/1829 1936/1/1936 +f 736/1/736 1936/1/1936 728/1/728 +f 1829/1/1829 1833/1/1833 1936/1/1936 +f 1936/1/1936 1833/1/1833 1844/1/1844 +f 1936/1/1936 1844/1/1844 729/1/729 +f 1833/1/1833 1832/1/1832 1844/1/1844 +f 1844/1/1844 1832/1/1832 1839/1/1839 +f 1844/1/1844 1839/1/1839 1845/1/1845 +f 1844/1/1844 1845/1/1845 1935/1/1935 +f 1839/1/1839 1843/1/1843 1845/1/1845 +f 1845/1/1845 1843/1/1843 1847/1/1847 +f 1845/1/1845 1847/1/1847 1850/1/1850 +f 1845/1/1845 1850/1/1850 1930/1/1930 +f 1930/1/1930 1850/1/1850 1934/1/1934 +f 1850/1/1850 1852/1/1852 1934/1/1934 +f 1934/1/1934 1852/1/1852 1932/1/1932 +f 1934/1/1934 1932/1/1932 1928/1/1928 +f 1928/1/1928 1932/1/1932 1931/1/1931 +f 1932/1/1932 1933/1/1933 1931/1/1931 +f 1933/1/1933 1860/1/1860 1931/1/1931 +f 1933/1/1933 1857/1/1857 1860/1/1860 +f 1933/1/1933 1858/1/1858 1857/1/1857 +f 1858/1/1858 770/1/770 1857/1/1857 +f 1857/1/1857 770/1/770 772/1/772 +f 1857/1/1857 772/1/772 1859/1/1859 +f 770/1/770 771/1/771 772/1/772 +f 772/1/772 771/1/771 773/1/773 +f 773/1/773 771/1/771 708/1/708 +f 770/1/770 766/1/766 771/1/771 +f 766/1/766 714/1/714 771/1/771 +f 771/1/771 714/1/714 707/1/707 +f 766/1/766 755/1/755 714/1/714 +f 755/1/755 715/1/715 714/1/714 +f 714/1/714 715/1/715 710/1/710 +f 715/1/715 712/1/712 710/1/710 +f 710/1/710 712/1/712 713/1/713 +f 713/1/713 712/1/712 716/1/716 +f 713/1/713 716/1/716 711/1/711 +f 712/1/712 718/1/718 716/1/716 +f 716/1/716 718/1/718 719/1/719 +f 716/1/716 719/1/719 717/1/717 +f 717/1/717 719/1/719 721/1/721 +f 719/1/719 718/1/718 723/1/723 +f 722/1/722 719/1/719 723/1/723 +f 723/1/723 725/1/725 722/1/722 +f 723/1/723 718/1/718 727/1/727 +f 712/1/712 732/1/732 718/1/718 +f 712/1/712 740/1/740 732/1/732 +f 715/1/715 740/1/740 712/1/712 +f 746/1/746 740/1/740 715/1/715 +f 746/1/746 743/1/743 740/1/740 +f 743/1/743 741/1/741 740/1/740 +f 741/1/741 734/1/734 740/1/740 +f 741/1/741 739/1/739 734/1/734 +f 742/1/742 739/1/739 741/1/741 +f 742/1/742 744/1/744 739/1/739 +f 745/1/745 744/1/744 742/1/742 +f 745/1/745 742/1/742 743/1/743 +f 747/1/747 745/1/745 743/1/743 +f 747/1/747 749/1/749 745/1/745 +f 749/1/749 748/1/748 745/1/745 +f 752/1/752 748/1/748 749/1/749 +f 754/1/754 752/1/752 749/1/749 +f 760/1/760 752/1/752 754/1/754 +f 758/1/758 760/1/760 754/1/754 +f 758/1/758 754/1/754 756/1/756 +f 757/1/757 758/1/758 756/1/756 +f 757/1/757 756/1/756 759/1/759 +f 763/1/763 757/1/757 759/1/759 +f 763/1/763 759/1/759 764/1/764 +f 767/1/767 763/1/763 764/1/764 +f 767/1/767 764/1/764 768/1/768 +f 1837/1/1837 767/1/767 768/1/768 +f 1837/1/1837 768/1/768 1842/1/1842 +f 1838/1/1838 1837/1/1837 1842/1/1842 +f 1838/1/1838 1842/1/1842 1841/1/1841 +f 1840/1/1840 1838/1/1838 1841/1/1841 +f 1840/1/1840 1841/1/1841 1843/1/1843 +f 1843/1/1843 1841/1/1841 1846/1/1846 +f 1841/1/1841 1848/1/1848 1846/1/1846 +f 1846/1/1846 1848/1/1848 1849/1/1849 +f 1847/1/1847 1846/1/1846 1849/1/1849 +f 1848/1/1848 1853/1/1853 1849/1/1849 +f 1849/1/1849 1853/1/1853 1851/1/1851 +f 1849/1/1849 1851/1/1851 1852/1/1852 +f 1852/1/1852 1851/1/1851 1933/1/1933 +f 1853/1/1853 1856/1/1856 1851/1/1851 +f 1851/1/1851 1856/1/1856 1858/1/1858 +f 1853/1/1853 1855/1/1855 1856/1/1856 +f 1855/1/1855 769/1/769 1856/1/1856 +f 1856/1/1856 769/1/769 770/1/770 +f 1855/1/1855 765/1/765 769/1/769 +f 765/1/765 766/1/766 769/1/769 +f 765/1/765 759/1/759 766/1/766 +f 1854/1/1854 765/1/765 1855/1/1855 +f 1848/1/1848 1854/1/1854 1855/1/1855 +f 1842/1/1842 1854/1/1854 1848/1/1848 +f 768/1/768 765/1/765 1854/1/1854 +f 1848/1/1848 1855/1/1855 1853/1/1853 +f 1835/1/1835 1838/1/1838 1840/1/1840 +f 1839/1/1839 1835/1/1835 1840/1/1840 +f 1835/1/1835 1836/1/1836 1838/1/1838 +f 1834/1/1834 1836/1/1836 1835/1/1835 +f 1832/1/1832 1834/1/1834 1835/1/1835 +f 1832/1/1832 1831/1/1831 1834/1/1834 +f 1831/1/1831 852/1/852 1834/1/1834 +f 1831/1/1831 851/1/851 852/1/852 +f 851/1/851 778/1/778 852/1/852 +f 852/1/852 778/1/778 1836/1/1836 +f 778/1/778 777/1/777 1836/1/1836 +f 1836/1/1836 777/1/777 1837/1/1837 +f 778/1/778 774/1/774 777/1/777 +f 777/1/777 774/1/774 767/1/767 +f 778/1/778 775/1/775 774/1/774 +f 775/1/775 763/1/763 774/1/774 +f 775/1/775 776/1/776 763/1/763 +f 841/1/841 776/1/776 775/1/775 +f 846/1/846 841/1/841 775/1/775 +f 842/1/842 841/1/841 846/1/846 +f 845/1/845 842/1/842 846/1/846 +f 845/1/845 846/1/846 851/1/851 +f 849/1/849 845/1/845 851/1/851 +f 847/1/847 845/1/845 849/1/849 +f 1830/1/1830 847/1/847 849/1/849 +f 1830/1/1830 849/1/849 1831/1/1831 +f 850/1/850 847/1/847 1830/1/1830 +f 1828/1/1828 850/1/850 1830/1/1830 +f 1828/1/1828 1830/1/1830 1833/1/1833 +f 854/1/854 850/1/850 1828/1/1828 +f 1826/1/1826 854/1/854 1828/1/1828 +f 1826/1/1826 1828/1/1828 1829/1/1829 +f 1824/1/1824 854/1/854 1826/1/1826 +f 1825/1/1825 1824/1/1824 1826/1/1826 +f 1825/1/1825 1826/1/1826 1827/1/1827 +f 1823/1/1823 1824/1/1824 1825/1/1825 +f 1940/1/1940 1823/1/1823 1825/1/1825 +f 1940/1/1940 1825/1/1825 1941/1/1941 +f 1941/1/1941 1780/1/1780 1940/1/1940 +f 1940/1/1940 1780/1/1780 1779/1/1779 +f 1940/1/1940 1779/1/1779 1943/1/1943 +f 1943/1/1943 1779/1/1779 1945/1/1945 +f 1945/1/1945 1823/1/1823 1943/1/1943 +f 1944/1/1944 1823/1/1823 1945/1/1945 +f 1945/1/1945 1786/1/1786 1944/1/1944 +f 1944/1/1944 1786/1/1786 1946/1/1946 +f 1946/1/1946 1821/1/1821 1944/1/1944 +f 1947/1/1947 1821/1/1821 1946/1/1946 +f 1946/1/1946 1948/1/1948 1947/1/1947 +f 1947/1/1947 1948/1/1948 1820/1/1820 +f 1820/1/1820 1948/1/1948 1804/1/1804 +f 1820/1/1820 1804/1/1804 1805/1/1805 +f 1805/1/1805 1818/1/1818 1820/1/1820 +f 1820/1/1820 1818/1/1818 1821/1/1821 +f 1818/1/1818 1819/1/1819 1821/1/1821 +f 1821/1/1821 1819/1/1819 1822/1/1822 +f 1821/1/1821 1822/1/1822 1823/1/1823 +f 1819/1/1819 818/1/818 1822/1/1822 +f 1822/1/1822 818/1/818 819/1/819 +f 1822/1/1822 819/1/819 1824/1/1824 +f 818/1/818 814/1/814 819/1/819 +f 819/1/819 814/1/814 817/1/817 +f 819/1/819 817/1/817 823/1/823 +f 819/1/819 823/1/823 854/1/854 +f 817/1/817 822/1/822 823/1/823 +f 823/1/823 822/1/822 829/1/829 +f 823/1/823 829/1/829 853/1/853 +f 823/1/823 853/1/853 850/1/850 +f 850/1/850 853/1/853 848/1/848 +f 853/1/853 838/1/838 848/1/848 +f 848/1/848 838/1/838 844/1/844 +f 848/1/848 844/1/844 847/1/847 +f 847/1/847 844/1/844 843/1/843 +f 844/1/844 839/1/839 843/1/843 +f 839/1/839 842/1/842 843/1/843 +f 839/1/839 840/1/840 842/1/842 +f 839/1/839 837/1/837 840/1/840 +f 837/1/837 780/1/780 840/1/840 +f 840/1/840 780/1/780 782/1/782 +f 840/1/840 782/1/782 841/1/841 +f 780/1/780 779/1/779 782/1/782 +f 782/1/782 779/1/779 776/1/776 +f 776/1/776 779/1/779 757/1/757 +f 780/1/780 781/1/781 779/1/779 +f 781/1/781 761/1/761 779/1/779 +f 779/1/779 761/1/761 758/1/758 +f 781/1/781 783/1/783 761/1/761 +f 783/1/783 762/1/762 761/1/761 +f 761/1/761 762/1/762 760/1/760 +f 762/1/762 1783/1/1783 760/1/760 +f 760/1/760 1783/1/1783 1949/1/1949 +f 1949/1/1949 1783/1/1783 753/1/753 +f 1949/1/1949 753/1/753 752/1/752 +f 1783/1/1783 1942/1/1942 753/1/753 +f 753/1/753 1942/1/1942 1939/1/1939 +f 753/1/753 1939/1/1939 748/1/748 +f 748/1/748 1939/1/1939 750/1/750 +f 1939/1/1939 1942/1/1942 1938/1/1938 +f 1937/1/1937 1939/1/1939 1938/1/1938 +f 1938/1/1938 1825/1/1825 1937/1/1937 +f 1938/1/1938 1942/1/1942 1941/1/1941 +f 1783/1/1783 1780/1/1780 1942/1/1942 +f 1783/1/1783 1778/1/1778 1780/1/1780 +f 762/1/762 1778/1/1778 1783/1/1783 +f 1784/1/1784 1778/1/1778 762/1/762 +f 1784/1/1784 1782/1/1782 1778/1/1778 +f 1782/1/1782 1781/1/1781 1778/1/1778 +f 1781/1/1781 1779/1/1779 1778/1/1778 +f 1781/1/1781 1786/1/1786 1779/1/1779 +f 1785/1/1785 1786/1/1786 1781/1/1781 +f 1785/1/1785 1948/1/1948 1786/1/1786 +f 1787/1/1787 1948/1/1948 1785/1/1785 +f 1787/1/1787 1785/1/1785 1782/1/1782 +f 1788/1/1788 1787/1/1787 1782/1/1782 +f 1788/1/1788 1790/1/1790 1787/1/1787 +f 1790/1/1790 1793/1/1793 1787/1/1787 +f 1791/1/1791 1793/1/1793 1790/1/1790 +f 1789/1/1789 1791/1/1791 1790/1/1790 +f 1792/1/1792 1791/1/1791 1789/1/1789 +f 791/1/791 1792/1/1792 1789/1/1789 +f 791/1/791 1789/1/1789 787/1/787 +f 790/1/790 791/1/791 787/1/787 +f 790/1/790 787/1/787 784/1/784 +f 788/1/788 790/1/790 784/1/784 +f 788/1/788 784/1/784 789/1/789 +f 855/1/855 788/1/788 789/1/789 +f 855/1/855 789/1/789 834/1/834 +f 825/1/825 855/1/855 834/1/834 +f 825/1/825 834/1/834 826/1/826 +f 821/1/821 825/1/825 826/1/826 +f 821/1/821 826/1/826 824/1/824 +f 820/1/820 821/1/821 824/1/824 +f 820/1/820 824/1/824 822/1/822 +f 822/1/822 824/1/824 828/1/828 +f 824/1/824 827/1/827 828/1/828 +f 828/1/828 827/1/827 830/1/830 +f 829/1/829 828/1/828 830/1/830 +f 827/1/827 832/1/832 830/1/830 +f 830/1/830 832/1/832 836/1/836 +f 830/1/830 836/1/836 838/1/838 +f 838/1/838 836/1/836 839/1/839 +f 832/1/832 835/1/835 836/1/836 +f 836/1/836 835/1/835 837/1/837 +f 832/1/832 831/1/831 835/1/835 +f 831/1/831 785/1/785 835/1/835 +f 835/1/835 785/1/785 780/1/780 +f 831/1/831 786/1/786 785/1/785 +f 786/1/786 781/1/781 785/1/785 +f 786/1/786 784/1/784 781/1/781 +f 833/1/833 786/1/786 831/1/831 +f 827/1/827 833/1/833 831/1/831 +f 826/1/826 833/1/833 827/1/827 +f 834/1/834 786/1/786 833/1/833 +f 827/1/827 831/1/831 832/1/832 +f 816/1/816 821/1/821 820/1/820 +f 817/1/817 816/1/816 820/1/820 +f 816/1/816 815/1/815 821/1/821 +f 813/1/813 815/1/815 816/1/816 +f 814/1/814 813/1/813 816/1/816 +f 814/1/814 810/1/810 813/1/813 +f 810/1/810 811/1/811 813/1/813 +f 810/1/810 806/1/806 811/1/811 +f 806/1/806 803/1/803 811/1/811 +f 811/1/811 803/1/803 815/1/815 +f 803/1/803 856/1/856 815/1/815 +f 815/1/815 856/1/856 825/1/825 +f 803/1/803 804/1/804 856/1/856 +f 856/1/856 804/1/804 855/1/855 +f 803/1/803 799/1/799 804/1/804 +f 799/1/799 788/1/788 804/1/804 +f 799/1/799 792/1/792 788/1/788 +f 798/1/798 792/1/792 799/1/799 +f 802/1/802 798/1/798 799/1/799 +f 801/1/801 798/1/798 802/1/802 +f 805/1/805 801/1/801 802/1/802 +f 805/1/805 802/1/802 806/1/806 +f 807/1/807 805/1/805 806/1/806 +f 808/1/808 805/1/805 807/1/807 +f 812/1/812 808/1/808 807/1/807 +f 812/1/812 807/1/807 810/1/810 +f 858/1/858 808/1/808 812/1/812 +f 857/1/857 858/1/858 812/1/812 +f 857/1/857 812/1/812 818/1/818 +f 859/1/859 858/1/858 857/1/857 +f 1817/1/1817 859/1/859 857/1/857 +f 1817/1/1817 857/1/857 1819/1/1819 +f 1816/1/1816 859/1/859 1817/1/1817 +f 1806/1/1806 1816/1/1816 1817/1/1817 +f 1806/1/1806 1817/1/1817 1818/1/1818 +f 1809/1/1809 1816/1/1816 1806/1/1806 +f 1807/1/1807 1809/1/1809 1806/1/1806 +f 1807/1/1807 1806/1/1806 1803/1/1803 +f 1803/1/1803 1801/1/1801 1807/1/1807 +f 1807/1/1807 1801/1/1801 1808/1/1808 +f 1807/1/1807 1808/1/1808 1810/1/1810 +f 1810/1/1810 1808/1/1808 1811/1/1811 +f 1811/1/1811 1809/1/1809 1810/1/1810 +f 1812/1/1812 1809/1/1809 1811/1/1811 +f 1811/1/1811 1813/1/1813 1812/1/1812 +f 1812/1/1812 1813/1/1813 1814/1/1814 +f 1814/1/1814 1397/1/1397 1812/1/1812 +f 1400/1/1400 1397/1/1397 1814/1/1814 +f 1814/1/1814 1401/1/1401 1400/1/1400 +f 1400/1/1400 1401/1/1401 1396/1/1396 +f 1396/1/1396 1401/1/1401 1398/1/1398 +f 1396/1/1396 1398/1/1398 1393/1/1393 +f 1393/1/1393 1394/1/1394 1396/1/1396 +f 1396/1/1396 1394/1/1394 1397/1/1397 +f 1394/1/1394 1395/1/1395 1397/1/1397 +f 1397/1/1397 1395/1/1395 1815/1/1815 +f 1397/1/1397 1815/1/1815 1809/1/1809 +f 1395/1/1395 1536/1/1536 1815/1/1815 +f 1815/1/1815 1536/1/1536 862/1/862 +f 1815/1/1815 862/1/862 1816/1/1816 +f 1536/1/1536 1428/1/1428 862/1/862 +f 862/1/862 1428/1/1428 1429/1/1429 +f 862/1/862 1429/1/1429 863/1/863 +f 862/1/862 863/1/863 859/1/859 +f 859/1/859 863/1/863 861/1/861 +f 863/1/863 864/1/864 861/1/861 +f 861/1/861 864/1/864 860/1/860 +f 861/1/861 860/1/860 858/1/858 +f 864/1/864 865/1/865 860/1/860 +f 860/1/860 865/1/865 866/1/866 +f 860/1/860 866/1/866 808/1/808 +f 808/1/808 866/1/866 809/1/809 +f 866/1/866 867/1/867 809/1/809 +f 867/1/867 801/1/801 809/1/809 +f 867/1/867 800/1/800 801/1/801 +f 867/1/867 870/1/870 800/1/800 +f 870/1/870 795/1/795 800/1/800 +f 800/1/800 795/1/795 797/1/797 +f 800/1/800 797/1/797 798/1/798 +f 795/1/795 793/1/793 797/1/797 +f 797/1/797 793/1/793 792/1/792 +f 792/1/792 793/1/793 790/1/790 +f 795/1/795 796/1/796 793/1/793 +f 796/1/796 794/1/794 793/1/793 +f 793/1/793 794/1/794 791/1/791 +f 796/1/796 895/1/895 794/1/794 +f 895/1/895 1796/1/1796 794/1/794 +f 794/1/794 1796/1/1796 1792/1/1792 +f 1796/1/1796 1797/1/1797 1792/1/1792 +f 1792/1/1792 1797/1/1797 1794/1/1794 +f 1794/1/1794 1797/1/1797 1795/1/1795 +f 1794/1/1794 1795/1/1795 1791/1/1791 +f 1797/1/1797 1799/1/1799 1795/1/1795 +f 1795/1/1795 1799/1/1799 1798/1/1798 +f 1795/1/1795 1798/1/1798 1793/1/1793 +f 1793/1/1793 1798/1/1798 1804/1/1804 +f 1798/1/1798 1799/1/1799 1802/1/1802 +f 1805/1/1805 1798/1/1798 1802/1/1802 +f 1802/1/1802 1806/1/1806 1805/1/1805 +f 1802/1/1802 1799/1/1799 1803/1/1803 +f 1797/1/1797 1801/1/1801 1799/1/1799 +f 1797/1/1797 1800/1/1800 1801/1/1801 +f 1796/1/1796 1800/1/1800 1797/1/1797 +f 2433/1/2433 1800/1/1800 1796/1/1796 +f 2433/1/2433 2432/1/2432 1800/1/1800 +f 2432/1/2432 2430/1/2430 1800/1/1800 +f 2430/1/2430 1808/1/1808 1800/1/1800 +f 2430/1/2430 1813/1/1813 1808/1/1808 +f 2431/1/2431 1813/1/1813 2430/1/2430 +f 2431/1/2431 1401/1/1401 1813/1/1813 +f 1416/1/1416 1401/1/1401 2431/1/2431 +f 1416/1/1416 2431/1/2431 2432/1/2432 +f 1415/1/1415 1416/1/1416 2432/1/2432 +f 1415/1/1415 1414/1/1414 1416/1/1416 +f 1414/1/1414 1412/1/1412 1416/1/1416 +f 1411/1/1411 1412/1/1412 1414/1/1414 +f 1413/1/1413 1411/1/1411 1414/1/1414 +f 1368/1/1368 1411/1/1411 1413/1/1413 +f 893/1/893 1368/1/1368 1413/1/1413 +f 893/1/893 1413/1/1413 894/1/894 +f 888/1/888 893/1/893 894/1/894 +f 888/1/888 894/1/894 878/1/878 +f 886/1/886 888/1/888 878/1/878 +f 886/1/886 878/1/878 879/1/879 +f 883/1/883 886/1/886 879/1/879 +f 883/1/883 879/1/879 880/1/880 +f 882/1/882 883/1/883 880/1/880 +f 882/1/882 880/1/880 881/1/881 +f 1422/1/1422 882/1/882 881/1/881 +f 1422/1/1422 881/1/881 1420/1/1420 +f 1424/1/1424 1422/1/1422 1420/1/1420 +f 1424/1/1424 1420/1/1420 1430/1/1430 +f 1429/1/1429 1424/1/1424 1430/1/1430 +f 1429/1/1429 1423/1/1423 1424/1/1424 +f 1430/1/1430 1420/1/1420 1421/1/1421 +f 1430/1/1430 1421/1/1421 1431/1/1431 +f 863/1/863 1430/1/1430 1431/1/1431 +f 1431/1/1431 1421/1/1421 868/1/868 +f 1431/1/1431 868/1/868 864/1/864 +f 1421/1/1421 875/1/875 868/1/868 +f 875/1/875 871/1/871 868/1/868 +f 868/1/868 871/1/871 869/1/869 +f 868/1/868 869/1/869 865/1/865 +f 865/1/865 869/1/869 867/1/867 +f 871/1/871 872/1/872 869/1/869 +f 869/1/869 872/1/872 870/1/870 +f 871/1/871 873/1/873 872/1/872 +f 873/1/873 874/1/874 872/1/872 +f 872/1/872 874/1/874 795/1/795 +f 873/1/873 877/1/877 874/1/874 +f 877/1/877 796/1/796 874/1/874 +f 877/1/877 878/1/878 796/1/796 +f 876/1/876 877/1/877 873/1/873 +f 875/1/875 876/1/876 873/1/873 +f 881/1/881 876/1/876 875/1/875 +f 880/1/880 877/1/877 876/1/876 +f 875/1/875 873/1/873 871/1/871 +f 1420/1/1420 875/1/875 1421/1/1421 +f 1423/1/1423 1422/1/1422 1424/1/1424 +f 1423/1/1423 1425/1/1425 1422/1/1422 +f 1427/1/1427 1425/1/1425 1423/1/1423 +f 1428/1/1428 1427/1/1427 1423/1/1423 +f 1428/1/1428 1562/1/1562 1427/1/1427 +f 1562/1/1562 1426/1/1426 1427/1/1427 +f 1562/1/1562 1561/1/1561 1426/1/1426 +f 1561/1/1561 1419/1/1419 1426/1/1426 +f 1426/1/1426 1419/1/1419 1425/1/1425 +f 1419/1/1419 884/1/884 1425/1/1425 +f 1425/1/1425 884/1/884 882/1/882 +f 1419/1/1419 885/1/885 884/1/884 +f 884/1/884 885/1/885 883/1/883 +f 1419/1/1419 1557/1/1557 885/1/885 +f 1557/1/1557 886/1/886 885/1/885 +f 1557/1/1557 887/1/887 886/1/886 +f 1554/1/1554 887/1/887 1557/1/1557 +f 1556/1/1556 1554/1/1554 1557/1/1557 +f 1555/1/1555 1554/1/1554 1556/1/1556 +f 1559/1/1559 1555/1/1555 1556/1/1556 +f 1559/1/1559 1556/1/1556 1561/1/1561 +f 1560/1/1560 1559/1/1559 1561/1/1561 +f 1537/1/1537 1559/1/1559 1560/1/1560 +f 1535/1/1535 1537/1/1537 1560/1/1560 +f 1535/1/1535 1560/1/1560 1562/1/1562 +f 1532/1/1532 1537/1/1537 1535/1/1535 +f 1533/1/1533 1532/1/1532 1535/1/1535 +f 1533/1/1533 1535/1/1535 1536/1/1536 +f 1531/1/1531 1532/1/1532 1533/1/1533 +f 1392/1/1392 1531/1/1531 1533/1/1533 +f 1392/1/1392 1533/1/1533 1395/1/1395 +f 1391/1/1391 1531/1/1531 1392/1/1392 +f 1374/1/1374 1391/1/1391 1392/1/1392 +f 1374/1/1374 1392/1/1392 1394/1/1394 +f 1376/1/1376 1391/1/1391 1374/1/1374 +f 1373/1/1373 1376/1/1376 1374/1/1374 +f 1373/1/1373 1374/1/1374 1372/1/1372 +f 1372/1/1372 1367/1/1367 1373/1/1373 +f 1373/1/1373 1367/1/1367 1364/1/1364 +f 1373/1/1373 1364/1/1364 1377/1/1377 +f 1377/1/1377 1364/1/1364 1380/1/1380 +f 1380/1/1380 1376/1/1376 1377/1/1377 +f 1378/1/1378 1376/1/1376 1380/1/1380 +f 1380/1/1380 1363/1/1363 1378/1/1378 +f 1378/1/1378 1363/1/1363 1381/1/1381 +f 1381/1/1381 1379/1/1379 1378/1/1378 +f 1382/1/1382 1379/1/1379 1381/1/1381 +f 1381/1/1381 1357/1/1357 1382/1/1382 +f 1382/1/1382 1357/1/1357 1383/1/1383 +f 1383/1/1383 1357/1/1357 1356/1/1356 +f 1383/1/1383 1356/1/1356 1384/1/1384 +f 1384/1/1384 1385/1/1385 1383/1/1383 +f 1383/1/1383 1385/1/1385 1379/1/1379 +f 1385/1/1385 1388/1/1388 1379/1/1379 +f 1379/1/1379 1388/1/1388 1390/1/1390 +f 1379/1/1379 1390/1/1390 1376/1/1376 +f 1388/1/1388 1480/1/1480 1390/1/1390 +f 1390/1/1390 1480/1/1480 1482/1/1482 +f 1390/1/1390 1482/1/1482 1391/1/1391 +f 1480/1/1480 1481/1/1481 1482/1/1482 +f 1482/1/1482 1481/1/1481 1526/1/1526 +f 1482/1/1482 1526/1/1526 1530/1/1530 +f 1482/1/1482 1530/1/1530 1531/1/1531 +f 1531/1/1531 1530/1/1530 1534/1/1534 +f 1530/1/1530 1539/1/1539 1534/1/1534 +f 1534/1/1534 1539/1/1539 1538/1/1538 +f 1534/1/1534 1538/1/1538 1532/1/1532 +f 1539/1/1539 1540/1/1540 1538/1/1538 +f 1538/1/1538 1540/1/1540 1541/1/1541 +f 1538/1/1538 1541/1/1541 1537/1/1537 +f 1537/1/1537 1541/1/1541 1558/1/1558 +f 1541/1/1541 1553/1/1553 1558/1/1558 +f 1553/1/1553 1555/1/1555 1558/1/1558 +f 1553/1/1553 1552/1/1552 1555/1/1555 +f 1553/1/1553 1551/1/1551 1552/1/1552 +f 1551/1/1551 1418/1/1418 1552/1/1552 +f 1552/1/1552 1418/1/1418 889/1/889 +f 1552/1/1552 889/1/889 1554/1/1554 +f 1418/1/1418 890/1/890 889/1/889 +f 889/1/889 890/1/890 887/1/887 +f 887/1/887 890/1/890 888/1/888 +f 1418/1/1418 891/1/891 890/1/890 +f 891/1/891 892/1/892 890/1/890 +f 890/1/890 892/1/892 893/1/893 +f 891/1/891 896/1/896 892/1/892 +f 896/1/896 1365/1/1365 892/1/892 +f 892/1/892 1365/1/1365 1368/1/1368 +f 1365/1/1365 1366/1/1366 1368/1/1368 +f 1368/1/1368 1366/1/1366 1369/1/1369 +f 1369/1/1369 1366/1/1366 1370/1/1370 +f 1369/1/1369 1370/1/1370 1411/1/1411 +f 1366/1/1366 1371/1/1371 1370/1/1370 +f 1370/1/1370 1371/1/1371 1399/1/1399 +f 1370/1/1370 1399/1/1399 1412/1/1412 +f 1412/1/1412 1399/1/1399 1398/1/1398 +f 1399/1/1399 1371/1/1371 1375/1/1375 +f 1393/1/1393 1399/1/1399 1375/1/1375 +f 1375/1/1375 1374/1/1374 1393/1/1393 +f 1375/1/1375 1371/1/1371 1372/1/1372 +f 1366/1/1366 1367/1/1367 1371/1/1371 +f 1366/1/1366 1361/1/1361 1367/1/1367 +f 1365/1/1365 1361/1/1361 1366/1/1366 +f 1360/1/1360 1361/1/1361 1365/1/1365 +f 1360/1/1360 1358/1/1358 1361/1/1361 +f 1358/1/1358 1362/1/1362 1361/1/1361 +f 1362/1/1362 1364/1/1364 1361/1/1361 +f 1362/1/1362 1363/1/1363 1364/1/1364 +f 1359/1/1359 1363/1/1363 1362/1/1362 +f 1359/1/1359 1357/1/1357 1363/1/1363 +f 1355/1/1355 1357/1/1357 1359/1/1359 +f 1355/1/1355 1359/1/1359 1358/1/1358 +f 901/1/901 1355/1/1355 1358/1/1358 +f 901/1/901 1354/1/1354 1355/1/1355 +f 1354/1/1354 1353/1/1353 1355/1/1355 +f 1351/1/1351 1353/1/1353 1354/1/1354 +f 900/1/900 1351/1/1351 1354/1/1354 +f 905/1/905 1351/1/1351 900/1/900 +f 902/1/902 905/1/905 900/1/900 +f 902/1/902 900/1/900 898/1/898 +f 899/1/899 902/1/902 898/1/898 +f 899/1/899 898/1/898 897/1/897 +f 1508/1/1508 899/1/899 897/1/897 +f 1508/1/1508 897/1/897 1512/1/1512 +f 1511/1/1511 1508/1/1508 1512/1/1512 +f 1511/1/1511 1512/1/1512 1515/1/1515 +f 1514/1/1514 1511/1/1511 1515/1/1515 +f 1514/1/1514 1515/1/1515 1518/1/1518 +f 1520/1/1520 1514/1/1514 1518/1/1518 +f 1520/1/1520 1518/1/1518 1525/1/1525 +f 1524/1/1524 1520/1/1520 1525/1/1525 +f 1524/1/1524 1525/1/1525 1544/1/1544 +f 1526/1/1526 1524/1/1524 1544/1/1544 +f 1526/1/1526 1523/1/1523 1524/1/1524 +f 1544/1/1544 1525/1/1525 1545/1/1545 +f 1544/1/1544 1545/1/1545 1543/1/1543 +f 1530/1/1530 1544/1/1544 1543/1/1543 +f 1543/1/1543 1545/1/1545 1542/1/1542 +f 1543/1/1543 1542/1/1542 1539/1/1539 +f 1545/1/1545 1546/1/1546 1542/1/1542 +f 1546/1/1546 1548/1/1548 1542/1/1542 +f 1542/1/1542 1548/1/1548 1550/1/1550 +f 1542/1/1542 1550/1/1550 1540/1/1540 +f 1540/1/1540 1550/1/1550 1553/1/1553 +f 1548/1/1548 1549/1/1549 1550/1/1550 +f 1550/1/1550 1549/1/1549 1551/1/1551 +f 1548/1/1548 1547/1/1547 1549/1/1549 +f 1547/1/1547 1417/1/1417 1549/1/1549 +f 1549/1/1549 1417/1/1417 1418/1/1418 +f 1547/1/1547 1516/1/1516 1417/1/1417 +f 1516/1/1516 891/1/891 1417/1/1417 +f 1516/1/1516 897/1/897 891/1/891 +f 1517/1/1517 1516/1/1516 1547/1/1547 +f 1546/1/1546 1517/1/1517 1547/1/1547 +f 1518/1/1518 1517/1/1517 1546/1/1546 +f 1515/1/1515 1516/1/1516 1517/1/1517 +f 1546/1/1546 1547/1/1547 1548/1/1548 +f 1525/1/1525 1546/1/1546 1545/1/1545 +f 1523/1/1523 1520/1/1520 1524/1/1524 +f 1523/1/1523 1519/1/1519 1520/1/1520 +f 1521/1/1521 1519/1/1519 1523/1/1523 +f 1481/1/1481 1521/1/1521 1523/1/1523 +f 1481/1/1481 1527/1/1527 1521/1/1521 +f 1527/1/1527 1522/1/1522 1521/1/1521 +f 1527/1/1527 1528/1/1528 1522/1/1522 +f 1528/1/1528 1510/1/1510 1522/1/1522 +f 1522/1/1522 1510/1/1510 1519/1/1519 +f 1510/1/1510 1513/1/1513 1519/1/1519 +f 1519/1/1519 1513/1/1513 1514/1/1514 +f 1510/1/1510 1509/1/1509 1513/1/1513 +f 1513/1/1513 1509/1/1509 1511/1/1511 +f 1510/1/1510 1507/1/1507 1509/1/1509 +f 1507/1/1507 1508/1/1508 1509/1/1509 +f 1507/1/1507 908/1/908 1508/1/1508 +f 1504/1/1504 908/1/908 1507/1/1507 +f 1506/1/1506 1504/1/1504 1507/1/1507 +f 1501/1/1501 1504/1/1504 1506/1/1506 +f 1505/1/1505 1501/1/1501 1506/1/1506 +f 1505/1/1505 1506/1/1506 1528/1/1528 +f 1529/1/1529 1505/1/1505 1528/1/1528 +f 1488/1/1488 1505/1/1505 1529/1/1529 +f 1483/1/1483 1488/1/1488 1529/1/1529 +f 1483/1/1483 1529/1/1529 1527/1/1527 +f 1485/1/1485 1488/1/1488 1483/1/1483 +f 1484/1/1484 1485/1/1485 1483/1/1483 +f 1484/1/1484 1483/1/1483 1480/1/1480 +f 1486/1/1486 1485/1/1485 1484/1/1484 +f 1389/1/1389 1486/1/1486 1484/1/1484 +f 1389/1/1389 1484/1/1484 1388/1/1388 +f 1588/1/1588 1486/1/1486 1389/1/1389 +f 1387/1/1387 1588/1/1588 1389/1/1389 +f 1387/1/1387 1389/1/1389 1385/1/1385 +f 1404/1/1404 1588/1/1588 1387/1/1387 +f 1403/1/1403 1404/1/1404 1387/1/1387 +f 1403/1/1403 1387/1/1387 1402/1/1402 +f 1402/1/1402 1346/1/1346 1403/1/1403 +f 1403/1/1403 1346/1/1346 1344/1/1344 +f 1403/1/1403 1344/1/1344 1405/1/1405 +f 1405/1/1405 1344/1/1344 1406/1/1406 +f 1406/1/1406 1404/1/1404 1405/1/1405 +f 1407/1/1407 1404/1/1404 1406/1/1406 +f 1406/1/1406 1338/1/1338 1407/1/1407 +f 1407/1/1407 1338/1/1338 1409/1/1409 +f 1409/1/1409 1408/1/1408 1407/1/1407 +f 1410/1/1410 1408/1/1408 1409/1/1409 +f 1409/1/1409 1333/1/1333 1410/1/1410 +f 1410/1/1410 1333/1/1333 1336/1/1336 +f 1336/1/1336 1333/1/1333 1332/1/1332 +f 1336/1/1336 1332/1/1332 1335/1/1335 +f 1335/1/1335 1590/1/1590 1336/1/1336 +f 1336/1/1336 1590/1/1590 1408/1/1408 +f 1590/1/1590 1589/1/1589 1408/1/1408 +f 1408/1/1408 1589/1/1589 1587/1/1587 +f 1408/1/1408 1587/1/1587 1404/1/1404 +f 1589/1/1589 1585/1/1585 1587/1/1587 +f 1587/1/1587 1585/1/1585 1575/1/1575 +f 1587/1/1587 1575/1/1575 1588/1/1588 +f 1585/1/1585 1576/1/1576 1575/1/1575 +f 1575/1/1575 1576/1/1576 1574/1/1574 +f 1575/1/1575 1574/1/1574 1493/1/1493 +f 1575/1/1575 1493/1/1493 1486/1/1486 +f 1486/1/1486 1493/1/1493 1489/1/1489 +f 1493/1/1493 1492/1/1492 1489/1/1489 +f 1489/1/1489 1492/1/1492 1487/1/1487 +f 1489/1/1489 1487/1/1487 1485/1/1485 +f 1492/1/1492 1490/1/1490 1487/1/1487 +f 1487/1/1487 1490/1/1490 1491/1/1491 +f 1487/1/1487 1491/1/1491 1488/1/1488 +f 1488/1/1488 1491/1/1491 1498/1/1498 +f 1491/1/1491 1497/1/1497 1498/1/1498 +f 1497/1/1497 1501/1/1501 1498/1/1498 +f 1497/1/1497 1500/1/1500 1501/1/1501 +f 1497/1/1497 1499/1/1499 1500/1/1500 +f 1499/1/1499 913/1/913 1500/1/1500 +f 1500/1/1500 913/1/913 907/1/907 +f 1500/1/1500 907/1/907 1504/1/1504 +f 913/1/913 903/1/903 907/1/907 +f 907/1/907 903/1/903 908/1/908 +f 908/1/908 903/1/903 899/1/899 +f 913/1/913 906/1/906 903/1/903 +f 906/1/906 904/1/904 903/1/903 +f 903/1/903 904/1/904 902/1/902 +f 906/1/906 909/1/909 904/1/904 +f 909/1/909 1345/1/1345 904/1/904 +f 904/1/904 1345/1/1345 905/1/905 +f 1345/1/1345 1347/1/1347 905/1/905 +f 905/1/905 1347/1/1347 1349/1/1349 +f 1349/1/1349 1347/1/1347 1350/1/1350 +f 1349/1/1349 1350/1/1350 1351/1/1351 +f 1347/1/1347 1348/1/1348 1350/1/1350 +f 1350/1/1350 1348/1/1348 1352/1/1352 +f 1350/1/1350 1352/1/1352 1353/1/1353 +f 1353/1/1353 1352/1/1352 1356/1/1356 +f 1352/1/1352 1348/1/1348 1386/1/1386 +f 1384/1/1384 1352/1/1352 1386/1/1386 +f 1386/1/1386 1387/1/1387 1384/1/1384 +f 1386/1/1386 1348/1/1348 1402/1/1402 +f 1347/1/1347 1346/1/1346 1348/1/1348 +f 1347/1/1347 1342/1/1342 1346/1/1346 +f 1345/1/1345 1342/1/1342 1347/1/1347 +f 1341/1/1341 1342/1/1342 1345/1/1345 +f 1341/1/1341 1339/1/1339 1342/1/1342 +f 1339/1/1339 1343/1/1343 1342/1/1342 +f 1343/1/1343 1344/1/1344 1342/1/1342 +f 1343/1/1343 1338/1/1338 1344/1/1344 +f 1337/1/1337 1338/1/1338 1343/1/1343 +f 1337/1/1337 1333/1/1333 1338/1/1338 +f 1334/1/1334 1333/1/1333 1337/1/1337 +f 1334/1/1334 1337/1/1337 1339/1/1339 +f 1340/1/1340 1334/1/1334 1339/1/1339 +f 1340/1/1340 1331/1/1331 1334/1/1334 +f 1331/1/1331 1329/1/1329 1334/1/1334 +f 1326/1/1326 1329/1/1329 1331/1/1331 +f 1323/1/1323 1326/1/1326 1331/1/1331 +f 1322/1/1322 1326/1/1326 1323/1/1323 +f 918/1/918 1322/1/1322 1323/1/1323 +f 918/1/918 1323/1/1323 914/1/914 +f 917/1/917 918/1/918 914/1/914 +f 917/1/917 914/1/914 911/1/911 +f 916/1/916 917/1/917 911/1/911 +f 916/1/916 911/1/911 915/1/915 +f 1321/1/1321 916/1/916 915/1/915 +f 1321/1/1321 915/1/915 1566/1/1566 +f 1568/1/1568 1321/1/1321 1566/1/1566 +f 1568/1/1568 1566/1/1566 1567/1/1567 +f 1572/1/1572 1568/1/1568 1567/1/1567 +f 1572/1/1572 1567/1/1567 1569/1/1569 +f 1573/1/1573 1572/1/1572 1569/1/1569 +f 1573/1/1573 1569/1/1569 1570/1/1570 +f 1574/1/1574 1573/1/1573 1570/1/1570 +f 1574/1/1574 1577/1/1577 1573/1/1573 +f 1570/1/1570 1569/1/1569 1571/1/1571 +f 1570/1/1570 1571/1/1571 1494/1/1494 +f 1493/1/1493 1570/1/1570 1494/1/1494 +f 1494/1/1494 1571/1/1571 1495/1/1495 +f 1494/1/1494 1495/1/1495 1492/1/1492 +f 1571/1/1571 1564/1/1564 1495/1/1495 +f 1564/1/1564 1502/1/1502 1495/1/1495 +f 1495/1/1495 1502/1/1502 1496/1/1496 +f 1495/1/1495 1496/1/1496 1490/1/1490 +f 1490/1/1490 1496/1/1496 1497/1/1497 +f 1502/1/1502 1503/1/1503 1496/1/1496 +f 1496/1/1496 1503/1/1503 1499/1/1499 +f 1502/1/1502 1563/1/1563 1503/1/1503 +f 1563/1/1563 912/1/912 1503/1/1503 +f 1503/1/1503 912/1/912 913/1/913 +f 1563/1/1563 910/1/910 912/1/912 +f 910/1/910 906/1/906 912/1/912 +f 910/1/910 911/1/911 906/1/906 +f 1565/1/1565 910/1/910 1563/1/1563 +f 1564/1/1564 1565/1/1565 1563/1/1563 +f 1567/1/1567 1565/1/1565 1564/1/1564 +f 1566/1/1566 910/1/910 1565/1/1565 +f 1564/1/1564 1563/1/1563 1502/1/1502 +f 1569/1/1569 1564/1/1564 1571/1/1571 +f 1577/1/1577 1572/1/1572 1573/1/1573 +f 1577/1/1577 1579/1/1579 1572/1/1572 +f 1578/1/1578 1579/1/1579 1577/1/1577 +f 1576/1/1576 1578/1/1578 1577/1/1577 +f 1576/1/1576 1580/1/1580 1578/1/1578 +f 1580/1/1580 1581/1/1581 1578/1/1578 +f 1580/1/1580 950/1/950 1581/1/1581 +f 950/1/950 1319/1/1319 1581/1/1581 +f 1581/1/1581 1319/1/1319 1579/1/1579 +f 1319/1/1319 1582/1/1582 1579/1/1579 +f 1579/1/1579 1582/1/1582 1568/1/1568 +f 1319/1/1319 1320/1/1320 1582/1/1582 +f 1582/1/1582 1320/1/1320 1321/1/1321 +f 1319/1/1319 923/1/923 1320/1/1320 +f 923/1/923 916/1/916 1320/1/1320 +f 923/1/923 919/1/919 916/1/916 +f 922/1/922 919/1/919 923/1/923 +f 929/1/929 922/1/922 923/1/923 +f 928/1/928 922/1/922 929/1/929 +f 949/1/949 928/1/928 929/1/929 +f 949/1/949 929/1/929 950/1/950 +f 1583/1/1583 949/1/949 950/1/950 +f 948/1/948 949/1/949 1583/1/1583 +f 1584/1/1584 948/1/948 1583/1/1583 +f 1584/1/1584 1583/1/1583 1580/1/1580 +f 956/1/956 948/1/948 1584/1/1584 +f 1586/1/1586 956/1/956 1584/1/1584 +f 1586/1/1586 1584/1/1584 1585/1/1585 +f 955/1/955 956/1/956 1586/1/1586 +f 1591/1/1591 955/1/955 1586/1/1586 +f 1591/1/1591 1586/1/1586 1589/1/1589 +f 1593/1/1593 955/1/955 1591/1/1591 +f 1592/1/1592 1593/1/1593 1591/1/1591 +f 1592/1/1592 1591/1/1591 1590/1/1590 +f 1594/1/1594 1593/1/1593 1592/1/1592 +f 1635/1/1635 1594/1/1594 1592/1/1592 +f 1635/1/1635 1592/1/1592 1637/1/1637 +f 1637/1/1637 1634/1/1634 1635/1/1635 +f 1635/1/1635 1634/1/1634 1631/1/1631 +f 1635/1/1635 1631/1/1631 1636/1/1636 +f 1636/1/1636 1631/1/1631 1632/1/1632 +f 1632/1/1632 1594/1/1594 1636/1/1636 +f 1633/1/1633 1594/1/1594 1632/1/1632 +f 1632/1/1632 1629/1/1629 1633/1/1633 +f 1633/1/1633 1629/1/1629 1630/1/1630 +f 1630/1/1630 1596/1/1596 1633/1/1633 +f 1604/1/1604 1596/1/1596 1630/1/1630 +f 1630/1/1630 1606/1/1606 1604/1/1604 +f 1604/1/1604 1606/1/1606 1602/1/1602 +f 1602/1/1602 1606/1/1606 1605/1/1605 +f 1602/1/1602 1605/1/1605 1603/1/1603 +f 1603/1/1603 1598/1/1598 1602/1/1602 +f 1602/1/1602 1598/1/1598 1596/1/1596 +f 1598/1/1598 1597/1/1597 1596/1/1596 +f 1596/1/1596 1597/1/1597 1595/1/1595 +f 1596/1/1596 1595/1/1595 1594/1/1594 +f 1597/1/1597 1001/1/1001 1595/1/1595 +f 1595/1/1595 1001/1/1001 952/1/952 +f 1595/1/1595 952/1/952 1593/1/1593 +f 1001/1/1001 999/1/999 952/1/952 +f 952/1/952 999/1/999 953/1/953 +f 952/1/952 953/1/953 951/1/951 +f 952/1/952 951/1/951 955/1/955 +f 953/1/953 954/1/954 951/1/951 +f 951/1/951 954/1/954 942/1/942 +f 951/1/951 942/1/942 943/1/943 +f 951/1/951 943/1/943 956/1/956 +f 956/1/956 943/1/943 945/1/945 +f 943/1/943 941/1/941 945/1/945 +f 945/1/945 941/1/941 946/1/946 +f 945/1/945 946/1/946 948/1/948 +f 948/1/948 946/1/946 947/1/947 +f 946/1/946 930/1/930 947/1/947 +f 930/1/930 928/1/928 947/1/947 +f 930/1/930 927/1/927 928/1/928 +f 930/1/930 931/1/931 927/1/927 +f 931/1/931 926/1/926 927/1/927 +f 927/1/927 926/1/926 921/1/921 +f 927/1/927 921/1/921 922/1/922 +f 926/1/926 920/1/920 921/1/921 +f 921/1/921 920/1/920 919/1/919 +f 919/1/919 920/1/920 917/1/917 +f 926/1/926 924/1/924 920/1/920 +f 924/1/924 925/1/925 920/1/920 +f 920/1/920 925/1/925 918/1/918 +f 924/1/924 976/1/976 925/1/925 +f 976/1/976 1324/1/1324 925/1/925 +f 925/1/925 1324/1/1324 1322/1/1322 +f 1324/1/1324 1327/1/1327 1322/1/1322 +f 1322/1/1322 1327/1/1327 1325/1/1325 +f 1325/1/1325 1327/1/1327 1328/1/1328 +f 1325/1/1325 1328/1/1328 1326/1/1326 +f 1327/1/1327 1639/1/1639 1328/1/1328 +f 1328/1/1328 1639/1/1639 1330/1/1330 +f 1328/1/1328 1330/1/1330 1329/1/1329 +f 1329/1/1329 1330/1/1330 1332/1/1332 +f 1330/1/1330 1639/1/1639 1638/1/1638 +f 1335/1/1335 1330/1/1330 1638/1/1638 +f 1638/1/1638 1592/1/1592 1335/1/1335 +f 1638/1/1638 1639/1/1639 1637/1/1637 +f 1327/1/1327 1634/1/1634 1639/1/1639 +f 1327/1/1327 1628/1/1628 1634/1/1634 +f 1324/1/1324 1628/1/1628 1327/1/1327 +f 1626/1/1626 1628/1/1628 1324/1/1324 +f 1626/1/1626 1624/1/1624 1628/1/1628 +f 1624/1/1624 1627/1/1627 1628/1/1628 +f 1627/1/1627 1631/1/1631 1628/1/1628 +f 1627/1/1627 1629/1/1629 1631/1/1631 +f 1625/1/1625 1629/1/1629 1627/1/1627 +f 1625/1/1625 1606/1/1606 1629/1/1629 +f 1623/1/1623 1606/1/1606 1625/1/1625 +f 1623/1/1623 1625/1/1625 1624/1/1624 +f 1622/1/1622 1623/1/1623 1624/1/1624 +f 1622/1/1622 1621/1/1621 1623/1/1623 +f 1621/1/1621 1609/1/1609 1623/1/1623 +f 1616/1/1616 1609/1/1609 1621/1/1621 +f 1620/1/1620 1616/1/1616 1621/1/1621 +f 1619/1/1619 1616/1/1616 1620/1/1620 +f 978/1/978 1619/1/1619 1620/1/1620 +f 978/1/978 1620/1/1620 975/1/975 +f 972/1/972 978/1/978 975/1/975 +f 972/1/972 975/1/975 973/1/973 +f 969/1/969 972/1/972 973/1/973 +f 969/1/969 973/1/973 967/1/967 +f 965/1/965 969/1/969 967/1/967 +f 965/1/965 967/1/967 964/1/964 +f 963/1/963 965/1/965 964/1/964 +f 963/1/963 964/1/964 960/1/960 +f 959/1/959 963/1/963 960/1/960 +f 959/1/959 960/1/960 958/1/958 +f 957/1/957 959/1/959 958/1/958 +f 957/1/957 958/1/958 954/1/954 +f 954/1/954 958/1/958 944/1/944 +f 958/1/958 938/1/938 944/1/944 +f 944/1/944 938/1/938 940/1/940 +f 942/1/942 944/1/944 940/1/940 +f 938/1/938 935/1/935 940/1/940 +f 940/1/940 935/1/935 934/1/934 +f 940/1/940 934/1/934 941/1/941 +f 941/1/941 934/1/934 930/1/930 +f 935/1/935 933/1/933 934/1/934 +f 934/1/934 933/1/933 931/1/931 +f 935/1/935 936/1/936 933/1/933 +f 936/1/936 932/1/932 933/1/933 +f 933/1/933 932/1/932 926/1/926 +f 936/1/936 937/1/937 932/1/932 +f 937/1/937 924/1/924 932/1/932 +f 937/1/937 973/1/973 924/1/924 +f 939/1/939 937/1/937 936/1/936 +f 938/1/938 939/1/939 936/1/936 +f 960/1/960 939/1/939 938/1/938 +f 964/1/964 937/1/937 939/1/939 +f 938/1/938 936/1/936 935/1/935 +f 961/1/961 959/1/959 957/1/957 +f 953/1/953 961/1/961 957/1/957 +f 961/1/961 962/1/962 959/1/959 +f 1003/1/1003 962/1/962 961/1/961 +f 999/1/999 1003/1/1003 961/1/961 +f 999/1/999 998/1/998 1003/1/1003 +f 998/1/998 1002/1/1002 1003/1/1003 +f 998/1/998 991/1/991 1002/1/1002 +f 991/1/991 970/1/970 1002/1/1002 +f 1002/1/1002 970/1/970 962/1/962 +f 970/1/970 966/1/966 962/1/962 +f 962/1/962 966/1/966 963/1/963 +f 970/1/970 968/1/968 966/1/966 +f 966/1/966 968/1/968 965/1/965 +f 970/1/970 971/1/971 968/1/968 +f 971/1/971 969/1/969 968/1/968 +f 971/1/971 974/1/974 969/1/969 +f 979/1/979 974/1/974 971/1/971 +f 986/1/986 979/1/979 971/1/971 +f 985/1/985 979/1/979 986/1/986 +f 990/1/990 985/1/985 986/1/986 +f 990/1/990 986/1/986 991/1/991 +f 993/1/993 990/1/990 991/1/991 +f 992/1/992 990/1/990 993/1/993 +f 996/1/996 992/1/992 993/1/993 +f 996/1/996 993/1/993 998/1/998 +f 995/1/995 992/1/992 996/1/996 +f 1000/1/1000 995/1/995 996/1/996 +f 1000/1/1000 996/1/996 1001/1/1001 +f 1004/1/1004 995/1/995 1000/1/1000 +f 1599/1/1599 1004/1/1004 1000/1/1000 +f 1599/1/1599 1000/1/1000 1597/1/1597 +f 1601/1/1601 1004/1/1004 1599/1/1599 +f 1600/1/1600 1601/1/1601 1599/1/1599 +f 1600/1/1600 1599/1/1599 1598/1/1598 +f 1652/1/1652 1601/1/1601 1600/1/1600 +f 1655/1/1655 1652/1/1652 1600/1/1600 +f 1655/1/1655 1600/1/1600 1612/1/1612 +f 1612/1/1612 1613/1/1613 1655/1/1655 +f 1655/1/1655 1613/1/1613 1645/1/1645 +f 1655/1/1655 1645/1/1645 1654/1/1654 +f 1654/1/1654 1645/1/1645 1653/1/1653 +f 1653/1/1653 1652/1/1652 1654/1/1654 +f 1651/1/1651 1652/1/1652 1653/1/1653 +f 1653/1/1653 1646/1/1646 1651/1/1651 +f 1651/1/1651 1646/1/1646 1648/1/1648 +f 1648/1/1648 1650/1/1650 1651/1/1651 +f 1649/1/1649 1650/1/1650 1648/1/1648 +f 1648/1/1648 1647/1/1647 1649/1/1649 +f 1649/1/1649 1647/1/1647 1308/1/1308 +f 1308/1/1308 1647/1/1647 1309/1/1309 +f 1308/1/1308 1309/1/1309 1305/1/1305 +f 1305/1/1305 1306/1/1306 1308/1/1308 +f 1308/1/1308 1306/1/1306 1650/1/1650 +f 1306/1/1306 1310/1/1310 1650/1/1650 +f 1650/1/1650 1310/1/1310 1656/1/1656 +f 1650/1/1650 1656/1/1656 1652/1/1652 +f 1310/1/1310 1657/1/1657 1656/1/1656 +f 1656/1/1656 1657/1/1657 1007/1/1007 +f 1656/1/1656 1007/1/1007 1601/1/1601 +f 1657/1/1657 1316/1/1316 1007/1/1007 +f 1007/1/1007 1316/1/1316 1008/1/1008 +f 1007/1/1007 1008/1/1008 1006/1/1006 +f 1007/1/1007 1006/1/1006 1004/1/1004 +f 1004/1/1004 1006/1/1006 1005/1/1005 +f 1006/1/1006 1011/1/1011 1005/1/1005 +f 1005/1/1005 1011/1/1011 997/1/997 +f 1005/1/1005 997/1/997 995/1/995 +f 1011/1/1011 1313/1/1313 997/1/997 +f 997/1/997 1313/1/1313 994/1/994 +f 997/1/997 994/1/994 992/1/992 +f 992/1/992 994/1/994 989/1/989 +f 994/1/994 988/1/988 989/1/989 +f 988/1/988 985/1/985 989/1/989 +f 988/1/988 984/1/984 985/1/985 +f 988/1/988 987/1/987 984/1/984 +f 987/1/987 981/1/981 984/1/984 +f 984/1/984 981/1/981 980/1/980 +f 984/1/984 980/1/980 979/1/979 +f 981/1/981 977/1/977 980/1/980 +f 980/1/980 977/1/977 974/1/974 +f 974/1/974 977/1/977 972/1/972 +f 981/1/981 982/1/982 977/1/977 +f 982/1/982 983/1/983 977/1/977 +f 977/1/977 983/1/983 978/1/978 +f 982/1/982 1031/1/1031 983/1/983 +f 1031/1/1031 1617/1/1617 983/1/983 +f 983/1/983 1617/1/1617 1619/1/1619 +f 1617/1/1617 1614/1/1614 1619/1/1619 +f 1619/1/1619 1614/1/1614 1615/1/1615 +f 1615/1/1615 1614/1/1614 1611/1/1611 +f 1615/1/1615 1611/1/1611 1616/1/1616 +f 1614/1/1614 1610/1/1610 1611/1/1611 +f 1611/1/1611 1610/1/1610 1608/1/1608 +f 1611/1/1611 1608/1/1608 1609/1/1609 +f 1609/1/1609 1608/1/1608 1605/1/1605 +f 1608/1/1608 1610/1/1610 1607/1/1607 +f 1603/1/1603 1608/1/1608 1607/1/1607 +f 1607/1/1607 1600/1/1600 1603/1/1603 +f 1607/1/1607 1610/1/1610 1612/1/1612 +f 1614/1/1614 1613/1/1613 1610/1/1610 +f 1614/1/1614 1618/1/1618 1613/1/1613 +f 1617/1/1617 1618/1/1618 1614/1/1614 +f 1640/1/1640 1618/1/1618 1617/1/1617 +f 1640/1/1640 1641/1/1641 1618/1/1618 +f 1641/1/1641 1644/1/1644 1618/1/1618 +f 1644/1/1644 1645/1/1645 1618/1/1618 +f 1644/1/1644 1646/1/1646 1645/1/1645 +f 1643/1/1643 1646/1/1646 1644/1/1644 +f 1643/1/1643 1647/1/1647 1646/1/1646 +f 1642/1/1642 1647/1/1647 1643/1/1643 +f 1642/1/1642 1643/1/1643 1641/1/1641 +f 1072/1/1072 1642/1/1642 1641/1/1641 +f 1072/1/1072 1071/1/1071 1642/1/1642 +f 1071/1/1071 1074/1/1074 1642/1/1642 +f 1069/1/1069 1074/1/1074 1071/1/1071 +f 1070/1/1070 1069/1/1069 1071/1/1071 +f 1068/1/1068 1069/1/1069 1070/1/1070 +f 1036/1/1036 1068/1/1068 1070/1/1070 +f 1036/1/1036 1070/1/1070 1032/1/1032 +f 1033/1/1033 1036/1/1036 1032/1/1032 +f 1033/1/1033 1032/1/1032 1030/1/1030 +f 1034/1/1034 1033/1/1033 1030/1/1030 +f 1034/1/1034 1030/1/1030 1035/1/1035 +f 1048/1/1048 1034/1/1034 1035/1/1035 +f 1048/1/1048 1035/1/1035 1025/1/1025 +f 1021/1/1021 1048/1/1048 1025/1/1025 +f 1021/1/1021 1025/1/1025 1019/1/1019 +f 1018/1/1018 1021/1/1021 1019/1/1019 +f 1018/1/1018 1019/1/1019 1014/1/1014 +f 1012/1/1012 1018/1/1018 1014/1/1014 +f 1012/1/1012 1014/1/1014 1009/1/1009 +f 1008/1/1008 1012/1/1012 1009/1/1009 +f 1008/1/1008 1013/1/1013 1012/1/1012 +f 1009/1/1009 1014/1/1014 1015/1/1015 +f 1009/1/1009 1015/1/1015 1010/1/1010 +f 1006/1/1006 1009/1/1009 1010/1/1010 +f 1010/1/1010 1015/1/1015 1016/1/1016 +f 1010/1/1010 1016/1/1016 1011/1/1011 +f 1015/1/1015 1017/1/1017 1016/1/1016 +f 1017/1/1017 1024/1/1024 1016/1/1016 +f 1016/1/1016 1024/1/1024 1029/1/1029 +f 1016/1/1016 1029/1/1029 1313/1/1313 +f 1313/1/1313 1029/1/1029 988/1/988 +f 1024/1/1024 1028/1/1028 1029/1/1029 +f 1029/1/1029 1028/1/1028 987/1/987 +f 1024/1/1024 1023/1/1023 1028/1/1028 +f 1023/1/1023 1027/1/1027 1028/1/1028 +f 1028/1/1028 1027/1/1027 981/1/981 +f 1023/1/1023 1026/1/1026 1027/1/1027 +f 1026/1/1026 982/1/982 1027/1/1027 +f 1026/1/1026 1030/1/1030 982/1/982 +f 1022/1/1022 1026/1/1026 1023/1/1023 +f 1017/1/1017 1022/1/1022 1023/1/1023 +f 1019/1/1019 1022/1/1022 1017/1/1017 +f 1025/1/1025 1026/1/1026 1022/1/1022 +f 1017/1/1017 1023/1/1023 1024/1/1024 +f 1014/1/1014 1017/1/1017 1015/1/1015 +f 1013/1/1013 1018/1/1018 1012/1/1012 +f 1013/1/1013 1020/1/1020 1018/1/1018 +f 1314/1/1314 1020/1/1020 1013/1/1013 +f 1316/1/1316 1314/1/1314 1013/1/1013 +f 1316/1/1316 1317/1/1317 1314/1/1314 +f 1317/1/1317 1315/1/1315 1314/1/1314 +f 1317/1/1317 1318/1/1318 1315/1/1315 +f 1318/1/1318 1045/1/1045 1315/1/1315 +f 1315/1/1315 1045/1/1045 1020/1/1020 +f 1045/1/1045 1047/1/1047 1020/1/1020 +f 1020/1/1020 1047/1/1047 1021/1/1021 +f 1045/1/1045 1046/1/1046 1047/1/1047 +f 1047/1/1047 1046/1/1046 1048/1/1048 +f 1045/1/1045 1043/1/1043 1046/1/1046 +f 1043/1/1043 1034/1/1034 1046/1/1046 +f 1043/1/1043 1038/1/1038 1034/1/1034 +f 1042/1/1042 1038/1/1038 1043/1/1043 +f 1044/1/1044 1042/1/1042 1043/1/1043 +f 1684/1/1684 1042/1/1042 1044/1/1044 +f 1776/1/1776 1684/1/1684 1044/1/1044 +f 1776/1/1776 1044/1/1044 1318/1/1318 +f 1777/1/1777 1776/1/1776 1318/1/1318 +f 1665/1/1665 1776/1/1776 1777/1/1777 +f 1659/1/1659 1665/1/1665 1777/1/1777 +f 1659/1/1659 1777/1/1777 1317/1/1317 +f 1661/1/1661 1665/1/1665 1659/1/1659 +f 1658/1/1658 1661/1/1661 1659/1/1659 +f 1658/1/1658 1659/1/1659 1657/1/1657 +f 1660/1/1660 1661/1/1661 1658/1/1658 +f 1307/1/1307 1660/1/1660 1658/1/1658 +f 1307/1/1307 1658/1/1658 1310/1/1310 +f 1087/1/1087 1660/1/1660 1307/1/1307 +f 1083/1/1083 1087/1/1087 1307/1/1307 +f 1083/1/1083 1307/1/1307 1306/1/1306 +f 1084/1/1084 1087/1/1087 1083/1/1083 +f 1081/1/1081 1084/1/1084 1083/1/1083 +f 1081/1/1081 1083/1/1083 1080/1/1080 +f 1080/1/1080 1078/1/1078 1081/1/1081 +f 1081/1/1081 1078/1/1078 1082/1/1082 +f 1082/1/1082 1078/1/1078 1079/1/1079 +f 1082/1/1082 1079/1/1079 1085/1/1085 +f 1085/1/1085 1084/1/1084 1082/1/1082 +f 1085/1/1085 1088/1/1088 1084/1/1084 +f 1088/1/1088 1086/1/1086 1084/1/1084 +f 1088/1/1088 1098/1/1098 1086/1/1086 +f 1098/1/1098 1711/1/1711 1086/1/1086 +f 1086/1/1086 1711/1/1711 1714/1/1714 +f 1086/1/1086 1714/1/1714 1664/1/1664 +f 1086/1/1086 1664/1/1664 1087/1/1087 +f 1714/1/1714 1715/1/1715 1664/1/1664 +f 1664/1/1664 1715/1/1715 1662/1/1662 +f 1664/1/1664 1662/1/1662 1660/1/1660 +f 1660/1/1660 1662/1/1662 1663/1/1663 +f 1662/1/1662 1668/1/1668 1663/1/1663 +f 1663/1/1663 1668/1/1668 1667/1/1667 +f 1663/1/1663 1667/1/1667 1666/1/1666 +f 1663/1/1663 1666/1/1666 1661/1/1661 +f 1667/1/1667 1670/1/1670 1666/1/1666 +f 1666/1/1666 1670/1/1670 1669/1/1669 +f 1666/1/1666 1669/1/1669 1665/1/1665 +f 1665/1/1665 1669/1/1669 1775/1/1775 +f 1669/1/1669 1677/1/1677 1775/1/1775 +f 1677/1/1677 1684/1/1684 1775/1/1775 +f 1677/1/1677 1683/1/1683 1684/1/1684 +f 1677/1/1677 1679/1/1679 1683/1/1683 +f 1679/1/1679 1682/1/1682 1683/1/1683 +f 1683/1/1683 1682/1/1682 1040/1/1040 +f 1683/1/1683 1040/1/1040 1042/1/1042 +f 1682/1/1682 1037/1/1037 1040/1/1040 +f 1040/1/1040 1037/1/1037 1038/1/1038 +f 1038/1/1038 1037/1/1037 1033/1/1033 +f 1682/1/1682 1041/1/1041 1037/1/1037 +f 1041/1/1041 1039/1/1039 1037/1/1037 +f 1037/1/1037 1039/1/1039 1036/1/1036 +f 1041/1/1041 1049/1/1049 1039/1/1039 +f 1049/1/1049 1062/1/1062 1039/1/1039 +f 1039/1/1039 1062/1/1062 1064/1/1064 +f 1039/1/1039 1064/1/1064 1068/1/1068 +f 1064/1/1064 1067/1/1067 1068/1/1068 +f 1064/1/1064 1063/1/1063 1067/1/1067 +f 1063/1/1063 1066/1/1066 1067/1/1067 +f 1066/1/1066 1078/1/1078 1067/1/1067 +f 1067/1/1067 1078/1/1078 1075/1/1075 +f 1067/1/1067 1075/1/1075 1073/1/1073 +f 1067/1/1067 1073/1/1073 1069/1/1069 +f 1073/1/1073 1075/1/1075 1076/1/1076 +f 1073/1/1073 1076/1/1076 1074/1/1074 +f 1074/1/1074 1076/1/1076 1309/1/1309 +f 1076/1/1076 1075/1/1075 1077/1/1077 +f 1305/1/1305 1076/1/1076 1077/1/1077 +f 1077/1/1077 1083/1/1083 1305/1/1305 +f 1077/1/1077 1075/1/1075 1080/1/1080 +f 1061/1/1061 1066/1/1066 1063/1/1063 +f 1062/1/1062 1061/1/1061 1063/1/1063 +f 1057/1/1057 1061/1/1061 1062/1/1062 +f 1057/1/1057 1059/1/1059 1061/1/1061 +f 1059/1/1059 1065/1/1065 1061/1/1061 +f 1059/1/1059 1095/1/1095 1065/1/1065 +f 1095/1/1095 1093/1/1093 1065/1/1065 +f 1065/1/1065 1093/1/1093 1079/1/1079 +f 1065/1/1065 1079/1/1079 1066/1/1066 +f 1089/1/1089 1079/1/1079 1093/1/1093 +f 1089/1/1089 1093/1/1093 1090/1/1090 +f 1090/1/1090 1088/1/1088 1089/1/1089 +f 1091/1/1091 1088/1/1088 1090/1/1090 +f 1091/1/1091 1092/1/1092 1088/1/1088 +f 1096/1/1096 1092/1/1092 1091/1/1091 +f 1091/1/1091 1094/1/1094 1096/1/1096 +f 1096/1/1096 1094/1/1094 1100/1/1100 +f 1096/1/1096 1100/1/1100 1099/1/1099 +f 1099/1/1099 1097/1/1097 1096/1/1096 +f 1101/1/1101 1097/1/1097 1099/1/1099 +f 1101/1/1101 1102/1/1102 1097/1/1097 +f 1102/1/1102 1128/1/1128 1097/1/1097 +f 1097/1/1097 1128/1/1128 1098/1/1098 +f 1097/1/1097 1098/1/1098 1092/1/1092 +f 1128/1/1128 1712/1/1712 1098/1/1098 +f 1128/1/1128 1724/1/1724 1712/1/1712 +f 1724/1/1724 1708/1/1708 1712/1/1712 +f 1712/1/1712 1708/1/1708 1707/1/1707 +f 1712/1/1712 1707/1/1707 1711/1/1711 +f 1711/1/1711 1707/1/1707 1710/1/1710 +f 1707/1/1707 1704/1/1704 1710/1/1710 +f 1710/1/1710 1704/1/1704 1709/1/1709 +f 1710/1/1710 1709/1/1709 1713/1/1713 +f 1710/1/1710 1713/1/1713 1715/1/1715 +f 1715/1/1715 1713/1/1713 1718/1/1718 +f 1715/1/1715 1718/1/1718 1721/1/1721 +f 1718/1/1718 1720/1/1720 1721/1/1721 +f 1721/1/1721 1720/1/1720 1722/1/1722 +f 1721/1/1721 1722/1/1722 1672/1/1672 +f 1662/1/1662 1721/1/1721 1672/1/1672 +f 1672/1/1672 1722/1/1722 1673/1/1673 +f 1672/1/1672 1673/1/1673 1668/1/1668 +f 1668/1/1668 1673/1/1673 1671/1/1671 +f 1673/1/1673 1674/1/1674 1671/1/1671 +f 1674/1/1674 1675/1/1675 1671/1/1671 +f 1671/1/1671 1675/1/1675 1676/1/1676 +f 1671/1/1671 1676/1/1676 1670/1/1670 +f 1670/1/1670 1676/1/1676 1677/1/1677 +f 1675/1/1675 1678/1/1678 1676/1/1676 +f 1676/1/1676 1678/1/1678 1679/1/1679 +f 1675/1/1675 1680/1/1680 1678/1/1678 +f 1680/1/1680 1681/1/1681 1678/1/1678 +f 1678/1/1678 1681/1/1681 1682/1/1682 +f 1685/1/1685 1681/1/1681 1680/1/1680 +f 1674/1/1674 1685/1/1685 1680/1/1680 +f 1688/1/1688 1685/1/1685 1674/1/1674 +f 1722/1/1722 1688/1/1688 1674/1/1674 +f 1688/1/1688 1687/1/1687 1685/1/1685 +f 1687/1/1687 1686/1/1686 1685/1/1685 +f 1687/1/1687 1312/1/1312 1686/1/1686 +f 1312/1/1312 1050/1/1050 1686/1/1686 +f 1686/1/1686 1050/1/1050 1681/1/1681 +f 1681/1/1681 1050/1/1050 1041/1/1041 +f 1312/1/1312 1056/1/1056 1050/1/1050 +f 1056/1/1056 1051/1/1051 1050/1/1050 +f 1050/1/1050 1051/1/1051 1052/1/1052 +f 1050/1/1050 1052/1/1052 1049/1/1049 +f 1052/1/1052 1057/1/1057 1049/1/1049 +f 1052/1/1052 1055/1/1055 1057/1/1057 +f 1051/1/1051 1055/1/1055 1052/1/1052 +f 1051/1/1051 1054/1/1054 1055/1/1055 +f 1054/1/1054 1060/1/1060 1055/1/1055 +f 1055/1/1055 1060/1/1060 1058/1/1058 +f 1055/1/1055 1058/1/1058 1059/1/1059 +f 1060/1/1060 1094/1/1094 1058/1/1058 +f 1058/1/1058 1094/1/1094 1093/1/1093 +f 1060/1/1060 1303/1/1303 1094/1/1094 +f 1302/1/1302 1303/1/1303 1060/1/1060 +f 1301/1/1301 1302/1/1302 1060/1/1060 +f 1301/1/1301 1104/1/1104 1302/1/1302 +f 1301/1/1301 1109/1/1109 1104/1/1104 +f 1109/1/1109 1105/1/1105 1104/1/1104 +f 1101/1/1101 1104/1/1104 1105/1/1105 +f 1101/1/1101 1105/1/1105 1103/1/1103 +f 1103/1/1103 1105/1/1105 1106/1/1106 +f 1106/1/1106 1102/1/1102 1103/1/1103 +f 1106/1/1106 1111/1/1111 1102/1/1102 +f 1111/1/1111 1127/1/1127 1102/1/1102 +f 1111/1/1111 1756/1/1756 1127/1/1127 +f 1756/1/1756 1727/1/1727 1127/1/1127 +f 1727/1/1727 1724/1/1724 1127/1/1127 +f 1727/1/1727 1726/1/1726 1724/1/1724 +f 1726/1/1726 1725/1/1725 1724/1/1724 +f 1726/1/1726 1729/1/1729 1725/1/1725 +f 1729/1/1729 1728/1/1728 1725/1/1725 +f 1725/1/1725 1728/1/1728 1708/1/1708 +f 1708/1/1708 1728/1/1728 1705/1/1705 +f 1708/1/1708 1705/1/1705 1703/1/1703 +f 1705/1/1705 1699/1/1699 1703/1/1703 +f 1703/1/1703 1699/1/1699 1701/1/1701 +f 1703/1/1703 1701/1/1701 1704/1/1704 +f 1704/1/1704 1701/1/1701 1702/1/1702 +f 1701/1/1701 1697/1/1697 1702/1/1702 +f 1702/1/1702 1697/1/1697 1693/1/1693 +f 1702/1/1702 1693/1/1693 1716/1/1716 +f 1709/1/1709 1702/1/1702 1716/1/1716 +f 1716/1/1716 1693/1/1693 1719/1/1719 +f 1716/1/1716 1719/1/1719 1717/1/1717 +f 1713/1/1713 1716/1/1716 1717/1/1717 +f 1717/1/1717 1719/1/1719 1720/1/1720 +f 1719/1/1719 1723/1/1723 1720/1/1720 +f 1720/1/1720 1723/1/1723 1688/1/1688 +f 1719/1/1719 1690/1/1690 1723/1/1723 +f 1723/1/1723 1690/1/1690 1687/1/1687 +f 1719/1/1719 1689/1/1689 1690/1/1690 +f 1689/1/1689 1312/1/1312 1690/1/1690 +f 1689/1/1689 1311/1/1311 1312/1/1312 +f 1692/1/1692 1311/1/1311 1689/1/1689 +f 1693/1/1693 1692/1/1692 1689/1/1689 +f 1694/1/1694 1692/1/1692 1693/1/1693 +f 1694/1/1694 1695/1/1695 1692/1/1692 +f 1695/1/1695 1691/1/1691 1692/1/1692 +f 1698/1/1698 1691/1/1691 1695/1/1695 +f 1696/1/1696 1698/1/1698 1695/1/1695 +f 1700/1/1700 1698/1/1698 1696/1/1696 +f 1699/1/1699 1700/1/1700 1696/1/1696 +f 1706/1/1706 1700/1/1700 1699/1/1699 +f 1706/1/1706 1735/1/1735 1700/1/1700 +f 1735/1/1735 1737/1/1737 1700/1/1700 +f 1735/1/1735 1736/1/1736 1737/1/1737 +f 1736/1/1736 1304/1/1304 1737/1/1737 +f 1737/1/1737 1304/1/1304 1698/1/1698 +f 1736/1/1736 1148/1/1148 1304/1/1304 +f 1148/1/1148 1149/1/1149 1304/1/1304 +f 1304/1/1304 1149/1/1149 1053/1/1053 +f 1304/1/1304 1053/1/1053 1691/1/1691 +f 1691/1/1691 1053/1/1053 1056/1/1056 +f 1691/1/1691 1056/1/1056 1311/1/1311 +f 1149/1/1149 1300/1/1300 1053/1/1053 +f 1053/1/1053 1300/1/1300 1054/1/1054 +f 1300/1/1300 1301/1/1301 1054/1/1054 +f 1149/1/1149 1144/1/1144 1300/1/1300 +f 1144/1/1144 1109/1/1109 1300/1/1300 +f 1144/1/1144 1115/1/1115 1109/1/1109 +f 1115/1/1115 1108/1/1108 1109/1/1109 +f 1114/1/1114 1108/1/1108 1115/1/1115 +f 1114/1/1114 1113/1/1113 1108/1/1108 +f 1113/1/1113 1107/1/1107 1108/1/1108 +f 1108/1/1108 1107/1/1107 1105/1/1105 +f 1113/1/1113 1112/1/1112 1107/1/1107 +f 1110/1/1110 1107/1/1107 1112/1/1112 +f 1110/1/1110 1112/1/1112 1119/1/1119 +f 1119/1/1119 1123/1/1123 1110/1/1110 +f 1110/1/1110 1123/1/1123 1111/1/1111 +f 1120/1/1120 1123/1/1123 1119/1/1119 +f 1119/1/1119 1118/1/1118 1120/1/1120 +f 1120/1/1120 1118/1/1118 1121/1/1121 +f 1121/1/1121 1124/1/1124 1120/1/1120 +f 1125/1/1125 1124/1/1124 1121/1/1121 +f 1121/1/1121 1122/1/1122 1125/1/1125 +f 1125/1/1125 1122/1/1122 1130/1/1130 +f 1130/1/1130 2435/1/2435 1125/1/1125 +f 1137/1/1137 2435/1/2435 1130/1/1130 +f 1137/1/1137 1130/1/1130 1129/1/1129 +f 1134/1/1134 1137/1/1137 1129/1/1129 +f 1134/1/1134 1129/1/1129 1133/1/1133 +f 1134/1/1134 1133/1/1133 1135/1/1135 +f 1134/1/1134 1135/1/1135 2436/1/2436 +f 1135/1/1135 2439/1/2439 2436/1/2436 +f 2436/1/2436 2439/1/2439 2437/1/2437 +f 2437/1/2437 2438/1/2438 2436/1/2436 +f 2436/1/2436 2438/1/2438 2434/1/2434 +f 2436/1/2436 2434/1/2434 1137/1/1137 +f 2438/1/2438 1759/1/1759 2434/1/2434 +f 2434/1/2434 1759/1/1759 1757/1/1757 +f 2434/1/2434 1757/1/1757 2435/1/2435 +f 2435/1/2435 1757/1/1757 1124/1/1124 +f 1124/1/1124 1757/1/1757 1126/1/1126 +f 1124/1/1124 1126/1/1126 1123/1/1123 +f 1123/1/1123 1126/1/1126 1756/1/1756 +f 1126/1/1126 1755/1/1755 1756/1/1756 +f 1126/1/1126 1754/1/1754 1755/1/1755 +f 1755/1/1755 1754/1/1754 1753/1/1753 +f 1755/1/1755 1753/1/1753 1727/1/1727 +f 1753/1/1753 1754/1/1754 1749/1/1749 +f 1748/1/1748 1753/1/1753 1749/1/1749 +f 1748/1/1748 1749/1/1749 1747/1/1747 +f 1746/1/1746 1748/1/1748 1747/1/1747 +f 1746/1/1746 1747/1/1747 1743/1/1743 +f 1743/1/1743 1739/1/1739 1746/1/1746 +f 1746/1/1746 1739/1/1739 1731/1/1731 +f 1746/1/1746 1731/1/1731 1733/1/1733 +f 1733/1/1733 1731/1/1731 1729/1/1729 +f 1731/1/1731 1732/1/1732 1729/1/1729 +f 1729/1/1729 1732/1/1732 1730/1/1730 +f 1730/1/1730 1732/1/1732 1734/1/1734 +f 1730/1/1730 1734/1/1734 1735/1/1735 +f 1732/1/1732 1738/1/1738 1734/1/1734 +f 1734/1/1734 1738/1/1738 1736/1/1736 +f 1738/1/1738 1740/1/1740 1736/1/1736 +f 1739/1/1739 1740/1/1740 1738/1/1738 +f 1741/1/1741 1740/1/1740 1739/1/1739 +f 1741/1/1741 1148/1/1148 1740/1/1740 +f 1147/1/1147 1148/1/1148 1741/1/1741 +f 1742/1/1742 1147/1/1147 1741/1/1741 +f 1742/1/1742 1741/1/1741 1743/1/1743 +f 1743/1/1743 1744/1/1744 1742/1/1742 +f 1742/1/1742 1744/1/1744 1152/1/1152 +f 1744/1/1744 1745/1/1745 1152/1/1152 +f 1152/1/1152 1745/1/1745 1153/1/1153 +f 1152/1/1152 1153/1/1153 1150/1/1150 +f 1147/1/1147 1152/1/1152 1150/1/1150 +f 1147/1/1147 1150/1/1150 1146/1/1146 +f 1146/1/1146 1145/1/1145 1147/1/1147 +f 1146/1/1146 1142/1/1142 1145/1/1145 +f 1142/1/1142 1141/1/1141 1145/1/1145 +f 1145/1/1145 1141/1/1141 1143/1/1143 +f 1145/1/1145 1143/1/1143 1144/1/1144 +f 1143/1/1143 1114/1/1114 1144/1/1144 +f 1141/1/1141 1114/1/1114 1143/1/1143 +f 1141/1/1141 1116/1/1116 1114/1/1114 +f 1141/1/1141 1140/1/1140 1116/1/1116 +f 1140/1/1140 1117/1/1117 1116/1/1116 +f 1116/1/1116 1117/1/1117 1113/1/1113 +f 1117/1/1117 1118/1/1118 1113/1/1113 +f 1117/1/1117 1122/1/1122 1118/1/1118 +f 1132/1/1132 1122/1/1122 1117/1/1117 +f 1131/1/1131 1122/1/1122 1132/1/1132 +f 1133/1/1133 1131/1/1131 1132/1/1132 +f 1133/1/1133 1132/1/1132 1136/1/1136 +f 1136/1/1136 1139/1/1139 1133/1/1133 +f 1133/1/1133 1139/1/1139 2448/1/2448 +f 1139/1/1139 1278/1/1278 2448/1/2448 +f 2448/1/2448 1278/1/1278 2447/1/2447 +f 2448/1/2448 2447/1/2447 2444/1/2444 +f 1135/1/1135 2448/1/2448 2444/1/2444 +f 2444/1/2444 2447/1/2447 2445/1/2445 +f 2444/1/2444 2445/1/2445 2443/1/2443 +f 2439/1/2439 2444/1/2444 2443/1/2443 +f 2439/1/2439 2443/1/2443 2440/1/2440 +f 2440/1/2440 2443/1/2443 2441/1/2441 +f 2440/1/2440 2441/1/2441 2438/1/2438 +f 2443/1/2443 2442/1/2442 2441/1/2441 +f 2442/1/2442 1761/1/1761 2441/1/2441 +f 1761/1/1761 1759/1/1759 2441/1/2441 +f 1198/1/1198 1759/1/1759 1761/1/1761 +f 1198/1/1198 1761/1/1761 1201/1/1201 +f 1198/1/1198 1201/1/1201 1200/1/1200 +f 1197/1/1197 1198/1/1198 1200/1/1200 +f 1197/1/1197 1200/1/1200 1194/1/1194 +f 1191/1/1191 1197/1/1197 1194/1/1194 +f 1191/1/1191 1194/1/1194 1190/1/1190 +f 1190/1/1190 1186/1/1186 1191/1/1191 +f 1191/1/1191 1186/1/1186 1183/1/1183 +f 1191/1/1191 1183/1/1183 1195/1/1195 +f 1195/1/1195 1196/1/1196 1191/1/1191 +f 1198/1/1198 1196/1/1196 1195/1/1195 +f 1198/1/1198 1195/1/1195 1199/1/1199 +f 1195/1/1195 1182/1/1182 1199/1/1199 +f 1199/1/1199 1182/1/1182 1181/1/1181 +f 1199/1/1199 1181/1/1181 1178/1/1178 +f 1199/1/1199 1178/1/1178 1758/1/1758 +f 1759/1/1759 1199/1/1199 1758/1/1758 +f 1758/1/1758 1178/1/1178 1760/1/1760 +f 1758/1/1758 1760/1/1760 1126/1/1126 +f 1126/1/1126 1760/1/1760 1772/1/1772 +f 1772/1/1772 1760/1/1760 1172/1/1172 +f 1773/1/1773 1772/1/1772 1172/1/1172 +f 1773/1/1773 1172/1/1172 1174/1/1174 +f 1175/1/1175 1773/1/1773 1174/1/1174 +f 1175/1/1175 1174/1/1174 1161/1/1161 +f 1160/1/1160 1175/1/1175 1161/1/1161 +f 1160/1/1160 1161/1/1161 1158/1/1158 +f 1153/1/1153 1160/1/1160 1158/1/1158 +f 1153/1/1153 1158/1/1158 1154/1/1154 +f 1158/1/1158 1159/1/1159 1154/1/1154 +f 1154/1/1154 1159/1/1159 1157/1/1157 +f 1154/1/1154 1157/1/1157 1155/1/1155 +f 1151/1/1151 1154/1/1154 1155/1/1155 +f 1151/1/1151 1155/1/1155 1139/1/1139 +f 1146/1/1146 1151/1/1151 1139/1/1139 +f 1139/1/1139 1155/1/1155 1156/1/1156 +f 1150/1/1150 1154/1/1154 1151/1/1151 +f 1155/1/1155 1157/1/1157 1156/1/1156 +f 1157/1/1157 1168/1/1168 1156/1/1156 +f 1156/1/1156 1168/1/1168 1275/1/1275 +f 1156/1/1156 1275/1/1275 1278/1/1278 +f 1278/1/1278 1275/1/1275 1277/1/1277 +f 1275/1/1275 1276/1/1276 1277/1/1277 +f 1277/1/1277 1276/1/1276 2451/1/2451 +f 1277/1/1277 2451/1/2451 2449/1/2449 +f 2447/1/2447 1277/1/1277 2449/1/2449 +f 2449/1/2449 2451/1/2451 2452/1/2452 +f 2449/1/2449 2452/1/2452 2450/1/2450 +f 2445/1/2445 2449/1/2449 2450/1/2450 +f 2445/1/2445 2450/1/2450 2446/1/2446 +f 2446/1/2446 2450/1/2450 2454/1/2454 +f 2446/1/2446 2454/1/2454 2476/1/2476 +f 2442/1/2442 2446/1/2446 2476/1/2476 +f 2476/1/2476 2454/1/2454 1762/1/1762 +f 1762/1/1762 1761/1/1761 2476/1/2476 +f 1762/1/1762 2454/1/2454 1763/1/1763 +f 1763/1/1763 1203/1/1203 1762/1/1762 +f 1762/1/1762 1203/1/1203 1201/1/1201 +f 1201/1/1201 1203/1/1203 1202/1/1202 +f 1202/1/1202 1203/1/1203 1204/1/1204 +f 1202/1/1202 1204/1/1204 1205/1/1205 +f 1206/1/1206 1202/1/1202 1205/1/1205 +f 1206/1/1206 1205/1/1205 1207/1/1207 +f 1208/1/1208 1206/1/1206 1207/1/1207 +f 1208/1/1208 1207/1/1207 1273/1/1273 +f 1192/1/1192 1208/1/1208 1273/1/1273 +f 1192/1/1192 1273/1/1273 1271/1/1271 +f 1271/1/1271 1274/1/1274 1192/1/1192 +f 1188/1/1188 1192/1/1192 1274/1/1274 +f 1275/1/1275 1188/1/1188 1274/1/1274 +f 1188/1/1188 1189/1/1189 1192/1/1192 +f 1193/1/1193 1192/1/1192 1189/1/1189 +f 1193/1/1193 1189/1/1189 1190/1/1190 +f 1187/1/1187 1189/1/1189 1188/1/1188 +f 1185/1/1185 1187/1/1187 1188/1/1188 +f 1168/1/1168 1185/1/1185 1188/1/1188 +f 1167/1/1167 1185/1/1185 1168/1/1168 +f 1165/1/1165 1167/1/1167 1168/1/1168 +f 1165/1/1165 1166/1/1166 1167/1/1167 +f 1166/1/1166 1170/1/1170 1167/1/1167 +f 1169/1/1169 1170/1/1170 1166/1/1166 +f 1164/1/1164 1169/1/1169 1166/1/1166 +f 1171/1/1171 1169/1/1169 1164/1/1164 +f 1162/1/1162 1171/1/1171 1164/1/1164 +f 1162/1/1162 1164/1/1164 1163/1/1163 +f 1159/1/1159 1162/1/1162 1163/1/1163 +f 1161/1/1161 1162/1/1162 1159/1/1159 +f 1163/1/1163 1164/1/1164 1165/1/1165 +f 1163/1/1163 1165/1/1165 1157/1/1157 +f 1174/1/1174 1171/1/1171 1162/1/1162 +f 1171/1/1171 1173/1/1173 1169/1/1169 +f 1173/1/1173 1176/1/1176 1169/1/1169 +f 1169/1/1169 1176/1/1176 1177/1/1177 +f 1176/1/1176 1179/1/1179 1177/1/1177 +f 1177/1/1177 1179/1/1179 1180/1/1180 +f 1177/1/1177 1180/1/1180 1170/1/1170 +f 1170/1/1170 1180/1/1180 1184/1/1184 +f 1170/1/1170 1184/1/1184 1185/1/1185 +f 1180/1/1180 1183/1/1183 1184/1/1184 +f 1180/1/1180 1182/1/1182 1183/1/1183 +f 1179/1/1179 1182/1/1182 1180/1/1180 +f 1176/1/1176 1178/1/1178 1179/1/1179 +f 1173/1/1173 1178/1/1178 1176/1/1176 +f 1172/1/1172 1173/1/1173 1171/1/1171 +f 1169/1/1169 1177/1/1177 1170/1/1170 +f 1164/1/1164 1166/1/1166 1165/1/1165 +f 1167/1/1167 1170/1/1170 1185/1/1185 +f 1185/1/1185 1184/1/1184 1187/1/1187 +f 1184/1/1184 1186/1/1186 1187/1/1187 +f 1187/1/1187 1186/1/1186 1189/1/1189 +f 1271/1/1271 1272/1/1272 1274/1/1274 +f 1276/1/1276 1274/1/1274 1272/1/1272 +f 1270/1/1270 1272/1/1272 1271/1/1271 +f 1271/1/1271 1222/1/1222 1270/1/1270 +f 1270/1/1270 1222/1/1222 1269/1/1269 +f 1270/1/1270 1269/1/1269 2457/1/2457 +f 2455/1/2455 1270/1/1270 2457/1/2457 +f 2455/1/2455 2457/1/2457 2458/1/2458 +f 2458/1/2458 2456/1/2456 2455/1/2455 +f 2452/1/2452 2455/1/2455 2456/1/2456 +f 2453/1/2453 2452/1/2452 2456/1/2456 +f 2453/1/2453 2456/1/2456 2454/1/2454 +f 2454/1/2454 2456/1/2456 2474/1/2474 +f 2456/1/2456 2475/1/2475 2474/1/2474 +f 2474/1/2474 2475/1/2475 2473/1/2473 +f 2474/1/2474 2473/1/2473 1763/1/1763 +f 1764/1/1764 1763/1/1763 2473/1/2473 +f 1764/1/1764 2473/1/2473 2471/1/2471 +f 2471/1/2471 2467/1/2467 1764/1/1764 +f 1764/1/1764 2467/1/2467 1765/1/1765 +f 1212/1/1212 1764/1/1764 1765/1/1765 +f 1212/1/1212 1765/1/1765 1235/1/1235 +f 1229/1/1229 1212/1/1212 1235/1/1235 +f 1229/1/1229 1235/1/1235 1228/1/1228 +f 1228/1/1228 1224/1/1224 1229/1/1229 +f 1229/1/1229 1224/1/1224 1213/1/1213 +f 1224/1/1224 1219/1/1219 1213/1/1213 +f 1213/1/1213 1219/1/1219 1217/1/1217 +f 1213/1/1213 1217/1/1217 1214/1/1214 +f 1213/1/1213 1214/1/1214 1211/1/1211 +f 1212/1/1212 1213/1/1213 1211/1/1211 +f 1203/1/1203 1212/1/1212 1211/1/1211 +f 1211/1/1211 1214/1/1214 1209/1/1209 +f 1211/1/1211 1209/1/1209 1204/1/1204 +f 1214/1/1214 1215/1/1215 1209/1/1209 +f 1210/1/1210 1209/1/1209 1215/1/1215 +f 1210/1/1210 1215/1/1215 1216/1/1216 +f 1207/1/1207 1210/1/1210 1216/1/1216 +f 1216/1/1216 1215/1/1215 1218/1/1218 +f 1216/1/1216 1218/1/1218 1222/1/1222 +f 1218/1/1218 1221/1/1221 1222/1/1222 +f 1220/1/1220 1221/1/1221 1218/1/1218 +f 1219/1/1219 1220/1/1220 1218/1/1218 +f 1223/1/1223 1220/1/1220 1219/1/1219 +f 1223/1/1223 1225/1/1225 1220/1/1220 +f 1226/1/1226 1225/1/1225 1223/1/1223 +f 1227/1/1227 1226/1/1226 1223/1/1223 +f 1227/1/1227 1223/1/1223 1224/1/1224 +f 1230/1/1230 1226/1/1226 1227/1/1227 +f 1231/1/1231 1230/1/1230 1227/1/1227 +f 1231/1/1231 1227/1/1227 1228/1/1228 +f 1234/1/1234 1230/1/1230 1231/1/1231 +f 1231/1/1231 1235/1/1235 1234/1/1234 +f 1236/1/1236 1234/1/1234 1235/1/1235 +f 1235/1/1235 1766/1/1766 1236/1/1236 +f 1236/1/1236 1766/1/1766 1767/1/1767 +f 1767/1/1767 1299/1/1299 1236/1/1236 +f 1236/1/1236 1299/1/1299 1298/1/1298 +f 1298/1/1298 1237/1/1237 1236/1/1236 +f 1298/1/1298 1239/1/1239 1237/1/1237 +f 1239/1/1239 1240/1/1240 1237/1/1237 +f 1237/1/1237 1240/1/1240 1238/1/1238 +f 1237/1/1237 1238/1/1238 1233/1/1233 +f 1237/1/1237 1233/1/1233 1234/1/1234 +f 1233/1/1233 1238/1/1238 1232/1/1232 +f 1233/1/1233 1232/1/1232 1230/1/1230 +f 1238/1/1238 1241/1/1241 1232/1/1232 +f 1232/1/1232 1241/1/1241 1225/1/1225 +f 1241/1/1241 1267/1/1267 1225/1/1225 +f 1225/1/1225 1267/1/1267 1221/1/1221 +f 1267/1/1267 1268/1/1268 1221/1/1221 +f 1221/1/1221 1268/1/1268 1269/1/1269 +f 1268/1/1268 2459/1/2459 1269/1/1269 +f 1268/1/1268 1297/1/1297 2459/1/2459 +f 1297/1/1297 2461/1/2461 2459/1/2459 +f 2459/1/2459 2461/1/2461 2465/1/2465 +f 2466/1/2466 2459/1/2459 2465/1/2465 +f 2468/1/2468 2466/1/2466 2465/1/2465 +f 2468/1/2468 2465/1/2465 2467/1/2467 +f 2465/1/2465 2464/1/2464 2467/1/2467 +f 2467/1/2467 2464/1/2464 2469/1/2469 +f 2463/1/2463 2469/1/2469 2464/1/2464 +f 2461/1/2461 2463/1/2463 2464/1/2464 +f 2460/1/2460 2463/1/2463 2461/1/2461 +f 2460/1/2460 2462/1/2462 2463/1/2463 +f 2462/1/2462 2470/1/2470 2463/1/2463 +f 2462/1/2462 2477/1/2477 2470/1/2470 +f 2470/1/2470 2477/1/2477 1766/1/1766 +f 2470/1/2470 1766/1/1766 2469/1/2469 +f 1766/1/1766 1765/1/1765 2469/1/2469 +f 2462/1/2462 1296/1/1296 2477/1/2477 +f 1296/1/1296 1767/1/1767 2477/1/2477 +f 1767/1/1767 1296/1/1296 2478/1/2478 +f 1767/1/1767 2478/1/2478 1292/1/1292 +f 1292/1/1292 1768/1/1768 1767/1/1767 +f 1768/1/1768 1292/1/1292 1290/1/1290 +f 1768/1/1768 1290/1/1290 1769/1/1769 +f 1768/1/1768 1769/1/1769 2515/1/2515 +f 2515/1/2515 1252/1/1252 1768/1/1768 +f 1768/1/1768 1252/1/1252 1250/1/1250 +f 1768/1/1768 1250/1/1250 1299/1/1299 +f 1299/1/1299 1250/1/1250 1244/1/1244 +f 1250/1/1250 1245/1/1245 1244/1/1244 +f 1244/1/1244 1245/1/1245 1242/1/1242 +f 1244/1/1244 1242/1/1242 1239/1/1239 +f 1245/1/1245 1243/1/1243 1242/1/1242 +f 1242/1/1242 1243/1/1243 1240/1/1240 +f 1240/1/1240 1243/1/1243 1241/1/1241 +f 1243/1/1243 1248/1/1248 1241/1/1241 +f 1243/1/1243 1247/1/1247 1248/1/1248 +f 1247/1/1247 1266/1/1266 1248/1/1248 +f 1248/1/1248 1266/1/1266 1297/1/1297 +f 1266/1/1266 2460/1/2460 1297/1/1297 +f 1266/1/1266 1295/1/1295 2460/1/2460 +f 1265/1/1265 1295/1/1295 1266/1/1266 +f 1265/1/1265 1293/1/1293 1295/1/1295 +f 1293/1/1293 1294/1/1294 1295/1/1295 +f 1295/1/1295 1294/1/1294 1296/1/1296 +f 1293/1/1293 1291/1/1291 1294/1/1294 +f 1291/1/1291 1292/1/1292 1294/1/1294 +f 1281/1/1281 1291/1/1291 1293/1/1293 +f 1282/1/1282 1281/1/1281 1293/1/1293 +f 1263/1/1263 1281/1/1281 1282/1/1282 +f 1262/1/1262 1263/1/1263 1282/1/1282 +f 1262/1/1262 1282/1/1282 1264/1/1264 +f 1254/1/1254 1262/1/1262 1264/1/1264 +f 1254/1/1254 1264/1/1264 1247/1/1247 +f 1246/1/1246 1254/1/1254 1247/1/1247 +f 1253/1/1253 1254/1/1254 1246/1/1246 +f 1251/1/1251 1253/1/1253 1246/1/1246 +f 1251/1/1251 1246/1/1246 1249/1/1249 +f 1252/1/1252 1251/1/1251 1249/1/1249 +f 1249/1/1249 1246/1/1246 1245/1/1245 +f 2513/1/2513 1253/1/1253 1251/1/1251 +f 2515/1/2515 2513/1/2513 1251/1/1251 +f 2514/1/2514 2513/1/2513 2515/1/2515 +f 2510/1/2510 2513/1/2513 2514/1/2514 +f 1769/1/1769 2510/1/2510 2514/1/2514 +f 2510/1/2510 1769/1/1769 1770/1/1770 +f 1770/1/1770 2509/1/2509 2510/1/2510 +f 2509/1/2509 2511/1/2511 2510/1/2510 +f 2510/1/2510 2511/1/2511 2512/1/2512 +f 2511/1/2511 1255/1/1255 2512/1/2512 +f 2512/1/2512 1255/1/1255 2513/1/2513 +f 2511/1/2511 1257/1/1257 1255/1/1255 +f 1257/1/1257 1258/1/1258 1255/1/1255 +f 1255/1/1255 1258/1/1258 1256/1/1256 +f 1255/1/1255 1256/1/1256 1253/1/1253 +f 1258/1/1258 1259/1/1259 1256/1/1256 +f 1256/1/1256 1259/1/1259 1262/1/1262 +f 1258/1/1258 1261/1/1261 1259/1/1259 +f 1259/1/1259 1261/1/1261 1263/1/1263 +f 1261/1/1261 1279/1/1279 1263/1/1263 +f 1263/1/1263 1279/1/1279 1280/1/1280 +f 1279/1/1279 1289/1/1289 1280/1/1280 +f 1280/1/1280 1289/1/1289 1290/1/1290 +f 1280/1/1280 1290/1/1290 1291/1/1291 +f 1290/1/1290 1289/1/1289 1770/1/1770 +f 1770/1/1770 1289/1/1289 1288/1/1288 +f 1287/1/1287 1770/1/1770 1288/1/1288 +f 1285/1/1285 1287/1/1287 1288/1/1288 +f 1285/1/1285 1288/1/1288 1286/1/1286 +f 1283/1/1283 1285/1/1285 1286/1/1286 +f 1283/1/1283 1286/1/1286 1279/1/1279 +f 1283/1/1283 1284/1/1284 1285/1/1285 +f 1260/1/1260 1284/1/1284 1283/1/1283 +f 1260/1/1260 1283/1/1283 1261/1/1261 +f 1284/1/1284 1260/1/1260 2504/1/2504 +f 1284/1/1284 2504/1/2504 1287/1/1287 +f 1287/1/1287 2504/1/2504 1771/1/1771 +f 1771/1/1771 2504/1/2504 2506/1/2506 +f 2506/1/2506 1770/1/1770 1771/1/1771 +f 1770/1/1770 2506/1/2506 2507/1/2507 +f 2506/1/2506 2508/1/2508 2507/1/2507 +f 2507/1/2507 2508/1/2508 2511/1/2511 +f 2506/1/2506 2504/1/2504 2508/1/2508 +f 2504/1/2504 2505/1/2505 2508/1/2508 +f 2508/1/2508 2505/1/2505 1257/1/1257 +f 2505/1/2505 2504/1/2504 1258/1/1258 +f 1260/1/1260 1258/1/1258 2504/1/2504 +f 1284/1/1284 1287/1/1287 1285/1/1285 +f 1287/1/1287 1771/1/1771 1770/1/1770 +f 1286/1/1286 1288/1/1288 1289/1/1289 +f 1286/1/1286 1289/1/1289 1279/1/1279 +f 1261/1/1261 1283/1/1283 1279/1/1279 +f 1258/1/1258 1260/1/1260 1261/1/1261 +f 2505/1/2505 1258/1/1258 1257/1/1257 +f 2508/1/2508 1257/1/1257 2511/1/2511 +f 2507/1/2507 2511/1/2511 2509/1/2509 +f 2509/1/2509 1770/1/1770 2507/1/2507 +f 2510/1/2510 2512/1/2512 2513/1/2513 +f 2513/1/2513 1255/1/1255 1253/1/1253 +f 1253/1/1253 1256/1/1256 1254/1/1254 +f 1264/1/1264 1265/1/1265 1247/1/1247 +f 1256/1/1256 1262/1/1262 1254/1/1254 +f 1264/1/1264 1282/1/1282 1265/1/1265 +f 1259/1/1259 1263/1/1263 1262/1/1262 +f 1263/1/1263 1280/1/1280 1281/1/1281 +f 1281/1/1281 1280/1/1280 1291/1/1291 +f 1282/1/1282 1293/1/1293 1265/1/1265 +f 1247/1/1247 1265/1/1265 1266/1/1266 +f 1246/1/1246 1247/1/1247 1243/1/1243 +f 1245/1/1245 1246/1/1246 1243/1/1243 +f 1250/1/1250 1249/1/1249 1245/1/1245 +f 1252/1/1252 1249/1/1249 1250/1/1250 +f 2515/1/2515 1251/1/1251 1252/1/1252 +f 2515/1/2515 1769/1/1769 2514/1/2514 +f 1769/1/1769 1290/1/1290 1770/1/1770 +f 1291/1/1291 1290/1/1290 1292/1/1292 +f 1294/1/1294 1292/1/1292 2478/1/2478 +f 1294/1/1294 2478/1/2478 1296/1/1296 +f 1295/1/1295 1296/1/1296 2462/1/2462 +f 1295/1/1295 2462/1/2462 2460/1/2460 +f 2463/1/2463 2470/1/2470 2469/1/2469 +f 2472/1/2472 2466/1/2466 2468/1/2468 +f 2472/1/2472 2468/1/2468 2471/1/2471 +f 2458/1/2458 2466/1/2466 2472/1/2472 +f 2472/1/2472 2475/1/2475 2458/1/2458 +f 2457/1/2457 2459/1/2459 2466/1/2466 +f 2461/1/2461 2464/1/2464 2465/1/2465 +f 1297/1/1297 2460/1/2460 2461/1/2461 +f 1248/1/1248 1297/1/1297 1268/1/1268 +f 1267/1/1267 1248/1/1248 1268/1/1268 +f 1241/1/1241 1248/1/1248 1267/1/1267 +f 1240/1/1240 1241/1/1241 1238/1/1238 +f 1239/1/1239 1242/1/1242 1240/1/1240 +f 1244/1/1244 1239/1/1239 1298/1/1298 +f 1298/1/1298 1299/1/1299 1244/1/1244 +f 1767/1/1767 1768/1/1768 1299/1/1299 +f 1766/1/1766 2477/1/2477 1767/1/1767 +f 1236/1/1236 1237/1/1237 1234/1/1234 +f 1234/1/1234 1233/1/1233 1230/1/1230 +f 1230/1/1230 1232/1/1232 1226/1/1226 +f 1232/1/1232 1225/1/1225 1226/1/1226 +f 1225/1/1225 1221/1/1221 1220/1/1220 +f 1217/1/1217 1218/1/1218 1215/1/1215 +f 1205/1/1205 1209/1/1209 1210/1/1210 +f 1214/1/1214 1217/1/1217 1215/1/1215 +f 1219/1/1219 1218/1/1218 1217/1/1217 +f 1224/1/1224 1223/1/1223 1219/1/1219 +f 1228/1/1228 1227/1/1227 1224/1/1224 +f 1228/1/1228 1235/1/1235 1231/1/1231 +f 1229/1/1229 1213/1/1213 1212/1/1212 +f 1235/1/1235 1765/1/1765 1766/1/1766 +f 1765/1/1765 2467/1/2467 2469/1/2469 +f 2471/1/2471 2468/1/2468 2467/1/2467 +f 2471/1/2471 2473/1/2473 2472/1/2472 +f 1764/1/1764 1212/1/1212 1763/1/1763 +f 2472/1/2472 2473/1/2473 2475/1/2475 +f 2458/1/2458 2475/1/2475 2456/1/2456 +f 2458/1/2458 2457/1/2457 2466/1/2466 +f 2457/1/2457 1269/1/1269 2459/1/2459 +f 1221/1/1221 1269/1/1269 1222/1/1222 +f 1271/1/1271 1216/1/1216 1222/1/1222 +f 1270/1/1270 2455/1/2455 1272/1/1272 +f 2451/1/2451 1272/1/1272 2455/1/2455 +f 1273/1/1273 1216/1/1216 1271/1/1271 +f 1193/1/1193 1208/1/1208 1192/1/1192 +f 1193/1/1193 1194/1/1194 1208/1/1208 +f 1273/1/1273 1207/1/1207 1216/1/1216 +f 1194/1/1194 1206/1/1206 1208/1/1208 +f 1207/1/1207 1205/1/1205 1210/1/1210 +f 1200/1/1200 1202/1/1202 1206/1/1206 +f 1205/1/1205 1204/1/1204 1209/1/1209 +f 1203/1/1203 1211/1/1211 1204/1/1204 +f 1763/1/1763 1212/1/1212 1203/1/1203 +f 2454/1/2454 2474/1/2474 1763/1/1763 +f 2450/1/2450 2453/1/2453 2454/1/2454 +f 2450/1/2450 2452/1/2452 2453/1/2453 +f 2451/1/2451 2455/1/2455 2452/1/2452 +f 1276/1/1276 1272/1/1272 2451/1/2451 +f 1275/1/1275 1274/1/1274 1276/1/1276 +f 1168/1/1168 1188/1/1188 1275/1/1275 +f 1157/1/1157 1165/1/1165 1168/1/1168 +f 1159/1/1159 1163/1/1163 1157/1/1157 +f 1158/1/1158 1161/1/1161 1159/1/1159 +f 1752/1/1752 1175/1/1175 1160/1/1160 +f 1750/1/1750 1752/1/1752 1160/1/1160 +f 1750/1/1750 1160/1/1160 1745/1/1745 +f 1750/1/1750 1751/1/1751 1752/1/1752 +f 1751/1/1751 1774/1/1774 1752/1/1752 +f 1751/1/1751 1754/1/1754 1774/1/1774 +f 1754/1/1754 1772/1/1772 1774/1/1774 +f 1749/1/1749 1751/1/1751 1750/1/1750 +f 1752/1/1752 1774/1/1774 1175/1/1175 +f 1161/1/1161 1174/1/1174 1162/1/1162 +f 1774/1/1774 1773/1/1773 1175/1/1175 +f 1174/1/1174 1172/1/1172 1171/1/1171 +f 1774/1/1774 1772/1/1772 1773/1/1773 +f 1172/1/1172 1760/1/1760 1173/1/1173 +f 1760/1/1760 1178/1/1178 1173/1/1173 +f 1178/1/1178 1181/1/1181 1179/1/1179 +f 1179/1/1179 1181/1/1181 1182/1/1182 +f 1195/1/1195 1183/1/1183 1182/1/1182 +f 1184/1/1184 1183/1/1183 1186/1/1186 +f 1190/1/1190 1189/1/1189 1186/1/1186 +f 1190/1/1190 1194/1/1194 1193/1/1193 +f 1191/1/1191 1196/1/1196 1197/1/1197 +f 1194/1/1194 1200/1/1200 1206/1/1206 +f 1196/1/1196 1198/1/1198 1197/1/1197 +f 1200/1/1200 1201/1/1201 1202/1/1202 +f 1762/1/1762 1201/1/1201 1761/1/1761 +f 1199/1/1199 1759/1/1759 1198/1/1198 +f 2442/1/2442 2476/1/2476 1761/1/1761 +f 2443/1/2443 2446/1/2446 2442/1/2442 +f 2443/1/2443 2445/1/2445 2446/1/2446 +f 2447/1/2447 2449/1/2449 2445/1/2445 +f 1278/1/1278 1277/1/1277 2447/1/2447 +f 1139/1/1139 1156/1/1156 1278/1/1278 +f 1136/1/1136 1138/1/1138 1139/1/1139 +f 1139/1/1139 1138/1/1138 1142/1/1142 +f 1136/1/1136 1132/1/1132 1138/1/1138 +f 1132/1/1132 1140/1/1140 1138/1/1138 +f 1129/1/1129 1122/1/1122 1131/1/1131 +f 1140/1/1140 1132/1/1132 1117/1/1117 +f 1138/1/1138 1140/1/1140 1141/1/1141 +f 1142/1/1142 1138/1/1138 1141/1/1141 +f 1139/1/1139 1142/1/1142 1146/1/1146 +f 1146/1/1146 1150/1/1150 1151/1/1151 +f 1150/1/1150 1153/1/1153 1154/1/1154 +f 1745/1/1745 1160/1/1160 1153/1/1153 +f 1744/1/1744 1750/1/1750 1745/1/1745 +f 1747/1/1747 1750/1/1750 1744/1/1744 +f 1742/1/1742 1152/1/1152 1147/1/1147 +f 1147/1/1147 1145/1/1145 1148/1/1148 +f 1739/1/1739 1738/1/1738 1732/1/1732 +f 1739/1/1739 1732/1/1732 1731/1/1731 +f 1743/1/1743 1741/1/1741 1739/1/1739 +f 1743/1/1743 1747/1/1747 1744/1/1744 +f 1733/1/1733 1748/1/1748 1746/1/1746 +f 1747/1/1747 1749/1/1749 1750/1/1750 +f 1733/1/1733 1753/1/1753 1748/1/1748 +f 1726/1/1726 1753/1/1753 1733/1/1733 +f 1749/1/1749 1754/1/1754 1751/1/1751 +f 1126/1/1126 1772/1/1772 1754/1/1754 +f 1757/1/1757 1758/1/1758 1126/1/1126 +f 1759/1/1759 1758/1/1758 1757/1/1757 +f 2441/1/2441 1759/1/1759 2438/1/2438 +f 2440/1/2440 2438/1/2438 2437/1/2437 +f 2437/1/2437 2439/1/2439 2440/1/2440 +f 1135/1/1135 2444/1/2444 2439/1/2439 +f 1133/1/1133 2448/1/2448 1135/1/1135 +f 1133/1/1133 1129/1/1129 1131/1/1131 +f 1134/1/1134 2436/1/2436 1137/1/1137 +f 1137/1/1137 2434/1/2434 2435/1/2435 +f 1129/1/1129 1130/1/1130 1122/1/1122 +f 1125/1/1125 2435/1/2435 1124/1/1124 +f 1121/1/1121 1118/1/1118 1122/1/1122 +f 1120/1/1120 1124/1/1124 1123/1/1123 +f 1119/1/1119 1112/1/1112 1118/1/1118 +f 1106/1/1106 1107/1/1107 1110/1/1110 +f 1113/1/1113 1118/1/1118 1112/1/1112 +f 1116/1/1116 1113/1/1113 1114/1/1114 +f 1144/1/1144 1114/1/1114 1115/1/1115 +f 1145/1/1145 1144/1/1144 1149/1/1149 +f 1148/1/1148 1145/1/1145 1149/1/1149 +f 1740/1/1740 1148/1/1148 1736/1/1736 +f 1734/1/1734 1736/1/1736 1735/1/1735 +f 1730/1/1730 1735/1/1735 1706/1/1706 +f 1728/1/1728 1730/1/1730 1706/1/1706 +f 1700/1/1700 1737/1/1737 1698/1/1698 +f 1698/1/1698 1304/1/1304 1691/1/1691 +f 1696/1/1696 1695/1/1695 1694/1/1694 +f 1696/1/1696 1694/1/1694 1697/1/1697 +f 1692/1/1692 1691/1/1691 1311/1/1311 +f 1693/1/1693 1689/1/1689 1719/1/1719 +f 1697/1/1697 1694/1/1694 1693/1/1693 +f 1701/1/1701 1696/1/1696 1697/1/1697 +f 1699/1/1699 1696/1/1696 1701/1/1701 +f 1705/1/1705 1706/1/1706 1699/1/1699 +f 1728/1/1728 1706/1/1706 1705/1/1705 +f 1729/1/1729 1730/1/1730 1728/1/1728 +f 1733/1/1733 1729/1/1729 1726/1/1726 +f 1727/1/1727 1753/1/1753 1726/1/1726 +f 1756/1/1756 1755/1/1755 1727/1/1727 +f 1123/1/1123 1756/1/1756 1111/1/1111 +f 1110/1/1110 1111/1/1111 1106/1/1106 +f 1106/1/1106 1105/1/1105 1107/1/1107 +f 1100/1/1100 1104/1/1104 1101/1/1101 +f 1100/1/1100 1303/1/1303 1104/1/1104 +f 1108/1/1108 1105/1/1105 1109/1/1109 +f 1300/1/1300 1109/1/1109 1301/1/1301 +f 1302/1/1302 1104/1/1104 1303/1/1303 +f 1054/1/1054 1301/1/1301 1060/1/1060 +f 1053/1/1053 1054/1/1054 1051/1/1051 +f 1056/1/1056 1053/1/1053 1051/1/1051 +f 1311/1/1311 1056/1/1056 1312/1/1312 +f 1690/1/1690 1312/1/1312 1687/1/1687 +f 1723/1/1723 1687/1/1687 1688/1/1688 +f 1685/1/1685 1686/1/1686 1681/1/1681 +f 1674/1/1674 1680/1/1680 1675/1/1675 +f 1722/1/1722 1674/1/1674 1673/1/1673 +f 1720/1/1720 1688/1/1688 1722/1/1722 +f 1718/1/1718 1717/1/1717 1720/1/1720 +f 1713/1/1713 1717/1/1717 1718/1/1718 +f 1709/1/1709 1716/1/1716 1713/1/1713 +f 1704/1/1704 1702/1/1702 1709/1/1709 +f 1707/1/1707 1703/1/1703 1704/1/1704 +f 1708/1/1708 1703/1/1703 1707/1/1707 +f 1724/1/1724 1725/1/1725 1708/1/1708 +f 1127/1/1127 1724/1/1724 1128/1/1128 +f 1102/1/1102 1127/1/1127 1128/1/1128 +f 1103/1/1103 1102/1/1102 1101/1/1101 +f 1099/1/1099 1100/1/1100 1101/1/1101 +f 1094/1/1094 1303/1/1303 1100/1/1100 +f 1091/1/1091 1093/1/1093 1094/1/1094 +f 1096/1/1096 1097/1/1097 1092/1/1092 +f 1090/1/1090 1093/1/1093 1091/1/1091 +f 1058/1/1058 1093/1/1093 1095/1/1095 +f 1059/1/1059 1058/1/1058 1095/1/1095 +f 1055/1/1055 1059/1/1059 1057/1/1057 +f 1061/1/1061 1065/1/1065 1066/1/1066 +f 1062/1/1062 1063/1/1063 1064/1/1064 +f 1049/1/1049 1057/1/1057 1062/1/1062 +f 1050/1/1050 1049/1/1049 1041/1/1041 +f 1681/1/1681 1041/1/1041 1682/1/1682 +f 1678/1/1678 1682/1/1682 1679/1/1679 +f 1676/1/1676 1679/1/1679 1677/1/1677 +f 1670/1/1670 1677/1/1677 1669/1/1669 +f 1667/1/1667 1671/1/1671 1670/1/1670 +f 1668/1/1668 1671/1/1671 1667/1/1667 +f 1662/1/1662 1672/1/1672 1668/1/1668 +f 1715/1/1715 1721/1/1721 1662/1/1662 +f 1714/1/1714 1710/1/1710 1715/1/1715 +f 1711/1/1711 1710/1/1710 1714/1/1714 +f 1098/1/1098 1712/1/1712 1711/1/1711 +f 1092/1/1092 1098/1/1098 1088/1/1088 +f 1089/1/1089 1088/1/1088 1085/1/1085 +f 1085/1/1085 1079/1/1079 1089/1/1089 +f 1066/1/1066 1079/1/1079 1078/1/1078 +f 1080/1/1080 1075/1/1075 1078/1/1078 +f 1080/1/1080 1083/1/1083 1077/1/1077 +f 1082/1/1082 1084/1/1084 1081/1/1081 +f 1084/1/1084 1086/1/1086 1087/1/1087 +f 1087/1/1087 1664/1/1664 1660/1/1660 +f 1660/1/1660 1663/1/1663 1661/1/1661 +f 1661/1/1661 1666/1/1666 1665/1/1665 +f 1665/1/1665 1775/1/1775 1776/1/1776 +f 1775/1/1775 1684/1/1684 1776/1/1776 +f 1684/1/1684 1683/1/1683 1042/1/1042 +f 1042/1/1042 1040/1/1040 1038/1/1038 +f 1044/1/1044 1043/1/1043 1045/1/1045 +f 1318/1/1318 1044/1/1044 1045/1/1045 +f 1777/1/1777 1318/1/1318 1317/1/1317 +f 1659/1/1659 1317/1/1317 1316/1/1316 +f 1314/1/1314 1315/1/1315 1020/1/1020 +f 1014/1/1014 1019/1/1019 1017/1/1017 +f 1020/1/1020 1021/1/1021 1018/1/1018 +f 1019/1/1019 1025/1/1025 1022/1/1022 +f 1047/1/1047 1048/1/1048 1021/1/1021 +f 1025/1/1025 1035/1/1035 1026/1/1026 +f 1046/1/1046 1034/1/1034 1048/1/1048 +f 1035/1/1035 1030/1/1030 1026/1/1026 +f 1038/1/1038 1033/1/1033 1034/1/1034 +f 1030/1/1030 1032/1/1032 1031/1/1031 +f 1032/1/1032 1072/1/1072 1031/1/1031 +f 1031/1/1031 1072/1/1072 1640/1/1640 +f 1037/1/1037 1036/1/1036 1033/1/1033 +f 1032/1/1032 1070/1/1070 1072/1/1072 +f 1039/1/1039 1068/1/1068 1036/1/1036 +f 1068/1/1068 1067/1/1067 1069/1/1069 +f 1069/1/1069 1073/1/1073 1074/1/1074 +f 1070/1/1070 1071/1/1071 1072/1/1072 +f 1074/1/1074 1647/1/1647 1642/1/1642 +f 1641/1/1641 1643/1/1643 1644/1/1644 +f 1072/1/1072 1641/1/1641 1640/1/1640 +f 1031/1/1031 1640/1/1640 1617/1/1617 +f 1030/1/1030 1031/1/1031 982/1/982 +f 1027/1/1027 982/1/982 981/1/981 +f 1028/1/1028 981/1/981 987/1/987 +f 1029/1/1029 987/1/987 988/1/988 +f 1313/1/1313 988/1/988 994/1/994 +f 1011/1/1011 1016/1/1016 1313/1/1313 +f 1006/1/1006 1010/1/1010 1011/1/1011 +f 1008/1/1008 1009/1/1009 1006/1/1006 +f 1316/1/1316 1013/1/1013 1008/1/1008 +f 1657/1/1657 1659/1/1659 1316/1/1316 +f 1310/1/1310 1658/1/1658 1657/1/1657 +f 1306/1/1306 1307/1/1307 1310/1/1310 +f 1305/1/1305 1083/1/1083 1306/1/1306 +f 1305/1/1305 1309/1/1309 1076/1/1076 +f 1074/1/1074 1309/1/1309 1647/1/1647 +f 1308/1/1308 1650/1/1650 1649/1/1649 +f 1648/1/1648 1646/1/1646 1647/1/1647 +f 1651/1/1651 1650/1/1650 1652/1/1652 +f 1653/1/1653 1645/1/1645 1646/1/1646 +f 1618/1/1618 1645/1/1645 1613/1/1613 +f 1612/1/1612 1610/1/1610 1613/1/1613 +f 1612/1/1612 1600/1/1600 1607/1/1607 +f 1654/1/1654 1652/1/1652 1655/1/1655 +f 1652/1/1652 1656/1/1656 1601/1/1601 +f 1601/1/1601 1007/1/1007 1004/1/1004 +f 1004/1/1004 1005/1/1005 995/1/995 +f 995/1/995 997/1/997 992/1/992 +f 992/1/992 989/1/989 990/1/990 +f 989/1/989 985/1/985 990/1/990 +f 985/1/985 984/1/984 979/1/979 +f 979/1/979 980/1/980 974/1/974 +f 986/1/986 971/1/971 970/1/970 +f 991/1/991 986/1/986 970/1/970 +f 993/1/993 991/1/991 998/1/998 +f 996/1/996 998/1/998 999/1/999 +f 1003/1/1003 1002/1/1002 962/1/962 +f 958/1/958 960/1/960 938/1/938 +f 962/1/962 963/1/963 959/1/959 +f 960/1/960 964/1/964 939/1/939 +f 966/1/966 965/1/965 963/1/963 +f 964/1/964 967/1/967 937/1/937 +f 968/1/968 969/1/969 965/1/965 +f 967/1/967 973/1/973 937/1/937 +f 974/1/974 972/1/972 969/1/969 +f 973/1/973 975/1/975 976/1/976 +f 975/1/975 1622/1/1622 976/1/976 +f 976/1/976 1622/1/1622 1626/1/1626 +f 977/1/977 978/1/978 972/1/972 +f 975/1/975 1620/1/1620 1622/1/1622 +f 983/1/983 1619/1/1619 978/1/978 +f 1619/1/1619 1615/1/1615 1616/1/1616 +f 1616/1/1616 1611/1/1611 1609/1/1609 +f 1620/1/1620 1621/1/1621 1622/1/1622 +f 1609/1/1609 1606/1/1606 1623/1/1623 +f 1624/1/1624 1625/1/1625 1627/1/1627 +f 1622/1/1622 1624/1/1624 1626/1/1626 +f 976/1/976 1626/1/1626 1324/1/1324 +f 973/1/973 976/1/976 924/1/924 +f 932/1/932 924/1/924 926/1/926 +f 933/1/933 926/1/926 931/1/931 +f 934/1/934 931/1/931 930/1/930 +f 941/1/941 930/1/930 946/1/946 +f 943/1/943 940/1/940 941/1/941 +f 942/1/942 940/1/940 943/1/943 +f 954/1/954 944/1/944 942/1/942 +f 953/1/953 957/1/957 954/1/954 +f 999/1/999 961/1/961 953/1/953 +f 1001/1/1001 996/1/996 999/1/999 +f 1597/1/1597 1000/1/1000 1001/1/1001 +f 1598/1/1598 1599/1/1599 1597/1/1597 +f 1603/1/1603 1600/1/1600 1598/1/1598 +f 1603/1/1603 1605/1/1605 1608/1/1608 +f 1609/1/1609 1605/1/1605 1606/1/1606 +f 1602/1/1602 1596/1/1596 1604/1/1604 +f 1630/1/1630 1629/1/1629 1606/1/1606 +f 1633/1/1633 1596/1/1596 1594/1/1594 +f 1632/1/1632 1631/1/1631 1629/1/1629 +f 1628/1/1628 1631/1/1631 1634/1/1634 +f 1637/1/1637 1639/1/1639 1634/1/1634 +f 1637/1/1637 1592/1/1592 1638/1/1638 +f 1636/1/1636 1594/1/1594 1635/1/1635 +f 1594/1/1594 1595/1/1595 1593/1/1593 +f 1593/1/1593 952/1/952 955/1/955 +f 955/1/955 951/1/951 956/1/956 +f 956/1/956 945/1/945 948/1/948 +f 948/1/948 947/1/947 949/1/949 +f 947/1/947 928/1/928 949/1/949 +f 928/1/928 927/1/927 922/1/922 +f 922/1/922 921/1/921 919/1/919 +f 929/1/929 923/1/923 1319/1/1319 +f 950/1/950 929/1/929 1319/1/1319 +f 1583/1/1583 950/1/950 1580/1/1580 +f 1584/1/1584 1580/1/1580 1576/1/1576 +f 1578/1/1578 1581/1/1581 1579/1/1579 +f 1569/1/1569 1567/1/1567 1564/1/1564 +f 1579/1/1579 1568/1/1568 1572/1/1572 +f 1567/1/1567 1566/1/1566 1565/1/1565 +f 1582/1/1582 1321/1/1321 1568/1/1568 +f 1566/1/1566 915/1/915 910/1/910 +f 1320/1/1320 916/1/916 1321/1/1321 +f 915/1/915 911/1/911 910/1/910 +f 919/1/919 917/1/917 916/1/916 +f 911/1/911 914/1/914 909/1/909 +f 914/1/914 1340/1/1340 909/1/909 +f 909/1/909 1340/1/1340 1341/1/1341 +f 920/1/920 918/1/918 917/1/917 +f 914/1/914 1323/1/1323 1340/1/1340 +f 925/1/925 1322/1/1322 918/1/918 +f 1322/1/1322 1325/1/1325 1326/1/1326 +f 1326/1/1326 1328/1/1328 1329/1/1329 +f 1323/1/1323 1331/1/1331 1340/1/1340 +f 1329/1/1329 1333/1/1333 1334/1/1334 +f 1339/1/1339 1337/1/1337 1343/1/1343 +f 1340/1/1340 1339/1/1339 1341/1/1341 +f 909/1/909 1341/1/1341 1345/1/1345 +f 911/1/911 909/1/909 906/1/906 +f 912/1/912 906/1/906 913/1/913 +f 1503/1/1503 913/1/913 1499/1/1499 +f 1496/1/1496 1499/1/1499 1497/1/1497 +f 1490/1/1490 1497/1/1497 1491/1/1491 +f 1492/1/1492 1495/1/1495 1490/1/1490 +f 1493/1/1493 1494/1/1494 1492/1/1492 +f 1574/1/1574 1570/1/1570 1493/1/1493 +f 1576/1/1576 1577/1/1577 1574/1/1574 +f 1585/1/1585 1584/1/1584 1576/1/1576 +f 1589/1/1589 1586/1/1586 1585/1/1585 +f 1590/1/1590 1591/1/1591 1589/1/1589 +f 1335/1/1335 1592/1/1592 1590/1/1590 +f 1335/1/1335 1332/1/1332 1330/1/1330 +f 1329/1/1329 1332/1/1332 1333/1/1333 +f 1336/1/1336 1408/1/1408 1410/1/1410 +f 1409/1/1409 1338/1/1338 1333/1/1333 +f 1407/1/1407 1408/1/1408 1404/1/1404 +f 1406/1/1406 1344/1/1344 1338/1/1338 +f 1342/1/1342 1344/1/1344 1346/1/1346 +f 1402/1/1402 1348/1/1348 1346/1/1346 +f 1402/1/1402 1387/1/1387 1386/1/1386 +f 1405/1/1405 1404/1/1404 1403/1/1403 +f 1404/1/1404 1587/1/1587 1588/1/1588 +f 1588/1/1588 1575/1/1575 1486/1/1486 +f 1486/1/1486 1489/1/1489 1485/1/1485 +f 1485/1/1485 1487/1/1487 1488/1/1488 +f 1488/1/1488 1498/1/1498 1505/1/1505 +f 1498/1/1498 1501/1/1501 1505/1/1505 +f 1501/1/1501 1500/1/1500 1504/1/1504 +f 1504/1/1504 907/1/907 908/1/908 +f 1506/1/1506 1507/1/1507 1510/1/1510 +f 1528/1/1528 1506/1/1506 1510/1/1510 +f 1529/1/1529 1528/1/1528 1527/1/1527 +f 1483/1/1483 1527/1/1527 1481/1/1481 +f 1521/1/1521 1522/1/1522 1519/1/1519 +f 1525/1/1525 1518/1/1518 1546/1/1546 +f 1519/1/1519 1514/1/1514 1520/1/1520 +f 1518/1/1518 1515/1/1515 1517/1/1517 +f 1513/1/1513 1511/1/1511 1514/1/1514 +f 1515/1/1515 1512/1/1512 1516/1/1516 +f 1509/1/1509 1508/1/1508 1511/1/1511 +f 1512/1/1512 897/1/897 1516/1/1516 +f 908/1/908 899/1/899 1508/1/1508 +f 897/1/897 898/1/898 896/1/896 +f 898/1/898 901/1/901 896/1/896 +f 896/1/896 901/1/901 1360/1/1360 +f 903/1/903 902/1/902 899/1/899 +f 898/1/898 900/1/900 901/1/901 +f 904/1/904 905/1/905 902/1/902 +f 905/1/905 1349/1/1349 1351/1/1351 +f 1351/1/1351 1350/1/1350 1353/1/1353 +f 900/1/900 1354/1/1354 901/1/901 +f 1353/1/1353 1357/1/1357 1355/1/1355 +f 1358/1/1358 1359/1/1359 1362/1/1362 +f 901/1/901 1358/1/1358 1360/1/1360 +f 896/1/896 1360/1/1360 1365/1/1365 +f 897/1/897 896/1/896 891/1/891 +f 1417/1/1417 891/1/891 1418/1/1418 +f 1549/1/1549 1418/1/1418 1551/1/1551 +f 1550/1/1550 1551/1/1551 1553/1/1553 +f 1540/1/1540 1553/1/1553 1541/1/1541 +f 1539/1/1539 1542/1/1542 1540/1/1540 +f 1530/1/1530 1543/1/1543 1539/1/1539 +f 1526/1/1526 1544/1/1544 1530/1/1530 +f 1481/1/1481 1523/1/1523 1526/1/1526 +f 1480/1/1480 1483/1/1483 1481/1/1481 +f 1388/1/1388 1484/1/1484 1480/1/1480 +f 1385/1/1385 1389/1/1389 1388/1/1388 +f 1384/1/1384 1387/1/1387 1385/1/1385 +f 1384/1/1384 1356/1/1356 1352/1/1352 +f 1353/1/1353 1356/1/1356 1357/1/1357 +f 1383/1/1383 1379/1/1379 1382/1/1382 +f 1381/1/1381 1363/1/1363 1357/1/1357 +f 1378/1/1378 1379/1/1379 1376/1/1376 +f 1380/1/1380 1364/1/1364 1363/1/1363 +f 1361/1/1361 1364/1/1364 1367/1/1367 +f 1372/1/1372 1371/1/1371 1367/1/1367 +f 1372/1/1372 1374/1/1374 1375/1/1375 +f 1377/1/1377 1376/1/1376 1373/1/1373 +f 1376/1/1376 1390/1/1390 1391/1/1391 +f 1391/1/1391 1482/1/1482 1531/1/1531 +f 1531/1/1531 1534/1/1534 1532/1/1532 +f 1532/1/1532 1538/1/1538 1537/1/1537 +f 1537/1/1537 1558/1/1558 1559/1/1559 +f 1558/1/1558 1555/1/1555 1559/1/1559 +f 1555/1/1555 1552/1/1552 1554/1/1554 +f 1554/1/1554 889/1/889 887/1/887 +f 1556/1/1556 1557/1/1557 1419/1/1419 +f 1561/1/1561 1556/1/1556 1419/1/1419 +f 1560/1/1560 1561/1/1561 1562/1/1562 +f 1535/1/1535 1562/1/1562 1428/1/1428 +f 1427/1/1427 1426/1/1426 1425/1/1425 +f 1420/1/1420 881/1/881 875/1/875 +f 1425/1/1425 882/1/882 1422/1/1422 +f 881/1/881 880/1/880 876/1/876 +f 884/1/884 883/1/883 882/1/882 +f 880/1/880 879/1/879 877/1/877 +f 885/1/885 886/1/886 883/1/883 +f 879/1/879 878/1/878 877/1/877 +f 887/1/887 888/1/888 886/1/886 +f 878/1/878 894/1/894 895/1/895 +f 894/1/894 1415/1/1415 895/1/895 +f 895/1/895 1415/1/1415 2433/1/2433 +f 890/1/890 893/1/893 888/1/888 +f 894/1/894 1413/1/1413 1415/1/1415 +f 892/1/892 1368/1/1368 893/1/893 +f 1368/1/1368 1369/1/1369 1411/1/1411 +f 1411/1/1411 1370/1/1370 1412/1/1412 +f 1413/1/1413 1414/1/1414 1415/1/1415 +f 1412/1/1412 1401/1/1401 1416/1/1416 +f 2432/1/2432 2431/1/2431 2430/1/2430 +f 1415/1/1415 2432/1/2432 2433/1/2433 +f 895/1/895 2433/1/2433 1796/1/1796 +f 878/1/878 895/1/895 796/1/796 +f 874/1/874 796/1/796 795/1/795 +f 872/1/872 795/1/795 870/1/870 +f 869/1/869 870/1/870 867/1/867 +f 865/1/865 867/1/867 866/1/866 +f 864/1/864 868/1/868 865/1/865 +f 863/1/863 1431/1/1431 864/1/864 +f 1429/1/1429 1430/1/1430 863/1/863 +f 1428/1/1428 1423/1/1423 1429/1/1429 +f 1536/1/1536 1535/1/1535 1428/1/1428 +f 1395/1/1395 1533/1/1533 1536/1/1536 +f 1394/1/1394 1392/1/1392 1395/1/1395 +f 1393/1/1393 1374/1/1374 1394/1/1394 +f 1393/1/1393 1398/1/1398 1399/1/1399 +f 1412/1/1412 1398/1/1398 1401/1/1401 +f 1396/1/1396 1397/1/1397 1400/1/1400 +f 1814/1/1814 1813/1/1813 1401/1/1401 +f 1812/1/1812 1397/1/1397 1809/1/1809 +f 1811/1/1811 1808/1/1808 1813/1/1813 +f 1800/1/1800 1808/1/1808 1801/1/1801 +f 1803/1/1803 1799/1/1799 1801/1/1801 +f 1803/1/1803 1806/1/1806 1802/1/1802 +f 1810/1/1810 1809/1/1809 1807/1/1807 +f 1809/1/1809 1815/1/1815 1816/1/1816 +f 1816/1/1816 862/1/862 859/1/859 +f 859/1/859 861/1/861 858/1/858 +f 858/1/858 860/1/860 808/1/808 +f 808/1/808 809/1/809 805/1/805 +f 809/1/809 801/1/801 805/1/805 +f 801/1/801 800/1/800 798/1/798 +f 798/1/798 797/1/797 792/1/792 +f 802/1/802 799/1/799 803/1/803 +f 806/1/806 802/1/802 803/1/803 +f 807/1/807 806/1/806 810/1/810 +f 812/1/812 810/1/810 814/1/814 +f 813/1/813 811/1/811 815/1/815 +f 824/1/824 826/1/826 827/1/827 +f 815/1/815 825/1/825 821/1/821 +f 826/1/826 834/1/834 833/1/833 +f 856/1/856 855/1/855 825/1/825 +f 834/1/834 789/1/789 786/1/786 +f 804/1/804 788/1/788 855/1/855 +f 789/1/789 784/1/784 786/1/786 +f 792/1/792 790/1/790 788/1/788 +f 784/1/784 787/1/787 783/1/783 +f 787/1/787 1788/1/1788 783/1/783 +f 783/1/783 1788/1/1788 1784/1/1784 +f 793/1/793 791/1/791 790/1/790 +f 787/1/787 1789/1/1789 1788/1/1788 +f 794/1/794 1792/1/1792 791/1/791 +f 1792/1/1792 1794/1/1794 1791/1/1791 +f 1791/1/1791 1795/1/1795 1793/1/1793 +f 1789/1/1789 1790/1/1790 1788/1/1788 +f 1793/1/1793 1948/1/1948 1787/1/1787 +f 1782/1/1782 1785/1/1785 1781/1/1781 +f 1788/1/1788 1782/1/1782 1784/1/1784 +f 783/1/783 1784/1/1784 762/1/762 +f 784/1/784 783/1/783 781/1/781 +f 785/1/785 781/1/781 780/1/780 +f 835/1/835 780/1/780 837/1/837 +f 836/1/836 837/1/837 839/1/839 +f 838/1/838 839/1/839 844/1/844 +f 853/1/853 830/1/830 838/1/838 +f 829/1/829 830/1/830 853/1/853 +f 822/1/822 828/1/828 829/1/829 +f 817/1/817 820/1/820 822/1/822 +f 814/1/814 816/1/816 817/1/817 +f 818/1/818 812/1/812 814/1/814 +f 1819/1/1819 857/1/857 818/1/818 +f 1818/1/1818 1817/1/1817 1819/1/1819 +f 1805/1/1805 1806/1/1806 1818/1/1818 +f 1805/1/1805 1804/1/1804 1798/1/1798 +f 1793/1/1793 1804/1/1804 1948/1/1948 +f 1820/1/1820 1821/1/1821 1947/1/1947 +f 1946/1/1946 1786/1/1786 1948/1/1948 +f 1944/1/1944 1821/1/1821 1823/1/1823 +f 1945/1/1945 1779/1/1779 1786/1/1786 +f 1778/1/1778 1779/1/1779 1780/1/1780 +f 1941/1/1941 1942/1/1942 1780/1/1780 +f 1941/1/1941 1825/1/1825 1938/1/1938 +f 1943/1/1943 1823/1/1823 1940/1/1940 +f 1823/1/1823 1822/1/1822 1824/1/1824 +f 1824/1/1824 819/1/819 854/1/854 +f 854/1/854 823/1/823 850/1/850 +f 850/1/850 848/1/848 847/1/847 +f 847/1/847 843/1/843 845/1/845 +f 843/1/843 842/1/842 845/1/845 +f 842/1/842 840/1/840 841/1/841 +f 841/1/841 782/1/782 776/1/776 +f 846/1/846 775/1/775 778/1/778 +f 851/1/851 846/1/846 778/1/778 +f 849/1/849 851/1/851 1831/1/1831 +f 1830/1/1830 1831/1/1831 1832/1/1832 +f 1834/1/1834 852/1/852 1836/1/1836 +f 1841/1/1841 1842/1/1842 1848/1/1848 +f 1836/1/1836 1837/1/1837 1838/1/1838 +f 1842/1/1842 768/1/768 1854/1/1854 +f 777/1/777 767/1/767 1837/1/1837 +f 768/1/768 764/1/764 765/1/765 +f 774/1/774 763/1/763 767/1/767 +f 764/1/764 759/1/759 765/1/765 +f 776/1/776 757/1/757 763/1/763 +f 759/1/759 756/1/756 755/1/755 +f 756/1/756 747/1/747 755/1/755 +f 755/1/755 747/1/747 746/1/746 +f 779/1/779 758/1/758 757/1/757 +f 756/1/756 754/1/754 747/1/747 +f 761/1/761 760/1/760 758/1/758 +f 760/1/760 1949/1/1949 752/1/752 +f 752/1/752 753/1/753 748/1/748 +f 754/1/754 749/1/749 747/1/747 +f 748/1/748 744/1/744 745/1/745 +f 743/1/743 742/1/742 741/1/741 +f 747/1/747 743/1/743 746/1/746 +f 755/1/755 746/1/746 715/1/715 +f 759/1/759 755/1/755 766/1/766 +f 769/1/769 766/1/766 770/1/770 +f 1856/1/1856 770/1/770 1858/1/1858 +f 1851/1/1851 1858/1/1858 1933/1/1933 +f 1852/1/1852 1933/1/1933 1932/1/1932 +f 1850/1/1850 1849/1/1849 1852/1/1852 +f 1847/1/1847 1849/1/1849 1850/1/1850 +f 1843/1/1843 1846/1/1846 1847/1/1847 +f 1839/1/1839 1840/1/1840 1843/1/1843 +f 1832/1/1832 1835/1/1835 1839/1/1839 +f 1833/1/1833 1830/1/1830 1832/1/1832 +f 1829/1/1829 1828/1/1828 1833/1/1833 +f 1827/1/1827 1826/1/1826 1829/1/1829 +f 1937/1/1937 1825/1/1825 1827/1/1827 +f 1937/1/1937 750/1/750 1939/1/1939 +f 748/1/748 750/1/750 744/1/744 +f 751/1/751 736/1/736 1950/1/1950 +f 738/1/738 739/1/739 744/1/744 +f 735/1/735 736/1/736 728/1/728 +f 737/1/737 734/1/734 739/1/739 +f 740/1/740 734/1/734 732/1/732 +f 727/1/727 718/1/718 732/1/732 +f 727/1/727 725/1/725 723/1/723 +f 733/1/733 728/1/728 731/1/731 +f 728/1/728 1936/1/1936 729/1/729 +f 729/1/729 1844/1/1844 1935/1/1935 +f 1935/1/1935 1845/1/1845 1930/1/1930 +f 1930/1/1930 1934/1/1934 1928/1/1928 +f 1928/1/1928 1931/1/1931 1866/1/1866 +f 1931/1/1931 1860/1/1860 1866/1/1866 +f 1860/1/1860 1857/1/1857 1859/1/1859 +f 1859/1/1859 772/1/772 773/1/773 +f 1861/1/1861 1862/1/1862 1864/1/1864 +f 1867/1/1867 1861/1/1861 1864/1/1864 +f 1929/1/1929 1867/1/1867 1876/1/1876 +f 1927/1/1927 1876/1/1876 1877/1/1877 +f 1873/1/1873 1870/1/1870 1869/1/1869 +f 1880/1/1880 1881/1/1881 1887/1/1887 +f 1869/1/1869 1872/1/1872 1875/1/1875 +f 1881/1/1881 1914/1/1914 1893/1/1893 +f 1868/1/1868 1871/1/1871 1872/1/1872 +f 1914/1/1914 1454/1/1454 1455/1/1455 +f 1865/1/1865 1863/1/1863 1871/1/1871 +f 1454/1/1454 709/1/709 1455/1/1455 +f 773/1/773 708/1/708 1863/1/1863 +f 709/1/709 703/1/703 701/1/701 +f 703/1/703 702/1/702 701/1/701 +f 701/1/701 702/1/702 700/1/700 +f 771/1/771 707/1/707 708/1/708 +f 703/1/703 706/1/706 702/1/702 +f 714/1/714 710/1/710 707/1/707 +f 710/1/710 713/1/713 711/1/711 +f 711/1/711 716/1/716 717/1/717 +f 706/1/706 704/1/704 702/1/702 +f 717/1/717 720/1/720 705/1/705 +f 698/1/698 1444/1/1444 699/1/699 +f 702/1/702 698/1/698 700/1/700 +f 701/1/701 700/1/700 697/1/697 +f 709/1/709 701/1/701 1453/1/1453 +f 1913/1/1913 1453/1/1453 1903/1/1903 +f 1895/1/1895 1903/1/1903 1896/1/1896 +f 1891/1/1891 1896/1/1896 1897/1/1897 +f 1892/1/1892 1897/1/1897 1899/1/1899 +f 1889/1/1889 1888/1/1888 1892/1/1892 +f 1883/1/1883 1886/1/1886 1889/1/1889 +f 1879/1/1879 1882/1/1882 1883/1/1883 +f 1877/1/1877 1874/1/1874 1879/1/1879 +f 1925/1/1925 1927/1/1927 1877/1/1877 +f 1432/1/1432 1926/1/1926 1925/1/1925 +f 726/1/726 730/1/730 1432/1/1432 +f 722/1/722 725/1/725 726/1/726 +f 722/1/722 721/1/721 719/1/719 +f 717/1/717 721/1/721 720/1/720 +f 724/1/724 1433/1/1433 1435/1/1435 +f 1436/1/1436 1439/1/1439 720/1/720 +f 1438/1/1438 1433/1/1433 1437/1/1437 +f 1440/1/1440 696/1/696 1439/1/1439 +f 695/1/695 696/1/696 693/1/693 +f 694/1/694 690/1/690 693/1/693 +f 694/1/694 1443/1/1443 691/1/691 +f 1441/1/1441 1437/1/1437 1442/1/1442 +f 1437/1/1437 1434/1/1434 1452/1/1452 +f 1452/1/1452 1884/1/1884 1923/1/1923 +f 1923/1/1923 1924/1/1924 1921/1/1921 +f 1921/1/1921 1898/1/1898 1922/1/1922 +f 1922/1/1922 1902/1/1902 1907/1/1907 +f 1902/1/1902 1901/1/1901 1907/1/1907 +f 1901/1/1901 1900/1/1900 1905/1/1905 +f 1905/1/1905 1904/1/1904 1911/1/1911 +f 1906/1/1906 1908/1/1908 1910/1/1910 +f 1909/1/1909 1906/1/1906 1910/1/1910 +f 1917/1/1917 1909/1/1909 1916/1/1916 +f 1918/1/1918 1916/1/1916 650/1/650 +f 1478/1/1478 1915/1/1915 1477/1/1477 +f 647/1/647 652/1/652 653/1/653 +f 1477/1/1477 1475/1/1475 651/1/651 +f 652/1/652 673/1/673 656/1/656 +f 1476/1/1476 672/1/672 1475/1/1475 +f 673/1/673 668/1/668 662/1/662 +f 1912/1/1912 671/1/671 672/1/672 +f 668/1/668 664/1/664 662/1/662 +f 1911/1/1911 669/1/669 671/1/671 +f 664/1/664 670/1/670 665/1/665 +f 670/1/670 675/1/675 665/1/665 +f 665/1/665 675/1/675 2420/1/2420 +f 1456/1/1456 676/1/676 669/1/669 +f 670/1/670 674/1/674 675/1/675 +f 678/1/678 677/1/677 676/1/676 +f 677/1/677 681/1/681 679/1/679 +f 679/1/679 682/1/682 683/1/683 +f 674/1/674 680/1/680 675/1/675 +f 683/1/683 685/1/685 684/1/684 +f 2421/1/2421 2424/1/2424 2422/1/2422 +f 675/1/675 2421/1/2421 2420/1/2420 +f 665/1/665 2420/1/2420 1975/1/1975 +f 664/1/664 665/1/665 663/1/663 +f 657/1/657 663/1/663 660/1/660 +f 658/1/658 660/1/660 661/1/661 +f 659/1/659 661/1/661 1464/1/1464 +f 1466/1/1466 1464/1/1464 1467/1/1467 +f 639/1/639 646/1/646 1466/1/1466 +f 638/1/638 641/1/641 639/1/639 +f 643/1/643 642/1/642 638/1/638 +f 650/1/650 649/1/649 643/1/643 +f 1919/1/1919 1918/1/1918 650/1/650 +f 1447/1/1447 1920/1/1920 1919/1/1919 +f 1445/1/1445 1448/1/1448 1447/1/1447 +f 689/1/689 1443/1/1443 1445/1/1445 +f 689/1/689 687/1/687 686/1/686 +f 683/1/683 687/1/687 685/1/685 +f 688/1/688 1446/1/1446 1449/1/1449 +f 1450/1/1450 2425/1/2425 685/1/685 +f 2429/1/2429 1446/1/1446 1951/1/1951 +f 2428/1/2428 2423/1/2423 2425/1/2425 +f 1976/1/1976 2423/1/2423 1970/1/1970 +f 1969/1/1969 1968/1/1968 1970/1/1970 +f 1969/1/1969 1953/1/1953 1963/1/1963 +f 2427/1/2427 1951/1/1951 2426/1/2426 +f 1951/1/1951 1451/1/1451 1952/1/1952 +f 1952/1/1952 644/1/644 637/1/637 +f 629/1/629 631/1/631 607/1/607 +f 629/1/629 607/1/607 606/1/606 +f 1958/1/1958 629/1/629 606/1/606 +f 637/1/637 636/1/636 630/1/630 +f 636/1/636 640/1/640 634/1/634 +f 634/1/634 1468/1/1468 635/1/635 +f 1470/1/1470 1469/1/1469 1471/1/1471 +f 1465/1/1465 1463/1/1463 1468/1/1468 +f 1463/1/1463 1461/1/1461 1462/1/1462 +f 1462/1/1462 1459/1/1459 1457/1/1457 +f 1469/1/1469 1473/1/1473 1471/1/1471 +f 1470/1/1470 1471/1/1471 1472/1/1472 +f 632/1/632 1470/1/1470 1472/1/1472 +f 631/1/631 632/1/632 607/1/607 +f 600/1/600 597/1/597 598/1/598 +f 600/1/600 598/1/598 601/1/601 +f 633/1/633 596/1/596 599/1/599 +f 596/1/596 594/1/594 591/1/591 +f 594/1/594 592/1/592 591/1/591 +f 589/1/589 588/1/588 585/1/585 +f 595/1/595 593/1/593 592/1/592 +f 1457/1/1457 1458/1/1458 593/1/593 +f 667/1/667 1460/1/1460 1458/1/1458 +f 1474/1/1474 1977/1/1977 1979/1/1979 +f 1474/1/1474 1979/1/1979 586/1/586 +f 666/1/666 1974/1/1974 1460/1/1460 +f 1974/1/1974 1972/1/1972 1973/1/1973 +f 1973/1/1973 1967/1/1967 1966/1/1966 +f 1977/1/1977 1978/1/1978 1979/1/1979 +f 1966/1/1966 1965/1/1965 1980/1/1980 +f 1981/1/1981 1982/1/1982 1984/1/1984 +f 1979/1/1979 1981/1/1981 1983/1/1983 +f 586/1/586 1979/1/1979 1983/1/1983 +f 587/1/587 1474/1/1474 586/1/586 +f 588/1/588 587/1/587 585/1/585 +f 589/1/589 585/1/585 584/1/584 +f 590/1/590 589/1/589 584/1/584 +f 597/1/597 590/1/590 598/1/598 +f 601/1/601 598/1/598 602/1/602 +f 604/1/604 600/1/600 601/1/601 +f 606/1/606 607/1/607 604/1/604 +f 605/1/605 603/1/603 609/1/609 +f 603/1/603 581/1/581 609/1/609 +f 582/1/582 576/1/576 574/1/574 +f 582/1/582 574/1/574 614/1/614 +f 583/1/583 579/1/579 581/1/581 +f 579/1/579 580/1/580 577/1/577 +f 577/1/577 578/1/578 566/1/566 +f 576/1/576 575/1/575 574/1/574 +f 614/1/614 574/1/574 615/1/615 +f 611/1/611 582/1/582 614/1/614 +f 610/1/610 611/1/611 612/1/612 +f 608/1/608 610/1/610 612/1/612 +f 1995/1/1995 606/1/606 608/1/608 +f 1958/1/1958 606/1/606 1995/1/1995 +f 1956/1/1956 629/1/629 1958/1/1958 +f 1955/1/1955 1954/1/1954 1956/1/1956 +f 1959/1/1959 1953/1/1953 1955/1/1955 +f 1959/1/1959 1961/1/1961 1962/1/1962 +f 1966/1/1966 1961/1/1961 1965/1/1965 +f 1960/1/1960 1957/1/1957 1964/1/1964 +f 1987/1/1987 1986/1/1986 1965/1/1965 +f 1988/1/1988 1989/1/1989 1986/1/1986 +f 1990/1/1990 1957/1/1957 1994/1/1994 +f 1993/1/1993 1989/1/1989 1988/1/1988 +f 1985/1/1985 1989/1/1989 1992/1/1992 +f 2015/1/2015 2010/1/2010 1992/1/1992 +f 1991/1/1991 1994/1/1994 1996/1/1996 +f 2008/1/2008 2010/1/2010 2015/1/2015 +f 2013/1/2013 2010/1/2010 2011/1/2011 +f 2012/1/2012 2011/1/2011 544/1/544 +f 564/1/564 2012/1/2012 544/1/544 +f 565/1/565 2014/1/2014 564/1/564 +f 567/1/567 565/1/565 562/1/562 +f 566/1/566 562/1/562 568/1/568 +f 571/1/571 568/1/568 569/1/569 +f 573/1/573 569/1/569 572/1/572 +f 618/1/618 573/1/573 572/1/572 +f 613/1/613 618/1/618 617/1/617 +f 616/1/616 613/1/613 617/1/617 +f 1998/1/1998 616/1/616 2001/1/2001 +f 1999/1/1999 2001/1/2001 2003/1/2003 +f 2000/1/2000 1997/1/1997 1999/1/1999 +f 2004/1/2004 1996/1/1996 2000/1/2000 +f 2004/1/2004 2006/1/2006 2007/1/2007 +f 541/1/541 2006/1/2006 537/1/537 +f 2005/1/2005 2002/1/2002 2009/1/2009 +f 536/1/536 534/1/534 537/1/537 +f 533/1/533 530/1/530 534/1/534 +f 535/1/535 2002/1/2002 531/1/531 +f 532/1/532 530/1/530 533/1/533 +f 525/1/525 526/1/526 529/1/529 +f 525/1/525 523/1/523 526/1/526 +f 521/1/521 523/1/523 525/1/525 +f 542/1/542 534/1/534 530/1/530 +f 440/1/440 539/1/539 542/1/542 +f 439/1/439 538/1/538 440/1/440 +f 545/1/545 543/1/543 439/1/439 +f 560/1/560 546/1/546 545/1/545 +f 563/1/563 560/1/560 558/1/558 +f 570/1/570 558/1/558 623/1/623 +f 621/1/621 623/1/623 624/1/624 +f 619/1/619 621/1/621 622/1/622 +f 620/1/620 622/1/622 2410/1/2410 +f 2021/1/2021 620/1/620 2410/1/2410 +f 2409/1/2409 626/1/626 2407/1/2407 +f 2405/1/2405 2408/1/2408 2402/1/2402 +f 626/1/626 627/1/627 2407/1/2407 +f 627/1/627 625/1/625 628/1/628 +f 628/1/628 559/1/559 561/1/561 +f 2408/1/2408 2411/1/2411 2402/1/2402 +f 2405/1/2405 2402/1/2402 2401/1/2401 +f 2404/1/2404 2405/1/2405 2401/1/2401 +f 2019/1/2019 2406/1/2406 2404/1/2404 +f 2017/1/2017 2021/1/2021 2019/1/2019 +f 2020/1/2020 2398/1/2398 2397/1/2397 +f 2397/1/2397 2399/1/2399 2396/1/2396 +f 2393/1/2393 2395/1/2395 2392/1/2392 +f 2395/1/2395 2389/1/2389 2392/1/2392 +f 2399/1/2399 2400/1/2400 2396/1/2396 +f 2395/1/2395 2414/1/2414 2415/1/2415 +f 2403/1/2403 2413/1/2413 2400/1/2400 +f 2414/1/2414 554/1/554 2415/1/2415 +f 2412/1/2412 1479/1/1479 2413/1/2413 +f 561/1/561 553/1/553 1479/1/1479 +f 557/1/557 443/1/443 553/1/553 +f 443/1/443 436/1/436 438/1/438 +f 438/1/438 437/1/437 441/1/441 +f 441/1/441 526/1/526 523/1/523 +f 527/1/527 524/1/524 528/1/528 +f 442/1/442 527/1/527 528/1/528 +f 444/1/444 442/1/442 445/1/445 +f 448/1/448 444/1/444 445/1/445 +f 554/1/554 448/1/448 555/1/555 +f 2415/1/2415 554/1/554 555/1/555 +f 2395/1/2395 2415/1/2415 2389/1/2389 +f 2392/1/2392 2389/1/2389 2387/1/2387 +f 2384/1/2384 2390/1/2390 2380/1/2380 +f 2380/1/2380 556/1/556 2377/1/2377 +f 2381/1/2381 2379/1/2379 2378/1/2378 +f 2381/1/2381 2378/1/2378 2382/1/2382 +f 2376/1/2376 2377/1/2377 454/1/454 +f 2374/1/2374 2373/1/2373 2371/1/2371 +f 2382/1/2382 2378/1/2378 2374/1/2374 +f 2385/1/2385 2381/1/2381 2382/1/2382 +f 2388/1/2388 2383/1/2383 2385/1/2385 +f 2386/1/2386 2383/1/2383 2388/1/2388 +f 2391/1/2391 2387/1/2387 2386/1/2386 +f 2023/1/2023 2394/1/2394 2391/1/2391 +f 2018/1/2018 2023/1/2023 2022/1/2022 +f 2016/1/2016 2017/1/2017 2018/1/2018 +f 531/1/531 2016/1/2016 518/1/518 +f 525/1/525 518/1/518 521/1/521 +f 520/1/520 523/1/523 521/1/521 +f 522/1/522 520/1/520 516/1/516 +f 522/1/522 516/1/516 509/1/509 +f 508/1/508 509/1/509 511/1/511 +f 511/1/511 510/1/510 508/1/508 +f 517/1/517 513/1/513 512/1/512 +f 513/1/513 519/1/519 514/1/514 +f 508/1/508 510/1/510 507/1/507 +f 507/1/507 504/1/504 508/1/508 +f 506/1/506 504/1/504 505/1/505 +f 459/1/459 506/1/506 505/1/505 +f 450/1/450 459/1/459 456/1/456 +f 447/1/447 446/1/446 450/1/450 +f 449/1/449 447/1/447 451/1/451 +f 454/1/454 451/1/451 455/1/455 +f 2369/1/2369 455/1/455 2367/1/2367 +f 2047/1/2047 2367/1/2367 2048/1/2048 +f 2368/1/2368 2367/1/2367 2047/1/2047 +f 2370/1/2370 2368/1/2368 2372/1/2372 +f 2419/1/2419 2370/1/2370 2372/1/2372 +f 2418/1/2418 2370/1/2370 2419/1/2419 +f 2417/1/2417 2375/1/2375 2418/1/2418 +f 2027/1/2027 2416/1/2416 2417/1/2417 +f 2025/1/2025 2024/1/2024 2027/1/2027 +f 514/1/514 2025/1/2025 515/1/515 +f 2026/1/2026 2030/1/2030 2028/1/2028 +f 2028/1/2028 2039/1/2039 2036/1/2036 +f 2036/1/2036 2040/1/2040 2037/1/2037 +f 2037/1/2037 2041/1/2041 2042/1/2042 +f 2033/1/2033 2038/1/2038 2034/1/2034 +f 2042/1/2042 2044/1/2044 2043/1/2043 +f 2042/1/2042 2045/1/2045 2044/1/2044 +f 2050/1/2050 2049/1/2049 2051/1/2051 +f 2046/1/2046 552/1/552 2045/1/2045 +f 2049/1/2049 549/1/549 2051/1/2051 +f 551/1/551 453/1/453 552/1/552 +f 453/1/453 452/1/452 458/1/458 +f 452/1/452 457/1/457 458/1/458 +f 457/1/457 460/1/460 461/1/461 +f 461/1/461 460/1/460 500/1/500 +f 466/1/466 467/1/467 464/1/464 +f 465/1/465 464/1/464 469/1/469 +f 463/1/463 462/1/462 465/1/465 +f 549/1/549 463/1/463 550/1/550 +f 2051/1/2051 549/1/549 550/1/550 +f 2050/1/2050 2051/1/2051 2052/1/2052 +f 2053/1/2053 2050/1/2050 2052/1/2052 +f 2060/1/2060 2053/1/2053 2061/1/2061 +f 2063/1/2063 2061/1/2061 2064/1/2064 +f 2035/1/2035 2062/1/2062 2063/1/2063 +f 2031/1/2031 2034/1/2034 2035/1/2035 +f 2029/1/2029 2032/1/2032 2031/1/2031 +f 496/1/496 2029/1/2029 493/1/493 +f 498/1/498 515/1/515 496/1/496 +f 503/1/503 498/1/498 502/1/502 +f 502/1/502 501/1/501 503/1/503 +f 460/1/460 501/1/501 500/1/500 +f 461/1/461 500/1/500 483/1/483 +f 497/1/497 495/1/495 499/1/499 +f 472/1/472 483/1/483 484/1/484 +f 468/1/468 472/1/472 473/1/473 +f 481/1/481 474/1/474 473/1/473 +f 482/1/482 495/1/495 486/1/486 +f 485/1/485 474/1/474 481/1/481 +f 476/1/476 474/1/474 479/1/479 +f 2364/1/2364 2363/1/2363 479/1/479 +f 480/1/480 487/1/487 488/1/488 +f 486/1/486 491/1/491 487/1/487 +f 491/1/491 494/1/494 2069/1/2069 +f 2069/1/2069 2066/1/2066 359/1/359 +f 2066/1/2066 2065/1/2065 317/1/317 +f 318/1/318 316/1/316 312/1/312 +f 2065/1/2065 2067/1/2067 317/1/317 +f 316/1/316 315/1/315 311/1/311 +f 2059/1/2059 2068/1/2068 2067/1/2067 +f 2068/1/2068 2058/1/2058 2057/1/2057 +f 2057/1/2057 2054/1/2054 2056/1/2056 +f 315/1/315 314/1/314 311/1/311 +f 316/1/316 311/1/311 312/1/312 +f 320/1/320 312/1/312 313/1/313 +f 319/1/319 320/1/320 321/1/321 +f 296/1/296 298/1/298 294/1/294 +f 298/1/298 297/1/297 294/1/294 +f 294/1/294 297/1/297 293/1/293 +f 322/1/322 300/1/300 299/1/299 +f 298/1/298 301/1/301 297/1/297 +f 301/1/301 303/1/303 297/1/297 +f 297/1/297 303/1/303 302/1/302 +f 303/1/303 304/1/304 302/1/302 +f 306/1/306 304/1/304 303/1/303 +f 309/1/309 307/1/307 300/1/300 +f 301/1/301 306/1/306 303/1/303 +f 309/1/309 308/1/308 307/1/307 +f 306/1/306 360/1/360 304/1/304 +f 310/1/310 363/1/363 308/1/308 +f 360/1/360 361/1/361 304/1/304 +f 304/1/304 361/1/361 362/1/362 +f 2056/1/2056 2055/1/2055 363/1/363 +f 2055/1/2055 478/1/478 364/1/364 +f 364/1/364 470/1/470 477/1/477 +f 477/1/477 475/1/475 2092/1/2092 +f 365/1/365 2091/1/2091 2093/1/2093 +f 361/1/361 365/1/365 362/1/362 +f 304/1/304 362/1/362 305/1/305 +f 302/1/302 304/1/304 305/1/305 +f 297/1/297 302/1/302 285/1/285 +f 297/1/297 285/1/285 293/1/293 +f 292/1/292 294/1/294 293/1/293 +f 283/1/283 280/1/280 273/1/273 +f 286/1/286 282/1/282 281/1/281 +f 282/1/282 284/1/284 277/1/277 +f 277/1/277 278/1/278 275/1/275 +f 280/1/280 274/1/274 272/1/272 +f 280/1/280 272/1/272 273/1/273 +f 289/1/289 283/1/283 273/1/273 +f 288/1/288 283/1/283 289/1/289 +f 290/1/290 287/1/287 288/1/288 +f 295/1/295 292/1/292 290/1/290 +f 323/1/323 321/1/321 295/1/295 +f 492/1/492 323/1/323 2071/1/2071 +f 489/1/489 490/1/490 492/1/492 +f 2364/1/2364 489/1/489 2365/1/2365 +f 2365/1/2365 2363/1/2363 2364/1/2364 +f 2092/1/2092 2363/1/2363 2087/1/2087 +f 2088/1/2088 2087/1/2087 2084/1/2084 +f 2366/1/2366 2070/1/2070 2086/1/2086 +f 2079/1/2079 2084/1/2084 2080/1/2080 +f 2083/1/2083 2079/1/2079 2078/1/2078 +f 2083/1/2083 2078/1/2078 2082/1/2082 +f 2077/1/2077 2082/1/2082 2078/1/2078 +f 2076/1/2076 2070/1/2070 2072/1/2072 +f 2081/1/2081 2082/1/2082 2077/1/2077 +f 2083/1/2083 2082/1/2082 2097/1/2097 +f 2094/1/2094 2083/1/2083 2097/1/2097 +f 2095/1/2095 2090/1/2090 2094/1/2094 +f 366/1/366 2095/1/2095 367/1/367 +f 279/1/279 367/1/367 276/1/276 +f 275/1/275 276/1/276 263/1/263 +f 269/1/269 263/1/263 262/1/262 +f 267/1/267 262/1/262 264/1/264 +f 270/1/270 268/1/268 267/1/267 +f 327/1/327 270/1/270 331/1/331 +f 328/1/328 327/1/327 331/1/331 +f 332/1/332 271/1/271 340/1/340 +f 271/1/271 265/1/265 340/1/340 +f 265/1/265 261/1/261 266/1/266 +f 261/1/261 259/1/259 258/1/258 +f 341/1/341 260/1/260 344/1/344 +f 338/1/338 341/1/341 339/1/339 +f 334/1/334 338/1/338 339/1/339 +f 329/1/329 333/1/333 334/1/334 +f 326/1/326 328/1/328 329/1/329 +f 325/1/325 291/1/291 326/1/326 +f 2073/1/2073 324/1/324 325/1/325 +f 2072/1/2072 2073/1/2073 2074/1/2074 +f 2104/1/2104 2074/1/2074 2107/1/2107 +f 2107/1/2107 2103/1/2103 2104/1/2104 +f 2098/1/2098 2103/1/2103 2101/1/2101 +f 2099/1/2099 2098/1/2098 2101/1/2101 +f 2096/1/2096 2099/1/2099 2100/1/2100 +f 257/1/257 2096/1/2096 2100/1/2100 +f 2359/1/2359 2102/1/2102 2358/1/2358 +f 2358/1/2358 2102/1/2102 2109/1/2109 +f 2360/1/2360 2355/1/2355 2361/1/2361 +f 255/1/255 2360/1/2360 2361/1/2361 +f 253/1/253 255/1/255 254/1/254 +f 252/1/252 257/1/257 253/1/253 +f 258/1/258 252/1/252 251/1/251 +f 250/1/250 251/1/251 248/1/248 +f 343/1/343 250/1/250 346/1/346 +f 345/1/345 346/1/346 348/1/348 +f 347/1/347 345/1/345 348/1/348 +f 336/1/336 337/1/337 347/1/347 +f 330/1/330 335/1/335 336/1/336 +f 2112/1/2112 330/1/330 2114/1/2114 +f 2111/1/2111 2075/1/2075 2112/1/2112 +f 2105/1/2105 2111/1/2111 2110/1/2110 +f 2110/1/2110 2106/1/2106 2105/1/2105 +f 2102/1/2102 2106/1/2106 2109/1/2109 +f 2358/1/2358 2109/1/2109 2354/1/2354 +f 2108/1/2108 2113/1/2113 2357/1/2357 +f 2352/1/2352 2354/1/2354 2353/1/2353 +f 2356/1/2356 2352/1/2352 2351/1/2351 +f 2119/1/2119 375/1/375 2351/1/2351 +f 2118/1/2118 2113/1/2113 2115/1/2115 +f 2349/1/2349 375/1/375 2119/1/2119 +f 374/1/374 375/1/375 373/1/373 +f 374/1/374 373/1/373 183/1/183 +f 182/1/182 183/1/183 371/1/371 +f 2350/1/2350 2120/1/2120 372/1/372 +f 2115/1/2115 2117/1/2117 2120/1/2120 +f 2117/1/2117 2116/1/2116 2122/1/2122 +f 2124/1/2124 2123/1/2123 2127/1/2127 +f 2116/1/2116 356/1/356 2122/1/2122 +f 356/1/356 350/1/350 352/1/352 +f 352/1/352 349/1/349 351/1/351 +f 349/1/349 247/1/247 351/1/351 +f 353/1/353 242/1/242 241/1/241 +f 353/1/353 241/1/241 357/1/357 +f 245/1/245 243/1/243 247/1/247 +f 246/1/246 244/1/244 243/1/243 +f 244/1/244 249/1/249 237/1/237 +f 242/1/242 238/1/238 241/1/241 +f 357/1/357 241/1/241 239/1/239 +f 354/1/354 353/1/353 357/1/357 +f 355/1/355 354/1/354 2217/1/2217 +f 2123/1/2123 2217/1/2217 2127/1/2127 +f 2215/1/2215 358/1/358 2214/1/2214 +f 2214/1/2214 2216/1/2216 2210/1/2210 +f 2213/1/2213 2212/1/2212 2207/1/2207 +f 2203/1/2203 2209/1/2209 2204/1/2204 +f 2209/1/2209 2220/1/2220 2204/1/2204 +f 2204/1/2204 2220/1/2220 2221/1/2221 +f 2220/1/2220 232/1/232 2221/1/2221 +f 2219/1/2219 232/1/232 2220/1/2220 +f 2210/1/2210 2211/1/2211 2208/1/2208 +f 2209/1/2209 2219/1/2219 2220/1/2220 +f 2210/1/2210 2218/1/2218 2211/1/2211 +f 2219/1/2219 235/1/235 232/1/232 +f 240/1/240 233/1/233 2218/1/2218 +f 236/1/236 234/1/234 233/1/233 +f 237/1/237 224/1/224 234/1/234 +f 224/1/224 256/1/256 225/1/225 +f 225/1/225 376/1/376 221/1/221 +f 374/1/374 183/1/183 221/1/221 +f 219/1/219 184/1/184 217/1/217 +f 220/1/220 217/1/217 218/1/218 +f 223/1/223 218/1/218 190/1/190 +f 231/1/231 222/1/222 223/1/223 +f 235/1/235 231/1/231 232/1/232 +f 2221/1/2221 232/1/232 229/1/229 +f 2204/1/2204 2221/1/2221 2222/1/2222 +f 2201/1/2201 2222/1/2222 2202/1/2202 +f 2197/1/2197 2201/1/2201 2202/1/2202 +f 2198/1/2198 2199/1/2199 2197/1/2197 +f 2200/1/2200 2199/1/2199 2198/1/2198 +f 2206/1/2206 2205/1/2205 2200/1/2200 +f 2128/1/2128 2207/1/2207 2206/1/2206 +f 2124/1/2124 2127/1/2127 2128/1/2128 +f 2121/1/2121 2124/1/2124 2125/1/2125 +f 378/1/378 2121/1/2121 2125/1/2125 +f 371/1/371 378/1/378 182/1/182 +f 182/1/182 181/1/181 183/1/183 +f 185/1/185 181/1/181 180/1/180 +f 179/1/179 175/1/175 178/1/178 +f 171/1/171 180/1/180 174/1/174 +f 168/1/168 172/1/172 171/1/171 +f 165/1/165 164/1/164 168/1/168 +f 170/1/170 173/1/173 169/1/169 +f 175/1/175 176/1/176 173/1/173 +f 176/1/176 2126/1/2126 2129/1/2129 +f 2129/1/2129 2130/1/2130 2131/1/2131 +f 2131/1/2131 2196/1/2196 2195/1/2195 +f 2195/1/2195 2194/1/2194 2189/1/2189 +f 2194/1/2194 2190/1/2190 2189/1/2189 +f 2187/1/2187 2186/1/2186 2182/1/2182 +f 2186/1/2186 2191/1/2191 2184/1/2184 +f 2192/1/2192 2193/1/2193 2190/1/2190 +f 2191/1/2191 2224/1/2224 2184/1/2184 +f 2223/1/2223 230/1/230 2193/1/2193 +f 230/1/230 227/1/227 228/1/228 +f 228/1/228 226/1/226 189/1/189 +f 2224/1/2224 368/1/368 2175/1/2175 +f 2175/1/2175 2174/1/2174 2178/1/2178 +f 2170/1/2170 2171/1/2171 2172/1/2172 +f 2174/1/2174 2176/1/2176 2177/1/2177 +f 2180/1/2180 2181/1/2181 2176/1/2176 +f 2180/1/2180 2226/1/2226 2181/1/2181 +f 2228/1/2228 2226/1/2226 2180/1/2180 +f 2227/1/2227 2226/1/2226 2228/1/2228 +f 2145/1/2145 2227/1/2227 2165/1/2165 +f 2225/1/2225 2226/1/2226 2227/1/2227 +f 2181/1/2181 2226/1/2226 2225/1/2225 +f 2141/1/2141 2179/1/2179 2181/1/2181 +f 2138/1/2138 2179/1/2179 2141/1/2141 +f 2139/1/2139 2185/1/2185 2138/1/2138 +f 2133/1/2133 2188/1/2188 2139/1/2139 +f 2132/1/2132 2133/1/2133 2134/1/2134 +f 162/1/162 2132/1/2132 2134/1/2134 +f 161/1/161 177/1/177 162/1/162 +f 165/1/165 161/1/161 160/1/160 +f 156/1/156 163/1/163 160/1/160 +f 163/1/163 166/1/166 167/1/167 +f 150/1/150 155/1/155 154/1/154 +f 191/1/191 167/1/167 166/1/166 +f 191/1/191 192/1/192 189/1/189 +f 194/1/194 195/1/195 193/1/193 +f 197/1/197 195/1/195 194/1/194 +f 197/1/197 198/1/198 195/1/195 +f 192/1/192 370/1/370 369/1/369 +f 216/1/216 2172/1/2172 370/1/370 +f 195/1/195 198/1/198 214/1/214 +f 214/1/214 198/1/198 210/1/210 +f 214/1/214 210/1/210 212/1/212 +f 216/1/216 2170/1/2170 2172/1/2172 +f 2170/1/2170 2173/1/2173 2171/1/2171 +f 2166/1/2166 2167/1/2167 2173/1/2173 +f 2161/1/2161 2162/1/2162 2166/1/2166 +f 2168/1/2168 2157/1/2157 2161/1/2161 +f 2169/1/2169 214/1/214 215/1/215 +f 215/1/215 214/1/214 212/1/212 +f 2168/1/2168 213/1/213 2158/1/2158 +f 2158/1/2158 2153/1/2153 2154/1/2154 +f 416/1/416 425/1/425 2153/1/2153 +f 409/1/409 414/1/414 412/1/412 +f 409/1/409 413/1/413 414/1/414 +f 405/1/405 413/1/413 409/1/409 +f 416/1/416 418/1/418 425/1/425 +f 413/1/413 415/1/415 414/1/414 +f 413/1/413 407/1/407 415/1/415 +f 407/1/407 417/1/417 415/1/415 +f 407/1/407 382/1/382 417/1/417 +f 423/1/423 425/1/425 418/1/418 +f 2152/1/2152 425/1/425 423/1/423 +f 2148/1/2148 2151/1/2151 2152/1/2152 +f 2149/1/2149 2151/1/2151 2148/1/2148 +f 2147/1/2147 2150/1/2150 2149/1/2149 +f 2143/1/2143 2164/1/2164 2147/1/2147 +f 2140/1/2140 2144/1/2144 2143/1/2143 +f 2137/1/2137 2142/1/2142 2140/1/2140 +f 2136/1/2136 2137/1/2137 2135/1/2135 +f 159/1/159 2135/1/2135 158/1/158 +f 152/1/152 159/1/159 158/1/158 +f 151/1/151 157/1/157 152/1/152 +f 151/1/151 150/1/150 154/1/154 +f 143/1/143 148/1/148 147/1/147 +f 153/1/153 155/1/155 150/1/150 +f 143/1/143 149/1/149 148/1/148 +f 145/1/145 149/1/149 143/1/143 +f 153/1/153 196/1/196 155/1/155 +f 194/1/194 196/1/196 197/1/197 +f 145/1/145 199/1/199 149/1/149 +f 200/1/200 198/1/198 197/1/197 +f 200/1/200 210/1/210 198/1/198 +f 212/1/212 210/1/210 211/1/211 +f 204/1/204 208/1/208 211/1/211 +f 207/1/207 208/1/208 204/1/204 +f 203/1/203 199/1/199 146/1/146 +f 204/1/204 202/1/202 205/1/205 +f 204/1/204 205/1/205 207/1/207 +f 207/1/207 209/1/209 208/1/208 +f 410/1/410 209/1/209 411/1/411 +f 410/1/410 411/1/411 408/1/408 +f 409/1/409 408/1/408 405/1/405 +f 405/1/405 407/1/407 413/1/413 +f 406/1/406 383/1/383 407/1/407 +f 390/1/390 384/1/384 406/1/406 +f 403/1/403 404/1/404 399/1/399 +f 398/1/398 391/1/391 390/1/390 +f 391/1/391 386/1/386 390/1/390 +f 394/1/394 393/1/393 392/1/392 +f 393/1/393 106/1/106 392/1/392 +f 98/1/98 106/1/106 393/1/393 +f 98/1/98 99/1/99 106/1/106 +f 99/1/99 104/1/104 106/1/106 +f 104/1/104 99/1/99 100/1/100 +f 391/1/391 389/1/389 386/1/386 +f 390/1/390 386/1/386 384/1/384 +f 406/1/406 384/1/384 383/1/383 +f 383/1/383 382/1/382 407/1/407 +f 420/1/420 417/1/417 382/1/382 +f 422/1/422 419/1/419 420/1/420 +f 126/1/126 419/1/419 422/1/422 +f 125/1/125 424/1/424 126/1/126 +f 122/1/122 2146/1/2146 125/1/125 +f 131/1/131 2146/1/2146 122/1/122 +f 130/1/130 138/1/138 131/1/131 +f 137/1/137 138/1/138 130/1/130 +f 142/1/142 379/1/379 137/1/137 +f 147/1/147 142/1/142 143/1/143 +f 144/1/144 145/1/145 143/1/143 +f 145/1/145 146/1/146 199/1/199 +f 140/1/140 139/1/139 135/1/135 +f 141/1/141 201/1/201 146/1/146 +f 136/1/136 135/1/135 129/1/129 +f 134/1/134 206/1/206 201/1/201 +f 132/1/132 129/1/129 128/1/128 +f 2276/1/2276 2277/1/2277 2275/1/2275 +f 133/1/133 2278/1/2278 206/1/206 +f 2276/1/2276 2233/1/2233 2277/1/2277 +f 2235/1/2235 2278/1/2278 2279/1/2279 +f 2235/1/2235 2279/1/2279 2230/1/2230 +f 2236/1/2236 2234/1/2234 2233/1/2233 +f 2236/1/2236 2237/1/2237 2234/1/2234 +f 2241/1/2241 2237/1/2237 2236/1/2236 +f 2231/1/2231 2229/1/2229 2230/1/2230 +f 2231/1/2231 2232/1/2232 2229/1/2229 +f 2238/1/2238 2234/1/2234 2237/1/2237 +f 2239/1/2239 2242/1/2242 2232/1/2232 +f 400/1/400 2232/1/2232 2242/1/2242 +f 399/1/399 400/1/400 396/1/396 +f 401/1/401 91/1/91 95/1/95 +f 395/1/395 396/1/396 397/1/397 +f 395/1/395 98/1/98 393/1/393 +f 94/1/94 95/1/95 91/1/91 +f 98/1/98 96/1/96 99/1/99 +f 91/1/91 93/1/93 94/1/94 +f 91/1/91 90/1/90 93/1/93 +f 90/1/90 92/1/92 93/1/93 +f 100/1/100 99/1/99 96/1/96 +f 103/1/103 104/1/104 100/1/100 +f 106/1/106 104/1/104 107/1/107 +f 109/1/109 388/1/388 107/1/107 +f 387/1/387 388/1/388 109/1/109 +f 116/1/116 385/1/385 387/1/387 +f 119/1/119 381/1/381 116/1/116 +f 118/1/118 380/1/380 119/1/119 +f 117/1/117 421/1/421 118/1/118 +f 120/1/120 121/1/121 117/1/117 +f 123/1/123 120/1/120 124/1/124 +f 128/1/128 127/1/127 123/1/123 +f 2275/1/2275 128/1/128 2276/1/2276 +f 2273/1/2273 2233/1/2233 2276/1/2276 +f 2273/1/2273 2236/1/2236 2233/1/2233 +f 2274/1/2274 2270/1/2270 2272/1/2272 +f 2271/1/2271 2241/1/2241 2236/1/2236 +f 2240/1/2240 2237/1/2237 2241/1/2241 +f 2269/1/2269 2270/1/2270 2266/1/2266 +f 2248/1/2248 2240/1/2240 2268/1/2268 +f 2248/1/2248 2243/1/2243 2240/1/2240 +f 2244/1/2244 2243/1/2243 2246/1/2246 +f 2249/1/2249 2250/1/2250 2246/1/2246 +f 2250/1/2250 91/1/91 401/1/401 +f 89/1/89 90/1/90 91/1/91 +f 89/1/89 80/1/80 90/1/90 +f 76/1/76 90/1/90 80/1/80 +f 89/1/89 86/1/86 80/1/80 +f 86/1/86 81/1/81 80/1/80 +f 77/1/77 80/1/80 81/1/81 +f 83/1/83 81/1/81 86/1/86 +f 79/1/79 81/1/81 83/1/83 +f 79/1/79 83/1/83 82/1/82 +f 86/1/86 89/1/89 88/1/88 +f 2252/1/2252 2251/1/2251 2254/1/2254 +f 2253/1/2253 2254/1/2254 2251/1/2251 +f 2255/1/2255 88/1/88 89/1/89 +f 86/1/86 88/1/88 83/1/83 +f 82/1/82 83/1/83 85/1/85 +f 84/1/84 82/1/82 85/1/85 +f 84/1/84 85/1/85 429/1/429 +f 84/1/84 429/1/429 430/1/430 +f 430/1/430 429/1/429 431/1/431 +f 430/1/430 431/1/431 2313/1/2313 +f 433/1/433 430/1/430 2313/1/2313 +f 2313/1/2313 431/1/431 2348/1/2348 +f 2313/1/2313 2348/1/2348 2314/1/2314 +f 2306/1/2306 2313/1/2313 2314/1/2314 +f 2306/1/2306 2314/1/2314 2315/1/2315 +f 2306/1/2306 2315/1/2315 2310/1/2310 +f 2310/1/2310 2315/1/2315 2316/1/2316 +f 2310/1/2310 2316/1/2316 2317/1/2317 +f 2311/1/2311 2310/1/2310 2317/1/2317 +f 2311/1/2311 2317/1/2317 2338/1/2338 +f 2345/1/2345 2311/1/2311 2338/1/2338 +f 2345/1/2345 2338/1/2338 2346/1/2346 +f 2484/1/2484 2345/1/2345 2346/1/2346 +f 2484/1/2484 2346/1/2346 2347/1/2347 +f 2494/1/2494 2484/1/2484 2347/1/2347 +f 2494/1/2494 2347/1/2347 2497/1/2497 +f 2497/1/2497 2495/1/2495 2494/1/2494 +f 2494/1/2494 2495/1/2495 2492/1/2492 +f 2494/1/2494 2492/1/2492 2491/1/2491 +f 2491/1/2491 2492/1/2492 2490/1/2490 +f 2491/1/2491 2490/1/2490 2486/1/2486 +f 2486/1/2486 2484/1/2484 2491/1/2491 +f 2486/1/2486 2482/1/2482 2484/1/2484 +f 2485/1/2485 2482/1/2482 2486/1/2486 +f 2483/1/2483 2482/1/2482 2485/1/2485 +f 2485/1/2485 2487/1/2487 2483/1/2483 +f 2485/1/2485 2489/1/2489 2487/1/2487 +f 2487/1/2487 2489/1/2489 2488/1/2488 +f 2485/1/2485 2490/1/2490 2489/1/2489 +f 2490/1/2490 2329/1/2329 2489/1/2489 +f 2489/1/2489 2329/1/2329 2499/1/2499 +f 2499/1/2499 2329/1/2329 2326/1/2326 +f 2328/1/2328 2326/1/2326 2329/1/2329 +f 2328/1/2328 2329/1/2329 2330/1/2330 +f 2327/1/2327 2328/1/2328 2330/1/2330 +f 2327/1/2327 2330/1/2330 2332/1/2332 +f 2331/1/2331 2327/1/2327 2332/1/2332 +f 2331/1/2331 2332/1/2332 2336/1/2336 +f 2331/1/2331 2336/1/2336 2337/1/2337 +f 2331/1/2331 2337/1/2337 2338/1/2338 +f 2338/1/2338 2337/1/2337 2343/1/2343 +f 2338/1/2338 2343/1/2343 2347/1/2347 +f 2343/1/2343 2498/1/2498 2347/1/2347 +f 2498/1/2498 2343/1/2343 2344/1/2344 +f 2344/1/2344 2496/1/2496 2498/1/2498 +f 2498/1/2498 2496/1/2496 2497/1/2497 +f 2496/1/2496 2344/1/2344 2493/1/2493 +f 2496/1/2496 2493/1/2493 2495/1/2495 +f 2344/1/2344 2335/1/2335 2493/1/2493 +f 2493/1/2493 2335/1/2335 2490/1/2490 +f 2344/1/2344 2339/1/2339 2335/1/2335 +f 2334/1/2334 2335/1/2335 2339/1/2339 +f 2334/1/2334 2339/1/2339 2336/1/2336 +f 2333/1/2333 2334/1/2334 2336/1/2336 +f 2333/1/2333 2329/1/2329 2334/1/2334 +f 2336/1/2336 2339/1/2339 2340/1/2340 +f 2339/1/2339 2341/1/2341 2340/1/2340 +f 2341/1/2341 2342/1/2342 2340/1/2340 +f 2337/1/2337 2340/1/2340 2342/1/2342 +f 2341/1/2341 2344/1/2344 2342/1/2342 +f 2329/1/2329 2335/1/2335 2334/1/2334 +f 2339/1/2339 2344/1/2344 2341/1/2341 +f 2343/1/2343 2342/1/2342 2344/1/2344 +f 2342/1/2342 2343/1/2343 2337/1/2337 +f 2336/1/2336 2340/1/2340 2337/1/2337 +f 2332/1/2332 2333/1/2333 2336/1/2336 +f 2317/1/2317 2327/1/2327 2331/1/2331 +f 2317/1/2317 2319/1/2319 2327/1/2327 +f 2319/1/2319 2325/1/2325 2327/1/2327 +f 2319/1/2319 2321/1/2321 2325/1/2325 +f 2321/1/2321 2326/1/2326 2325/1/2325 +f 2321/1/2321 2324/1/2324 2326/1/2326 +f 2320/1/2320 2324/1/2324 2321/1/2321 +f 2316/1/2316 2320/1/2320 2321/1/2321 +f 2316/1/2316 2318/1/2318 2320/1/2320 +f 2318/1/2318 2324/1/2324 2320/1/2320 +f 2316/1/2316 2321/1/2321 2319/1/2319 +f 2332/1/2332 2330/1/2330 2333/1/2333 +f 2327/1/2327 2325/1/2325 2328/1/2328 +f 2329/1/2329 2333/1/2333 2330/1/2330 +f 2325/1/2325 2326/1/2326 2328/1/2328 +f 2490/1/2490 2335/1/2335 2329/1/2329 +f 2486/1/2486 2490/1/2490 2485/1/2485 +f 2490/1/2490 2492/1/2492 2493/1/2493 +f 2492/1/2492 2495/1/2495 2493/1/2493 +f 2497/1/2497 2496/1/2496 2495/1/2495 +f 2497/1/2497 2347/1/2347 2498/1/2498 +f 2491/1/2491 2484/1/2484 2494/1/2494 +f 2482/1/2482 2345/1/2345 2484/1/2484 +f 2482/1/2482 2312/1/2312 2345/1/2345 +f 2479/1/2479 2312/1/2312 2482/1/2482 +f 2346/1/2346 2338/1/2338 2347/1/2347 +f 2312/1/2312 2311/1/2311 2345/1/2345 +f 2312/1/2312 2307/1/2307 2311/1/2311 +f 2338/1/2338 2317/1/2317 2331/1/2331 +f 2307/1/2307 2310/1/2310 2311/1/2311 +f 2317/1/2317 2316/1/2316 2319/1/2319 +f 2315/1/2315 2318/1/2318 2316/1/2316 +f 2315/1/2315 2322/1/2322 2318/1/2318 +f 2318/1/2318 2322/1/2322 2323/1/2323 +f 2323/1/2323 2322/1/2322 432/1/432 +f 2348/1/2348 432/1/432 2322/1/2322 +f 2314/1/2314 2322/1/2322 2315/1/2315 +f 2314/1/2314 2348/1/2348 2322/1/2322 +f 431/1/431 432/1/432 2348/1/2348 +f 431/1/431 428/1/428 432/1/432 +f 429/1/429 428/1/428 431/1/431 +f 85/1/85 426/1/426 429/1/429 +f 429/1/429 426/1/426 428/1/428 +f 427/1/427 432/1/432 428/1/428 +f 87/1/87 2294/1/2294 2295/1/2295 +f 2292/1/2292 2295/1/2295 2294/1/2294 +f 2323/1/2323 432/1/432 427/1/427 +f 2323/1/2323 2324/1/2324 2318/1/2318 +f 2501/1/2501 2326/1/2326 2324/1/2324 +f 2499/1/2499 2326/1/2326 2501/1/2501 +f 2489/1/2489 2499/1/2499 2488/1/2488 +f 2483/1/2483 2487/1/2487 2488/1/2488 +f 2483/1/2483 2479/1/2479 2482/1/2482 +f 2480/1/2480 2308/1/2308 2481/1/2481 +f 2479/1/2479 2309/1/2309 2312/1/2312 +f 2304/1/2304 2305/1/2305 2308/1/2308 +f 2309/1/2309 2307/1/2307 2312/1/2312 +f 2303/1/2303 435/1/435 2305/1/2305 +f 2307/1/2307 2306/1/2306 2310/1/2310 +f 433/1/433 2313/1/2313 2306/1/2306 +f 433/1/433 84/1/84 430/1/430 +f 78/1/78 82/1/82 84/1/84 +f 78/1/78 79/1/79 82/1/82 +f 77/1/77 81/1/81 79/1/79 +f 76/1/76 80/1/80 77/1/77 +f 92/1/92 90/1/90 76/1/76 +f 93/1/93 92/1/92 97/1/97 +f 71/1/71 101/1/101 97/1/97 +f 69/1/69 102/1/102 71/1/71 +f 108/1/108 105/1/105 69/1/69 +f 111/1/111 113/1/113 108/1/108 +f 114/1/114 112/1/112 111/1/111 +f 2270/1/2270 114/1/114 2266/1/2266 +f 2267/1/2267 2266/1/2266 2265/1/2265 +f 2264/1/2264 2247/1/2247 2265/1/2265 +f 2253/1/2253 2251/1/2251 2247/1/2247 +f 2258/1/2258 2254/1/2254 2253/1/2253 +f 2261/1/2261 2256/1/2256 2258/1/2258 +f 2283/1/2283 2256/1/2256 2261/1/2261 +f 2261/1/2261 2263/1/2263 2281/1/2281 +f 2260/1/2260 2262/1/2262 2259/1/2259 +f 2262/1/2262 115/1/115 2280/1/2280 +f 2280/1/2280 110/1/110 68/1/68 +f 2263/1/2263 2284/1/2284 2281/1/2281 +f 2261/1/2261 2281/1/2281 2282/1/2282 +f 2282/1/2282 2283/1/2283 2261/1/2261 +f 2283/1/2283 2293/1/2293 2256/1/2256 +f 2292/1/2292 2294/1/2294 2293/1/2293 +f 2298/1/2298 2295/1/2295 2292/1/2292 +f 2291/1/2291 2296/1/2296 2298/1/2298 +f 2289/1/2289 2286/1/2286 2290/1/2290 +f 2299/1/2299 2296/1/2296 2291/1/2291 +f 2299/1/2299 2302/1/2302 2296/1/2296 +f 2502/1/2502 2503/1/2503 2302/1/2302 +f 2500/1/2500 2502/1/2502 2480/1/2480 +f 2480/1/2480 2304/1/2304 2308/1/2308 +f 2301/1/2301 2288/1/2288 2300/1/2300 +f 2304/1/2304 2303/1/2303 2305/1/2305 +f 2286/1/2286 2287/1/2287 2288/1/2288 +f 2303/1/2303 434/1/434 435/1/435 +f 2285/1/2285 70/1/70 2287/1/2287 +f 434/1/434 75/1/75 435/1/435 +f 67/1/67 74/1/74 75/1/75 +f 68/1/68 65/1/65 70/1/70 +f 67/1/67 66/1/66 73/1/73 +f 65/1/65 72/1/72 66/1/66 +f 2516/1/2516 2517/1/2517 2518/1/2518 +f 2521/1/2521 2516/1/2516 2518/1/2518 +f 2521/1/2521 2518/1/2518 2591/1/2591 +f 2521/1/2521 2591/1/2591 2596/1/2596 +f 4858/1/4858 2521/1/2521 2596/1/2596 +f 4858/1/4858 2596/1/2596 4863/1/4863 +f 4859/1/4859 4858/1/4858 4863/1/4863 +f 4859/1/4859 4863/1/4863 4864/1/4864 +f 4872/1/4872 4859/1/4859 4864/1/4864 +f 4872/1/4872 4864/1/4864 4873/1/4873 +f 4873/1/4873 4877/1/4877 4872/1/4872 +f 4872/1/4872 4877/1/4877 4878/1/4878 +f 4872/1/4872 4878/1/4878 4881/1/4881 +f 4872/1/4872 4881/1/4881 4883/1/4883 +f 4883/1/4883 4881/1/4881 4862/1/4862 +f 4862/1/4862 4859/1/4859 4883/1/4883 +f 4862/1/4862 4857/1/4857 4859/1/4859 +f 4861/1/4861 4857/1/4857 4862/1/4862 +f 4862/1/4862 4884/1/4884 4861/1/4861 +f 4884/1/4884 4885/1/4885 4861/1/4861 +f 4861/1/4861 4885/1/4885 4860/1/4860 +f 4860/1/4860 4885/1/4885 4889/1/4889 +f 4860/1/4860 4889/1/4889 4890/1/4890 +f 4860/1/4860 4890/1/4890 4896/1/4896 +f 4896/1/4896 4853/1/4853 4860/1/4860 +f 4860/1/4860 4853/1/4853 4857/1/4857 +f 4853/1/4853 4856/1/4856 4857/1/4857 +f 4857/1/4857 4856/1/4856 4858/1/4858 +f 4853/1/4853 4852/1/4852 4856/1/4856 +f 4852/1/4852 2521/1/2521 4856/1/4856 +f 4852/1/4852 2519/1/2519 2521/1/2521 +f 2539/1/2539 2519/1/2519 4852/1/4852 +f 4851/1/4851 2539/1/2539 4852/1/4852 +f 4850/1/4850 2539/1/2539 4851/1/4851 +f 4854/1/4854 4850/1/4850 4851/1/4851 +f 4854/1/4854 4851/1/4851 4855/1/4855 +f 4855/1/4855 4895/1/4895 4854/1/4854 +f 4895/1/4895 4897/1/4897 4854/1/4854 +f 4854/1/4854 4897/1/4897 4902/1/4902 +f 4902/1/4902 4897/1/4897 4903/1/4903 +f 4902/1/4902 4903/1/4903 4904/1/4904 +f 4904/1/4904 4850/1/4850 4902/1/4902 +f 4905/1/4905 4850/1/4850 4904/1/4904 +f 4905/1/4905 4846/1/4846 4850/1/4850 +f 4846/1/4846 2527/1/2527 4850/1/4850 +f 4846/1/4846 2530/1/2530 2527/1/2527 +f 2530/1/2530 2525/1/2525 2527/1/2527 +f 2527/1/2527 2525/1/2525 2524/1/2524 +f 2527/1/2527 2524/1/2524 2539/1/2539 +f 2525/1/2525 2526/1/2526 2524/1/2524 +f 2524/1/2524 2526/1/2526 2520/1/2520 +f 2524/1/2524 2520/1/2520 2519/1/2519 +f 2519/1/2519 2520/1/2520 2516/1/2516 +f 2520/1/2520 2522/1/2522 2516/1/2516 +f 2516/1/2516 2522/1/2522 2523/1/2523 +f 2522/1/2522 2579/1/2579 2523/1/2523 +f 2523/1/2523 2579/1/2579 2578/1/2578 +f 2523/1/2523 2578/1/2578 2517/1/2517 +f 2517/1/2517 2578/1/2578 2581/1/2581 +f 2517/1/2517 2581/1/2581 2586/1/2586 +f 2586/1/2586 2581/1/2581 2584/1/2584 +f 2586/1/2586 2584/1/2584 2587/1/2587 +f 2518/1/2518 2586/1/2586 2587/1/2587 +f 2587/1/2587 2584/1/2584 2588/1/2588 +f 2587/1/2587 2588/1/2588 2590/1/2590 +f 2591/1/2591 2587/1/2587 2590/1/2590 +f 2591/1/2591 2590/1/2590 2597/1/2597 +f 2591/1/2591 2597/1/2597 2598/1/2598 +f 2599/1/2599 2591/1/2591 2598/1/2598 +f 2599/1/2599 2598/1/2598 2604/1/2604 +f 2599/1/2599 2604/1/2604 2605/1/2605 +f 4865/1/4865 2599/1/2599 2605/1/2605 +f 4865/1/4865 2605/1/2605 4866/1/4866 +f 4871/1/4871 4865/1/4865 4866/1/4866 +f 4871/1/4871 4866/1/4866 4874/1/4874 +f 4875/1/4875 4871/1/4871 4874/1/4874 +f 4875/1/4875 4874/1/4874 4928/1/4928 +f 4928/1/4928 4932/1/4932 4875/1/4875 +f 4875/1/4875 4932/1/4932 4933/1/4933 +f 4875/1/4875 4933/1/4933 4876/1/4876 +f 4875/1/4875 4876/1/4876 4873/1/4873 +f 4876/1/4876 4933/1/4933 4879/1/4879 +f 4876/1/4876 4879/1/4879 4877/1/4877 +f 4877/1/4877 4879/1/4879 4880/1/4880 +f 4879/1/4879 2614/1/2614 4880/1/4880 +f 2614/1/2614 2616/1/2616 4880/1/4880 +f 2616/1/2616 4886/1/4886 4880/1/4880 +f 4882/1/4882 4880/1/4880 4886/1/4886 +f 4882/1/4882 4886/1/4886 4884/1/4884 +f 4884/1/4884 4886/1/4886 4887/1/4887 +f 4888/1/4888 4887/1/4887 4886/1/4886 +f 2618/1/2618 4888/1/4888 4886/1/4886 +f 2618/1/2618 4886/1/4886 2617/1/2617 +f 2617/1/2617 2610/1/2610 2618/1/2618 +f 2618/1/2618 2610/1/2610 2619/1/2619 +f 2619/1/2619 2601/1/2601 2618/1/2618 +f 2618/1/2618 2601/1/2601 2589/1/2589 +f 2618/1/2618 2589/1/2589 2583/1/2583 +f 2583/1/2583 2589/1/2589 2585/1/2585 +f 2583/1/2583 2585/1/2585 2582/1/2582 +f 2582/1/2582 2576/1/2576 2583/1/2583 +f 4893/1/4893 2583/1/2583 2576/1/2576 +f 4893/1/4893 2576/1/2576 4899/1/4899 +f 4899/1/4899 4898/1/4898 4893/1/4893 +f 4898/1/4898 4894/1/4894 4893/1/4893 +f 4893/1/4893 4894/1/4894 4892/1/4892 +f 4893/1/4893 4892/1/4892 4888/1/4888 +f 4888/1/4888 4892/1/4892 4889/1/4889 +f 4889/1/4889 4892/1/4892 4891/1/4891 +f 4891/1/4891 4892/1/4892 4894/1/4894 +f 4891/1/4891 4894/1/4894 4895/1/4895 +f 4897/1/4897 4894/1/4894 4898/1/4898 +f 4897/1/4897 4898/1/4898 4900/1/4900 +f 4901/1/4901 4900/1/4900 4898/1/4898 +f 4925/1/4925 4900/1/4900 4901/1/4901 +f 4901/1/4901 4899/1/4899 4925/1/4925 +f 4925/1/4925 4899/1/4899 4924/1/4924 +f 4925/1/4925 4924/1/4924 4926/1/4926 +f 4926/1/4926 4907/1/4907 4925/1/4925 +f 4926/1/4926 4912/1/4912 4907/1/4907 +f 4910/1/4910 4907/1/4907 4912/1/4912 +f 4910/1/4910 4912/1/4912 4913/1/4913 +f 4910/1/4910 4913/1/4913 4911/1/4911 +f 4849/1/4849 4910/1/4910 4911/1/4911 +f 4849/1/4849 4911/1/4911 4848/1/4848 +f 4848/1/4848 3984/1/3984 4849/1/4849 +f 4849/1/4849 3984/1/3984 4846/1/4846 +f 4849/1/4849 4846/1/4846 4909/1/4909 +f 4909/1/4909 4846/1/4846 4908/1/4908 +f 4908/1/4908 4906/1/4906 4909/1/4909 +f 4906/1/4906 4910/1/4910 4909/1/4909 +f 4905/1/4905 4906/1/4906 4908/1/4908 +f 4905/1/4905 4903/1/4903 4906/1/4906 +f 4903/1/4903 4907/1/4907 4906/1/4906 +f 4903/1/4903 4900/1/4900 4907/1/4907 +f 4847/1/4847 3984/1/3984 4848/1/4848 +f 4848/1/4848 4914/1/4914 4847/1/4847 +f 4847/1/4847 4914/1/4914 3983/1/3983 +f 4847/1/4847 3983/1/3983 3981/1/3981 +f 3981/1/3981 3983/1/3983 3982/1/3982 +f 3982/1/3982 3959/1/3959 3981/1/3981 +f 3959/1/3959 2536/1/2536 3981/1/3981 +f 3981/1/3981 2536/1/2536 2533/1/2533 +f 3981/1/3981 2533/1/2533 3984/1/3984 +f 3984/1/3984 2533/1/2533 2530/1/2530 +f 2533/1/2533 2528/1/2528 2530/1/2530 +f 2533/1/2533 2531/1/2531 2528/1/2528 +f 2531/1/2531 2532/1/2532 2528/1/2528 +f 2528/1/2528 2532/1/2532 2529/1/2529 +f 2528/1/2528 2529/1/2529 2525/1/2525 +f 2532/1/2532 2543/1/2543 2529/1/2529 +f 2529/1/2529 2543/1/2543 2547/1/2547 +f 2529/1/2529 2547/1/2547 2546/1/2546 +f 2529/1/2529 2546/1/2546 2526/1/2526 +f 2526/1/2526 2546/1/2546 2550/1/2550 +f 2526/1/2526 2550/1/2550 2552/1/2552 +f 2526/1/2526 2552/1/2552 2551/1/2551 +f 2552/1/2552 2556/1/2556 2551/1/2551 +f 2551/1/2551 2556/1/2556 2557/1/2557 +f 2551/1/2551 2557/1/2557 2595/1/2595 +f 2520/1/2520 2551/1/2551 2595/1/2595 +f 2520/1/2520 2595/1/2595 2593/1/2593 +f 2595/1/2595 2594/1/2594 2593/1/2593 +f 2593/1/2593 2594/1/2594 2592/1/2592 +f 2593/1/2593 2592/1/2592 2522/1/2522 +f 2594/1/2594 2574/1/2574 2592/1/2592 +f 2592/1/2592 2574/1/2574 2579/1/2579 +f 2575/1/2575 2579/1/2579 2574/1/2574 +f 2572/1/2572 2575/1/2575 2574/1/2574 +f 2572/1/2572 2574/1/2574 2563/1/2563 +f 2571/1/2571 2572/1/2572 2563/1/2563 +f 2571/1/2571 2563/1/2563 2568/1/2568 +f 2568/1/2568 2570/1/2570 2571/1/2571 +f 4923/1/4923 2571/1/2571 2570/1/2570 +f 2567/1/2567 4923/1/4923 2570/1/2570 +f 2567/1/2567 4922/1/4922 4923/1/4923 +f 4922/1/4922 4921/1/4921 4923/1/4923 +f 4923/1/4923 4921/1/4921 4924/1/4924 +f 4922/1/4922 4918/1/4918 4921/1/4921 +f 4912/1/4912 4921/1/4921 4918/1/4918 +f 4912/1/4912 4918/1/4918 4916/1/4916 +f 4916/1/4916 4918/1/4918 4917/1/4917 +f 4917/1/4917 4915/1/4915 4916/1/4916 +f 4916/1/4916 4915/1/4915 4913/1/4913 +f 4914/1/4914 4913/1/4913 4915/1/4915 +f 4914/1/4914 4915/1/4915 3977/1/3977 +f 3977/1/3977 4915/1/4915 3975/1/3975 +f 3977/1/3977 3975/1/3975 3976/1/3976 +f 3977/1/3977 3976/1/3976 3964/1/3964 +f 3980/1/3980 3977/1/3977 3964/1/3964 +f 3980/1/3980 3964/1/3964 3978/1/3978 +f 3979/1/3979 3980/1/3980 3978/1/3978 +f 3978/1/3978 3959/1/3959 3979/1/3979 +f 3960/1/3960 3959/1/3959 3978/1/3978 +f 3978/1/3978 3961/1/3961 3960/1/3960 +f 3960/1/3960 3961/1/3961 3958/1/3958 +f 3958/1/3958 3955/1/3955 3960/1/3960 +f 3956/1/3956 3955/1/3955 3958/1/3958 +f 3958/1/3958 3957/1/3957 3956/1/3956 +f 3956/1/3956 3957/1/3957 3954/1/3954 +f 3954/1/3954 3953/1/3953 3956/1/3956 +f 3950/1/3950 3953/1/3953 3954/1/3954 +f 3954/1/3954 3949/1/3949 3950/1/3950 +f 3950/1/3950 3949/1/3949 3946/1/3946 +f 3950/1/3950 3946/1/3946 3951/1/3951 +f 3951/1/3951 3952/1/3952 3950/1/3950 +f 3947/1/3947 3952/1/3952 3951/1/3951 +f 3947/1/3947 3696/1/3696 3952/1/3952 +f 3696/1/3696 2542/1/2542 3952/1/3952 +f 3952/1/3952 2542/1/2542 3953/1/3953 +f 3953/1/3953 2542/1/2542 2540/1/2540 +f 3953/1/3953 2540/1/2540 3955/1/3955 +f 3955/1/3955 2540/1/2540 2537/1/2537 +f 3955/1/3955 2537/1/2537 3959/1/3959 +f 2540/1/2540 2538/1/2538 2537/1/2537 +f 2537/1/2537 2538/1/2538 2534/1/2534 +f 2537/1/2537 2534/1/2534 2536/1/2536 +f 2536/1/2536 2534/1/2534 2531/1/2531 +f 2534/1/2534 2535/1/2535 2531/1/2531 +f 2534/1/2534 3699/1/3699 2535/1/2535 +f 3699/1/3699 3703/1/3703 2535/1/2535 +f 2535/1/2535 3703/1/3703 2544/1/2544 +f 2535/1/2535 2544/1/2544 2532/1/2532 +f 2532/1/2532 2544/1/2544 2545/1/2545 +f 2544/1/2544 2631/1/2631 2545/1/2545 +f 2545/1/2545 2631/1/2631 2627/1/2627 +f 2545/1/2545 2627/1/2627 2543/1/2543 +f 2543/1/2543 2627/1/2627 2626/1/2626 +f 2627/1/2627 2625/1/2625 2626/1/2626 +f 2626/1/2626 2625/1/2625 2624/1/2624 +f 2626/1/2626 2624/1/2624 2548/1/2548 +f 2547/1/2547 2626/1/2626 2548/1/2548 +f 2548/1/2548 2624/1/2624 2554/1/2554 +f 2548/1/2548 2554/1/2554 2549/1/2549 +f 2546/1/2546 2548/1/2548 2549/1/2549 +f 2549/1/2549 2554/1/2554 2555/1/2555 +f 2549/1/2549 2555/1/2555 2553/1/2553 +f 2550/1/2550 2549/1/2549 2553/1/2553 +f 2553/1/2553 2555/1/2555 2556/1/2556 +f 2558/1/2558 2556/1/2556 2555/1/2555 +f 2559/1/2559 2558/1/2558 2555/1/2555 +f 2559/1/2559 2555/1/2555 2560/1/2560 +f 2564/1/2564 2559/1/2559 2560/1/2560 +f 2564/1/2564 2560/1/2560 2565/1/2565 +f 2565/1/2565 2569/1/2569 2564/1/2564 +f 2564/1/2564 2569/1/2569 2567/1/2567 +f 2564/1/2564 2567/1/2567 2568/1/2568 +f 2568/1/2568 2561/1/2561 2564/1/2564 +f 2620/1/2620 2569/1/2569 2565/1/2565 +f 2565/1/2565 2566/1/2566 2620/1/2620 +f 2620/1/2620 2566/1/2566 2621/1/2621 +f 2620/1/2620 2621/1/2621 2622/1/2622 +f 2620/1/2620 2622/1/2622 2623/1/2623 +f 2623/1/2623 3743/1/3743 2620/1/2620 +f 2623/1/2623 3742/1/3742 3743/1/3743 +f 3743/1/3743 3742/1/3742 4920/1/4920 +f 3743/1/3743 4920/1/4920 2569/1/2569 +f 2569/1/2569 4920/1/4920 4922/1/4922 +f 3742/1/3742 4919/1/4919 4920/1/4920 +f 4920/1/4920 4919/1/4919 4918/1/4918 +f 3742/1/3742 3973/1/3973 4919/1/4919 +f 3975/1/3975 4919/1/4919 3973/1/3973 +f 3975/1/3975 3973/1/3973 3974/1/3974 +f 3974/1/3974 3973/1/3973 3972/1/3972 +f 3974/1/3974 3972/1/3972 3966/1/3966 +f 3966/1/3966 3964/1/3964 3974/1/3974 +f 3966/1/3966 3962/1/3962 3964/1/3964 +f 3961/1/3961 3964/1/3964 3962/1/3962 +f 3961/1/3961 3962/1/3962 3957/1/3957 +f 3957/1/3957 3962/1/3962 3963/1/3963 +f 3957/1/3957 3963/1/3963 3949/1/3949 +f 3967/1/3967 3949/1/3949 3963/1/3963 +f 3967/1/3967 3963/1/3963 3965/1/3965 +f 3965/1/3965 3731/1/3731 3967/1/3967 +f 3967/1/3967 3731/1/3731 3968/1/3968 +f 3967/1/3967 3968/1/3968 3944/1/3944 +f 3944/1/3944 3945/1/3945 3967/1/3967 +f 3944/1/3944 3942/1/3942 3945/1/3945 +f 3943/1/3943 3945/1/3945 3942/1/3942 +f 3943/1/3943 3942/1/3942 3940/1/3940 +f 3943/1/3943 3940/1/3940 3939/1/3939 +f 3948/1/3948 3943/1/3943 3939/1/3939 +f 3948/1/3948 3939/1/3939 3941/1/3941 +f 3985/1/3985 3948/1/3948 3941/1/3941 +f 3985/1/3985 3941/1/3941 3987/1/3987 +f 3987/1/3987 3986/1/3986 3985/1/3985 +f 3985/1/3985 3986/1/3986 3696/1/3696 +f 3986/1/3986 3692/1/3692 3696/1/3696 +f 3692/1/3692 3691/1/3691 3696/1/3696 +f 3692/1/3692 3655/1/3655 3691/1/3691 +f 3655/1/3655 3650/1/3650 3691/1/3691 +f 3691/1/3691 3650/1/3650 3694/1/3694 +f 3691/1/3691 3694/1/3694 2541/1/2541 +f 2542/1/2542 3691/1/3691 2541/1/2541 +f 2541/1/2541 3694/1/3694 3697/1/3697 +f 2541/1/2541 3697/1/3697 2538/1/2538 +f 2538/1/2538 3697/1/3697 3698/1/3698 +f 3697/1/3697 3700/1/3700 3698/1/3698 +f 3698/1/3698 3700/1/3700 3702/1/3702 +f 3698/1/3698 3702/1/3702 3701/1/3701 +f 3698/1/3698 3701/1/3701 3699/1/3699 +f 3699/1/3699 3701/1/3701 3704/1/3704 +f 3701/1/3701 3706/1/3706 3704/1/3704 +f 3704/1/3704 3706/1/3706 3737/1/3737 +f 3704/1/3704 3737/1/3737 3703/1/3703 +f 3703/1/3703 3737/1/3737 3740/1/3740 +f 3737/1/3737 3738/1/3738 3740/1/3740 +f 3740/1/3740 3738/1/3738 2628/1/2628 +f 3740/1/3740 2628/1/2628 2631/1/2631 +f 2629/1/2629 2628/1/2628 3738/1/3738 +f 3739/1/3739 2629/1/2629 3738/1/3738 +f 3739/1/3739 3738/1/3738 3736/1/3736 +f 3734/1/3734 3739/1/3739 3736/1/3736 +f 3734/1/3734 3736/1/3736 3732/1/3732 +f 3734/1/3734 3732/1/3732 3729/1/3729 +f 3729/1/3729 3731/1/3731 3734/1/3734 +f 3734/1/3734 3731/1/3731 3742/1/3742 +f 3734/1/3734 3742/1/3742 3741/1/3741 +f 3731/1/3731 3971/1/3971 3742/1/3742 +f 3731/1/3731 3970/1/3970 3971/1/3971 +f 3971/1/3971 3970/1/3970 3972/1/3972 +f 3729/1/3729 3728/1/3728 3731/1/3731 +f 3728/1/3728 3969/1/3969 3731/1/3731 +f 3726/1/3726 3969/1/3969 3728/1/3728 +f 3725/1/3725 3726/1/3726 3728/1/3728 +f 3724/1/3724 3726/1/3726 3725/1/3725 +f 3725/1/3725 3717/1/3717 3724/1/3724 +f 3724/1/3724 3717/1/3717 3718/1/3718 +f 3724/1/3724 3718/1/3718 3722/1/3722 +f 3724/1/3724 3722/1/3722 3637/1/3637 +f 3637/1/3637 3727/1/3727 3724/1/3724 +f 3727/1/3727 3637/1/3637 3635/1/3635 +f 3923/1/3923 3727/1/3727 3635/1/3635 +f 3923/1/3923 3635/1/3635 3630/1/3630 +f 3923/1/3923 3630/1/3630 3924/1/3924 +f 3933/1/3933 3923/1/3923 3924/1/3924 +f 3933/1/3933 3924/1/3924 3930/1/3930 +f 3930/1/3930 3934/1/3934 3933/1/3933 +f 3933/1/3933 3934/1/3934 3936/1/3936 +f 3933/1/3933 3936/1/3936 3935/1/3935 +f 3935/1/3935 3936/1/3936 3940/1/3940 +f 3937/1/3937 3936/1/3936 3934/1/3934 +f 3937/1/3937 3934/1/3934 3938/1/3938 +f 3937/1/3937 3938/1/3938 3989/1/3989 +f 3987/1/3987 3937/1/3937 3989/1/3989 +f 3989/1/3989 3988/1/3988 3987/1/3987 +f 3990/1/3990 3988/1/3988 3989/1/3989 +f 3990/1/3990 3991/1/3991 3988/1/3988 +f 3991/1/3991 3747/1/3747 3988/1/3988 +f 3988/1/3988 3747/1/3747 3693/1/3693 +f 3988/1/3988 3693/1/3693 3986/1/3986 +f 3747/1/3747 3654/1/3654 3693/1/3693 +f 3693/1/3693 3654/1/3654 3655/1/3655 +f 3654/1/3654 3649/1/3649 3655/1/3655 +f 3654/1/3654 3653/1/3653 3649/1/3649 +f 3653/1/3653 3651/1/3651 3649/1/3649 +f 3649/1/3649 3651/1/3651 3646/1/3646 +f 3649/1/3649 3646/1/3646 3650/1/3650 +f 3646/1/3646 3647/1/3647 3650/1/3650 +f 3650/1/3650 3647/1/3647 3695/1/3695 +f 3647/1/3647 3648/1/3648 3695/1/3695 +f 3695/1/3695 3648/1/3648 3746/1/3746 +f 3695/1/3695 3746/1/3746 3721/1/3721 +f 3695/1/3695 3721/1/3721 3720/1/3720 +f 3694/1/3694 3695/1/3695 3720/1/3720 +f 3694/1/3694 3720/1/3720 3713/1/3713 +f 3720/1/3720 3714/1/3714 3713/1/3713 +f 3713/1/3713 3714/1/3714 3711/1/3711 +f 3713/1/3713 3711/1/3711 3710/1/3710 +f 3697/1/3697 3713/1/3713 3710/1/3710 +f 3710/1/3710 3711/1/3711 3708/1/3708 +f 3710/1/3710 3708/1/3708 3700/1/3700 +f 3700/1/3700 3708/1/3708 3707/1/3707 +f 3708/1/3708 3709/1/3709 3707/1/3707 +f 3707/1/3707 3709/1/3709 3705/1/3705 +f 3702/1/3702 3707/1/3707 3705/1/3705 +f 3733/1/3733 3705/1/3705 3709/1/3709 +f 3730/1/3730 3733/1/3733 3709/1/3709 +f 3730/1/3730 3709/1/3709 3716/1/3716 +f 3725/1/3725 3730/1/3730 3716/1/3716 +f 3729/1/3729 3730/1/3730 3725/1/3725 +f 3716/1/3716 3709/1/3709 3712/1/3712 +f 3716/1/3716 3712/1/3712 3717/1/3717 +f 3717/1/3717 3712/1/3712 3715/1/3715 +f 3711/1/3711 3715/1/3715 3712/1/3712 +f 3729/1/3729 3733/1/3733 3730/1/3730 +f 3732/1/3732 3705/1/3705 3733/1/3733 +f 3732/1/3732 3706/1/3706 3705/1/3705 +f 3735/1/3735 3706/1/3706 3732/1/3732 +f 3708/1/3708 3712/1/3712 3709/1/3709 +f 3711/1/3711 3712/1/3712 3708/1/3708 +f 3714/1/3714 3715/1/3715 3711/1/3711 +f 3714/1/3714 3719/1/3719 3715/1/3715 +f 3718/1/3718 3715/1/3715 3719/1/3719 +f 3721/1/3721 3719/1/3719 3714/1/3714 +f 3721/1/3721 3723/1/3723 3719/1/3719 +f 3722/1/3722 3719/1/3719 3723/1/3723 +f 3722/1/3722 3723/1/3723 3744/1/3744 +f 3722/1/3722 3744/1/3744 3636/1/3636 +f 3636/1/3636 3744/1/3744 3638/1/3638 +f 3636/1/3636 3638/1/3638 3634/1/3634 +f 3633/1/3633 3636/1/3636 3634/1/3634 +f 3633/1/3633 3634/1/3634 3629/1/3629 +f 3630/1/3630 3633/1/3633 3629/1/3629 +f 3630/1/3630 3629/1/3629 3628/1/3628 +f 3922/1/3922 3630/1/3630 3628/1/3628 +f 3922/1/3922 3628/1/3628 3920/1/3920 +f 3924/1/3924 3922/1/3922 3920/1/3920 +f 3623/1/3623 3920/1/3920 3628/1/3628 +f 3624/1/3624 3623/1/3623 3628/1/3628 +f 3621/1/3621 3623/1/3623 3624/1/3624 +f 3626/1/3626 3621/1/3621 3624/1/3624 +f 3626/1/3626 3624/1/3624 3664/1/3664 +f 3662/1/3662 3626/1/3626 3664/1/3664 +f 3662/1/3662 3664/1/3664 3644/1/3644 +f 3662/1/3662 3644/1/3644 3643/1/3643 +f 3659/1/3659 3662/1/3662 3643/1/3643 +f 3652/1/3652 3659/1/3659 3643/1/3643 +f 3652/1/3652 3643/1/3643 3651/1/3651 +f 3651/1/3651 3643/1/3643 3645/1/3645 +f 3643/1/3643 3640/1/3640 3645/1/3645 +f 3640/1/3640 3641/1/3641 3645/1/3645 +f 3645/1/3645 3641/1/3641 3646/1/3646 +f 3646/1/3646 3641/1/3641 3642/1/3642 +f 3639/1/3639 3642/1/3642 3641/1/3641 +f 3638/1/3638 3642/1/3642 3639/1/3639 +f 3642/1/3642 3638/1/3638 3648/1/3648 +f 3648/1/3648 3638/1/3638 3745/1/3745 +f 3640/1/3640 3639/1/3639 3641/1/3641 +f 3640/1/3640 3632/1/3632 3639/1/3639 +f 3634/1/3634 3639/1/3639 3632/1/3632 +f 3631/1/3631 3632/1/3632 3640/1/3640 +f 3644/1/3644 3631/1/3631 3640/1/3640 +f 3631/1/3631 3629/1/3629 3632/1/3632 +f 3624/1/3624 3629/1/3629 3631/1/3631 +f 3658/1/3658 3659/1/3659 3652/1/3652 +f 3653/1/3653 3658/1/3658 3652/1/3652 +f 3657/1/3657 3658/1/3658 3653/1/3653 +f 3656/1/3656 3657/1/3657 3653/1/3653 +f 3672/1/3672 3657/1/3657 3656/1/3656 +f 3748/1/3748 3672/1/3672 3656/1/3656 +f 3748/1/3748 3656/1/3656 3747/1/3747 +f 3749/1/3749 3672/1/3672 3748/1/3748 +f 3995/1/3995 3749/1/3749 3748/1/3748 +f 3995/1/3995 3748/1/3748 3991/1/3991 +f 3994/1/3994 3995/1/3995 3991/1/3991 +f 3994/1/3994 3991/1/3991 3993/1/3993 +f 3993/1/3993 3996/1/3996 3994/1/3994 +f 3994/1/3994 3996/1/3996 3997/1/3997 +f 3997/1/3997 3996/1/3996 3998/1/3998 +f 3997/1/3997 3998/1/3998 3999/1/3999 +f 3999/1/3999 3750/1/3750 3997/1/3997 +f 3997/1/3997 3750/1/3750 3995/1/3995 +f 3754/1/3754 3750/1/3750 3999/1/3999 +f 3999/1/3999 4000/1/4000 3754/1/3754 +f 3754/1/3754 4000/1/4000 3802/1/3802 +f 3754/1/3754 3802/1/3802 3752/1/3752 +f 3752/1/3752 3802/1/3802 3801/1/3801 +f 3801/1/3801 3753/1/3753 3752/1/3752 +f 3752/1/3752 3753/1/3753 3750/1/3750 +f 3753/1/3753 3751/1/3751 3750/1/3750 +f 3750/1/3750 3751/1/3751 3749/1/3749 +f 3751/1/3751 3673/1/3673 3749/1/3749 +f 3751/1/3751 3679/1/3679 3673/1/3673 +f 3679/1/3679 3677/1/3677 3673/1/3673 +f 3673/1/3673 3677/1/3677 3674/1/3674 +f 3673/1/3673 3674/1/3674 3670/1/3670 +f 3673/1/3673 3670/1/3670 3672/1/3672 +f 3674/1/3674 3671/1/3671 3670/1/3670 +f 3670/1/3670 3671/1/3671 3666/1/3666 +f 3670/1/3670 3666/1/3666 3657/1/3657 +f 3657/1/3657 3666/1/3666 3661/1/3661 +f 3666/1/3666 3665/1/3665 3661/1/3661 +f 3661/1/3661 3665/1/3665 3660/1/3660 +f 3661/1/3661 3660/1/3660 3658/1/3658 +f 3665/1/3665 3663/1/3663 3660/1/3660 +f 3660/1/3660 3663/1/3663 3662/1/3662 +f 3665/1/3665 3669/1/3669 3663/1/3663 +f 3669/1/3669 3683/1/3683 3663/1/3663 +f 3683/1/3683 3625/1/3625 3663/1/3663 +f 3663/1/3663 3625/1/3625 3626/1/3626 +f 3683/1/3683 3684/1/3684 3625/1/3625 +f 3684/1/3684 3627/1/3627 3625/1/3625 +f 3625/1/3625 3627/1/3627 3621/1/3621 +f 3627/1/3627 3622/1/3622 3621/1/3621 +f 3687/1/3687 3622/1/3622 3627/1/3627 +f 3687/1/3687 3911/1/3911 3622/1/3622 +f 3911/1/3911 3913/1/3913 3622/1/3622 +f 3622/1/3622 3913/1/3913 3919/1/3919 +f 3622/1/3622 3919/1/3919 3623/1/3623 +f 3913/1/3913 3921/1/3921 3919/1/3919 +f 3919/1/3919 3921/1/3921 3920/1/3920 +f 3921/1/3921 3926/1/3926 3920/1/3920 +f 3926/1/3926 3929/1/3929 3920/1/3920 +f 3930/1/3930 3920/1/3920 3929/1/3929 +f 3929/1/3929 3932/1/3932 3930/1/3930 +f 3929/1/3929 3931/1/3931 3932/1/3932 +f 3996/1/3996 3932/1/3932 3931/1/3931 +f 3992/1/3992 3932/1/3932 3996/1/3996 +f 3938/1/3938 3932/1/3932 3992/1/3992 +f 3990/1/3990 3938/1/3938 3992/1/3992 +f 3990/1/3990 3992/1/3992 3993/1/3993 +f 3926/1/3926 3931/1/3931 3929/1/3929 +f 4001/1/4001 3931/1/3931 3926/1/3926 +f 3928/1/3928 4001/1/4001 3926/1/3926 +f 3928/1/3928 4000/1/4000 4001/1/4001 +f 4000/1/4000 3998/1/3998 4001/1/4001 +f 4001/1/4001 3998/1/3998 3931/1/3931 +f 3921/1/3921 3928/1/3928 3926/1/3926 +f 3927/1/3927 3928/1/3928 3921/1/3921 +f 3927/1/3927 4002/1/4002 3928/1/3928 +f 4002/1/4002 3804/1/3804 3928/1/3928 +f 3804/1/3804 3802/1/3802 3928/1/3928 +f 3804/1/3804 3795/1/3795 3802/1/3802 +f 3790/1/3790 3795/1/3795 3804/1/3804 +f 3803/1/3803 3790/1/3790 3804/1/3804 +f 3791/1/3791 3790/1/3790 3803/1/3803 +f 3791/1/3791 3803/1/3803 4002/1/4002 +f 3788/1/3788 3790/1/3790 3791/1/3791 +f 3805/1/3805 3788/1/3788 3791/1/3791 +f 3805/1/3805 3791/1/3791 3913/1/3913 +f 3913/1/3913 3791/1/3791 3927/1/3927 +f 3787/1/3787 3788/1/3788 3805/1/3805 +f 3912/1/3912 3787/1/3787 3805/1/3805 +f 3912/1/3912 3805/1/3805 3911/1/3911 +f 3908/1/3908 3912/1/3912 3911/1/3911 +f 3908/1/3908 3911/1/3911 3910/1/3910 +f 3909/1/3909 3908/1/3908 3910/1/3910 +f 3909/1/3909 3910/1/3910 3689/1/3689 +f 3690/1/3690 3909/1/3909 3689/1/3689 +f 3690/1/3690 3689/1/3689 3688/1/3688 +f 3682/1/3682 3690/1/3690 3688/1/3688 +f 3682/1/3682 3688/1/3688 3676/1/3676 +f 3675/1/3675 3682/1/3682 3676/1/3676 +f 3675/1/3675 3676/1/3676 3671/1/3671 +f 3671/1/3671 3676/1/3676 3667/1/3667 +f 3676/1/3676 3685/1/3685 3667/1/3667 +f 3667/1/3667 3685/1/3685 3668/1/3668 +f 3667/1/3667 3668/1/3668 3665/1/3665 +f 3685/1/3685 3683/1/3683 3668/1/3668 +f 3678/1/3678 3682/1/3682 3675/1/3675 +f 3674/1/3674 3678/1/3678 3675/1/3675 +f 3678/1/3678 3906/1/3906 3682/1/3682 +f 3906/1/3906 3905/1/3905 3682/1/3682 +f 3904/1/3904 3905/1/3905 3906/1/3906 +f 3681/1/3681 3904/1/3904 3906/1/3906 +f 4003/1/4003 3904/1/3904 3681/1/3681 +f 3677/1/3677 4003/1/4003 3681/1/3681 +f 3677/1/3677 3681/1/3681 3678/1/3678 +f 3680/1/3680 4003/1/4003 3677/1/3677 +f 3680/1/3680 3898/1/3898 4003/1/4003 +f 3898/1/3898 3900/1/3900 4003/1/4003 +f 3898/1/3898 3895/1/3895 3900/1/3900 +f 3895/1/3895 3899/1/3899 3900/1/3900 +f 3900/1/3900 3899/1/3899 3903/1/3903 +f 3900/1/3900 3903/1/3903 3904/1/3904 +f 3899/1/3899 3902/1/3902 3903/1/3903 +f 3903/1/3903 3902/1/3902 3907/1/3907 +f 3903/1/3903 3907/1/3907 3905/1/3905 +f 3905/1/3905 3907/1/3907 3909/1/3909 +f 3902/1/3902 3908/1/3908 3907/1/3907 +f 3902/1/3902 3914/1/3914 3908/1/3908 +f 3901/1/3901 3914/1/3914 3902/1/3902 +f 3901/1/3901 3915/1/3915 3914/1/3914 +f 3915/1/3915 3912/1/3912 3914/1/3914 +f 3915/1/3915 3916/1/3916 3912/1/3912 +f 3917/1/3917 3916/1/3916 3915/1/3915 +f 3892/1/3892 3917/1/3917 3915/1/3915 +f 3892/1/3892 3915/1/3915 3893/1/3893 +f 3891/1/3891 3892/1/3892 3893/1/3893 +f 3891/1/3891 3893/1/3893 3894/1/3894 +f 3891/1/3891 3894/1/3894 3895/1/3895 +f 3890/1/3890 3891/1/3891 3895/1/3895 +f 3896/1/3896 3890/1/3890 3895/1/3895 +f 3889/1/3889 3890/1/3890 3896/1/3896 +f 3897/1/3897 3889/1/3889 3896/1/3896 +f 3897/1/3897 3896/1/3896 3898/1/3898 +f 3888/1/3888 3889/1/3889 3897/1/3897 +f 3758/1/3758 3888/1/3888 3897/1/3897 +f 3758/1/3758 3897/1/3897 3679/1/3679 +f 3755/1/3755 3758/1/3758 3679/1/3679 +f 3757/1/3757 3758/1/3758 3755/1/3755 +f 3756/1/3756 3757/1/3757 3755/1/3755 +f 3756/1/3756 3755/1/3755 3753/1/3753 +f 3799/1/3799 3756/1/3756 3753/1/3753 +f 3799/1/3799 3753/1/3753 3800/1/3800 +f 3800/1/3800 3795/1/3795 3799/1/3799 +f 3799/1/3799 3795/1/3795 3794/1/3794 +f 3799/1/3799 3794/1/3794 3798/1/3798 +f 3798/1/3798 3794/1/3794 3793/1/3793 +f 3798/1/3798 3793/1/3793 3797/1/3797 +f 3797/1/3797 3756/1/3756 3798/1/3798 +f 3763/1/3763 3756/1/3756 3797/1/3797 +f 3763/1/3763 3760/1/3760 3756/1/3756 +f 3762/1/3762 3760/1/3760 3763/1/3763 +f 3763/1/3763 3796/1/3796 3762/1/3762 +f 3762/1/3762 3796/1/3796 3770/1/3770 +f 3762/1/3762 3770/1/3770 3767/1/3767 +f 3767/1/3767 3764/1/3764 3762/1/3762 +f 3769/1/3769 3764/1/3764 3767/1/3767 +f 3767/1/3767 3771/1/3771 3769/1/3769 +f 3769/1/3769 3771/1/3771 3772/1/3772 +f 3769/1/3769 3772/1/3772 3768/1/3768 +f 3768/1/3768 3772/1/3772 3773/1/3773 +f 3768/1/3768 3773/1/3773 3774/1/3774 +f 3774/1/3774 3766/1/3766 3768/1/3768 +f 3768/1/3768 3766/1/3766 3764/1/3764 +f 3766/1/3766 3765/1/3765 3764/1/3764 +f 3764/1/3764 3765/1/3765 3761/1/3761 +f 3764/1/3764 3761/1/3761 3760/1/3760 +f 3760/1/3760 3761/1/3761 3757/1/3757 +f 3761/1/3761 3759/1/3759 3757/1/3757 +f 3761/1/3761 3849/1/3849 3759/1/3759 +f 3849/1/3849 3887/1/3887 3759/1/3759 +f 3759/1/3759 3887/1/3887 3888/1/3888 +f 3887/1/3887 3881/1/3881 3888/1/3888 +f 3888/1/3888 3881/1/3881 3885/1/3885 +f 3881/1/3881 3882/1/3882 3885/1/3885 +f 3885/1/3885 3882/1/3882 3886/1/3886 +f 3885/1/3885 3886/1/3886 3889/1/3889 +f 3882/1/3882 3884/1/3884 3886/1/3886 +f 3886/1/3886 3884/1/3884 3891/1/3891 +f 3882/1/3882 3878/1/3878 3884/1/3884 +f 3878/1/3878 3883/1/3883 3884/1/3884 +f 3884/1/3884 3883/1/3883 3892/1/3892 +f 3878/1/3878 3875/1/3875 3883/1/3883 +f 3875/1/3875 3918/1/3918 3883/1/3883 +f 3883/1/3883 3918/1/3918 3917/1/3917 +f 3918/1/3918 3863/1/3863 3917/1/3917 +f 3862/1/3862 3863/1/3863 3918/1/3918 +f 3862/1/3862 3835/1/3835 3863/1/3863 +f 3835/1/3835 3783/1/3783 3863/1/3863 +f 3863/1/3863 3783/1/3783 3784/1/3784 +f 3863/1/3863 3784/1/3784 3916/1/3916 +f 3916/1/3916 3784/1/3784 3787/1/3787 +f 3784/1/3784 3785/1/3785 3787/1/3787 +f 3784/1/3784 3780/1/3780 3785/1/3785 +f 3780/1/3780 3781/1/3781 3785/1/3785 +f 3785/1/3785 3781/1/3781 3786/1/3786 +f 3785/1/3785 3786/1/3786 3788/1/3788 +f 3788/1/3788 3786/1/3786 3789/1/3789 +f 3786/1/3786 3782/1/3782 3789/1/3789 +f 3782/1/3782 3793/1/3793 3789/1/3789 +f 3789/1/3789 3793/1/3793 3792/1/3792 +f 3789/1/3789 3792/1/3792 3790/1/3790 +f 3782/1/3782 3796/1/3796 3793/1/3793 +f 3781/1/3781 3782/1/3782 3786/1/3786 +f 3781/1/3781 3777/1/3777 3782/1/3782 +f 3777/1/3777 3770/1/3770 3782/1/3782 +f 3777/1/3777 3771/1/3771 3770/1/3770 +f 3775/1/3775 3771/1/3771 3777/1/3777 +f 3778/1/3778 3775/1/3775 3777/1/3777 +f 3780/1/3780 3775/1/3775 3778/1/3778 +f 3779/1/3779 3775/1/3775 3780/1/3780 +f 3783/1/3783 3779/1/3779 3780/1/3780 +f 3806/1/3806 3779/1/3779 3783/1/3783 +f 3806/1/3806 3809/1/3809 3779/1/3779 +f 3809/1/3809 3776/1/3776 3779/1/3779 +f 3809/1/3809 3810/1/3810 3776/1/3776 +f 3810/1/3810 3815/1/3815 3776/1/3776 +f 3815/1/3815 3773/1/3773 3776/1/3776 +f 3815/1/3815 3816/1/3816 3773/1/3773 +f 3845/1/3845 3773/1/3773 3816/1/3816 +f 3845/1/3845 3816/1/3816 3844/1/3844 +f 3844/1/3844 3766/1/3766 3845/1/3845 +f 3844/1/3844 3841/1/3841 3766/1/3766 +f 3841/1/3841 3847/1/3847 3766/1/3766 +f 3841/1/3841 3846/1/3846 3847/1/3847 +f 3846/1/3846 4010/1/4010 3847/1/3847 +f 3847/1/3847 4010/1/4010 4005/1/4005 +f 3847/1/3847 4005/1/4005 3765/1/3765 +f 3765/1/3765 4005/1/4005 3849/1/3849 +f 4005/1/4005 4006/1/4006 3849/1/3849 +f 3849/1/3849 4006/1/4006 4004/1/4004 +f 4006/1/4006 3880/1/3880 4004/1/4004 +f 4004/1/4004 3880/1/3880 3879/1/3879 +f 4004/1/4004 3879/1/3879 3887/1/3887 +f 3880/1/3880 3874/1/3874 3879/1/3879 +f 3879/1/3879 3874/1/3874 3876/1/3876 +f 3879/1/3879 3876/1/3876 3881/1/3881 +f 3881/1/3881 3876/1/3876 3877/1/3877 +f 3876/1/3876 3873/1/3873 3877/1/3877 +f 3873/1/3873 3878/1/3878 3877/1/3877 +f 3874/1/3874 3873/1/3873 3876/1/3876 +f 3874/1/3874 3871/1/3871 3873/1/3873 +f 3871/1/3871 3872/1/3872 3873/1/3873 +f 3873/1/3873 3872/1/3872 3875/1/3875 +f 3872/1/3872 3862/1/3862 3875/1/3875 +f 3864/1/3864 3862/1/3862 3872/1/3872 +f 3864/1/3864 3859/1/3859 3862/1/3862 +f 3861/1/3861 3859/1/3859 3864/1/3864 +f 3865/1/3865 3861/1/3861 3864/1/3864 +f 3865/1/3865 3864/1/3864 3871/1/3871 +f 3868/1/3868 3865/1/3865 3871/1/3871 +f 3866/1/3866 3865/1/3865 3868/1/3868 +f 3870/1/3870 3866/1/3866 3868/1/3868 +f 4007/1/4007 3870/1/3870 3868/1/3868 +f 4007/1/4007 3868/1/3868 3880/1/3880 +f 4009/1/4009 3870/1/3870 4007/1/4007 +f 4006/1/4006 4009/1/4009 4007/1/4007 +f 4008/1/4008 4009/1/4009 4006/1/4006 +f 4008/1/4008 4012/1/4012 4009/1/4009 +f 4012/1/4012 3869/1/3869 4009/1/4009 +f 4012/1/4012 4014/1/4014 3869/1/3869 +f 4014/1/4014 3867/1/3867 3869/1/3869 +f 3869/1/3869 3867/1/3867 3866/1/3866 +f 3867/1/3867 3860/1/3860 3866/1/3866 +f 3866/1/3866 3860/1/3860 3861/1/3861 +f 3860/1/3860 3856/1/3856 3861/1/3861 +f 3857/1/3857 3856/1/3856 3860/1/3860 +f 3857/1/3857 3855/1/3855 3856/1/3856 +f 3855/1/3855 3834/1/3834 3856/1/3856 +f 3856/1/3856 3834/1/3834 3835/1/3835 +f 3856/1/3856 3835/1/3835 3859/1/3859 +f 3834/1/3834 3806/1/3806 3835/1/3835 +f 3834/1/3834 3807/1/3807 3806/1/3806 +f 3807/1/3807 3808/1/3808 3806/1/3806 +f 3807/1/3807 3812/1/3812 3808/1/3808 +f 3812/1/3812 3813/1/3813 3808/1/3808 +f 3808/1/3808 3813/1/3813 3811/1/3811 +f 3808/1/3808 3811/1/3811 3810/1/3810 +f 3811/1/3811 3814/1/3814 3810/1/3810 +f 3811/1/3811 3817/1/3817 3814/1/3814 +f 3814/1/3814 3817/1/3817 3816/1/3816 +f 3843/1/3843 3816/1/3816 3817/1/3817 +f 3843/1/3843 3817/1/3817 3842/1/3842 +f 3842/1/3842 3841/1/3841 3843/1/3843 +f 3839/1/3839 3841/1/3841 3842/1/3842 +f 3839/1/3839 3840/1/3840 3841/1/3841 +f 3837/1/3837 3840/1/3840 3839/1/3839 +f 3839/1/3839 3822/1/3822 3837/1/3837 +f 3837/1/3837 3822/1/3822 3821/1/3821 +f 3837/1/3837 3821/1/3821 3838/1/3838 +f 3838/1/3838 3373/1/3373 3837/1/3837 +f 3848/1/3848 3373/1/3373 3838/1/3838 +f 3838/1/3838 3826/1/3826 3848/1/3848 +f 3848/1/3848 3826/1/3826 3836/1/3836 +f 3848/1/3848 3836/1/3836 3372/1/3372 +f 3372/1/3372 3836/1/3836 3194/1/3194 +f 3372/1/3372 3194/1/3194 3371/1/3371 +f 3371/1/3371 3370/1/3370 3372/1/3372 +f 3372/1/3372 3370/1/3370 3373/1/3373 +f 3370/1/3370 3374/1/3374 3373/1/3373 +f 3373/1/3373 3374/1/3374 3375/1/3375 +f 3373/1/3373 3375/1/3375 3840/1/3840 +f 3840/1/3840 3375/1/3375 3846/1/3846 +f 3375/1/3375 4037/1/4037 3846/1/3846 +f 3375/1/3375 4036/1/4036 4037/1/4037 +f 4036/1/4036 4033/1/4033 4037/1/4037 +f 4037/1/4037 4033/1/4033 4027/1/4027 +f 4037/1/4037 4027/1/4027 4010/1/4010 +f 4010/1/4010 4027/1/4027 4011/1/4011 +f 4027/1/4027 4024/1/4024 4011/1/4011 +f 4011/1/4011 4024/1/4024 4015/1/4015 +f 4011/1/4011 4015/1/4015 4013/1/4013 +f 4011/1/4011 4013/1/4013 4008/1/4008 +f 4005/1/4005 4011/1/4011 4008/1/4008 +f 4015/1/4015 4016/1/4016 4013/1/4013 +f 4013/1/4013 4016/1/4016 4014/1/4014 +f 4016/1/4016 4017/1/4017 4014/1/4014 +f 4016/1/4016 4018/1/4018 4017/1/4017 +f 4018/1/4018 3858/1/3858 4017/1/4017 +f 4017/1/4017 3858/1/3858 3857/1/3857 +f 4017/1/4017 3857/1/3857 3867/1/3867 +f 4018/1/4018 4019/1/4019 3858/1/3858 +f 4019/1/4019 3851/1/3851 3858/1/3858 +f 3858/1/3858 3851/1/3851 3855/1/3855 +f 3854/1/3854 3851/1/3851 4019/1/4019 +f 4020/1/4020 3854/1/3854 4019/1/4019 +f 4021/1/4021 3854/1/3854 4020/1/4020 +f 4022/1/4022 4021/1/4021 4020/1/4020 +f 4022/1/4022 4020/1/4020 4023/1/4023 +f 4024/1/4024 4022/1/4022 4023/1/4023 +f 4025/1/4025 4022/1/4022 4024/1/4024 +f 4025/1/4025 4026/1/4026 4022/1/4022 +f 4028/1/4028 4026/1/4026 4025/1/4025 +f 4027/1/4027 4028/1/4028 4025/1/4025 +f 4028/1/4028 4030/1/4030 4026/1/4026 +f 4030/1/4030 4029/1/4029 4026/1/4026 +f 4026/1/4026 4029/1/4029 4021/1/4021 +f 4029/1/4029 3853/1/3853 4021/1/4021 +f 4029/1/4029 4048/1/4048 3853/1/3853 +f 4048/1/4048 3852/1/3852 3853/1/3853 +f 3853/1/3853 3852/1/3852 3850/1/3850 +f 3853/1/3853 3850/1/3850 3854/1/3854 +f 3852/1/3852 3829/1/3829 3850/1/3850 +f 3850/1/3850 3829/1/3829 3830/1/3830 +f 3850/1/3850 3830/1/3830 3851/1/3851 +f 3851/1/3851 3830/1/3830 3834/1/3834 +f 3829/1/3829 3827/1/3827 3830/1/3830 +f 3830/1/3830 3827/1/3827 3807/1/3807 +f 3829/1/3829 3828/1/3828 3827/1/3827 +f 3828/1/3828 3824/1/3824 3827/1/3827 +f 3827/1/3827 3824/1/3824 3812/1/3812 +f 3824/1/3824 3819/1/3819 3812/1/3812 +f 3824/1/3824 3823/1/3823 3819/1/3819 +f 3823/1/3823 3820/1/3820 3819/1/3819 +f 3819/1/3819 3820/1/3820 3818/1/3818 +f 3819/1/3819 3818/1/3818 3813/1/3813 +f 3820/1/3820 3821/1/3821 3818/1/3818 +f 3820/1/3820 3826/1/3826 3821/1/3821 +f 3825/1/3825 3826/1/3826 3820/1/3820 +f 3823/1/3823 3825/1/3825 3820/1/3820 +f 3824/1/3824 3825/1/3825 3823/1/3823 +f 3193/1/3193 3825/1/3825 3824/1/3824 +f 3193/1/3193 3190/1/3190 3825/1/3825 +f 3825/1/3825 3190/1/3190 3836/1/3836 +f 3188/1/3188 3190/1/3190 3193/1/3193 +f 3189/1/3189 3188/1/3188 3193/1/3193 +f 3189/1/3189 3193/1/3193 3828/1/3828 +f 3831/1/3831 3189/1/3189 3828/1/3828 +f 3832/1/3832 3189/1/3189 3831/1/3831 +f 4639/1/4639 3832/1/3832 3831/1/3831 +f 4639/1/4639 3831/1/3831 4641/1/4641 +f 4640/1/4640 4639/1/4639 4641/1/4641 +f 4640/1/4640 4641/1/4641 4052/1/4052 +f 4053/1/4053 4640/1/4640 4052/1/4052 +f 4053/1/4053 4052/1/4052 4051/1/4051 +f 4040/1/4040 4053/1/4053 4051/1/4051 +f 4040/1/4040 4051/1/4051 4035/1/4035 +f 4034/1/4034 4040/1/4040 4035/1/4035 +f 4034/1/4034 4035/1/4035 4031/1/4031 +f 4033/1/4033 4034/1/4034 4031/1/4031 +f 4033/1/4033 4031/1/4031 4028/1/4028 +f 4031/1/4031 4032/1/4032 4028/1/4028 +f 4038/1/4038 4034/1/4034 4033/1/4033 +f 4038/1/4038 4039/1/4039 4034/1/4034 +f 4038/1/4038 4043/1/4043 4039/1/4039 +f 4043/1/4043 4044/1/4044 4039/1/4039 +f 4039/1/4039 4044/1/4044 4040/1/4040 +f 4044/1/4044 4644/1/4644 4040/1/4040 +f 4560/1/4560 4644/1/4644 4044/1/4044 +f 4560/1/4560 4643/1/4643 4644/1/4644 +f 4643/1/4643 4642/1/4642 4644/1/4644 +f 4644/1/4644 4642/1/4642 4640/1/4640 +f 4643/1/4643 4638/1/4638 4642/1/4642 +f 4638/1/4638 4639/1/4639 4642/1/4642 +f 4638/1/4638 4633/1/4633 4639/1/4639 +f 4635/1/4635 4633/1/4633 4638/1/4638 +f 4637/1/4637 4635/1/4635 4638/1/4638 +f 4636/1/4636 4635/1/4635 4637/1/4637 +f 4557/1/4557 4636/1/4636 4637/1/4637 +f 4557/1/4557 4637/1/4637 4558/1/4558 +f 4555/1/4555 4557/1/4557 4558/1/4558 +f 4555/1/4555 4558/1/4558 4559/1/4559 +f 4042/1/4042 4555/1/4555 4559/1/4559 +f 4042/1/4042 4559/1/4559 4043/1/4043 +f 4559/1/4559 4560/1/4560 4043/1/4043 +f 4552/1/4552 4555/1/4555 4042/1/4042 +f 4041/1/4041 4552/1/4552 4042/1/4042 +f 4041/1/4041 4042/1/4042 4038/1/4038 +f 4041/1/4041 4038/1/4038 4036/1/4036 +f 3374/1/3374 4041/1/4041 4036/1/4036 +f 3376/1/3376 4041/1/4041 3374/1/3374 +f 3376/1/3376 4045/1/4045 4041/1/4041 +f 3365/1/3365 4045/1/4045 3376/1/3376 +f 3364/1/3364 3365/1/3365 3376/1/3376 +f 3364/1/3364 3376/1/3376 3370/1/3370 +f 3368/1/3368 3364/1/3364 3370/1/3370 +f 3368/1/3368 3370/1/3370 3369/1/3369 +f 3369/1/3369 3195/1/3195 3368/1/3368 +f 3368/1/3368 3195/1/3195 3367/1/3367 +f 3367/1/3367 3195/1/3195 3183/1/3183 +f 3367/1/3367 3183/1/3183 3366/1/3366 +f 3366/1/3366 3364/1/3364 3367/1/3367 +f 3333/1/3333 3364/1/3364 3366/1/3366 +f 3333/1/3333 3336/1/3336 3364/1/3364 +f 3334/1/3334 3336/1/3336 3333/1/3333 +f 3333/1/3333 3182/1/3182 3334/1/3334 +f 3334/1/3334 3182/1/3182 3175/1/3175 +f 3334/1/3334 3175/1/3175 3176/1/3176 +f 3176/1/3176 3335/1/3335 3334/1/3334 +f 3173/1/3173 3335/1/3335 3176/1/3176 +f 3176/1/3176 3172/1/3172 3173/1/3173 +f 3173/1/3173 3172/1/3172 3167/1/3167 +f 3173/1/3173 3167/1/3167 3174/1/3174 +f 3174/1/3174 3167/1/3167 3164/1/3164 +f 3174/1/3174 3164/1/3164 3340/1/3340 +f 3340/1/3340 3339/1/3339 3174/1/3174 +f 3174/1/3174 3339/1/3339 3335/1/3335 +f 3339/1/3339 3337/1/3337 3335/1/3335 +f 3335/1/3335 3337/1/3337 3338/1/3338 +f 3335/1/3335 3338/1/3338 3336/1/3336 +f 3336/1/3336 3338/1/3338 3365/1/3365 +f 3338/1/3338 4046/1/4046 3365/1/3365 +f 3338/1/3338 4543/1/4543 4046/1/4046 +f 4543/1/4543 4546/1/4546 4046/1/4046 +f 4046/1/4046 4546/1/4546 4550/1/4550 +f 4046/1/4046 4550/1/4550 4045/1/4045 +f 4045/1/4045 4550/1/4550 4552/1/4552 +f 4550/1/4550 4551/1/4551 4552/1/4552 +f 4552/1/4552 4551/1/4551 4554/1/4554 +f 4551/1/4551 4556/1/4556 4554/1/4554 +f 4554/1/4554 4556/1/4556 4557/1/4557 +f 4556/1/4556 4562/1/4562 4557/1/4557 +f 4561/1/4561 4562/1/4562 4556/1/4556 +f 4561/1/4561 4564/1/4564 4562/1/4562 +f 4564/1/4564 4567/1/4567 4562/1/4562 +f 4562/1/4562 4567/1/4567 4634/1/4634 +f 4562/1/4562 4634/1/4634 4636/1/4636 +f 4567/1/4567 4632/1/4632 4634/1/4634 +f 4634/1/4634 4632/1/4632 4635/1/4635 +f 4567/1/4567 4631/1/4631 4632/1/4632 +f 4631/1/4631 3833/1/3833 4632/1/4632 +f 4632/1/4632 3833/1/3833 3832/1/3832 +f 4632/1/4632 3832/1/3832 4633/1/4633 +f 3833/1/3833 3186/1/3186 3832/1/3832 +f 3833/1/3833 3185/1/3185 3186/1/3186 +f 3185/1/3185 3180/1/3180 3186/1/3186 +f 3186/1/3186 3180/1/3180 3184/1/3184 +f 3186/1/3186 3184/1/3184 3189/1/3189 +f 3180/1/3180 3179/1/3179 3184/1/3184 +f 3184/1/3184 3179/1/3179 3181/1/3181 +f 3184/1/3184 3181/1/3181 3187/1/3187 +f 3184/1/3184 3187/1/3187 3188/1/3188 +f 3181/1/3181 3191/1/3191 3187/1/3187 +f 3187/1/3187 3191/1/3191 3192/1/3192 +f 3187/1/3187 3192/1/3192 3190/1/3190 +f 3192/1/3192 3194/1/3194 3190/1/3190 +f 3192/1/3192 3195/1/3195 3194/1/3194 +f 3191/1/3191 3195/1/3195 3192/1/3192 +f 3181/1/3181 3183/1/3183 3191/1/3191 +f 3178/1/3178 3183/1/3183 3181/1/3181 +f 3178/1/3178 3182/1/3182 3183/1/3183 +f 3179/1/3179 3178/1/3178 3181/1/3181 +f 3177/1/3177 3178/1/3178 3179/1/3179 +f 3177/1/3177 3171/1/3171 3178/1/3178 +f 3171/1/3171 3175/1/3175 3178/1/3178 +f 3171/1/3171 3172/1/3172 3175/1/3175 +f 3166/1/3166 3172/1/3172 3171/1/3171 +f 3170/1/3170 3166/1/3166 3171/1/3171 +f 3169/1/3169 3166/1/3166 3170/1/3170 +f 3169/1/3169 3170/1/3170 3177/1/3177 +f 3169/1/3169 3177/1/3177 3180/1/3180 +f 3165/1/3165 3166/1/3166 3169/1/3169 +f 3168/1/3168 3165/1/3165 3169/1/3169 +f 3168/1/3168 3169/1/3169 3185/1/3185 +f 3196/1/3196 3168/1/3168 3185/1/3185 +f 3197/1/3197 3168/1/3168 3196/1/3196 +f 4575/1/4575 3197/1/3197 3196/1/3196 +f 4575/1/4575 3196/1/3196 4576/1/4576 +f 4570/1/4570 4575/1/4575 4576/1/4576 +f 4570/1/4570 4576/1/4576 4568/1/4568 +f 4565/1/4565 4570/1/4570 4568/1/4568 +f 4565/1/4565 4568/1/4568 4564/1/4564 +f 4563/1/4563 4565/1/4565 4564/1/4564 +f 4566/1/4566 4565/1/4565 4563/1/4563 +f 4549/1/4549 4566/1/4566 4563/1/4563 +f 4549/1/4549 4563/1/4563 4553/1/4553 +f 4550/1/4550 4549/1/4549 4553/1/4553 +f 4553/1/4553 4563/1/4563 4561/1/4561 +f 4553/1/4553 4561/1/4561 4551/1/4551 +f 4549/1/4549 4571/1/4571 4566/1/4566 +f 4571/1/4571 4569/1/4569 4566/1/4566 +f 4572/1/4572 4569/1/4569 4571/1/4571 +f 4548/1/4548 4572/1/4572 4571/1/4571 +f 4580/1/4580 4572/1/4572 4548/1/4548 +f 4547/1/4547 4580/1/4580 4548/1/4548 +f 4547/1/4547 4548/1/4548 4546/1/4546 +f 4546/1/4546 4548/1/4548 4549/1/4549 +f 4545/1/4545 4580/1/4580 4547/1/4547 +f 4543/1/4543 4545/1/4545 4547/1/4547 +f 4541/1/4541 4545/1/4545 4543/1/4543 +f 3337/1/3337 4541/1/4541 4543/1/4543 +f 3363/1/3363 4541/1/4541 3337/1/3337 +f 3363/1/3363 4540/1/4540 4541/1/4541 +f 4540/1/4540 4542/1/4542 4541/1/4541 +f 4541/1/4541 4542/1/4542 4544/1/4544 +f 4542/1/4542 4598/1/4598 4544/1/4544 +f 4544/1/4544 4598/1/4598 4589/1/4589 +f 4544/1/4544 4589/1/4589 4588/1/4588 +f 4544/1/4544 4588/1/4588 4545/1/4545 +f 4545/1/4545 4588/1/4588 4581/1/4581 +f 4588/1/4588 4582/1/4582 4581/1/4581 +f 4581/1/4581 4582/1/4582 4578/1/4578 +f 4581/1/4581 4578/1/4578 4580/1/4580 +f 4582/1/4582 4583/1/4583 4578/1/4578 +f 4583/1/4583 4579/1/4579 4578/1/4578 +f 4578/1/4578 4579/1/4579 4573/1/4573 +f 4578/1/4578 4573/1/4573 4572/1/4572 +f 4579/1/4579 4577/1/4577 4573/1/4573 +f 4573/1/4573 4577/1/4577 4574/1/4574 +f 4573/1/4573 4574/1/4574 4569/1/4569 +f 4569/1/4569 4574/1/4574 4570/1/4570 +f 4577/1/4577 4575/1/4575 4574/1/4574 +f 4577/1/4577 4630/1/4630 4575/1/4575 +f 4584/1/4584 4630/1/4630 4577/1/4577 +f 4584/1/4584 4593/1/4593 4630/1/4630 +f 4593/1/4593 3197/1/3197 4630/1/4630 +f 4593/1/4593 3198/1/3198 3197/1/3197 +f 3198/1/3198 3143/1/3143 3197/1/3197 +f 3198/1/3198 3140/1/3140 3143/1/3143 +f 3140/1/3140 3142/1/3142 3143/1/3143 +f 3143/1/3143 3142/1/3142 3160/1/3160 +f 3143/1/3143 3160/1/3160 3165/1/3165 +f 3160/1/3160 3161/1/3161 3165/1/3165 +f 3160/1/3160 3158/1/3158 3161/1/3161 +f 3158/1/3158 3162/1/3162 3161/1/3161 +f 3162/1/3162 3164/1/3164 3161/1/3161 +f 3162/1/3162 3163/1/3163 3164/1/3164 +f 3342/1/3342 3164/1/3164 3163/1/3163 +f 3342/1/3342 3163/1/3163 3341/1/3341 +f 3341/1/3341 3339/1/3339 3342/1/3342 +f 3341/1/3341 3343/1/3343 3339/1/3339 +f 3343/1/3343 3363/1/3363 3339/1/3339 +f 3343/1/3343 3362/1/3362 3363/1/3363 +f 3348/1/3348 3362/1/3362 3343/1/3343 +f 3346/1/3346 3348/1/3348 3343/1/3343 +f 3346/1/3346 3343/1/3343 3345/1/3345 +f 3345/1/3345 3157/1/3157 3346/1/3346 +f 3346/1/3346 3157/1/3157 3156/1/3156 +f 3346/1/3346 3156/1/3156 3347/1/3347 +f 3347/1/3347 3156/1/3156 3155/1/3155 +f 3347/1/3347 3155/1/3155 3349/1/3349 +f 3349/1/3349 3351/1/3351 3347/1/3347 +f 3347/1/3347 3351/1/3351 3348/1/3348 +f 3351/1/3351 3354/1/3354 3348/1/3348 +f 3351/1/3351 4533/1/4533 3354/1/3354 +f 4533/1/4533 4538/1/4538 3354/1/3354 +f 3354/1/3354 4538/1/4538 4539/1/4539 +f 3354/1/3354 4539/1/4539 3362/1/3362 +f 3362/1/3362 4539/1/4539 4540/1/4540 +f 4539/1/4539 4608/1/4608 4540/1/4540 +f 4539/1/4539 4611/1/4611 4608/1/4608 +f 4611/1/4611 4610/1/4610 4608/1/4608 +f 4608/1/4608 4610/1/4610 4607/1/4607 +f 4608/1/4608 4607/1/4607 4606/1/4606 +f 4608/1/4608 4606/1/4606 4542/1/4542 +f 4542/1/4542 4606/1/4606 4599/1/4599 +f 4606/1/4606 4601/1/4601 4599/1/4599 +f 4599/1/4599 4601/1/4601 4596/1/4596 +f 4599/1/4599 4596/1/4596 4598/1/4598 +f 4598/1/4598 4596/1/4596 4590/1/4590 +f 4596/1/4596 4591/1/4591 4590/1/4590 +f 4590/1/4590 4591/1/4591 4586/1/4586 +f 4590/1/4590 4586/1/4586 4585/1/4585 +f 4589/1/4589 4590/1/4590 4585/1/4585 +f 4585/1/4585 4586/1/4586 4583/1/4583 +f 4586/1/4586 4587/1/4587 4583/1/4583 +f 4583/1/4583 4587/1/4587 4584/1/4584 +f 4586/1/4586 4592/1/4592 4587/1/4587 +f 4592/1/4592 4593/1/4593 4587/1/4587 +f 4592/1/4592 4594/1/4594 4593/1/4593 +f 4595/1/4595 4594/1/4594 4592/1/4592 +f 4591/1/4591 4595/1/4595 4592/1/4592 +f 4597/1/4597 4595/1/4595 4591/1/4591 +f 4597/1/4597 4602/1/4602 4595/1/4595 +f 4602/1/4602 4629/1/4629 4595/1/4595 +f 4604/1/4604 4629/1/4629 4602/1/4602 +f 4600/1/4600 4604/1/4604 4602/1/4602 +f 4603/1/4603 4604/1/4604 4600/1/4600 +f 4605/1/4605 4603/1/4603 4600/1/4600 +f 4605/1/4605 4600/1/4600 4601/1/4601 +f 4609/1/4609 4603/1/4603 4605/1/4605 +f 4607/1/4607 4609/1/4609 4605/1/4605 +f 4609/1/4609 4622/1/4622 4603/1/4603 +f 4622/1/4622 4625/1/4625 4603/1/4603 +f 4622/1/4622 4624/1/4624 4625/1/4625 +f 4624/1/4624 4626/1/4626 4625/1/4625 +f 4625/1/4625 4626/1/4626 4627/1/4627 +f 4625/1/4625 4627/1/4627 4604/1/4604 +f 4626/1/4626 3200/1/3200 4627/1/4627 +f 4627/1/4627 3200/1/3200 3199/1/3199 +f 4627/1/4627 3199/1/3199 4629/1/4629 +f 4629/1/4629 3199/1/3199 3198/1/3198 +f 4629/1/4629 3198/1/3198 4594/1/4594 +f 3200/1/3200 3144/1/3144 3199/1/3199 +f 3199/1/3199 3144/1/3144 3140/1/3140 +f 3144/1/3144 3141/1/3141 3140/1/3140 +f 3144/1/3144 3145/1/3145 3141/1/3141 +f 3145/1/3145 3146/1/3146 3141/1/3141 +f 3141/1/3141 3146/1/3146 3147/1/3147 +f 3141/1/3141 3147/1/3147 3142/1/3142 +f 3142/1/3142 3147/1/3147 3154/1/3154 +f 3142/1/3142 3154/1/3154 3158/1/3158 +f 3154/1/3154 3159/1/3159 3158/1/3158 +f 3154/1/3154 3157/1/3157 3159/1/3159 +f 3159/1/3159 3157/1/3157 3163/1/3163 +f 3344/1/3344 3163/1/3163 3157/1/3157 +f 3153/1/3153 3157/1/3157 3154/1/3154 +f 3147/1/3147 3153/1/3153 3154/1/3154 +f 3146/1/3146 3153/1/3153 3147/1/3147 +f 3146/1/3146 3152/1/3152 3153/1/3153 +f 3152/1/3152 3155/1/3155 3153/1/3153 +f 3152/1/3152 3350/1/3350 3155/1/3155 +f 3150/1/3150 3350/1/3350 3152/1/3152 +f 3151/1/3151 3150/1/3150 3152/1/3152 +f 3145/1/3145 3150/1/3150 3151/1/3151 +f 3149/1/3149 3150/1/3150 3145/1/3145 +f 3148/1/3148 3149/1/3149 3145/1/3145 +f 3202/1/3202 3149/1/3149 3148/1/3148 +f 3201/1/3201 3202/1/3202 3148/1/3148 +f 3201/1/3201 3148/1/3148 3200/1/3200 +f 3329/1/3329 3201/1/3201 3200/1/3200 +f 3327/1/3327 3201/1/3201 3329/1/3329 +f 3328/1/3328 3327/1/3327 3329/1/3329 +f 3328/1/3328 3329/1/3329 4628/1/4628 +f 4619/1/4619 3328/1/3328 4628/1/4628 +f 4619/1/4619 4628/1/4628 4621/1/4621 +f 4617/1/4617 4619/1/4619 4621/1/4621 +f 4617/1/4617 4621/1/4621 4618/1/4618 +f 4613/1/4613 4617/1/4617 4618/1/4618 +f 4613/1/4613 4618/1/4618 4610/1/4610 +f 4610/1/4610 4618/1/4618 4620/1/4620 +f 4610/1/4610 4620/1/4620 4609/1/4609 +f 4612/1/4612 4617/1/4617 4613/1/4613 +f 4611/1/4611 4612/1/4612 4613/1/4613 +f 4614/1/4614 4612/1/4612 4611/1/4611 +f 4538/1/4538 4614/1/4614 4611/1/4611 +f 4532/1/4532 4614/1/4614 4538/1/4538 +f 4532/1/4532 3311/1/3311 4614/1/4614 +f 3311/1/3311 3316/1/3316 4614/1/4614 +f 4614/1/4614 3316/1/3316 4615/1/4615 +f 3316/1/3316 3317/1/3317 4615/1/4615 +f 4615/1/4615 3317/1/3317 4616/1/4616 +f 4615/1/4615 4616/1/4616 4612/1/4612 +f 3317/1/3317 3325/1/3325 4616/1/4616 +f 3325/1/3325 4623/1/4623 4616/1/4616 +f 4616/1/4616 4623/1/4623 4619/1/4619 +f 3325/1/3325 3326/1/3326 4623/1/4623 +f 4623/1/4623 3326/1/3326 3328/1/3328 +f 3325/1/3325 3324/1/3324 3326/1/3326 +f 3324/1/3324 3208/1/3208 3326/1/3326 +f 3326/1/3326 3208/1/3208 3327/1/3327 +f 3322/1/3322 3208/1/3208 3324/1/3324 +f 3323/1/3323 3322/1/3322 3324/1/3324 +f 3319/1/3319 3322/1/3322 3323/1/3323 +f 3313/1/3313 3319/1/3319 3323/1/3323 +f 3313/1/3313 3323/1/3323 3315/1/3315 +f 3314/1/3314 3313/1/3313 3315/1/3315 +f 3314/1/3314 3315/1/3315 3316/1/3316 +f 3310/1/3310 3313/1/3313 3314/1/3314 +f 3311/1/3311 3310/1/3310 3314/1/3314 +f 3307/1/3307 3310/1/3310 3311/1/3311 +f 3307/1/3307 3308/1/3308 3310/1/3310 +f 3308/1/3308 3309/1/3309 3310/1/3310 +f 3308/1/3308 3306/1/3306 3309/1/3309 +f 3306/1/3306 3298/1/3298 3309/1/3309 +f 3298/1/3298 3318/1/3318 3309/1/3309 +f 3309/1/3309 3318/1/3318 3319/1/3319 +f 3318/1/3318 3321/1/3321 3319/1/3319 +f 3318/1/3318 3320/1/3320 3321/1/3321 +f 3320/1/3320 3205/1/3205 3321/1/3321 +f 3321/1/3321 3205/1/3205 3207/1/3207 +f 3321/1/3321 3207/1/3207 3322/1/3322 +f 3205/1/3205 3203/1/3203 3207/1/3207 +f 3207/1/3207 3203/1/3203 3208/1/3208 +f 3208/1/3208 3203/1/3203 3201/1/3201 +f 3205/1/3205 3206/1/3206 3203/1/3203 +f 3206/1/3206 3204/1/3204 3203/1/3203 +f 3203/1/3203 3204/1/3204 3202/1/3202 +f 3204/1/3204 3361/1/3361 3202/1/3202 +f 3202/1/3202 3361/1/3361 3359/1/3359 +f 3361/1/3361 3360/1/3360 3359/1/3359 +f 3359/1/3359 3360/1/3360 3358/1/3358 +f 3359/1/3359 3358/1/3358 3149/1/3149 +f 3360/1/3360 4649/1/4649 3358/1/3358 +f 4649/1/4649 3356/1/3356 3358/1/3358 +f 3358/1/3358 3356/1/3356 3355/1/3355 +f 3150/1/3150 3358/1/3358 3355/1/3355 +f 3353/1/3353 3355/1/3355 3356/1/3356 +f 3353/1/3353 3356/1/3356 3357/1/3357 +f 3357/1/3357 4531/1/4531 3353/1/3353 +f 3353/1/3353 4531/1/4531 3351/1/3351 +f 3353/1/3353 3351/1/3351 3352/1/3352 +f 4536/1/4536 4531/1/4531 3357/1/3357 +f 4534/1/4534 4531/1/4531 4536/1/4536 +f 4536/1/4536 4537/1/4537 4534/1/4534 +f 4534/1/4534 4537/1/4537 4535/1/4535 +f 4535/1/4535 4526/1/4526 4534/1/4534 +f 4525/1/4525 4526/1/4526 4535/1/4535 +f 4535/1/4535 4524/1/4524 4525/1/4525 +f 4525/1/4525 4524/1/4524 4522/1/4522 +f 4522/1/4522 4524/1/4524 4521/1/4521 +f 4522/1/4522 4521/1/4521 4520/1/4520 +f 4520/1/4520 4523/1/4523 4522/1/4522 +f 4522/1/4522 4523/1/4523 4526/1/4526 +f 4523/1/4523 4528/1/4528 4526/1/4526 +f 4526/1/4526 4528/1/4528 4530/1/4530 +f 4526/1/4526 4530/1/4530 4531/1/4531 +f 4531/1/4531 4530/1/4530 4533/1/4533 +f 4530/1/4530 4532/1/4532 4533/1/4533 +f 4530/1/4530 3312/1/3312 4532/1/4532 +f 3312/1/3312 3307/1/3307 4532/1/4532 +f 3312/1/3312 3302/1/3302 3307/1/3307 +f 3302/1/3302 3305/1/3305 3307/1/3307 +f 3302/1/3302 3301/1/3301 3305/1/3305 +f 3301/1/3301 3299/1/3299 3305/1/3305 +f 3305/1/3305 3299/1/3299 3306/1/3306 +f 3301/1/3301 3296/1/3296 3299/1/3299 +f 3296/1/3296 3295/1/3295 3299/1/3299 +f 3299/1/3299 3295/1/3295 3298/1/3298 +f 3295/1/3295 3297/1/3297 3298/1/3298 +f 3298/1/3298 3297/1/3297 3320/1/3320 +f 3295/1/3295 3292/1/3292 3297/1/3297 +f 3292/1/3292 3215/1/3215 3297/1/3297 +f 3297/1/3297 3215/1/3215 3205/1/3205 +f 3292/1/3292 3214/1/3214 3215/1/3215 +f 3214/1/3214 3210/1/3210 3215/1/3215 +f 3215/1/3215 3210/1/3210 3206/1/3206 +f 3210/1/3210 3209/1/3209 3206/1/3206 +f 3210/1/3210 3211/1/3211 3209/1/3209 +f 3211/1/3211 4471/1/4471 3209/1/3209 +f 3209/1/3209 4471/1/4471 4647/1/4647 +f 3209/1/3209 4647/1/4647 3204/1/3204 +f 4471/1/4471 4518/1/4518 4647/1/4647 +f 4647/1/4647 4518/1/4518 4645/1/4645 +f 4647/1/4647 4645/1/4645 3361/1/3361 +f 3361/1/3361 4645/1/4645 4646/1/4646 +f 4645/1/4645 4519/1/4519 4646/1/4646 +f 4519/1/4519 4524/1/4524 4646/1/4646 +f 4646/1/4646 4524/1/4524 4648/1/4648 +f 4646/1/4646 4648/1/4648 3360/1/3360 +f 4648/1/4648 4524/1/4524 4537/1/4537 +f 4648/1/4648 4537/1/4537 4649/1/4649 +f 4518/1/4518 4519/1/4519 4645/1/4645 +f 4518/1/4518 4516/1/4516 4519/1/4519 +f 4516/1/4516 4515/1/4515 4519/1/4519 +f 4519/1/4519 4515/1/4515 4521/1/4521 +f 4516/1/4516 4513/1/4513 4515/1/4515 +f 4515/1/4515 4513/1/4513 4514/1/4514 +f 4520/1/4520 4515/1/4515 4514/1/4514 +f 4514/1/4514 4511/1/4511 4520/1/4520 +f 4512/1/4512 4511/1/4511 4514/1/4514 +f 4507/1/4507 4511/1/4511 4512/1/4512 +f 4512/1/4512 4508/1/4508 4507/1/4507 +f 4507/1/4507 4508/1/4508 4505/1/4505 +f 4507/1/4507 4505/1/4505 4509/1/4509 +f 4509/1/4509 4510/1/4510 4507/1/4507 +f 4504/1/4504 4510/1/4510 4509/1/4509 +f 4503/1/4503 4510/1/4510 4504/1/4504 +f 4504/1/4504 4501/1/4501 4503/1/4503 +f 4503/1/4503 4501/1/4501 4500/1/4500 +f 4500/1/4500 4497/1/4497 4503/1/4503 +f 4498/1/4498 4497/1/4497 4500/1/4500 +f 4500/1/4500 4499/1/4499 4498/1/4498 +f 4498/1/4498 4499/1/4499 4495/1/4495 +f 4495/1/4495 4499/1/4499 4496/1/4496 +f 4495/1/4495 4496/1/4496 4492/1/4492 +f 4492/1/4492 4493/1/4493 4495/1/4495 +f 4495/1/4495 4493/1/4493 4497/1/4497 +f 4493/1/4493 3265/1/3265 4497/1/4497 +f 4497/1/4497 3265/1/3265 3266/1/3266 +f 4497/1/4497 3266/1/3266 4510/1/4510 +f 4510/1/4510 3266/1/3266 4529/1/4529 +f 4510/1/4510 4529/1/4529 4511/1/4511 +f 4511/1/4511 4529/1/4529 4527/1/4527 +f 4511/1/4511 4527/1/4527 4523/1/4523 +f 4529/1/4529 3270/1/3270 4527/1/4527 +f 4527/1/4527 3270/1/3270 3330/1/3330 +f 4527/1/4527 3330/1/3330 4528/1/4528 +f 4528/1/4528 3330/1/3330 3312/1/3312 +f 3270/1/3270 3303/1/3303 3330/1/3330 +f 3330/1/3330 3303/1/3303 3302/1/3302 +f 3303/1/3303 3300/1/3300 3302/1/3302 +f 3303/1/3303 3304/1/3304 3300/1/3300 +f 3304/1/3304 3293/1/3293 3300/1/3300 +f 3300/1/3300 3293/1/3293 3294/1/3294 +f 3300/1/3300 3294/1/3294 3296/1/3296 +f 3294/1/3294 3291/1/3291 3296/1/3296 +f 3288/1/3288 3291/1/3291 3294/1/3294 +f 3288/1/3288 3290/1/3290 3291/1/3291 +f 3291/1/3291 3290/1/3290 3292/1/3292 +f 3288/1/3288 3286/1/3286 3290/1/3290 +f 3286/1/3286 3213/1/3213 3290/1/3290 +f 3290/1/3290 3213/1/3213 3214/1/3214 +f 3284/1/3284 3213/1/3213 3286/1/3286 +f 3285/1/3285 3284/1/3284 3286/1/3286 +f 3283/1/3283 3284/1/3284 3285/1/3285 +f 3287/1/3287 3283/1/3283 3285/1/3285 +f 3287/1/3287 3285/1/3285 3289/1/3289 +f 3332/1/3332 3287/1/3287 3289/1/3289 +f 3332/1/3332 3289/1/3289 3304/1/3304 +f 3331/1/3331 3332/1/3332 3304/1/3304 +f 3269/1/3269 3332/1/3332 3331/1/3331 +f 3270/1/3270 3269/1/3269 3331/1/3331 +f 3267/1/3267 3269/1/3269 3270/1/3270 +f 3267/1/3267 3268/1/3268 3269/1/3269 +f 3268/1/3268 3273/1/3273 3269/1/3269 +f 3269/1/3269 3273/1/3273 3277/1/3277 +f 3273/1/3273 3276/1/3276 3277/1/3277 +f 3277/1/3277 3276/1/3276 3287/1/3287 +f 3276/1/3276 3279/1/3279 3287/1/3287 +f 3275/1/3275 3279/1/3279 3276/1/3276 +f 3275/1/3275 3278/1/3278 3279/1/3279 +f 3278/1/3278 3281/1/3281 3279/1/3279 +f 3279/1/3279 3281/1/3281 3282/1/3282 +f 3279/1/3279 3282/1/3282 3283/1/3283 +f 3281/1/3281 3216/1/3216 3282/1/3282 +f 3282/1/3282 3216/1/3216 3218/1/3218 +f 3282/1/3282 3218/1/3218 3284/1/3284 +f 3216/1/3216 3212/1/3212 3218/1/3218 +f 3218/1/3218 3212/1/3212 3213/1/3213 +f 3213/1/3213 3212/1/3212 3210/1/3210 +f 3216/1/3216 3217/1/3217 3212/1/3212 +f 3217/1/3217 4469/1/4469 3212/1/3212 +f 3212/1/3212 4469/1/4469 3211/1/3211 +f 4469/1/4469 4466/1/4466 3211/1/3211 +f 4469/1/4469 4470/1/4470 4466/1/4466 +f 4470/1/4470 4467/1/4467 4466/1/4466 +f 4466/1/4466 4467/1/4467 4468/1/4468 +f 4466/1/4466 4468/1/4468 4471/1/4471 +f 4471/1/4471 4468/1/4468 4517/1/4517 +f 4517/1/4517 4468/1/4468 4516/1/4516 +f 4468/1/4468 4467/1/4467 4508/1/4508 +f 4468/1/4468 4508/1/4508 4513/1/4513 +f 4470/1/4470 4474/1/4474 4467/1/4467 +f 4474/1/4474 4506/1/4506 4467/1/4467 +f 4506/1/4506 4505/1/4505 4467/1/4467 +f 4506/1/4506 4501/1/4501 4505/1/4505 +f 4502/1/4502 4501/1/4501 4506/1/4506 +f 4502/1/4502 4499/1/4499 4501/1/4501 +f 4476/1/4476 4499/1/4499 4502/1/4502 +f 4476/1/4476 4502/1/4502 4474/1/4474 +f 4473/1/4473 4476/1/4476 4474/1/4474 +f 4473/1/4473 4477/1/4477 4476/1/4476 +f 4477/1/4477 4481/1/4481 4476/1/4476 +f 4479/1/4479 4481/1/4481 4477/1/4477 +f 4475/1/4475 4479/1/4479 4477/1/4477 +f 4480/1/4480 4479/1/4479 4475/1/4475 +f 4478/1/4478 4480/1/4480 4475/1/4475 +f 4478/1/4478 4475/1/4475 4472/1/4472 +f 3221/1/3221 4478/1/4478 4472/1/4472 +f 3221/1/3221 4472/1/4472 3217/1/3217 +f 3220/1/3220 3221/1/3221 3217/1/3217 +f 3220/1/3220 3217/1/3217 3219/1/3219 +f 3222/1/3222 3220/1/3220 3219/1/3219 +f 3222/1/3222 3219/1/3219 3223/1/3223 +f 3280/1/3280 3222/1/3222 3223/1/3223 +f 3280/1/3280 3223/1/3223 3278/1/3278 +f 3274/1/3274 3280/1/3280 3278/1/3278 +f 3239/1/3239 3280/1/3280 3274/1/3274 +f 3271/1/3271 3239/1/3239 3274/1/3274 +f 3271/1/3271 3274/1/3274 3272/1/3272 +f 3268/1/3268 3271/1/3271 3272/1/3272 +f 3241/1/3241 3271/1/3271 3268/1/3268 +f 3241/1/3241 3238/1/3238 3271/1/3271 +f 3241/1/3241 3237/1/3237 3238/1/3238 +f 3237/1/3237 3233/1/3233 3238/1/3238 +f 3238/1/3238 3233/1/3233 3239/1/3239 +f 3233/1/3233 3231/1/3231 3239/1/3239 +f 3233/1/3233 3230/1/3230 3231/1/3231 +f 3230/1/3230 3225/1/3225 3231/1/3231 +f 3231/1/3231 3225/1/3225 3222/1/3222 +f 3230/1/3230 3224/1/3224 3225/1/3225 +f 3224/1/3224 3220/1/3220 3225/1/3225 +f 3224/1/3224 3226/1/3226 3220/1/3220 +f 3227/1/3227 3226/1/3226 3224/1/3224 +f 3229/1/3229 3227/1/3227 3224/1/3224 +f 3235/1/3235 3227/1/3227 3229/1/3229 +f 3234/1/3234 3235/1/3235 3229/1/3229 +f 3234/1/3234 3229/1/3229 3232/1/3232 +f 3236/1/3236 3234/1/3234 3232/1/3232 +f 3236/1/3236 3232/1/3232 3237/1/3237 +f 3240/1/3240 3236/1/3236 3237/1/3237 +f 3240/1/3240 3242/1/3242 3236/1/3236 +f 3245/1/3245 3242/1/3242 3240/1/3240 +f 3243/1/3243 3245/1/3245 3240/1/3240 +f 3243/1/3243 3240/1/3240 3244/1/3244 +f 3265/1/3265 3243/1/3243 3244/1/3244 +f 3262/1/3262 3243/1/3243 3265/1/3265 +f 3262/1/3262 3260/1/3260 3243/1/3243 +f 3261/1/3261 3260/1/3260 3262/1/3262 +f 4463/1/4463 3261/1/3261 3262/1/3262 +f 4463/1/4463 3262/1/3262 4493/1/4493 +f 4462/1/4462 3261/1/3261 4463/1/4463 +f 4490/1/4490 4462/1/4462 4463/1/4463 +f 4490/1/4490 4463/1/4463 4489/1/4489 +f 4489/1/4489 4487/1/4487 4490/1/4490 +f 4490/1/4490 4487/1/4487 4405/1/4405 +f 4490/1/4490 4405/1/4405 4465/1/4465 +f 4465/1/4465 4405/1/4405 4464/1/4464 +f 4464/1/4464 4462/1/4462 4465/1/4465 +f 4461/1/4461 4462/1/4462 4464/1/4464 +f 4464/1/4464 4403/1/4403 4461/1/4461 +f 4461/1/4461 4403/1/4403 4460/1/4460 +f 4460/1/4460 4410/1/4410 4461/1/4461 +f 4411/1/4411 4410/1/4410 4460/1/4460 +f 4460/1/4460 4399/1/4399 4411/1/4411 +f 4411/1/4411 4399/1/4399 4407/1/4407 +f 4407/1/4407 4399/1/4399 4401/1/4401 +f 4407/1/4407 4401/1/4401 4408/1/4408 +f 4408/1/4408 4409/1/4409 4407/1/4407 +f 4407/1/4407 4409/1/4409 4410/1/4410 +f 4409/1/4409 3264/1/3264 4410/1/4410 +f 4410/1/4410 3264/1/3264 3263/1/3263 +f 4410/1/4410 3263/1/3263 4462/1/4462 +f 3264/1/3264 3075/1/3075 3263/1/3263 +f 3263/1/3263 3075/1/3075 3077/1/3077 +f 3263/1/3263 3077/1/3077 3261/1/3261 +f 3075/1/3075 3072/1/3072 3077/1/3077 +f 3077/1/3077 3072/1/3072 3076/1/3076 +f 3077/1/3077 3076/1/3076 3258/1/3258 +f 3077/1/3077 3258/1/3258 3260/1/3260 +f 3260/1/3260 3258/1/3258 3245/1/3245 +f 3258/1/3258 3257/1/3257 3245/1/3245 +f 3245/1/3245 3257/1/3257 3248/1/3248 +f 3257/1/3257 3250/1/3250 3248/1/3248 +f 3248/1/3248 3250/1/3250 3246/1/3246 +f 3248/1/3248 3246/1/3246 3242/1/3242 +f 3242/1/3242 3246/1/3246 3247/1/3247 +f 3242/1/3242 3247/1/3247 3234/1/3234 +f 3246/1/3246 3249/1/3249 3247/1/3247 +f 3249/1/3249 3235/1/3235 3247/1/3247 +f 3249/1/3249 3251/1/3251 3235/1/3235 +f 3249/1/3249 3252/1/3252 3251/1/3251 +f 3252/1/3252 3104/1/3104 3251/1/3251 +f 3251/1/3251 3104/1/3104 3228/1/3228 +f 3251/1/3251 3228/1/3228 3227/1/3227 +f 3104/1/3104 3105/1/3105 3228/1/3228 +f 3228/1/3228 3105/1/3105 3226/1/3226 +f 3226/1/3226 3105/1/3105 3221/1/3221 +f 3104/1/3104 3102/1/3102 3105/1/3105 +f 3102/1/3102 4486/1/4486 3105/1/3105 +f 3105/1/3105 4486/1/4486 4478/1/4478 +f 3102/1/3102 4393/1/4393 4486/1/4486 +f 4393/1/4393 4485/1/4485 4486/1/4486 +f 4486/1/4486 4485/1/4485 4480/1/4480 +f 4485/1/4485 4484/1/4484 4480/1/4480 +f 4480/1/4480 4484/1/4484 4482/1/4482 +f 4482/1/4482 4484/1/4484 4483/1/4483 +f 4482/1/4482 4483/1/4483 4479/1/4479 +f 4484/1/4484 4488/1/4488 4483/1/4483 +f 4483/1/4483 4488/1/4488 4494/1/4494 +f 4483/1/4483 4494/1/4494 4481/1/4481 +f 4481/1/4481 4494/1/4494 4496/1/4496 +f 4494/1/4494 4488/1/4488 4491/1/4491 +f 4492/1/4492 4494/1/4494 4491/1/4491 +f 4491/1/4491 4463/1/4463 4492/1/4492 +f 4491/1/4491 4488/1/4488 4489/1/4489 +f 4484/1/4484 4487/1/4487 4488/1/4488 +f 4484/1/4484 4406/1/4406 4487/1/4487 +f 4485/1/4485 4406/1/4406 4484/1/4484 +f 4396/1/4396 4406/1/4406 4485/1/4485 +f 4396/1/4396 4395/1/4395 4406/1/4406 +f 4395/1/4395 4404/1/4404 4406/1/4406 +f 4404/1/4404 4405/1/4405 4406/1/4406 +f 4404/1/4404 4403/1/4403 4405/1/4405 +f 4398/1/4398 4403/1/4403 4404/1/4404 +f 4398/1/4398 4399/1/4399 4403/1/4403 +f 4394/1/4394 4399/1/4399 4398/1/4398 +f 4394/1/4394 4398/1/4398 4395/1/4395 +f 4390/1/4390 4394/1/4394 4395/1/4395 +f 4390/1/4390 4392/1/4392 4394/1/4394 +f 4392/1/4392 4397/1/4397 4394/1/4394 +f 4391/1/4391 4397/1/4397 4392/1/4392 +f 4388/1/4388 4391/1/4391 4392/1/4392 +f 4387/1/4387 4391/1/4391 4388/1/4388 +f 4386/1/4386 4387/1/4387 4388/1/4388 +f 4386/1/4386 4388/1/4388 4389/1/4389 +f 3056/1/3056 4386/1/4386 4389/1/4389 +f 3056/1/3056 4389/1/4389 3101/1/3101 +f 3057/1/3057 3056/1/3056 3101/1/3101 +f 3057/1/3057 3101/1/3101 3103/1/3103 +f 3093/1/3093 3057/1/3057 3103/1/3103 +f 3093/1/3093 3103/1/3103 3094/1/3094 +f 3092/1/3092 3093/1/3093 3094/1/3094 +f 3092/1/3092 3094/1/3094 3095/1/3095 +f 3079/1/3079 3092/1/3092 3095/1/3095 +f 3079/1/3079 3095/1/3095 3080/1/3080 +f 3078/1/3078 3079/1/3079 3080/1/3080 +f 3078/1/3078 3080/1/3080 3081/1/3081 +f 3076/1/3076 3078/1/3078 3081/1/3081 +f 3076/1/3076 3074/1/3074 3078/1/3078 +f 3081/1/3081 3080/1/3080 3082/1/3082 +f 3081/1/3081 3082/1/3082 3259/1/3259 +f 3258/1/3258 3081/1/3081 3259/1/3259 +f 3259/1/3259 3082/1/3082 3256/1/3256 +f 3259/1/3259 3256/1/3256 3257/1/3257 +f 3082/1/3082 3096/1/3096 3256/1/3256 +f 3096/1/3096 3255/1/3255 3256/1/3256 +f 3256/1/3256 3255/1/3255 3254/1/3254 +f 3256/1/3256 3254/1/3254 3250/1/3250 +f 3250/1/3250 3254/1/3254 3249/1/3249 +f 3255/1/3255 3253/1/3253 3254/1/3254 +f 3254/1/3254 3253/1/3253 3252/1/3252 +f 3255/1/3255 3098/1/3098 3253/1/3253 +f 3098/1/3098 3100/1/3100 3253/1/3253 +f 3253/1/3253 3100/1/3100 3104/1/3104 +f 3098/1/3098 3099/1/3099 3100/1/3100 +f 3099/1/3099 3102/1/3102 3100/1/3100 +f 3099/1/3099 3101/1/3101 3102/1/3102 +f 3097/1/3097 3099/1/3099 3098/1/3098 +f 3096/1/3096 3097/1/3097 3098/1/3098 +f 3095/1/3095 3097/1/3097 3096/1/3096 +f 3094/1/3094 3099/1/3099 3097/1/3097 +f 3096/1/3096 3098/1/3098 3255/1/3255 +f 3080/1/3080 3096/1/3096 3082/1/3082 +f 3074/1/3074 3079/1/3079 3078/1/3078 +f 3074/1/3074 3066/1/3066 3079/1/3079 +f 3073/1/3073 3066/1/3066 3074/1/3074 +f 3072/1/3072 3073/1/3073 3074/1/3074 +f 3072/1/3072 3069/1/3069 3073/1/3073 +f 3069/1/3069 3067/1/3067 3073/1/3073 +f 3069/1/3069 3063/1/3063 3067/1/3067 +f 3063/1/3063 3062/1/3062 3067/1/3067 +f 3067/1/3067 3062/1/3062 3066/1/3066 +f 3062/1/3062 3065/1/3065 3066/1/3066 +f 3066/1/3066 3065/1/3065 3092/1/3092 +f 3062/1/3062 3064/1/3064 3065/1/3065 +f 3065/1/3065 3064/1/3064 3093/1/3093 +f 3062/1/3062 3058/1/3058 3064/1/3064 +f 3058/1/3058 3057/1/3057 3064/1/3064 +f 3058/1/3058 3055/1/3055 3057/1/3057 +f 3053/1/3053 3055/1/3055 3058/1/3058 +f 3059/1/3059 3053/1/3053 3058/1/3058 +f 3054/1/3054 3053/1/3053 3059/1/3059 +f 3060/1/3060 3054/1/3054 3059/1/3059 +f 3060/1/3060 3059/1/3059 3063/1/3063 +f 3068/1/3068 3060/1/3060 3063/1/3063 +f 3070/1/3070 3060/1/3060 3068/1/3068 +f 3071/1/3071 3070/1/3070 3068/1/3068 +f 3071/1/3071 3068/1/3068 3069/1/3069 +f 3084/1/3084 3070/1/3070 3071/1/3071 +f 3083/1/3083 3084/1/3084 3071/1/3071 +f 3083/1/3083 3071/1/3071 3075/1/3075 +f 3085/1/3085 3084/1/3084 3083/1/3083 +f 3086/1/3086 3085/1/3085 3083/1/3083 +f 3086/1/3086 3083/1/3083 3264/1/3264 +f 3089/1/3089 3085/1/3085 3086/1/3086 +f 4412/1/4412 3089/1/3089 3086/1/3086 +f 4412/1/4412 3086/1/3086 4409/1/4409 +f 4414/1/4414 3089/1/3089 4412/1/4412 +f 4455/1/4455 4414/1/4414 4412/1/4412 +f 4455/1/4455 4412/1/4412 4454/1/4454 +f 4454/1/4454 4452/1/4452 4455/1/4455 +f 4455/1/4455 4452/1/4452 4449/1/4449 +f 4455/1/4455 4449/1/4449 4456/1/4456 +f 4456/1/4456 4449/1/4449 4457/1/4457 +f 4457/1/4457 4414/1/4414 4456/1/4456 +f 4458/1/4458 4414/1/4414 4457/1/4457 +f 4457/1/4457 4444/1/4444 4458/1/4458 +f 4458/1/4458 4444/1/4444 4445/1/4445 +f 4445/1/4445 4415/1/4415 4458/1/4458 +f 4446/1/4446 4415/1/4415 4445/1/4445 +f 4445/1/4445 4443/1/4443 4446/1/4446 +f 4446/1/4446 4443/1/4443 4418/1/4418 +f 4418/1/4418 4443/1/4443 4420/1/4420 +f 4418/1/4418 4420/1/4420 4417/1/4417 +f 4417/1/4417 4416/1/4416 4418/1/4418 +f 4418/1/4418 4416/1/4416 4415/1/4415 +f 4416/1/4416 2983/1/2983 4415/1/4415 +f 4415/1/4415 2983/1/2983 3091/1/3091 +f 4415/1/4415 3091/1/3091 4414/1/4414 +f 2983/1/2983 2985/1/2985 3091/1/3091 +f 3091/1/3091 2985/1/2985 3020/1/3020 +f 3091/1/3091 3020/1/3020 3089/1/3089 +f 2985/1/2985 3014/1/3014 3020/1/3020 +f 3020/1/3020 3014/1/3014 3021/1/3021 +f 3020/1/3020 3021/1/3021 3029/1/3029 +f 3020/1/3020 3029/1/3029 3085/1/3085 +f 3085/1/3085 3029/1/3029 3088/1/3088 +f 3029/1/3029 3038/1/3038 3088/1/3088 +f 3088/1/3088 3038/1/3038 3087/1/3087 +f 3088/1/3088 3087/1/3087 3084/1/3084 +f 3038/1/3038 3040/1/3040 3087/1/3087 +f 3087/1/3087 3040/1/3040 3090/1/3090 +f 3087/1/3087 3090/1/3090 3070/1/3070 +f 3070/1/3070 3090/1/3090 3061/1/3061 +f 3090/1/3090 3052/1/3052 3061/1/3061 +f 3052/1/3052 3054/1/3054 3061/1/3061 +f 3052/1/3052 3051/1/3051 3054/1/3054 +f 3052/1/3052 3048/1/3048 3051/1/3051 +f 3048/1/3048 3047/1/3047 3051/1/3051 +f 3051/1/3051 3047/1/3047 3050/1/3050 +f 3051/1/3051 3050/1/3050 3053/1/3053 +f 3047/1/3047 3049/1/3049 3050/1/3050 +f 3050/1/3050 3049/1/3049 3055/1/3055 +f 3055/1/3055 3049/1/3049 3056/1/3056 +f 3047/1/3047 3044/1/3044 3049/1/3049 +f 3044/1/3044 4385/1/4385 3049/1/3049 +f 3049/1/3049 4385/1/4385 4386/1/4386 +f 3044/1/3044 4384/1/4384 4385/1/4385 +f 4384/1/4384 4450/1/4450 4385/1/4385 +f 4385/1/4385 4450/1/4450 4387/1/4387 +f 4450/1/4450 4451/1/4451 4387/1/4387 +f 4387/1/4387 4451/1/4451 4459/1/4459 +f 4459/1/4459 4451/1/4451 4400/1/4400 +f 4459/1/4459 4400/1/4400 4391/1/4391 +f 4451/1/4451 4453/1/4453 4400/1/4400 +f 4400/1/4400 4453/1/4453 4402/1/4402 +f 4400/1/4400 4402/1/4402 4397/1/4397 +f 4397/1/4397 4402/1/4402 4401/1/4401 +f 4402/1/4402 4453/1/4453 4413/1/4413 +f 4408/1/4408 4402/1/4402 4413/1/4413 +f 4413/1/4413 4412/1/4412 4408/1/4408 +f 4413/1/4413 4453/1/4453 4454/1/4454 +f 4451/1/4451 4452/1/4452 4453/1/4453 +f 4451/1/4451 4448/1/4448 4452/1/4452 +f 4450/1/4450 4448/1/4448 4451/1/4451 +f 4441/1/4441 4448/1/4448 4450/1/4450 +f 4441/1/4441 4440/1/4440 4448/1/4448 +f 4440/1/4440 4447/1/4447 4448/1/4448 +f 4447/1/4447 4449/1/4449 4448/1/4448 +f 4447/1/4447 4444/1/4444 4449/1/4449 +f 4442/1/4442 4444/1/4444 4447/1/4447 +f 4442/1/4442 4443/1/4443 4444/1/4444 +f 4439/1/4439 4443/1/4443 4442/1/4442 +f 4439/1/4439 4442/1/4442 4440/1/4440 +f 4438/1/4438 4439/1/4439 4440/1/4440 +f 4438/1/4438 4437/1/4437 4439/1/4439 +f 4437/1/4437 4426/1/4426 4439/1/4439 +f 4430/1/4430 4426/1/4426 4437/1/4437 +f 4436/1/4436 4430/1/4430 4437/1/4437 +f 4432/1/4432 4430/1/4430 4436/1/4436 +f 4382/1/4382 4432/1/4432 4436/1/4436 +f 4382/1/4382 4436/1/4436 4383/1/4383 +f 3107/1/3107 4382/1/4382 4383/1/4383 +f 3107/1/3107 4383/1/4383 3046/1/3046 +f 3106/1/3106 3107/1/3107 3046/1/3046 +f 3106/1/3106 3046/1/3046 3045/1/3045 +f 3116/1/3116 3106/1/3106 3045/1/3045 +f 3116/1/3116 3045/1/3045 3033/1/3033 +f 3025/1/3025 3116/1/3116 3033/1/3033 +f 3025/1/3025 3033/1/3033 3027/1/3027 +f 3022/1/3022 3025/1/3025 3027/1/3027 +f 3022/1/3022 3027/1/3027 3026/1/3026 +f 3023/1/3023 3022/1/3022 3026/1/3026 +f 3023/1/3023 3026/1/3026 3028/1/3028 +f 3021/1/3021 3023/1/3023 3028/1/3028 +f 3021/1/3021 3019/1/3019 3023/1/3023 +f 3028/1/3028 3026/1/3026 3031/1/3031 +f 3028/1/3028 3031/1/3031 3030/1/3030 +f 3029/1/3029 3028/1/3028 3030/1/3030 +f 3030/1/3030 3031/1/3031 3036/1/3036 +f 3030/1/3030 3036/1/3036 3038/1/3038 +f 3031/1/3031 3032/1/3032 3036/1/3036 +f 3032/1/3032 3035/1/3035 3036/1/3036 +f 3036/1/3036 3035/1/3035 3039/1/3039 +f 3036/1/3036 3039/1/3039 3040/1/3040 +f 3040/1/3040 3039/1/3039 3052/1/3052 +f 3035/1/3035 3041/1/3041 3039/1/3039 +f 3039/1/3039 3041/1/3041 3048/1/3048 +f 3035/1/3035 3037/1/3037 3041/1/3041 +f 3037/1/3037 3042/1/3042 3041/1/3041 +f 3041/1/3041 3042/1/3042 3047/1/3047 +f 3037/1/3037 3043/1/3043 3042/1/3042 +f 3043/1/3043 3044/1/3044 3042/1/3042 +f 3043/1/3043 3046/1/3046 3044/1/3044 +f 3034/1/3034 3043/1/3043 3037/1/3037 +f 3032/1/3032 3034/1/3034 3037/1/3037 +f 3027/1/3027 3034/1/3034 3032/1/3032 +f 3033/1/3033 3043/1/3043 3034/1/3034 +f 3032/1/3032 3037/1/3037 3035/1/3035 +f 3026/1/3026 3032/1/3032 3031/1/3031 +f 3019/1/3019 3022/1/3022 3023/1/3023 +f 3019/1/3019 3018/1/3018 3022/1/3022 +f 3016/1/3016 3018/1/3018 3019/1/3019 +f 3014/1/3014 3016/1/3016 3019/1/3019 +f 3014/1/3014 3013/1/3013 3016/1/3016 +f 3013/1/3013 3015/1/3015 3016/1/3016 +f 3013/1/3013 3012/1/3012 3015/1/3015 +f 3012/1/3012 3017/1/3017 3015/1/3015 +f 3015/1/3015 3017/1/3017 3018/1/3018 +f 3017/1/3017 3024/1/3024 3018/1/3018 +f 3018/1/3018 3024/1/3024 3025/1/3025 +f 3017/1/3017 3115/1/3115 3024/1/3024 +f 3024/1/3024 3115/1/3115 3116/1/3116 +f 3017/1/3017 3111/1/3111 3115/1/3115 +f 3111/1/3111 3106/1/3106 3115/1/3115 +f 3111/1/3111 3108/1/3108 3106/1/3106 +f 3110/1/3110 3108/1/3108 3111/1/3111 +f 3011/1/3011 3110/1/3110 3111/1/3111 +f 3010/1/3010 3110/1/3110 3011/1/3011 +f 3008/1/3008 3010/1/3010 3011/1/3011 +f 3008/1/3008 3011/1/3011 3012/1/3012 +f 3009/1/3009 3008/1/3008 3012/1/3012 +f 2990/1/2990 3008/1/3008 3009/1/3009 +f 2984/1/2984 2990/1/2990 3009/1/3009 +f 2984/1/2984 3009/1/3009 3013/1/3013 +f 2986/1/2986 2990/1/2990 2984/1/2984 +f 2982/1/2982 2986/1/2986 2984/1/2984 +f 2982/1/2982 2984/1/2984 2985/1/2985 +f 2981/1/2981 2986/1/2986 2982/1/2982 +f 2980/1/2980 2981/1/2981 2982/1/2982 +f 2980/1/2980 2982/1/2982 2983/1/2983 +f 2977/1/2977 2981/1/2981 2980/1/2980 +f 2978/1/2978 2977/1/2977 2980/1/2980 +f 2978/1/2978 2980/1/2980 4416/1/4416 +f 2973/1/2973 2977/1/2977 2978/1/2978 +f 4422/1/4422 2973/1/2973 2978/1/2978 +f 4422/1/4422 2978/1/2978 4423/1/4423 +f 4423/1/4423 4428/1/4428 4422/1/4422 +f 4422/1/4422 4428/1/4428 2976/1/2976 +f 4422/1/4422 2976/1/2976 2975/1/2975 +f 2975/1/2975 2976/1/2976 2974/1/2974 +f 2974/1/2974 2973/1/2973 2975/1/2975 +f 2972/1/2972 2973/1/2973 2974/1/2974 +f 2974/1/2974 2969/1/2969 2972/1/2972 +f 2972/1/2972 2969/1/2969 2971/1/2971 +f 2971/1/2971 2927/1/2927 2972/1/2972 +f 2970/1/2970 2927/1/2927 2971/1/2971 +f 2971/1/2971 2966/1/2966 2970/1/2970 +f 2970/1/2970 2966/1/2966 2929/1/2929 +f 2929/1/2929 2966/1/2966 2931/1/2931 +f 2929/1/2929 2931/1/2931 2928/1/2928 +f 2928/1/2928 2924/1/2924 2929/1/2929 +f 2929/1/2929 2924/1/2924 2927/1/2927 +f 2924/1/2924 2923/1/2923 2927/1/2927 +f 2927/1/2927 2923/1/2923 2926/1/2926 +f 2927/1/2927 2926/1/2926 2973/1/2973 +f 2923/1/2923 2925/1/2925 2926/1/2926 +f 2926/1/2926 2925/1/2925 2979/1/2979 +f 2926/1/2926 2979/1/2979 2977/1/2977 +f 2925/1/2925 2994/1/2994 2979/1/2979 +f 2979/1/2979 2994/1/2994 2991/1/2991 +f 2979/1/2979 2991/1/2991 2987/1/2987 +f 2979/1/2979 2987/1/2987 2981/1/2981 +f 2991/1/2991 2992/1/2992 2987/1/2987 +f 2987/1/2987 2992/1/2992 2993/1/2993 +f 2987/1/2987 2993/1/2993 2988/1/2988 +f 2987/1/2987 2988/1/2988 2986/1/2986 +f 2986/1/2986 2988/1/2988 2989/1/2989 +f 2988/1/2988 3004/1/3004 2989/1/2989 +f 2989/1/2989 3004/1/3004 3006/1/3006 +f 2989/1/2989 3006/1/3006 2990/1/2990 +f 2990/1/2990 3006/1/3006 3007/1/3007 +f 3006/1/3006 3005/1/3005 3007/1/3007 +f 3005/1/3005 3010/1/3010 3007/1/3007 +f 3005/1/3005 3114/1/3114 3010/1/3010 +f 3005/1/3005 3117/1/3117 3114/1/3114 +f 3117/1/3117 3113/1/3113 3114/1/3114 +f 3114/1/3114 3113/1/3113 3112/1/3112 +f 3114/1/3114 3112/1/3112 3110/1/3110 +f 3113/1/3113 3109/1/3109 3112/1/3112 +f 3112/1/3112 3109/1/3109 3108/1/3108 +f 3108/1/3108 3109/1/3109 3107/1/3107 +f 3113/1/3113 4380/1/4380 3109/1/3109 +f 4380/1/4380 4381/1/4381 3109/1/3109 +f 3109/1/3109 4381/1/4381 4382/1/4382 +f 4380/1/4380 3121/1/3121 4381/1/4381 +f 3121/1/3121 4431/1/4431 4381/1/4381 +f 4381/1/4381 4431/1/4431 4432/1/4432 +f 4431/1/4431 4427/1/4427 4432/1/4432 +f 4432/1/4432 4427/1/4427 4429/1/4429 +f 4429/1/4429 4427/1/4427 4425/1/4425 +f 4429/1/4429 4425/1/4425 4430/1/4430 +f 4427/1/4427 4424/1/4424 4425/1/4425 +f 4425/1/4425 4424/1/4424 4421/1/4421 +f 4425/1/4425 4421/1/4421 4426/1/4426 +f 4426/1/4426 4421/1/4421 4420/1/4420 +f 4421/1/4421 4424/1/4424 4419/1/4419 +f 4417/1/4417 4421/1/4421 4419/1/4419 +f 4419/1/4419 2978/1/2978 4417/1/4417 +f 4419/1/4419 4424/1/4424 4423/1/4423 +f 4427/1/4427 4428/1/4428 4424/1/4424 +f 4427/1/4427 4433/1/4433 4428/1/4428 +f 4431/1/4431 4433/1/4433 4427/1/4427 +f 4435/1/4435 4433/1/4433 4431/1/4431 +f 4435/1/4435 2968/1/2968 4433/1/4433 +f 2968/1/2968 4434/1/4434 4433/1/4433 +f 4434/1/4434 2976/1/2976 4433/1/4433 +f 4434/1/4434 2969/1/2969 2976/1/2976 +f 2967/1/2967 2969/1/2969 4434/1/4434 +f 2967/1/2967 2966/1/2966 2969/1/2969 +f 2965/1/2965 2966/1/2966 2967/1/2967 +f 2965/1/2965 2967/1/2967 2968/1/2968 +f 2964/1/2964 2965/1/2965 2968/1/2968 +f 2964/1/2964 2962/1/2962 2965/1/2965 +f 2962/1/2962 2961/1/2961 2965/1/2965 +f 2960/1/2960 2961/1/2961 2962/1/2962 +f 2959/1/2959 2960/1/2960 2962/1/2962 +f 2955/1/2955 2960/1/2960 2959/1/2959 +f 2958/1/2958 2955/1/2955 2959/1/2959 +f 2958/1/2958 2959/1/2959 2963/1/2963 +f 4348/1/4348 2958/1/2958 2963/1/2963 +f 4348/1/4348 2963/1/2963 4349/1/4349 +f 4350/1/4350 4348/1/4348 4349/1/4349 +f 4350/1/4350 4349/1/4349 4377/1/4377 +f 4375/1/4375 4350/1/4350 4377/1/4377 +f 4375/1/4375 4377/1/4377 4376/1/4376 +f 4373/1/4373 4375/1/4375 4376/1/4376 +f 4373/1/4373 4376/1/4376 3001/1/3001 +f 4372/1/4372 4373/1/4373 3001/1/3001 +f 4372/1/4372 3001/1/3001 2998/1/2998 +f 2995/1/2995 4372/1/4372 2998/1/2998 +f 2995/1/2995 2998/1/2998 2992/1/2992 +f 2992/1/2992 2998/1/2998 2997/1/2997 +f 2998/1/2998 3000/1/3000 2997/1/2997 +f 2997/1/2997 3000/1/3000 2999/1/2999 +f 2993/1/2993 2997/1/2997 2999/1/2999 +f 3000/1/3000 3002/1/3002 2999/1/2999 +f 2999/1/2999 3002/1/3002 3003/1/3003 +f 2999/1/2999 3003/1/3003 3004/1/3004 +f 3004/1/3004 3003/1/3003 3005/1/3005 +f 3002/1/3002 3118/1/3118 3003/1/3003 +f 3003/1/3003 3118/1/3118 3117/1/3117 +f 3002/1/3002 3120/1/3120 3118/1/3118 +f 3120/1/3120 3119/1/3119 3118/1/3118 +f 3118/1/3118 3119/1/3119 3113/1/3113 +f 3120/1/3120 4378/1/4378 3119/1/3119 +f 4378/1/4378 4380/1/4380 3119/1/3119 +f 4378/1/4378 4349/1/4349 4380/1/4380 +f 4379/1/4379 4378/1/4378 3120/1/3120 +f 3000/1/3000 4379/1/4379 3120/1/3120 +f 3001/1/3001 4379/1/4379 3000/1/3000 +f 4376/1/4376 4378/1/4378 4379/1/4379 +f 3000/1/3000 3120/1/3120 3002/1/3002 +f 2996/1/2996 4372/1/4372 2995/1/2995 +f 2991/1/2991 2996/1/2996 2995/1/2995 +f 2996/1/2996 4371/1/4371 4372/1/4372 +f 4370/1/4370 4371/1/4371 2996/1/2996 +f 2994/1/2994 4370/1/4370 2996/1/2996 +f 2994/1/2994 4364/1/4364 4370/1/4370 +f 4364/1/4364 4365/1/4365 4370/1/4370 +f 4364/1/4364 4359/1/4359 4365/1/4365 +f 4359/1/4359 4357/1/4357 4365/1/4365 +f 4365/1/4365 4357/1/4357 4371/1/4371 +f 4357/1/4357 4374/1/4374 4371/1/4371 +f 4371/1/4371 4374/1/4374 4373/1/4373 +f 4357/1/4357 4356/1/4356 4374/1/4374 +f 4374/1/4374 4356/1/4356 4375/1/4375 +f 4357/1/4357 4352/1/4352 4356/1/4356 +f 4352/1/4352 4350/1/4350 4356/1/4356 +f 4352/1/4352 4347/1/4347 4350/1/4350 +f 4351/1/4351 4347/1/4347 4352/1/4352 +f 4355/1/4355 4351/1/4351 4352/1/4352 +f 4354/1/4354 4351/1/4351 4355/1/4355 +f 4358/1/4358 4354/1/4354 4355/1/4355 +f 4358/1/4358 4355/1/4355 4359/1/4359 +f 4363/1/4363 4358/1/4358 4359/1/4359 +f 4362/1/4362 4358/1/4358 4363/1/4363 +f 4366/1/4366 4362/1/4362 4363/1/4363 +f 4366/1/4366 4363/1/4363 4364/1/4364 +f 4367/1/4367 4362/1/4362 4366/1/4366 +f 2922/1/2922 4367/1/4367 4366/1/4366 +f 2922/1/2922 4366/1/4366 2925/1/2925 +f 2921/1/2921 4367/1/4367 2922/1/2922 +f 2920/1/2920 2921/1/2921 2922/1/2922 +f 2920/1/2920 2922/1/2922 2923/1/2923 +f 2918/1/2918 2921/1/2921 2920/1/2920 +f 2919/1/2919 2918/1/2918 2920/1/2920 +f 2919/1/2919 2920/1/2920 2924/1/2924 +f 2916/1/2916 2918/1/2918 2919/1/2919 +f 2935/1/2935 2916/1/2916 2919/1/2919 +f 2935/1/2935 2919/1/2919 2933/1/2933 +f 2933/1/2933 2936/1/2936 2935/1/2935 +f 2935/1/2935 2936/1/2936 2940/1/2940 +f 2935/1/2935 2940/1/2940 2941/1/2941 +f 2941/1/2941 2940/1/2940 2944/1/2944 +f 2944/1/2944 2916/1/2916 2941/1/2941 +f 2945/1/2945 2916/1/2916 2944/1/2944 +f 2944/1/2944 2943/1/2943 2945/1/2945 +f 2945/1/2945 2943/1/2943 2947/1/2947 +f 2947/1/2947 2910/1/2910 2945/1/2945 +f 2911/1/2911 2910/1/2910 2947/1/2947 +f 2947/1/2947 2905/1/2905 2911/1/2911 +f 2911/1/2911 2905/1/2905 2908/1/2908 +f 2908/1/2908 2905/1/2905 2902/1/2902 +f 2908/1/2908 2902/1/2902 2900/1/2900 +f 2900/1/2900 2909/1/2909 2908/1/2908 +f 2908/1/2908 2909/1/2909 2910/1/2910 +f 2909/1/2909 2913/1/2913 2910/1/2910 +f 2910/1/2910 2913/1/2913 2915/1/2915 +f 2910/1/2910 2915/1/2915 2916/1/2916 +f 2913/1/2913 4284/1/4284 2915/1/2915 +f 2915/1/2915 4284/1/4284 2917/1/2917 +f 2915/1/2915 2917/1/2917 2918/1/2918 +f 4284/1/4284 4289/1/4289 2917/1/2917 +f 2917/1/2917 4289/1/4289 4322/1/4322 +f 2917/1/2917 4322/1/4322 4323/1/4323 +f 2917/1/2917 4323/1/4323 2921/1/2921 +f 2921/1/2921 4323/1/4323 4369/1/4369 +f 4323/1/4323 4331/1/4331 4369/1/4369 +f 4369/1/4369 4331/1/4331 4368/1/4368 +f 4369/1/4369 4368/1/4368 4367/1/4367 +f 4331/1/4331 4332/1/4332 4368/1/4368 +f 4368/1/4368 4332/1/4332 4361/1/4361 +f 4368/1/4368 4361/1/4361 4362/1/4362 +f 4362/1/4362 4361/1/4361 4360/1/4360 +f 4361/1/4361 4338/1/4338 4360/1/4360 +f 4338/1/4338 4354/1/4354 4360/1/4360 +f 4338/1/4338 4353/1/4353 4354/1/4354 +f 4338/1/4338 4339/1/4339 4353/1/4353 +f 4339/1/4339 4340/1/4340 4353/1/4353 +f 4353/1/4353 4340/1/4340 4346/1/4346 +f 4353/1/4353 4346/1/4346 4351/1/4351 +f 4340/1/4340 4345/1/4345 4346/1/4346 +f 4346/1/4346 4345/1/4345 4347/1/4347 +f 4347/1/4347 4345/1/4345 4348/1/4348 +f 4340/1/4340 4344/1/4344 4345/1/4345 +f 4344/1/4344 2956/1/2956 4345/1/4345 +f 4345/1/4345 2956/1/2956 2958/1/2958 +f 4344/1/4344 2953/1/2953 2956/1/2956 +f 2953/1/2953 2954/1/2954 2956/1/2956 +f 2956/1/2956 2954/1/2954 2955/1/2955 +f 2954/1/2954 2937/1/2937 2955/1/2955 +f 2955/1/2955 2937/1/2937 2957/1/2957 +f 2957/1/2957 2937/1/2937 2938/1/2938 +f 2957/1/2957 2938/1/2938 2960/1/2960 +f 2937/1/2937 2934/1/2934 2938/1/2938 +f 2938/1/2938 2934/1/2934 2932/1/2932 +f 2938/1/2938 2932/1/2932 2961/1/2961 +f 2961/1/2961 2932/1/2932 2931/1/2931 +f 2932/1/2932 2934/1/2934 2930/1/2930 +f 2928/1/2928 2932/1/2932 2930/1/2930 +f 2930/1/2930 2919/1/2919 2928/1/2928 +f 2930/1/2930 2934/1/2934 2933/1/2933 +f 2937/1/2937 2936/1/2936 2934/1/2934 +f 2937/1/2937 2939/1/2939 2936/1/2936 +f 2954/1/2954 2939/1/2939 2937/1/2937 +f 2950/1/2950 2939/1/2939 2954/1/2954 +f 2950/1/2950 2948/1/2948 2939/1/2939 +f 2948/1/2948 2942/1/2942 2939/1/2939 +f 2942/1/2942 2940/1/2940 2939/1/2939 +f 2942/1/2942 2943/1/2943 2940/1/2940 +f 2946/1/2946 2943/1/2943 2942/1/2942 +f 2946/1/2946 2905/1/2905 2943/1/2943 +f 2906/1/2906 2905/1/2905 2946/1/2946 +f 2906/1/2906 2946/1/2946 2948/1/2948 +f 2949/1/2949 2906/1/2906 2948/1/2948 +f 2949/1/2949 2907/1/2907 2906/1/2906 +f 2907/1/2907 2901/1/2901 2906/1/2906 +f 2904/1/2904 2901/1/2901 2907/1/2907 +f 2951/1/2951 2904/1/2904 2907/1/2907 +f 3123/1/3123 2904/1/2904 2951/1/2951 +f 3122/1/3122 3123/1/3123 2951/1/2951 +f 3122/1/3122 2951/1/2951 2952/1/2952 +f 3134/1/3134 3122/1/3122 2952/1/2952 +f 3134/1/3134 2952/1/2952 3138/1/3138 +f 4309/1/4309 3134/1/3134 3138/1/3138 +f 4309/1/4309 3138/1/3138 4312/1/4312 +f 4311/1/4311 4309/1/4309 4312/1/4312 +f 4311/1/4311 4312/1/4312 4343/1/4343 +f 4317/1/4317 4311/1/4311 4343/1/4343 +f 4317/1/4317 4343/1/4343 4328/1/4328 +f 4319/1/4319 4317/1/4317 4328/1/4328 +f 4319/1/4319 4328/1/4328 4325/1/4325 +f 4321/1/4321 4319/1/4319 4325/1/4325 +f 4321/1/4321 4325/1/4325 4324/1/4324 +f 4322/1/4322 4321/1/4321 4324/1/4324 +f 4322/1/4322 4318/1/4318 4321/1/4321 +f 4324/1/4324 4325/1/4325 4327/1/4327 +f 4324/1/4324 4327/1/4327 4326/1/4326 +f 4323/1/4323 4324/1/4324 4326/1/4326 +f 4326/1/4326 4327/1/4327 4330/1/4330 +f 4326/1/4326 4330/1/4330 4331/1/4331 +f 4327/1/4327 4329/1/4329 4330/1/4330 +f 4329/1/4329 4334/1/4334 4330/1/4330 +f 4330/1/4330 4334/1/4334 4333/1/4333 +f 4330/1/4330 4333/1/4333 4332/1/4332 +f 4332/1/4332 4333/1/4333 4338/1/4338 +f 4334/1/4334 4337/1/4337 4333/1/4333 +f 4333/1/4333 4337/1/4337 4339/1/4339 +f 4334/1/4334 4336/1/4336 4337/1/4337 +f 4336/1/4336 4341/1/4341 4337/1/4337 +f 4337/1/4337 4341/1/4341 4340/1/4340 +f 4336/1/4336 4342/1/4342 4341/1/4341 +f 4342/1/4342 4344/1/4344 4341/1/4341 +f 4342/1/4342 3138/1/3138 4344/1/4344 +f 4335/1/4335 4342/1/4342 4336/1/4336 +f 4329/1/4329 4335/1/4335 4336/1/4336 +f 4328/1/4328 4335/1/4335 4329/1/4329 +f 4343/1/4343 4342/1/4342 4335/1/4335 +f 4329/1/4329 4336/1/4336 4334/1/4334 +f 4325/1/4325 4329/1/4329 4327/1/4327 +f 4318/1/4318 4319/1/4319 4321/1/4321 +f 4318/1/4318 4316/1/4316 4319/1/4319 +f 4320/1/4320 4316/1/4316 4318/1/4318 +f 4289/1/4289 4320/1/4320 4318/1/4318 +f 4289/1/4289 4288/1/4288 4320/1/4320 +f 4288/1/4288 4315/1/4315 4320/1/4320 +f 4288/1/4288 4296/1/4296 4315/1/4315 +f 4296/1/4296 4313/1/4313 4315/1/4315 +f 4315/1/4315 4313/1/4313 4316/1/4316 +f 4313/1/4313 4314/1/4314 4316/1/4316 +f 4316/1/4316 4314/1/4314 4317/1/4317 +f 4313/1/4313 4310/1/4310 4314/1/4314 +f 4314/1/4314 4310/1/4310 4311/1/4311 +f 4313/1/4313 4308/1/4308 4310/1/4310 +f 4308/1/4308 4309/1/4309 4310/1/4310 +f 4308/1/4308 4306/1/4306 4309/1/4309 +f 4298/1/4298 4306/1/4306 4308/1/4308 +f 4295/1/4295 4298/1/4298 4308/1/4308 +f 4294/1/4294 4298/1/4298 4295/1/4295 +f 4292/1/4292 4294/1/4294 4295/1/4295 +f 4292/1/4292 4295/1/4295 4296/1/4296 +f 4287/1/4287 4292/1/4292 4296/1/4296 +f 4286/1/4286 4292/1/4292 4287/1/4287 +f 4285/1/4285 4286/1/4286 4287/1/4287 +f 4285/1/4285 4287/1/4287 4288/1/4288 +f 4282/1/4282 4286/1/4286 4285/1/4285 +f 4283/1/4283 4282/1/4282 4285/1/4285 +f 4283/1/4283 4285/1/4285 4284/1/4284 +f 4281/1/4281 4282/1/4282 4283/1/4283 +f 2912/1/2912 4281/1/4281 4283/1/4283 +f 2912/1/2912 4283/1/4283 2913/1/2913 +f 2914/1/2914 4281/1/4281 2912/1/2912 +f 2888/1/2888 2914/1/2914 2912/1/2912 +f 2888/1/2888 2912/1/2912 2909/1/2909 +f 2891/1/2891 2914/1/2914 2888/1/2888 +f 2887/1/2887 2891/1/2891 2888/1/2888 +f 2887/1/2887 2888/1/2888 2889/1/2889 +f 2889/1/2889 2892/1/2892 2887/1/2887 +f 2887/1/2887 2892/1/2892 2893/1/2893 +f 2887/1/2887 2893/1/2893 2890/1/2890 +f 2890/1/2890 2893/1/2893 3139/1/3139 +f 3139/1/3139 2891/1/2891 2890/1/2890 +f 4155/1/4155 2891/1/2891 3139/1/3139 +f 3139/1/3139 3132/1/3132 4155/1/4155 +f 4155/1/4155 3132/1/3132 4156/1/4156 +f 4156/1/4156 4152/1/4152 4155/1/4155 +f 4157/1/4157 4152/1/4152 4156/1/4156 +f 4156/1/4156 4158/1/4158 4157/1/4157 +f 4157/1/4157 4158/1/4158 4151/1/4151 +f 4151/1/4151 4158/1/4158 4148/1/4148 +f 4151/1/4151 4148/1/4148 4149/1/4149 +f 4149/1/4149 4150/1/4150 4151/1/4151 +f 4151/1/4151 4150/1/4150 4152/1/4152 +f 4150/1/4150 4153/1/4153 4152/1/4152 +f 4152/1/4152 4153/1/4153 4154/1/4154 +f 4152/1/4152 4154/1/4154 2891/1/2891 +f 4153/1/4153 2693/1/2693 4154/1/4154 +f 4154/1/4154 2693/1/2693 4280/1/4280 +f 4154/1/4154 4280/1/4280 2914/1/2914 +f 2693/1/2693 2694/1/2694 4280/1/4280 +f 4280/1/4280 2694/1/2694 2698/1/2698 +f 4280/1/4280 2698/1/2698 4277/1/4277 +f 4280/1/4280 4277/1/4277 4281/1/4281 +f 4281/1/4281 4277/1/4277 4274/1/4274 +f 4277/1/4277 4271/1/4271 4274/1/4274 +f 4274/1/4274 4271/1/4271 4275/1/4275 +f 4274/1/4274 4275/1/4275 4282/1/4282 +f 4271/1/4271 4273/1/4273 4275/1/4275 +f 4275/1/4275 4273/1/4273 4290/1/4290 +f 4275/1/4275 4290/1/4290 4286/1/4286 +f 4286/1/4286 4290/1/4290 4291/1/4291 +f 4290/1/4290 4293/1/4293 4291/1/4291 +f 4293/1/4293 4294/1/4294 4291/1/4291 +f 4293/1/4293 4297/1/4297 4294/1/4294 +f 4293/1/4293 4299/1/4299 4297/1/4297 +f 4299/1/4299 4303/1/4303 4297/1/4297 +f 4297/1/4297 4303/1/4303 4307/1/4307 +f 4297/1/4297 4307/1/4307 4298/1/4298 +f 4303/1/4303 3133/1/3133 4307/1/4307 +f 4307/1/4307 3133/1/3133 4306/1/4306 +f 4306/1/4306 3133/1/3133 3134/1/3134 +f 4303/1/4303 2721/1/2721 3133/1/3133 +f 2721/1/2721 3124/1/3124 3133/1/3133 +f 3133/1/3133 3124/1/3124 3122/1/3122 +f 2721/1/2721 3126/1/3126 3124/1/3124 +f 3126/1/3126 3125/1/3125 3124/1/3124 +f 3124/1/3124 3125/1/3125 3123/1/3123 +f 3125/1/3125 2897/1/2897 3123/1/3123 +f 3123/1/3123 2897/1/2897 2903/1/2903 +f 2903/1/2903 2897/1/2897 2898/1/2898 +f 2903/1/2903 2898/1/2898 2904/1/2904 +f 2897/1/2897 2895/1/2895 2898/1/2898 +f 2898/1/2898 2895/1/2895 2899/1/2899 +f 2898/1/2898 2899/1/2899 2901/1/2901 +f 2901/1/2901 2899/1/2899 2902/1/2902 +f 2899/1/2899 2895/1/2895 2894/1/2894 +f 2900/1/2900 2899/1/2899 2894/1/2894 +f 2894/1/2894 2888/1/2888 2900/1/2900 +f 2894/1/2894 2895/1/2895 2889/1/2889 +f 2897/1/2897 2892/1/2892 2895/1/2895 +f 2897/1/2897 2896/1/2896 2892/1/2892 +f 3125/1/3125 2896/1/2896 2897/1/2897 +f 3127/1/3127 2896/1/2896 3125/1/3125 +f 3127/1/3127 3129/1/3129 2896/1/2896 +f 3129/1/3129 3128/1/3128 2896/1/2896 +f 3128/1/3128 2893/1/2893 2896/1/2896 +f 3128/1/3128 3132/1/3132 2893/1/2893 +f 3131/1/3131 3132/1/3132 3128/1/3128 +f 3131/1/3131 4158/1/4158 3132/1/3132 +f 4159/1/4159 4158/1/4158 3131/1/3131 +f 4159/1/4159 3131/1/3131 3129/1/3129 +f 3130/1/3130 4159/1/4159 3129/1/3129 +f 3130/1/3130 4160/1/4160 4159/1/4159 +f 4160/1/4160 4147/1/4147 4159/1/4159 +f 4146/1/4146 4147/1/4147 4160/1/4160 +f 4161/1/4161 4146/1/4146 4160/1/4160 +f 4145/1/4145 4146/1/4146 4161/1/4161 +f 3136/1/3136 4145/1/4145 4161/1/4161 +f 3136/1/3136 4161/1/4161 3135/1/3135 +f 2723/1/2723 3136/1/3136 3135/1/3135 +f 2723/1/2723 3135/1/3135 2720/1/2720 +f 2711/1/2711 2723/1/2723 2720/1/2720 +f 2711/1/2711 2720/1/2720 2717/1/2717 +f 2713/1/2713 2711/1/2711 2717/1/2717 +f 2713/1/2713 2717/1/2717 2715/1/2715 +f 2714/1/2714 2713/1/2713 2715/1/2715 +f 2714/1/2714 2715/1/2715 2716/1/2716 +f 2702/1/2702 2714/1/2714 2716/1/2716 +f 2702/1/2702 2716/1/2716 2704/1/2704 +f 2703/1/2703 2702/1/2702 2704/1/2704 +f 2703/1/2703 2704/1/2704 4279/1/4279 +f 2698/1/2698 2703/1/2703 4279/1/4279 +f 2698/1/2698 2697/1/2697 2703/1/2703 +f 4279/1/4279 2704/1/2704 4278/1/4278 +f 4279/1/4279 4278/1/4278 4276/1/4276 +f 4277/1/4277 4279/1/4279 4276/1/4276 +f 4276/1/4276 4278/1/4278 4272/1/4272 +f 4276/1/4276 4272/1/4272 4271/1/4271 +f 4278/1/4278 4305/1/4305 4272/1/4272 +f 4305/1/4305 4301/1/4301 4272/1/4272 +f 4272/1/4272 4301/1/4301 4300/1/4300 +f 4272/1/4272 4300/1/4300 4273/1/4273 +f 4273/1/4273 4300/1/4300 4293/1/4293 +f 4301/1/4301 4302/1/4302 4300/1/4300 +f 4300/1/4300 4302/1/4302 4299/1/4299 +f 4301/1/4301 4304/1/4304 4302/1/4302 +f 4304/1/4304 2722/1/2722 4302/1/4302 +f 4302/1/4302 2722/1/2722 4303/1/4303 +f 4304/1/4304 2718/1/2718 2722/1/2722 +f 2718/1/2718 2721/1/2721 2722/1/2722 +f 2718/1/2718 2720/1/2720 2721/1/2721 +f 2719/1/2719 2718/1/2718 4304/1/4304 +f 4305/1/4305 2719/1/2719 4304/1/4304 +f 2716/1/2716 2719/1/2719 4305/1/4305 +f 2715/1/2715 2718/1/2718 2719/1/2719 +f 4305/1/4305 4304/1/4304 4301/1/4301 +f 2704/1/2704 4305/1/4305 4278/1/4278 +f 2697/1/2697 2702/1/2702 2703/1/2703 +f 2697/1/2697 2701/1/2701 2702/1/2702 +f 2696/1/2696 2701/1/2701 2697/1/2697 +f 2694/1/2694 2696/1/2696 2697/1/2697 +f 2694/1/2694 2695/1/2695 2696/1/2696 +f 2695/1/2695 2700/1/2700 2696/1/2696 +f 2695/1/2695 2699/1/2699 2700/1/2700 +f 2699/1/2699 2708/1/2708 2700/1/2700 +f 2700/1/2700 2708/1/2708 2701/1/2701 +f 2708/1/2708 2709/1/2709 2701/1/2701 +f 2701/1/2701 2709/1/2709 2714/1/2714 +f 2708/1/2708 2710/1/2710 2709/1/2709 +f 2709/1/2709 2710/1/2710 2713/1/2713 +f 2708/1/2708 2707/1/2707 2710/1/2710 +f 2707/1/2707 2711/1/2711 2710/1/2710 +f 2707/1/2707 2712/1/2712 2711/1/2711 +f 2706/1/2706 2712/1/2712 2707/1/2707 +f 2705/1/2705 2706/1/2706 2707/1/2707 +f 2681/1/2681 2706/1/2706 2705/1/2705 +f 2686/1/2686 2681/1/2681 2705/1/2705 +f 2686/1/2686 2705/1/2705 2699/1/2699 +f 2687/1/2687 2686/1/2686 2699/1/2699 +f 2685/1/2685 2686/1/2686 2687/1/2687 +f 2688/1/2688 2685/1/2685 2687/1/2687 +f 2688/1/2688 2687/1/2687 2695/1/2695 +f 2684/1/2684 2685/1/2685 2688/1/2688 +f 2690/1/2690 2684/1/2684 2688/1/2688 +f 2690/1/2690 2688/1/2688 2693/1/2693 +f 2689/1/2689 2684/1/2684 2690/1/2690 +f 2692/1/2692 2689/1/2689 2690/1/2690 +f 2692/1/2692 2690/1/2690 4153/1/4153 +f 2691/1/2691 2689/1/2689 2692/1/2692 +f 4132/1/4132 2691/1/2691 2692/1/2692 +f 4132/1/4132 2692/1/2692 4150/1/4150 +f 4125/1/4125 2691/1/2691 4132/1/4132 +f 4131/1/4131 4125/1/4125 4132/1/4132 +f 4131/1/4131 4132/1/4132 4140/1/4140 +f 4140/1/4140 4134/1/4134 4131/1/4131 +f 4131/1/4131 4134/1/4134 4129/1/4129 +f 4131/1/4131 4129/1/4129 4130/1/4130 +f 4130/1/4130 4129/1/4129 4126/1/4126 +f 4126/1/4126 4125/1/4125 4130/1/4130 +f 4123/1/4123 4125/1/4125 4126/1/4126 +f 4126/1/4126 4124/1/4124 4123/1/4123 +f 4123/1/4123 4124/1/4124 4122/1/4122 +f 4122/1/4122 4119/1/4119 4123/1/4123 +f 4120/1/4120 4119/1/4119 4122/1/4122 +f 4122/1/4122 4121/1/4121 4120/1/4120 +f 4120/1/4120 4121/1/4121 4118/1/4118 +f 4118/1/4118 4121/1/4121 4115/1/4115 +f 4118/1/4118 4115/1/4115 4116/1/4116 +f 4116/1/4116 4117/1/4117 4118/1/4118 +f 4118/1/4118 4117/1/4117 4119/1/4119 +f 4117/1/4117 2725/1/2725 4119/1/4119 +f 4119/1/4119 2725/1/2725 2724/1/2724 +f 4119/1/4119 2724/1/2724 4125/1/4125 +f 2725/1/2725 2650/1/2650 2724/1/2724 +f 2724/1/2724 2650/1/2650 2651/1/2651 +f 2724/1/2724 2651/1/2651 2691/1/2691 +f 2650/1/2650 2645/1/2645 2651/1/2651 +f 2651/1/2651 2645/1/2645 2649/1/2649 +f 2651/1/2651 2649/1/2649 2655/1/2655 +f 2651/1/2651 2655/1/2655 2689/1/2689 +f 2649/1/2649 2654/1/2654 2655/1/2655 +f 2655/1/2655 2654/1/2654 2661/1/2661 +f 2655/1/2655 2661/1/2661 2682/1/2682 +f 2655/1/2655 2682/1/2682 2684/1/2684 +f 2684/1/2684 2682/1/2682 2683/1/2683 +f 2682/1/2682 2678/1/2678 2683/1/2683 +f 2683/1/2683 2678/1/2678 2679/1/2679 +f 2683/1/2683 2679/1/2679 2685/1/2685 +f 2685/1/2685 2679/1/2679 2680/1/2680 +f 2679/1/2679 2677/1/2677 2680/1/2680 +f 2677/1/2677 2681/1/2681 2680/1/2680 +f 2677/1/2677 2674/1/2674 2681/1/2681 +f 2677/1/2677 2672/1/2672 2674/1/2674 +f 2672/1/2672 2671/1/2671 2674/1/2674 +f 2674/1/2674 2671/1/2671 2675/1/2675 +f 2674/1/2674 2675/1/2675 2706/1/2706 +f 2671/1/2671 2676/1/2676 2675/1/2675 +f 2675/1/2675 2676/1/2676 2712/1/2712 +f 2712/1/2712 2676/1/2676 2723/1/2723 +f 2671/1/2671 2673/1/2673 2676/1/2676 +f 2673/1/2673 3137/1/3137 2676/1/2676 +f 2676/1/2676 3137/1/3137 3136/1/3136 +f 2673/1/2673 4092/1/4092 3137/1/3137 +f 4092/1/4092 4137/1/4137 3137/1/3137 +f 3137/1/3137 4137/1/4137 4145/1/4145 +f 4137/1/4137 4138/1/4138 4145/1/4145 +f 4145/1/4145 4138/1/4138 4144/1/4144 +f 4144/1/4144 4138/1/4138 4142/1/4142 +f 4144/1/4144 4142/1/4142 4146/1/4146 +f 4138/1/4138 4139/1/4139 4142/1/4142 +f 4142/1/4142 4139/1/4139 4143/1/4143 +f 4142/1/4142 4143/1/4143 4147/1/4147 +f 4147/1/4147 4143/1/4143 4148/1/4148 +f 4143/1/4143 4139/1/4139 4141/1/4141 +f 4149/1/4149 4143/1/4143 4141/1/4141 +f 4141/1/4141 4132/1/4132 4149/1/4149 +f 4141/1/4141 4139/1/4139 4140/1/4140 +f 4138/1/4138 4134/1/4134 4139/1/4139 +f 4138/1/4138 4133/1/4133 4134/1/4134 +f 4137/1/4137 4133/1/4133 4138/1/4138 +f 4136/1/4136 4133/1/4133 4137/1/4137 +f 4136/1/4136 4135/1/4135 4133/1/4133 +f 4135/1/4135 4128/1/4128 4133/1/4133 +f 4128/1/4128 4129/1/4129 4133/1/4133 +f 4128/1/4128 4124/1/4124 4129/1/4129 +f 4127/1/4127 4124/1/4124 4128/1/4128 +f 4127/1/4127 4121/1/4121 4124/1/4124 +f 4162/1/4162 4121/1/4121 4127/1/4127 +f 4162/1/4162 4127/1/4127 4135/1/4135 +f 4094/1/4094 4162/1/4162 4135/1/4135 +f 4094/1/4094 4096/1/4096 4162/1/4162 +f 4096/1/4096 4114/1/4114 4162/1/4162 +f 4095/1/4095 4114/1/4114 4096/1/4096 +f 4093/1/4093 4095/1/4095 4096/1/4096 +f 4097/1/4097 4095/1/4095 4093/1/4093 +f 4090/1/4090 4097/1/4097 4093/1/4093 +f 4090/1/4090 4093/1/4093 4091/1/4091 +f 2871/1/2871 4090/1/4090 4091/1/4091 +f 2871/1/2871 4091/1/4091 2876/1/2876 +f 2872/1/2872 2871/1/2871 2876/1/2876 +f 2872/1/2872 2876/1/2876 2875/1/2875 +f 2874/1/2874 2872/1/2872 2875/1/2875 +f 2874/1/2874 2875/1/2875 2666/1/2666 +f 2657/1/2657 2874/1/2874 2666/1/2666 +f 2657/1/2657 2666/1/2666 2658/1/2658 +f 2652/1/2652 2657/1/2657 2658/1/2658 +f 2652/1/2652 2658/1/2658 2656/1/2656 +f 2653/1/2653 2652/1/2652 2656/1/2656 +f 2653/1/2653 2656/1/2656 2654/1/2654 +f 2654/1/2654 2656/1/2656 2659/1/2659 +f 2656/1/2656 2660/1/2660 2659/1/2659 +f 2659/1/2659 2660/1/2660 2662/1/2662 +f 2661/1/2661 2659/1/2659 2662/1/2662 +f 2660/1/2660 2664/1/2664 2662/1/2662 +f 2662/1/2662 2664/1/2664 2670/1/2670 +f 2662/1/2662 2670/1/2670 2678/1/2678 +f 2678/1/2678 2670/1/2670 2677/1/2677 +f 2664/1/2664 2669/1/2669 2670/1/2670 +f 2670/1/2670 2669/1/2669 2672/1/2672 +f 2664/1/2664 2665/1/2665 2669/1/2669 +f 2665/1/2665 2668/1/2668 2669/1/2669 +f 2669/1/2669 2668/1/2668 2671/1/2671 +f 2665/1/2665 2667/1/2667 2668/1/2668 +f 2667/1/2667 2673/1/2673 2668/1/2668 +f 2667/1/2667 2876/1/2876 2673/1/2673 +f 2663/1/2663 2667/1/2667 2665/1/2665 +f 2660/1/2660 2663/1/2663 2665/1/2665 +f 2658/1/2658 2663/1/2663 2660/1/2660 +f 2666/1/2666 2667/1/2667 2663/1/2663 +f 2660/1/2660 2665/1/2665 2664/1/2664 +f 2648/1/2648 2652/1/2652 2653/1/2653 +f 2649/1/2649 2648/1/2648 2653/1/2653 +f 2648/1/2648 2647/1/2647 2652/1/2652 +f 2646/1/2646 2647/1/2647 2648/1/2648 +f 2645/1/2645 2646/1/2646 2648/1/2648 +f 2645/1/2645 2643/1/2643 2646/1/2646 +f 2643/1/2643 2642/1/2642 2646/1/2646 +f 2643/1/2643 2637/1/2637 2642/1/2642 +f 2637/1/2637 2635/1/2635 2642/1/2642 +f 2642/1/2642 2635/1/2635 2647/1/2647 +f 2635/1/2635 2877/1/2877 2647/1/2647 +f 2647/1/2647 2877/1/2877 2657/1/2657 +f 2635/1/2635 2873/1/2873 2877/1/2877 +f 2877/1/2877 2873/1/2873 2874/1/2874 +f 2635/1/2635 2634/1/2634 2873/1/2873 +f 2634/1/2634 2872/1/2872 2873/1/2873 +f 2634/1/2634 2870/1/2870 2872/1/2872 +f 2633/1/2633 2870/1/2870 2634/1/2634 +f 2632/1/2632 2633/1/2633 2634/1/2634 +f 2638/1/2638 2633/1/2633 2632/1/2632 +f 2636/1/2636 2638/1/2638 2632/1/2632 +f 2636/1/2636 2632/1/2632 2637/1/2637 +f 2641/1/2641 2636/1/2636 2637/1/2637 +f 2640/1/2640 2636/1/2636 2641/1/2641 +f 2644/1/2644 2640/1/2640 2641/1/2641 +f 2644/1/2644 2641/1/2641 2643/1/2643 +f 2844/1/2844 2640/1/2640 2644/1/2644 +f 2726/1/2726 2844/1/2844 2644/1/2644 +f 2726/1/2726 2644/1/2644 2650/1/2650 +f 2730/1/2730 2844/1/2844 2726/1/2726 +f 2727/1/2727 2730/1/2730 2726/1/2726 +f 2727/1/2727 2726/1/2726 2725/1/2725 +f 2729/1/2729 2730/1/2730 2727/1/2727 +f 2728/1/2728 2729/1/2729 2727/1/2727 +f 2728/1/2728 2727/1/2727 4117/1/4117 +f 2731/1/2731 2729/1/2729 2728/1/2728 +f 4110/1/4110 2731/1/2731 2728/1/2728 +f 4110/1/4110 2728/1/2728 4109/1/4109 +f 4109/1/4109 4106/1/4106 4110/1/4110 +f 4110/1/4110 4106/1/4106 4105/1/4105 +f 4110/1/4110 4105/1/4105 4163/1/4163 +f 4163/1/4163 4105/1/4105 2843/1/2843 +f 2843/1/2843 2731/1/2731 4163/1/4163 +f 2840/1/2840 2731/1/2731 2843/1/2843 +f 2843/1/2843 2842/1/2842 2840/1/2840 +f 2840/1/2840 2842/1/2842 2841/1/2841 +f 2841/1/2841 2733/1/2733 2840/1/2840 +f 2839/1/2839 2733/1/2733 2841/1/2841 +f 2841/1/2841 2826/1/2826 2839/1/2839 +f 2839/1/2839 2826/1/2826 2742/1/2742 +f 2742/1/2742 2826/1/2826 2824/1/2824 +f 2742/1/2742 2824/1/2824 2741/1/2741 +f 2741/1/2741 2737/1/2737 2742/1/2742 +f 2742/1/2742 2737/1/2737 2733/1/2733 +f 2737/1/2737 2734/1/2734 2733/1/2733 +f 2733/1/2733 2734/1/2734 2732/1/2732 +f 2733/1/2733 2732/1/2732 2731/1/2731 +f 2734/1/2734 2735/1/2735 2732/1/2732 +f 2732/1/2732 2735/1/2735 2736/1/2736 +f 2732/1/2732 2736/1/2736 2729/1/2729 +f 2735/1/2735 2885/1/2885 2736/1/2736 +f 2736/1/2736 2885/1/2885 2884/1/2884 +f 2736/1/2736 2884/1/2884 2847/1/2847 +f 2736/1/2736 2847/1/2847 2730/1/2730 +f 2730/1/2730 2847/1/2847 2846/1/2846 +f 2847/1/2847 2848/1/2848 2846/1/2846 +f 2846/1/2846 2848/1/2848 2845/1/2845 +f 2846/1/2846 2845/1/2845 2844/1/2844 +f 2848/1/2848 2849/1/2849 2845/1/2845 +f 2845/1/2845 2849/1/2849 2850/1/2850 +f 2845/1/2845 2850/1/2850 2640/1/2640 +f 2640/1/2640 2850/1/2850 2639/1/2639 +f 2850/1/2850 2851/1/2851 2639/1/2639 +f 2851/1/2851 2638/1/2638 2639/1/2639 +f 2851/1/2851 2861/1/2861 2638/1/2638 +f 2851/1/2851 2858/1/2858 2861/1/2861 +f 2858/1/2858 2860/1/2860 2861/1/2861 +f 2861/1/2861 2860/1/2860 2867/1/2867 +f 2861/1/2861 2867/1/2867 2633/1/2633 +f 2860/1/2860 2869/1/2869 2867/1/2867 +f 2867/1/2867 2869/1/2869 2870/1/2870 +f 2870/1/2870 2869/1/2869 2871/1/2871 +f 2860/1/2860 2868/1/2868 2869/1/2869 +f 2868/1/2868 4089/1/4089 2869/1/2869 +f 2869/1/2869 4089/1/4089 4090/1/4090 +f 2868/1/2868 4086/1/4086 4089/1/4089 +f 4086/1/4086 4100/1/4100 4089/1/4089 +f 4089/1/4089 4100/1/4100 4097/1/4097 +f 4100/1/4100 4098/1/4098 4097/1/4097 +f 4097/1/4097 4098/1/4098 4099/1/4099 +f 4099/1/4099 4098/1/4098 4111/1/4111 +f 4099/1/4099 4111/1/4111 4095/1/4095 +f 4098/1/4098 4108/1/4108 4111/1/4111 +f 4111/1/4111 4108/1/4108 4112/1/4112 +f 4111/1/4111 4112/1/4112 4114/1/4114 +f 4114/1/4114 4112/1/4112 4115/1/4115 +f 4112/1/4112 4108/1/4108 4113/1/4113 +f 4116/1/4116 4112/1/4112 4113/1/4113 +f 4113/1/4113 2728/1/2728 4116/1/4116 +f 4113/1/4113 4108/1/4108 4109/1/4109 +f 4098/1/4098 4106/1/4106 4108/1/4108 +f 4098/1/4098 4102/1/4102 4106/1/4106 +f 4100/1/4100 4102/1/4102 4098/1/4098 +f 4101/1/4101 4102/1/4102 4100/1/4100 +f 4101/1/4101 4103/1/4103 4102/1/4102 +f 4103/1/4103 4104/1/4104 4102/1/4102 +f 4104/1/4104 4105/1/4105 4102/1/4102 +f 4104/1/4104 2842/1/2842 4105/1/4105 +f 4107/1/4107 2842/1/2842 4104/1/4104 +f 4107/1/4107 2826/1/2826 2842/1/2842 +f 2829/1/2829 2826/1/2826 4107/1/4107 +f 2829/1/2829 4107/1/4107 4103/1/4103 +f 2833/1/2833 2829/1/2829 4103/1/4103 +f 2833/1/2833 2828/1/2828 2829/1/2829 +f 2828/1/2828 2825/1/2825 2829/1/2829 +f 2827/1/2827 2825/1/2825 2828/1/2828 +f 2830/1/2830 2827/1/2827 2828/1/2828 +f 2832/1/2832 2827/1/2827 2830/1/2830 +f 2834/1/2834 2832/1/2832 2830/1/2830 +f 2834/1/2834 2830/1/2830 2835/1/2835 +f 4082/1/4082 2834/1/2834 2835/1/2835 +f 4082/1/4082 2835/1/2835 4085/1/4085 +f 4083/1/4083 4082/1/4082 4085/1/4085 +f 4083/1/4083 4085/1/4085 4087/1/4087 +f 4164/1/4164 4083/1/4083 4087/1/4087 +f 4164/1/4164 4087/1/4087 4088/1/4088 +f 2880/1/2880 4164/1/4164 4088/1/4088 +f 2880/1/2880 4088/1/4088 2866/1/2866 +f 2879/1/2879 2880/1/2880 2866/1/2866 +f 2879/1/2879 2866/1/2866 2878/1/2878 +f 2881/1/2881 2879/1/2879 2878/1/2878 +f 2881/1/2881 2878/1/2878 2883/1/2883 +f 2884/1/2884 2881/1/2881 2883/1/2883 +f 2884/1/2884 2882/1/2882 2881/1/2881 +f 2883/1/2883 2878/1/2878 2855/1/2855 +f 2883/1/2883 2855/1/2855 2854/1/2854 +f 2847/1/2847 2883/1/2883 2854/1/2854 +f 2854/1/2854 2855/1/2855 2852/1/2852 +f 2854/1/2854 2852/1/2852 2848/1/2848 +f 2855/1/2855 2856/1/2856 2852/1/2852 +f 2856/1/2856 2857/1/2857 2852/1/2852 +f 2852/1/2852 2857/1/2857 2853/1/2853 +f 2852/1/2852 2853/1/2853 2849/1/2849 +f 2849/1/2849 2853/1/2853 2851/1/2851 +f 2857/1/2857 2859/1/2859 2853/1/2853 +f 2853/1/2853 2859/1/2859 2858/1/2858 +f 2857/1/2857 2862/1/2862 2859/1/2859 +f 2862/1/2862 2863/1/2863 2859/1/2859 +f 2859/1/2859 2863/1/2863 2860/1/2860 +f 2862/1/2862 2865/1/2865 2863/1/2863 +f 2865/1/2865 2868/1/2868 2863/1/2863 +f 2865/1/2865 4085/1/4085 2868/1/2868 +f 2864/1/2864 2865/1/2865 2862/1/2862 +f 2856/1/2856 2864/1/2864 2862/1/2862 +f 2866/1/2866 2864/1/2864 2856/1/2856 +f 4088/1/4088 2865/1/2865 2864/1/2864 +f 2856/1/2856 2862/1/2862 2857/1/2857 +f 2878/1/2878 2856/1/2856 2855/1/2855 +f 2882/1/2882 2879/1/2879 2881/1/2881 +f 2882/1/2882 4242/1/4242 2879/1/2879 +f 2886/1/2886 4242/1/4242 2882/1/2882 +f 2885/1/2885 2886/1/2886 2882/1/2882 +f 2885/1/2885 4064/1/4064 2886/1/2886 +f 4064/1/4064 4067/1/4067 2886/1/2886 +f 4064/1/4064 4066/1/4066 4067/1/4067 +f 4066/1/4066 4069/1/4069 4067/1/4067 +f 4067/1/4067 4069/1/4069 4242/1/4242 +f 4069/1/4069 4166/1/4166 4242/1/4242 +f 4242/1/4242 4166/1/4166 2880/1/2880 +f 4069/1/4069 4165/1/4165 4166/1/4166 +f 4166/1/4166 4165/1/4165 4164/1/4164 +f 4069/1/4069 4076/1/4076 4165/1/4165 +f 4076/1/4076 4083/1/4083 4165/1/4165 +f 4076/1/4076 4077/1/4077 4083/1/4083 +f 4075/1/4075 4077/1/4077 4076/1/4076 +f 4068/1/4068 4075/1/4075 4076/1/4076 +f 4071/1/4071 4075/1/4075 4068/1/4068 +f 4065/1/4065 4071/1/4071 4068/1/4068 +f 4065/1/4065 4068/1/4068 4066/1/4066 +f 4063/1/4063 4065/1/4065 4066/1/4066 +f 4061/1/4061 4065/1/4065 4063/1/4063 +f 4062/1/4062 4061/1/4061 4063/1/4063 +f 4062/1/4062 4063/1/4063 4064/1/4064 +f 4058/1/4058 4061/1/4061 4062/1/4062 +f 2739/1/2739 4058/1/4058 4062/1/4062 +f 2739/1/2739 4062/1/4062 2735/1/2735 +f 2744/1/2744 4058/1/4058 2739/1/2739 +f 2738/1/2738 2744/1/2744 2739/1/2739 +f 2738/1/2738 2739/1/2739 2734/1/2734 +f 2743/1/2743 2744/1/2744 2738/1/2738 +f 2740/1/2740 2743/1/2743 2738/1/2738 +f 2740/1/2740 2738/1/2738 2737/1/2737 +f 2747/1/2747 2743/1/2743 2740/1/2740 +f 2814/1/2814 2747/1/2747 2740/1/2740 +f 2814/1/2814 2740/1/2740 2816/1/2816 +f 2816/1/2816 2817/1/2817 2814/1/2814 +f 2814/1/2814 2817/1/2817 2815/1/2815 +f 2814/1/2814 2815/1/2815 2813/1/2813 +f 2813/1/2813 2815/1/2815 2812/1/2812 +f 2812/1/2812 2747/1/2747 2813/1/2813 +f 2811/1/2811 2747/1/2747 2812/1/2812 +f 2812/1/2812 2809/1/2809 2811/1/2811 +f 2811/1/2811 2809/1/2809 2808/1/2808 +f 2808/1/2808 2748/1/2748 2811/1/2811 +f 2810/1/2810 2748/1/2748 2808/1/2808 +f 2808/1/2808 2806/1/2806 2810/1/2810 +f 2810/1/2810 2806/1/2806 2753/1/2753 +f 2753/1/2753 2806/1/2806 2805/1/2805 +f 2753/1/2753 2805/1/2805 2752/1/2752 +f 2752/1/2752 2750/1/2750 2753/1/2753 +f 2753/1/2753 2750/1/2750 2748/1/2748 +f 2750/1/2750 2749/1/2749 2748/1/2748 +f 2748/1/2748 2749/1/2749 2745/1/2745 +f 2748/1/2748 2745/1/2745 2747/1/2747 +f 2749/1/2749 4056/1/4056 2745/1/2745 +f 2745/1/2745 4056/1/4056 2746/1/2746 +f 2745/1/2745 2746/1/2746 2743/1/2743 +f 4056/1/4056 4057/1/4057 2746/1/2746 +f 2746/1/2746 4057/1/4057 4054/1/4054 +f 2746/1/2746 4054/1/4054 4055/1/4055 +f 2746/1/2746 4055/1/4055 2744/1/2744 +f 4054/1/4054 4217/1/4217 4055/1/4055 +f 4055/1/4055 4217/1/4217 4230/1/4230 +f 4055/1/4055 4230/1/4230 4059/1/4059 +f 4055/1/4055 4059/1/4059 4058/1/4058 +f 4058/1/4058 4059/1/4059 4060/1/4060 +f 4059/1/4059 4229/1/4229 4060/1/4060 +f 4060/1/4060 4229/1/4229 4072/1/4072 +f 4060/1/4060 4072/1/4072 4061/1/4061 +f 4061/1/4061 4072/1/4072 4070/1/4070 +f 4072/1/4072 4073/1/4073 4070/1/4070 +f 4073/1/4073 4071/1/4071 4070/1/4070 +f 4073/1/4073 4074/1/4074 4071/1/4071 +f 4073/1/4073 4079/1/4079 4074/1/4074 +f 4079/1/4079 4080/1/4080 4074/1/4074 +f 4074/1/4074 4080/1/4080 4078/1/4078 +f 4074/1/4074 4078/1/4078 4075/1/4075 +f 4080/1/4080 4081/1/4081 4078/1/4078 +f 4078/1/4078 4081/1/4081 4077/1/4077 +f 4077/1/4077 4081/1/4081 4082/1/4082 +f 4080/1/4080 4084/1/4084 4081/1/4081 +f 4084/1/4084 2836/1/2836 4081/1/4081 +f 4081/1/4081 2836/1/2836 2834/1/2834 +f 4084/1/4084 2800/1/2800 2836/1/2836 +f 2800/1/2800 2837/1/2837 2836/1/2836 +f 2836/1/2836 2837/1/2837 2832/1/2832 +f 2837/1/2837 2820/1/2820 2832/1/2832 +f 2832/1/2832 2820/1/2820 2831/1/2831 +f 2831/1/2831 2820/1/2820 2822/1/2822 +f 2831/1/2831 2822/1/2822 2827/1/2827 +f 2820/1/2820 2819/1/2819 2822/1/2822 +f 2822/1/2822 2819/1/2819 2823/1/2823 +f 2822/1/2822 2823/1/2823 2825/1/2825 +f 2825/1/2825 2823/1/2823 2824/1/2824 +f 2823/1/2823 2819/1/2819 2818/1/2818 +f 2741/1/2741 2823/1/2823 2818/1/2818 +f 2818/1/2818 2740/1/2740 2741/1/2741 +f 2818/1/2818 2819/1/2819 2816/1/2816 +f 2820/1/2820 2817/1/2817 2819/1/2819 +f 2820/1/2820 2821/1/2821 2817/1/2817 +f 2837/1/2837 2821/1/2821 2820/1/2820 +f 2801/1/2801 2821/1/2821 2837/1/2837 +f 2801/1/2801 2803/1/2803 2821/1/2821 +f 2803/1/2803 2838/1/2838 2821/1/2821 +f 2838/1/2838 2815/1/2815 2821/1/2821 +f 2838/1/2838 2809/1/2809 2815/1/2815 +f 2807/1/2807 2809/1/2809 2838/1/2838 +f 2807/1/2807 2806/1/2806 2809/1/2809 +f 2802/1/2802 2806/1/2806 2807/1/2807 +f 2802/1/2802 2807/1/2807 2803/1/2803 +f 2798/1/2798 2802/1/2802 2803/1/2803 +f 2798/1/2798 2799/1/2799 2802/1/2802 +f 2799/1/2799 2804/1/2804 2802/1/2802 +f 2797/1/2797 2804/1/2804 2799/1/2799 +f 2795/1/2795 2797/1/2797 2799/1/2799 +f 2773/1/2773 2797/1/2797 2795/1/2795 +f 2793/1/2793 2773/1/2773 2795/1/2795 +f 2793/1/2793 2795/1/2795 2796/1/2796 +f 2794/1/2794 2793/1/2793 2796/1/2796 +f 2794/1/2794 2796/1/2796 4168/1/4168 +f 4171/1/4171 2794/1/2794 4168/1/4168 +f 4171/1/4171 4168/1/4168 4170/1/4170 +f 4172/1/4172 4171/1/4171 4170/1/4170 +f 4172/1/4172 4170/1/4170 4173/1/4173 +f 4219/1/4219 4172/1/4172 4173/1/4173 +f 4219/1/4219 4173/1/4173 4220/1/4220 +f 4215/1/4215 4219/1/4219 4220/1/4220 +f 4215/1/4215 4220/1/4220 4218/1/4218 +f 4216/1/4216 4215/1/4215 4218/1/4218 +f 4216/1/4216 4218/1/4218 4217/1/4217 +f 4217/1/4217 4218/1/4218 4223/1/4223 +f 4218/1/4218 4222/1/4222 4223/1/4223 +f 4223/1/4223 4222/1/4222 4226/1/4226 +f 4230/1/4230 4223/1/4223 4226/1/4226 +f 4222/1/4222 4225/1/4225 4226/1/4226 +f 4226/1/4226 4225/1/4225 4228/1/4228 +f 4226/1/4226 4228/1/4228 4229/1/4229 +f 4229/1/4229 4228/1/4228 4073/1/4073 +f 4225/1/4225 4227/1/4227 4228/1/4228 +f 4228/1/4228 4227/1/4227 4079/1/4079 +f 4225/1/4225 4224/1/4224 4227/1/4227 +f 4224/1/4224 4169/1/4169 4227/1/4227 +f 4227/1/4227 4169/1/4169 4080/1/4080 +f 4224/1/4224 4167/1/4167 4169/1/4169 +f 4167/1/4167 4084/1/4084 4169/1/4169 +f 4167/1/4167 4168/1/4168 4084/1/4084 +f 4221/1/4221 4167/1/4167 4224/1/4224 +f 4222/1/4222 4221/1/4221 4224/1/4224 +f 4220/1/4220 4221/1/4221 4222/1/4222 +f 4173/1/4173 4167/1/4167 4221/1/4221 +f 4222/1/4222 4224/1/4224 4225/1/4225 +f 4214/1/4214 4215/1/4215 4216/1/4216 +f 4054/1/4054 4214/1/4214 4216/1/4216 +f 4214/1/4214 4182/1/4182 4215/1/4215 +f 4189/1/4189 4182/1/4182 4214/1/4214 +f 4057/1/4057 4189/1/4189 4214/1/4214 +f 4057/1/4057 4187/1/4187 4189/1/4189 +f 4187/1/4187 4184/1/4184 4189/1/4189 +f 4187/1/4187 4183/1/4183 4184/1/4184 +f 4183/1/4183 4179/1/4179 4184/1/4184 +f 4184/1/4184 4179/1/4179 4182/1/4182 +f 4179/1/4179 4181/1/4181 4182/1/4182 +f 4182/1/4182 4181/1/4181 4219/1/4219 +f 4179/1/4179 4175/1/4175 4181/1/4181 +f 4181/1/4181 4175/1/4175 4172/1/4172 +f 4179/1/4179 4174/1/4174 4175/1/4175 +f 4174/1/4174 4171/1/4171 4175/1/4175 +f 4174/1/4174 4176/1/4176 4171/1/4171 +f 4177/1/4177 4176/1/4176 4174/1/4174 +f 4180/1/4180 4177/1/4177 4174/1/4174 +f 4186/1/4186 4177/1/4177 4180/1/4180 +f 4185/1/4185 4186/1/4186 4180/1/4180 +f 4185/1/4185 4180/1/4180 4183/1/4183 +f 4188/1/4188 4185/1/4185 4183/1/4183 +f 4191/1/4191 4185/1/4185 4188/1/4188 +f 4190/1/4190 4191/1/4191 4188/1/4188 +f 4190/1/4190 4188/1/4188 4187/1/4187 +f 4195/1/4195 4191/1/4191 4190/1/4190 +f 4201/1/4201 4195/1/4195 4190/1/4190 +f 4201/1/4201 4190/1/4190 4056/1/4056 +f 4200/1/4200 4195/1/4195 4201/1/4201 +f 2751/1/2751 4200/1/4200 4201/1/4201 +f 2751/1/2751 4201/1/4201 2749/1/2749 +f 2755/1/2755 4200/1/4200 2751/1/2751 +f 2754/1/2754 2755/1/2755 2751/1/2751 +f 2754/1/2754 2751/1/2751 2750/1/2750 +f 2757/1/2757 2755/1/2755 2754/1/2754 +f 2758/1/2758 2757/1/2757 2754/1/2754 +f 2758/1/2758 2754/1/2754 2759/1/2759 +f 2759/1/2759 2762/1/2762 2758/1/2758 +f 2758/1/2758 2762/1/2762 2764/1/2764 +f 2758/1/2758 2764/1/2764 2763/1/2763 +f 2763/1/2763 2764/1/2764 2766/1/2766 +f 2766/1/2766 2757/1/2757 2763/1/2763 +f 2765/1/2765 2757/1/2757 2766/1/2766 +f 2766/1/2766 2767/1/2767 2765/1/2765 +f 2765/1/2765 2767/1/2767 2769/1/2769 +f 2769/1/2769 4698/1/4698 2765/1/2765 +f 4709/1/4709 4698/1/4698 2769/1/2769 +f 2769/1/2769 2770/1/2770 4709/1/4709 +f 4709/1/4709 2770/1/2770 4697/1/4697 +f 4697/1/4697 2770/1/2770 4699/1/4699 +f 4697/1/4697 4699/1/4699 4695/1/4695 +f 4695/1/4695 4696/1/4696 4697/1/4697 +f 4697/1/4697 4696/1/4696 4698/1/4698 +f 4696/1/4696 4211/1/4211 4698/1/4698 +f 4698/1/4698 4211/1/4211 4212/1/4212 +f 4698/1/4698 4212/1/4212 2757/1/2757 +f 4211/1/4211 3385/1/3385 4212/1/4212 +f 4212/1/4212 3385/1/3385 4205/1/4205 +f 4212/1/4212 4205/1/4205 2755/1/2755 +f 3385/1/3385 3380/1/3380 4205/1/4205 +f 4205/1/4205 3380/1/3380 4206/1/4206 +f 4205/1/4205 4206/1/4206 4202/1/4202 +f 4205/1/4205 4202/1/4202 4200/1/4200 +f 4200/1/4200 4202/1/4202 4198/1/4198 +f 4202/1/4202 4199/1/4199 4198/1/4198 +f 4198/1/4198 4199/1/4199 4193/1/4193 +f 4198/1/4198 4193/1/4193 4195/1/4195 +f 4199/1/4199 4197/1/4197 4193/1/4193 +f 4193/1/4193 4197/1/4197 4194/1/4194 +f 4193/1/4193 4194/1/4194 4191/1/4191 +f 4191/1/4191 4194/1/4194 4192/1/4192 +f 4194/1/4194 4196/1/4196 4192/1/4192 +f 4196/1/4196 4186/1/4186 4192/1/4192 +f 4196/1/4196 4236/1/4236 4186/1/4186 +f 4196/1/4196 4235/1/4235 4236/1/4236 +f 4235/1/4235 4237/1/4237 4236/1/4236 +f 4236/1/4236 4237/1/4237 4178/1/4178 +f 4236/1/4236 4178/1/4178 4177/1/4177 +f 4237/1/4237 2792/1/2792 4178/1/4178 +f 4178/1/4178 2792/1/2792 4176/1/4176 +f 4176/1/4176 2792/1/2792 2794/1/2794 +f 4237/1/4237 2791/1/2791 2792/1/2792 +f 2791/1/2791 2777/1/2777 2792/1/2792 +f 2792/1/2792 2777/1/2777 2793/1/2793 +f 2791/1/2791 2776/1/2776 2777/1/2777 +f 2776/1/2776 2772/1/2772 2777/1/2777 +f 2777/1/2777 2772/1/2772 2773/1/2773 +f 2772/1/2772 2771/1/2771 2773/1/2773 +f 2773/1/2773 2771/1/2771 2774/1/2774 +f 2774/1/2774 2771/1/2771 2775/1/2775 +f 2774/1/2774 2775/1/2775 2797/1/2797 +f 2771/1/2771 2761/1/2761 2775/1/2775 +f 2775/1/2775 2761/1/2761 2760/1/2760 +f 2775/1/2775 2760/1/2760 2804/1/2804 +f 2804/1/2804 2760/1/2760 2805/1/2805 +f 2760/1/2760 2761/1/2761 2756/1/2756 +f 2752/1/2752 2760/1/2760 2756/1/2756 +f 2756/1/2756 2754/1/2754 2752/1/2752 +f 2756/1/2756 2761/1/2761 2759/1/2759 +f 2771/1/2771 2762/1/2762 2761/1/2761 +f 2771/1/2771 2768/1/2768 2762/1/2762 +f 2772/1/2772 2768/1/2768 2771/1/2771 +f 2778/1/2778 2768/1/2768 2772/1/2772 +f 2778/1/2778 2781/1/2781 2768/1/2768 +f 2781/1/2781 2784/1/2784 2768/1/2768 +f 2784/1/2784 2764/1/2764 2768/1/2768 +f 2784/1/2784 2767/1/2767 2764/1/2764 +f 2783/1/2783 2767/1/2767 2784/1/2784 +f 2783/1/2783 2770/1/2770 2767/1/2767 +f 2782/1/2782 2770/1/2770 2783/1/2783 +f 2782/1/2782 2783/1/2783 2781/1/2781 +f 2780/1/2780 2782/1/2782 2781/1/2781 +f 2780/1/2780 4706/1/4706 2782/1/2782 +f 4706/1/4706 4702/1/4702 2782/1/2782 +f 4703/1/4703 4702/1/4702 4706/1/4706 +f 4707/1/4707 4703/1/4703 4706/1/4706 +f 4704/1/4704 4703/1/4703 4707/1/4707 +f 2786/1/2786 4704/1/4704 4707/1/4707 +f 2786/1/2786 4707/1/4707 2779/1/2779 +f 2785/1/2785 2786/1/2786 2779/1/2779 +f 2785/1/2785 2779/1/2779 2787/1/2787 +f 3612/1/3612 2785/1/2785 2787/1/2787 +f 3612/1/3612 2787/1/2787 3613/1/3613 +f 3614/1/3614 3612/1/3612 3613/1/3613 +f 3614/1/3614 3613/1/3613 3619/1/3619 +f 3618/1/3618 3614/1/3614 3619/1/3619 +f 3618/1/3618 3619/1/3619 4241/1/4241 +f 3379/1/3379 3618/1/3618 4241/1/4241 +f 3379/1/3379 4241/1/4241 4210/1/4210 +f 4209/1/4209 3379/1/3379 4210/1/4210 +f 4209/1/4209 4210/1/4210 4207/1/4207 +f 4206/1/4206 4209/1/4209 4207/1/4207 +f 4206/1/4206 3377/1/3377 4209/1/4209 +f 4207/1/4207 4210/1/4210 4208/1/4208 +f 4207/1/4207 4208/1/4208 4204/1/4204 +f 4202/1/4202 4207/1/4207 4204/1/4204 +f 4204/1/4204 4208/1/4208 4203/1/4203 +f 4204/1/4204 4203/1/4203 4199/1/4199 +f 4208/1/4208 4233/1/4233 4203/1/4203 +f 4233/1/4233 4232/1/4232 4203/1/4203 +f 4203/1/4203 4232/1/4232 4231/1/4231 +f 4203/1/4203 4231/1/4231 4197/1/4197 +f 4197/1/4197 4231/1/4231 4196/1/4196 +f 4232/1/4232 4234/1/4234 4231/1/4231 +f 4231/1/4231 4234/1/4234 4235/1/4235 +f 4232/1/4232 4238/1/4238 4234/1/4234 +f 4238/1/4238 4239/1/4239 4234/1/4234 +f 4234/1/4234 4239/1/4239 4237/1/4237 +f 4238/1/4238 3620/1/3620 4239/1/4239 +f 3620/1/3620 2791/1/2791 4239/1/4239 +f 3620/1/3620 2787/1/2787 2791/1/2791 +f 4240/1/4240 3620/1/3620 4238/1/4238 +f 4233/1/4233 4240/1/4240 4238/1/4238 +f 4241/1/4241 4240/1/4240 4233/1/4233 +f 3619/1/3619 3620/1/3620 4240/1/4240 +f 4233/1/4233 4238/1/4238 4232/1/4232 +f 4210/1/4210 4233/1/4233 4208/1/4208 +f 3377/1/3377 3379/1/3379 4209/1/4209 +f 3377/1/3377 3378/1/3378 3379/1/3379 +f 3381/1/3381 3378/1/3378 3377/1/3377 +f 3380/1/3380 3381/1/3381 3377/1/3377 +f 3380/1/3380 3383/1/3383 3381/1/3381 +f 3383/1/3383 3382/1/3382 3381/1/3381 +f 3383/1/3383 3386/1/3386 3382/1/3382 +f 3386/1/3386 3616/1/3616 3382/1/3382 +f 3382/1/3382 3616/1/3616 3378/1/3378 +f 3616/1/3616 3617/1/3617 3378/1/3378 +f 3378/1/3378 3617/1/3617 3618/1/3618 +f 3616/1/3616 3615/1/3615 3617/1/3617 +f 3617/1/3617 3615/1/3615 3614/1/3614 +f 3616/1/3616 3611/1/3611 3615/1/3615 +f 3611/1/3611 3612/1/3612 3615/1/3615 +f 3611/1/3611 3608/1/3608 3612/1/3612 +f 3609/1/3609 3608/1/3608 3611/1/3611 +f 3610/1/3610 3609/1/3609 3611/1/3611 +f 3400/1/3400 3609/1/3609 3610/1/3610 +f 3391/1/3391 3400/1/3400 3610/1/3610 +f 3391/1/3391 3610/1/3610 3386/1/3386 +f 3387/1/3387 3391/1/3391 3386/1/3386 +f 3388/1/3388 3391/1/3391 3387/1/3387 +f 3384/1/3384 3388/1/3388 3387/1/3387 +f 3384/1/3384 3387/1/3387 3383/1/3383 +f 3390/1/3390 3388/1/3388 3384/1/3384 +f 3389/1/3389 3390/1/3390 3384/1/3384 +f 3389/1/3389 3384/1/3384 3385/1/3385 +f 3395/1/3395 3390/1/3390 3389/1/3389 +f 4213/1/4213 3395/1/3395 3389/1/3389 +f 4213/1/4213 3389/1/3389 4211/1/4211 +f 3458/1/3458 3395/1/3395 4213/1/4213 +f 4651/1/4651 3458/1/3458 4213/1/4213 +f 4651/1/4651 4213/1/4213 4696/1/4696 +f 4654/1/4654 3458/1/3458 4651/1/4651 +f 4650/1/4650 4654/1/4654 4651/1/4651 +f 4650/1/4650 4651/1/4651 4652/1/4652 +f 4652/1/4652 4655/1/4655 4650/1/4650 +f 4650/1/4650 4655/1/4655 4653/1/4653 +f 4653/1/4653 4655/1/4655 4658/1/4658 +f 4653/1/4653 4658/1/4658 4694/1/4694 +f 4694/1/4694 4654/1/4654 4653/1/4653 +f 4694/1/4694 4689/1/4689 4654/1/4654 +f 4689/1/4689 3459/1/3459 4654/1/4654 +f 4689/1/4689 3460/1/3460 3459/1/3459 +f 3460/1/3460 3450/1/3450 3459/1/3459 +f 3459/1/3459 3450/1/3450 3451/1/3451 +f 3459/1/3459 3451/1/3451 3454/1/3454 +f 3459/1/3459 3454/1/3454 3458/1/3458 +f 3451/1/3451 3449/1/3449 3454/1/3454 +f 3454/1/3454 3449/1/3449 3453/1/3453 +f 3454/1/3454 3453/1/3453 3395/1/3395 +f 3395/1/3395 3453/1/3453 3396/1/3396 +f 3453/1/3453 3405/1/3405 3396/1/3396 +f 3396/1/3396 3405/1/3405 3398/1/3398 +f 3396/1/3396 3398/1/3398 3393/1/3393 +f 3396/1/3396 3393/1/3393 3390/1/3390 +f 3398/1/3398 3397/1/3397 3393/1/3393 +f 3393/1/3393 3397/1/3397 3394/1/3394 +f 3393/1/3393 3394/1/3394 3388/1/3388 +f 3388/1/3388 3394/1/3394 3392/1/3392 +f 3394/1/3394 3399/1/3399 3392/1/3392 +f 3399/1/3399 3400/1/3400 3392/1/3392 +f 3399/1/3399 3403/1/3403 3400/1/3400 +f 3399/1/3399 3402/1/3402 3403/1/3403 +f 3402/1/3402 3410/1/3410 3403/1/3403 +f 3403/1/3403 3410/1/3410 3607/1/3607 +f 3403/1/3403 3607/1/3607 3609/1/3609 +f 3410/1/3410 2788/1/2788 3607/1/3607 +f 3607/1/3607 2788/1/2788 3608/1/3608 +f 3608/1/3608 2788/1/2788 2785/1/2785 +f 3410/1/3410 2790/1/2790 2788/1/2788 +f 2790/1/2790 2789/1/2789 2788/1/2788 +f 2788/1/2788 2789/1/2789 2786/1/2786 +f 2790/1/2790 4708/1/4708 2789/1/2789 +f 4708/1/4708 4666/1/4666 2789/1/2789 +f 2789/1/2789 4666/1/4666 4705/1/4705 +f 2789/1/2789 4705/1/4705 4704/1/4704 +f 4705/1/4705 4660/1/4660 4704/1/4704 +f 4705/1/4705 4663/1/4663 4660/1/4660 +f 4663/1/4663 4659/1/4659 4660/1/4660 +f 4659/1/4659 4655/1/4655 4660/1/4660 +f 4660/1/4660 4655/1/4655 4657/1/4657 +f 4660/1/4660 4657/1/4657 4701/1/4701 +f 4660/1/4660 4701/1/4701 4703/1/4703 +f 4701/1/4701 4657/1/4657 4700/1/4700 +f 4701/1/4701 4700/1/4700 4702/1/4702 +f 4702/1/4702 4700/1/4700 4699/1/4699 +f 4700/1/4700 4657/1/4657 4656/1/4656 +f 4695/1/4695 4700/1/4700 4656/1/4656 +f 4656/1/4656 4651/1/4651 4695/1/4695 +f 4656/1/4656 4657/1/4657 4652/1/4652 +f 4661/1/4661 4659/1/4659 4663/1/4663 +f 4666/1/4666 4661/1/4661 4663/1/4663 +f 4664/1/4664 4661/1/4661 4666/1/4666 +f 4664/1/4664 4665/1/4665 4661/1/4661 +f 4665/1/4665 4662/1/4662 4661/1/4661 +f 4665/1/4665 4667/1/4667 4662/1/4662 +f 4667/1/4667 4668/1/4668 4662/1/4662 +f 4662/1/4662 4668/1/4668 4658/1/4658 +f 4662/1/4662 4658/1/4658 4659/1/4659 +f 4710/1/4710 4658/1/4658 4668/1/4668 +f 4710/1/4710 4668/1/4668 4690/1/4690 +f 4690/1/4690 4689/1/4689 4710/1/4710 +f 4686/1/4686 4689/1/4689 4690/1/4690 +f 4686/1/4686 4688/1/4688 4689/1/4689 +f 4687/1/4687 4688/1/4688 4686/1/4686 +f 4686/1/4686 4672/1/4672 4687/1/4687 +f 4687/1/4687 4672/1/4672 4683/1/4683 +f 4687/1/4687 4683/1/4683 4691/1/4691 +f 4691/1/4691 4692/1/4692 4687/1/4687 +f 4684/1/4684 4692/1/4692 4691/1/4691 +f 4684/1/4684 4693/1/4693 4692/1/4692 +f 4693/1/4693 3461/1/3461 4692/1/4692 +f 4692/1/4692 3461/1/3461 3460/1/3460 +f 4692/1/4692 3460/1/3460 4688/1/4688 +f 3461/1/3461 3462/1/3462 3460/1/3460 +f 3461/1/3461 3463/1/3463 3462/1/3462 +f 3463/1/3463 3577/1/3577 3462/1/3462 +f 3462/1/3462 3577/1/3577 3444/1/3444 +f 3462/1/3462 3444/1/3444 3450/1/3450 +f 3450/1/3450 3444/1/3444 3445/1/3445 +f 3444/1/3444 3439/1/3439 3445/1/3445 +f 3445/1/3445 3439/1/3439 3442/1/3442 +f 3445/1/3445 3442/1/3442 3446/1/3446 +f 3445/1/3445 3446/1/3446 3449/1/3449 +f 3449/1/3449 3446/1/3446 3448/1/3448 +f 3449/1/3449 3448/1/3448 3452/1/3452 +f 3448/1/3448 3455/1/3455 3452/1/3452 +f 3452/1/3452 3455/1/3455 3456/1/3456 +f 3452/1/3452 3456/1/3456 3457/1/3457 +f 3453/1/3453 3452/1/3452 3457/1/3457 +f 3457/1/3457 3456/1/3456 3408/1/3408 +f 3457/1/3457 3408/1/3408 3405/1/3405 +f 3405/1/3405 3408/1/3408 3404/1/3404 +f 3408/1/3408 3406/1/3406 3404/1/3404 +f 3406/1/3406 3407/1/3407 3404/1/3404 +f 3404/1/3404 3407/1/3407 3401/1/3401 +f 3404/1/3404 3401/1/3401 3397/1/3397 +f 3397/1/3397 3401/1/3401 3399/1/3399 +f 3407/1/3407 3409/1/3409 3401/1/3401 +f 3401/1/3401 3409/1/3409 3402/1/3402 +f 3407/1/3407 3411/1/3411 3409/1/3409 +f 3411/1/3411 3412/1/3412 3409/1/3409 +f 3409/1/3409 3412/1/3412 3410/1/3410 +f 3413/1/3413 3412/1/3412 3411/1/3411 +f 3406/1/3406 3413/1/3413 3411/1/3411 +f 3416/1/3416 3413/1/3413 3406/1/3406 +f 3456/1/3456 3416/1/3416 3406/1/3406 +f 3416/1/3416 3417/1/3417 3413/1/3413 +f 3417/1/3417 3415/1/3415 3413/1/3413 +f 3417/1/3417 3418/1/3418 3415/1/3415 +f 3418/1/3418 3414/1/3414 3415/1/3415 +f 3415/1/3415 3414/1/3414 3412/1/3412 +f 3412/1/3412 3414/1/3414 2790/1/2790 +f 3418/1/3418 3419/1/3419 3414/1/3414 +f 3419/1/3419 4674/1/4674 3414/1/3414 +f 3414/1/3414 4674/1/4674 4675/1/4675 +f 3414/1/3414 4675/1/4675 4708/1/4708 +f 4675/1/4675 4664/1/4664 4708/1/4708 +f 4675/1/4675 4669/1/4669 4664/1/4664 +f 4674/1/4674 4669/1/4669 4675/1/4675 +f 4674/1/4674 4673/1/4673 4669/1/4669 +f 4673/1/4673 4671/1/4671 4669/1/4669 +f 4669/1/4669 4671/1/4671 4670/1/4670 +f 4669/1/4669 4670/1/4670 4665/1/4665 +f 4671/1/4671 4672/1/4672 4670/1/4670 +f 4670/1/4670 4672/1/4672 4668/1/4668 +f 4671/1/4671 4682/1/4682 4672/1/4672 +f 4681/1/4681 4682/1/4682 4671/1/4671 +f 4676/1/4676 4681/1/4681 4671/1/4671 +f 4676/1/4676 4680/1/4680 4681/1/4681 +f 4676/1/4676 4679/1/4679 4680/1/4680 +f 4679/1/4679 4685/1/4685 4680/1/4680 +f 4684/1/4684 4680/1/4680 4685/1/4685 +f 4684/1/4684 4685/1/4685 4711/1/4711 +f 4711/1/4711 4685/1/4685 4712/1/4712 +f 4712/1/4712 4693/1/4693 4711/1/4711 +f 4712/1/4712 3467/1/3467 4693/1/4693 +f 3467/1/3467 3464/1/3464 4693/1/4693 +f 3467/1/3467 3466/1/3466 3464/1/3464 +f 3466/1/3466 3465/1/3465 3464/1/3464 +f 3465/1/3465 3463/1/3463 3464/1/3464 +f 3465/1/3465 3581/1/3581 3463/1/3463 +f 3581/1/3581 3578/1/3578 3463/1/3463 +f 3581/1/3581 3582/1/3582 3578/1/3578 +f 3582/1/3582 3580/1/3580 3578/1/3578 +f 3578/1/3578 3580/1/3580 3577/1/3577 +f 3577/1/3577 3580/1/3580 3579/1/3579 +f 3577/1/3577 3579/1/3579 3438/1/3438 +f 3579/1/3579 3440/1/3440 3438/1/3438 +f 3438/1/3438 3440/1/3440 3436/1/3436 +f 3438/1/3438 3436/1/3436 3439/1/3439 +f 3439/1/3439 3436/1/3436 3441/1/3441 +f 3436/1/3436 3437/1/3437 3441/1/3441 +f 3441/1/3441 3437/1/3437 3426/1/3426 +f 3441/1/3441 3426/1/3426 3443/1/3443 +f 3442/1/3442 3441/1/3441 3443/1/3443 +f 3443/1/3443 3426/1/3426 3424/1/3424 +f 3443/1/3443 3424/1/3424 3447/1/3447 +f 3446/1/3446 3443/1/3443 3447/1/3447 +f 3447/1/3447 3424/1/3424 3455/1/3455 +f 3424/1/3424 3423/1/3423 3455/1/3455 +f 3455/1/3455 3423/1/3423 3416/1/3416 +f 3424/1/3424 3422/1/3422 3423/1/3423 +f 3423/1/3423 3422/1/3422 3417/1/3417 +f 3424/1/3424 3420/1/3420 3422/1/3422 +f 3420/1/3420 3418/1/3418 3422/1/3422 +f 3420/1/3420 3421/1/3421 3418/1/3418 +f 3425/1/3425 3421/1/3421 3420/1/3420 +f 3426/1/3426 3425/1/3425 3420/1/3420 +f 3432/1/3432 3425/1/3425 3426/1/3426 +f 3432/1/3432 3430/1/3430 3425/1/3425 +f 3430/1/3430 3427/1/3427 3425/1/3425 +f 3431/1/3431 3427/1/3427 3430/1/3430 +f 3433/1/3433 3431/1/3431 3430/1/3430 +f 3434/1/3434 3431/1/3431 3433/1/3433 +f 3434/1/3434 3433/1/3433 3436/1/3436 +f 3436/1/3436 3433/1/3433 3432/1/3432 +f 3434/1/3434 3435/1/3435 3431/1/3431 +f 3435/1/3435 3429/1/3429 3431/1/3431 +f 3588/1/3588 3429/1/3429 3435/1/3435 +f 3585/1/3585 3588/1/3588 3435/1/3435 +f 3586/1/3586 3588/1/3588 3585/1/3585 +f 3583/1/3583 3586/1/3586 3585/1/3585 +f 3583/1/3583 3585/1/3585 3584/1/3584 +f 3580/1/3580 3583/1/3583 3584/1/3584 +f 3584/1/3584 3585/1/3585 3434/1/3434 +f 3584/1/3584 3434/1/3434 3440/1/3440 +f 3583/1/3583 3587/1/3587 3586/1/3586 +f 3587/1/3587 3589/1/3589 3586/1/3586 +f 3590/1/3590 3589/1/3589 3587/1/3587 +f 3590/1/3590 3587/1/3587 3591/1/3591 +f 3593/1/3593 3590/1/3590 3591/1/3591 +f 3593/1/3593 3591/1/3591 3594/1/3594 +f 3594/1/3594 3596/1/3596 3593/1/3593 +f 3593/1/3593 3596/1/3596 3597/1/3597 +f 3593/1/3593 3597/1/3597 3592/1/3592 +f 3592/1/3592 3597/1/3597 3598/1/3598 +f 3592/1/3592 3598/1/3598 4845/1/4845 +f 4845/1/4845 3605/1/3605 3592/1/3592 +f 3592/1/3592 3605/1/3605 3590/1/3590 +f 3605/1/3605 3603/1/3603 3590/1/3590 +f 3605/1/3605 3604/1/3604 3603/1/3603 +f 3603/1/3603 3604/1/3604 3588/1/3588 +f 3589/1/3589 3603/1/3603 3588/1/3588 +f 4725/1/4725 3604/1/3604 3605/1/3605 +f 4725/1/4725 4721/1/4721 3604/1/3604 +f 3604/1/3604 4721/1/4721 3606/1/3606 +f 3604/1/3604 3606/1/3606 3429/1/3429 +f 3429/1/3429 3606/1/3606 3428/1/3428 +f 3429/1/3429 3428/1/3428 3427/1/3427 +f 3427/1/3427 3428/1/3428 3419/1/3419 +f 3427/1/3427 3419/1/3419 3421/1/3421 +f 3606/1/3606 4677/1/4677 3428/1/3428 +f 3428/1/3428 4677/1/4677 4673/1/4673 +f 4677/1/4677 4676/1/4676 4673/1/4673 +f 3606/1/3606 4678/1/4678 4677/1/4677 +f 4678/1/4678 4679/1/4679 4677/1/4677 +f 4678/1/4678 4719/1/4719 4679/1/4679 +f 4719/1/4719 4716/1/4716 4679/1/4679 +f 4717/1/4717 4716/1/4716 4719/1/4719 +f 4717/1/4717 4718/1/4718 4716/1/4716 +f 4718/1/4718 4714/1/4714 4716/1/4716 +f 4716/1/4716 4714/1/4714 4685/1/4685 +f 4718/1/4718 4715/1/4715 4714/1/4714 +f 4713/1/4713 4714/1/4714 4715/1/4715 +f 4713/1/4713 4715/1/4715 3497/1/3497 +f 3497/1/3497 3470/1/3470 4713/1/4713 +f 4713/1/4713 3470/1/3470 3467/1/3467 +f 3496/1/3496 3470/1/3470 3497/1/3497 +f 3497/1/3497 3499/1/3499 3496/1/3496 +f 3496/1/3496 3499/1/3499 3498/1/3498 +f 3498/1/3498 3473/1/3473 3496/1/3496 +f 3500/1/3500 3473/1/3473 3498/1/3498 +f 3498/1/3498 3502/1/3502 3500/1/3500 +f 3500/1/3500 3502/1/3502 3503/1/3503 +f 3503/1/3503 3501/1/3501 3500/1/3500 +f 3504/1/3504 3501/1/3501 3503/1/3503 +f 3504/1/3504 3503/1/3503 3506/1/3506 +f 3508/1/3508 3504/1/3504 3506/1/3506 +f 3508/1/3508 3506/1/3506 3509/1/3509 +f 3508/1/3508 3509/1/3509 3511/1/3511 +f 3508/1/3508 3511/1/3511 3507/1/3507 +f 3511/1/3511 3524/1/3524 3507/1/3507 +f 3507/1/3507 3524/1/3524 3574/1/3574 +f 3574/1/3574 3573/1/3573 3507/1/3507 +f 3507/1/3507 3573/1/3573 3505/1/3505 +f 3507/1/3507 3505/1/3505 3504/1/3504 +f 3573/1/3573 3474/1/3474 3505/1/3505 +f 3505/1/3505 3474/1/3474 3471/1/3471 +f 3505/1/3505 3471/1/3471 3501/1/3501 +f 3501/1/3501 3471/1/3471 3473/1/3473 +f 3473/1/3473 3471/1/3471 3469/1/3469 +f 3473/1/3473 3469/1/3469 3470/1/3470 +f 3470/1/3470 3469/1/3469 3466/1/3466 +f 3469/1/3469 3468/1/3468 3466/1/3466 +f 3469/1/3469 3600/1/3600 3468/1/3468 +f 3468/1/3468 3600/1/3600 3595/1/3595 +f 3468/1/3468 3595/1/3595 3465/1/3465 +f 3595/1/3595 3600/1/3600 3599/1/3599 +f 3596/1/3596 3595/1/3595 3599/1/3599 +f 3599/1/3599 3600/1/3600 3601/1/3601 +f 3599/1/3599 3601/1/3601 4842/1/4842 +f 3597/1/3597 3599/1/3599 4842/1/4842 +f 4842/1/4842 3601/1/3601 4839/1/4839 +f 4842/1/4842 4839/1/4839 4840/1/4840 +f 4842/1/4842 4840/1/4840 4843/1/4843 +f 3598/1/3598 4842/1/4842 4843/1/4843 +f 3598/1/3598 4843/1/4843 4728/1/4728 +f 4728/1/4728 4843/1/4843 4729/1/4729 +f 4728/1/4728 4729/1/4729 4726/1/4726 +f 4725/1/4725 4728/1/4728 4726/1/4726 +f 4725/1/4725 4726/1/4726 4724/1/4724 +f 4724/1/4724 4726/1/4726 4727/1/4727 +f 4724/1/4724 4727/1/4727 3518/1/3518 +f 3518/1/3518 3519/1/3519 4724/1/4724 +f 4724/1/4724 3519/1/3519 4721/1/4721 +f 3519/1/3519 4722/1/4722 4721/1/4721 +f 4721/1/4721 4722/1/4722 4720/1/4720 +f 4721/1/4721 4720/1/4720 4678/1/4678 +f 4720/1/4720 4717/1/4717 4678/1/4678 +f 4722/1/4722 4717/1/4717 4720/1/4720 +f 4722/1/4722 4723/1/4723 4717/1/4717 +f 4722/1/4722 3515/1/3515 4723/1/4723 +f 3515/1/3515 3516/1/3516 4723/1/4723 +f 4723/1/4723 3516/1/3516 4718/1/4718 +f 3516/1/3516 3499/1/3499 4718/1/4718 +f 3516/1/3516 3502/1/3502 3499/1/3499 +f 3513/1/3513 3502/1/3502 3516/1/3516 +f 3510/1/3510 3502/1/3502 3513/1/3513 +f 3509/1/3509 3510/1/3510 3513/1/3513 +f 3509/1/3509 3513/1/3513 3514/1/3514 +f 3514/1/3514 3518/1/3518 3509/1/3509 +f 3509/1/3509 3518/1/3518 3512/1/3512 +f 3518/1/3518 3525/1/3525 3512/1/3512 +f 3512/1/3512 3525/1/3525 3521/1/3521 +f 3512/1/3512 3521/1/3521 3520/1/3520 +f 3511/1/3511 3512/1/3512 3520/1/3520 +f 3520/1/3520 3521/1/3521 3522/1/3522 +f 3520/1/3520 3522/1/3522 3523/1/3523 +f 3524/1/3524 3520/1/3520 3523/1/3523 +f 3524/1/3524 3523/1/3523 3572/1/3572 +f 3572/1/3572 3523/1/3523 3571/1/3571 +f 3572/1/3572 3571/1/3571 3573/1/3573 +f 3523/1/3523 3570/1/3570 3571/1/3571 +f 3570/1/3570 3477/1/3477 3571/1/3571 +f 3477/1/3477 3474/1/3474 3571/1/3571 +f 3476/1/3476 3474/1/3474 3477/1/3477 +f 3476/1/3476 3477/1/3477 3478/1/3478 +f 4759/1/4759 3476/1/3476 3478/1/3478 +f 4759/1/4759 3478/1/3478 4761/1/4761 +f 4760/1/4760 4759/1/4759 4761/1/4761 +f 4760/1/4760 4761/1/4761 4762/1/4762 +f 4760/1/4760 4762/1/4762 4763/1/4763 +f 4763/1/4763 4764/1/4764 4760/1/4760 +f 4760/1/4760 4764/1/4764 4754/1/4754 +f 4760/1/4760 4754/1/4754 4758/1/4758 +f 4758/1/4758 4754/1/4754 4753/1/4753 +f 4758/1/4758 4753/1/4753 3475/1/3475 +f 3476/1/3476 4758/1/4758 3475/1/3475 +f 3475/1/3475 4753/1/4753 4756/1/4756 +f 3475/1/3475 4756/1/4756 4755/1/4755 +f 3475/1/3475 4755/1/4755 3472/1/3472 +f 3474/1/3474 3475/1/3475 3472/1/3472 +f 3472/1/3472 4755/1/4755 4757/1/4757 +f 3472/1/3472 4757/1/4757 3469/1/3469 +f 3469/1/3469 4757/1/4757 3602/1/3602 +f 3602/1/3602 4757/1/4757 4834/1/4834 +f 4835/1/4835 3602/1/3602 4834/1/4834 +f 4835/1/4835 4834/1/4834 4837/1/4837 +f 4838/1/4838 4835/1/4835 4837/1/4837 +f 4838/1/4838 4837/1/4837 4841/1/4841 +f 4840/1/4840 4838/1/4838 4841/1/4841 +f 4840/1/4840 4841/1/4841 4733/1/4733 +f 4729/1/4729 4840/1/4840 4733/1/4733 +f 4729/1/4729 4733/1/4733 4730/1/4730 +f 4733/1/4733 4734/1/4734 4730/1/4730 +f 4730/1/4730 4734/1/4734 4732/1/4732 +f 4730/1/4730 4732/1/4732 4731/1/4731 +f 4727/1/4727 4730/1/4730 4731/1/4731 +f 4731/1/4731 4732/1/4732 3526/1/3526 +f 3518/1/3518 4731/1/4731 3526/1/3526 +f 4732/1/4732 4737/1/4737 3526/1/3526 +f 3526/1/3526 4737/1/4737 3527/1/3527 +f 3526/1/3526 3527/1/3527 3525/1/3525 +f 3525/1/3525 3527/1/3527 3528/1/3528 +f 3527/1/3527 3529/1/3529 3528/1/3528 +f 3528/1/3528 3529/1/3529 3530/1/3530 +f 3528/1/3528 3530/1/3530 3531/1/3531 +f 3521/1/3521 3528/1/3528 3531/1/3531 +f 3531/1/3531 3530/1/3530 3532/1/3532 +f 3531/1/3531 3532/1/3532 3533/1/3533 +f 3522/1/3522 3531/1/3531 3533/1/3533 +f 3522/1/3522 3533/1/3533 3568/1/3568 +f 3568/1/3568 3533/1/3533 3564/1/3564 +f 3568/1/3568 3564/1/3564 3569/1/3569 +f 3570/1/3570 3568/1/3568 3569/1/3569 +f 3569/1/3569 3564/1/3564 3479/1/3479 +f 3479/1/3479 3477/1/3477 3569/1/3569 +f 3479/1/3479 3564/1/3564 3481/1/3481 +f 3481/1/3481 3480/1/3480 3479/1/3479 +f 3479/1/3479 3480/1/3480 3478/1/3478 +f 4766/1/4766 3478/1/3478 3480/1/3480 +f 3480/1/3480 4768/1/4768 4766/1/4766 +f 4766/1/4766 4768/1/4768 4769/1/4769 +f 4767/1/4767 4766/1/4766 4769/1/4769 +f 4767/1/4767 4769/1/4769 4770/1/4770 +f 4771/1/4771 4767/1/4767 4770/1/4770 +f 4771/1/4771 4770/1/4770 4778/1/4778 +f 4807/1/4807 4771/1/4771 4778/1/4778 +f 4807/1/4807 4778/1/4778 3536/1/3536 +f 4740/1/4740 4807/1/4807 3536/1/3536 +f 3527/1/3527 4740/1/4740 3536/1/3536 +f 4740/1/4740 4809/1/4809 4807/1/4807 +f 4808/1/4808 4807/1/4807 4809/1/4809 +f 4808/1/4808 4809/1/4809 4763/1/4763 +f 4745/1/4745 4809/1/4809 4740/1/4740 +f 4739/1/4739 4745/1/4745 4740/1/4740 +f 4737/1/4737 4739/1/4739 4740/1/4740 +f 4738/1/4738 4739/1/4739 4737/1/4737 +f 4736/1/4736 4738/1/4738 4737/1/4737 +f 4736/1/4736 4742/1/4742 4738/1/4738 +f 4742/1/4742 4743/1/4743 4738/1/4738 +f 4748/1/4748 4743/1/4743 4742/1/4742 +f 4741/1/4741 4748/1/4748 4742/1/4742 +f 4751/1/4751 4748/1/4748 4741/1/4741 +f 4844/1/4844 4751/1/4751 4741/1/4741 +f 4844/1/4844 4741/1/4741 4735/1/4735 +f 4734/1/4734 4844/1/4844 4735/1/4735 +f 4841/1/4841 4844/1/4844 4734/1/4734 +f 4735/1/4735 4741/1/4741 4736/1/4736 +f 4735/1/4735 4736/1/4736 4732/1/4732 +f 4837/1/4837 4751/1/4751 4844/1/4844 +f 4751/1/4751 4749/1/4749 4748/1/4748 +f 4749/1/4749 4750/1/4750 4748/1/4748 +f 4748/1/4748 4750/1/4750 4746/1/4746 +f 4750/1/4750 4752/1/4752 4746/1/4746 +f 4746/1/4746 4752/1/4752 4747/1/4747 +f 4746/1/4746 4747/1/4747 4743/1/4743 +f 4743/1/4743 4747/1/4747 4744/1/4744 +f 4743/1/4743 4744/1/4744 4739/1/4739 +f 4747/1/4747 4754/1/4754 4744/1/4744 +f 4752/1/4752 4753/1/4753 4747/1/4747 +f 4750/1/4750 4755/1/4755 4752/1/4752 +f 4749/1/4749 4755/1/4755 4750/1/4750 +f 4834/1/4834 4749/1/4749 4751/1/4751 +f 4748/1/4748 4746/1/4746 4743/1/4743 +f 4741/1/4741 4742/1/4742 4736/1/4736 +f 4738/1/4738 4743/1/4743 4739/1/4739 +f 4739/1/4739 4744/1/4744 4745/1/4745 +f 4744/1/4744 4764/1/4764 4745/1/4745 +f 4745/1/4745 4764/1/4764 4809/1/4809 +f 3536/1/3536 4778/1/4778 4781/1/4781 +f 3536/1/3536 4781/1/4781 3537/1/3537 +f 3537/1/3537 3534/1/3534 3536/1/3536 +f 3529/1/3529 3536/1/3536 3534/1/3534 +f 3537/1/3537 3535/1/3535 3534/1/3534 +f 3530/1/3530 3534/1/3534 3535/1/3535 +f 3535/1/3535 3537/1/3537 3538/1/3538 +f 3535/1/3535 3538/1/3538 3539/1/3539 +f 3539/1/3539 3540/1/3540 3535/1/3535 +f 3532/1/3532 3535/1/3535 3540/1/3540 +f 3567/1/3567 3532/1/3532 3540/1/3540 +f 3567/1/3567 3540/1/3540 3564/1/3564 +f 3564/1/3564 3540/1/3540 3563/1/3563 +f 3540/1/3540 3561/1/3561 3563/1/3563 +f 3563/1/3563 3561/1/3561 3560/1/3560 +f 3563/1/3563 3560/1/3560 3481/1/3481 +f 3562/1/3562 3481/1/3481 3560/1/3560 +f 3562/1/3562 3560/1/3560 3558/1/3558 +f 3562/1/3562 3558/1/3558 3483/1/3483 +f 3558/1/3558 3556/1/3556 3483/1/3483 +f 3483/1/3483 3556/1/3556 3484/1/3484 +f 3482/1/3482 3483/1/3483 3484/1/3484 +f 3482/1/3482 3484/1/3484 3485/1/3485 +f 4802/1/4802 3482/1/3482 3485/1/3485 +f 4802/1/4802 3485/1/3485 4801/1/4801 +f 4801/1/4801 4793/1/4793 4802/1/4802 +f 4802/1/4802 4793/1/4793 4787/1/4787 +f 4802/1/4802 4787/1/4787 4803/1/4803 +f 4803/1/4803 4787/1/4787 4785/1/4785 +f 4803/1/4803 4785/1/4785 4804/1/4804 +f 3482/1/3482 4803/1/4803 4804/1/4804 +f 4804/1/4804 3480/1/3480 3482/1/3482 +f 4774/1/4774 3480/1/3480 4804/1/4804 +f 4804/1/4804 4775/1/4775 4774/1/4774 +f 4774/1/4774 4775/1/4775 4772/1/4772 +f 4774/1/4774 4772/1/4772 4768/1/4768 +f 4775/1/4775 4776/1/4776 4772/1/4772 +f 4773/1/4773 4772/1/4772 4776/1/4776 +f 4773/1/4773 4776/1/4776 4777/1/4777 +f 4770/1/4770 4773/1/4773 4777/1/4777 +f 4777/1/4777 4776/1/4776 4779/1/4779 +f 4777/1/4777 4779/1/4779 4780/1/4780 +f 4781/1/4781 4777/1/4777 4780/1/4780 +f 4779/1/4779 3543/1/3543 4780/1/4780 +f 3543/1/3543 3541/1/3541 4780/1/4780 +f 3537/1/3537 4780/1/4780 3541/1/3541 +f 3543/1/3543 3544/1/3544 3541/1/3541 +f 3544/1/3544 3542/1/3542 3541/1/3541 +f 3538/1/3538 3541/1/3541 3542/1/3542 +f 3538/1/3538 3542/1/3542 3555/1/3555 +f 3555/1/3555 3542/1/3542 3554/1/3554 +f 3557/1/3557 3555/1/3555 3554/1/3554 +f 3557/1/3557 3554/1/3554 3556/1/3556 +f 3554/1/3554 3553/1/3553 3556/1/3556 +f 3556/1/3556 3553/1/3553 3552/1/3552 +f 3549/1/3549 3552/1/3552 3553/1/3553 +f 3549/1/3549 3551/1/3551 3552/1/3552 +f 3551/1/3551 3565/1/3565 3552/1/3552 +f 3565/1/3565 3484/1/3484 3552/1/3552 +f 3565/1/3565 3566/1/3566 3484/1/3484 +f 3484/1/3484 3566/1/3566 3486/1/3486 +f 3576/1/3576 3486/1/3486 3566/1/3566 +f 3550/1/3550 3576/1/3576 3566/1/3566 +f 3550/1/3550 3566/1/3566 3551/1/3551 +f 3548/1/3548 3550/1/3550 3551/1/3551 +f 3575/1/3575 3550/1/3550 3548/1/3548 +f 3547/1/3547 3575/1/3575 3548/1/3548 +f 3547/1/3547 3548/1/3548 3545/1/3545 +f 3546/1/3546 3547/1/3547 3545/1/3545 +f 3546/1/3546 3545/1/3545 3544/1/3544 +f 4789/1/4789 3546/1/3546 3544/1/3544 +f 4790/1/4790 3546/1/3546 4789/1/4789 +f 4790/1/4790 4789/1/4789 4788/1/4788 +f 4791/1/4791 4790/1/4790 4788/1/4788 +f 4791/1/4791 4788/1/4788 4792/1/4792 +f 4794/1/4794 4791/1/4791 4792/1/4792 +f 4794/1/4794 4792/1/4792 4793/1/4793 +f 4793/1/4793 4792/1/4792 4786/1/4786 +f 4796/1/4796 4791/1/4791 4794/1/4794 +f 4800/1/4800 4796/1/4796 4794/1/4794 +f 4800/1/4800 4794/1/4794 4801/1/4801 +f 4799/1/4799 4796/1/4796 4800/1/4800 +f 3485/1/3485 4799/1/4799 4800/1/4800 +f 4799/1/4799 3485/1/3485 4806/1/4806 +f 4806/1/4806 4798/1/4798 4799/1/4799 +f 4806/1/4806 4805/1/4805 4798/1/4798 +f 4805/1/4805 4797/1/4797 4798/1/4798 +f 4798/1/4798 4797/1/4797 4795/1/4795 +f 4798/1/4798 4795/1/4795 4796/1/4796 +f 4797/1/4797 4790/1/4790 4795/1/4795 +f 4797/1/4797 4967/1/4967 4790/1/4790 +f 4966/1/4966 4967/1/4967 4797/1/4797 +f 4964/1/4964 4967/1/4967 4966/1/4966 +f 4965/1/4965 4964/1/4964 4966/1/4966 +f 4965/1/4965 4966/1/4966 4805/1/4805 +f 4962/1/4962 4964/1/4964 4965/1/4965 +f 3487/1/3487 4962/1/4962 4965/1/4965 +f 4806/1/4806 3487/1/3487 4965/1/4965 +f 4960/1/4960 4962/1/4962 3487/1/3487 +f 3489/1/3489 4960/1/4960 3487/1/3487 +f 3487/1/3487 3488/1/3488 3489/1/3489 +f 3489/1/3489 3488/1/3488 3490/1/3490 +f 3489/1/3489 3490/1/3490 3491/1/3491 +f 4956/1/4956 3489/1/3489 3491/1/3491 +f 3491/1/3491 4954/1/4954 4956/1/4956 +f 4954/1/4954 4955/1/4955 4956/1/4956 +f 4956/1/4956 4955/1/4955 4957/1/4957 +f 4957/1/4957 4955/1/4955 4959/1/4959 +f 4957/1/4957 4959/1/4959 4960/1/4960 +f 4960/1/4960 4959/1/4959 4961/1/4961 +f 4959/1/4959 4963/1/4963 4961/1/4961 +f 4961/1/4961 4963/1/4963 4964/1/4964 +f 4959/1/4959 4958/1/4958 4963/1/4963 +f 4958/1/4958 4811/1/4811 4963/1/4963 +f 4963/1/4963 4811/1/4811 4810/1/4810 +f 4963/1/4963 4810/1/4810 4967/1/4967 +f 4967/1/4967 4810/1/4810 3546/1/3546 +f 4811/1/4811 4812/1/4812 4810/1/4810 +f 4812/1/4812 4813/1/4813 4810/1/4810 +f 4810/1/4810 4813/1/4813 3547/1/3547 +f 4812/1/4812 4814/1/4814 4813/1/4813 +f 4814/1/4814 4815/1/4815 4813/1/4813 +f 4813/1/4813 4815/1/4815 3575/1/3575 +f 4815/1/4815 4827/1/4827 3575/1/3575 +f 3575/1/3575 4827/1/4827 3576/1/3576 +f 4827/1/4827 4828/1/4828 3576/1/3576 +f 4827/1/4827 3488/1/3488 4828/1/4828 +f 3486/1/3486 4828/1/4828 3488/1/3488 +f 4824/1/4824 3488/1/3488 4827/1/4827 +f 4815/1/4815 4824/1/4824 4827/1/4827 +f 4820/1/4820 4824/1/4824 4815/1/4815 +f 4820/1/4820 4823/1/4823 4824/1/4824 +f 4823/1/4823 3490/1/3490 4824/1/4824 +f 4822/1/4822 3490/1/3490 4823/1/4823 +f 4819/1/4819 4822/1/4822 4823/1/4823 +f 4821/1/4821 4822/1/4822 4819/1/4819 +f 4818/1/4818 4821/1/4821 4819/1/4819 +f 4818/1/4818 4819/1/4819 4816/1/4816 +f 4817/1/4817 4818/1/4818 4816/1/4816 +f 4817/1/4817 4816/1/4816 4811/1/4811 +f 4833/1/4833 4818/1/4818 4817/1/4817 +f 4951/1/4951 4833/1/4833 4817/1/4817 +f 4951/1/4951 4817/1/4817 4958/1/4958 +f 4955/1/4955 4951/1/4951 4958/1/4958 +f 4952/1/4952 4951/1/4951 4955/1/4955 +f 4948/1/4948 4951/1/4951 4952/1/4952 +f 4953/1/4953 4948/1/4948 4952/1/4952 +f 4953/1/4953 4952/1/4952 4954/1/4954 +f 4949/1/4949 4948/1/4948 4953/1/4953 +f 3491/1/3491 4949/1/4949 4953/1/4953 +f 4949/1/4949 3491/1/3491 3493/1/3493 +f 3492/1/3492 3493/1/3493 3491/1/3491 +f 3494/1/3494 3493/1/3493 3492/1/3492 +f 4829/1/4829 3494/1/3494 3492/1/3492 +f 4829/1/4829 3492/1/3492 4826/1/4826 +f 4825/1/4825 4829/1/4829 4826/1/4826 +f 4825/1/4825 4826/1/4826 4822/1/4822 +f 4825/1/4825 4830/1/4830 4829/1/4829 +f 4831/1/4831 4830/1/4830 4825/1/4825 +f 4831/1/4831 4825/1/4825 4821/1/4821 +f 4832/1/4832 4831/1/4831 4821/1/4821 +f 4831/1/4831 4832/1/4832 4945/1/4945 +f 4945/1/4945 4832/1/4832 4833/1/4833 +f 4945/1/4945 4833/1/4833 4947/1/4947 +f 4945/1/4945 4947/1/4947 4946/1/4946 +f 4946/1/4946 3495/1/3495 4945/1/4945 +f 3494/1/3494 4945/1/4945 3495/1/3495 +f 4830/1/4830 4945/1/4945 3494/1/3494 +f 3493/1/3493 3495/1/3495 4946/1/4946 +f 4946/1/4946 4947/1/4947 3493/1/3493 +f 3493/1/3493 4947/1/4947 4948/1/4948 +f 4947/1/4947 4950/1/4950 4948/1/4948 +f 4947/1/4947 4833/1/4833 4950/1/4950 +f 4830/1/4830 4831/1/4831 4945/1/4945 +f 4826/1/4826 3492/1/3492 3490/1/3490 +f 4830/1/4830 3494/1/3494 4829/1/4829 +f 3494/1/3494 3495/1/3495 3493/1/3493 +f 3493/1/3493 4948/1/4948 4949/1/4949 +f 4948/1/4948 4950/1/4950 4951/1/4951 +f 4950/1/4950 4833/1/4833 4951/1/4951 +f 4833/1/4833 4832/1/4832 4818/1/4818 +f 4816/1/4816 4819/1/4819 4814/1/4814 +f 4819/1/4819 4820/1/4820 4814/1/4814 +f 4832/1/4832 4821/1/4821 4818/1/4818 +f 4821/1/4821 4825/1/4825 4822/1/4822 +f 4826/1/4826 3490/1/3490 4822/1/4822 +f 4819/1/4819 4823/1/4823 4820/1/4820 +f 4814/1/4814 4820/1/4820 4815/1/4815 +f 4816/1/4816 4814/1/4814 4812/1/4812 +f 4811/1/4811 4816/1/4816 4812/1/4812 +f 4958/1/4958 4817/1/4817 4811/1/4811 +f 4955/1/4955 4958/1/4958 4959/1/4959 +f 4954/1/4954 4952/1/4952 4955/1/4955 +f 4954/1/4954 3491/1/3491 4953/1/4953 +f 4956/1/4956 4957/1/4957 3489/1/3489 +f 3491/1/3491 3490/1/3490 3492/1/3492 +f 4824/1/4824 3490/1/3490 3488/1/3488 +f 3487/1/3487 3486/1/3486 3488/1/3488 +f 3486/1/3486 3487/1/3487 3485/1/3485 +f 3489/1/3489 4957/1/4957 4960/1/4960 +f 4960/1/4960 4961/1/4961 4962/1/4962 +f 4962/1/4962 4961/1/4961 4964/1/4964 +f 4964/1/4964 4963/1/4963 4967/1/4967 +f 4805/1/4805 4966/1/4966 4797/1/4797 +f 4965/1/4965 4805/1/4805 4806/1/4806 +f 3485/1/3485 3487/1/3487 4806/1/4806 +f 4799/1/4799 4798/1/4798 4796/1/4796 +f 4796/1/4796 4795/1/4795 4791/1/4791 +f 4792/1/4792 4788/1/4788 4786/1/4786 +f 4786/1/4786 4788/1/4788 4783/1/4783 +f 4786/1/4786 4783/1/4783 4784/1/4784 +f 4787/1/4787 4786/1/4786 4784/1/4784 +f 4784/1/4784 4783/1/4783 4779/1/4779 +f 4784/1/4784 4779/1/4779 4782/1/4782 +f 4785/1/4785 4784/1/4784 4782/1/4782 +f 4785/1/4785 4782/1/4782 4775/1/4775 +f 4788/1/4788 3543/1/3543 4783/1/4783 +f 4795/1/4795 4790/1/4790 4791/1/4791 +f 4788/1/4788 4789/1/4789 3543/1/3543 +f 4967/1/4967 3546/1/3546 4790/1/4790 +f 4810/1/4810 3547/1/3547 3546/1/3546 +f 3545/1/3545 3548/1/3548 3549/1/3549 +f 3545/1/3545 3549/1/3549 3542/1/3542 +f 4813/1/4813 3575/1/3575 3547/1/3547 +f 3575/1/3575 3576/1/3576 3550/1/3550 +f 3486/1/3486 3576/1/3576 4828/1/4828 +f 3551/1/3551 3566/1/3566 3565/1/3565 +f 3548/1/3548 3551/1/3551 3549/1/3549 +f 3549/1/3549 3553/1/3553 3554/1/3554 +f 3559/1/3559 3555/1/3555 3557/1/3557 +f 3559/1/3559 3557/1/3557 3558/1/3558 +f 3539/1/3539 3555/1/3555 3559/1/3559 +f 3559/1/3559 3561/1/3561 3539/1/3539 +f 3542/1/3542 3549/1/3549 3554/1/3554 +f 3544/1/3544 3545/1/3545 3542/1/3542 +f 4789/1/4789 3544/1/3544 3543/1/3543 +f 4783/1/4783 3543/1/3543 4779/1/4779 +f 4782/1/4782 4779/1/4779 4776/1/4776 +f 4769/1/4769 4772/1/4772 4773/1/4773 +f 4775/1/4775 4782/1/4782 4776/1/4776 +f 4804/1/4804 4785/1/4785 4775/1/4775 +f 4787/1/4787 4784/1/4784 4785/1/4785 +f 4793/1/4793 4786/1/4786 4787/1/4787 +f 4801/1/4801 4794/1/4794 4793/1/4793 +f 4801/1/4801 3485/1/3485 4800/1/4800 +f 4803/1/4803 3482/1/3482 4802/1/4802 +f 3485/1/3485 3484/1/3484 3486/1/3486 +f 3482/1/3482 3480/1/3480 3483/1/3483 +f 3556/1/3556 3552/1/3552 3484/1/3484 +f 3558/1/3558 3557/1/3557 3556/1/3556 +f 3558/1/3558 3560/1/3560 3559/1/3559 +f 3483/1/3483 3481/1/3481 3562/1/3562 +f 3559/1/3559 3560/1/3560 3561/1/3561 +f 3539/1/3539 3561/1/3561 3540/1/3540 +f 3539/1/3539 3538/1/3538 3555/1/3555 +f 3537/1/3537 3541/1/3541 3538/1/3538 +f 4781/1/4781 4780/1/4780 3537/1/3537 +f 4778/1/4778 4777/1/4777 4781/1/4781 +f 4808/1/4808 4771/1/4771 4807/1/4807 +f 4808/1/4808 4762/1/4762 4771/1/4771 +f 4778/1/4778 4770/1/4770 4777/1/4777 +f 4762/1/4762 4767/1/4767 4771/1/4771 +f 4762/1/4762 4765/1/4765 4767/1/4767 +f 4770/1/4770 4769/1/4769 4773/1/4773 +f 4765/1/4765 4766/1/4766 4767/1/4767 +f 4769/1/4769 4768/1/4768 4772/1/4772 +f 3480/1/3480 4774/1/4774 4768/1/4768 +f 4765/1/4765 3478/1/3478 4766/1/4766 +f 3483/1/3483 3480/1/3480 3481/1/3481 +f 3564/1/3564 3563/1/3563 3481/1/3481 +f 3533/1/3533 3567/1/3567 3564/1/3564 +f 3533/1/3533 3532/1/3532 3567/1/3567 +f 3530/1/3530 3535/1/3535 3532/1/3532 +f 3529/1/3529 3534/1/3534 3530/1/3530 +f 3527/1/3527 3536/1/3536 3529/1/3529 +f 4737/1/4737 4740/1/4740 3527/1/3527 +f 4732/1/4732 4736/1/4736 4737/1/4737 +f 4734/1/4734 4735/1/4735 4732/1/4732 +f 4733/1/4733 4841/1/4841 4734/1/4734 +f 4841/1/4841 4837/1/4837 4844/1/4844 +f 4836/1/4836 4835/1/4835 4838/1/4838 +f 4839/1/4839 4836/1/4836 4838/1/4838 +f 4837/1/4837 4834/1/4834 4751/1/4751 +f 4836/1/4836 3602/1/3602 4835/1/4835 +f 3600/1/3600 3602/1/3602 4836/1/4836 +f 4834/1/4834 4757/1/4757 4749/1/4749 +f 4757/1/4757 4755/1/4755 4749/1/4749 +f 4755/1/4755 4756/1/4756 4752/1/4752 +f 4752/1/4752 4756/1/4756 4753/1/4753 +f 4747/1/4747 4753/1/4753 4754/1/4754 +f 4744/1/4744 4754/1/4754 4764/1/4764 +f 4763/1/4763 4809/1/4809 4764/1/4764 +f 4763/1/4763 4762/1/4762 4808/1/4808 +f 4761/1/4761 4765/1/4765 4762/1/4762 +f 4758/1/4758 4759/1/4759 4760/1/4760 +f 4761/1/4761 3478/1/3478 4765/1/4765 +f 3476/1/3476 4759/1/4759 4758/1/4758 +f 3479/1/3479 3478/1/3478 3477/1/3477 +f 3475/1/3475 3474/1/3474 3476/1/3476 +f 3570/1/3570 3569/1/3569 3477/1/3477 +f 3523/1/3523 3568/1/3568 3570/1/3570 +f 3523/1/3523 3522/1/3522 3568/1/3568 +f 3521/1/3521 3531/1/3531 3522/1/3522 +f 3525/1/3525 3528/1/3528 3521/1/3521 +f 3518/1/3518 3526/1/3526 3525/1/3525 +f 3514/1/3514 3517/1/3517 3518/1/3518 +f 3514/1/3514 3513/1/3513 3517/1/3517 +f 3513/1/3513 3515/1/3515 3517/1/3517 +f 3506/1/3506 3502/1/3502 3510/1/3510 +f 3515/1/3515 3513/1/3513 3516/1/3516 +f 3517/1/3517 3515/1/3515 4722/1/4722 +f 3519/1/3519 3517/1/3517 4722/1/4722 +f 3518/1/3518 3517/1/3517 3519/1/3519 +f 4727/1/4727 4731/1/4731 3518/1/3518 +f 4726/1/4726 4730/1/4730 4727/1/4727 +f 4845/1/4845 4728/1/4728 4725/1/4725 +f 4726/1/4726 4729/1/4729 4730/1/4730 +f 4843/1/4843 4840/1/4840 4729/1/4729 +f 4839/1/4839 4838/1/4838 4840/1/4840 +f 3601/1/3601 4836/1/4836 4839/1/4839 +f 3601/1/3601 3600/1/3600 4836/1/4836 +f 3469/1/3469 3602/1/3602 3600/1/3600 +f 3471/1/3471 3472/1/3472 3469/1/3469 +f 3474/1/3474 3472/1/3472 3471/1/3471 +f 3571/1/3571 3474/1/3474 3573/1/3573 +f 3572/1/3572 3573/1/3573 3574/1/3574 +f 3574/1/3574 3524/1/3524 3572/1/3572 +f 3511/1/3511 3520/1/3520 3524/1/3524 +f 3509/1/3509 3512/1/3512 3511/1/3511 +f 3509/1/3509 3506/1/3506 3510/1/3510 +f 3508/1/3508 3507/1/3507 3504/1/3504 +f 3504/1/3504 3505/1/3505 3501/1/3501 +f 3506/1/3506 3503/1/3503 3502/1/3502 +f 3500/1/3500 3501/1/3501 3473/1/3473 +f 3498/1/3498 3499/1/3499 3502/1/3502 +f 3496/1/3496 3473/1/3473 3470/1/3470 +f 3497/1/3497 4715/1/4715 3499/1/3499 +f 4712/1/4712 4714/1/4714 4713/1/4713 +f 4718/1/4718 3499/1/3499 4715/1/4715 +f 4723/1/4723 4718/1/4718 4717/1/4717 +f 4678/1/4678 4717/1/4717 4719/1/4719 +f 4721/1/4721 4678/1/4678 3606/1/3606 +f 4724/1/4724 4721/1/4721 4725/1/4725 +f 4845/1/4845 4725/1/4725 3605/1/3605 +f 4845/1/4845 3598/1/3598 4728/1/4728 +f 3597/1/3597 4842/1/4842 3598/1/3598 +f 3596/1/3596 3599/1/3599 3597/1/3597 +f 3594/1/3594 3595/1/3595 3596/1/3596 +f 3581/1/3581 3595/1/3595 3594/1/3594 +f 3594/1/3594 3591/1/3591 3582/1/3582 +f 3592/1/3592 3590/1/3590 3593/1/3593 +f 3591/1/3591 3587/1/3587 3582/1/3582 +f 3590/1/3590 3603/1/3603 3589/1/3589 +f 3582/1/3582 3587/1/3587 3583/1/3583 +f 3586/1/3586 3589/1/3589 3588/1/3588 +f 3588/1/3588 3604/1/3604 3429/1/3429 +f 3585/1/3585 3435/1/3435 3434/1/3434 +f 3431/1/3431 3429/1/3429 3427/1/3427 +f 3433/1/3433 3430/1/3430 3432/1/3432 +f 3425/1/3425 3427/1/3427 3421/1/3421 +f 3426/1/3426 3420/1/3420 3424/1/3424 +f 3437/1/3437 3432/1/3432 3426/1/3426 +f 3436/1/3436 3432/1/3432 3437/1/3437 +f 3440/1/3440 3434/1/3434 3436/1/3436 +f 3579/1/3579 3584/1/3584 3440/1/3440 +f 3580/1/3580 3584/1/3584 3579/1/3579 +f 3582/1/3582 3583/1/3583 3580/1/3580 +f 3594/1/3594 3582/1/3582 3581/1/3581 +f 3465/1/3465 3595/1/3595 3581/1/3581 +f 3466/1/3466 3468/1/3468 3465/1/3465 +f 3470/1/3470 3466/1/3466 3467/1/3467 +f 4713/1/4713 3467/1/3467 4712/1/4712 +f 4712/1/4712 4685/1/4685 4714/1/4714 +f 4683/1/4683 4680/1/4680 4684/1/4684 +f 4683/1/4683 4682/1/4682 4680/1/4680 +f 4716/1/4716 4685/1/4685 4679/1/4679 +f 4677/1/4677 4679/1/4679 4676/1/4676 +f 4681/1/4681 4680/1/4680 4682/1/4682 +f 4673/1/4673 4676/1/4676 4671/1/4671 +f 3428/1/3428 4673/1/4673 4674/1/4674 +f 3419/1/3419 3428/1/3428 4674/1/4674 +f 3421/1/3421 3419/1/3419 3418/1/3418 +f 3422/1/3422 3418/1/3418 3417/1/3417 +f 3423/1/3423 3417/1/3417 3416/1/3416 +f 3413/1/3413 3415/1/3415 3412/1/3412 +f 3406/1/3406 3411/1/3411 3407/1/3407 +f 3456/1/3456 3406/1/3406 3408/1/3408 +f 3455/1/3455 3416/1/3416 3456/1/3456 +f 3448/1/3448 3447/1/3447 3455/1/3455 +f 3446/1/3446 3447/1/3447 3448/1/3448 +f 3442/1/3442 3443/1/3443 3446/1/3446 +f 3439/1/3439 3441/1/3441 3442/1/3442 +f 3444/1/3444 3438/1/3438 3439/1/3439 +f 3577/1/3577 3438/1/3438 3444/1/3444 +f 3463/1/3463 3578/1/3578 3577/1/3577 +f 3464/1/3464 3463/1/3463 3461/1/3461 +f 4693/1/4693 3464/1/3464 3461/1/3461 +f 4711/1/4711 4693/1/4693 4684/1/4684 +f 4691/1/4691 4683/1/4683 4684/1/4684 +f 4672/1/4672 4682/1/4682 4683/1/4683 +f 4686/1/4686 4668/1/4668 4672/1/4672 +f 4687/1/4687 4692/1/4692 4688/1/4688 +f 4690/1/4690 4668/1/4668 4686/1/4686 +f 4670/1/4670 4668/1/4668 4667/1/4667 +f 4665/1/4665 4670/1/4670 4667/1/4667 +f 4669/1/4669 4665/1/4665 4664/1/4664 +f 4661/1/4661 4662/1/4662 4659/1/4659 +f 4666/1/4666 4663/1/4663 4705/1/4705 +f 4708/1/4708 4664/1/4664 4666/1/4666 +f 3414/1/3414 4708/1/4708 2790/1/2790 +f 3412/1/3412 2790/1/2790 3410/1/3410 +f 3409/1/3409 3410/1/3410 3402/1/3402 +f 3401/1/3401 3402/1/3402 3399/1/3399 +f 3397/1/3397 3399/1/3399 3394/1/3394 +f 3398/1/3398 3404/1/3404 3397/1/3397 +f 3405/1/3405 3404/1/3404 3398/1/3398 +f 3453/1/3453 3457/1/3457 3405/1/3405 +f 3449/1/3449 3452/1/3452 3453/1/3453 +f 3451/1/3451 3445/1/3445 3449/1/3449 +f 3450/1/3450 3445/1/3445 3451/1/3451 +f 3460/1/3460 3462/1/3462 3450/1/3450 +f 4688/1/4688 3460/1/3460 4689/1/4689 +f 4710/1/4710 4689/1/4689 4694/1/4694 +f 4694/1/4694 4658/1/4658 4710/1/4710 +f 4659/1/4659 4658/1/4658 4655/1/4655 +f 4652/1/4652 4657/1/4657 4655/1/4655 +f 4652/1/4652 4651/1/4651 4656/1/4656 +f 4653/1/4653 4654/1/4654 4650/1/4650 +f 4654/1/4654 3459/1/3459 3458/1/3458 +f 3458/1/3458 3454/1/3454 3395/1/3395 +f 3395/1/3395 3396/1/3396 3390/1/3390 +f 3390/1/3390 3393/1/3393 3388/1/3388 +f 3388/1/3388 3392/1/3392 3391/1/3391 +f 3392/1/3392 3400/1/3400 3391/1/3391 +f 3400/1/3400 3403/1/3403 3609/1/3609 +f 3609/1/3609 3607/1/3607 3608/1/3608 +f 3610/1/3610 3611/1/3611 3616/1/3616 +f 3386/1/3386 3610/1/3610 3616/1/3616 +f 3387/1/3387 3386/1/3386 3383/1/3383 +f 3384/1/3384 3383/1/3383 3380/1/3380 +f 3381/1/3381 3382/1/3382 3378/1/3378 +f 4210/1/4210 4241/1/4241 4233/1/4233 +f 3378/1/3378 3618/1/3618 3379/1/3379 +f 4241/1/4241 3619/1/3619 4240/1/4240 +f 3617/1/3617 3614/1/3614 3618/1/3618 +f 3619/1/3619 3613/1/3613 3620/1/3620 +f 3615/1/3615 3612/1/3612 3614/1/3614 +f 3613/1/3613 2787/1/2787 3620/1/3620 +f 3608/1/3608 2785/1/2785 3612/1/3612 +f 2787/1/2787 2779/1/2779 2776/1/2776 +f 2779/1/2779 2780/1/2780 2776/1/2776 +f 2776/1/2776 2780/1/2780 2778/1/2778 +f 2788/1/2788 2786/1/2786 2785/1/2785 +f 2779/1/2779 4707/1/4707 2780/1/2780 +f 2789/1/2789 4704/1/4704 2786/1/2786 +f 4704/1/4704 4660/1/4660 4703/1/4703 +f 4703/1/4703 4701/1/4701 4702/1/4702 +f 4707/1/4707 4706/1/4706 2780/1/2780 +f 4702/1/4702 2770/1/2770 2782/1/2782 +f 2781/1/2781 2783/1/2783 2784/1/2784 +f 2780/1/2780 2781/1/2781 2778/1/2778 +f 2776/1/2776 2778/1/2778 2772/1/2772 +f 2787/1/2787 2776/1/2776 2791/1/2791 +f 4239/1/4239 2791/1/2791 4237/1/4237 +f 4234/1/4234 4237/1/4237 4235/1/4235 +f 4231/1/4231 4235/1/4235 4196/1/4196 +f 4197/1/4197 4196/1/4196 4194/1/4194 +f 4199/1/4199 4203/1/4203 4197/1/4197 +f 4202/1/4202 4204/1/4204 4199/1/4199 +f 4206/1/4206 4207/1/4207 4202/1/4202 +f 3380/1/3380 3377/1/3377 4206/1/4206 +f 3385/1/3385 3384/1/3384 3380/1/3380 +f 4211/1/4211 3389/1/3389 3385/1/3385 +f 4696/1/4696 4213/1/4213 4211/1/4211 +f 4695/1/4695 4651/1/4651 4696/1/4696 +f 4695/1/4695 4699/1/4699 4700/1/4700 +f 4702/1/4702 4699/1/4699 2770/1/2770 +f 4697/1/4697 4698/1/4698 4709/1/4709 +f 2769/1/2769 2767/1/2767 2770/1/2770 +f 2765/1/2765 4698/1/4698 2757/1/2757 +f 2766/1/2766 2764/1/2764 2767/1/2767 +f 2768/1/2768 2764/1/2764 2762/1/2762 +f 2759/1/2759 2761/1/2761 2762/1/2762 +f 2759/1/2759 2754/1/2754 2756/1/2756 +f 2763/1/2763 2757/1/2757 2758/1/2758 +f 2757/1/2757 4212/1/4212 2755/1/2755 +f 2755/1/2755 4205/1/4205 4200/1/4200 +f 4200/1/4200 4198/1/4198 4195/1/4195 +f 4195/1/4195 4193/1/4193 4191/1/4191 +f 4191/1/4191 4192/1/4192 4185/1/4185 +f 4192/1/4192 4186/1/4186 4185/1/4185 +f 4186/1/4186 4236/1/4236 4177/1/4177 +f 4177/1/4177 4178/1/4178 4176/1/4176 +f 4180/1/4180 4174/1/4174 4179/1/4179 +f 4183/1/4183 4180/1/4180 4179/1/4179 +f 4188/1/4188 4183/1/4183 4187/1/4187 +f 4190/1/4190 4187/1/4187 4057/1/4057 +f 4189/1/4189 4184/1/4184 4182/1/4182 +f 4218/1/4218 4220/1/4220 4222/1/4222 +f 4182/1/4182 4219/1/4219 4215/1/4215 +f 4220/1/4220 4173/1/4173 4221/1/4221 +f 4181/1/4181 4172/1/4172 4219/1/4219 +f 4173/1/4173 4170/1/4170 4167/1/4167 +f 4175/1/4175 4171/1/4171 4172/1/4172 +f 4170/1/4170 4168/1/4168 4167/1/4167 +f 4176/1/4176 2794/1/2794 4171/1/4171 +f 4168/1/4168 2796/1/2796 2800/1/2800 +f 2796/1/2796 2798/1/2798 2800/1/2800 +f 2800/1/2800 2798/1/2798 2801/1/2801 +f 2792/1/2792 2793/1/2793 2794/1/2794 +f 2796/1/2796 2795/1/2795 2798/1/2798 +f 2777/1/2777 2773/1/2773 2793/1/2793 +f 2773/1/2773 2774/1/2774 2797/1/2797 +f 2797/1/2797 2775/1/2775 2804/1/2804 +f 2795/1/2795 2799/1/2799 2798/1/2798 +f 2804/1/2804 2806/1/2806 2802/1/2802 +f 2803/1/2803 2807/1/2807 2838/1/2838 +f 2798/1/2798 2803/1/2803 2801/1/2801 +f 2800/1/2800 2801/1/2801 2837/1/2837 +f 4168/1/4168 2800/1/2800 4084/1/4084 +f 4169/1/4169 4084/1/4084 4080/1/4080 +f 4227/1/4227 4080/1/4080 4079/1/4079 +f 4228/1/4228 4079/1/4079 4073/1/4073 +f 4229/1/4229 4073/1/4073 4072/1/4072 +f 4059/1/4059 4226/1/4226 4229/1/4229 +f 4230/1/4230 4226/1/4226 4059/1/4059 +f 4217/1/4217 4223/1/4223 4230/1/4230 +f 4054/1/4054 4216/1/4216 4217/1/4217 +f 4057/1/4057 4214/1/4214 4054/1/4054 +f 4056/1/4056 4190/1/4190 4057/1/4057 +f 2749/1/2749 4201/1/4201 4056/1/4056 +f 2750/1/2750 2751/1/2751 2749/1/2749 +f 2752/1/2752 2754/1/2754 2750/1/2750 +f 2752/1/2752 2805/1/2805 2760/1/2760 +f 2804/1/2804 2805/1/2805 2806/1/2806 +f 2753/1/2753 2748/1/2748 2810/1/2810 +f 2808/1/2808 2809/1/2809 2806/1/2806 +f 2811/1/2811 2748/1/2748 2747/1/2747 +f 2812/1/2812 2815/1/2815 2809/1/2809 +f 2821/1/2821 2815/1/2815 2817/1/2817 +f 2816/1/2816 2819/1/2819 2817/1/2817 +f 2816/1/2816 2740/1/2740 2818/1/2818 +f 2813/1/2813 2747/1/2747 2814/1/2814 +f 2747/1/2747 2745/1/2745 2743/1/2743 +f 2743/1/2743 2746/1/2746 2744/1/2744 +f 2744/1/2744 4055/1/4055 4058/1/4058 +f 4058/1/4058 4060/1/4060 4061/1/4061 +f 4061/1/4061 4070/1/4070 4065/1/4065 +f 4070/1/4070 4071/1/4071 4065/1/4065 +f 4071/1/4071 4074/1/4074 4075/1/4075 +f 4075/1/4075 4078/1/4078 4077/1/4077 +f 4068/1/4068 4076/1/4076 4069/1/4069 +f 4066/1/4066 4068/1/4068 4069/1/4069 +f 4063/1/4063 4066/1/4066 4064/1/4064 +f 4062/1/4062 4064/1/4064 2885/1/2885 +f 2886/1/2886 4067/1/4067 4242/1/4242 +f 2878/1/2878 2866/1/2866 2856/1/2856 +f 4242/1/4242 2880/1/2880 2879/1/2879 +f 2866/1/2866 4088/1/4088 2864/1/2864 +f 4166/1/4166 4164/1/4164 2880/1/2880 +f 4088/1/4088 4087/1/4087 2865/1/2865 +f 4165/1/4165 4083/1/4083 4164/1/4164 +f 4087/1/4087 4085/1/4085 2865/1/2865 +f 4077/1/4077 4082/1/4082 4083/1/4083 +f 4085/1/4085 2835/1/2835 4086/1/4086 +f 2835/1/2835 2833/1/2833 4086/1/4086 +f 4086/1/4086 2833/1/2833 4101/1/4101 +f 4081/1/4081 2834/1/2834 4082/1/4082 +f 2835/1/2835 2830/1/2830 2833/1/2833 +f 2836/1/2836 2832/1/2832 2834/1/2834 +f 2832/1/2832 2831/1/2831 2827/1/2827 +f 2827/1/2827 2822/1/2822 2825/1/2825 +f 2830/1/2830 2828/1/2828 2833/1/2833 +f 2825/1/2825 2826/1/2826 2829/1/2829 +f 4103/1/4103 4107/1/4107 4104/1/4104 +f 2833/1/2833 4103/1/4103 4101/1/4101 +f 4086/1/4086 4101/1/4101 4100/1/4100 +f 4085/1/4085 4086/1/4086 2868/1/2868 +f 2863/1/2863 2868/1/2868 2860/1/2860 +f 2859/1/2859 2860/1/2860 2858/1/2858 +f 2853/1/2853 2858/1/2858 2851/1/2851 +f 2849/1/2849 2851/1/2851 2850/1/2850 +f 2848/1/2848 2852/1/2852 2849/1/2849 +f 2847/1/2847 2854/1/2854 2848/1/2848 +f 2884/1/2884 2883/1/2883 2847/1/2847 +f 2885/1/2885 2882/1/2882 2884/1/2884 +f 2735/1/2735 4062/1/4062 2885/1/2885 +f 2734/1/2734 2739/1/2739 2735/1/2735 +f 2737/1/2737 2738/1/2738 2734/1/2734 +f 2741/1/2741 2740/1/2740 2737/1/2737 +f 2741/1/2741 2824/1/2824 2823/1/2823 +f 2825/1/2825 2824/1/2824 2826/1/2826 +f 2742/1/2742 2733/1/2733 2839/1/2839 +f 2841/1/2841 2842/1/2842 2826/1/2826 +f 2840/1/2840 2733/1/2733 2731/1/2731 +f 2843/1/2843 4105/1/4105 2842/1/2842 +f 4102/1/4102 4105/1/4105 4106/1/4106 +f 4109/1/4109 4108/1/4108 4106/1/4106 +f 4109/1/4109 2728/1/2728 4113/1/4113 +f 4163/1/4163 2731/1/2731 4110/1/4110 +f 2731/1/2731 2732/1/2732 2729/1/2729 +f 2729/1/2729 2736/1/2736 2730/1/2730 +f 2730/1/2730 2846/1/2846 2844/1/2844 +f 2844/1/2844 2845/1/2845 2640/1/2640 +f 2640/1/2640 2639/1/2639 2636/1/2636 +f 2639/1/2639 2638/1/2638 2636/1/2636 +f 2638/1/2638 2861/1/2861 2633/1/2633 +f 2633/1/2633 2867/1/2867 2870/1/2870 +f 2632/1/2632 2634/1/2634 2635/1/2635 +f 2637/1/2637 2632/1/2632 2635/1/2635 +f 2641/1/2641 2637/1/2637 2643/1/2643 +f 2644/1/2644 2643/1/2643 2645/1/2645 +f 2646/1/2646 2642/1/2642 2647/1/2647 +f 2656/1/2656 2658/1/2658 2660/1/2660 +f 2647/1/2647 2657/1/2657 2652/1/2652 +f 2658/1/2658 2666/1/2666 2663/1/2663 +f 2877/1/2877 2874/1/2874 2657/1/2657 +f 2666/1/2666 2875/1/2875 2667/1/2667 +f 2873/1/2873 2872/1/2872 2874/1/2874 +f 2875/1/2875 2876/1/2876 2667/1/2667 +f 2870/1/2870 2871/1/2871 2872/1/2872 +f 2876/1/2876 4091/1/4091 4092/1/4092 +f 4091/1/4091 4094/1/4094 4092/1/4092 +f 4092/1/4092 4094/1/4094 4136/1/4136 +f 2869/1/2869 4090/1/4090 2871/1/2871 +f 4091/1/4091 4093/1/4093 4094/1/4094 +f 4089/1/4089 4097/1/4097 4090/1/4090 +f 4097/1/4097 4099/1/4099 4095/1/4095 +f 4095/1/4095 4111/1/4111 4114/1/4114 +f 4093/1/4093 4096/1/4096 4094/1/4094 +f 4114/1/4114 4121/1/4121 4162/1/4162 +f 4135/1/4135 4127/1/4127 4128/1/4128 +f 4094/1/4094 4135/1/4135 4136/1/4136 +f 4092/1/4092 4136/1/4136 4137/1/4137 +f 2876/1/2876 4092/1/4092 2673/1/2673 +f 2668/1/2668 2673/1/2673 2671/1/2671 +f 2669/1/2669 2671/1/2671 2672/1/2672 +f 2670/1/2670 2672/1/2672 2677/1/2677 +f 2678/1/2678 2677/1/2677 2679/1/2679 +f 2682/1/2682 2662/1/2662 2678/1/2678 +f 2661/1/2661 2662/1/2662 2682/1/2682 +f 2654/1/2654 2659/1/2659 2661/1/2661 +f 2649/1/2649 2653/1/2653 2654/1/2654 +f 2645/1/2645 2648/1/2648 2649/1/2649 +f 2650/1/2650 2644/1/2644 2645/1/2645 +f 2725/1/2725 2726/1/2726 2650/1/2650 +f 4117/1/4117 2727/1/2727 2725/1/2725 +f 4116/1/4116 2728/1/2728 4117/1/4117 +f 4116/1/4116 4115/1/4115 4112/1/4112 +f 4114/1/4114 4115/1/4115 4121/1/4121 +f 4118/1/4118 4119/1/4119 4120/1/4120 +f 4122/1/4122 4124/1/4124 4121/1/4121 +f 4123/1/4123 4119/1/4119 4125/1/4125 +f 4126/1/4126 4129/1/4129 4124/1/4124 +f 4133/1/4133 4129/1/4129 4134/1/4134 +f 4140/1/4140 4139/1/4139 4134/1/4134 +f 4140/1/4140 4132/1/4132 4141/1/4141 +f 4130/1/4130 4125/1/4125 4131/1/4131 +f 4125/1/4125 2724/1/2724 2691/1/2691 +f 2691/1/2691 2651/1/2651 2689/1/2689 +f 2689/1/2689 2655/1/2655 2684/1/2684 +f 2684/1/2684 2683/1/2683 2685/1/2685 +f 2685/1/2685 2680/1/2680 2686/1/2686 +f 2680/1/2680 2681/1/2681 2686/1/2686 +f 2681/1/2681 2674/1/2674 2706/1/2706 +f 2706/1/2706 2675/1/2675 2712/1/2712 +f 2705/1/2705 2707/1/2707 2708/1/2708 +f 2699/1/2699 2705/1/2705 2708/1/2708 +f 2687/1/2687 2699/1/2699 2695/1/2695 +f 2688/1/2688 2695/1/2695 2694/1/2694 +f 2696/1/2696 2700/1/2700 2701/1/2701 +f 2704/1/2704 2716/1/2716 4305/1/4305 +f 2701/1/2701 2714/1/2714 2702/1/2702 +f 2716/1/2716 2715/1/2715 2719/1/2719 +f 2709/1/2709 2713/1/2713 2714/1/2714 +f 2715/1/2715 2717/1/2717 2718/1/2718 +f 2710/1/2710 2711/1/2711 2713/1/2713 +f 2717/1/2717 2720/1/2720 2718/1/2718 +f 2712/1/2712 2723/1/2723 2711/1/2711 +f 2720/1/2720 3135/1/3135 3126/1/3126 +f 3135/1/3135 3130/1/3130 3126/1/3126 +f 3126/1/3126 3130/1/3130 3127/1/3127 +f 2676/1/2676 3136/1/3136 2723/1/2723 +f 3135/1/3135 4161/1/4161 3130/1/3130 +f 3137/1/3137 4145/1/4145 3136/1/3136 +f 4145/1/4145 4144/1/4144 4146/1/4146 +f 4146/1/4146 4142/1/4142 4147/1/4147 +f 4161/1/4161 4160/1/4160 3130/1/3130 +f 4147/1/4147 4158/1/4158 4159/1/4159 +f 3129/1/3129 3131/1/3131 3128/1/3128 +f 3130/1/3130 3129/1/3129 3127/1/3127 +f 3126/1/3126 3127/1/3127 3125/1/3125 +f 2720/1/2720 3126/1/3126 2721/1/2721 +f 2722/1/2722 2721/1/2721 4303/1/4303 +f 4302/1/4302 4303/1/4303 4299/1/4299 +f 4300/1/4300 4299/1/4299 4293/1/4293 +f 4273/1/4273 4293/1/4293 4290/1/4290 +f 4271/1/4271 4272/1/4272 4273/1/4273 +f 4277/1/4277 4276/1/4276 4271/1/4271 +f 2698/1/2698 4279/1/4279 4277/1/4277 +f 2694/1/2694 2697/1/2697 2698/1/2698 +f 2693/1/2693 2688/1/2688 2694/1/2694 +f 4153/1/4153 2690/1/2690 2693/1/2693 +f 4150/1/4150 2692/1/2692 4153/1/4153 +f 4149/1/4149 4132/1/4132 4150/1/4150 +f 4149/1/4149 4148/1/4148 4143/1/4143 +f 4147/1/4147 4148/1/4148 4158/1/4158 +f 4151/1/4151 4152/1/4152 4157/1/4157 +f 4156/1/4156 3132/1/3132 4158/1/4158 +f 4155/1/4155 4152/1/4152 2891/1/2891 +f 3139/1/3139 2893/1/2893 3132/1/3132 +f 2896/1/2896 2893/1/2893 2892/1/2892 +f 2889/1/2889 2895/1/2895 2892/1/2892 +f 2889/1/2889 2888/1/2888 2894/1/2894 +f 2890/1/2890 2891/1/2891 2887/1/2887 +f 2891/1/2891 4154/1/4154 2914/1/2914 +f 2914/1/2914 4280/1/4280 4281/1/4281 +f 4281/1/4281 4274/1/4274 4282/1/4282 +f 4282/1/4282 4275/1/4275 4286/1/4286 +f 4286/1/4286 4291/1/4291 4292/1/4292 +f 4291/1/4291 4294/1/4294 4292/1/4292 +f 4294/1/4294 4297/1/4297 4298/1/4298 +f 4298/1/4298 4307/1/4307 4306/1/4306 +f 4295/1/4295 4308/1/4308 4313/1/4313 +f 4296/1/4296 4295/1/4295 4313/1/4313 +f 4287/1/4287 4296/1/4296 4288/1/4288 +f 4285/1/4285 4288/1/4288 4289/1/4289 +f 4320/1/4320 4315/1/4315 4316/1/4316 +f 4325/1/4325 4328/1/4328 4329/1/4329 +f 4316/1/4316 4317/1/4317 4319/1/4319 +f 4328/1/4328 4343/1/4343 4335/1/4335 +f 4314/1/4314 4311/1/4311 4317/1/4317 +f 4343/1/4343 4312/1/4312 4342/1/4342 +f 4310/1/4310 4309/1/4309 4311/1/4311 +f 4312/1/4312 3138/1/3138 4342/1/4342 +f 4306/1/4306 3134/1/3134 4309/1/4309 +f 3138/1/3138 2952/1/2952 2953/1/2953 +f 2952/1/2952 2949/1/2949 2953/1/2953 +f 2953/1/2953 2949/1/2949 2950/1/2950 +f 3133/1/3133 3122/1/3122 3134/1/3134 +f 2952/1/2952 2951/1/2951 2949/1/2949 +f 3124/1/3124 3123/1/3123 3122/1/3122 +f 3123/1/3123 2903/1/2903 2904/1/2904 +f 2904/1/2904 2898/1/2898 2901/1/2901 +f 2951/1/2951 2907/1/2907 2949/1/2949 +f 2901/1/2901 2905/1/2905 2906/1/2906 +f 2948/1/2948 2946/1/2946 2942/1/2942 +f 2949/1/2949 2948/1/2948 2950/1/2950 +f 2953/1/2953 2950/1/2950 2954/1/2954 +f 3138/1/3138 2953/1/2953 4344/1/4344 +f 4341/1/4341 4344/1/4344 4340/1/4340 +f 4337/1/4337 4340/1/4340 4339/1/4339 +f 4333/1/4333 4339/1/4339 4338/1/4338 +f 4332/1/4332 4338/1/4338 4361/1/4361 +f 4331/1/4331 4330/1/4330 4332/1/4332 +f 4323/1/4323 4326/1/4326 4331/1/4331 +f 4322/1/4322 4324/1/4324 4323/1/4323 +f 4289/1/4289 4318/1/4318 4322/1/4322 +f 4284/1/4284 4285/1/4285 4289/1/4289 +f 2913/1/2913 4283/1/4283 4284/1/4284 +f 2909/1/2909 2912/1/2912 2913/1/2913 +f 2900/1/2900 2888/1/2888 2909/1/2909 +f 2900/1/2900 2902/1/2902 2899/1/2899 +f 2901/1/2901 2902/1/2902 2905/1/2905 +f 2908/1/2908 2910/1/2910 2911/1/2911 +f 2947/1/2947 2943/1/2943 2905/1/2905 +f 2945/1/2945 2910/1/2910 2916/1/2916 +f 2944/1/2944 2940/1/2940 2943/1/2943 +f 2939/1/2939 2940/1/2940 2936/1/2936 +f 2933/1/2933 2934/1/2934 2936/1/2936 +f 2933/1/2933 2919/1/2919 2930/1/2930 +f 2941/1/2941 2916/1/2916 2935/1/2935 +f 2916/1/2916 2915/1/2915 2918/1/2918 +f 2918/1/2918 2917/1/2917 2921/1/2921 +f 2921/1/2921 4369/1/4369 4367/1/4367 +f 4367/1/4367 4368/1/4368 4362/1/4362 +f 4362/1/4362 4360/1/4360 4358/1/4358 +f 4360/1/4360 4354/1/4354 4358/1/4358 +f 4354/1/4354 4353/1/4353 4351/1/4351 +f 4351/1/4351 4346/1/4346 4347/1/4347 +f 4355/1/4355 4352/1/4352 4357/1/4357 +f 4359/1/4359 4355/1/4355 4357/1/4357 +f 4363/1/4363 4359/1/4359 4364/1/4364 +f 4366/1/4366 4364/1/4364 2994/1/2994 +f 4370/1/4370 4365/1/4365 4371/1/4371 +f 2998/1/2998 3001/1/3001 3000/1/3000 +f 4371/1/4371 4373/1/4373 4372/1/4372 +f 3001/1/3001 4376/1/4376 4379/1/4379 +f 4374/1/4374 4375/1/4375 4373/1/4373 +f 4376/1/4376 4377/1/4377 4378/1/4378 +f 4356/1/4356 4350/1/4350 4375/1/4375 +f 4377/1/4377 4349/1/4349 4378/1/4378 +f 4347/1/4347 4348/1/4348 4350/1/4350 +f 4349/1/4349 2963/1/2963 3121/1/3121 +f 2963/1/2963 2964/1/2964 3121/1/3121 +f 3121/1/3121 2964/1/2964 4435/1/4435 +f 4345/1/4345 2958/1/2958 4348/1/4348 +f 2963/1/2963 2959/1/2959 2964/1/2964 +f 2956/1/2956 2955/1/2955 2958/1/2958 +f 2955/1/2955 2957/1/2957 2960/1/2960 +f 2960/1/2960 2938/1/2938 2961/1/2961 +f 2959/1/2959 2962/1/2962 2964/1/2964 +f 2961/1/2961 2966/1/2966 2965/1/2965 +f 2968/1/2968 2967/1/2967 4434/1/4434 +f 2964/1/2964 2968/1/2968 4435/1/4435 +f 3121/1/3121 4435/1/4435 4431/1/4431 +f 4349/1/4349 3121/1/3121 4380/1/4380 +f 3119/1/3119 4380/1/4380 3113/1/3113 +f 3118/1/3118 3113/1/3113 3117/1/3117 +f 3003/1/3003 3117/1/3117 3005/1/3005 +f 3004/1/3004 3005/1/3005 3006/1/3006 +f 2988/1/2988 2999/1/2999 3004/1/3004 +f 2993/1/2993 2999/1/2999 2988/1/2988 +f 2992/1/2992 2997/1/2997 2993/1/2993 +f 2991/1/2991 2995/1/2995 2992/1/2992 +f 2994/1/2994 2996/1/2996 2991/1/2991 +f 2925/1/2925 4366/1/4366 2994/1/2994 +f 2923/1/2923 2922/1/2922 2925/1/2925 +f 2924/1/2924 2920/1/2920 2923/1/2923 +f 2928/1/2928 2919/1/2919 2924/1/2924 +f 2928/1/2928 2931/1/2931 2932/1/2932 +f 2961/1/2961 2931/1/2931 2966/1/2966 +f 2929/1/2929 2927/1/2927 2970/1/2970 +f 2971/1/2971 2969/1/2969 2966/1/2966 +f 2972/1/2972 2927/1/2927 2973/1/2973 +f 2974/1/2974 2976/1/2976 2969/1/2969 +f 4433/1/4433 2976/1/2976 4428/1/4428 +f 4423/1/4423 4424/1/4424 4428/1/4428 +f 4423/1/4423 2978/1/2978 4419/1/4419 +f 2975/1/2975 2973/1/2973 4422/1/4422 +f 2973/1/2973 2926/1/2926 2977/1/2977 +f 2977/1/2977 2979/1/2979 2981/1/2981 +f 2981/1/2981 2987/1/2987 2986/1/2986 +f 2986/1/2986 2989/1/2989 2990/1/2990 +f 2990/1/2990 3007/1/3007 3008/1/3008 +f 3007/1/3007 3010/1/3010 3008/1/3008 +f 3010/1/3010 3114/1/3114 3110/1/3110 +f 3110/1/3110 3112/1/3112 3108/1/3108 +f 3011/1/3011 3111/1/3111 3017/1/3017 +f 3012/1/3012 3011/1/3011 3017/1/3017 +f 3009/1/3009 3012/1/3012 3013/1/3013 +f 2984/1/2984 3013/1/3013 3014/1/3014 +f 3016/1/3016 3015/1/3015 3018/1/3018 +f 3026/1/3026 3027/1/3027 3032/1/3032 +f 3018/1/3018 3025/1/3025 3022/1/3022 +f 3027/1/3027 3033/1/3033 3034/1/3034 +f 3024/1/3024 3116/1/3116 3025/1/3025 +f 3033/1/3033 3045/1/3045 3043/1/3043 +f 3115/1/3115 3106/1/3106 3116/1/3116 +f 3045/1/3045 3046/1/3046 3043/1/3043 +f 3108/1/3108 3107/1/3107 3106/1/3106 +f 3046/1/3046 4383/1/4383 4384/1/4384 +f 4383/1/4383 4438/1/4438 4384/1/4384 +f 4384/1/4384 4438/1/4438 4441/1/4441 +f 3109/1/3109 4382/1/4382 3107/1/3107 +f 4383/1/4383 4436/1/4436 4438/1/4438 +f 4381/1/4381 4432/1/4432 4382/1/4382 +f 4432/1/4432 4429/1/4429 4430/1/4430 +f 4430/1/4430 4425/1/4425 4426/1/4426 +f 4436/1/4436 4437/1/4437 4438/1/4438 +f 4426/1/4426 4443/1/4443 4439/1/4439 +f 4440/1/4440 4442/1/4442 4447/1/4447 +f 4438/1/4438 4440/1/4440 4441/1/4441 +f 4384/1/4384 4441/1/4441 4450/1/4450 +f 3046/1/3046 4384/1/4384 3044/1/3044 +f 3042/1/3042 3044/1/3044 3047/1/3047 +f 3041/1/3041 3047/1/3047 3048/1/3048 +f 3039/1/3039 3048/1/3048 3052/1/3052 +f 3040/1/3040 3052/1/3052 3090/1/3090 +f 3038/1/3038 3036/1/3036 3040/1/3040 +f 3029/1/3029 3030/1/3030 3038/1/3038 +f 3021/1/3021 3028/1/3028 3029/1/3029 +f 3014/1/3014 3019/1/3019 3021/1/3021 +f 2985/1/2985 2984/1/2984 3014/1/3014 +f 2983/1/2983 2982/1/2982 2985/1/2985 +f 4416/1/4416 2980/1/2980 2983/1/2983 +f 4417/1/4417 2978/1/2978 4416/1/4416 +f 4417/1/4417 4420/1/4420 4421/1/4421 +f 4426/1/4426 4420/1/4420 4443/1/4443 +f 4418/1/4418 4415/1/4415 4446/1/4446 +f 4445/1/4445 4444/1/4444 4443/1/4443 +f 4458/1/4458 4415/1/4415 4414/1/4414 +f 4457/1/4457 4449/1/4449 4444/1/4444 +f 4448/1/4448 4449/1/4449 4452/1/4452 +f 4454/1/4454 4453/1/4453 4452/1/4452 +f 4454/1/4454 4412/1/4412 4413/1/4413 +f 4456/1/4456 4414/1/4414 4455/1/4455 +f 4414/1/4414 3091/1/3091 3089/1/3089 +f 3089/1/3089 3020/1/3020 3085/1/3085 +f 3085/1/3085 3088/1/3088 3084/1/3084 +f 3084/1/3084 3087/1/3087 3070/1/3070 +f 3070/1/3070 3061/1/3061 3060/1/3060 +f 3061/1/3061 3054/1/3054 3060/1/3060 +f 3054/1/3054 3051/1/3051 3053/1/3053 +f 3053/1/3053 3050/1/3050 3055/1/3055 +f 3059/1/3059 3058/1/3058 3062/1/3062 +f 3063/1/3063 3059/1/3059 3062/1/3062 +f 3068/1/3068 3063/1/3063 3069/1/3069 +f 3071/1/3071 3069/1/3069 3072/1/3072 +f 3073/1/3073 3067/1/3067 3066/1/3066 +f 3080/1/3080 3095/1/3095 3096/1/3096 +f 3066/1/3066 3092/1/3092 3079/1/3079 +f 3095/1/3095 3094/1/3094 3097/1/3097 +f 3065/1/3065 3093/1/3093 3092/1/3092 +f 3094/1/3094 3103/1/3103 3099/1/3099 +f 3064/1/3064 3057/1/3057 3093/1/3093 +f 3103/1/3103 3101/1/3101 3099/1/3099 +f 3055/1/3055 3056/1/3056 3057/1/3057 +f 3101/1/3101 4389/1/4389 4393/1/4393 +f 4389/1/4389 4390/1/4390 4393/1/4393 +f 4393/1/4393 4390/1/4390 4396/1/4396 +f 3049/1/3049 4386/1/4386 3056/1/3056 +f 4389/1/4389 4388/1/4388 4390/1/4390 +f 4385/1/4385 4387/1/4387 4386/1/4386 +f 4387/1/4387 4459/1/4459 4391/1/4391 +f 4391/1/4391 4400/1/4400 4397/1/4397 +f 4388/1/4388 4392/1/4392 4390/1/4390 +f 4397/1/4397 4399/1/4399 4394/1/4394 +f 4395/1/4395 4398/1/4398 4404/1/4404 +f 4390/1/4390 4395/1/4395 4396/1/4396 +f 4393/1/4393 4396/1/4396 4485/1/4485 +f 3101/1/3101 4393/1/4393 3102/1/3102 +f 3100/1/3100 3102/1/3102 3104/1/3104 +f 3253/1/3253 3104/1/3104 3252/1/3252 +f 3254/1/3254 3252/1/3252 3249/1/3249 +f 3250/1/3250 3249/1/3249 3246/1/3246 +f 3257/1/3257 3256/1/3256 3250/1/3250 +f 3258/1/3258 3259/1/3259 3257/1/3257 +f 3076/1/3076 3081/1/3081 3258/1/3258 +f 3072/1/3072 3074/1/3074 3076/1/3076 +f 3075/1/3075 3071/1/3071 3072/1/3072 +f 3264/1/3264 3083/1/3083 3075/1/3075 +f 4409/1/4409 3086/1/3086 3264/1/3264 +f 4408/1/4408 4412/1/4412 4409/1/4409 +f 4408/1/4408 4401/1/4401 4402/1/4402 +f 4397/1/4397 4401/1/4401 4399/1/4399 +f 4407/1/4407 4410/1/4410 4411/1/4411 +f 4460/1/4460 4403/1/4403 4399/1/4399 +f 4461/1/4461 4410/1/4410 4462/1/4462 +f 4464/1/4464 4405/1/4405 4403/1/4403 +f 4406/1/4406 4405/1/4405 4487/1/4487 +f 4489/1/4489 4488/1/4488 4487/1/4487 +f 4489/1/4489 4463/1/4463 4491/1/4491 +f 4465/1/4465 4462/1/4462 4490/1/4490 +f 4462/1/4462 3263/1/3263 3261/1/3261 +f 3261/1/3261 3077/1/3077 3260/1/3260 +f 3244/1/3244 3240/1/3240 3241/1/3241 +f 3244/1/3244 3241/1/3241 3267/1/3267 +f 3266/1/3266 3244/1/3244 3267/1/3267 +f 3260/1/3260 3245/1/3245 3243/1/3243 +f 3245/1/3245 3248/1/3248 3242/1/3242 +f 3242/1/3242 3234/1/3234 3236/1/3236 +f 3232/1/3232 3229/1/3229 3230/1/3230 +f 3247/1/3247 3235/1/3235 3234/1/3234 +f 3235/1/3235 3251/1/3251 3227/1/3227 +f 3227/1/3227 3228/1/3228 3226/1/3226 +f 3229/1/3229 3224/1/3224 3230/1/3230 +f 3232/1/3232 3230/1/3230 3233/1/3233 +f 3237/1/3237 3232/1/3232 3233/1/3233 +f 3240/1/3240 3237/1/3237 3241/1/3241 +f 3272/1/3272 3274/1/3274 3275/1/3275 +f 3272/1/3272 3275/1/3275 3273/1/3273 +f 3238/1/3238 3239/1/3239 3271/1/3271 +f 3239/1/3239 3231/1/3231 3280/1/3280 +f 3231/1/3231 3222/1/3222 3280/1/3280 +f 3223/1/3223 3219/1/3219 3216/1/3216 +f 3225/1/3225 3220/1/3220 3222/1/3222 +f 3226/1/3226 3221/1/3221 3220/1/3220 +f 3105/1/3105 4478/1/4478 3221/1/3221 +f 4472/1/4472 4475/1/4475 4473/1/4473 +f 4472/1/4472 4473/1/4473 4469/1/4469 +f 4486/1/4486 4480/1/4480 4478/1/4478 +f 4480/1/4480 4482/1/4482 4479/1/4479 +f 4479/1/4479 4483/1/4483 4481/1/4481 +f 4475/1/4475 4477/1/4477 4473/1/4473 +f 4481/1/4481 4499/1/4499 4476/1/4476 +f 4474/1/4474 4502/1/4502 4506/1/4506 +f 4473/1/4473 4474/1/4474 4470/1/4470 +f 4469/1/4469 4473/1/4473 4470/1/4470 +f 3217/1/3217 4472/1/4472 4469/1/4469 +f 3219/1/3219 3217/1/3217 3216/1/3216 +f 3223/1/3223 3216/1/3216 3281/1/3281 +f 3278/1/3278 3223/1/3223 3281/1/3281 +f 3274/1/3274 3278/1/3278 3275/1/3275 +f 3273/1/3273 3275/1/3275 3276/1/3276 +f 3268/1/3268 3272/1/3272 3273/1/3273 +f 3267/1/3267 3241/1/3241 3268/1/3268 +f 3269/1/3269 3277/1/3277 3332/1/3332 +f 3277/1/3277 3287/1/3287 3332/1/3332 +f 3289/1/3289 3285/1/3285 3288/1/3288 +f 3289/1/3289 3288/1/3288 3293/1/3293 +f 3279/1/3279 3283/1/3283 3287/1/3287 +f 3283/1/3283 3282/1/3282 3284/1/3284 +f 3284/1/3284 3218/1/3218 3213/1/3213 +f 3285/1/3285 3286/1/3286 3288/1/3288 +f 3293/1/3293 3288/1/3288 3294/1/3294 +f 3304/1/3304 3289/1/3289 3293/1/3293 +f 3331/1/3331 3304/1/3304 3303/1/3303 +f 3270/1/3270 3331/1/3331 3303/1/3303 +f 4529/1/4529 3267/1/3267 3270/1/3270 +f 3266/1/3266 3267/1/3267 4529/1/4529 +f 3265/1/3265 3244/1/3244 3266/1/3266 +f 4493/1/4493 3262/1/3262 3265/1/3265 +f 4492/1/4492 4463/1/4463 4493/1/4493 +f 4492/1/4492 4496/1/4496 4494/1/4494 +f 4481/1/4481 4496/1/4496 4499/1/4499 +f 4495/1/4495 4497/1/4497 4498/1/4498 +f 4500/1/4500 4501/1/4501 4499/1/4499 +f 4504/1/4504 4505/1/4505 4501/1/4501 +f 4503/1/4503 4497/1/4497 4510/1/4510 +f 4509/1/4509 4505/1/4505 4504/1/4504 +f 4467/1/4467 4505/1/4505 4508/1/4508 +f 4512/1/4512 4513/1/4513 4508/1/4508 +f 4507/1/4507 4510/1/4510 4511/1/4511 +f 4514/1/4514 4513/1/4513 4512/1/4512 +f 4468/1/4468 4513/1/4513 4516/1/4516 +f 4517/1/4517 4516/1/4516 4518/1/4518 +f 4471/1/4471 4517/1/4517 4518/1/4518 +f 3211/1/3211 4466/1/4466 4471/1/4471 +f 3212/1/3212 3211/1/3211 3210/1/3210 +f 3213/1/3213 3210/1/3210 3214/1/3214 +f 3290/1/3290 3214/1/3214 3292/1/3292 +f 3291/1/3291 3292/1/3292 3295/1/3295 +f 3296/1/3296 3291/1/3291 3295/1/3295 +f 3300/1/3300 3296/1/3296 3301/1/3301 +f 3302/1/3302 3300/1/3300 3301/1/3301 +f 3330/1/3330 3302/1/3302 3312/1/3312 +f 4528/1/4528 3312/1/3312 4530/1/4530 +f 4523/1/4523 4527/1/4527 4528/1/4528 +f 4520/1/4520 4511/1/4511 4523/1/4523 +f 4520/1/4520 4521/1/4521 4515/1/4515 +f 4519/1/4519 4521/1/4521 4524/1/4524 +f 4522/1/4522 4526/1/4526 4525/1/4525 +f 4535/1/4535 4537/1/4537 4524/1/4524 +f 4536/1/4536 3356/1/3356 4537/1/4537 +f 4534/1/4534 4526/1/4526 4531/1/4531 +f 3357/1/3357 3356/1/3356 4536/1/4536 +f 3352/1/3352 3355/1/3355 3353/1/3353 +f 3352/1/3352 3350/1/3350 3355/1/3355 +f 3349/1/3349 3350/1/3350 3352/1/3352 +f 4649/1/4649 4537/1/4537 3356/1/3356 +f 3360/1/3360 4648/1/4648 4649/1/4649 +f 3361/1/3361 4646/1/4646 3360/1/3360 +f 3204/1/3204 4647/1/4647 3361/1/3361 +f 3206/1/3206 3209/1/3209 3204/1/3204 +f 3215/1/3215 3206/1/3206 3205/1/3205 +f 3297/1/3297 3205/1/3205 3320/1/3320 +f 3298/1/3298 3320/1/3320 3318/1/3318 +f 3299/1/3299 3298/1/3298 3306/1/3306 +f 3305/1/3305 3306/1/3306 3308/1/3308 +f 3307/1/3307 3305/1/3305 3308/1/3308 +f 3310/1/3310 3309/1/3309 3313/1/3313 +f 3315/1/3315 3323/1/3323 3325/1/3325 +f 3309/1/3309 3319/1/3319 3313/1/3313 +f 3319/1/3319 3321/1/3321 3322/1/3322 +f 3322/1/3322 3207/1/3207 3208/1/3208 +f 3323/1/3323 3324/1/3324 3325/1/3325 +f 3315/1/3315 3325/1/3325 3317/1/3317 +f 3316/1/3316 3315/1/3315 3317/1/3317 +f 3311/1/3311 3314/1/3314 3316/1/3316 +f 4532/1/4532 3307/1/3307 3311/1/3311 +f 4614/1/4614 4615/1/4615 4612/1/4612 +f 4612/1/4612 4616/1/4616 4617/1/4617 +f 4618/1/4618 4621/1/4621 4620/1/4620 +f 4621/1/4621 4622/1/4622 4620/1/4620 +f 4616/1/4616 4619/1/4619 4617/1/4617 +f 4621/1/4621 4628/1/4628 4624/1/4624 +f 4623/1/4623 3328/1/3328 4619/1/4619 +f 4628/1/4628 3329/1/3329 4624/1/4624 +f 3326/1/3326 3327/1/3327 3328/1/3328 +f 3208/1/3208 3201/1/3201 3327/1/3327 +f 3203/1/3203 3202/1/3202 3201/1/3201 +f 3202/1/3202 3359/1/3359 3149/1/3149 +f 3149/1/3149 3358/1/3358 3150/1/3150 +f 3150/1/3150 3355/1/3355 3350/1/3350 +f 3151/1/3151 3152/1/3152 3146/1/3146 +f 3145/1/3145 3151/1/3151 3146/1/3146 +f 3148/1/3148 3145/1/3145 3144/1/3144 +f 3200/1/3200 3148/1/3148 3144/1/3144 +f 3329/1/3329 3200/1/3200 4626/1/4626 +f 4624/1/4624 3329/1/3329 4626/1/4626 +f 4621/1/4621 4624/1/4624 4622/1/4622 +f 4620/1/4620 4622/1/4622 4609/1/4609 +f 4603/1/4603 4625/1/4625 4604/1/4604 +f 4604/1/4604 4627/1/4627 4629/1/4629 +f 4600/1/4600 4602/1/4602 4597/1/4597 +f 4600/1/4600 4597/1/4597 4596/1/4596 +f 4595/1/4595 4629/1/4629 4594/1/4594 +f 4591/1/4591 4592/1/4592 4586/1/4586 +f 4596/1/4596 4597/1/4597 4591/1/4591 +f 4601/1/4601 4600/1/4600 4596/1/4596 +f 4606/1/4606 4605/1/4605 4601/1/4601 +f 4607/1/4607 4605/1/4605 4606/1/4606 +f 4610/1/4610 4609/1/4609 4607/1/4607 +f 4611/1/4611 4613/1/4613 4610/1/4610 +f 4538/1/4538 4611/1/4611 4539/1/4539 +f 4533/1/4533 4532/1/4532 4538/1/4538 +f 4531/1/4531 4533/1/4533 3351/1/3351 +f 3352/1/3352 3351/1/3351 3349/1/3349 +f 3155/1/3155 3350/1/3350 3349/1/3349 +f 3153/1/3153 3155/1/3155 3156/1/3156 +f 3153/1/3153 3156/1/3156 3157/1/3157 +f 3344/1/3344 3157/1/3157 3345/1/3345 +f 3345/1/3345 3343/1/3343 3344/1/3344 +f 3347/1/3347 3348/1/3348 3346/1/3346 +f 3348/1/3348 3354/1/3354 3362/1/3362 +f 3344/1/3344 3343/1/3343 3341/1/3341 +f 3341/1/3341 3163/1/3163 3344/1/3344 +f 3159/1/3159 3163/1/3163 3162/1/3162 +f 3158/1/3158 3159/1/3159 3162/1/3162 +f 3142/1/3142 3158/1/3158 3160/1/3160 +f 3140/1/3140 3141/1/3141 3142/1/3142 +f 3199/1/3199 3140/1/3140 3198/1/3198 +f 4594/1/4594 3198/1/3198 4593/1/4593 +f 4587/1/4587 4593/1/4593 4584/1/4584 +f 4579/1/4579 4584/1/4584 4577/1/4577 +f 4583/1/4583 4584/1/4584 4579/1/4579 +f 4585/1/4585 4583/1/4583 4582/1/4582 +f 4588/1/4588 4585/1/4585 4582/1/4582 +f 4589/1/4589 4585/1/4585 4588/1/4588 +f 4598/1/4598 4590/1/4590 4589/1/4589 +f 4542/1/4542 4599/1/4599 4598/1/4598 +f 4540/1/4540 4608/1/4608 4542/1/4542 +f 3362/1/3362 4540/1/4540 3363/1/3363 +f 4541/1/4541 4544/1/4544 4545/1/4545 +f 4545/1/4545 4581/1/4581 4580/1/4580 +f 4580/1/4580 4578/1/4578 4572/1/4572 +f 4572/1/4572 4573/1/4573 4569/1/4569 +f 4548/1/4548 4571/1/4571 4549/1/4549 +f 4569/1/4569 4565/1/4565 4566/1/4566 +f 4569/1/4569 4570/1/4570 4565/1/4565 +f 4568/1/4568 4576/1/4576 4631/1/4631 +f 4574/1/4574 4575/1/4575 4570/1/4570 +f 4576/1/4576 3196/1/3196 4631/1/4631 +f 4630/1/4630 3197/1/3197 4575/1/4575 +f 3197/1/3197 3143/1/3143 3168/1/3168 +f 3143/1/3143 3165/1/3165 3168/1/3168 +f 3165/1/3165 3161/1/3161 3166/1/3166 +f 3166/1/3166 3161/1/3161 3167/1/3167 +f 3170/1/3170 3171/1/3171 3177/1/3177 +f 3180/1/3180 3177/1/3177 3179/1/3179 +f 3185/1/3185 3169/1/3169 3180/1/3180 +f 3196/1/3196 3185/1/3185 3833/1/3833 +f 4631/1/4631 3196/1/3196 3833/1/3833 +f 4568/1/4568 4631/1/4631 4567/1/4567 +f 4564/1/4564 4568/1/4568 4567/1/4567 +f 4563/1/4563 4564/1/4564 4561/1/4561 +f 4551/1/4551 4561/1/4561 4556/1/4556 +f 4550/1/4550 4553/1/4553 4551/1/4551 +f 4546/1/4546 4549/1/4549 4550/1/4550 +f 4543/1/4543 4547/1/4547 4546/1/4546 +f 3337/1/3337 4543/1/4543 3338/1/3338 +f 3339/1/3339 3363/1/3363 3337/1/3337 +f 3342/1/3342 3339/1/3339 3340/1/3340 +f 3340/1/3340 3164/1/3164 3342/1/3342 +f 3161/1/3161 3164/1/3164 3167/1/3167 +f 3166/1/3166 3167/1/3167 3172/1/3172 +f 3174/1/3174 3335/1/3335 3173/1/3173 +f 3175/1/3175 3172/1/3172 3176/1/3176 +f 3178/1/3178 3175/1/3175 3182/1/3182 +f 3333/1/3333 3183/1/3183 3182/1/3182 +f 3334/1/3334 3335/1/3335 3336/1/3336 +f 3366/1/3366 3183/1/3183 3333/1/3333 +f 3191/1/3191 3183/1/3183 3195/1/3195 +f 3369/1/3369 3194/1/3194 3195/1/3195 +f 3367/1/3367 3364/1/3364 3368/1/3368 +f 3336/1/3336 3365/1/3365 3364/1/3364 +f 3365/1/3365 4046/1/4046 4045/1/4045 +f 4045/1/4045 4552/1/4552 4041/1/4041 +f 4552/1/4552 4554/1/4554 4555/1/4555 +f 4559/1/4559 4558/1/4558 4560/1/4560 +f 4554/1/4554 4557/1/4557 4555/1/4555 +f 4558/1/4558 4637/1/4637 4643/1/4643 +f 4562/1/4562 4636/1/4636 4557/1/4557 +f 4636/1/4636 4634/1/4634 4635/1/4635 +f 4635/1/4635 4632/1/4632 4633/1/4633 +f 4637/1/4637 4638/1/4638 4643/1/4643 +f 4558/1/4558 4643/1/4643 4560/1/4560 +f 4043/1/4043 4560/1/4560 4044/1/4044 +f 4042/1/4042 4043/1/4043 4038/1/4038 +f 4031/1/4031 4035/1/4035 4032/1/4032 +f 4035/1/4035 4047/1/4047 4032/1/4032 +f 4032/1/4032 4047/1/4047 4030/1/4030 +f 4039/1/4039 4040/1/4040 4034/1/4034 +f 4035/1/4035 4051/1/4051 4047/1/4047 +f 4051/1/4051 4050/1/4050 4047/1/4047 +f 4047/1/4047 4050/1/4050 4048/1/4048 +f 4050/1/4050 4049/1/4049 4048/1/4048 +f 4052/1/4052 4049/1/4049 4050/1/4050 +f 4644/1/4644 4053/1/4053 4040/1/4040 +f 4051/1/4051 4052/1/4052 4050/1/4050 +f 4644/1/4644 4640/1/4640 4053/1/4053 +f 4052/1/4052 4641/1/4641 4049/1/4049 +f 4642/1/4642 4639/1/4639 4640/1/4640 +f 4641/1/4641 3831/1/3831 4049/1/4049 +f 4049/1/4049 3831/1/3831 3829/1/3829 +f 4633/1/4633 3832/1/3832 4639/1/4639 +f 3832/1/3832 3186/1/3186 3189/1/3189 +f 3189/1/3189 3184/1/3184 3188/1/3188 +f 3188/1/3188 3187/1/3187 3190/1/3190 +f 3828/1/3828 3193/1/3193 3824/1/3824 +f 3831/1/3831 3828/1/3828 3829/1/3829 +f 4049/1/4049 3829/1/3829 3852/1/3852 +f 4048/1/4048 4049/1/4049 3852/1/3852 +f 4047/1/4047 4048/1/4048 4029/1/4029 +f 4047/1/4047 4029/1/4029 4030/1/4030 +f 4028/1/4028 4032/1/4032 4030/1/4030 +f 4023/1/4023 4020/1/4020 4016/1/4016 +f 4026/1/4026 4021/1/4021 4022/1/4022 +f 4021/1/4021 3853/1/3853 3854/1/3854 +f 3854/1/3854 3850/1/3850 3851/1/3851 +f 4020/1/4020 4019/1/4019 4018/1/4018 +f 4020/1/4020 4018/1/4018 4016/1/4016 +f 4015/1/4015 4023/1/4023 4016/1/4016 +f 4024/1/4024 4023/1/4023 4015/1/4015 +f 4027/1/4027 4025/1/4025 4024/1/4024 +f 4033/1/4033 4028/1/4028 4027/1/4027 +f 4036/1/4036 4038/1/4038 4033/1/4033 +f 3374/1/3374 4036/1/4036 3375/1/3375 +f 3370/1/3370 3376/1/3376 3374/1/3374 +f 3369/1/3369 3370/1/3370 3371/1/3371 +f 3371/1/3371 3194/1/3194 3369/1/3369 +f 3190/1/3190 3194/1/3194 3836/1/3836 +f 3825/1/3825 3836/1/3836 3826/1/3826 +f 3372/1/3372 3373/1/3373 3848/1/3848 +f 3821/1/3821 3826/1/3826 3838/1/3838 +f 3818/1/3818 3821/1/3821 3822/1/3822 +f 3818/1/3818 3822/1/3822 3817/1/3817 +f 3839/1/3839 3817/1/3817 3822/1/3822 +f 3837/1/3837 3373/1/3373 3840/1/3840 +f 3842/1/3842 3817/1/3817 3839/1/3839 +f 3818/1/3818 3817/1/3817 3811/1/3811 +f 3813/1/3813 3818/1/3818 3811/1/3811 +f 3812/1/3812 3819/1/3819 3813/1/3813 +f 3827/1/3827 3812/1/3812 3807/1/3807 +f 3830/1/3830 3807/1/3807 3834/1/3834 +f 3851/1/3851 3834/1/3834 3855/1/3855 +f 3858/1/3858 3855/1/3855 3857/1/3857 +f 3867/1/3867 3857/1/3857 3860/1/3860 +f 4014/1/4014 4017/1/4017 3867/1/3867 +f 4013/1/4013 4014/1/4014 4012/1/4012 +f 4008/1/4008 4013/1/4013 4012/1/4012 +f 4009/1/4009 3869/1/3869 3870/1/3870 +f 3869/1/3869 3866/1/3866 3870/1/3870 +f 3866/1/3866 3861/1/3861 3865/1/3865 +f 3861/1/3861 3856/1/3856 3859/1/3859 +f 3871/1/3871 3864/1/3864 3872/1/3872 +f 3868/1/3868 3871/1/3871 3874/1/3874 +f 3880/1/3880 3868/1/3868 3874/1/3874 +f 4006/1/4006 4007/1/4007 3880/1/3880 +f 4005/1/4005 4008/1/4008 4006/1/4006 +f 4010/1/4010 4011/1/4011 4005/1/4005 +f 3846/1/3846 4037/1/4037 4010/1/4010 +f 3840/1/3840 3846/1/3846 3841/1/3841 +f 3843/1/3843 3841/1/3841 3844/1/3844 +f 3844/1/3844 3816/1/3816 3843/1/3843 +f 3814/1/3814 3816/1/3816 3815/1/3815 +f 3810/1/3810 3814/1/3814 3815/1/3815 +f 3808/1/3808 3810/1/3810 3809/1/3809 +f 3806/1/3806 3808/1/3808 3809/1/3809 +f 3779/1/3779 3776/1/3776 3775/1/3775 +f 3775/1/3775 3776/1/3776 3772/1/3772 +f 3778/1/3778 3777/1/3777 3781/1/3781 +f 3780/1/3780 3778/1/3778 3781/1/3781 +f 3783/1/3783 3780/1/3780 3784/1/3784 +f 3835/1/3835 3806/1/3806 3783/1/3783 +f 3859/1/3859 3835/1/3835 3862/1/3862 +f 3875/1/3875 3862/1/3862 3918/1/3918 +f 3873/1/3873 3875/1/3875 3878/1/3878 +f 3877/1/3877 3878/1/3878 3882/1/3882 +f 3881/1/3881 3877/1/3877 3882/1/3882 +f 3887/1/3887 3879/1/3879 3881/1/3881 +f 3849/1/3849 4004/1/4004 3887/1/3887 +f 3765/1/3765 3849/1/3849 3761/1/3761 +f 3766/1/3766 3847/1/3847 3765/1/3765 +f 3845/1/3845 3766/1/3766 3774/1/3774 +f 3774/1/3774 3773/1/3773 3845/1/3845 +f 3776/1/3776 3773/1/3773 3772/1/3772 +f 3775/1/3775 3772/1/3772 3771/1/3771 +f 3768/1/3768 3764/1/3764 3769/1/3769 +f 3770/1/3770 3771/1/3771 3767/1/3767 +f 3782/1/3782 3770/1/3770 3796/1/3796 +f 3763/1/3763 3793/1/3793 3796/1/3796 +f 3762/1/3762 3764/1/3764 3760/1/3760 +f 3797/1/3797 3793/1/3793 3763/1/3763 +f 3792/1/3792 3793/1/3793 3794/1/3794 +f 3792/1/3792 3794/1/3794 3795/1/3795 +f 3801/1/3801 3795/1/3795 3800/1/3800 +f 3798/1/3798 3756/1/3756 3799/1/3799 +f 3760/1/3760 3757/1/3757 3756/1/3756 +f 3757/1/3757 3759/1/3759 3758/1/3758 +f 3679/1/3679 3897/1/3897 3680/1/3680 +f 3759/1/3759 3888/1/3888 3758/1/3758 +f 3888/1/3888 3885/1/3885 3889/1/3889 +f 3889/1/3889 3886/1/3886 3890/1/3890 +f 3886/1/3886 3891/1/3891 3890/1/3890 +f 3894/1/3894 3893/1/3893 3901/1/3901 +f 3894/1/3894 3901/1/3901 3899/1/3899 +f 3884/1/3884 3892/1/3892 3891/1/3891 +f 3883/1/3883 3917/1/3917 3892/1/3892 +f 3917/1/3917 3863/1/3863 3916/1/3916 +f 3893/1/3893 3915/1/3915 3901/1/3901 +f 3899/1/3899 3901/1/3901 3902/1/3902 +f 3895/1/3895 3894/1/3894 3899/1/3899 +f 3896/1/3896 3895/1/3895 3898/1/3898 +f 3897/1/3897 3898/1/3898 3680/1/3680 +f 4003/1/4003 3900/1/3900 3904/1/3904 +f 3904/1/3904 3903/1/3903 3905/1/3905 +f 3681/1/3681 3906/1/3906 3678/1/3678 +f 3676/1/3676 3688/1/3688 3685/1/3685 +f 3688/1/3688 3686/1/3686 3685/1/3685 +f 3685/1/3685 3686/1/3686 3684/1/3684 +f 3686/1/3686 3687/1/3687 3684/1/3684 +f 3689/1/3689 3687/1/3687 3686/1/3686 +f 3905/1/3905 3690/1/3690 3682/1/3682 +f 3688/1/3688 3689/1/3689 3686/1/3686 +f 3905/1/3905 3909/1/3909 3690/1/3690 +f 3689/1/3689 3910/1/3910 3687/1/3687 +f 3907/1/3907 3908/1/3908 3909/1/3909 +f 3914/1/3914 3912/1/3912 3908/1/3908 +f 3916/1/3916 3787/1/3787 3912/1/3912 +f 3787/1/3787 3785/1/3785 3788/1/3788 +f 3788/1/3788 3789/1/3789 3790/1/3790 +f 3792/1/3792 3795/1/3795 3790/1/3790 +f 3803/1/3803 3804/1/3804 4002/1/4002 +f 3791/1/3791 4002/1/4002 3927/1/3927 +f 3913/1/3913 3927/1/3927 3921/1/3921 +f 3911/1/3911 3805/1/3805 3913/1/3913 +f 3910/1/3910 3911/1/3911 3687/1/3687 +f 3684/1/3684 3687/1/3687 3627/1/3627 +f 3685/1/3685 3684/1/3684 3683/1/3683 +f 3668/1/3668 3683/1/3683 3669/1/3669 +f 3665/1/3665 3668/1/3668 3669/1/3669 +f 3666/1/3666 3667/1/3667 3665/1/3665 +f 3671/1/3671 3667/1/3667 3666/1/3666 +f 3674/1/3674 3675/1/3675 3671/1/3671 +f 3677/1/3677 3678/1/3678 3674/1/3674 +f 3679/1/3679 3680/1/3680 3677/1/3677 +f 3755/1/3755 3679/1/3679 3751/1/3751 +f 3753/1/3753 3755/1/3755 3751/1/3751 +f 3800/1/3800 3753/1/3753 3801/1/3801 +f 3801/1/3801 3802/1/3802 3795/1/3795 +f 3928/1/3928 3802/1/3802 4000/1/4000 +f 3752/1/3752 3750/1/3750 3754/1/3754 +f 3998/1/3998 4000/1/4000 3999/1/3999 +f 3996/1/3996 3931/1/3931 3998/1/3998 +f 3993/1/3993 3992/1/3992 3996/1/3996 +f 3997/1/3997 3995/1/3995 3994/1/3994 +f 3750/1/3750 3749/1/3749 3995/1/3995 +f 3749/1/3749 3673/1/3673 3672/1/3672 +f 3672/1/3672 3670/1/3670 3657/1/3657 +f 3657/1/3657 3661/1/3661 3658/1/3658 +f 3658/1/3658 3660/1/3660 3659/1/3659 +f 3660/1/3660 3662/1/3662 3659/1/3659 +f 3643/1/3643 3644/1/3644 3640/1/3640 +f 3644/1/3644 3664/1/3664 3631/1/3631 +f 3663/1/3663 3626/1/3626 3662/1/3662 +f 3664/1/3664 3624/1/3624 3631/1/3631 +f 3625/1/3625 3621/1/3621 3626/1/3626 +f 3621/1/3621 3622/1/3622 3623/1/3623 +f 3623/1/3623 3919/1/3919 3920/1/3920 +f 3624/1/3624 3628/1/3628 3629/1/3629 +f 3629/1/3629 3634/1/3634 3632/1/3632 +f 3637/1/3637 3636/1/3636 3633/1/3633 +f 3634/1/3634 3638/1/3638 3639/1/3639 +f 3744/1/3744 3745/1/3745 3638/1/3638 +f 3723/1/3723 3745/1/3745 3744/1/3744 +f 3721/1/3721 3745/1/3745 3723/1/3723 +f 3720/1/3720 3721/1/3721 3714/1/3714 +f 3746/1/3746 3745/1/3745 3721/1/3721 +f 3648/1/3648 3745/1/3745 3746/1/3746 +f 3647/1/3647 3642/1/3642 3648/1/3648 +f 3646/1/3646 3642/1/3642 3647/1/3647 +f 3651/1/3651 3645/1/3645 3646/1/3646 +f 3653/1/3653 3652/1/3652 3651/1/3651 +f 3656/1/3656 3653/1/3653 3654/1/3654 +f 3747/1/3747 3656/1/3656 3654/1/3654 +f 3991/1/3991 3748/1/3748 3747/1/3747 +f 3993/1/3993 3991/1/3991 3990/1/3990 +f 3989/1/3989 3938/1/3938 3990/1/3990 +f 3938/1/3938 3934/1/3934 3932/1/3932 +f 3941/1/3941 3936/1/3936 3937/1/3937 +f 3930/1/3930 3932/1/3932 3934/1/3934 +f 3930/1/3930 3924/1/3924 3920/1/3920 +f 3935/1/3935 3923/1/3923 3933/1/3933 +f 3942/1/3942 3923/1/3923 3935/1/3935 +f 3942/1/3942 3925/1/3925 3923/1/3923 +f 3924/1/3924 3630/1/3630 3922/1/3922 +f 3635/1/3635 3633/1/3633 3630/1/3630 +f 3923/1/3923 3925/1/3925 3727/1/3727 +f 3727/1/3727 3925/1/3925 3968/1/3968 +f 3727/1/3727 3968/1/3968 3969/1/3969 +f 3635/1/3635 3637/1/3637 3633/1/3633 +f 3637/1/3637 3722/1/3722 3636/1/3636 +f 3718/1/3718 3719/1/3719 3722/1/3722 +f 3717/1/3717 3715/1/3715 3718/1/3718 +f 3725/1/3725 3716/1/3716 3717/1/3717 +f 3724/1/3724 3727/1/3727 3726/1/3726 +f 3726/1/3726 3727/1/3727 3969/1/3969 +f 3725/1/3725 3728/1/3728 3729/1/3729 +f 3729/1/3729 3732/1/3732 3733/1/3733 +f 3736/1/3736 3735/1/3735 3732/1/3732 +f 3741/1/3741 3739/1/3739 3734/1/3734 +f 3741/1/3741 2630/1/2630 3739/1/3739 +f 2623/1/2623 2630/1/2630 3741/1/3741 +f 3736/1/3736 3738/1/3738 3735/1/3735 +f 2630/1/2630 2629/1/2629 3739/1/3739 +f 2630/1/2630 2622/1/2622 2629/1/2629 +f 2622/1/2622 2628/1/2628 2629/1/2629 +f 2622/1/2622 2627/1/2627 2628/1/2628 +f 3737/1/3737 3735/1/3735 3738/1/3738 +f 3706/1/3706 3735/1/3735 3737/1/3737 +f 3701/1/3701 3705/1/3705 3706/1/3706 +f 3702/1/3702 3705/1/3705 3701/1/3701 +f 3700/1/3700 3707/1/3707 3702/1/3702 +f 3697/1/3697 3710/1/3710 3700/1/3700 +f 3694/1/3694 3713/1/3713 3697/1/3697 +f 3650/1/3650 3695/1/3695 3694/1/3694 +f 3649/1/3649 3650/1/3650 3655/1/3655 +f 3693/1/3693 3655/1/3655 3692/1/3692 +f 3986/1/3986 3693/1/3693 3692/1/3692 +f 3987/1/3987 3988/1/3988 3986/1/3986 +f 3987/1/3987 3941/1/3941 3937/1/3937 +f 3947/1/3947 3948/1/3948 3985/1/3985 +f 3939/1/3939 3936/1/3936 3941/1/3941 +f 3947/1/3947 3943/1/3943 3948/1/3948 +f 3946/1/3946 3943/1/3943 3947/1/3947 +f 3939/1/3939 3940/1/3940 3936/1/3936 +f 3935/1/3935 3940/1/3940 3942/1/3942 +f 3946/1/3946 3945/1/3945 3943/1/3943 +f 3944/1/3944 3925/1/3925 3942/1/3942 +f 3944/1/3944 3968/1/3968 3925/1/3925 +f 3969/1/3969 3968/1/3968 3731/1/3731 +f 3965/1/3965 3970/1/3970 3731/1/3731 +f 3966/1/3966 3970/1/3970 3965/1/3965 +f 3967/1/3967 3945/1/3945 3949/1/3949 +f 3965/1/3965 3963/1/3963 3962/1/3962 +f 3965/1/3965 3962/1/3962 3966/1/3966 +f 3966/1/3966 3972/1/3972 3970/1/3970 +f 3971/1/3971 3972/1/3972 3973/1/3973 +f 4917/1/4917 4919/1/4919 3975/1/3975 +f 3971/1/3971 3973/1/3973 3742/1/3742 +f 3741/1/3741 3742/1/3742 2623/1/2623 +f 2623/1/2623 2622/1/2622 2630/1/2630 +f 2621/1/2621 2625/1/2625 2622/1/2622 +f 2566/1/2566 2624/1/2624 2621/1/2621 +f 2620/1/2620 3743/1/3743 2569/1/2569 +f 2565/1/2565 2560/1/2560 2566/1/2566 +f 2560/1/2560 2554/1/2554 2566/1/2566 +f 2564/1/2564 2561/1/2561 2559/1/2559 +f 2561/1/2561 2558/1/2558 2559/1/2559 +f 2563/1/2563 2558/1/2558 2561/1/2561 +f 2563/1/2563 2562/1/2562 2558/1/2558 +f 2562/1/2562 2557/1/2557 2558/1/2558 +f 2557/1/2557 2562/1/2562 2594/1/2594 +f 2560/1/2560 2555/1/2555 2554/1/2554 +f 2566/1/2566 2554/1/2554 2624/1/2624 +f 2621/1/2621 2624/1/2624 2625/1/2625 +f 2625/1/2625 2627/1/2627 2622/1/2622 +f 2631/1/2631 2628/1/2628 2627/1/2627 +f 2544/1/2544 3740/1/3740 2631/1/2631 +f 3703/1/3703 3740/1/3740 2544/1/2544 +f 3699/1/3699 3704/1/3704 3703/1/3703 +f 2534/1/2534 3698/1/3698 3699/1/3699 +f 2538/1/2538 3698/1/3698 2534/1/2534 +f 2540/1/2540 2541/1/2541 2538/1/2538 +f 2542/1/2542 2541/1/2541 2540/1/2540 +f 3696/1/3696 3691/1/3691 2542/1/2542 +f 3985/1/3985 3696/1/3696 3947/1/3947 +f 3951/1/3951 3946/1/3946 3947/1/3947 +f 3946/1/3946 3949/1/3949 3945/1/3945 +f 3950/1/3950 3952/1/3952 3953/1/3953 +f 3954/1/3954 3957/1/3957 3949/1/3949 +f 3956/1/3956 3953/1/3953 3955/1/3955 +f 3958/1/3958 3961/1/3961 3957/1/3957 +f 3960/1/3960 3955/1/3955 3959/1/3959 +f 3982/1/3982 3980/1/3980 3979/1/3979 +f 3978/1/3978 3964/1/3964 3961/1/3961 +f 3982/1/3982 3977/1/3977 3980/1/3980 +f 3974/1/3974 3964/1/3964 3976/1/3976 +f 3974/1/3974 3976/1/3976 3975/1/3975 +f 4917/1/4917 3975/1/3975 4915/1/4915 +f 4917/1/4917 4918/1/4918 4919/1/4919 +f 4920/1/4920 4918/1/4918 4922/1/4922 +f 2569/1/2569 4922/1/4922 2567/1/2567 +f 4923/1/4923 2573/1/2573 2571/1/2571 +f 4899/1/4899 2573/1/2573 4923/1/4923 +f 2568/1/2568 2567/1/2567 2570/1/2570 +f 2568/1/2568 2563/1/2563 2561/1/2561 +f 2572/1/2572 2571/1/2571 2573/1/2573 +f 2563/1/2563 2574/1/2574 2562/1/2562 +f 2573/1/2573 2575/1/2575 2572/1/2572 +f 2573/1/2573 2577/1/2577 2575/1/2575 +f 2577/1/2577 2578/1/2578 2575/1/2575 +f 2576/1/2576 2577/1/2577 2573/1/2573 +f 2576/1/2576 2580/1/2580 2577/1/2577 +f 2581/1/2581 2577/1/2577 2580/1/2580 +f 2594/1/2594 2562/1/2562 2574/1/2574 +f 2595/1/2595 2557/1/2557 2594/1/2594 +f 2558/1/2558 2557/1/2557 2556/1/2556 +f 2552/1/2552 2553/1/2553 2556/1/2556 +f 2550/1/2550 2553/1/2553 2552/1/2552 +f 2546/1/2546 2549/1/2549 2550/1/2550 +f 2547/1/2547 2548/1/2548 2546/1/2546 +f 2543/1/2543 2626/1/2626 2547/1/2547 +f 2532/1/2532 2545/1/2545 2543/1/2543 +f 2531/1/2531 2535/1/2535 2532/1/2532 +f 2536/1/2536 2531/1/2531 2533/1/2533 +f 3959/1/3959 2537/1/2537 2536/1/2536 +f 3979/1/3979 3959/1/3959 3982/1/3982 +f 3983/1/3983 3977/1/3977 3982/1/3982 +f 3983/1/3983 4914/1/4914 3977/1/3977 +f 3981/1/3981 3984/1/3984 4847/1/4847 +f 4848/1/4848 4911/1/4911 4914/1/4914 +f 4909/1/4909 4910/1/4910 4849/1/4849 +f 4911/1/4911 4913/1/4913 4914/1/4914 +f 4916/1/4916 4913/1/4913 4912/1/4912 +f 4906/1/4906 4907/1/4907 4910/1/4910 +f 4926/1/4926 4921/1/4921 4912/1/4912 +f 4926/1/4926 4924/1/4924 4921/1/4921 +f 4899/1/4899 4923/1/4923 4924/1/4924 +f 4925/1/4925 4907/1/4907 4900/1/4900 +f 4899/1/4899 4901/1/4901 4898/1/4898 +f 4899/1/4899 2576/1/2576 2573/1/2573 +f 4888/1/4888 2583/1/2583 4893/1/4893 +f 2576/1/2576 2582/1/2582 2580/1/2580 +f 2582/1/2582 2585/1/2585 2580/1/2580 +f 2584/1/2584 2580/1/2580 2585/1/2585 +f 2588/1/2588 2585/1/2585 2589/1/2589 +f 2597/1/2597 2589/1/2589 2601/1/2601 +f 2597/1/2597 2601/1/2601 2602/1/2602 +f 2597/1/2597 2602/1/2602 2600/1/2600 +f 2600/1/2600 2602/1/2602 2608/1/2608 +f 2600/1/2600 2608/1/2608 2603/1/2603 +f 2598/1/2598 2600/1/2600 2603/1/2603 +f 2603/1/2603 2608/1/2608 2609/1/2609 +f 2603/1/2603 2609/1/2609 2606/1/2606 +f 2604/1/2604 2603/1/2603 2606/1/2606 +f 2604/1/2604 2606/1/2606 2607/1/2607 +f 2604/1/2604 2607/1/2607 4243/1/4243 +f 4243/1/4243 2607/1/2607 4244/1/4244 +f 4243/1/4243 4244/1/4244 4245/1/4245 +f 4246/1/4246 4243/1/4243 4245/1/4245 +f 4246/1/4246 4245/1/4245 4250/1/4250 +f 4868/1/4868 4246/1/4246 4250/1/4250 +f 4868/1/4868 4250/1/4250 4869/1/4869 +f 4929/1/4929 4868/1/4868 4869/1/4869 +f 4929/1/4929 4869/1/4869 4939/1/4939 +f 4940/1/4940 4929/1/4929 4939/1/4939 +f 4940/1/4940 4939/1/4939 4942/1/4942 +f 4942/1/4942 4941/1/4941 4940/1/4940 +f 4940/1/4940 4941/1/4941 4938/1/4938 +f 4941/1/4941 4937/1/4937 4938/1/4938 +f 4938/1/4938 4937/1/4937 4936/1/4936 +f 4936/1/4936 4929/1/4929 4938/1/4938 +f 4930/1/4930 4929/1/4929 4936/1/4936 +f 4936/1/4936 4935/1/4935 4930/1/4930 +f 4930/1/4930 4935/1/4935 4931/1/4931 +f 4930/1/4930 4931/1/4931 4928/1/4928 +f 4928/1/4928 4927/1/4927 4930/1/4930 +f 4931/1/4931 4935/1/4935 4934/1/4934 +f 4931/1/4931 4934/1/4934 4932/1/4932 +f 4935/1/4935 4256/1/4256 4934/1/4934 +f 4934/1/4934 4256/1/4256 4933/1/4933 +f 4933/1/4933 4256/1/4256 4254/1/4254 +f 4255/1/4255 4254/1/4254 4256/1/4256 +f 4255/1/4255 4256/1/4256 4257/1/4257 +f 4248/1/4248 4255/1/4255 4257/1/4257 +f 4248/1/4248 4257/1/4257 4261/1/4261 +f 4249/1/4249 4248/1/4248 4261/1/4261 +f 4249/1/4249 4261/1/4261 4262/1/4262 +f 4249/1/4249 4262/1/4262 4265/1/4265 +f 4249/1/4249 4265/1/4265 4266/1/4266 +f 4250/1/4250 4249/1/4249 4266/1/4266 +f 4265/1/4265 4268/1/4268 4266/1/4266 +f 4870/1/4870 4266/1/4266 4268/1/4268 +f 4870/1/4870 4268/1/4268 4943/1/4943 +f 4939/1/4939 4870/1/4870 4943/1/4943 +f 4943/1/4943 4268/1/4268 4270/1/4270 +f 4270/1/4270 4942/1/4942 4943/1/4943 +f 4942/1/4942 4270/1/4270 4944/1/4944 +f 4270/1/4270 4937/1/4937 4944/1/4944 +f 4270/1/4270 4258/1/4258 4937/1/4937 +f 4937/1/4937 4258/1/4258 4935/1/4935 +f 4270/1/4270 4263/1/4263 4258/1/4258 +f 4259/1/4259 4258/1/4258 4263/1/4263 +f 4259/1/4259 4263/1/4263 4262/1/4262 +f 4260/1/4260 4259/1/4259 4262/1/4262 +f 4260/1/4260 4256/1/4256 4259/1/4259 +f 4262/1/4262 4263/1/4263 4264/1/4264 +f 4263/1/4263 4269/1/4269 4264/1/4264 +f 4269/1/4269 4267/1/4267 4264/1/4264 +f 4265/1/4265 4264/1/4264 4267/1/4267 +f 4269/1/4269 4270/1/4270 4267/1/4267 +f 4256/1/4256 4258/1/4258 4259/1/4259 +f 4263/1/4263 4270/1/4270 4269/1/4269 +f 4270/1/4270 4268/1/4268 4267/1/4267 +f 4869/1/4869 4266/1/4266 4870/1/4870 +f 4267/1/4267 4268/1/4268 4265/1/4265 +f 4262/1/4262 4264/1/4264 4265/1/4265 +f 4261/1/4261 4260/1/4260 4262/1/4262 +f 4245/1/4245 4248/1/4248 4249/1/4249 +f 4245/1/4245 4247/1/4247 4248/1/4248 +f 4247/1/4247 4252/1/4252 4248/1/4248 +f 4247/1/4247 4251/1/4251 4252/1/4252 +f 4251/1/4251 4254/1/4254 4252/1/4252 +f 4251/1/4251 2614/1/2614 4254/1/4254 +f 4253/1/4253 2614/1/2614 4251/1/4251 +f 4244/1/4244 4253/1/4253 4251/1/4251 +f 4244/1/4244 2615/1/2615 4253/1/4253 +f 2615/1/2615 2614/1/2614 4253/1/4253 +f 2613/1/2613 2614/1/2614 2615/1/2615 +f 2607/1/2607 2613/1/2613 2615/1/2615 +f 2607/1/2607 2612/1/2612 2613/1/2613 +f 2613/1/2613 2612/1/2612 2616/1/2616 +f 2616/1/2616 2612/1/2612 2611/1/2611 +f 2611/1/2611 2617/1/2617 2616/1/2616 +f 2609/1/2609 2611/1/2611 2612/1/2612 +f 4244/1/4244 4251/1/4251 4247/1/4247 +f 4261/1/4261 4257/1/4257 4260/1/4260 +f 4248/1/4248 4252/1/4252 4255/1/4255 +f 4256/1/4256 4260/1/4260 4257/1/4257 +f 4252/1/4252 4254/1/4254 4255/1/4255 +f 4935/1/4935 4258/1/4258 4256/1/4256 +f 4930/1/4930 4927/1/4927 4929/1/4929 +f 4936/1/4936 4937/1/4937 4935/1/4935 +f 4941/1/4941 4944/1/4944 4937/1/4937 +f 4941/1/4941 4942/1/4942 4944/1/4944 +f 4939/1/4939 4943/1/4943 4942/1/4942 +f 4938/1/4938 4929/1/4929 4940/1/4940 +f 4939/1/4939 4869/1/4869 4870/1/4870 +f 4927/1/4927 4868/1/4868 4929/1/4929 +f 4927/1/4927 4867/1/4867 4868/1/4868 +f 4874/1/4874 4867/1/4867 4927/1/4927 +f 4869/1/4869 4250/1/4250 4266/1/4266 +f 4867/1/4867 4246/1/4246 4868/1/4868 +f 4867/1/4867 2605/1/2605 4246/1/4246 +f 4250/1/4250 4245/1/4245 4249/1/4249 +f 2605/1/2605 4243/1/4243 4246/1/4246 +f 4245/1/4245 4244/1/4244 4247/1/4247 +f 2607/1/2607 2615/1/2615 4244/1/4244 +f 2606/1/2606 2612/1/2612 2607/1/2607 +f 2606/1/2606 2609/1/2609 2612/1/2612 +f 2608/1/2608 2611/1/2611 2609/1/2609 +f 2608/1/2608 2610/1/2610 2611/1/2611 +f 2602/1/2602 2610/1/2610 2608/1/2608 +f 2601/1/2601 2619/1/2619 2602/1/2602 +f 2602/1/2602 2619/1/2619 2610/1/2610 +f 2617/1/2617 2611/1/2611 2610/1/2610 +f 4888/1/4888 2618/1/2618 2583/1/2583 +f 4888/1/4888 4889/1/4889 4887/1/4887 +f 4878/1/4878 4880/1/4880 4882/1/4882 +f 2617/1/2617 4886/1/4886 2616/1/2616 +f 2616/1/2616 2614/1/2614 2613/1/2613 +f 4879/1/4879 4254/1/4254 2614/1/2614 +f 4933/1/4933 4254/1/4254 4879/1/4879 +f 4934/1/4934 4933/1/4933 4932/1/4932 +f 4928/1/4928 4931/1/4931 4932/1/4932 +f 4928/1/4928 4874/1/4874 4927/1/4927 +f 4873/1/4873 4871/1/4871 4875/1/4875 +f 4874/1/4874 4866/1/4866 4867/1/4867 +f 4864/1/4864 4865/1/4865 4871/1/4871 +f 4866/1/4866 2605/1/2605 4867/1/4867 +f 4863/1/4863 2599/1/2599 4865/1/4865 +f 2605/1/2605 2604/1/2604 4243/1/4243 +f 2598/1/2598 2603/1/2603 2604/1/2604 +f 2598/1/2598 2597/1/2597 2600/1/2600 +f 2590/1/2590 2589/1/2589 2597/1/2597 +f 2590/1/2590 2588/1/2588 2589/1/2589 +f 2584/1/2584 2585/1/2585 2588/1/2588 +f 2581/1/2581 2580/1/2580 2584/1/2584 +f 2578/1/2578 2577/1/2577 2581/1/2581 +f 2575/1/2575 2578/1/2578 2579/1/2579 +f 2522/1/2522 2592/1/2592 2579/1/2579 +f 2520/1/2520 2593/1/2593 2522/1/2522 +f 2526/1/2526 2551/1/2551 2520/1/2520 +f 2525/1/2525 2529/1/2529 2526/1/2526 +f 2530/1/2530 2528/1/2528 2525/1/2525 +f 3984/1/3984 2530/1/2530 4846/1/4846 +f 4908/1/4908 4846/1/4846 4905/1/4905 +f 4904/1/4904 4903/1/4903 4905/1/4905 +f 4897/1/4897 4900/1/4900 4903/1/4903 +f 4895/1/4895 4894/1/4894 4897/1/4897 +f 4855/1/4855 4891/1/4891 4895/1/4895 +f 4890/1/4890 4891/1/4891 4855/1/4855 +f 4855/1/4855 4851/1/4851 4853/1/4853 +f 4902/1/4902 4850/1/4850 4854/1/4854 +f 4850/1/4850 2527/1/2527 2539/1/2539 +f 2539/1/2539 2524/1/2524 2519/1/2519 +f 4851/1/4851 4852/1/4852 4853/1/4853 +f 4855/1/4855 4853/1/4853 4896/1/4896 +f 4896/1/4896 4890/1/4890 4855/1/4855 +f 4890/1/4890 4889/1/4889 4891/1/4891 +f 4885/1/4885 4887/1/4887 4889/1/4889 +f 4884/1/4884 4887/1/4887 4885/1/4885 +f 4862/1/4862 4882/1/4882 4884/1/4884 +f 4860/1/4860 4857/1/4857 4861/1/4861 +f 4881/1/4881 4882/1/4882 4862/1/4862 +f 4881/1/4881 4878/1/4878 4882/1/4882 +f 4877/1/4877 4880/1/4880 4878/1/4878 +f 4876/1/4876 4877/1/4877 4873/1/4873 +f 4873/1/4873 4864/1/4864 4871/1/4871 +f 4883/1/4883 4859/1/4859 4872/1/4872 +f 4864/1/4864 4863/1/4863 4865/1/4865 +f 4857/1/4857 4858/1/4858 4859/1/4859 +f 4863/1/4863 2596/1/2596 2599/1/2599 +f 4856/1/4856 2521/1/2521 4858/1/4858 +f 2596/1/2596 2591/1/2591 2599/1/2599 +f 2518/1/2518 2587/1/2587 2591/1/2591 +f 2519/1/2519 2516/1/2516 2521/1/2521 +f 2518/1/2518 2517/1/2517 2586/1/2586 +f 2516/1/2516 2523/1/2523 2517/1/2517 +f 4968/1/4968 4969/1/4969 4970/1/4970 +f 4973/1/4973 4968/1/4968 4970/1/4970 +f 4973/1/4973 4970/1/4970 4980/1/4980 +f 4973/1/4973 4980/1/4980 4981/1/4981 +f 5050/1/5050 4973/1/4973 4981/1/4981 +f 5050/1/5050 4981/1/4981 5049/1/5049 +f 5146/1/5146 5050/1/5050 5049/1/5049 +f 5146/1/5146 5049/1/5049 5424/1/5424 +f 5427/1/5427 5146/1/5146 5424/1/5424 +f 5427/1/5427 5424/1/5424 5428/1/5428 +f 5428/1/5428 5445/1/5445 5427/1/5427 +f 5445/1/5445 5436/1/5436 5427/1/5427 +f 5427/1/5427 5436/1/5436 5430/1/5430 +f 5427/1/5427 5430/1/5430 5429/1/5429 +f 5430/1/5430 5431/1/5431 5429/1/5429 +f 5429/1/5429 5431/1/5431 5145/1/5145 +f 5145/1/5145 5051/1/5051 5429/1/5429 +f 5429/1/5429 5051/1/5051 5146/1/5146 +f 5145/1/5145 5144/1/5144 5051/1/5051 +f 5144/1/5144 4979/1/4979 5051/1/5051 +f 4979/1/4979 4973/1/4973 5051/1/5051 +f 4979/1/4979 4971/1/4971 4973/1/4973 +f 4976/1/4976 4971/1/4971 4979/1/4979 +f 5140/1/5140 4976/1/4976 4979/1/4979 +f 5134/1/5134 4976/1/4976 5140/1/5140 +f 5139/1/5139 5134/1/5134 5140/1/5140 +f 5139/1/5139 5140/1/5140 5142/1/5142 +f 5142/1/5142 5143/1/5143 5139/1/5139 +f 5143/1/5143 5141/1/5141 5139/1/5139 +f 5139/1/5139 5141/1/5141 5138/1/5138 +f 5138/1/5138 5141/1/5141 5137/1/5137 +f 5138/1/5138 5137/1/5137 5136/1/5136 +f 5136/1/5136 5134/1/5134 5138/1/5138 +f 5133/1/5133 5134/1/5134 5136/1/5136 +f 5133/1/5133 5127/1/5127 5134/1/5134 +f 5127/1/5127 4977/1/4977 5134/1/5134 +f 5127/1/5127 5056/1/5056 4977/1/4977 +f 5056/1/5056 4978/1/4978 4977/1/4977 +f 4977/1/4977 4978/1/4978 4975/1/4975 +f 4977/1/4977 4975/1/4975 4976/1/4976 +f 4978/1/4978 7004/1/7004 4975/1/4975 +f 4975/1/4975 7004/1/7004 4972/1/4972 +f 4975/1/4975 4972/1/4972 4971/1/4971 +f 4971/1/4971 4972/1/4972 4968/1/4968 +f 4972/1/4972 7006/1/7006 4968/1/4968 +f 4968/1/4968 7006/1/7006 4974/1/4974 +f 7006/1/7006 7010/1/7010 4974/1/4974 +f 4974/1/4974 7010/1/7010 4994/1/4994 +f 4974/1/4974 4994/1/4994 4969/1/4969 +f 4969/1/4969 4994/1/4994 4993/1/4993 +f 4969/1/4969 4993/1/4993 4987/1/4987 +f 4987/1/4987 4993/1/4993 4988/1/4988 +f 4987/1/4987 4988/1/4988 4983/1/4983 +f 4970/1/4970 4987/1/4987 4983/1/4983 +f 4983/1/4983 4988/1/4988 4989/1/4989 +f 4983/1/4983 4989/1/4989 4984/1/4984 +f 4980/1/4980 4983/1/4983 4984/1/4984 +f 4980/1/4980 4984/1/4984 4985/1/4985 +f 4980/1/4980 4985/1/4985 4986/1/4986 +f 4982/1/4982 4980/1/4980 4986/1/4986 +f 4982/1/4982 4986/1/4986 5012/1/5012 +f 4982/1/4982 5012/1/5012 5015/1/5015 +f 5048/1/5048 4982/1/4982 5015/1/5015 +f 5048/1/5048 5015/1/5015 5047/1/5047 +f 5416/1/5416 5048/1/5048 5047/1/5047 +f 5416/1/5416 5047/1/5047 5417/1/5417 +f 5411/1/5411 5416/1/5416 5417/1/5417 +f 5411/1/5411 5417/1/5417 5415/1/5415 +f 5415/1/5415 5412/1/5412 5411/1/5411 +f 5411/1/5411 5412/1/5412 5407/1/5407 +f 5411/1/5411 5407/1/5407 5409/1/5409 +f 5407/1/5407 5406/1/5406 5409/1/5409 +f 5409/1/5409 5406/1/5406 5410/1/5410 +f 5409/1/5409 5410/1/5410 5426/1/5426 +f 5426/1/5426 5416/1/5416 5409/1/5409 +f 5426/1/5426 5423/1/5423 5416/1/5416 +f 5425/1/5425 5423/1/5423 5426/1/5426 +f 5425/1/5425 5424/1/5424 5423/1/5423 +f 5426/1/5426 5410/1/5410 5425/1/5425 +f 5425/1/5425 5410/1/5410 5443/1/5443 +f 5425/1/5425 5443/1/5443 5445/1/5445 +f 5410/1/5410 5444/1/5444 5443/1/5443 +f 5443/1/5443 5444/1/5444 5438/1/5438 +f 5443/1/5443 5438/1/5438 5436/1/5436 +f 5436/1/5436 5438/1/5438 5434/1/5434 +f 5000/1/5000 5434/1/5434 5438/1/5438 +f 5000/1/5000 5438/1/5438 5004/1/5004 +f 5004/1/5004 5005/1/5005 5000/1/5000 +f 5000/1/5000 5005/1/5005 5003/1/5003 +f 5000/1/5000 5003/1/5003 4998/1/4998 +f 4998/1/4998 4995/1/4995 5000/1/5000 +f 4995/1/4995 5437/1/5437 5000/1/5000 +f 5437/1/5437 4995/1/4995 5442/1/5442 +f 5442/1/5442 5439/1/5439 5437/1/5437 +f 5437/1/5437 5439/1/5439 5435/1/5435 +f 5437/1/5437 5435/1/5435 5434/1/5434 +f 5431/1/5431 5434/1/5434 5435/1/5435 +f 5431/1/5431 5435/1/5435 5433/1/5433 +f 5433/1/5433 5435/1/5435 5439/1/5439 +f 5433/1/5433 5439/1/5439 5440/1/5440 +f 5433/1/5433 5440/1/5440 5142/1/5142 +f 5432/1/5432 5433/1/5433 5142/1/5142 +f 5142/1/5142 5144/1/5144 5432/1/5432 +f 5145/1/5145 5433/1/5433 5432/1/5432 +f 5440/1/5440 5439/1/5439 5441/1/5441 +f 5440/1/5440 5441/1/5441 5143/1/5143 +f 5442/1/5442 5441/1/5441 5439/1/5439 +f 5162/1/5162 5441/1/5441 5442/1/5442 +f 5158/1/5158 5162/1/5162 5442/1/5442 +f 5442/1/5442 4999/1/4999 5158/1/5158 +f 5158/1/5158 4999/1/4999 7020/1/7020 +f 5158/1/5158 7020/1/7020 7021/1/7021 +f 5158/1/5158 7021/1/7021 5155/1/5155 +f 5158/1/5158 5155/1/5155 5157/1/5157 +f 5159/1/5159 5158/1/5158 5157/1/5157 +f 5159/1/5159 5157/1/5157 5156/1/5156 +f 5156/1/5156 5149/1/5149 5159/1/5159 +f 5159/1/5159 5149/1/5149 5160/1/5160 +f 5159/1/5159 5160/1/5160 5161/1/5161 +f 5161/1/5161 5160/1/5160 5162/1/5162 +f 5141/1/5141 5162/1/5162 5160/1/5160 +f 5137/1/5137 5160/1/5160 5149/1/5149 +f 5137/1/5137 5149/1/5149 5135/1/5135 +f 5133/1/5133 5137/1/5137 5135/1/5135 +f 5133/1/5133 5135/1/5135 5132/1/5132 +f 5132/1/5132 5135/1/5135 5130/1/5130 +f 5130/1/5130 5127/1/5127 5132/1/5132 +f 5128/1/5128 5127/1/5127 5130/1/5130 +f 5130/1/5130 5131/1/5131 5128/1/5128 +f 5128/1/5128 5131/1/5131 5129/1/5129 +f 5128/1/5128 5129/1/5129 5126/1/5126 +f 5126/1/5126 5125/1/5125 5128/1/5128 +f 5124/1/5124 5125/1/5125 5126/1/5126 +f 5126/1/5126 5121/1/5121 5124/1/5124 +f 5124/1/5124 5121/1/5121 5120/1/5120 +f 5124/1/5124 5120/1/5120 5063/1/5063 +f 5063/1/5063 5120/1/5120 5122/1/5122 +f 5122/1/5122 5061/1/5061 5063/1/5063 +f 5061/1/5061 5060/1/5060 5063/1/5063 +f 5063/1/5063 5060/1/5060 5058/1/5058 +f 5063/1/5063 5058/1/5058 5125/1/5125 +f 5125/1/5125 5058/1/5058 5056/1/5056 +f 5058/1/5058 5057/1/5057 5056/1/5056 +f 5058/1/5058 5059/1/5059 5057/1/5057 +f 5059/1/5059 7000/1/7000 5057/1/5057 +f 5057/1/5057 7000/1/7000 7002/1/7002 +f 5057/1/5057 7002/1/7002 4978/1/4978 +f 7000/1/7000 7003/1/7003 7002/1/7002 +f 7002/1/7002 7003/1/7003 7047/1/7047 +f 7002/1/7002 7047/1/7047 7048/1/7048 +f 7002/1/7002 7048/1/7048 7004/1/7004 +f 7004/1/7004 7048/1/7048 7049/1/7049 +f 7004/1/7004 7049/1/7049 7050/1/7050 +f 7004/1/7004 7050/1/7050 7005/1/7005 +f 7050/1/7050 7014/1/7014 7005/1/7005 +f 7005/1/7005 7014/1/7014 7012/1/7012 +f 7005/1/7005 7012/1/7012 7007/1/7007 +f 4972/1/4972 7005/1/7005 7007/1/7007 +f 4972/1/4972 7007/1/7007 7008/1/7008 +f 7007/1/7007 7011/1/7011 7008/1/7008 +f 7008/1/7008 7011/1/7011 7009/1/7009 +f 7008/1/7008 7009/1/7009 7006/1/7006 +f 7011/1/7011 7016/1/7016 7009/1/7009 +f 7009/1/7009 7016/1/7016 7010/1/7010 +f 7018/1/7018 7010/1/7010 7016/1/7016 +f 7019/1/7019 7018/1/7018 7016/1/7016 +f 7019/1/7019 7016/1/7016 7017/1/7017 +f 7021/1/7021 7019/1/7019 7017/1/7017 +f 7021/1/7021 7017/1/7017 7022/1/7022 +f 7022/1/7022 7023/1/7023 7021/1/7021 +f 7022/1/7022 7026/1/7026 7023/1/7023 +f 7026/1/7026 5155/1/5155 7023/1/7023 +f 7026/1/7026 5153/1/5153 5155/1/5155 +f 5153/1/5153 5152/1/5152 5155/1/5155 +f 5153/1/5153 5151/1/5151 5152/1/5152 +f 5147/1/5147 5152/1/5152 5151/1/5151 +f 5147/1/5147 5151/1/5151 5150/1/5150 +f 5150/1/5150 5148/1/5148 5147/1/5147 +f 5131/1/5131 5147/1/5147 5148/1/5148 +f 5131/1/5131 5149/1/5149 5147/1/5147 +f 5150/1/5150 5117/1/5117 5148/1/5148 +f 5121/1/5121 5148/1/5148 5117/1/5117 +f 5121/1/5121 5117/1/5117 5118/1/5118 +f 5118/1/5118 5117/1/5117 5113/1/5113 +f 5118/1/5118 5113/1/5113 5112/1/5112 +f 5118/1/5118 5112/1/5112 5104/1/5104 +f 5119/1/5119 5118/1/5118 5104/1/5104 +f 5119/1/5119 5104/1/5104 5103/1/5103 +f 5123/1/5123 5119/1/5119 5103/1/5103 +f 5103/1/5103 5061/1/5061 5123/1/5123 +f 5069/1/5069 5061/1/5061 5103/1/5103 +f 5103/1/5103 5102/1/5102 5069/1/5069 +f 5069/1/5069 5102/1/5102 5068/1/5068 +f 5068/1/5068 5064/1/5064 5069/1/5069 +f 5067/1/5067 5064/1/5064 5068/1/5068 +f 5068/1/5068 5100/1/5100 5067/1/5067 +f 5067/1/5067 5100/1/5100 5099/1/5099 +f 5099/1/5099 5066/1/5066 5067/1/5067 +f 5077/1/5077 5066/1/5066 5099/1/5099 +f 5099/1/5099 5093/1/5093 5077/1/5077 +f 5077/1/5077 5093/1/5093 5078/1/5078 +f 5077/1/5077 5078/1/5078 5076/1/5076 +f 5076/1/5076 5073/1/5073 5077/1/5077 +f 5075/1/5075 5073/1/5073 5076/1/5076 +f 5075/1/5075 5071/1/5071 5073/1/5073 +f 5071/1/5071 5070/1/5070 5073/1/5073 +f 5073/1/5073 5070/1/5070 5066/1/5066 +f 5066/1/5066 5070/1/5070 5065/1/5065 +f 5066/1/5066 5065/1/5065 5064/1/5064 +f 5064/1/5064 5065/1/5065 5062/1/5062 +f 5064/1/5064 5062/1/5062 5061/1/5061 +f 5065/1/5065 6555/1/6555 5062/1/5062 +f 5062/1/5062 6555/1/6555 6556/1/6556 +f 5062/1/5062 6556/1/6556 5060/1/5060 +f 5060/1/5060 6556/1/6556 5059/1/5059 +f 6556/1/6556 6998/1/6998 5059/1/5059 +f 6556/1/6556 6996/1/6996 6998/1/6998 +f 6996/1/6996 6995/1/6995 6998/1/6998 +f 6998/1/6998 6995/1/6995 6997/1/6997 +f 6998/1/6998 6997/1/6997 7000/1/7000 +f 7000/1/7000 6997/1/6997 7001/1/7001 +f 6997/1/6997 6999/1/6999 7001/1/7001 +f 7001/1/7001 6999/1/6999 7045/1/7045 +f 7001/1/7001 7045/1/7045 7003/1/7003 +f 7003/1/7003 7045/1/7045 7044/1/7044 +f 7045/1/7045 7043/1/7043 7044/1/7044 +f 7044/1/7044 7043/1/7043 7037/1/7037 +f 7044/1/7044 7037/1/7037 7036/1/7036 +f 7047/1/7047 7044/1/7044 7036/1/7036 +f 7036/1/7036 7037/1/7037 7032/1/7032 +f 7036/1/7036 7032/1/7032 7035/1/7035 +f 7048/1/7048 7036/1/7036 7035/1/7035 +f 7035/1/7035 7032/1/7032 7028/1/7028 +f 7035/1/7035 7028/1/7028 7034/1/7034 +f 7049/1/7049 7035/1/7035 7034/1/7034 +f 7034/1/7034 7028/1/7028 7014/1/7014 +f 7015/1/7015 7014/1/7014 7028/1/7028 +f 7027/1/7027 7015/1/7015 7028/1/7028 +f 7027/1/7027 7028/1/7028 7029/1/7029 +f 7025/1/7025 7027/1/7027 7029/1/7029 +f 7025/1/7025 7029/1/7029 7030/1/7030 +f 7030/1/7030 7031/1/7031 7025/1/7025 +f 7025/1/7025 7031/1/7031 7026/1/7026 +f 7039/1/7039 7031/1/7031 7030/1/7030 +f 7030/1/7030 7033/1/7033 7039/1/7039 +f 7039/1/7039 7033/1/7033 7038/1/7038 +f 7039/1/7039 7038/1/7038 7042/1/7042 +f 7039/1/7039 7042/1/7042 7041/1/7041 +f 7041/1/7041 7040/1/7040 7039/1/7039 +f 7041/1/7041 5114/1/5114 7040/1/7040 +f 7040/1/7040 5114/1/5114 5154/1/5154 +f 7040/1/7040 5154/1/5154 7031/1/7031 +f 7031/1/7031 5154/1/5154 5153/1/5153 +f 5114/1/5114 5115/1/5115 5154/1/5154 +f 5154/1/5154 5115/1/5115 5151/1/5151 +f 5116/1/5116 5151/1/5151 5115/1/5115 +f 5116/1/5116 5115/1/5115 5113/1/5113 +f 5113/1/5113 5115/1/5115 5111/1/5111 +f 5113/1/5113 5111/1/5111 5108/1/5108 +f 5108/1/5108 5111/1/5111 5109/1/5109 +f 5108/1/5108 5109/1/5109 5106/1/5106 +f 5106/1/5106 5104/1/5104 5108/1/5108 +f 5106/1/5106 5105/1/5105 5104/1/5104 +f 5102/1/5102 5104/1/5104 5105/1/5105 +f 5102/1/5102 5105/1/5105 5100/1/5100 +f 5100/1/5100 5105/1/5105 5101/1/5101 +f 5100/1/5100 5101/1/5101 5093/1/5093 +f 5092/1/5092 5093/1/5093 5101/1/5101 +f 5092/1/5092 5101/1/5101 5098/1/5098 +f 5098/1/5098 5097/1/5097 5092/1/5092 +f 5092/1/5092 5097/1/5097 5094/1/5094 +f 5092/1/5092 5094/1/5094 5090/1/5090 +f 5090/1/5090 5085/1/5085 5092/1/5092 +f 5090/1/5090 5086/1/5086 5085/1/5085 +f 5080/1/5080 5085/1/5085 5086/1/5086 +f 5080/1/5080 5086/1/5086 5084/1/5084 +f 5080/1/5080 5084/1/5084 5082/1/5082 +f 5079/1/5079 5080/1/5080 5082/1/5082 +f 5079/1/5079 5082/1/5082 5081/1/5081 +f 5074/1/5074 5079/1/5079 5081/1/5081 +f 5074/1/5074 5081/1/5081 6552/1/6552 +f 6552/1/6552 6551/1/6551 5074/1/5074 +f 5074/1/5074 6551/1/6551 5071/1/5071 +f 6551/1/6551 6553/1/6553 5071/1/5071 +f 6553/1/6553 5072/1/5072 5071/1/5071 +f 6553/1/6553 5403/1/5403 5072/1/5072 +f 5403/1/5403 5402/1/5402 5072/1/5072 +f 5072/1/5072 5402/1/5402 6954/1/6954 +f 5072/1/5072 6954/1/6954 6554/1/6554 +f 5070/1/5070 5072/1/5072 6554/1/6554 +f 6554/1/6554 6954/1/6954 6956/1/6956 +f 6554/1/6554 6956/1/6956 6555/1/6555 +f 6555/1/6555 6956/1/6956 6959/1/6959 +f 6956/1/6956 6961/1/6961 6959/1/6959 +f 6959/1/6959 6961/1/6961 6986/1/6986 +f 6959/1/6959 6986/1/6986 6987/1/6987 +f 6959/1/6959 6987/1/6987 6996/1/6996 +f 6996/1/6996 6987/1/6987 6989/1/6989 +f 6987/1/6987 6984/1/6984 6989/1/6989 +f 6989/1/6989 6984/1/6984 6988/1/6988 +f 6989/1/6989 6988/1/6988 6995/1/6995 +f 6995/1/6995 6988/1/6988 6994/1/6994 +f 6988/1/6988 6990/1/6990 6994/1/6994 +f 6994/1/6994 6990/1/6990 6993/1/6993 +f 6994/1/6994 6993/1/6993 6999/1/6999 +f 6992/1/6992 6993/1/6993 6990/1/6990 +f 6991/1/6991 6992/1/6992 6990/1/6990 +f 6991/1/6991 6990/1/6990 6985/1/6985 +f 6980/1/6980 6991/1/6991 6985/1/6985 +f 6980/1/6980 6985/1/6985 6981/1/6981 +f 6980/1/6980 6981/1/6981 6978/1/6978 +f 6978/1/6978 5097/1/5097 6980/1/6980 +f 6980/1/6980 5097/1/5097 5114/1/5114 +f 6980/1/6980 5114/1/5114 7051/1/7051 +f 5097/1/5097 5110/1/5110 5114/1/5114 +f 5110/1/5110 5111/1/5111 5114/1/5114 +f 5097/1/5097 5107/1/5107 5110/1/5110 +f 5110/1/5110 5107/1/5107 5109/1/5109 +f 6978/1/6978 5163/1/5163 5097/1/5097 +f 5163/1/5163 5096/1/5096 5097/1/5097 +f 5164/1/5164 5096/1/5096 5163/1/5163 +f 6972/1/6972 5164/1/5164 5163/1/5163 +f 5169/1/5169 5164/1/5164 6972/1/6972 +f 6972/1/6972 6971/1/6971 5169/1/5169 +f 5169/1/5169 6971/1/6971 6974/1/6974 +f 5169/1/5169 6974/1/6974 6975/1/6975 +f 5169/1/5169 6975/1/6975 5165/1/5165 +f 5165/1/5165 5095/1/5095 5169/1/5169 +f 5095/1/5095 5165/1/5165 5166/1/5166 +f 5088/1/5088 5095/1/5095 5166/1/5166 +f 5088/1/5088 5166/1/5166 5170/1/5170 +f 5088/1/5088 5170/1/5170 6358/1/6358 +f 5091/1/5091 5088/1/5088 6358/1/6358 +f 5091/1/5091 6358/1/6358 6359/1/6359 +f 6359/1/6359 6360/1/6360 5091/1/5091 +f 5091/1/5091 6360/1/6360 5083/1/5083 +f 5091/1/5091 5083/1/5083 5087/1/5087 +f 5087/1/5087 5083/1/5083 5084/1/5084 +f 6364/1/6364 5083/1/5083 6360/1/6360 +f 6364/1/6364 6360/1/6360 6365/1/6365 +f 6364/1/6364 6365/1/6365 6372/1/6372 +f 6552/1/6552 6364/1/6364 6372/1/6372 +f 6372/1/6372 6374/1/6374 6552/1/6552 +f 6368/1/6368 6374/1/6374 6372/1/6372 +f 6368/1/6368 6373/1/6373 6374/1/6374 +f 6373/1/6373 6549/1/6549 6374/1/6374 +f 6374/1/6374 6549/1/6549 6550/1/6550 +f 6374/1/6374 6550/1/6550 6551/1/6551 +f 6549/1/6549 5400/1/5400 6550/1/6550 +f 6550/1/6550 5400/1/5400 5403/1/5403 +f 5400/1/5400 5399/1/5399 5403/1/5403 +f 5400/1/5400 5191/1/5191 5399/1/5399 +f 5191/1/5191 5184/1/5184 5399/1/5399 +f 5399/1/5399 5184/1/5184 5401/1/5401 +f 5399/1/5399 5401/1/5401 5402/1/5402 +f 5401/1/5401 5404/1/5404 5402/1/5402 +f 5402/1/5402 5404/1/5404 6955/1/6955 +f 5404/1/5404 5180/1/5180 6955/1/6955 +f 6955/1/6955 5180/1/5180 6977/1/6977 +f 6955/1/6955 6977/1/6977 6964/1/6964 +f 6955/1/6955 6964/1/6964 6957/1/6957 +f 6954/1/6954 6955/1/6955 6957/1/6957 +f 6954/1/6954 6957/1/6957 6958/1/6958 +f 6957/1/6957 6963/1/6963 6958/1/6958 +f 6958/1/6958 6963/1/6963 6962/1/6962 +f 6958/1/6958 6962/1/6962 6960/1/6960 +f 6956/1/6956 6958/1/6958 6960/1/6960 +f 6960/1/6960 6962/1/6962 6967/1/6967 +f 6960/1/6960 6967/1/6967 6961/1/6961 +f 6961/1/6961 6967/1/6967 6969/1/6969 +f 6967/1/6967 6968/1/6968 6969/1/6969 +f 6969/1/6969 6968/1/6968 6982/1/6982 +f 6986/1/6986 6969/1/6969 6982/1/6982 +f 6979/1/6979 6982/1/6982 6968/1/6968 +f 6973/1/6973 6979/1/6979 6968/1/6968 +f 6973/1/6973 6968/1/6968 6970/1/6970 +f 6972/1/6972 6973/1/6973 6970/1/6970 +f 6978/1/6978 6973/1/6973 6972/1/6972 +f 6970/1/6970 6968/1/6968 6966/1/6966 +f 6970/1/6970 6966/1/6966 6971/1/6971 +f 6966/1/6966 6962/1/6962 6971/1/6971 +f 6971/1/6971 6962/1/6962 6965/1/6965 +f 6978/1/6978 6979/1/6979 6973/1/6973 +f 6981/1/6981 6982/1/6982 6979/1/6979 +f 6981/1/6981 6984/1/6984 6982/1/6982 +f 6983/1/6983 6984/1/6984 6981/1/6981 +f 6967/1/6967 6966/1/6966 6968/1/6968 +f 6962/1/6962 6966/1/6966 6967/1/6967 +f 6963/1/6963 6965/1/6965 6962/1/6962 +f 6964/1/6964 6965/1/6965 6963/1/6963 +f 6964/1/6964 6976/1/6976 6965/1/6965 +f 6975/1/6975 6965/1/6965 6976/1/6976 +f 6975/1/6975 6976/1/6976 5174/1/5174 +f 6975/1/6975 5174/1/5174 5167/1/5167 +f 5167/1/5167 5174/1/5174 5173/1/5173 +f 5167/1/5167 5173/1/5173 5171/1/5171 +f 5168/1/5168 5167/1/5167 5171/1/5171 +f 5168/1/5168 5171/1/5171 5172/1/5172 +f 5170/1/5170 5168/1/5168 5172/1/5172 +f 5170/1/5170 5172/1/5172 5397/1/5397 +f 6429/1/6429 5170/1/5170 5397/1/5397 +f 6429/1/6429 5397/1/5397 6361/1/6361 +f 6358/1/6358 6429/1/6429 6361/1/6361 +f 5250/1/5250 6361/1/6361 5397/1/5397 +f 5251/1/5251 5250/1/5250 5397/1/5397 +f 5247/1/5247 5250/1/5250 5251/1/5251 +f 5245/1/5245 5247/1/5247 5251/1/5251 +f 5245/1/5245 5251/1/5251 5398/1/5398 +f 5186/1/5186 5245/1/5245 5398/1/5398 +f 5186/1/5186 5398/1/5398 5187/1/5187 +f 5186/1/5186 5187/1/5187 5183/1/5183 +f 5185/1/5185 5186/1/5186 5183/1/5183 +f 5188/1/5188 5185/1/5185 5183/1/5183 +f 5188/1/5188 5183/1/5183 5184/1/5184 +f 5184/1/5184 5183/1/5183 5182/1/5182 +f 5183/1/5183 5178/1/5178 5182/1/5182 +f 5178/1/5178 5181/1/5181 5182/1/5182 +f 5182/1/5182 5181/1/5181 5401/1/5401 +f 5401/1/5401 5181/1/5181 5179/1/5179 +f 5176/1/5176 5179/1/5179 5181/1/5181 +f 5173/1/5173 5179/1/5179 5176/1/5176 +f 5173/1/5173 5180/1/5180 5179/1/5179 +f 5178/1/5178 5176/1/5176 5181/1/5181 +f 5178/1/5178 5175/1/5175 5176/1/5176 +f 5171/1/5171 5176/1/5176 5175/1/5175 +f 5177/1/5177 5175/1/5175 5178/1/5178 +f 5187/1/5187 5177/1/5177 5178/1/5178 +f 5177/1/5177 5172/1/5172 5175/1/5175 +f 5251/1/5251 5172/1/5172 5177/1/5177 +f 5190/1/5190 5185/1/5185 5188/1/5188 +f 5191/1/5191 5190/1/5190 5188/1/5188 +f 5193/1/5193 5190/1/5190 5191/1/5191 +f 5199/1/5199 5193/1/5193 5191/1/5191 +f 5198/1/5198 5193/1/5193 5199/1/5199 +f 6380/1/6380 5198/1/5198 5199/1/5199 +f 6380/1/6380 5199/1/5199 6549/1/6549 +f 5204/1/5204 5198/1/5198 6380/1/6380 +f 6376/1/6376 5204/1/5204 6380/1/6380 +f 6376/1/6376 6380/1/6380 6373/1/6373 +f 6370/1/6370 6376/1/6376 6373/1/6373 +f 6370/1/6370 6373/1/6373 6369/1/6369 +f 6369/1/6369 6366/1/6366 6370/1/6370 +f 6370/1/6370 6366/1/6366 6371/1/6371 +f 6370/1/6370 6371/1/6371 6375/1/6375 +f 6375/1/6375 6371/1/6371 6377/1/6377 +f 6375/1/6375 6377/1/6377 6378/1/6378 +f 6378/1/6378 6379/1/6379 6375/1/6375 +f 6375/1/6375 6379/1/6379 6376/1/6376 +f 6383/1/6383 6379/1/6379 6378/1/6378 +f 6378/1/6378 6421/1/6421 6383/1/6383 +f 6383/1/6383 6421/1/6421 6418/1/6418 +f 6383/1/6383 6418/1/6418 6382/1/6382 +f 6382/1/6382 6418/1/6418 6423/1/6423 +f 6423/1/6423 6381/1/6381 6382/1/6382 +f 6382/1/6382 6381/1/6381 6379/1/6379 +f 6381/1/6381 5205/1/5205 6379/1/6379 +f 6379/1/6379 5205/1/5205 5204/1/5204 +f 5205/1/5205 5203/1/5203 5204/1/5204 +f 5205/1/5205 5206/1/5206 5203/1/5203 +f 5206/1/5206 5209/1/5209 5203/1/5203 +f 5203/1/5203 5209/1/5209 5202/1/5202 +f 5203/1/5203 5202/1/5202 5197/1/5197 +f 5203/1/5203 5197/1/5197 5198/1/5198 +f 5202/1/5202 5200/1/5200 5197/1/5197 +f 5197/1/5197 5200/1/5200 5196/1/5196 +f 5197/1/5197 5196/1/5196 5193/1/5193 +f 5193/1/5193 5196/1/5196 5192/1/5192 +f 5196/1/5196 5194/1/5194 5192/1/5192 +f 5192/1/5192 5194/1/5194 5189/1/5189 +f 5192/1/5192 5189/1/5189 5190/1/5190 +f 5194/1/5194 5195/1/5195 5189/1/5189 +f 5189/1/5189 5195/1/5195 5186/1/5186 +f 5194/1/5194 5242/1/5242 5195/1/5195 +f 5242/1/5242 5241/1/5241 5195/1/5195 +f 5241/1/5241 5244/1/5244 5195/1/5195 +f 5195/1/5195 5244/1/5244 5245/1/5245 +f 5241/1/5241 5243/1/5243 5244/1/5244 +f 5243/1/5243 5246/1/5246 5244/1/5244 +f 5244/1/5244 5246/1/5246 5247/1/5247 +f 5246/1/5246 5249/1/5249 5247/1/5247 +f 5248/1/5248 5249/1/5249 5246/1/5246 +f 5248/1/5248 5252/1/5252 5249/1/5249 +f 5252/1/5252 6409/1/6409 5249/1/5249 +f 5249/1/5249 6409/1/6409 6415/1/6415 +f 5249/1/5249 6415/1/6415 5250/1/5250 +f 6409/1/6409 6414/1/6414 6415/1/6415 +f 6415/1/6415 6414/1/6414 6361/1/6361 +f 6414/1/6414 6420/1/6420 6361/1/6361 +f 6420/1/6420 6362/1/6362 6361/1/6361 +f 6359/1/6359 6361/1/6361 6362/1/6362 +f 6362/1/6362 6363/1/6363 6359/1/6359 +f 6362/1/6362 6367/1/6367 6363/1/6363 +f 6366/1/6366 6363/1/6363 6367/1/6367 +f 6365/1/6365 6363/1/6363 6366/1/6366 +f 6368/1/6368 6365/1/6365 6366/1/6366 +f 6420/1/6420 6367/1/6367 6362/1/6362 +f 6422/1/6422 6367/1/6367 6420/1/6420 +f 6416/1/6416 6422/1/6422 6420/1/6420 +f 6416/1/6416 6421/1/6421 6422/1/6422 +f 6421/1/6421 6377/1/6377 6422/1/6422 +f 6422/1/6422 6377/1/6377 6367/1/6367 +f 6414/1/6414 6416/1/6416 6420/1/6420 +f 6413/1/6413 6416/1/6416 6414/1/6414 +f 6413/1/6413 6412/1/6412 6416/1/6416 +f 6412/1/6412 6417/1/6417 6416/1/6416 +f 6417/1/6417 6418/1/6418 6416/1/6416 +f 6417/1/6417 6419/1/6419 6418/1/6418 +f 6410/1/6410 6419/1/6419 6417/1/6417 +f 6411/1/6411 6410/1/6410 6417/1/6417 +f 6408/1/6408 6410/1/6410 6411/1/6411 +f 6408/1/6408 6411/1/6411 6412/1/6412 +f 6403/1/6403 6410/1/6410 6408/1/6408 +f 6407/1/6407 6403/1/6403 6408/1/6408 +f 6407/1/6407 6408/1/6408 6409/1/6409 +f 6409/1/6409 6408/1/6408 6413/1/6413 +f 6405/1/6405 6403/1/6403 6407/1/6407 +f 5255/1/5255 6405/1/6405 6407/1/6407 +f 5255/1/5255 6407/1/6407 5252/1/5252 +f 5254/1/5254 5255/1/5255 5252/1/5252 +f 5254/1/5254 5252/1/5252 5253/1/5253 +f 5232/1/5232 5254/1/5254 5253/1/5253 +f 5232/1/5232 5253/1/5253 5237/1/5237 +f 5233/1/5233 5232/1/5232 5237/1/5237 +f 5233/1/5233 5237/1/5237 5234/1/5234 +f 5231/1/5231 5233/1/5233 5234/1/5234 +f 5231/1/5231 5234/1/5234 5235/1/5235 +f 5236/1/5236 5231/1/5231 5235/1/5235 +f 5236/1/5236 5235/1/5235 5200/1/5200 +f 5200/1/5200 5235/1/5235 5201/1/5201 +f 5235/1/5235 5238/1/5238 5201/1/5201 +f 5201/1/5201 5238/1/5238 5240/1/5240 +f 5201/1/5201 5240/1/5240 5194/1/5194 +f 5238/1/5238 5241/1/5241 5240/1/5240 +f 5213/1/5213 5231/1/5231 5236/1/5236 +f 5202/1/5202 5213/1/5213 5236/1/5236 +f 5213/1/5213 5228/1/5228 5231/1/5231 +f 5228/1/5228 5227/1/5227 5231/1/5231 +f 5226/1/5226 5227/1/5227 5228/1/5228 +f 5212/1/5212 5226/1/5226 5228/1/5228 +f 5211/1/5211 5226/1/5226 5212/1/5212 +f 5209/1/5209 5211/1/5211 5212/1/5212 +f 5209/1/5209 5212/1/5212 5213/1/5213 +f 5210/1/5210 5211/1/5211 5209/1/5209 +f 5210/1/5210 5215/1/5215 5211/1/5211 +f 5215/1/5215 5220/1/5220 5211/1/5211 +f 5215/1/5215 5219/1/5219 5220/1/5220 +f 5219/1/5219 5223/1/5223 5220/1/5220 +f 5220/1/5220 5223/1/5223 5225/1/5225 +f 5220/1/5220 5225/1/5225 5226/1/5226 +f 5223/1/5223 5229/1/5229 5225/1/5225 +f 5225/1/5225 5229/1/5229 5230/1/5230 +f 5225/1/5225 5230/1/5230 5227/1/5227 +f 5227/1/5227 5230/1/5230 5232/1/5232 +f 5229/1/5229 5254/1/5254 5230/1/5230 +f 5229/1/5229 5256/1/5256 5254/1/5254 +f 5259/1/5259 5256/1/5256 5229/1/5229 +f 5259/1/5259 5257/1/5257 5256/1/5256 +f 5257/1/5257 5255/1/5255 5256/1/5256 +f 5257/1/5257 5258/1/5258 5255/1/5255 +f 5261/1/5261 5258/1/5258 5257/1/5257 +f 5262/1/5262 5261/1/5261 5257/1/5257 +f 5262/1/5262 5257/1/5257 5260/1/5260 +f 5222/1/5222 5262/1/5262 5260/1/5260 +f 5222/1/5222 5260/1/5260 5224/1/5224 +f 5222/1/5222 5224/1/5224 5219/1/5219 +f 5221/1/5221 5222/1/5222 5219/1/5219 +f 5218/1/5218 5221/1/5221 5219/1/5219 +f 5217/1/5217 5221/1/5221 5218/1/5218 +f 5214/1/5214 5217/1/5217 5218/1/5218 +f 5214/1/5214 5218/1/5218 5215/1/5215 +f 5216/1/5216 5217/1/5217 5214/1/5214 +f 5208/1/5208 5216/1/5216 5214/1/5214 +f 5208/1/5208 5214/1/5214 5206/1/5206 +f 5207/1/5207 5208/1/5208 5206/1/5206 +f 5394/1/5394 5208/1/5208 5207/1/5207 +f 6384/1/6384 5394/1/5394 5207/1/5207 +f 6384/1/6384 5207/1/5207 6381/1/6381 +f 6425/1/6425 6384/1/6384 6381/1/6381 +f 6425/1/6425 6381/1/6381 6424/1/6424 +f 6424/1/6424 6419/1/6419 6425/1/6425 +f 6425/1/6425 6419/1/6419 6426/1/6426 +f 6425/1/6425 6426/1/6426 6428/1/6428 +f 6428/1/6428 6426/1/6426 6392/1/6392 +f 6428/1/6428 6392/1/6392 6391/1/6391 +f 6391/1/6391 6384/1/6384 6428/1/6428 +f 6387/1/6387 6384/1/6384 6391/1/6391 +f 6387/1/6387 6385/1/6385 6384/1/6384 +f 6386/1/6386 6385/1/6385 6387/1/6387 +f 6387/1/6387 6389/1/6389 6386/1/6386 +f 6386/1/6386 6389/1/6389 6390/1/6390 +f 6386/1/6386 6390/1/6390 6388/1/6388 +f 6388/1/6388 5370/1/5370 6386/1/6386 +f 5372/1/5372 5370/1/5370 6388/1/6388 +f 6388/1/6388 6395/1/6395 5372/1/5372 +f 5372/1/5372 6395/1/6395 6396/1/6396 +f 5372/1/5372 6396/1/6396 5371/1/5371 +f 5371/1/5371 6396/1/6396 5375/1/5375 +f 5371/1/5371 5375/1/5375 5374/1/5374 +f 5374/1/5374 5366/1/5366 5371/1/5371 +f 5371/1/5371 5366/1/5366 5370/1/5370 +f 5366/1/5366 5293/1/5293 5370/1/5370 +f 5370/1/5370 5293/1/5293 5294/1/5294 +f 5370/1/5370 5294/1/5294 6385/1/6385 +f 6385/1/6385 5294/1/5294 5394/1/5394 +f 5294/1/5294 5292/1/5292 5394/1/5394 +f 5294/1/5294 5291/1/5291 5292/1/5292 +f 5291/1/5291 5281/1/5281 5292/1/5292 +f 5292/1/5292 5281/1/5281 5216/1/5216 +f 5281/1/5281 5278/1/5278 5216/1/5216 +f 5216/1/5216 5278/1/5278 5280/1/5280 +f 5278/1/5278 5269/1/5269 5280/1/5280 +f 5280/1/5280 5269/1/5269 5267/1/5267 +f 5280/1/5280 5267/1/5267 5217/1/5217 +f 5269/1/5269 5266/1/5266 5267/1/5267 +f 5267/1/5267 5266/1/5266 5222/1/5222 +f 5269/1/5269 5268/1/5268 5266/1/5266 +f 5268/1/5268 5264/1/5264 5266/1/5266 +f 5266/1/5266 5264/1/5264 5262/1/5262 +f 5268/1/5268 5270/1/5270 5264/1/5264 +f 5270/1/5270 5265/1/5265 5264/1/5264 +f 5264/1/5264 5265/1/5265 5261/1/5261 +f 5265/1/5265 5263/1/5263 5261/1/5261 +f 5271/1/5271 5263/1/5263 5265/1/5265 +f 5271/1/5271 6430/1/6430 5263/1/5263 +f 6430/1/6430 6406/1/6406 5263/1/5263 +f 5263/1/5263 6406/1/6406 6404/1/6404 +f 5263/1/5263 6404/1/6404 5258/1/5258 +f 5258/1/5258 6404/1/6404 6405/1/6405 +f 6404/1/6404 6401/1/6401 6405/1/6405 +f 6404/1/6404 6400/1/6400 6401/1/6401 +f 6400/1/6400 6397/1/6397 6401/1/6401 +f 6401/1/6401 6397/1/6397 6398/1/6398 +f 6401/1/6401 6398/1/6398 6403/1/6403 +f 6403/1/6403 6398/1/6398 6399/1/6399 +f 6398/1/6398 6393/1/6393 6399/1/6399 +f 6393/1/6393 6392/1/6392 6399/1/6399 +f 6399/1/6399 6392/1/6392 6427/1/6427 +f 6399/1/6399 6427/1/6427 6410/1/6410 +f 6393/1/6393 6389/1/6389 6392/1/6392 +f 6397/1/6397 6393/1/6393 6398/1/6398 +f 6397/1/6397 6394/1/6394 6393/1/6393 +f 6394/1/6394 6390/1/6390 6393/1/6393 +f 6394/1/6394 6395/1/6395 6390/1/6390 +f 6547/1/6547 6395/1/6395 6394/1/6394 +f 6402/1/6402 6547/1/6547 6394/1/6394 +f 6400/1/6400 6547/1/6547 6402/1/6402 +f 6548/1/6548 6547/1/6547 6400/1/6400 +f 6406/1/6406 6548/1/6548 6400/1/6400 +f 5387/1/5387 6548/1/6548 6406/1/6406 +f 5387/1/5387 5385/1/5385 6548/1/6548 +f 5385/1/5385 5389/1/5389 6548/1/6548 +f 5385/1/5385 5382/1/5382 5389/1/5389 +f 5382/1/5382 5388/1/5388 5389/1/5389 +f 5388/1/5388 5375/1/5375 5389/1/5389 +f 5388/1/5388 5376/1/5376 5375/1/5375 +f 5373/1/5373 5375/1/5375 5376/1/5376 +f 5373/1/5373 5376/1/5376 5369/1/5369 +f 5369/1/5369 5366/1/5366 5373/1/5373 +f 5369/1/5369 5365/1/5365 5366/1/5366 +f 5365/1/5365 5295/1/5295 5366/1/5366 +f 5365/1/5365 5297/1/5297 5295/1/5295 +f 5297/1/5297 5296/1/5296 5295/1/5295 +f 5295/1/5295 5296/1/5296 5290/1/5290 +f 5295/1/5295 5290/1/5290 5293/1/5293 +f 5293/1/5293 5290/1/5290 5291/1/5291 +f 5290/1/5290 5285/1/5285 5291/1/5291 +f 5291/1/5291 5285/1/5285 5286/1/5286 +f 5285/1/5285 5282/1/5282 5286/1/5286 +f 5286/1/5286 5282/1/5282 5279/1/5279 +f 5286/1/5286 5279/1/5279 5281/1/5281 +f 5282/1/5282 5275/1/5275 5279/1/5279 +f 5279/1/5279 5275/1/5275 5276/1/5276 +f 5279/1/5279 5276/1/5276 5278/1/5278 +f 5278/1/5278 5276/1/5276 5274/1/5274 +f 5276/1/5276 5273/1/5273 5274/1/5274 +f 5273/1/5273 5268/1/5268 5274/1/5274 +f 5275/1/5275 5273/1/5273 5276/1/5276 +f 5275/1/5275 5277/1/5277 5273/1/5273 +f 5277/1/5277 5272/1/5272 5273/1/5273 +f 5273/1/5273 5272/1/5272 5270/1/5270 +f 5272/1/5272 5271/1/5271 5270/1/5270 +f 5396/1/5396 5271/1/5271 5272/1/5272 +f 5396/1/5396 6533/1/6533 5271/1/5271 +f 6532/1/6532 6533/1/6533 5396/1/5396 +f 5395/1/5395 6532/1/6532 5396/1/5396 +f 5395/1/5395 5396/1/5396 5277/1/5277 +f 5283/1/5283 5395/1/5395 5277/1/5277 +f 6528/1/6528 5395/1/5395 5283/1/5283 +f 5287/1/5287 6528/1/6528 5283/1/5283 +f 5284/1/5284 5287/1/5287 5283/1/5283 +f 5284/1/5284 5283/1/5283 5282/1/5282 +f 5288/1/5288 5287/1/5287 5284/1/5284 +f 5285/1/5285 5288/1/5288 5284/1/5284 +f 5289/1/5289 5288/1/5288 5285/1/5285 +f 5289/1/5289 6517/1/6517 5288/1/5288 +f 6517/1/6517 6518/1/6518 5288/1/5288 +f 6517/1/6517 6516/1/6516 6518/1/6518 +f 6516/1/6516 6525/1/6525 6518/1/6518 +f 6518/1/6518 6525/1/6525 6528/1/6528 +f 6525/1/6525 6529/1/6529 6528/1/6528 +f 6528/1/6528 6529/1/6529 6532/1/6532 +f 6529/1/6529 6531/1/6531 6532/1/6532 +f 6527/1/6527 6531/1/6531 6529/1/6529 +f 6527/1/6527 6530/1/6530 6531/1/6531 +f 6530/1/6530 6431/1/6431 6531/1/6531 +f 6531/1/6531 6431/1/6431 6430/1/6430 +f 6531/1/6531 6430/1/6430 6533/1/6533 +f 6431/1/6431 5387/1/5387 6430/1/6430 +f 6431/1/6431 5386/1/5386 5387/1/5387 +f 5386/1/5386 5383/1/5383 5387/1/5387 +f 5386/1/5386 5384/1/5384 5383/1/5383 +f 5384/1/5384 5378/1/5378 5383/1/5383 +f 5383/1/5383 5378/1/5378 5379/1/5379 +f 5383/1/5383 5379/1/5379 5382/1/5382 +f 5379/1/5379 5381/1/5381 5382/1/5382 +f 5379/1/5379 5377/1/5377 5381/1/5381 +f 5381/1/5381 5377/1/5377 5376/1/5376 +f 5368/1/5368 5376/1/5376 5377/1/5377 +f 5368/1/5368 5377/1/5377 5367/1/5367 +f 5367/1/5367 5365/1/5365 5368/1/5368 +f 5363/1/5363 5365/1/5365 5367/1/5367 +f 5363/1/5363 5364/1/5364 5365/1/5365 +f 5360/1/5360 5364/1/5364 5363/1/5363 +f 5363/1/5363 5361/1/5361 5360/1/5360 +f 5360/1/5360 5361/1/5361 5358/1/5358 +f 5360/1/5360 5358/1/5358 5359/1/5359 +f 5359/1/5359 5302/1/5302 5360/1/5360 +f 5353/1/5353 5302/1/5302 5359/1/5359 +f 5359/1/5359 5354/1/5354 5353/1/5353 +f 5353/1/5353 5354/1/5354 5350/1/5350 +f 5353/1/5353 5350/1/5350 5349/1/5349 +f 5349/1/5349 5350/1/5350 5345/1/5345 +f 5349/1/5349 5345/1/5345 5347/1/5347 +f 5347/1/5347 5303/1/5303 5349/1/5349 +f 5349/1/5349 5303/1/5303 5302/1/5302 +f 5303/1/5303 5301/1/5301 5302/1/5302 +f 5302/1/5302 5301/1/5301 5299/1/5299 +f 5302/1/5302 5299/1/5299 5364/1/5364 +f 5364/1/5364 5299/1/5299 5297/1/5297 +f 5299/1/5299 5298/1/5298 5297/1/5297 +f 5299/1/5299 5300/1/5300 5298/1/5298 +f 5300/1/5300 6504/1/6504 5298/1/5298 +f 5298/1/5298 6504/1/6504 6505/1/6505 +f 5298/1/5298 6505/1/6505 5296/1/5296 +f 5296/1/5296 6505/1/6505 6514/1/6514 +f 6505/1/6505 6506/1/6506 6514/1/6514 +f 6514/1/6514 6506/1/6506 6513/1/6513 +f 6514/1/6514 6513/1/6513 6515/1/6515 +f 6514/1/6514 6515/1/6515 5289/1/5289 +f 5290/1/5290 6514/1/6514 5289/1/5289 +f 6513/1/6513 6510/1/6510 6515/1/6515 +f 6515/1/6515 6510/1/6510 6516/1/6516 +f 6510/1/6510 6524/1/6524 6516/1/6516 +f 6510/1/6510 6512/1/6512 6524/1/6524 +f 6512/1/6512 6526/1/6526 6524/1/6524 +f 6524/1/6524 6526/1/6526 6527/1/6527 +f 6524/1/6524 6527/1/6527 6525/1/6525 +f 6512/1/6512 6511/1/6511 6526/1/6526 +f 6511/1/6511 6534/1/6534 6526/1/6526 +f 6526/1/6526 6534/1/6534 6530/1/6530 +f 6509/1/6509 6534/1/6534 6511/1/6511 +f 6507/1/6507 6509/1/6509 6511/1/6511 +f 6501/1/6501 6509/1/6509 6507/1/6507 +f 6502/1/6502 6501/1/6501 6507/1/6507 +f 6502/1/6502 6507/1/6507 6508/1/6508 +f 6506/1/6506 6502/1/6502 6508/1/6508 +f 6503/1/6503 6502/1/6502 6506/1/6506 +f 6503/1/6503 6499/1/6499 6502/1/6502 +f 6498/1/6498 6499/1/6499 6503/1/6503 +f 6505/1/6505 6498/1/6498 6503/1/6503 +f 6498/1/6498 6494/1/6494 6499/1/6499 +f 6494/1/6494 6495/1/6495 6499/1/6499 +f 6499/1/6499 6495/1/6495 6501/1/6501 +f 6495/1/6495 6500/1/6500 6501/1/6501 +f 6495/1/6495 6492/1/6492 6500/1/6500 +f 6492/1/6492 6536/1/6536 6500/1/6500 +f 6500/1/6500 6536/1/6536 6535/1/6535 +f 6500/1/6500 6535/1/6535 6509/1/6509 +f 6536/1/6536 6433/1/6433 6535/1/6535 +f 6535/1/6535 6433/1/6433 6432/1/6432 +f 6535/1/6535 6432/1/6432 6534/1/6534 +f 6534/1/6534 6432/1/6432 6431/1/6431 +f 6433/1/6433 5390/1/5390 6432/1/6432 +f 6432/1/6432 5390/1/5390 5386/1/5386 +f 6433/1/6433 5391/1/5391 5390/1/5390 +f 5391/1/5391 5356/1/5356 5390/1/5390 +f 5390/1/5390 5356/1/5356 5384/1/5384 +f 5356/1/5356 5380/1/5380 5384/1/5384 +f 5356/1/5356 5357/1/5357 5380/1/5380 +f 5357/1/5357 5355/1/5355 5380/1/5380 +f 5380/1/5380 5355/1/5355 5362/1/5362 +f 5380/1/5380 5362/1/5362 5378/1/5378 +f 5355/1/5355 5358/1/5358 5362/1/5362 +f 5355/1/5355 5354/1/5354 5358/1/5358 +f 5352/1/5352 5354/1/5354 5355/1/5355 +f 5357/1/5357 5352/1/5352 5355/1/5355 +f 5356/1/5356 5352/1/5352 5357/1/5357 +f 5351/1/5351 5352/1/5352 5356/1/5356 +f 5351/1/5351 5348/1/5348 5352/1/5352 +f 5352/1/5352 5348/1/5348 5350/1/5350 +f 5336/1/5336 5348/1/5348 5351/1/5351 +f 5337/1/5337 5336/1/5336 5351/1/5351 +f 5337/1/5337 5351/1/5351 5391/1/5391 +f 6434/1/6434 5337/1/5337 5391/1/5391 +f 6436/1/6436 5337/1/5337 6434/1/6434 +f 6435/1/6435 6436/1/6436 6434/1/6434 +f 6435/1/6435 6434/1/6434 6484/1/6484 +f 6481/1/6481 6435/1/6435 6484/1/6484 +f 6481/1/6481 6484/1/6484 6485/1/6485 +f 6483/1/6483 6481/1/6481 6485/1/6485 +f 6483/1/6483 6485/1/6485 6488/1/6488 +f 6489/1/6489 6483/1/6483 6488/1/6488 +f 6489/1/6489 6488/1/6488 6490/1/6490 +f 6496/1/6496 6489/1/6489 6490/1/6490 +f 6496/1/6496 6490/1/6490 6497/1/6497 +f 6519/1/6519 6496/1/6496 6497/1/6497 +f 6519/1/6519 6497/1/6497 6504/1/6504 +f 6504/1/6504 6497/1/6497 6498/1/6498 +f 6497/1/6497 6493/1/6493 6498/1/6498 +f 6520/1/6520 6496/1/6496 6519/1/6519 +f 5300/1/5300 6520/1/6520 6519/1/6519 +f 6350/1/6350 6520/1/6520 5300/1/5300 +f 5301/1/5301 6350/1/6350 5300/1/5300 +f 5304/1/5304 6350/1/6350 5301/1/5301 +f 5304/1/5304 6349/1/6349 6350/1/6350 +f 6349/1/6349 6466/1/6466 6350/1/6350 +f 6350/1/6350 6466/1/6466 6521/1/6521 +f 6466/1/6466 6470/1/6470 6521/1/6521 +f 6521/1/6521 6470/1/6470 6478/1/6478 +f 6521/1/6521 6478/1/6478 6522/1/6522 +f 6521/1/6521 6522/1/6522 6520/1/6520 +f 6520/1/6520 6522/1/6522 6523/1/6523 +f 6522/1/6522 6482/1/6482 6523/1/6523 +f 6523/1/6523 6482/1/6482 6489/1/6489 +f 6522/1/6522 6477/1/6477 6482/1/6482 +f 6477/1/6477 6479/1/6479 6482/1/6482 +f 6482/1/6482 6479/1/6479 6483/1/6483 +f 6477/1/6477 6475/1/6475 6479/1/6479 +f 6475/1/6475 6480/1/6480 6479/1/6479 +f 6479/1/6479 6480/1/6480 6481/1/6481 +f 6475/1/6475 6476/1/6476 6480/1/6480 +f 6476/1/6476 6435/1/6435 6480/1/6480 +f 6476/1/6476 6439/1/6439 6435/1/6435 +f 6474/1/6474 6439/1/6439 6476/1/6476 +f 6471/1/6471 6474/1/6474 6476/1/6476 +f 6473/1/6473 6474/1/6474 6471/1/6471 +f 6469/1/6469 6473/1/6473 6471/1/6471 +f 6469/1/6469 6471/1/6471 6472/1/6472 +f 6470/1/6470 6469/1/6469 6472/1/6472 +f 6468/1/6468 6469/1/6469 6470/1/6470 +f 6468/1/6468 6467/1/6467 6469/1/6469 +f 6467/1/6467 6450/1/6450 6469/1/6469 +f 6452/1/6452 6450/1/6450 6467/1/6467 +f 6465/1/6465 6452/1/6452 6467/1/6467 +f 6460/1/6460 6452/1/6452 6465/1/6465 +f 6464/1/6464 6460/1/6460 6465/1/6465 +f 6464/1/6464 6465/1/6465 6466/1/6466 +f 6466/1/6466 6465/1/6465 6468/1/6468 +f 6464/1/6464 6459/1/6459 6460/1/6460 +f 6459/1/6459 6451/1/6451 6460/1/6460 +f 6459/1/6459 6458/1/6458 6451/1/6451 +f 6458/1/6458 6447/1/6447 6451/1/6451 +f 6451/1/6451 6447/1/6447 6448/1/6448 +f 6451/1/6451 6448/1/6448 6452/1/6452 +f 6447/1/6447 6443/1/6443 6448/1/6448 +f 6448/1/6448 6443/1/6443 6444/1/6444 +f 6448/1/6448 6444/1/6444 6450/1/6450 +f 6450/1/6450 6444/1/6444 6449/1/6449 +f 6450/1/6450 6449/1/6449 6473/1/6473 +f 6444/1/6444 6437/1/6437 6449/1/6449 +f 6449/1/6449 6437/1/6437 6474/1/6474 +f 6444/1/6444 6440/1/6440 6437/1/6437 +f 6440/1/6440 6438/1/6438 6437/1/6437 +f 6437/1/6437 6438/1/6438 6436/1/6436 +f 6437/1/6437 6436/1/6436 6439/1/6439 +f 6438/1/6438 5333/1/5333 6436/1/6436 +f 6438/1/6438 5330/1/5330 5333/1/5333 +f 5330/1/5330 5328/1/5328 5333/1/5333 +f 5333/1/5333 5328/1/5328 5332/1/5332 +f 5333/1/5333 5332/1/5332 5337/1/5337 +f 5328/1/5328 5327/1/5327 5332/1/5332 +f 5332/1/5332 5327/1/5327 5334/1/5334 +f 5332/1/5332 5334/1/5334 5335/1/5335 +f 5332/1/5332 5335/1/5335 5336/1/5336 +f 5334/1/5334 5339/1/5339 5335/1/5335 +f 5335/1/5335 5339/1/5339 5343/1/5343 +f 5335/1/5335 5343/1/5343 5348/1/5348 +f 5343/1/5343 5345/1/5345 5348/1/5348 +f 5343/1/5343 5342/1/5342 5345/1/5345 +f 5344/1/5344 5345/1/5345 5342/1/5342 +f 5344/1/5344 5342/1/5342 5346/1/5346 +f 5346/1/5346 5303/1/5303 5344/1/5344 +f 5346/1/5346 5305/1/5305 5303/1/5303 +f 5305/1/5305 5304/1/5304 5303/1/5303 +f 5305/1/5305 5306/1/5306 5304/1/5304 +f 5307/1/5307 5306/1/5306 5305/1/5305 +f 5311/1/5311 5307/1/5307 5305/1/5305 +f 5311/1/5311 5305/1/5305 5340/1/5340 +f 5340/1/5340 5338/1/5338 5311/1/5311 +f 5311/1/5311 5338/1/5338 5315/1/5315 +f 5311/1/5311 5315/1/5315 5310/1/5310 +f 5310/1/5310 5315/1/5315 5316/1/5316 +f 5310/1/5310 5316/1/5316 5314/1/5314 +f 5314/1/5314 5309/1/5309 5310/1/5310 +f 5310/1/5310 5309/1/5309 5307/1/5307 +f 5309/1/5309 5308/1/5308 5307/1/5307 +f 5309/1/5309 6345/1/6345 5308/1/5308 +f 6345/1/6345 6346/1/6346 5308/1/5308 +f 5308/1/5308 6346/1/6346 6348/1/6348 +f 5308/1/5308 6348/1/6348 5306/1/5306 +f 5306/1/5306 6348/1/6348 6349/1/6349 +f 6348/1/6348 6464/1/6464 6349/1/6349 +f 6348/1/6348 6463/1/6463 6464/1/6464 +f 6346/1/6346 6463/1/6463 6348/1/6348 +f 6346/1/6346 6538/1/6538 6463/1/6463 +f 6538/1/6538 6462/1/6462 6463/1/6463 +f 6463/1/6463 6462/1/6462 6459/1/6459 +f 6462/1/6462 6461/1/6461 6459/1/6459 +f 6462/1/6462 6544/1/6544 6461/1/6461 +f 6544/1/6544 6453/1/6453 6461/1/6461 +f 6461/1/6461 6453/1/6453 6458/1/6458 +f 6544/1/6544 6456/1/6456 6453/1/6453 +f 6456/1/6456 6454/1/6454 6453/1/6453 +f 6453/1/6453 6454/1/6454 6446/1/6446 +f 6453/1/6453 6446/1/6446 6447/1/6447 +f 6454/1/6454 6445/1/6445 6446/1/6446 +f 6446/1/6446 6445/1/6445 6442/1/6442 +f 6446/1/6446 6442/1/6442 6443/1/6443 +f 6443/1/6443 6442/1/6442 6440/1/6440 +f 6442/1/6442 6441/1/6441 6440/1/6440 +f 6445/1/6445 6441/1/6441 6442/1/6442 +f 6445/1/6445 6892/1/6892 6441/1/6441 +f 6892/1/6892 5329/1/5329 6441/1/6441 +f 6441/1/6441 5329/1/5329 5330/1/5330 +f 5329/1/5329 5326/1/5326 5330/1/5330 +f 5329/1/5329 5331/1/5331 5326/1/5326 +f 5331/1/5331 5320/1/5320 5326/1/5326 +f 5326/1/5326 5320/1/5320 5324/1/5324 +f 5326/1/5326 5324/1/5324 5325/1/5325 +f 5326/1/5326 5325/1/5325 5328/1/5328 +f 5324/1/5324 5322/1/5322 5325/1/5325 +f 5325/1/5325 5322/1/5322 5323/1/5323 +f 5325/1/5325 5323/1/5323 5327/1/5327 +f 5322/1/5322 5316/1/5316 5323/1/5323 +f 5322/1/5322 5317/1/5317 5316/1/5316 +f 5320/1/5320 5317/1/5317 5322/1/5322 +f 5320/1/5320 5318/1/5318 5317/1/5317 +f 5313/1/5313 5317/1/5317 5318/1/5318 +f 5313/1/5313 5318/1/5318 5312/1/5312 +f 5312/1/5312 5309/1/5309 5313/1/5313 +f 5312/1/5312 6347/1/6347 5309/1/5309 +f 6351/1/6351 6347/1/6347 5312/1/5312 +f 5312/1/5312 5319/1/5319 6351/1/6351 +f 6351/1/6351 5319/1/5319 6353/1/6353 +f 6353/1/6353 5319/1/5319 6276/1/6276 +f 6353/1/6353 6276/1/6276 6352/1/6352 +f 6352/1/6352 6347/1/6347 6353/1/6353 +f 6352/1/6352 6340/1/6340 6347/1/6347 +f 6340/1/6340 6342/1/6342 6347/1/6347 +f 6347/1/6347 6342/1/6342 6345/1/6345 +f 6342/1/6342 6344/1/6344 6345/1/6345 +f 6342/1/6342 6341/1/6341 6344/1/6344 +f 6341/1/6341 6868/1/6868 6344/1/6344 +f 6344/1/6344 6868/1/6868 6540/1/6540 +f 6344/1/6344 6540/1/6540 6537/1/6537 +f 6344/1/6344 6537/1/6537 6346/1/6346 +f 6540/1/6540 6541/1/6541 6537/1/6537 +f 6537/1/6537 6541/1/6541 6542/1/6542 +f 6537/1/6537 6542/1/6542 6539/1/6539 +f 6537/1/6537 6539/1/6539 6538/1/6538 +f 6542/1/6542 6543/1/6543 6539/1/6539 +f 6539/1/6539 6543/1/6543 6544/1/6544 +f 6542/1/6542 6545/1/6545 6543/1/6543 +f 6545/1/6545 6546/1/6546 6543/1/6543 +f 6546/1/6546 6457/1/6457 6543/1/6543 +f 6543/1/6543 6457/1/6457 6456/1/6456 +f 6457/1/6457 6455/1/6455 6456/1/6456 +f 6457/1/6457 6894/1/6894 6455/1/6455 +f 6894/1/6894 6893/1/6893 6455/1/6455 +f 6455/1/6455 6893/1/6893 6445/1/6445 +f 6894/1/6894 6889/1/6889 6893/1/6893 +f 6889/1/6889 6892/1/6892 6893/1/6893 +f 6889/1/6889 6891/1/6891 6892/1/6892 +f 6891/1/6891 5392/1/5392 6892/1/6892 +f 6891/1/6891 6265/1/6265 5392/1/5392 +f 6265/1/6265 6268/1/6268 5392/1/5392 +f 5392/1/5392 6268/1/6268 5393/1/5393 +f 5392/1/5392 5393/1/5393 5331/1/5331 +f 5393/1/5393 5321/1/5321 5331/1/5331 +f 5393/1/5393 6270/1/6270 5321/1/5321 +f 6270/1/6270 6275/1/6275 5321/1/5321 +f 6275/1/6275 5319/1/5319 5321/1/5321 +f 5321/1/5321 5319/1/5319 5318/1/5318 +f 6270/1/6270 6273/1/6273 6275/1/6275 +f 6273/1/6273 6276/1/6276 6275/1/6275 +f 6273/1/6273 6274/1/6274 6276/1/6276 +f 6354/1/6354 6276/1/6276 6274/1/6274 +f 6354/1/6354 6274/1/6274 6355/1/6355 +f 6355/1/6355 6340/1/6340 6354/1/6354 +f 6279/1/6279 6340/1/6340 6355/1/6355 +f 6279/1/6279 6285/1/6285 6340/1/6340 +f 6285/1/6285 6339/1/6339 6340/1/6340 +f 6285/1/6285 6338/1/6338 6339/1/6339 +f 6338/1/6338 6343/1/6343 6339/1/6339 +f 6339/1/6339 6343/1/6343 6341/1/6341 +f 6343/1/6343 6866/1/6866 6341/1/6341 +f 6343/1/6343 6864/1/6864 6866/1/6866 +f 6864/1/6864 6863/1/6863 6866/1/6866 +f 6866/1/6866 6863/1/6863 6872/1/6872 +f 6866/1/6866 6872/1/6872 6869/1/6869 +f 6866/1/6866 6869/1/6869 6868/1/6868 +f 6868/1/6868 6869/1/6869 6870/1/6870 +f 6868/1/6868 6870/1/6870 6871/1/6871 +f 6870/1/6870 6875/1/6875 6871/1/6871 +f 6871/1/6871 6875/1/6875 6883/1/6883 +f 6871/1/6871 6883/1/6883 6905/1/6905 +f 6540/1/6540 6871/1/6871 6905/1/6905 +f 6905/1/6905 6883/1/6883 6904/1/6904 +f 6905/1/6905 6904/1/6904 6541/1/6541 +f 6541/1/6541 6904/1/6904 6545/1/6545 +f 6883/1/6883 6888/1/6888 6904/1/6904 +f 6904/1/6904 6888/1/6888 6546/1/6546 +f 6888/1/6888 6890/1/6890 6546/1/6546 +f 6546/1/6546 6890/1/6890 6894/1/6894 +f 6888/1/6888 6887/1/6887 6890/1/6890 +f 6887/1/6887 6889/1/6889 6890/1/6890 +f 6887/1/6887 6886/1/6886 6889/1/6889 +f 6884/1/6884 6886/1/6886 6887/1/6887 +f 6882/1/6882 6884/1/6884 6887/1/6887 +f 6881/1/6881 6884/1/6884 6882/1/6882 +f 6875/1/6875 6881/1/6881 6882/1/6882 +f 6876/1/6876 6881/1/6881 6875/1/6875 +f 6874/1/6874 6876/1/6876 6875/1/6875 +f 6873/1/6873 6876/1/6876 6874/1/6874 +f 6869/1/6869 6873/1/6873 6874/1/6874 +f 6873/1/6873 6878/1/6878 6876/1/6876 +f 6878/1/6878 6879/1/6879 6876/1/6876 +f 6876/1/6876 6879/1/6879 6880/1/6880 +f 6879/1/6879 6885/1/6885 6880/1/6880 +f 6880/1/6880 6885/1/6885 6884/1/6884 +f 6879/1/6879 6902/1/6902 6885/1/6885 +f 6902/1/6902 6895/1/6895 6885/1/6885 +f 6885/1/6885 6895/1/6895 6891/1/6891 +f 6885/1/6885 6891/1/6891 6886/1/6886 +f 6902/1/6902 6262/1/6262 6895/1/6895 +f 6262/1/6262 6263/1/6263 6895/1/6895 +f 6895/1/6895 6263/1/6263 6265/1/6265 +f 6263/1/6263 6264/1/6264 6265/1/6265 +f 6263/1/6263 6266/1/6266 6264/1/6264 +f 6266/1/6266 6267/1/6267 6264/1/6264 +f 6264/1/6264 6267/1/6267 6269/1/6269 +f 6264/1/6264 6269/1/6269 6268/1/6268 +f 6268/1/6268 6269/1/6269 6271/1/6271 +f 6268/1/6268 6271/1/6271 6270/1/6270 +f 6269/1/6269 6272/1/6272 6271/1/6271 +f 6272/1/6272 6274/1/6274 6271/1/6271 +f 6272/1/6272 6277/1/6277 6274/1/6274 +f 6279/1/6279 6274/1/6274 6277/1/6277 +f 6279/1/6279 6277/1/6277 6280/1/6280 +f 6280/1/6280 6277/1/6277 6278/1/6278 +f 6280/1/6280 6278/1/6278 6281/1/6281 +f 6281/1/6281 6284/1/6284 6280/1/6280 +f 6280/1/6280 6284/1/6284 6285/1/6285 +f 6286/1/6286 6284/1/6284 6281/1/6281 +f 6281/1/6281 6282/1/6282 6286/1/6286 +f 6286/1/6286 6282/1/6282 6288/1/6288 +f 6286/1/6286 6288/1/6288 6289/1/6289 +f 6289/1/6289 6288/1/6288 6291/1/6291 +f 6289/1/6289 6291/1/6291 6292/1/6292 +f 6292/1/6292 6293/1/6293 6289/1/6289 +f 6289/1/6289 6293/1/6293 6284/1/6284 +f 6293/1/6293 6337/1/6337 6284/1/6284 +f 6284/1/6284 6337/1/6337 6338/1/6338 +f 6337/1/6337 6865/1/6865 6338/1/6338 +f 6337/1/6337 6867/1/6867 6865/1/6865 +f 6867/1/6867 6858/1/6858 6865/1/6865 +f 6865/1/6865 6858/1/6858 6860/1/6860 +f 6865/1/6865 6860/1/6860 6864/1/6864 +f 6860/1/6860 6859/1/6859 6864/1/6864 +f 6860/1/6860 6855/1/6855 6859/1/6859 +f 6855/1/6855 6856/1/6856 6859/1/6859 +f 6859/1/6859 6856/1/6856 6862/1/6862 +f 6859/1/6859 6862/1/6862 6863/1/6863 +f 6863/1/6863 6862/1/6862 6903/1/6903 +f 6863/1/6863 6903/1/6903 6877/1/6877 +f 6903/1/6903 6901/1/6901 6877/1/6877 +f 6877/1/6877 6901/1/6901 6878/1/6878 +f 6901/1/6901 6900/1/6900 6878/1/6878 +f 6901/1/6901 6899/1/6899 6900/1/6900 +f 6899/1/6899 6897/1/6897 6900/1/6900 +f 6900/1/6900 6897/1/6897 6902/1/6902 +f 6899/1/6899 6896/1/6896 6897/1/6897 +f 6896/1/6896 6262/1/6262 6897/1/6897 +f 6896/1/6896 6260/1/6260 6262/1/6262 +f 6260/1/6260 6261/1/6261 6262/1/6262 +f 6260/1/6260 6259/1/6259 6261/1/6261 +f 6259/1/6259 6305/1/6305 6261/1/6261 +f 6261/1/6261 6305/1/6305 6266/1/6266 +f 6305/1/6305 6287/1/6287 6266/1/6266 +f 6266/1/6266 6287/1/6287 6357/1/6357 +f 6357/1/6357 6287/1/6287 6283/1/6283 +f 6357/1/6357 6283/1/6283 6267/1/6267 +f 6267/1/6267 6283/1/6283 6272/1/6272 +f 6283/1/6283 6278/1/6278 6272/1/6272 +f 6283/1/6283 6282/1/6282 6278/1/6278 +f 6287/1/6287 6282/1/6282 6283/1/6283 +f 6305/1/6305 6290/1/6290 6287/1/6287 +f 6287/1/6287 6290/1/6290 6288/1/6288 +f 6304/1/6304 6290/1/6290 6305/1/6305 +f 6304/1/6304 6302/1/6302 6290/1/6290 +f 6302/1/6302 6294/1/6294 6290/1/6290 +f 6294/1/6294 6291/1/6291 6290/1/6290 +f 6294/1/6294 6295/1/6295 6291/1/6291 +f 6296/1/6296 6291/1/6291 6295/1/6295 +f 6296/1/6296 6295/1/6295 6297/1/6297 +f 6297/1/6297 6293/1/6293 6296/1/6296 +f 6297/1/6297 6298/1/6298 6293/1/6293 +f 6298/1/6298 6336/1/6336 6293/1/6293 +f 6298/1/6298 6335/1/6335 6336/1/6336 +f 6335/1/6335 6906/1/6906 6336/1/6336 +f 6336/1/6336 6906/1/6906 6867/1/6867 +f 6906/1/6906 6907/1/6907 6867/1/6867 +f 6867/1/6867 6907/1/6907 6908/1/6908 +f 6907/1/6907 6837/1/6837 6908/1/6908 +f 6908/1/6908 6837/1/6837 6909/1/6909 +f 6908/1/6908 6909/1/6909 6857/1/6857 +f 6908/1/6908 6857/1/6857 6858/1/6858 +f 6858/1/6858 6857/1/6857 6854/1/6854 +f 6858/1/6858 6854/1/6854 6855/1/6855 +f 6854/1/6854 6850/1/6850 6855/1/6855 +f 6854/1/6854 6849/1/6849 6850/1/6850 +f 6849/1/6849 6847/1/6847 6850/1/6850 +f 6847/1/6847 6851/1/6851 6850/1/6850 +f 6850/1/6850 6851/1/6851 6853/1/6853 +f 6850/1/6850 6853/1/6853 6856/1/6856 +f 6856/1/6856 6853/1/6853 6861/1/6861 +f 6853/1/6853 6898/1/6898 6861/1/6861 +f 6861/1/6861 6898/1/6898 6899/1/6899 +f 6853/1/6853 6852/1/6852 6898/1/6898 +f 6852/1/6852 6896/1/6896 6898/1/6898 +f 6852/1/6852 6845/1/6845 6896/1/6896 +f 6846/1/6846 6845/1/6845 6852/1/6852 +f 6851/1/6851 6846/1/6846 6852/1/6852 +f 6846/1/6846 6843/1/6843 6845/1/6845 +f 6843/1/6843 6260/1/6260 6845/1/6845 +f 6843/1/6843 6255/1/6255 6260/1/6260 +f 6840/1/6840 6255/1/6255 6843/1/6843 +f 6841/1/6841 6840/1/6840 6843/1/6843 +f 6841/1/6841 6843/1/6843 6844/1/6844 +f 6842/1/6842 6841/1/6841 6844/1/6844 +f 6842/1/6842 6844/1/6844 6847/1/6847 +f 6848/1/6848 6842/1/6842 6847/1/6847 +f 6836/1/6836 6842/1/6842 6848/1/6848 +f 6909/1/6909 6836/1/6836 6848/1/6848 +f 6836/1/6836 6835/1/6835 6842/1/6842 +f 6833/1/6833 6835/1/6835 6836/1/6836 +f 6837/1/6837 6833/1/6833 6836/1/6836 +f 6834/1/6834 6833/1/6833 6837/1/6837 +f 6834/1/6834 6827/1/6827 6833/1/6833 +f 6827/1/6827 6828/1/6828 6833/1/6833 +f 6828/1/6828 6832/1/6832 6833/1/6833 +f 6828/1/6828 6831/1/6831 6832/1/6832 +f 6832/1/6832 6831/1/6831 6838/1/6838 +f 6832/1/6832 6838/1/6838 6835/1/6835 +f 6835/1/6835 6838/1/6838 6841/1/6841 +f 6831/1/6831 6839/1/6839 6838/1/6838 +f 6838/1/6838 6839/1/6839 6840/1/6840 +f 6829/1/6829 6839/1/6839 6831/1/6831 +f 6829/1/6829 6910/1/6910 6839/1/6839 +f 6910/1/6910 5627/1/5627 6839/1/6839 +f 6839/1/6839 5627/1/5627 6255/1/6255 +f 5627/1/5627 6254/1/6254 6255/1/6255 +f 6255/1/6255 6254/1/6254 6259/1/6259 +f 6254/1/6254 6258/1/6258 6259/1/6259 +f 6259/1/6259 6258/1/6258 6304/1/6304 +f 6254/1/6254 6257/1/6257 6258/1/6258 +f 6257/1/6257 6306/1/6306 6258/1/6258 +f 6258/1/6258 6306/1/6306 6303/1/6303 +f 6258/1/6258 6303/1/6303 6302/1/6302 +f 6303/1/6303 6299/1/6299 6302/1/6302 +f 6303/1/6303 6300/1/6300 6299/1/6299 +f 6299/1/6299 6300/1/6300 6295/1/6295 +f 6301/1/6301 6295/1/6295 6300/1/6300 +f 6301/1/6301 6300/1/6300 6334/1/6334 +f 6334/1/6334 6298/1/6298 6301/1/6301 +f 6333/1/6333 6298/1/6298 6334/1/6334 +f 6333/1/6333 6331/1/6331 6298/1/6298 +f 6327/1/6327 6331/1/6331 6333/1/6333 +f 6333/1/6333 6312/1/6312 6327/1/6327 +f 6327/1/6327 6312/1/6312 6311/1/6311 +f 6327/1/6327 6311/1/6311 6325/1/6325 +f 6325/1/6325 6328/1/6328 6327/1/6327 +f 6326/1/6326 6328/1/6328 6325/1/6325 +f 6325/1/6325 6314/1/6314 6326/1/6326 +f 6326/1/6326 6314/1/6314 6317/1/6317 +f 6326/1/6326 6317/1/6317 6329/1/6329 +f 6329/1/6329 6317/1/6317 6321/1/6321 +f 6329/1/6329 6321/1/6321 6356/1/6356 +f 6356/1/6356 6332/1/6332 6329/1/6329 +f 6329/1/6329 6332/1/6332 6328/1/6328 +f 6332/1/6332 6731/1/6731 6328/1/6328 +f 6328/1/6328 6731/1/6731 6330/1/6330 +f 6328/1/6328 6330/1/6330 6331/1/6331 +f 6331/1/6331 6330/1/6330 6335/1/6335 +f 6330/1/6330 6815/1/6815 6335/1/6335 +f 6330/1/6330 6733/1/6733 6815/1/6815 +f 6733/1/6733 6814/1/6814 6815/1/6815 +f 6815/1/6815 6814/1/6814 6817/1/6817 +f 6815/1/6815 6817/1/6817 6906/1/6906 +f 6814/1/6814 6816/1/6816 6817/1/6817 +f 6817/1/6817 6816/1/6816 6821/1/6821 +f 6817/1/6817 6821/1/6821 6826/1/6826 +f 6817/1/6817 6826/1/6826 6907/1/6907 +f 6907/1/6907 6826/1/6826 6834/1/6834 +f 6821/1/6821 6825/1/6825 6826/1/6826 +f 6826/1/6826 6825/1/6825 6827/1/6827 +f 6821/1/6821 6820/1/6820 6825/1/6825 +f 6820/1/6820 6824/1/6824 6825/1/6825 +f 6825/1/6825 6824/1/6824 6828/1/6828 +f 6824/1/6824 6829/1/6829 6828/1/6828 +f 6824/1/6824 6830/1/6830 6829/1/6829 +f 6823/1/6823 6830/1/6830 6824/1/6824 +f 6823/1/6823 6912/1/6912 6830/1/6830 +f 6912/1/6912 6911/1/6911 6830/1/6830 +f 6830/1/6830 6911/1/6911 6910/1/6910 +f 6911/1/6911 5623/1/5623 6910/1/6910 +f 5734/1/5734 5623/1/5623 6911/1/6911 +f 5734/1/5734 5626/1/5626 5623/1/5623 +f 5626/1/5626 5624/1/5624 5623/1/5623 +f 5623/1/5623 5624/1/5624 5625/1/5625 +f 5623/1/5623 5625/1/5625 5627/1/5627 +f 5624/1/5624 6256/1/6256 5625/1/5625 +f 5625/1/5625 6256/1/6256 6257/1/6257 +f 6256/1/6256 6308/1/6308 6257/1/6257 +f 6256/1/6256 6309/1/6309 6308/1/6308 +f 6309/1/6309 6310/1/6310 6308/1/6308 +f 6308/1/6308 6310/1/6310 6307/1/6307 +f 6308/1/6308 6307/1/6307 6306/1/6306 +f 6310/1/6310 6311/1/6311 6307/1/6307 +f 6310/1/6310 6314/1/6314 6311/1/6311 +f 6313/1/6313 6314/1/6314 6310/1/6310 +f 6309/1/6309 6313/1/6313 6310/1/6310 +f 6256/1/6256 6313/1/6313 6309/1/6309 +f 6315/1/6315 6313/1/6313 6256/1/6256 +f 6315/1/6315 6316/1/6316 6313/1/6313 +f 6313/1/6313 6316/1/6316 6317/1/6317 +f 6318/1/6318 6316/1/6316 6315/1/6315 +f 5628/1/5628 6318/1/6318 6315/1/6315 +f 5628/1/5628 6315/1/6315 5624/1/5624 +f 5628/1/5628 6322/1/6322 6318/1/6318 +f 6322/1/6322 6319/1/6319 6318/1/6318 +f 6322/1/6322 6806/1/6806 6319/1/6319 +f 6806/1/6806 6323/1/6323 6319/1/6319 +f 6319/1/6319 6323/1/6323 6320/1/6320 +f 6319/1/6319 6320/1/6320 6316/1/6316 +f 6320/1/6320 6321/1/6321 6316/1/6316 +f 6320/1/6320 6324/1/6324 6321/1/6321 +f 6791/1/6791 6321/1/6321 6324/1/6324 +f 6791/1/6791 6324/1/6324 6789/1/6789 +f 6789/1/6789 6332/1/6332 6791/1/6791 +f 6789/1/6789 6785/1/6785 6332/1/6332 +f 6785/1/6785 6734/1/6734 6332/1/6332 +f 6785/1/6785 6736/1/6736 6734/1/6734 +f 6736/1/6736 5707/1/5707 6734/1/6734 +f 6734/1/6734 5707/1/5707 6732/1/6732 +f 6734/1/6734 6732/1/6732 6731/1/6731 +f 6731/1/6731 6732/1/6732 6733/1/6733 +f 6732/1/6732 6735/1/6735 6733/1/6733 +f 6733/1/6733 6735/1/6735 6810/1/6810 +f 6735/1/6735 6809/1/6809 6810/1/6810 +f 6810/1/6810 6809/1/6809 6813/1/6813 +f 6810/1/6810 6813/1/6813 6814/1/6814 +f 6809/1/6809 6812/1/6812 6813/1/6813 +f 6813/1/6813 6812/1/6812 6818/1/6818 +f 6813/1/6813 6818/1/6818 6816/1/6816 +f 6816/1/6816 6818/1/6818 6819/1/6819 +f 6816/1/6816 6819/1/6819 6820/1/6820 +f 6819/1/6819 6823/1/6823 6820/1/6820 +f 6822/1/6822 6823/1/6823 6819/1/6819 +f 6818/1/6818 6822/1/6822 6819/1/6819 +f 6812/1/6812 6822/1/6822 6818/1/6818 +f 6812/1/6812 6914/1/6914 6822/1/6822 +f 6914/1/6914 6913/1/6913 6822/1/6822 +f 6822/1/6822 6913/1/6913 6912/1/6912 +f 6913/1/6913 5734/1/5734 6912/1/6912 +f 5733/1/5733 5734/1/5734 6913/1/6913 +f 5733/1/5733 5732/1/5732 5734/1/5734 +f 5730/1/5730 5732/1/5732 5733/1/5733 +f 6915/1/6915 5730/1/5730 5733/1/5733 +f 6915/1/6915 5733/1/5733 6914/1/6914 +f 6811/1/6811 6915/1/6915 6914/1/6914 +f 5729/1/5729 6915/1/6915 6811/1/6811 +f 5731/1/5731 5729/1/5729 6811/1/6811 +f 6808/1/6808 5731/1/5731 6811/1/6811 +f 6808/1/6808 6811/1/6811 6809/1/6809 +f 6807/1/6807 5731/1/5731 6808/1/6808 +f 6735/1/6735 6807/1/6807 6808/1/6808 +f 5710/1/5710 6807/1/6807 6735/1/6735 +f 5710/1/5710 5714/1/5714 6807/1/6807 +f 5714/1/5714 5715/1/5715 6807/1/6807 +f 5714/1/5714 5713/1/5713 5715/1/5715 +f 5713/1/5713 5725/1/5725 5715/1/5715 +f 5715/1/5715 5725/1/5725 5729/1/5729 +f 5725/1/5725 5728/1/5728 5729/1/5729 +f 5729/1/5729 5728/1/5728 5730/1/5730 +f 5728/1/5728 5727/1/5727 5730/1/5730 +f 5724/1/5724 5727/1/5727 5728/1/5728 +f 5724/1/5724 5726/1/5726 5727/1/5727 +f 5726/1/5726 5629/1/5629 5727/1/5727 +f 5727/1/5727 5629/1/5629 5626/1/5626 +f 5727/1/5727 5626/1/5626 5732/1/5732 +f 5629/1/5629 5628/1/5628 5626/1/5626 +f 5629/1/5629 5630/1/5630 5628/1/5628 +f 5631/1/5631 5630/1/5630 5629/1/5629 +f 5721/1/5721 5631/1/5631 5629/1/5629 +f 5720/1/5720 5631/1/5631 5721/1/5721 +f 5717/1/5717 5720/1/5720 5721/1/5721 +f 5717/1/5717 5721/1/5721 5718/1/5718 +f 5716/1/5716 5717/1/5717 5718/1/5718 +f 5716/1/5716 5718/1/5718 5719/1/5719 +f 5716/1/5716 5719/1/5719 5712/1/5712 +f 5711/1/5711 5716/1/5716 5712/1/5712 +f 5708/1/5708 5711/1/5711 5712/1/5712 +f 5708/1/5708 5712/1/5712 5709/1/5709 +f 5705/1/5705 5708/1/5708 5709/1/5709 +f 5705/1/5705 5709/1/5709 5710/1/5710 +f 6732/1/6732 5705/1/5705 5710/1/5710 +f 5705/1/5705 5704/1/5704 5708/1/5708 +f 5702/1/5702 5704/1/5704 5705/1/5705 +f 5707/1/5707 5702/1/5702 5705/1/5705 +f 5706/1/5706 5702/1/5702 5707/1/5707 +f 5706/1/5706 5680/1/5680 5702/1/5702 +f 5680/1/5680 5700/1/5700 5702/1/5702 +f 5702/1/5702 5700/1/5700 5701/1/5701 +f 5700/1/5700 5699/1/5699 5701/1/5701 +f 5701/1/5701 5699/1/5699 5703/1/5703 +f 5701/1/5701 5703/1/5703 5704/1/5704 +f 5704/1/5704 5703/1/5703 5711/1/5711 +f 5699/1/5699 5698/1/5698 5703/1/5703 +f 5703/1/5703 5698/1/5698 5716/1/5716 +f 5699/1/5699 5693/1/5693 5698/1/5698 +f 5693/1/5693 5697/1/5697 5698/1/5698 +f 5698/1/5698 5697/1/5697 5717/1/5717 +f 5693/1/5693 5692/1/5692 5697/1/5697 +f 5692/1/5692 5696/1/5696 5697/1/5697 +f 5697/1/5697 5696/1/5696 5720/1/5720 +f 5696/1/5696 5633/1/5633 5720/1/5720 +f 5695/1/5695 5633/1/5633 5696/1/5696 +f 5695/1/5695 5635/1/5635 5633/1/5633 +f 5635/1/5635 5634/1/5634 5633/1/5633 +f 5633/1/5633 5634/1/5634 5632/1/5632 +f 5633/1/5633 5632/1/5632 5631/1/5631 +f 5634/1/5634 6802/1/6802 5632/1/5632 +f 5632/1/5632 6802/1/6802 6804/1/6804 +f 5632/1/5632 6804/1/6804 5630/1/5630 +f 5630/1/5630 6804/1/6804 6322/1/6322 +f 6804/1/6804 6805/1/6805 6322/1/6322 +f 6804/1/6804 6800/1/6800 6805/1/6805 +f 6800/1/6800 6793/1/6793 6805/1/6805 +f 6805/1/6805 6793/1/6793 6806/1/6806 +f 6793/1/6793 6790/1/6790 6806/1/6806 +f 6793/1/6793 6792/1/6792 6790/1/6790 +f 6786/1/6786 6790/1/6790 6792/1/6792 +f 6786/1/6786 6792/1/6792 6784/1/6784 +f 6784/1/6784 6783/1/6783 6786/1/6786 +f 6786/1/6786 6783/1/6783 6785/1/6785 +f 6786/1/6786 6785/1/6785 6787/1/6787 +f 6787/1/6787 6785/1/6785 6788/1/6788 +f 6788/1/6788 6790/1/6790 6787/1/6787 +f 6788/1/6788 6324/1/6324 6790/1/6790 +f 6323/1/6323 6790/1/6790 6324/1/6324 +f 6784/1/6784 6782/1/6782 6783/1/6783 +f 6782/1/6782 6737/1/6737 6783/1/6783 +f 6783/1/6783 6737/1/6737 6736/1/6736 +f 6737/1/6737 5706/1/5706 6736/1/6736 +f 6737/1/6737 5681/1/5681 5706/1/5706 +f 6738/1/6738 5681/1/5681 6737/1/6737 +f 6738/1/6738 5676/1/5676 5681/1/5681 +f 5676/1/5676 5677/1/5677 5681/1/5681 +f 5681/1/5681 5677/1/5677 5680/1/5680 +f 5677/1/5677 5679/1/5679 5680/1/5680 +f 5680/1/5680 5679/1/5679 5690/1/5690 +f 5679/1/5679 5685/1/5685 5690/1/5690 +f 5690/1/5690 5685/1/5685 5691/1/5691 +f 5690/1/5690 5691/1/5691 5700/1/5700 +f 5700/1/5700 5691/1/5691 5694/1/5694 +f 5691/1/5691 5689/1/5689 5694/1/5694 +f 5689/1/5689 5693/1/5693 5694/1/5694 +f 5685/1/5685 5689/1/5689 5691/1/5691 +f 5685/1/5685 5684/1/5684 5689/1/5689 +f 5684/1/5684 5688/1/5688 5689/1/5689 +f 5689/1/5689 5688/1/5688 5692/1/5692 +f 5688/1/5688 5695/1/5695 5692/1/5692 +f 5687/1/5687 5695/1/5695 5688/1/5688 +f 5687/1/5687 5735/1/5735 5695/1/5695 +f 5686/1/5686 5735/1/5735 5687/1/5687 +f 5683/1/5683 5686/1/5686 5687/1/5687 +f 5683/1/5683 5687/1/5687 5684/1/5684 +f 5682/1/5682 5683/1/5683 5684/1/5684 +f 5664/1/5664 5683/1/5683 5682/1/5682 +f 5669/1/5669 5664/1/5664 5682/1/5682 +f 5678/1/5678 5669/1/5669 5682/1/5682 +f 5678/1/5678 5682/1/5682 5679/1/5679 +f 5668/1/5668 5669/1/5669 5678/1/5678 +f 5677/1/5677 5668/1/5668 5678/1/5678 +f 5670/1/5670 5668/1/5668 5677/1/5677 +f 5670/1/5670 5667/1/5667 5668/1/5668 +f 5667/1/5667 5665/1/5665 5668/1/5668 +f 5667/1/5667 5662/1/5662 5665/1/5665 +f 5662/1/5662 5661/1/5661 5665/1/5665 +f 5665/1/5665 5661/1/5661 5664/1/5664 +f 5661/1/5661 5663/1/5663 5664/1/5664 +f 5664/1/5664 5663/1/5663 5686/1/5686 +f 5663/1/5663 5641/1/5641 5686/1/5686 +f 5659/1/5659 5641/1/5641 5663/1/5663 +f 5659/1/5659 5640/1/5640 5641/1/5641 +f 5640/1/5640 5637/1/5637 5641/1/5641 +f 5641/1/5641 5637/1/5637 5635/1/5635 +f 5641/1/5641 5635/1/5635 5735/1/5735 +f 5637/1/5637 5636/1/5636 5635/1/5635 +f 5637/1/5637 6766/1/6766 5636/1/5636 +f 6766/1/6766 6767/1/6767 5636/1/5636 +f 5636/1/5636 6767/1/6767 6771/1/6771 +f 5636/1/5636 6771/1/6771 6803/1/6803 +f 5636/1/5636 6803/1/6803 5634/1/5634 +f 6771/1/6771 6773/1/6773 6803/1/6803 +f 6803/1/6803 6773/1/6773 6799/1/6799 +f 6803/1/6803 6799/1/6799 6802/1/6802 +f 6802/1/6802 6799/1/6799 6801/1/6801 +f 6802/1/6802 6801/1/6801 6800/1/6800 +f 6801/1/6801 6797/1/6797 6800/1/6800 +f 6801/1/6801 6799/1/6799 6797/1/6797 +f 6799/1/6799 6796/1/6796 6797/1/6797 +f 6797/1/6797 6796/1/6796 6794/1/6794 +f 6797/1/6797 6794/1/6794 6793/1/6793 +f 6794/1/6794 6796/1/6796 6795/1/6795 +f 6784/1/6784 6794/1/6794 6795/1/6795 +f 6795/1/6795 6796/1/6796 6798/1/6798 +f 6798/1/6798 6782/1/6782 6795/1/6795 +f 6779/1/6779 6782/1/6782 6798/1/6798 +f 6798/1/6798 6780/1/6780 6779/1/6779 +f 6779/1/6779 6780/1/6780 6777/1/6777 +f 6779/1/6779 6777/1/6777 6781/1/6781 +f 6781/1/6781 6739/1/6739 6779/1/6779 +f 6776/1/6776 6739/1/6739 6781/1/6781 +f 6778/1/6778 6739/1/6739 6776/1/6776 +f 6776/1/6776 6774/1/6774 6778/1/6778 +f 6778/1/6778 6774/1/6774 6775/1/6775 +f 6775/1/6775 6740/1/6740 6778/1/6778 +f 6747/1/6747 6740/1/6740 6775/1/6775 +f 6775/1/6775 6748/1/6748 6747/1/6747 +f 6747/1/6747 6748/1/6748 6743/1/6743 +f 6743/1/6743 6748/1/6748 6745/1/6745 +f 6743/1/6743 6745/1/6745 6742/1/6742 +f 6742/1/6742 6741/1/6741 6743/1/6743 +f 6743/1/6743 6741/1/6741 6740/1/6740 +f 6741/1/6741 5737/1/5737 6740/1/6740 +f 6740/1/6740 5737/1/5737 5736/1/5736 +f 6740/1/6740 5736/1/5736 6739/1/6739 +f 6739/1/6739 5736/1/5736 6738/1/6738 +f 6739/1/6739 6738/1/6738 6782/1/6782 +f 5737/1/5737 5675/1/5675 5736/1/5736 +f 5736/1/5736 5675/1/5675 5676/1/5676 +f 5675/1/5675 5672/1/5672 5676/1/5676 +f 5676/1/5676 5672/1/5672 5670/1/5670 +f 5672/1/5672 5666/1/5666 5670/1/5670 +f 5672/1/5672 5671/1/5671 5666/1/5666 +f 5671/1/5671 5656/1/5656 5666/1/5666 +f 5666/1/5666 5656/1/5656 5662/1/5662 +f 5656/1/5656 5660/1/5660 5662/1/5662 +f 5656/1/5656 5655/1/5655 5660/1/5660 +f 5655/1/5655 5658/1/5658 5660/1/5660 +f 5660/1/5660 5658/1/5658 5659/1/5659 +f 5660/1/5660 5659/1/5659 5661/1/5661 +f 5655/1/5655 5651/1/5651 5658/1/5658 +f 5651/1/5651 5638/1/5638 5658/1/5658 +f 5658/1/5658 5638/1/5638 5640/1/5640 +f 5646/1/5646 5638/1/5638 5651/1/5651 +f 5652/1/5652 5646/1/5646 5651/1/5651 +f 5650/1/5650 5646/1/5646 5652/1/5652 +f 5654/1/5654 5650/1/5650 5652/1/5652 +f 5654/1/5654 5652/1/5652 5657/1/5657 +f 5673/1/5673 5654/1/5654 5657/1/5657 +f 5673/1/5673 5657/1/5657 5671/1/5671 +f 6231/1/6231 5654/1/5654 5673/1/5673 +f 5674/1/5674 6231/1/6231 5673/1/5673 +f 5674/1/5674 5673/1/5673 5672/1/5672 +f 5674/1/5674 6230/1/6230 6231/1/6231 +f 6230/1/6230 5653/1/5653 6231/1/6231 +f 6230/1/6230 6246/1/6246 5653/1/5653 +f 6246/1/6246 5649/1/5649 5653/1/5653 +f 5653/1/5653 5649/1/5649 5650/1/5650 +f 5649/1/5649 5645/1/5645 5650/1/5650 +f 5649/1/5649 5648/1/5648 5645/1/5645 +f 5648/1/5648 5644/1/5644 5645/1/5645 +f 5645/1/5645 5644/1/5644 5642/1/5642 +f 5645/1/5645 5642/1/5642 5646/1/5646 +f 5644/1/5644 5643/1/5643 5642/1/5642 +f 5642/1/5642 5643/1/5643 5639/1/5639 +f 5642/1/5642 5639/1/5639 5638/1/5638 +f 5638/1/5638 5639/1/5639 5637/1/5637 +f 5643/1/5643 6763/1/6763 5639/1/5639 +f 5639/1/5639 6763/1/6763 6766/1/6766 +f 6763/1/6763 6764/1/6764 6766/1/6766 +f 6763/1/6763 6756/1/6756 6764/1/6764 +f 6756/1/6756 6762/1/6762 6764/1/6764 +f 6764/1/6764 6762/1/6762 6765/1/6765 +f 6764/1/6764 6765/1/6765 6767/1/6767 +f 6767/1/6767 6765/1/6765 6768/1/6768 +f 6767/1/6767 6768/1/6768 6770/1/6770 +f 6768/1/6768 6769/1/6769 6770/1/6770 +f 6770/1/6770 6769/1/6769 6772/1/6772 +f 6770/1/6770 6772/1/6772 6773/1/6773 +f 6772/1/6772 6777/1/6777 6773/1/6773 +f 6772/1/6772 6774/1/6774 6777/1/6777 +f 6769/1/6769 6774/1/6774 6772/1/6772 +f 6769/1/6769 6748/1/6748 6774/1/6774 +f 6768/1/6768 6748/1/6748 6769/1/6769 +f 6749/1/6749 6748/1/6748 6768/1/6768 +f 6765/1/6765 6749/1/6749 6768/1/6768 +f 6762/1/6762 6749/1/6749 6765/1/6765 +f 6762/1/6762 6750/1/6750 6749/1/6749 +f 6750/1/6750 6746/1/6746 6749/1/6749 +f 6749/1/6749 6746/1/6746 6745/1/6745 +f 6750/1/6750 6751/1/6751 6746/1/6746 +f 6746/1/6746 6751/1/6751 6744/1/6744 +f 6742/1/6742 6746/1/6746 6744/1/6744 +f 6744/1/6744 5741/1/5741 6742/1/6742 +f 6752/1/6752 5741/1/5741 6744/1/6744 +f 6753/1/6753 5741/1/5741 6752/1/6752 +f 6752/1/6752 6754/1/6754 6753/1/6753 +f 6753/1/6753 6754/1/6754 5837/1/5837 +f 6753/1/6753 5837/1/5837 5836/1/5836 +f 5836/1/5836 5744/1/5744 6753/1/6753 +f 5835/1/5835 5744/1/5744 5836/1/5836 +f 5834/1/5834 5744/1/5744 5835/1/5835 +f 5835/1/5835 5819/1/5819 5834/1/5834 +f 5834/1/5834 5819/1/5819 5833/1/5833 +f 5833/1/5833 5747/1/5747 5834/1/5834 +f 5832/1/5832 5747/1/5747 5833/1/5833 +f 5833/1/5833 5815/1/5815 5832/1/5832 +f 5832/1/5832 5815/1/5815 5753/1/5753 +f 5753/1/5753 5815/1/5815 5816/1/5816 +f 5753/1/5753 5816/1/5816 5752/1/5752 +f 5752/1/5752 5750/1/5750 5753/1/5753 +f 5753/1/5753 5750/1/5750 5747/1/5747 +f 5750/1/5750 5748/1/5748 5747/1/5747 +f 5747/1/5747 5748/1/5748 5745/1/5745 +f 5747/1/5747 5745/1/5745 5744/1/5744 +f 5744/1/5744 5745/1/5745 5742/1/5742 +f 5744/1/5744 5742/1/5742 5741/1/5741 +f 5741/1/5741 5742/1/5742 5739/1/5739 +f 5741/1/5741 5739/1/5739 6741/1/6741 +f 5742/1/5742 5740/1/5740 5739/1/5739 +f 5739/1/5739 5740/1/5740 5738/1/5738 +f 5739/1/5739 5738/1/5738 5737/1/5737 +f 5740/1/5740 6229/1/6229 5738/1/5738 +f 5738/1/5738 6229/1/6229 5674/1/5674 +f 5738/1/5738 5674/1/5674 5675/1/5675 +f 5740/1/5740 6232/1/6232 6229/1/6229 +f 6232/1/6232 6233/1/6233 6229/1/6229 +f 6229/1/6229 6233/1/6233 6234/1/6234 +f 6229/1/6229 6234/1/6234 6230/1/6230 +f 6234/1/6234 6240/1/6240 6230/1/6230 +f 6234/1/6234 6239/1/6239 6240/1/6240 +f 6239/1/6239 6245/1/6245 6240/1/6240 +f 6240/1/6240 6245/1/6245 6246/1/6246 +f 6239/1/6239 6241/1/6241 6245/1/6245 +f 6241/1/6241 6247/1/6247 6245/1/6245 +f 6245/1/6245 6247/1/6247 5648/1/5648 +f 6247/1/6247 5647/1/5647 5648/1/5648 +f 6248/1/6248 5647/1/5647 6247/1/6247 +f 6248/1/6248 6250/1/6250 5647/1/5647 +f 6250/1/6250 7412/1/7412 5647/1/5647 +f 5647/1/5647 7412/1/7412 5643/1/5643 +f 7412/1/7412 6760/1/6760 5643/1/5643 +f 7412/1/7412 5821/1/5821 6760/1/6760 +f 5821/1/5821 6758/1/6758 6760/1/6760 +f 6760/1/6760 6758/1/6758 6756/1/6756 +f 6758/1/6758 6755/1/6755 6756/1/6756 +f 6756/1/6756 6755/1/6755 6757/1/6757 +f 6757/1/6757 6755/1/6755 6750/1/6750 +f 6758/1/6758 6759/1/6759 6755/1/6755 +f 6755/1/6755 6759/1/6759 6754/1/6754 +f 6755/1/6755 6754/1/6754 6751/1/6751 +f 5820/1/5820 6759/1/6759 6758/1/6758 +f 5820/1/5820 5818/1/5818 6759/1/6759 +f 5818/1/5818 6761/1/6761 6759/1/6759 +f 6761/1/6761 5837/1/5837 6759/1/6759 +f 6761/1/6761 5819/1/5819 5837/1/5837 +f 5817/1/5817 5819/1/5819 6761/1/6761 +f 5817/1/5817 5815/1/5815 5819/1/5819 +f 5814/1/5814 5815/1/5815 5817/1/5817 +f 5814/1/5814 5817/1/5817 5818/1/5818 +f 5809/1/5809 5814/1/5814 5818/1/5818 +f 5809/1/5809 5808/1/5808 5814/1/5814 +f 5808/1/5808 5811/1/5811 5814/1/5814 +f 5805/1/5805 5811/1/5811 5808/1/5808 +f 5806/1/5806 5805/1/5805 5808/1/5808 +f 5802/1/5802 5805/1/5805 5806/1/5806 +f 5803/1/5803 5802/1/5802 5806/1/5806 +f 5803/1/5803 5806/1/5806 5807/1/5807 +f 7413/1/7413 5803/1/5803 5807/1/5807 +f 7413/1/7413 5807/1/5807 7411/1/7411 +f 7406/1/7406 7413/1/7413 7411/1/7411 +f 7406/1/7406 7411/1/7411 7407/1/7407 +f 7405/1/7405 7406/1/7406 7407/1/7407 +f 7405/1/7405 7407/1/7407 7408/1/7408 +f 7402/1/7402 7405/1/7405 7408/1/7408 +f 7402/1/7402 7408/1/7408 6253/1/6253 +f 7403/1/7403 7402/1/7402 6253/1/6253 +f 7403/1/7403 6253/1/6253 6252/1/6252 +f 6251/1/6251 7403/1/7403 6252/1/6252 +f 6251/1/6251 6252/1/6252 6236/1/6236 +f 6235/1/6235 6251/1/6251 6236/1/6236 +f 6235/1/6235 6236/1/6236 6232/1/6232 +f 5743/1/5743 6235/1/6235 6232/1/6232 +f 5743/1/5743 7392/1/7392 6235/1/6235 +f 7392/1/7392 7404/1/7404 6235/1/6235 +f 7392/1/7392 7395/1/7395 7404/1/7404 +f 7395/1/7395 7398/1/7398 7404/1/7404 +f 7404/1/7404 7398/1/7398 7403/1/7403 +f 7395/1/7395 7394/1/7394 7398/1/7398 +f 7394/1/7394 7397/1/7397 7398/1/7398 +f 7397/1/7397 7401/1/7401 7398/1/7398 +f 7398/1/7398 7401/1/7401 7402/1/7402 +f 7397/1/7397 7400/1/7400 7401/1/7401 +f 7401/1/7401 7400/1/7400 7405/1/7405 +f 7397/1/7397 7399/1/7399 7400/1/7400 +f 7399/1/7399 7406/1/7406 7400/1/7400 +f 7399/1/7399 7414/1/7414 7406/1/7406 +f 7415/1/7415 7414/1/7414 7399/1/7399 +f 7396/1/7396 7415/1/7415 7399/1/7399 +f 7416/1/7416 7415/1/7415 7396/1/7396 +f 7388/1/7388 7416/1/7416 7396/1/7396 +f 7388/1/7388 7396/1/7396 7393/1/7393 +f 7389/1/7389 7388/1/7388 7393/1/7393 +f 7389/1/7389 7393/1/7393 7391/1/7391 +f 7390/1/7390 7389/1/7389 7391/1/7391 +f 7390/1/7390 7391/1/7391 7392/1/7392 +f 5746/1/5746 7390/1/7390 7392/1/7392 +f 5749/1/5749 7390/1/7390 5746/1/5746 +f 5748/1/5748 5749/1/5749 5746/1/5746 +f 5751/1/5751 5749/1/5749 5748/1/5748 +f 5751/1/5751 7328/1/7328 5749/1/5749 +f 7328/1/7328 7386/1/7386 5749/1/5749 +f 7328/1/7328 7384/1/7384 7386/1/7386 +f 7384/1/7384 7383/1/7383 7386/1/7386 +f 7386/1/7386 7383/1/7383 7385/1/7385 +f 7386/1/7386 7385/1/7385 7390/1/7390 +f 7383/1/7383 7382/1/7382 7385/1/7385 +f 7385/1/7385 7382/1/7382 7387/1/7387 +f 7385/1/7385 7387/1/7387 7388/1/7388 +f 7382/1/7382 7378/1/7378 7387/1/7387 +f 7378/1/7378 7416/1/7416 7387/1/7387 +f 7378/1/7378 7377/1/7377 7416/1/7416 +f 7378/1/7378 7374/1/7374 7377/1/7377 +f 7374/1/7374 7372/1/7372 7377/1/7377 +f 7377/1/7377 7372/1/7372 7376/1/7376 +f 7377/1/7377 7376/1/7376 7415/1/7415 +f 7372/1/7372 5796/1/5796 7376/1/7376 +f 7376/1/7376 5796/1/5796 7414/1/7414 +f 7414/1/7414 5796/1/5796 7413/1/7413 +f 7372/1/7372 5794/1/5794 5796/1/5796 +f 5794/1/5794 5795/1/5795 5796/1/5796 +f 5796/1/5796 5795/1/5795 5803/1/5803 +f 5794/1/5794 5793/1/5793 5795/1/5795 +f 5793/1/5793 5798/1/5798 5795/1/5795 +f 5795/1/5795 5798/1/5798 5802/1/5802 +f 5798/1/5798 5801/1/5801 5802/1/5802 +f 5802/1/5802 5801/1/5801 5804/1/5804 +f 5804/1/5804 5801/1/5801 5810/1/5810 +f 5804/1/5804 5810/1/5810 5805/1/5805 +f 5801/1/5801 5813/1/5813 5810/1/5810 +f 5810/1/5810 5813/1/5813 5812/1/5812 +f 5810/1/5810 5812/1/5812 5811/1/5811 +f 5811/1/5811 5812/1/5812 5816/1/5816 +f 5812/1/5812 5813/1/5813 5757/1/5757 +f 5752/1/5752 5812/1/5812 5757/1/5757 +f 5757/1/5757 5754/1/5754 5752/1/5752 +f 5756/1/5756 5754/1/5754 5757/1/5757 +f 5758/1/5758 5754/1/5754 5756/1/5756 +f 5756/1/5756 5822/1/5822 5758/1/5758 +f 5758/1/5758 5822/1/5822 5823/1/5823 +f 5758/1/5758 5823/1/5823 5824/1/5824 +f 5824/1/5824 5759/1/5759 5758/1/5758 +f 5825/1/5825 5759/1/5759 5824/1/5824 +f 5829/1/5829 5759/1/5759 5825/1/5825 +f 5825/1/5825 5826/1/5826 5829/1/5829 +f 5829/1/5829 5826/1/5826 5830/1/5830 +f 5830/1/5830 5761/1/5761 5829/1/5829 +f 5831/1/5831 5761/1/5761 5830/1/5830 +f 5830/1/5830 5777/1/5777 5831/1/5831 +f 5831/1/5831 5777/1/5777 5767/1/5767 +f 5767/1/5767 5777/1/5777 5769/1/5769 +f 5767/1/5767 5769/1/5769 5765/1/5765 +f 5765/1/5765 5763/1/5763 5767/1/5767 +f 5767/1/5767 5763/1/5763 5761/1/5761 +f 5763/1/5763 5762/1/5762 5761/1/5761 +f 5761/1/5761 5762/1/5762 5760/1/5760 +f 5761/1/5761 5760/1/5760 5759/1/5759 +f 5759/1/5759 5760/1/5760 5755/1/5755 +f 5759/1/5759 5755/1/5755 5754/1/5754 +f 5754/1/5754 5755/1/5755 5751/1/5751 +f 5754/1/5754 5751/1/5751 5750/1/5750 +f 5760/1/5760 7325/1/7325 5755/1/5755 +f 5755/1/5755 7325/1/7325 7328/1/7328 +f 7325/1/7325 7327/1/7327 7328/1/7328 +f 7325/1/7325 7326/1/7326 7327/1/7327 +f 7326/1/7326 7331/1/7331 7327/1/7327 +f 7327/1/7327 7331/1/7331 7337/1/7337 +f 7327/1/7327 7337/1/7337 7381/1/7381 +f 7327/1/7327 7381/1/7381 7384/1/7384 +f 7337/1/7337 7379/1/7379 7381/1/7381 +f 7381/1/7381 7379/1/7379 7380/1/7380 +f 7381/1/7381 7380/1/7380 7383/1/7383 +f 7379/1/7379 7375/1/7375 7380/1/7380 +f 7380/1/7380 7375/1/7375 7378/1/7378 +f 7379/1/7379 7343/1/7343 7375/1/7375 +f 7343/1/7343 7373/1/7373 7375/1/7375 +f 7375/1/7375 7373/1/7373 7374/1/7374 +f 7343/1/7343 7344/1/7344 7373/1/7373 +f 7344/1/7344 7371/1/7371 7373/1/7373 +f 7373/1/7373 7371/1/7371 7372/1/7372 +f 7344/1/7344 7345/1/7345 7371/1/7371 +f 7345/1/7345 5794/1/5794 7371/1/7371 +f 7345/1/7345 5792/1/5792 5794/1/5794 +f 7347/1/7347 5792/1/5792 7345/1/7345 +f 7341/1/7341 7347/1/7347 7345/1/7345 +f 7341/1/7341 7345/1/7345 7342/1/7342 +f 7338/1/7338 7341/1/7341 7342/1/7342 +f 7338/1/7338 7342/1/7342 7339/1/7339 +f 7335/1/7335 7338/1/7338 7339/1/7339 +f 7335/1/7335 7339/1/7339 7336/1/7336 +f 7331/1/7331 7335/1/7335 7336/1/7336 +f 7330/1/7330 7335/1/7335 7331/1/7331 +f 7330/1/7330 7334/1/7334 7335/1/7335 +f 7329/1/7329 7334/1/7334 7330/1/7330 +f 7326/1/7326 7329/1/7329 7330/1/7330 +f 7324/1/7324 7329/1/7329 7326/1/7326 +f 7324/1/7324 7332/1/7332 7329/1/7329 +f 7332/1/7332 7333/1/7333 7329/1/7329 +f 7332/1/7332 7354/1/7354 7333/1/7333 +f 7354/1/7354 7353/1/7353 7333/1/7333 +f 7353/1/7353 7348/1/7348 7333/1/7333 +f 7333/1/7333 7348/1/7348 7340/1/7340 +f 7333/1/7333 7340/1/7340 7334/1/7334 +f 7334/1/7334 7340/1/7340 7338/1/7338 +f 7348/1/7348 7346/1/7346 7340/1/7340 +f 7340/1/7340 7346/1/7346 7341/1/7341 +f 7348/1/7348 7349/1/7349 7346/1/7346 +f 7349/1/7349 7350/1/7350 7346/1/7346 +f 7346/1/7346 7350/1/7350 7347/1/7347 +f 7352/1/7352 7350/1/7350 7349/1/7349 +f 7353/1/7353 7352/1/7352 7349/1/7349 +f 7356/1/7356 7352/1/7352 7353/1/7353 +f 7355/1/7355 7356/1/7356 7353/1/7353 +f 7358/1/7358 7356/1/7356 7355/1/7355 +f 7360/1/7360 7358/1/7358 7355/1/7355 +f 7360/1/7360 7355/1/7355 7361/1/7361 +f 7321/1/7321 7360/1/7360 7361/1/7361 +f 7321/1/7321 7361/1/7361 7324/1/7324 +f 7323/1/7323 7321/1/7321 7324/1/7324 +f 7323/1/7323 7324/1/7324 7325/1/7325 +f 7322/1/7322 7321/1/7321 7323/1/7323 +f 5762/1/5762 7322/1/7322 7323/1/7323 +f 5764/1/5764 7322/1/7322 5762/1/5762 +f 5764/1/5764 7308/1/7308 7322/1/7322 +f 7308/1/7308 7320/1/7320 7322/1/7322 +f 7308/1/7308 7317/1/7317 7320/1/7320 +f 7317/1/7317 7316/1/7316 7320/1/7320 +f 7320/1/7320 7316/1/7316 7319/1/7319 +f 7320/1/7320 7319/1/7319 7321/1/7321 +f 7316/1/7316 7318/1/7318 7319/1/7319 +f 7319/1/7319 7318/1/7318 7362/1/7362 +f 7319/1/7319 7362/1/7362 7358/1/7358 +f 7362/1/7362 7359/1/7359 7358/1/7358 +f 7363/1/7363 7359/1/7359 7362/1/7362 +f 7363/1/7363 7366/1/7366 7359/1/7359 +f 7359/1/7359 7366/1/7366 7357/1/7357 +f 7359/1/7359 7357/1/7357 7356/1/7356 +f 7366/1/7366 7370/1/7370 7357/1/7357 +f 7357/1/7357 7370/1/7370 7351/1/7351 +f 7357/1/7357 7351/1/7351 7352/1/7352 +f 7370/1/7370 5790/1/5790 7351/1/7351 +f 7351/1/7351 5790/1/5790 5791/1/5791 +f 7351/1/7351 5791/1/5791 7350/1/7350 +f 7350/1/7350 5791/1/5791 5792/1/5792 +f 5791/1/5791 5787/1/5787 5792/1/5792 +f 5792/1/5792 5787/1/5787 5793/1/5793 +f 5787/1/5787 5785/1/5785 5793/1/5793 +f 5793/1/5793 5785/1/5785 5797/1/5797 +f 5785/1/5785 5799/1/5799 5797/1/5797 +f 5797/1/5797 5799/1/5799 5800/1/5800 +f 5797/1/5797 5800/1/5800 5798/1/5798 +f 5799/1/5799 5827/1/5827 5800/1/5800 +f 5827/1/5827 5823/1/5823 5800/1/5800 +f 5827/1/5827 5826/1/5826 5823/1/5823 +f 5828/1/5828 5826/1/5826 5827/1/5827 +f 5828/1/5828 5777/1/5777 5826/1/5826 +f 5779/1/5779 5777/1/5777 5828/1/5828 +f 5779/1/5779 5828/1/5828 5799/1/5799 +f 5776/1/5776 5777/1/5777 5779/1/5779 +f 5778/1/5778 5776/1/5776 5779/1/5779 +f 5785/1/5785 5778/1/5778 5779/1/5779 +f 5783/1/5783 5778/1/5778 5785/1/5785 +f 5783/1/5783 5780/1/5780 5778/1/5778 +f 5784/1/5784 5780/1/5780 5783/1/5783 +f 5786/1/5786 5784/1/5784 5783/1/5783 +f 5786/1/5786 5783/1/5783 5787/1/5787 +f 5788/1/5788 5784/1/5784 5786/1/5786 +f 5790/1/5790 5788/1/5788 5786/1/5786 +f 5838/1/5838 5788/1/5788 5790/1/5790 +f 5943/1/5943 5838/1/5838 5790/1/5790 +f 5938/1/5938 5838/1/5838 5943/1/5943 +f 7368/1/7368 5938/1/5938 5943/1/5943 +f 7368/1/7368 5943/1/5943 7365/1/7365 +f 7364/1/7364 7368/1/7368 7365/1/7365 +f 7364/1/7364 7365/1/7365 7363/1/7363 +f 7315/1/7315 7364/1/7364 7363/1/7363 +f 7315/1/7315 7363/1/7363 7318/1/7318 +f 7313/1/7313 7364/1/7364 7315/1/7315 +f 7314/1/7314 7313/1/7313 7315/1/7315 +f 7314/1/7314 7315/1/7315 7316/1/7316 +f 7312/1/7312 7313/1/7313 7314/1/7314 +f 7307/1/7307 7312/1/7312 7314/1/7314 +f 7307/1/7307 7314/1/7314 7317/1/7317 +f 7307/1/7307 7310/1/7310 7312/1/7312 +f 7310/1/7310 7311/1/7311 7312/1/7312 +f 7310/1/7310 5942/1/5942 7311/1/7311 +f 5942/1/5942 7369/1/7369 7311/1/7311 +f 7311/1/7311 7369/1/7369 7313/1/7313 +f 7369/1/7369 7367/1/7367 7313/1/7313 +f 7369/1/7369 5940/1/5940 7367/1/7367 +f 7367/1/7367 5940/1/5940 7368/1/7368 +f 7369/1/7369 5939/1/5939 5940/1/5940 +f 5939/1/5939 5937/1/5937 5940/1/5940 +f 5940/1/5940 5937/1/5937 5938/1/5938 +f 5935/1/5935 5937/1/5937 5939/1/5939 +f 5941/1/5941 5935/1/5935 5939/1/5939 +f 5936/1/5936 5935/1/5935 5941/1/5941 +f 5926/1/5926 5936/1/5936 5941/1/5941 +f 5926/1/5926 5941/1/5941 5942/1/5942 +f 7309/1/7309 5926/1/5926 5942/1/5942 +f 5924/1/5924 5926/1/5926 7309/1/7309 +f 7306/1/7306 5924/1/5924 7309/1/7309 +f 7306/1/7306 7309/1/7309 7310/1/7310 +f 5919/1/5919 5924/1/5924 7306/1/7306 +f 7304/1/7304 5919/1/5919 7306/1/7306 +f 7304/1/7304 7306/1/7306 7307/1/7307 +f 7304/1/7304 7307/1/7307 7308/1/7308 +f 7305/1/7305 7304/1/7304 7308/1/7308 +f 7303/1/7303 7304/1/7304 7305/1/7305 +f 5773/1/5773 7303/1/7303 7305/1/7305 +f 5773/1/5773 7305/1/7305 5766/1/5766 +f 5772/1/5772 5773/1/5773 5766/1/5766 +f 5772/1/5772 5766/1/5766 5771/1/5771 +f 5771/1/5771 6222/1/6222 5772/1/5772 +f 5772/1/5772 6222/1/6222 6224/1/6224 +f 5772/1/5772 6224/1/6224 6227/1/6227 +f 6227/1/6227 6224/1/6224 6228/1/6228 +f 6228/1/6228 5773/1/5773 6227/1/6227 +f 7418/1/7418 5773/1/5773 6228/1/6228 +f 6228/1/6228 6226/1/6226 7418/1/7418 +f 7418/1/7418 6226/1/6226 7417/1/7417 +f 7417/1/7417 7249/1/7249 7418/1/7418 +f 7248/1/7248 7249/1/7249 7417/1/7417 +f 7417/1/7417 7247/1/7247 7248/1/7248 +f 7248/1/7248 7247/1/7247 7245/1/7245 +f 7245/1/7245 7247/1/7247 7241/1/7241 +f 7245/1/7245 7241/1/7241 7240/1/7240 +f 7240/1/7240 7246/1/7246 7245/1/7245 +f 7245/1/7245 7246/1/7246 7249/1/7249 +f 7246/1/7246 7251/1/7251 7249/1/7249 +f 7249/1/7249 7251/1/7251 7303/1/7303 +f 7251/1/7251 5921/1/5921 7303/1/7303 +f 7251/1/7251 5920/1/5920 5921/1/5921 +f 5920/1/5920 5916/1/5916 5921/1/5921 +f 5921/1/5921 5916/1/5916 5919/1/5919 +f 5916/1/5916 5918/1/5918 5919/1/5919 +f 5919/1/5919 5918/1/5918 5923/1/5923 +f 5918/1/5918 5922/1/5922 5923/1/5923 +f 5923/1/5923 5922/1/5922 5925/1/5925 +f 5923/1/5923 5925/1/5925 5924/1/5924 +f 5922/1/5922 5927/1/5927 5925/1/5925 +f 5927/1/5927 5930/1/5930 5925/1/5925 +f 5925/1/5925 5930/1/5930 5936/1/5936 +f 5930/1/5930 5934/1/5934 5936/1/5936 +f 5930/1/5930 5929/1/5929 5934/1/5934 +f 5929/1/5929 5932/1/5932 5934/1/5934 +f 5934/1/5934 5932/1/5932 5933/1/5933 +f 5934/1/5934 5933/1/5933 5935/1/5935 +f 5932/1/5932 5839/1/5839 5933/1/5933 +f 5933/1/5933 5839/1/5839 5937/1/5937 +f 5937/1/5937 5839/1/5839 5838/1/5838 +f 5839/1/5839 5840/1/5840 5838/1/5838 +f 5839/1/5839 5841/1/5841 5840/1/5840 +f 5841/1/5841 5844/1/5844 5840/1/5840 +f 5840/1/5840 5844/1/5844 6218/1/6218 +f 5840/1/5840 6218/1/6218 5789/1/5789 +f 5840/1/5840 5789/1/5789 5788/1/5788 +f 6218/1/6218 6221/1/6221 5789/1/5789 +f 5789/1/5789 6221/1/6221 5782/1/5782 +f 5789/1/5789 5782/1/5782 5784/1/5784 +f 5784/1/5784 5782/1/5782 5781/1/5781 +f 5781/1/5781 5782/1/5782 5775/1/5775 +f 5781/1/5781 5775/1/5775 5780/1/5780 +f 5780/1/5780 5775/1/5775 5776/1/5776 +f 5775/1/5775 5770/1/5770 5776/1/5776 +f 5776/1/5776 5770/1/5770 5769/1/5769 +f 5775/1/5775 5774/1/5774 5770/1/5770 +f 5770/1/5770 5774/1/5774 5768/1/5768 +f 5765/1/5765 5770/1/5770 5768/1/5768 +f 5768/1/5768 5766/1/5766 5765/1/5765 +f 5768/1/5768 5774/1/5774 5771/1/5771 +f 5782/1/5782 5774/1/5774 5775/1/5775 +f 5782/1/5782 6222/1/6222 5774/1/5774 +f 5782/1/5782 6221/1/6221 6222/1/6222 +f 6218/1/6218 6219/1/6219 6221/1/6221 +f 6219/1/6219 6223/1/6223 6221/1/6221 +f 6223/1/6223 6224/1/6224 6221/1/6221 +f 6223/1/6223 6226/1/6226 6224/1/6224 +f 6225/1/6225 6226/1/6226 6223/1/6223 +f 6225/1/6225 7247/1/7247 6226/1/6226 +f 6220/1/6220 7247/1/7247 6225/1/6225 +f 6220/1/6220 6225/1/6225 6219/1/6219 +f 5844/1/5844 6220/1/6220 6219/1/6219 +f 5844/1/5844 7294/1/7294 6220/1/6220 +f 7294/1/7294 7242/1/7242 6220/1/6220 +f 7293/1/7293 7242/1/7242 7294/1/7294 +f 5843/1/5843 7293/1/7293 7294/1/7294 +f 7290/1/7290 7293/1/7293 5843/1/5843 +f 5845/1/5845 7290/1/7290 5843/1/5843 +f 5845/1/5845 5843/1/5843 5841/1/5841 +f 5842/1/5842 5845/1/5845 5841/1/5841 +f 5846/1/5846 5845/1/5845 5842/1/5842 +f 5931/1/5931 5846/1/5846 5842/1/5842 +f 5931/1/5931 5842/1/5842 5932/1/5932 +f 5928/1/5928 5931/1/5931 5932/1/5932 +f 5911/1/5911 5931/1/5931 5928/1/5928 +f 5912/1/5912 5911/1/5911 5928/1/5928 +f 5912/1/5912 5928/1/5928 5927/1/5927 +f 5917/1/5917 5912/1/5912 5927/1/5927 +f 5913/1/5913 5912/1/5912 5917/1/5917 +f 5915/1/5915 5913/1/5913 5917/1/5917 +f 5915/1/5915 5917/1/5917 5918/1/5918 +f 5914/1/5914 5913/1/5913 5915/1/5915 +f 5916/1/5916 5914/1/5914 5915/1/5915 +f 5894/1/5894 5914/1/5914 5916/1/5916 +f 5894/1/5894 5904/1/5904 5914/1/5914 +f 5904/1/5904 5905/1/5905 5914/1/5914 +f 5914/1/5914 5905/1/5905 5908/1/5908 +f 5905/1/5905 5903/1/5903 5908/1/5908 +f 5903/1/5903 5907/1/5907 5908/1/5908 +f 5908/1/5908 5907/1/5907 5913/1/5913 +f 5903/1/5903 5906/1/5906 5907/1/5907 +f 5907/1/5907 5906/1/5906 5911/1/5911 +f 5906/1/5906 5910/1/5910 5911/1/5911 +f 5906/1/5906 5909/1/5909 5910/1/5910 +f 5909/1/5909 5846/1/5846 5910/1/5910 +f 5909/1/5909 5848/1/5848 5846/1/5846 +f 5848/1/5848 5847/1/5847 5846/1/5846 +f 5848/1/5848 5849/1/5849 5847/1/5847 +f 5849/1/5849 7292/1/7292 5847/1/5847 +f 5847/1/5847 7292/1/7292 7290/1/7290 +f 7292/1/7292 7288/1/7288 7290/1/7290 +f 7290/1/7290 7288/1/7288 7291/1/7291 +f 7291/1/7291 7288/1/7288 7239/1/7239 +f 7291/1/7291 7239/1/7239 7293/1/7293 +f 7288/1/7288 7237/1/7237 7239/1/7239 +f 7239/1/7239 7237/1/7237 7236/1/7236 +f 7239/1/7239 7236/1/7236 7242/1/7242 +f 7242/1/7242 7236/1/7236 7241/1/7241 +f 7236/1/7236 7237/1/7237 7238/1/7238 +f 7240/1/7240 7236/1/7236 7238/1/7238 +f 7238/1/7238 7244/1/7244 7240/1/7240 +f 7243/1/7243 7244/1/7244 7238/1/7238 +f 7286/1/7286 7244/1/7244 7243/1/7243 +f 7243/1/7243 7287/1/7287 7286/1/7286 +f 7286/1/7286 7287/1/7287 7282/1/7282 +f 7286/1/7286 7282/1/7282 7285/1/7285 +f 7285/1/7285 7253/1/7253 7286/1/7286 +f 7281/1/7281 7253/1/7253 7285/1/7285 +f 7259/1/7259 7253/1/7253 7281/1/7281 +f 7281/1/7281 7280/1/7280 7259/1/7259 +f 7259/1/7259 7280/1/7280 7258/1/7258 +f 7258/1/7258 7254/1/7254 7259/1/7259 +f 7257/1/7257 7254/1/7254 7258/1/7258 +f 7258/1/7258 7277/1/7277 7257/1/7257 +f 7257/1/7257 7277/1/7277 7256/1/7256 +f 7256/1/7256 7277/1/7277 7273/1/7273 +f 7256/1/7256 7273/1/7273 7264/1/7264 +f 7264/1/7264 7255/1/7255 7256/1/7256 +f 7256/1/7256 7255/1/7255 7254/1/7254 +f 7255/1/7255 5946/1/5946 7254/1/7254 +f 7254/1/7254 5946/1/5946 5945/1/5945 +f 7254/1/7254 5945/1/5945 7253/1/7253 +f 7253/1/7253 5945/1/5945 7252/1/7252 +f 7253/1/7253 7252/1/7252 7244/1/7244 +f 7244/1/7244 7252/1/7252 7250/1/7250 +f 7244/1/7244 7250/1/7250 7246/1/7246 +f 7252/1/7252 5895/1/5895 7250/1/7250 +f 7250/1/7250 5895/1/5895 5920/1/5920 +f 5895/1/5895 5894/1/5894 5920/1/5920 +f 5895/1/5895 5891/1/5891 5894/1/5894 +f 5891/1/5891 5893/1/5893 5894/1/5894 +f 5891/1/5891 5892/1/5892 5893/1/5893 +f 5892/1/5892 5896/1/5896 5893/1/5893 +f 5893/1/5893 5896/1/5896 5899/1/5899 +f 5893/1/5893 5899/1/5899 5904/1/5904 +f 5896/1/5896 5898/1/5898 5899/1/5899 +f 5899/1/5899 5898/1/5898 5903/1/5903 +f 5898/1/5898 5902/1/5902 5903/1/5903 +f 5898/1/5898 5901/1/5901 5902/1/5902 +f 5901/1/5901 5909/1/5909 5902/1/5902 +f 5901/1/5901 5944/1/5944 5909/1/5909 +f 5900/1/5900 5944/1/5944 5901/1/5901 +f 5897/1/5897 5900/1/5900 5901/1/5901 +f 5879/1/5879 5900/1/5900 5897/1/5897 +f 5879/1/5879 5897/1/5897 5896/1/5896 +f 5882/1/5882 5879/1/5879 5896/1/5896 +f 5878/1/5878 5879/1/5879 5882/1/5882 +f 5883/1/5883 5878/1/5878 5882/1/5882 +f 5883/1/5883 5882/1/5882 5892/1/5892 +f 5881/1/5881 5878/1/5878 5883/1/5883 +f 5884/1/5884 5881/1/5881 5883/1/5883 +f 5884/1/5884 5883/1/5883 5891/1/5891 +f 5890/1/5890 5884/1/5884 5891/1/5891 +f 5890/1/5890 5886/1/5886 5884/1/5884 +f 5886/1/5886 5880/1/5880 5884/1/5884 +f 5886/1/5886 5885/1/5885 5880/1/5880 +f 5885/1/5885 5870/1/5870 5880/1/5880 +f 5880/1/5880 5870/1/5870 5875/1/5875 +f 5880/1/5880 5875/1/5875 5881/1/5881 +f 5870/1/5870 5874/1/5874 5875/1/5875 +f 5875/1/5875 5874/1/5874 5876/1/5876 +f 5875/1/5875 5876/1/5876 5878/1/5878 +f 5874/1/5874 5873/1/5873 5876/1/5876 +f 5876/1/5876 5873/1/5873 5877/1/5877 +f 5876/1/5876 5877/1/5877 5879/1/5879 +f 5873/1/5873 5854/1/5854 5877/1/5877 +f 5877/1/5877 5854/1/5854 5900/1/5900 +f 5873/1/5873 5853/1/5853 5854/1/5854 +f 5853/1/5853 5850/1/5850 5854/1/5854 +f 5854/1/5854 5850/1/5850 5848/1/5848 +f 5854/1/5854 5848/1/5848 5944/1/5944 +f 5851/1/5851 5850/1/5850 5853/1/5853 +f 5872/1/5872 5851/1/5851 5853/1/5853 +f 5865/1/5865 5851/1/5851 5872/1/5872 +f 5871/1/5871 5865/1/5865 5872/1/5872 +f 5871/1/5871 5872/1/5872 5874/1/5874 +f 5866/1/5866 5865/1/5865 5871/1/5871 +f 5866/1/5866 5871/1/5871 5870/1/5870 +f 5869/1/5869 5866/1/5866 5870/1/5870 +f 5867/1/5867 5866/1/5866 5869/1/5869 +f 5887/1/5887 5867/1/5867 5869/1/5869 +f 5887/1/5887 5869/1/5869 5885/1/5885 +f 6189/1/6189 5867/1/5867 5887/1/5887 +f 5888/1/5888 6189/1/6189 5887/1/5887 +f 5888/1/5888 5887/1/5887 5886/1/5886 +f 5889/1/5889 5888/1/5888 5886/1/5886 +f 5947/1/5947 5888/1/5888 5889/1/5889 +f 5946/1/5946 5947/1/5947 5889/1/5889 +f 5948/1/5948 5947/1/5947 5946/1/5946 +f 5948/1/5948 5949/1/5949 5947/1/5947 +f 5949/1/5949 6187/1/6187 5947/1/5947 +f 5949/1/5949 6190/1/6190 6187/1/6187 +f 6190/1/6190 6191/1/6191 6187/1/6187 +f 6187/1/6187 6191/1/6191 6192/1/6192 +f 6187/1/6187 6192/1/6192 6188/1/6188 +f 6187/1/6187 6188/1/6188 5888/1/5888 +f 6192/1/6192 6198/1/6198 6188/1/6188 +f 6188/1/6188 6198/1/6198 6201/1/6201 +f 6188/1/6188 6201/1/6201 5868/1/5868 +f 6188/1/6188 5868/1/5868 6189/1/6189 +f 6201/1/6201 5863/1/5863 5868/1/5868 +f 5868/1/5868 5863/1/5863 5864/1/5864 +f 5868/1/5868 5864/1/5864 5867/1/5867 +f 5863/1/5863 5858/1/5858 5864/1/5864 +f 5864/1/5864 5858/1/5858 5859/1/5859 +f 5864/1/5864 5859/1/5859 5866/1/5866 +f 5858/1/5858 5855/1/5855 5859/1/5859 +f 5859/1/5859 5855/1/5855 5851/1/5851 +f 5855/1/5855 5852/1/5852 5851/1/5851 +f 5855/1/5855 5856/1/5856 5852/1/5852 +f 5856/1/5856 7229/1/7229 5852/1/5852 +f 5852/1/5852 7229/1/7229 7230/1/7230 +f 5852/1/5852 7230/1/7230 5850/1/5850 +f 5850/1/5850 7230/1/7230 5849/1/5849 +f 7230/1/7230 7295/1/7295 5849/1/5849 +f 5849/1/5849 7295/1/7295 7296/1/7296 +f 7295/1/7295 7297/1/7297 7296/1/7296 +f 7296/1/7296 7297/1/7297 7289/1/7289 +f 7296/1/7296 7289/1/7289 7292/1/7292 +f 7297/1/7297 7284/1/7284 7289/1/7289 +f 7284/1/7284 7282/1/7282 7289/1/7289 +f 7284/1/7284 7280/1/7280 7282/1/7282 +f 7283/1/7283 7280/1/7280 7284/1/7284 +f 7283/1/7283 7277/1/7277 7280/1/7280 +f 7278/1/7278 7277/1/7277 7283/1/7283 +f 7278/1/7278 7283/1/7283 7297/1/7297 +f 7274/1/7274 7277/1/7277 7278/1/7278 +f 7279/1/7279 7274/1/7274 7278/1/7278 +f 7295/1/7295 7279/1/7279 7278/1/7278 +f 7298/1/7298 7279/1/7279 7295/1/7295 +f 7298/1/7298 7275/1/7275 7279/1/7279 +f 7299/1/7299 7275/1/7275 7298/1/7298 +f 7229/1/7229 7299/1/7299 7298/1/7298 +f 7228/1/7228 7299/1/7299 7229/1/7229 +f 7228/1/7228 7300/1/7300 7299/1/7299 +f 7300/1/7300 7269/1/7269 7299/1/7299 +f 7299/1/7299 7269/1/7269 7276/1/7276 +f 7276/1/7276 7269/1/7269 7272/1/7272 +f 7276/1/7276 7272/1/7272 7275/1/7275 +f 7275/1/7275 7272/1/7272 7274/1/7274 +f 7272/1/7272 7271/1/7271 7274/1/7274 +f 7274/1/7274 7271/1/7271 7273/1/7273 +f 7272/1/7272 7268/1/7268 7271/1/7271 +f 7271/1/7271 7268/1/7268 7263/1/7263 +f 7264/1/7264 7271/1/7271 7263/1/7263 +f 7263/1/7263 7260/1/7260 7264/1/7264 +f 7262/1/7262 7260/1/7260 7263/1/7263 +f 7261/1/7261 7260/1/7260 7262/1/7262 +f 7262/1/7262 7267/1/7267 7261/1/7261 +f 7261/1/7261 7267/1/7267 7266/1/7266 +f 7261/1/7261 7266/1/7266 7265/1/7265 +f 7265/1/7265 5953/1/5953 7261/1/7261 +f 6186/1/6186 5953/1/5953 7265/1/7265 +f 6185/1/6185 5953/1/5953 6186/1/6186 +f 6186/1/6186 6179/1/6179 6185/1/6185 +f 6185/1/6185 6179/1/6179 6184/1/6184 +f 6184/1/6184 5955/1/5955 6185/1/6185 +f 6183/1/6183 5955/1/5955 6184/1/6184 +f 6184/1/6184 6174/1/6174 6183/1/6183 +f 6183/1/6183 6174/1/6174 6182/1/6182 +f 6182/1/6182 6174/1/6174 6172/1/6172 +f 6182/1/6182 6172/1/6172 6173/1/6173 +f 6173/1/6173 5958/1/5958 6182/1/6182 +f 6182/1/6182 5958/1/5958 5955/1/5955 +f 5958/1/5958 5956/1/5956 5955/1/5955 +f 5955/1/5955 5956/1/5956 5952/1/5952 +f 5955/1/5955 5952/1/5952 5953/1/5953 +f 5953/1/5953 5952/1/5952 5950/1/5950 +f 5953/1/5953 5950/1/5950 7260/1/7260 +f 7260/1/7260 5950/1/5950 5948/1/5948 +f 7260/1/7260 5948/1/5948 7255/1/7255 +f 5952/1/5952 5951/1/5951 5950/1/5950 +f 5950/1/5950 5951/1/5951 5949/1/5949 +f 5952/1/5952 5954/1/5954 5951/1/5951 +f 5954/1/5954 6216/1/6216 5951/1/5951 +f 5951/1/5951 6216/1/6216 6193/1/6193 +f 5951/1/5951 6193/1/6193 6190/1/6190 +f 6193/1/6193 6194/1/6194 6190/1/6190 +f 6190/1/6190 6194/1/6194 6195/1/6195 +f 6194/1/6194 6211/1/6211 6195/1/6195 +f 6195/1/6195 6211/1/6211 6196/1/6196 +f 6195/1/6195 6196/1/6196 6191/1/6191 +f 6191/1/6191 6196/1/6196 6197/1/6197 +f 6196/1/6196 6200/1/6200 6197/1/6197 +f 6197/1/6197 6200/1/6200 6199/1/6199 +f 6197/1/6197 6199/1/6199 6198/1/6198 +f 6200/1/6200 6202/1/6202 6199/1/6199 +f 6199/1/6199 6202/1/6202 5862/1/5862 +f 6199/1/6199 5862/1/5862 5863/1/5863 +f 6202/1/6202 5860/1/5860 5862/1/5862 +f 5862/1/5862 5860/1/5860 5857/1/5857 +f 5862/1/5862 5857/1/5857 5858/1/5858 +f 5860/1/5860 5856/1/5856 5857/1/5857 +f 5860/1/5860 5861/1/5861 5856/1/5856 +f 5861/1/5861 7228/1/7228 5856/1/5856 +f 5861/1/5861 6181/1/6181 7228/1/7228 +f 7226/1/7226 6181/1/6181 5861/1/5861 +f 6209/1/6209 7226/1/7226 5861/1/5861 +f 6209/1/6209 5861/1/5861 6206/1/6206 +f 6205/1/6205 6209/1/6209 6206/1/6206 +f 6205/1/6205 6206/1/6206 6204/1/6204 +f 6203/1/6203 6205/1/6205 6204/1/6204 +f 6203/1/6203 6204/1/6204 6200/1/6200 +f 6207/1/6207 6205/1/6205 6203/1/6203 +f 6207/1/6207 6203/1/6203 6196/1/6196 +f 6207/1/6207 6208/1/6208 6205/1/6205 +f 6210/1/6210 6208/1/6208 6207/1/6207 +f 6212/1/6212 6210/1/6210 6207/1/6207 +f 6212/1/6212 6207/1/6207 6211/1/6211 +f 6215/1/6215 6210/1/6210 6212/1/6212 +f 6213/1/6213 6215/1/6215 6212/1/6212 +f 6213/1/6213 6212/1/6212 6194/1/6194 +f 6214/1/6214 6215/1/6215 6213/1/6213 +f 6193/1/6193 6214/1/6214 6213/1/6213 +f 6214/1/6214 7214/1/7214 6215/1/6215 +f 7214/1/7214 6217/1/6217 6215/1/6215 +f 7214/1/7214 7234/1/7234 6217/1/6217 +f 7234/1/7234 7232/1/7232 6217/1/6217 +f 6217/1/6217 7232/1/7232 7231/1/7231 +f 6217/1/6217 7231/1/7231 6210/1/6210 +f 7232/1/7232 7227/1/7227 7231/1/7231 +f 7231/1/7231 7227/1/7227 6209/1/6209 +f 7231/1/7231 6209/1/6209 6208/1/6208 +f 7232/1/7232 7225/1/7225 7227/1/7227 +f 7225/1/7225 7226/1/7226 7227/1/7227 +f 7225/1/7225 7224/1/7224 7226/1/7226 +f 7224/1/7224 6180/1/6180 7226/1/7226 +f 7224/1/7224 6166/1/6166 6180/1/6180 +f 6166/1/6166 6165/1/6165 6180/1/6180 +f 6180/1/6180 6165/1/6165 6176/1/6176 +f 6180/1/6180 6176/1/6176 6181/1/6181 +f 6181/1/6181 6176/1/6176 7301/1/7301 +f 6181/1/6181 7301/1/7301 7300/1/7300 +f 7301/1/7301 7270/1/7270 7300/1/7300 +f 7301/1/7301 6178/1/6178 7270/1/7270 +f 6178/1/6178 7302/1/7302 7270/1/7270 +f 7302/1/7302 7266/1/7266 7270/1/7270 +f 7302/1/7302 6179/1/6179 7266/1/7266 +f 6177/1/6177 6179/1/6179 7302/1/7302 +f 6177/1/6177 6174/1/6174 6179/1/6179 +f 6175/1/6175 6174/1/6174 6177/1/6177 +f 6175/1/6175 6177/1/6177 6178/1/6178 +f 6176/1/6176 6175/1/6175 6178/1/6178 +f 6176/1/6176 6169/1/6169 6175/1/6175 +f 6169/1/6169 6168/1/6168 6175/1/6175 +f 6164/1/6164 6168/1/6168 6169/1/6169 +f 6165/1/6165 6164/1/6164 6169/1/6169 +f 6019/1/6019 6164/1/6164 6165/1/6165 +f 6019/1/6019 6163/1/6163 6164/1/6164 +f 6163/1/6163 6167/1/6167 6164/1/6164 +f 6163/1/6163 6011/1/6011 6167/1/6167 +f 6011/1/6011 6012/1/6012 6167/1/6167 +f 6167/1/6167 6012/1/6012 6170/1/6170 +f 6167/1/6167 6170/1/6170 6168/1/6168 +f 6168/1/6168 6170/1/6170 6172/1/6172 +f 6170/1/6170 6012/1/6012 6171/1/6171 +f 6173/1/6173 6170/1/6170 6171/1/6171 +f 6171/1/6171 5962/1/5962 6173/1/6173 +f 6010/1/6010 5962/1/5962 6171/1/6171 +f 6004/1/6004 5962/1/5962 6010/1/6010 +f 6010/1/6010 6008/1/6008 6004/1/6004 +f 6004/1/6004 6008/1/6008 6005/1/6005 +f 6004/1/6004 6005/1/6005 6003/1/6003 +f 6003/1/6003 5963/1/5963 6004/1/6004 +f 6002/1/6002 5963/1/5963 6003/1/6003 +f 6000/1/6000 5963/1/5963 6002/1/6002 +f 6002/1/6002 6001/1/6001 6000/1/6000 +f 6000/1/6000 6001/1/6001 5999/1/5999 +f 5999/1/5999 5965/1/5965 6000/1/6000 +f 5998/1/5998 5965/1/5965 5999/1/5999 +f 5999/1/5999 5997/1/5997 5998/1/5998 +f 5998/1/5998 5997/1/5997 5971/1/5971 +f 5971/1/5971 5997/1/5997 5996/1/5996 +f 5971/1/5971 5996/1/5996 5970/1/5970 +f 5970/1/5970 5967/1/5967 5971/1/5971 +f 5971/1/5971 5967/1/5967 5965/1/5965 +f 5967/1/5967 5966/1/5966 5965/1/5965 +f 5965/1/5965 5966/1/5966 5964/1/5964 +f 5965/1/5965 5964/1/5964 5963/1/5963 +f 5963/1/5963 5964/1/5964 5961/1/5961 +f 5963/1/5963 5961/1/5961 5962/1/5962 +f 5962/1/5962 5961/1/5961 5959/1/5959 +f 5962/1/5962 5959/1/5959 5958/1/5958 +f 5961/1/5961 5960/1/5960 5959/1/5959 +f 5959/1/5959 5960/1/5960 5957/1/5957 +f 5959/1/5959 5957/1/5957 5956/1/5956 +f 5956/1/5956 5957/1/5957 5954/1/5954 +f 5957/1/5957 7207/1/7207 5954/1/5954 +f 5957/1/5957 7205/1/7205 7207/1/7207 +f 7205/1/7205 7206/1/7206 7207/1/7207 +f 7207/1/7207 7206/1/7206 7208/1/7208 +f 7207/1/7207 7208/1/7208 7209/1/7209 +f 7207/1/7207 7209/1/7209 6216/1/6216 +f 6216/1/6216 7209/1/7209 7213/1/7213 +f 6216/1/6216 7213/1/7213 6214/1/6214 +f 7209/1/7209 7212/1/7212 7213/1/7213 +f 7213/1/7213 7212/1/7212 7214/1/7214 +f 7212/1/7212 7216/1/7216 7214/1/7214 +f 7211/1/7211 7216/1/7216 7212/1/7212 +f 7211/1/7211 7215/1/7215 7216/1/7216 +f 7215/1/7215 7219/1/7219 7216/1/7216 +f 7216/1/7216 7219/1/7219 7233/1/7233 +f 7216/1/7216 7233/1/7233 7234/1/7234 +f 7219/1/7219 7225/1/7225 7233/1/7233 +f 7219/1/7219 7223/1/7223 7225/1/7225 +f 7218/1/7218 7223/1/7223 7219/1/7219 +f 7218/1/7218 7222/1/7222 7223/1/7223 +f 7222/1/7222 7185/1/7185 7223/1/7223 +f 7223/1/7223 7185/1/7185 7224/1/7224 +f 7184/1/7184 7185/1/7185 7222/1/7222 +f 7220/1/7220 7184/1/7184 7222/1/7222 +f 7193/1/7193 7184/1/7184 7220/1/7220 +f 7194/1/7194 7193/1/7193 7220/1/7220 +f 7194/1/7194 7220/1/7220 7217/1/7217 +f 7194/1/7194 7217/1/7217 7221/1/7221 +f 7198/1/7198 7194/1/7194 7221/1/7221 +f 7206/1/7206 7198/1/7198 7221/1/7221 +f 7206/1/7206 7221/1/7221 7210/1/7210 +f 7199/1/7199 7198/1/7198 7206/1/7206 +f 7199/1/7199 7195/1/7195 7198/1/7198 +f 7197/1/7197 7195/1/7195 7199/1/7199 +f 7201/1/7201 7197/1/7197 7199/1/7199 +f 7201/1/7201 7199/1/7199 7205/1/7205 +f 5960/1/5960 7201/1/7201 7205/1/7205 +f 5960/1/5960 7200/1/7200 7201/1/7201 +f 7204/1/7204 7200/1/7200 5960/1/5960 +f 7204/1/7204 7203/1/7203 7200/1/7200 +f 7203/1/7203 7202/1/7202 7200/1/7200 +f 7200/1/7200 7202/1/7202 7196/1/7196 +f 7200/1/7200 7196/1/7196 7197/1/7197 +f 7196/1/7196 7190/1/7190 7197/1/7197 +f 7196/1/7196 7189/1/7189 7190/1/7190 +f 7189/1/7189 7187/1/7187 7190/1/7190 +f 7187/1/7187 7188/1/7188 7190/1/7190 +f 7190/1/7190 7188/1/7188 7192/1/7192 +f 7190/1/7190 7192/1/7192 7195/1/7195 +f 7195/1/7195 7192/1/7192 7194/1/7194 +f 7188/1/7188 7186/1/7186 7192/1/7192 +f 7192/1/7192 7186/1/7186 7193/1/7193 +f 7188/1/7188 7183/1/7183 7186/1/7186 +f 7183/1/7183 7182/1/7182 7186/1/7186 +f 7186/1/7186 7182/1/7182 7184/1/7184 +f 7182/1/7182 6162/1/6162 7184/1/7184 +f 7178/1/7178 6162/1/6162 7182/1/7182 +f 7178/1/7178 6023/1/6023 6162/1/6162 +f 6023/1/6023 6017/1/6017 6162/1/6162 +f 6162/1/6162 6017/1/6017 6018/1/6018 +f 6162/1/6162 6018/1/6018 7185/1/7185 +f 7185/1/7185 6018/1/6018 6166/1/6166 +f 6018/1/6018 6019/1/6019 6166/1/6166 +f 6018/1/6018 6015/1/6015 6019/1/6019 +f 6015/1/6015 6011/1/6011 6019/1/6019 +f 6015/1/6015 6009/1/6009 6011/1/6011 +f 6011/1/6011 6009/1/6009 6008/1/6008 +f 6014/1/6014 6009/1/6009 6015/1/6015 +f 6017/1/6017 6014/1/6014 6015/1/6015 +f 6017/1/6017 6016/1/6016 6014/1/6014 +f 6016/1/6016 6013/1/6013 6014/1/6014 +f 6016/1/6016 5995/1/5995 6013/1/6013 +f 5995/1/5995 6007/1/6007 6013/1/6013 +f 6013/1/6013 6007/1/6007 6006/1/6006 +f 6013/1/6013 6006/1/6006 6009/1/6009 +f 6006/1/6006 6005/1/6005 6009/1/6009 +f 6006/1/6006 6001/1/6001 6005/1/6005 +f 6007/1/6007 6001/1/6001 6006/1/6006 +f 6007/1/6007 5997/1/5997 6001/1/6001 +f 5995/1/5995 5997/1/5997 6007/1/6007 +f 5991/1/5991 5997/1/5997 5995/1/5995 +f 5994/1/5994 5991/1/5991 5995/1/5995 +f 5990/1/5990 5991/1/5991 5994/1/5994 +f 5993/1/5993 5990/1/5990 5994/1/5994 +f 5993/1/5993 5994/1/5994 6016/1/6016 +f 6020/1/6020 5993/1/5993 6016/1/6016 +f 6022/1/6022 5993/1/5993 6020/1/6020 +f 6021/1/6021 6022/1/6022 6020/1/6020 +f 6021/1/6021 6020/1/6020 6023/1/6023 +f 7166/1/7166 6021/1/6021 6023/1/6023 +f 7166/1/7166 6023/1/6023 7177/1/7177 +f 7165/1/7165 7166/1/7166 7177/1/7177 +f 7165/1/7165 7177/1/7177 7179/1/7179 +f 7160/1/7160 7165/1/7165 7179/1/7179 +f 7160/1/7160 7179/1/7179 7181/1/7181 +f 7161/1/7161 7160/1/7160 7181/1/7181 +f 7161/1/7161 7181/1/7181 7191/1/7191 +f 7235/1/7235 7161/1/7161 7191/1/7191 +f 7235/1/7235 7191/1/7191 7202/1/7202 +f 7202/1/7202 7191/1/7191 7189/1/7189 +f 7159/1/7159 7161/1/7161 7235/1/7235 +f 7203/1/7203 7159/1/7159 7235/1/7235 +f 7152/1/7152 7159/1/7159 7203/1/7203 +f 7152/1/7152 7156/1/7156 7159/1/7159 +f 7156/1/7156 7158/1/7158 7159/1/7159 +f 7156/1/7156 7155/1/7155 7158/1/7158 +f 7155/1/7155 7157/1/7157 7158/1/7158 +f 7157/1/7157 7162/1/7162 7158/1/7158 +f 7158/1/7158 7162/1/7162 7160/1/7160 +f 7157/1/7157 7164/1/7164 7162/1/7162 +f 7162/1/7162 7164/1/7164 7165/1/7165 +f 7157/1/7157 7163/1/7163 7164/1/7164 +f 7163/1/7163 7166/1/7166 7164/1/7164 +f 7163/1/7163 7168/1/7168 7166/1/7166 +f 7167/1/7167 7168/1/7168 7163/1/7163 +f 7149/1/7149 7167/1/7167 7163/1/7163 +f 7144/1/7144 7167/1/7167 7149/1/7149 +f 7145/1/7145 7144/1/7144 7149/1/7149 +f 7145/1/7145 7149/1/7149 7150/1/7150 +f 7146/1/7146 7145/1/7145 7150/1/7150 +f 7146/1/7146 7150/1/7150 7151/1/7151 +f 7148/1/7148 7146/1/7146 7151/1/7151 +f 7148/1/7148 7151/1/7151 7152/1/7152 +f 7154/1/7154 7148/1/7148 7152/1/7152 +f 7154/1/7154 7152/1/7152 7204/1/7204 +f 5964/1/5964 7154/1/7154 7204/1/7204 +f 7153/1/7153 7148/1/7148 7154/1/7154 +f 5966/1/5966 7153/1/7153 7154/1/7154 +f 5968/1/5968 7153/1/7153 5966/1/5966 +f 5968/1/5968 7125/1/7125 7153/1/7153 +f 7125/1/7125 7147/1/7147 7153/1/7153 +f 7125/1/7125 7138/1/7138 7147/1/7147 +f 7138/1/7138 7137/1/7137 7147/1/7147 +f 7147/1/7147 7137/1/7137 7143/1/7143 +f 7147/1/7147 7143/1/7143 7148/1/7148 +f 7137/1/7137 7140/1/7140 7143/1/7143 +f 7143/1/7143 7140/1/7140 7142/1/7142 +f 7143/1/7143 7142/1/7142 7145/1/7145 +f 7140/1/7140 7139/1/7139 7142/1/7142 +f 7139/1/7139 7144/1/7144 7142/1/7142 +f 7139/1/7139 7169/1/7169 7144/1/7144 +f 7139/1/7139 7171/1/7171 7169/1/7169 +f 7171/1/7171 6159/1/6159 7169/1/7169 +f 7169/1/7169 6159/1/6159 7170/1/7170 +f 7169/1/7169 7170/1/7170 7167/1/7167 +f 6159/1/6159 6024/1/6024 7170/1/7170 +f 7170/1/7170 6024/1/6024 7168/1/7168 +f 7168/1/7168 6024/1/6024 6021/1/6021 +f 6159/1/6159 6156/1/6156 6024/1/6024 +f 6156/1/6156 6025/1/6025 6024/1/6024 +f 6024/1/6024 6025/1/6025 6022/1/6022 +f 6025/1/6025 5987/1/5987 6022/1/6022 +f 6025/1/6025 5989/1/5989 5987/1/5987 +f 5989/1/5989 5983/1/5983 5987/1/5987 +f 5987/1/5987 5983/1/5983 5988/1/5988 +f 5987/1/5987 5988/1/5988 5990/1/5990 +f 5988/1/5988 5986/1/5986 5990/1/5990 +f 5988/1/5988 5983/1/5983 5986/1/5986 +f 5983/1/5983 5984/1/5984 5986/1/5986 +f 5986/1/5986 5984/1/5984 5992/1/5992 +f 5986/1/5986 5992/1/5992 5991/1/5991 +f 5991/1/5991 5992/1/5992 5996/1/5996 +f 5992/1/5992 5984/1/5984 5976/1/5976 +f 5970/1/5970 5992/1/5992 5976/1/5976 +f 5976/1/5976 5969/1/5969 5970/1/5970 +f 5975/1/5975 5969/1/5969 5976/1/5976 +f 5973/1/5973 5969/1/5969 5975/1/5975 +f 5975/1/5975 5977/1/5977 5973/1/5973 +f 5973/1/5973 5977/1/5977 5978/1/5978 +f 5973/1/5973 5978/1/5978 5979/1/5979 +f 5979/1/5979 5974/1/5974 5973/1/5973 +f 5980/1/5980 5974/1/5974 5979/1/5979 +f 5982/1/5982 5974/1/5974 5980/1/5980 +f 5980/1/5980 5981/1/5981 5982/1/5982 +f 5982/1/5982 5981/1/5981 7107/1/7107 +f 7107/1/7107 7104/1/7104 5982/1/5982 +f 7103/1/7103 7104/1/7104 7107/1/7107 +f 7107/1/7107 6161/1/6161 7103/1/7103 +f 7103/1/7103 6161/1/6161 7101/1/7101 +f 7101/1/7101 6161/1/6161 7100/1/7100 +f 7101/1/7101 7100/1/7100 7098/1/7098 +f 7098/1/7098 7102/1/7102 7101/1/7101 +f 7101/1/7101 7102/1/7102 7104/1/7104 +f 7102/1/7102 7105/1/7105 7104/1/7104 +f 7104/1/7104 7105/1/7105 7106/1/7106 +f 7104/1/7104 7106/1/7106 5974/1/5974 +f 5974/1/5974 7106/1/7106 5972/1/5972 +f 5974/1/5974 5972/1/5972 5969/1/5969 +f 5969/1/5969 5972/1/5972 5968/1/5968 +f 5969/1/5969 5968/1/5968 5967/1/5967 +f 7106/1/7106 7124/1/7124 5972/1/5972 +f 5972/1/5972 7124/1/7124 7125/1/7125 +f 7124/1/7124 7127/1/7127 7125/1/7125 +f 7124/1/7124 7126/1/7126 7127/1/7127 +f 7126/1/7126 7130/1/7130 7127/1/7127 +f 7127/1/7127 7130/1/7130 7133/1/7133 +f 7127/1/7127 7133/1/7133 7135/1/7135 +f 7127/1/7127 7135/1/7135 7138/1/7138 +f 7133/1/7133 7134/1/7134 7135/1/7135 +f 7135/1/7135 7134/1/7134 7136/1/7136 +f 7135/1/7135 7136/1/7136 7137/1/7137 +f 7134/1/7134 7141/1/7141 7136/1/7136 +f 7136/1/7136 7141/1/7141 7139/1/7139 +f 7134/1/7134 7174/1/7174 7141/1/7141 +f 7174/1/7174 7172/1/7172 7141/1/7141 +f 7141/1/7141 7172/1/7172 7171/1/7171 +f 7174/1/7174 7173/1/7173 7172/1/7172 +f 7173/1/7173 6157/1/6157 7172/1/7172 +f 7172/1/7172 6157/1/6157 6159/1/6159 +f 7173/1/7173 6155/1/6155 6157/1/6157 +f 6155/1/6155 6156/1/6156 6157/1/6157 +f 6155/1/6155 6036/1/6036 6156/1/6156 +f 6036/1/6036 6026/1/6026 6156/1/6156 +f 6036/1/6036 6028/1/6028 6026/1/6026 +f 6028/1/6028 6029/1/6029 6026/1/6026 +f 6026/1/6026 6029/1/6029 6027/1/6027 +f 6026/1/6026 6027/1/6027 5989/1/5989 +f 6027/1/6027 5985/1/5985 5989/1/5989 +f 6027/1/6027 6030/1/6030 5985/1/5985 +f 6030/1/6030 6031/1/6031 5985/1/5985 +f 6031/1/6031 5978/1/5978 5985/1/5985 +f 6031/1/6031 5981/1/5981 5978/1/5978 +f 6033/1/6033 5981/1/5981 6031/1/6031 +f 6033/1/6033 6161/1/6161 5981/1/5981 +f 6032/1/6032 6161/1/6161 6033/1/6033 +f 6032/1/6032 6033/1/6033 6030/1/6030 +f 6029/1/6029 6032/1/6032 6030/1/6030 +f 6029/1/6029 7108/1/7108 6032/1/6032 +f 7108/1/7108 7099/1/7099 6032/1/6032 +f 7109/1/7109 7099/1/7099 7108/1/7108 +f 6034/1/6034 7109/1/7109 7108/1/7108 +f 7111/1/7111 7109/1/7109 6034/1/6034 +f 6037/1/6037 7111/1/7111 6034/1/6034 +f 6037/1/6037 6034/1/6034 6028/1/6028 +f 6035/1/6035 6037/1/6037 6028/1/6028 +f 6038/1/6038 6037/1/6037 6035/1/6035 +f 6149/1/6149 6038/1/6038 6035/1/6035 +f 6149/1/6149 6035/1/6035 6150/1/6150 +f 6146/1/6146 6149/1/6149 6150/1/6150 +f 6146/1/6146 6150/1/6150 6147/1/6147 +f 6145/1/6145 6146/1/6146 6147/1/6147 +f 6145/1/6145 6147/1/6147 6148/1/6148 +f 6145/1/6145 6148/1/6148 6104/1/6104 +f 6102/1/6102 6145/1/6145 6104/1/6104 +f 6103/1/6103 6102/1/6102 6104/1/6104 +f 6103/1/6103 6104/1/6104 7128/1/7128 +f 6100/1/6100 6103/1/6103 7128/1/7128 +f 6100/1/6100 7128/1/7128 7126/1/7126 +f 7126/1/7126 7128/1/7128 7129/1/7129 +f 7128/1/7128 6160/1/6160 7129/1/7129 +f 7129/1/7129 6160/1/6160 7131/1/7131 +f 7129/1/7129 7131/1/7131 7130/1/7130 +f 7130/1/7130 7131/1/7131 7132/1/7132 +f 7131/1/7131 7175/1/7175 7132/1/7132 +f 7132/1/7132 7175/1/7175 7134/1/7134 +f 7131/1/7131 7176/1/7176 7175/1/7175 +f 7176/1/7176 6158/1/6158 7175/1/7175 +f 7175/1/7175 6158/1/6158 7173/1/7173 +f 7176/1/7176 6153/1/6153 6158/1/6158 +f 6153/1/6153 6155/1/6155 6158/1/6158 +f 6153/1/6153 6151/1/6151 6155/1/6155 +f 6152/1/6152 6151/1/6151 6153/1/6153 +f 6154/1/6154 6152/1/6152 6153/1/6153 +f 6148/1/6148 6152/1/6152 6154/1/6154 +f 6152/1/6152 6150/1/6150 6151/1/6151 +f 6150/1/6150 6036/1/6036 6151/1/6151 +f 6154/1/6154 6153/1/6153 7176/1/7176 +f 6160/1/6160 6154/1/6154 7176/1/7176 +f 6104/1/6104 6154/1/6154 6160/1/6160 +f 6160/1/6160 7176/1/7176 7131/1/7131 +f 6100/1/6100 6099/1/6099 6103/1/6103 +f 6097/1/6097 6099/1/6099 6100/1/6100 +f 7123/1/7123 6097/1/6097 6100/1/6100 +f 7123/1/7123 6100/1/6100 7124/1/7124 +f 6101/1/6101 6097/1/6097 7123/1/7123 +f 7105/1/7105 6101/1/6101 7123/1/7123 +f 7053/1/7053 6101/1/6101 7105/1/7105 +f 7053/1/7053 6106/1/6106 6101/1/6101 +f 6106/1/6106 6096/1/6096 6101/1/6101 +f 6106/1/6106 6105/1/6105 6096/1/6096 +f 6105/1/6105 6081/1/6081 6096/1/6096 +f 6096/1/6096 6081/1/6081 6094/1/6094 +f 6096/1/6096 6094/1/6094 6093/1/6093 +f 6096/1/6096 6093/1/6093 6097/1/6097 +f 6097/1/6097 6093/1/6093 6095/1/6095 +f 6093/1/6093 6092/1/6092 6095/1/6095 +f 6095/1/6095 6092/1/6092 6098/1/6098 +f 6095/1/6095 6098/1/6098 6099/1/6099 +f 6099/1/6099 6098/1/6098 6102/1/6102 +f 6092/1/6092 6091/1/6091 6098/1/6098 +f 6098/1/6098 6091/1/6091 6145/1/6145 +f 6092/1/6092 6087/1/6087 6091/1/6091 +f 6087/1/6087 6090/1/6090 6091/1/6091 +f 6091/1/6091 6090/1/6090 6146/1/6146 +f 6087/1/6087 6085/1/6085 6090/1/6090 +f 6085/1/6085 6089/1/6089 6090/1/6090 +f 6090/1/6090 6089/1/6089 6149/1/6149 +f 6085/1/6085 6084/1/6084 6089/1/6089 +f 6084/1/6084 6038/1/6038 6089/1/6089 +f 6084/1/6084 6040/1/6040 6038/1/6038 +f 6040/1/6040 6039/1/6039 6038/1/6038 +f 6040/1/6040 6041/1/6041 6039/1/6039 +f 6041/1/6041 7112/1/7112 6039/1/6039 +f 6039/1/6039 7112/1/7112 7111/1/7111 +f 7112/1/7112 7093/1/7093 7111/1/7111 +f 7111/1/7111 7093/1/7093 7110/1/7110 +f 7110/1/7110 7093/1/7093 7097/1/7097 +f 7110/1/7110 7097/1/7097 7109/1/7109 +f 7093/1/7093 7094/1/7094 7097/1/7097 +f 7097/1/7097 7094/1/7094 7096/1/7096 +f 7097/1/7097 7096/1/7096 7099/1/7099 +f 7099/1/7099 7096/1/7096 7100/1/7100 +f 7096/1/7096 7094/1/7094 7095/1/7095 +f 7098/1/7098 7096/1/7096 7095/1/7095 +f 7095/1/7095 7087/1/7087 7098/1/7098 +f 7090/1/7090 7087/1/7087 7095/1/7095 +f 7086/1/7086 7087/1/7087 7090/1/7090 +f 7090/1/7090 7089/1/7089 7086/1/7086 +f 7086/1/7086 7089/1/7089 7088/1/7088 +f 7086/1/7086 7088/1/7088 7085/1/7085 +f 7085/1/7085 7082/1/7082 7086/1/7086 +f 7084/1/7084 7082/1/7082 7085/1/7085 +f 7083/1/7083 7082/1/7082 7084/1/7084 +f 7084/1/7084 7080/1/7080 7083/1/7083 +f 7083/1/7083 7080/1/7080 7079/1/7079 +f 7079/1/7079 7055/1/7055 7083/1/7083 +f 7078/1/7078 7055/1/7055 7079/1/7079 +f 7079/1/7079 7077/1/7077 7078/1/7078 +f 7078/1/7078 7077/1/7077 7059/1/7059 +f 7059/1/7059 7077/1/7077 7071/1/7071 +f 7059/1/7059 7071/1/7071 7058/1/7058 +f 7058/1/7058 7056/1/7056 7059/1/7059 +f 7059/1/7059 7056/1/7056 7055/1/7055 +f 7056/1/7056 6602/1/6602 7055/1/7055 +f 7055/1/7055 6602/1/6602 7054/1/7054 +f 7055/1/7055 7054/1/7054 7082/1/7082 +f 7082/1/7082 7054/1/7054 7052/1/7052 +f 7082/1/7082 7052/1/7052 7087/1/7087 +f 7087/1/7087 7052/1/7052 7053/1/7053 +f 7087/1/7087 7053/1/7053 7102/1/7102 +f 7054/1/7054 6109/1/6109 7052/1/7052 +f 7052/1/7052 6109/1/6109 6106/1/6106 +f 7054/1/7054 6117/1/6117 6109/1/6109 +f 6117/1/6117 6108/1/6108 6109/1/6109 +f 6109/1/6109 6108/1/6108 6107/1/6107 +f 6109/1/6109 6107/1/6107 6105/1/6105 +f 6107/1/6107 6072/1/6072 6105/1/6105 +f 6105/1/6105 6072/1/6072 6079/1/6079 +f 6072/1/6072 6071/1/6071 6079/1/6079 +f 6079/1/6079 6071/1/6071 6077/1/6077 +f 6079/1/6079 6077/1/6077 6081/1/6081 +f 6081/1/6081 6077/1/6077 6080/1/6080 +f 6077/1/6077 6078/1/6078 6080/1/6080 +f 6080/1/6080 6078/1/6078 6083/1/6083 +f 6080/1/6080 6083/1/6083 6086/1/6086 +f 6094/1/6094 6080/1/6080 6086/1/6086 +f 6086/1/6086 6083/1/6083 6088/1/6088 +f 6093/1/6093 6086/1/6086 6088/1/6088 +f 6083/1/6083 6087/1/6087 6088/1/6088 +f 6078/1/6078 6082/1/6082 6083/1/6083 +f 6083/1/6083 6082/1/6082 6085/1/6085 +f 6078/1/6078 6076/1/6076 6082/1/6082 +f 6076/1/6076 6084/1/6084 6082/1/6082 +f 6076/1/6076 6075/1/6075 6084/1/6084 +f 6074/1/6074 6075/1/6075 6076/1/6076 +f 6073/1/6073 6074/1/6074 6076/1/6076 +f 6068/1/6068 6074/1/6074 6073/1/6073 +f 6071/1/6071 6068/1/6068 6073/1/6073 +f 6067/1/6067 6068/1/6068 6071/1/6071 +f 6067/1/6067 6065/1/6065 6068/1/6068 +f 6065/1/6065 6066/1/6066 6068/1/6068 +f 6065/1/6065 6062/1/6062 6066/1/6066 +f 6062/1/6062 6045/1/6045 6066/1/6066 +f 6066/1/6066 6045/1/6045 6074/1/6074 +f 6062/1/6062 6044/1/6044 6045/1/6045 +f 6044/1/6044 6042/1/6042 6045/1/6045 +f 6045/1/6045 6042/1/6042 6040/1/6040 +f 6045/1/6045 6040/1/6040 6075/1/6075 +f 6043/1/6043 6042/1/6042 6044/1/6044 +f 6061/1/6061 6043/1/6043 6044/1/6044 +f 6054/1/6054 6043/1/6043 6061/1/6061 +f 6060/1/6060 6054/1/6054 6061/1/6061 +f 6060/1/6060 6061/1/6061 6063/1/6063 +f 6059/1/6059 6060/1/6060 6063/1/6063 +f 6059/1/6059 6063/1/6063 6064/1/6064 +f 6069/1/6069 6059/1/6059 6064/1/6064 +f 6069/1/6069 6064/1/6064 6070/1/6070 +f 6107/1/6107 6069/1/6069 6070/1/6070 +f 6070/1/6070 6064/1/6064 6067/1/6067 +f 6070/1/6070 6067/1/6067 6072/1/6072 +f 6110/1/6110 6059/1/6059 6069/1/6069 +f 6108/1/6108 6110/1/6110 6069/1/6069 +f 6108/1/6108 6111/1/6111 6110/1/6110 +f 6111/1/6111 6058/1/6058 6110/1/6110 +f 6111/1/6111 6056/1/6056 6058/1/6058 +f 6056/1/6056 6055/1/6055 6058/1/6058 +f 6058/1/6058 6055/1/6055 6059/1/6059 +f 6056/1/6056 6053/1/6053 6055/1/6055 +f 6053/1/6053 6049/1/6049 6055/1/6055 +f 6055/1/6055 6049/1/6049 6054/1/6054 +f 6053/1/6053 6048/1/6048 6049/1/6049 +f 6048/1/6048 6046/1/6046 6049/1/6049 +f 6049/1/6049 6046/1/6046 6043/1/6043 +f 6046/1/6046 5595/1/5595 6043/1/6043 +f 6046/1/6046 5593/1/5593 5595/1/5595 +f 5593/1/5593 5594/1/5594 5595/1/5595 +f 5595/1/5595 5594/1/5594 5596/1/5596 +f 5595/1/5595 5596/1/5596 6042/1/6042 +f 6042/1/6042 5596/1/5596 6041/1/6041 +f 5596/1/5596 7114/1/7114 6041/1/6041 +f 6041/1/6041 7114/1/7114 7113/1/7113 +f 7114/1/7114 7115/1/7115 7113/1/7113 +f 7113/1/7113 7115/1/7115 7092/1/7092 +f 7113/1/7113 7092/1/7092 7112/1/7112 +f 7115/1/7115 7091/1/7091 7092/1/7092 +f 7091/1/7091 7088/1/7088 7092/1/7092 +f 7091/1/7091 7080/1/7080 7088/1/7088 +f 7081/1/7081 7080/1/7080 7091/1/7091 +f 7081/1/7081 7077/1/7077 7080/1/7080 +f 7076/1/7076 7077/1/7077 7081/1/7081 +f 7076/1/7076 7081/1/7081 7115/1/7115 +f 7073/1/7073 7077/1/7077 7076/1/7076 +f 7075/1/7075 7073/1/7073 7076/1/7076 +f 7114/1/7114 7075/1/7075 7076/1/7076 +f 7116/1/7116 7075/1/7075 7114/1/7114 +f 7116/1/7116 7074/1/7074 7075/1/7075 +f 7117/1/7117 7074/1/7074 7116/1/7116 +f 5594/1/5594 7117/1/7117 7116/1/7116 +f 5592/1/5592 7117/1/7117 5594/1/5594 +f 5592/1/5592 7118/1/7118 7117/1/7117 +f 7118/1/7118 7068/1/7068 7117/1/7117 +f 7118/1/7118 7120/1/7120 7068/1/7068 +f 7120/1/7120 7067/1/7067 7068/1/7068 +f 7067/1/7067 7064/1/7064 7068/1/7068 +f 7068/1/7068 7064/1/7064 7066/1/7066 +f 7068/1/7068 7066/1/7066 7072/1/7072 +f 7068/1/7068 7072/1/7072 7074/1/7074 +f 7074/1/7074 7072/1/7072 7073/1/7073 +f 7072/1/7072 7070/1/7070 7073/1/7073 +f 7073/1/7073 7070/1/7070 7071/1/7071 +f 7072/1/7072 7066/1/7066 7070/1/7070 +f 7070/1/7070 7066/1/7066 7069/1/7069 +f 7058/1/7058 7070/1/7070 7069/1/7069 +f 7069/1/7069 7057/1/7057 7058/1/7058 +f 7065/1/7065 7057/1/7057 7069/1/7069 +f 7062/1/7062 7057/1/7057 7065/1/7065 +f 7065/1/7065 7064/1/7064 7062/1/7062 +f 7062/1/7062 7064/1/7064 7061/1/7061 +f 7061/1/7061 6600/1/6600 7062/1/7062 +f 7060/1/7060 6600/1/6600 7061/1/7061 +f 7061/1/7061 7063/1/7063 7060/1/7060 +f 7060/1/7060 7063/1/7063 6611/1/6611 +f 6611/1/6611 6598/1/6598 7060/1/7060 +f 6612/1/6612 6598/1/6598 6611/1/6611 +f 6611/1/6611 6610/1/6610 6612/1/6612 +f 6612/1/6612 6610/1/6610 6604/1/6604 +f 6604/1/6604 6610/1/6610 6609/1/6609 +f 6604/1/6604 6609/1/6609 6603/1/6603 +f 6603/1/6603 6597/1/6597 6604/1/6604 +f 6604/1/6604 6597/1/6597 6598/1/6598 +f 6597/1/6597 6595/1/6595 6598/1/6598 +f 6598/1/6598 6595/1/6595 6596/1/6596 +f 6598/1/6598 6596/1/6596 6600/1/6600 +f 6600/1/6600 6596/1/6596 6599/1/6599 +f 6600/1/6600 6599/1/6599 7057/1/7057 +f 7057/1/7057 6599/1/6599 6601/1/6601 +f 7057/1/7057 6601/1/6601 7056/1/7056 +f 6599/1/6599 6120/1/6120 6601/1/6601 +f 6601/1/6601 6120/1/6120 6116/1/6116 +f 6601/1/6601 6116/1/6116 6602/1/6602 +f 6602/1/6602 6116/1/6116 6117/1/6117 +f 6116/1/6116 6113/1/6113 6117/1/6117 +f 6116/1/6116 6115/1/6115 6113/1/6113 +f 6115/1/6115 6114/1/6114 6113/1/6113 +f 6113/1/6113 6114/1/6114 6112/1/6112 +f 6113/1/6113 6112/1/6112 6111/1/6111 +f 6114/1/6114 6057/1/6057 6112/1/6112 +f 6112/1/6112 6057/1/6057 6056/1/6056 +f 6114/1/6114 6144/1/6144 6057/1/6057 +f 6144/1/6144 6052/1/6052 6057/1/6057 +f 6057/1/6057 6052/1/6052 6053/1/6053 +f 6140/1/6140 6052/1/6052 6144/1/6144 +f 6125/1/6125 6140/1/6140 6144/1/6144 +f 6124/1/6124 6140/1/6140 6125/1/6125 +f 6119/1/6119 6124/1/6124 6125/1/6125 +f 6119/1/6119 6125/1/6125 6114/1/6114 +f 6123/1/6123 6124/1/6124 6119/1/6119 +f 6118/1/6118 6123/1/6123 6119/1/6119 +f 6118/1/6118 6119/1/6119 6115/1/6115 +f 6120/1/6120 6118/1/6118 6115/1/6115 +f 6120/1/6120 6121/1/6121 6118/1/6118 +f 6121/1/6121 6122/1/6122 6118/1/6118 +f 6121/1/6121 6127/1/6127 6122/1/6122 +f 6127/1/6127 6128/1/6128 6122/1/6122 +f 6122/1/6122 6128/1/6128 6126/1/6126 +f 6122/1/6122 6126/1/6126 6123/1/6123 +f 6128/1/6128 6129/1/6129 6126/1/6126 +f 6129/1/6129 6131/1/6131 6126/1/6126 +f 6126/1/6126 6131/1/6131 6130/1/6130 +f 6126/1/6126 6130/1/6130 6124/1/6124 +f 6131/1/6131 6138/1/6138 6130/1/6130 +f 6130/1/6130 6138/1/6138 6139/1/6139 +f 6130/1/6130 6139/1/6139 6140/1/6140 +f 6140/1/6140 6139/1/6139 6051/1/6051 +f 6139/1/6139 6050/1/6050 6051/1/6051 +f 6051/1/6051 6050/1/6050 6047/1/6047 +f 6051/1/6051 6047/1/6047 6048/1/6048 +f 6052/1/6052 6051/1/6051 6048/1/6048 +f 6050/1/6050 5593/1/5593 6047/1/6047 +f 6050/1/6050 5591/1/5591 5593/1/5593 +f 5591/1/5591 5592/1/5592 5593/1/5593 +f 5591/1/5591 5590/1/5590 5592/1/5592 +f 5590/1/5590 7119/1/7119 5592/1/5592 +f 5590/1/5590 6728/1/6728 7119/1/7119 +f 6728/1/6728 7121/1/7121 7119/1/7119 +f 7119/1/7119 7121/1/7121 7120/1/7120 +f 6728/1/6728 6726/1/6726 7121/1/7121 +f 6726/1/6726 7122/1/7122 7121/1/7121 +f 7121/1/7121 7122/1/7122 7067/1/7067 +f 7122/1/7122 7063/1/7063 7067/1/7067 +f 7122/1/7122 6610/1/6610 7063/1/7063 +f 6727/1/6727 6610/1/6610 7122/1/7122 +f 6725/1/6725 6610/1/6610 6727/1/6727 +f 6726/1/6726 6725/1/6725 6727/1/6727 +f 6724/1/6724 6725/1/6725 6726/1/6726 +f 6724/1/6724 6722/1/6722 6725/1/6725 +f 6722/1/6722 6609/1/6609 6725/1/6725 +f 6722/1/6722 6613/1/6613 6609/1/6609 +f 6609/1/6609 6613/1/6613 6608/1/6608 +f 6608/1/6608 6613/1/6613 6606/1/6606 +f 6608/1/6608 6606/1/6606 6594/1/6594 +f 6605/1/6605 6608/1/6608 6594/1/6594 +f 6594/1/6594 6592/1/6592 6605/1/6605 +f 6605/1/6605 6592/1/6592 6603/1/6603 +f 6594/1/6594 6591/1/6591 6592/1/6592 +f 6591/1/6591 5608/1/5608 6592/1/6592 +f 6592/1/6592 5608/1/5608 6595/1/6595 +f 5608/1/5608 5555/1/5555 6595/1/6595 +f 6595/1/6595 5555/1/5555 5605/1/5605 +f 5555/1/5555 5554/1/5554 5605/1/5605 +f 5605/1/5605 5554/1/5554 5603/1/5603 +f 5605/1/5605 5603/1/5603 6137/1/6137 +f 6596/1/6596 5605/1/5605 6137/1/6137 +f 6596/1/6596 6137/1/6137 6136/1/6136 +f 6137/1/6137 5604/1/5604 6136/1/6136 +f 6136/1/6136 5604/1/5604 6121/1/6121 +f 5604/1/5604 6133/1/6133 6121/1/6121 +f 5604/1/5604 6135/1/6135 6133/1/6133 +f 6135/1/6135 5606/1/5606 6133/1/6133 +f 6133/1/6133 5606/1/5606 6132/1/6132 +f 6133/1/6133 6132/1/6132 6127/1/6127 +f 5606/1/5606 6134/1/6134 6132/1/6132 +f 6132/1/6132 6134/1/6134 6129/1/6129 +f 6134/1/6134 6142/1/6142 6129/1/6129 +f 6129/1/6129 6142/1/6142 6141/1/6141 +f 6142/1/6142 6143/1/6143 6141/1/6141 +f 6141/1/6141 6143/1/6143 6138/1/6138 +f 6138/1/6138 6143/1/6143 6050/1/6050 +f 6142/1/6142 5586/1/5586 6143/1/6143 +f 5586/1/5586 5580/1/5580 6143/1/6143 +f 6143/1/6143 5580/1/5580 5591/1/5591 +f 5581/1/5581 5580/1/5580 5586/1/5586 +f 5587/1/5587 5581/1/5581 5586/1/5586 +f 5584/1/5584 5581/1/5581 5587/1/5587 +f 5588/1/5588 5584/1/5584 5587/1/5587 +f 5588/1/5588 5587/1/5587 6134/1/6134 +f 5585/1/5585 5584/1/5584 5588/1/5588 +f 5585/1/5585 5588/1/5588 5606/1/5606 +f 5601/1/5601 5585/1/5585 5606/1/5606 +f 5598/1/5598 5585/1/5585 5601/1/5601 +f 5602/1/5602 5598/1/5598 5601/1/5601 +f 5602/1/5602 5601/1/5601 6135/1/6135 +f 5600/1/5600 5598/1/5598 5602/1/5602 +f 5603/1/5603 5600/1/5600 5602/1/5602 +f 5603/1/5603 5602/1/5602 5604/1/5604 +f 5603/1/5603 5599/1/5599 5600/1/5600 +f 5599/1/5599 5597/1/5597 5600/1/5600 +f 5599/1/5599 5559/1/5559 5597/1/5597 +f 5559/1/5559 5563/1/5563 5597/1/5597 +f 5597/1/5597 5563/1/5563 5598/1/5598 +f 5563/1/5563 5583/1/5583 5598/1/5598 +f 5563/1/5563 5565/1/5565 5583/1/5583 +f 5565/1/5565 5578/1/5578 5583/1/5583 +f 5583/1/5583 5578/1/5578 5582/1/5582 +f 5583/1/5583 5582/1/5582 5585/1/5585 +f 5578/1/5578 5577/1/5577 5582/1/5582 +f 5582/1/5582 5577/1/5577 5581/1/5581 +f 5577/1/5577 5576/1/5576 5581/1/5581 +f 5567/1/5567 5576/1/5576 5577/1/5577 +f 5567/1/5567 5570/1/5570 5576/1/5576 +f 5576/1/5576 5570/1/5570 5579/1/5579 +f 5576/1/5576 5579/1/5579 5580/1/5580 +f 5580/1/5580 5579/1/5579 5589/1/5589 +f 5580/1/5580 5589/1/5589 5590/1/5590 +f 5579/1/5579 6724/1/6724 5589/1/5589 +f 5589/1/5589 6724/1/6724 6728/1/6728 +f 5579/1/5579 6721/1/6721 6724/1/6724 +f 5570/1/5570 6721/1/6721 5579/1/5579 +f 5570/1/5570 6622/1/6622 6721/1/6721 +f 6622/1/6622 6720/1/6720 6721/1/6721 +f 6721/1/6721 6720/1/6720 6722/1/6722 +f 6720/1/6720 6723/1/6723 6722/1/6722 +f 6720/1/6720 6606/1/6606 6723/1/6723 +f 6720/1/6720 6615/1/6615 6606/1/6606 +f 6615/1/6615 6607/1/6607 6606/1/6606 +f 6614/1/6614 6607/1/6607 6615/1/6615 +f 6616/1/6616 6614/1/6614 6615/1/6615 +f 6620/1/6620 6616/1/6616 6615/1/6615 +f 6620/1/6620 6615/1/6615 6622/1/6622 +f 5569/1/5569 6620/1/6620 6622/1/6622 +f 5572/1/5572 6620/1/6620 5569/1/5569 +f 5571/1/5571 5572/1/5572 5569/1/5569 +f 5571/1/5571 5569/1/5569 5566/1/5566 +f 5568/1/5568 5571/1/5571 5566/1/5566 +f 5568/1/5568 5566/1/5566 5561/1/5561 +f 5557/1/5557 5568/1/5568 5561/1/5561 +f 5557/1/5557 5561/1/5561 5558/1/5558 +f 5551/1/5551 5557/1/5557 5558/1/5558 +f 5551/1/5551 5558/1/5558 5556/1/5556 +f 5552/1/5552 5551/1/5551 5556/1/5556 +f 5552/1/5552 5556/1/5556 5553/1/5553 +f 5550/1/5550 5552/1/5552 5553/1/5553 +f 5550/1/5550 5553/1/5553 5554/1/5554 +f 5554/1/5554 5553/1/5553 5599/1/5599 +f 5550/1/5550 5547/1/5547 5552/1/5552 +f 5548/1/5548 5547/1/5547 5550/1/5550 +f 5549/1/5549 5548/1/5548 5550/1/5550 +f 5549/1/5549 5550/1/5550 5555/1/5555 +f 5542/1/5542 5548/1/5548 5549/1/5549 +f 5543/1/5543 5542/1/5542 5549/1/5549 +f 5543/1/5543 5549/1/5549 5607/1/5607 +f 5460/1/5460 5543/1/5543 5607/1/5607 +f 6590/1/6590 5460/1/5460 5607/1/5607 +f 6590/1/6590 5607/1/5607 6591/1/6591 +f 6589/1/6589 6590/1/6590 6591/1/6591 +f 6589/1/6589 6591/1/6591 6593/1/6593 +f 6593/1/6593 6607/1/6607 6589/1/6589 +f 6589/1/6589 6607/1/6607 6588/1/6588 +f 6589/1/6589 6588/1/6588 6587/1/6587 +f 6587/1/6587 6588/1/6588 6584/1/6584 +f 6587/1/6587 6584/1/6584 6583/1/6583 +f 6583/1/6583 6586/1/6586 6587/1/6587 +f 6587/1/6587 6586/1/6586 6590/1/6590 +f 6582/1/6582 6586/1/6586 6583/1/6583 +f 6583/1/6583 6580/1/6580 6582/1/6582 +f 6582/1/6582 6580/1/6580 6581/1/6581 +f 6581/1/6581 6573/1/6573 6582/1/6582 +f 6574/1/6574 6573/1/6573 6581/1/6581 +f 6581/1/6581 6575/1/6575 6574/1/6574 +f 6574/1/6574 6575/1/6575 6571/1/6571 +f 6571/1/6571 6568/1/6568 6574/1/6574 +f 6569/1/6569 6568/1/6568 6571/1/6571 +f 6569/1/6569 6571/1/6571 6572/1/6572 +f 6570/1/6570 6569/1/6569 6572/1/6572 +f 6570/1/6570 6572/1/6572 6577/1/6577 +f 6570/1/6570 6577/1/6577 6563/1/6563 +f 6570/1/6570 6563/1/6563 6560/1/6560 +f 6563/1/6563 6558/1/6558 6560/1/6560 +f 6560/1/6560 6558/1/6558 6557/1/6557 +f 6557/1/6557 6561/1/6561 6560/1/6560 +f 6560/1/6560 6561/1/6561 6566/1/6566 +f 6560/1/6560 6566/1/6566 6569/1/6569 +f 6561/1/6561 5461/1/5461 6566/1/6566 +f 6566/1/6566 5461/1/5461 5456/1/5456 +f 6566/1/6566 5456/1/5456 6568/1/6568 +f 6568/1/6568 5456/1/5456 6573/1/6573 +f 6573/1/6573 5456/1/5456 5453/1/5453 +f 6573/1/6573 5453/1/5453 6586/1/6586 +f 6586/1/6586 5453/1/5453 5460/1/5460 +f 5453/1/5453 5459/1/5459 5460/1/5460 +f 5453/1/5453 5455/1/5455 5459/1/5459 +f 5459/1/5459 5455/1/5455 5540/1/5540 +f 5459/1/5459 5540/1/5540 5543/1/5543 +f 5540/1/5540 5455/1/5455 5537/1/5537 +f 5536/1/5536 5540/1/5540 5537/1/5537 +f 5536/1/5536 5537/1/5537 5532/1/5532 +f 5535/1/5535 5536/1/5536 5532/1/5532 +f 5535/1/5535 5532/1/5532 5531/1/5531 +f 5531/1/5531 5534/1/5534 5535/1/5535 +f 5535/1/5535 5534/1/5534 5539/1/5539 +f 5535/1/5535 5539/1/5539 5538/1/5538 +f 5538/1/5538 5539/1/5539 5544/1/5544 +f 5538/1/5538 5544/1/5544 5542/1/5542 +f 5542/1/5542 5540/1/5540 5538/1/5538 +f 5539/1/5539 5545/1/5545 5544/1/5544 +f 5544/1/5544 5545/1/5545 5546/1/5546 +f 5544/1/5544 5546/1/5546 5547/1/5547 +f 5547/1/5547 5546/1/5546 5551/1/5551 +f 5546/1/5546 5545/1/5545 5575/1/5575 +f 5546/1/5546 5575/1/5575 5557/1/5557 +f 5545/1/5545 5574/1/5574 5575/1/5575 +f 5575/1/5575 5574/1/5574 5568/1/5568 +f 5574/1/5574 5573/1/5573 5568/1/5568 +f 5534/1/5534 5573/1/5573 5574/1/5574 +f 5533/1/5533 5573/1/5573 5534/1/5534 +f 5533/1/5533 5571/1/5571 5573/1/5573 +f 5527/1/5527 5571/1/5571 5533/1/5533 +f 5529/1/5529 5527/1/5527 5533/1/5533 +f 5529/1/5529 5533/1/5533 5531/1/5531 +f 5531/1/5531 5528/1/5528 5529/1/5529 +f 5529/1/5529 5528/1/5528 5524/1/5524 +f 5528/1/5528 5525/1/5525 5524/1/5524 +f 5524/1/5524 5525/1/5525 5522/1/5522 +f 5524/1/5524 5522/1/5522 5520/1/5520 +f 5527/1/5527 5524/1/5524 5520/1/5520 +f 5527/1/5527 5520/1/5520 5526/1/5526 +f 5526/1/5526 5572/1/5572 5527/1/5527 +f 5526/1/5526 6623/1/6623 5572/1/5572 +f 6623/1/6623 6619/1/6619 5572/1/5572 +f 5572/1/5572 6619/1/6619 6621/1/6621 +f 6619/1/6619 6617/1/6617 6621/1/6621 +f 6621/1/6621 6617/1/6617 6620/1/6620 +f 6619/1/6619 6618/1/6618 6617/1/6617 +f 6618/1/6618 6585/1/6585 6617/1/6617 +f 6617/1/6617 6585/1/6585 6614/1/6614 +f 6585/1/6585 6588/1/6588 6614/1/6614 +f 6618/1/6618 6579/1/6579 6585/1/6585 +f 6579/1/6579 6580/1/6580 6585/1/6585 +f 6585/1/6585 6580/1/6580 6584/1/6584 +f 6579/1/6579 6575/1/6575 6580/1/6580 +f 6578/1/6578 6575/1/6575 6579/1/6579 +f 6719/1/6719 6578/1/6578 6579/1/6579 +f 6578/1/6578 6719/1/6719 6624/1/6624 +f 6718/1/6718 6578/1/6578 6624/1/6624 +f 6718/1/6718 6624/1/6624 6625/1/6625 +f 6718/1/6718 6625/1/6625 6577/1/6577 +f 6577/1/6577 6625/1/6625 6627/1/6627 +f 6625/1/6625 6626/1/6626 6627/1/6627 +f 6627/1/6627 6626/1/6626 6628/1/6628 +f 6627/1/6627 6628/1/6628 6564/1/6564 +f 6563/1/6563 6627/1/6627 6564/1/6564 +f 6564/1/6564 6628/1/6628 6631/1/6631 +f 6564/1/6564 6631/1/6631 6562/1/6562 +f 6558/1/6558 6564/1/6564 6562/1/6562 +f 6558/1/6558 6562/1/6562 6559/1/6559 +f 6559/1/6559 6562/1/6562 6565/1/6565 +f 6559/1/6559 6565/1/6565 6561/1/6561 +f 6562/1/6562 6567/1/6567 6565/1/6565 +f 6567/1/6567 5479/1/5479 6565/1/6565 +f 5479/1/5479 5461/1/5461 6565/1/6565 +f 5478/1/5478 5461/1/5461 5479/1/5479 +f 5478/1/5478 5479/1/5479 5480/1/5480 +f 5478/1/5478 5480/1/5480 5481/1/5481 +f 5478/1/5478 5481/1/5481 5503/1/5503 +f 5476/1/5476 5478/1/5478 5503/1/5503 +f 5476/1/5476 5503/1/5503 5502/1/5502 +f 5477/1/5477 5476/1/5476 5502/1/5502 +f 5477/1/5477 5502/1/5502 5621/1/5621 +f 5477/1/5477 5621/1/5621 5620/1/5620 +f 5620/1/5620 5619/1/5619 5477/1/5477 +f 5477/1/5477 5619/1/5619 5475/1/5475 +f 5477/1/5477 5475/1/5475 5474/1/5474 +f 5474/1/5474 5475/1/5475 5473/1/5473 +f 5474/1/5474 5473/1/5473 5462/1/5462 +f 5478/1/5478 5474/1/5474 5462/1/5462 +f 5462/1/5462 5473/1/5473 5466/1/5466 +f 5462/1/5462 5466/1/5466 5463/1/5463 +f 5462/1/5462 5463/1/5463 5457/1/5457 +f 5461/1/5461 5462/1/5462 5457/1/5457 +f 5457/1/5457 5463/1/5463 5458/1/5458 +f 5457/1/5457 5458/1/5458 5453/1/5453 +f 5453/1/5453 5458/1/5458 5454/1/5454 +f 5454/1/5454 5458/1/5458 5464/1/5464 +f 5610/1/5610 5454/1/5454 5464/1/5464 +f 5610/1/5610 5464/1/5464 5507/1/5507 +f 5611/1/5611 5610/1/5610 5507/1/5507 +f 5611/1/5611 5507/1/5507 5515/1/5515 +f 5523/1/5523 5611/1/5611 5515/1/5515 +f 5523/1/5523 5515/1/5515 5516/1/5516 +f 5522/1/5522 5523/1/5523 5516/1/5516 +f 5522/1/5522 5516/1/5516 5517/1/5517 +f 5516/1/5516 5514/1/5514 5517/1/5517 +f 5517/1/5517 5514/1/5514 5513/1/5513 +f 5517/1/5517 5513/1/5513 5518/1/5518 +f 5521/1/5521 5517/1/5517 5518/1/5518 +f 5521/1/5521 5518/1/5518 6625/1/6625 +f 5526/1/5526 5521/1/5521 6625/1/6625 +f 6625/1/6625 5518/1/5518 5519/1/5519 +f 5520/1/5520 5517/1/5517 5521/1/5521 +f 5518/1/5518 5513/1/5513 5519/1/5519 +f 5513/1/5513 5512/1/5512 5519/1/5519 +f 5519/1/5519 5512/1/5512 5613/1/5613 +f 5519/1/5519 5613/1/5613 6626/1/6626 +f 6626/1/6626 5613/1/5613 6629/1/6629 +f 5613/1/5613 6632/1/6632 6629/1/6629 +f 6629/1/6629 6632/1/6632 6633/1/6633 +f 6629/1/6629 6633/1/6633 6630/1/6630 +f 6628/1/6628 6629/1/6629 6630/1/6630 +f 6630/1/6630 6633/1/6633 6636/1/6636 +f 6630/1/6630 6636/1/6636 6715/1/6715 +f 6716/1/6716 6630/1/6630 6715/1/6715 +f 6716/1/6716 6715/1/6715 6717/1/6717 +f 6716/1/6716 6717/1/6717 6567/1/6567 +f 6567/1/6567 6717/1/6717 5480/1/5480 +f 6717/1/6717 7419/1/7419 5480/1/5480 +f 5480/1/5480 7419/1/7419 5482/1/5482 +f 7419/1/7419 6952/1/6952 5482/1/5482 +f 6952/1/6952 5484/1/5484 5482/1/5482 +f 5484/1/5484 5483/1/5483 5482/1/5482 +f 5482/1/5482 5483/1/5483 5481/1/5481 +f 6708/1/6708 5481/1/5481 5483/1/5483 +f 5483/1/5483 6705/1/6705 6708/1/6708 +f 6709/1/6709 6708/1/6708 6705/1/6705 +f 6709/1/6709 6705/1/6705 6703/1/6703 +f 6702/1/6702 6709/1/6709 6703/1/6703 +f 6702/1/6702 6703/1/6703 6700/1/6700 +f 6704/1/6704 6702/1/6702 6700/1/6700 +f 6704/1/6704 6700/1/6700 6639/1/6639 +f 6634/1/6634 6704/1/6704 6639/1/6639 +f 6634/1/6634 6639/1/6639 6638/1/6638 +f 6638/1/6638 6635/1/6635 6634/1/6634 +f 6632/1/6632 6634/1/6634 6635/1/6635 +f 6638/1/6638 6637/1/6637 6635/1/6635 +f 6633/1/6633 6635/1/6635 6637/1/6637 +f 6637/1/6637 6638/1/6638 6947/1/6947 +f 6637/1/6637 6947/1/6947 6948/1/6948 +f 6948/1/6948 6950/1/6950 6637/1/6637 +f 6636/1/6636 6637/1/6637 6950/1/6950 +f 6948/1/6948 6951/1/6951 6950/1/6950 +f 6950/1/6950 6951/1/6951 6952/1/6952 +f 6953/1/6953 6950/1/6950 6952/1/6952 +f 6715/1/6715 6950/1/6950 6953/1/6953 +f 6952/1/6952 6951/1/6951 6949/1/6949 +f 6949/1/6949 6951/1/6951 6948/1/6948 +f 6949/1/6949 6948/1/6948 6944/1/6944 +f 6949/1/6949 6944/1/6944 6943/1/6943 +f 6943/1/6943 5484/1/5484 6949/1/6949 +f 5485/1/5485 5484/1/5484 6943/1/6943 +f 6943/1/6943 6941/1/6941 5485/1/5485 +f 5485/1/5485 6941/1/6941 5487/1/5487 +f 5486/1/5486 5485/1/5485 5487/1/5487 +f 5486/1/5486 5487/1/5487 5488/1/5488 +f 6692/1/6692 5486/1/5486 5488/1/5488 +f 6692/1/6692 5488/1/5488 6691/1/6691 +f 6691/1/6691 6690/1/6690 6692/1/6692 +f 6692/1/6692 6690/1/6690 6693/1/6693 +f 6690/1/6690 6694/1/6694 6693/1/6693 +f 6693/1/6693 6694/1/6694 6696/1/6696 +f 6693/1/6693 6696/1/6696 6698/1/6698 +f 6693/1/6693 6698/1/6698 6707/1/6707 +f 5486/1/5486 6693/1/6693 6707/1/6707 +f 5486/1/5486 6707/1/6707 5483/1/5483 +f 6707/1/6707 6706/1/6706 5483/1/5483 +f 6707/1/6707 6698/1/6698 6706/1/6706 +f 6698/1/6698 6699/1/6699 6706/1/6706 +f 6706/1/6706 6699/1/6699 6701/1/6701 +f 6706/1/6706 6701/1/6701 6705/1/6705 +f 6699/1/6699 6697/1/6697 6701/1/6701 +f 6700/1/6700 6701/1/6701 6697/1/6697 +f 6700/1/6700 6697/1/6697 6640/1/6640 +f 6695/1/6695 6640/1/6640 6697/1/6697 +f 6696/1/6696 6695/1/6695 6697/1/6697 +f 6695/1/6695 6642/1/6642 6640/1/6640 +f 6642/1/6642 6643/1/6643 6640/1/6640 +f 6640/1/6640 6643/1/6643 6641/1/6641 +f 6638/1/6638 6640/1/6640 6641/1/6641 +f 6643/1/6643 6920/1/6920 6641/1/6641 +f 6947/1/6947 6641/1/6641 6920/1/6920 +f 6947/1/6947 6920/1/6920 6946/1/6946 +f 6946/1/6946 6920/1/6920 6945/1/6945 +f 6944/1/6944 6946/1/6946 6945/1/6945 +f 6944/1/6944 6945/1/6945 6941/1/6941 +f 6945/1/6945 6942/1/6942 6941/1/6941 +f 6941/1/6941 6942/1/6942 6939/1/6939 +f 6940/1/6940 6939/1/6939 6942/1/6942 +f 6918/1/6918 6940/1/6940 6942/1/6942 +f 6917/1/6917 6940/1/6940 6918/1/6918 +f 6916/1/6916 6917/1/6917 6918/1/6918 +f 6916/1/6916 6918/1/6918 6920/1/6920 +f 6919/1/6919 6917/1/6917 6916/1/6916 +f 6645/1/6645 6919/1/6919 6916/1/6916 +f 6645/1/6645 6916/1/6916 6643/1/6643 +f 6644/1/6644 6645/1/6645 6643/1/6643 +f 6684/1/6684 6645/1/6645 6644/1/6644 +f 6684/1/6684 6644/1/6644 6686/1/6686 +f 6685/1/6685 6684/1/6684 6686/1/6686 +f 6685/1/6685 6686/1/6686 6689/1/6689 +f 6687/1/6687 6685/1/6685 6689/1/6689 +f 6687/1/6687 6689/1/6689 6690/1/6690 +f 6683/1/6683 6685/1/6685 6687/1/6687 +f 6688/1/6688 6683/1/6683 6687/1/6687 +f 6688/1/6688 6687/1/6687 6691/1/6691 +f 6681/1/6681 6683/1/6683 6688/1/6688 +f 5488/1/5488 6681/1/6681 6688/1/6688 +f 6681/1/6681 5488/1/5488 6676/1/6676 +f 6676/1/6676 6680/1/6680 6681/1/6681 +f 6676/1/6676 6678/1/6678 6680/1/6680 +f 6678/1/6678 6679/1/6679 6680/1/6680 +f 6680/1/6680 6679/1/6679 6682/1/6682 +f 6680/1/6680 6682/1/6682 6683/1/6683 +f 6679/1/6679 6684/1/6684 6682/1/6682 +f 6679/1/6679 6646/1/6646 6684/1/6684 +f 6677/1/6677 6646/1/6646 6679/1/6679 +f 6651/1/6651 6646/1/6646 6677/1/6677 +f 6675/1/6675 6651/1/6651 6677/1/6677 +f 6675/1/6675 6677/1/6677 6678/1/6678 +f 6674/1/6674 6651/1/6651 6675/1/6675 +f 5491/1/5491 6674/1/6674 6675/1/6675 +f 6676/1/6676 5491/1/5491 6675/1/6675 +f 5493/1/5493 6674/1/6674 5491/1/5491 +f 5490/1/5490 5493/1/5493 5491/1/5491 +f 5490/1/5490 5491/1/5491 5488/1/5488 +f 5488/1/5488 5489/1/5489 5490/1/5490 +f 5489/1/5489 6930/1/6930 5490/1/5490 +f 6926/1/6926 5490/1/5490 6930/1/6930 +f 6924/1/6924 6926/1/6926 6930/1/6930 +f 6924/1/6924 6930/1/6930 6938/1/6938 +f 6924/1/6924 6938/1/6938 6940/1/6940 +f 6921/1/6921 6926/1/6926 6924/1/6924 +f 6921/1/6921 6924/1/6924 6917/1/6917 +f 6921/1/6921 6925/1/6925 6926/1/6926 +f 6925/1/6925 6929/1/6929 6926/1/6926 +f 6925/1/6925 5492/1/5492 6929/1/6929 +f 5490/1/5490 6929/1/6929 5492/1/5492 +f 6928/1/6928 5492/1/5492 6925/1/6925 +f 6923/1/6923 6928/1/6928 6925/1/6925 +f 6927/1/6927 6928/1/6928 6923/1/6923 +f 6922/1/6922 6927/1/6927 6923/1/6923 +f 6922/1/6922 6923/1/6923 6650/1/6650 +f 6649/1/6649 6922/1/6922 6650/1/6650 +f 6649/1/6649 6650/1/6650 6647/1/6647 +f 6653/1/6653 6649/1/6649 6647/1/6647 +f 6648/1/6648 6653/1/6653 6647/1/6647 +f 6648/1/6648 6647/1/6647 6646/1/6646 +f 6646/1/6646 6647/1/6647 6645/1/6645 +f 6652/1/6652 6653/1/6653 6648/1/6648 +f 6655/1/6655 6652/1/6652 6648/1/6648 +f 6655/1/6655 6648/1/6648 6654/1/6654 +f 6673/1/6673 6655/1/6655 6654/1/6654 +f 6673/1/6673 6654/1/6654 6674/1/6674 +f 6672/1/6672 6655/1/6655 6673/1/6673 +f 6672/1/6672 6673/1/6673 5493/1/5493 +f 6672/1/6672 5493/1/5493 5495/1/5495 +f 5495/1/5495 6671/1/6671 6672/1/6672 +f 6671/1/6671 6664/1/6664 6672/1/6672 +f 6671/1/6671 6665/1/6665 6664/1/6664 +f 6665/1/6665 6658/1/6658 6664/1/6664 +f 6664/1/6664 6658/1/6658 6652/1/6652 +f 6658/1/6658 6656/1/6656 6652/1/6652 +f 6658/1/6658 6659/1/6659 6656/1/6656 +f 6659/1/6659 6660/1/6660 6656/1/6656 +f 6656/1/6656 6660/1/6660 6657/1/6657 +f 6656/1/6656 6657/1/6657 6653/1/6653 +f 6660/1/6660 6932/1/6932 6657/1/6657 +f 6657/1/6657 6932/1/6932 6922/1/6922 +f 6660/1/6660 6934/1/6934 6932/1/6932 +f 6934/1/6934 6933/1/6933 6932/1/6932 +f 6932/1/6932 6933/1/6933 6931/1/6931 +f 6932/1/6932 6931/1/6931 6927/1/6927 +f 6933/1/6933 5497/1/5497 6931/1/6931 +f 6931/1/6931 5497/1/5497 5494/1/5494 +f 6931/1/6931 5494/1/5494 6928/1/6928 +f 5496/1/5496 5494/1/5494 5497/1/5497 +f 5496/1/5496 5497/1/5497 5498/1/5498 +f 5498/1/5498 5499/1/5499 5496/1/5496 +f 6669/1/6669 5496/1/5496 5499/1/5499 +f 5499/1/5499 6663/1/6663 6669/1/6669 +f 6669/1/6669 6663/1/6663 6670/1/6670 +f 6670/1/6670 6663/1/6663 6665/1/6665 +f 5499/1/5499 6666/1/6666 6663/1/6663 +f 6666/1/6666 6661/1/6661 6663/1/6663 +f 6663/1/6663 6661/1/6661 6658/1/6658 +f 6666/1/6666 6659/1/6659 6661/1/6661 +f 6668/1/6668 6659/1/6659 6666/1/6666 +f 6668/1/6668 6666/1/6666 6667/1/6667 +f 5501/1/5501 6668/1/6668 6667/1/6667 +f 6667/1/6667 5499/1/5499 5501/1/5501 +f 5500/1/5500 5501/1/5501 5499/1/5499 +f 6730/1/6730 5501/1/5501 5500/1/5500 +f 6730/1/6730 5500/1/5500 6937/1/6937 +f 6936/1/6936 6730/1/6730 6937/1/6937 +f 6936/1/6936 6937/1/6937 6935/1/6935 +f 6936/1/6936 6935/1/6935 6933/1/6933 +f 6937/1/6937 5498/1/5498 6935/1/6935 +f 6729/1/6729 6730/1/6730 6936/1/6936 +f 6729/1/6729 6936/1/6936 6934/1/6934 +f 6662/1/6662 6729/1/6729 6934/1/6934 +f 6729/1/6729 6662/1/6662 5501/1/5501 +f 5501/1/5501 6662/1/6662 6659/1/6659 +f 6937/1/6937 5500/1/5500 5498/1/5498 +f 6730/1/6730 6729/1/6729 5501/1/5501 +f 6668/1/6668 5501/1/5501 6659/1/6659 +f 6667/1/6667 6666/1/6666 5499/1/5499 +f 5496/1/5496 6669/1/6669 6670/1/6670 +f 6670/1/6670 6671/1/6671 5496/1/5496 +f 5500/1/5500 5499/1/5499 5498/1/5498 +f 6935/1/6935 5498/1/5498 5497/1/5497 +f 5495/1/5495 5494/1/5494 5496/1/5496 +f 6935/1/6935 5497/1/5497 6933/1/6933 +f 6934/1/6934 6936/1/6936 6933/1/6933 +f 6662/1/6662 6934/1/6934 6660/1/6660 +f 6659/1/6659 6662/1/6662 6660/1/6660 +f 6661/1/6661 6659/1/6659 6658/1/6658 +f 6663/1/6663 6658/1/6658 6665/1/6665 +f 6670/1/6670 6665/1/6665 6671/1/6671 +f 5496/1/5496 6671/1/6671 5495/1/5495 +f 5493/1/5493 5494/1/5494 5495/1/5495 +f 5493/1/5493 5492/1/5492 5494/1/5494 +f 6672/1/6672 6664/1/6664 6655/1/6655 +f 6654/1/6654 6648/1/6648 6651/1/6651 +f 6664/1/6664 6652/1/6652 6655/1/6655 +f 6652/1/6652 6656/1/6656 6653/1/6653 +f 6653/1/6653 6657/1/6657 6649/1/6649 +f 6647/1/6647 6650/1/6650 6919/1/6919 +f 6650/1/6650 6921/1/6921 6919/1/6919 +f 6657/1/6657 6922/1/6922 6649/1/6649 +f 6650/1/6650 6923/1/6923 6921/1/6921 +f 6932/1/6932 6927/1/6927 6922/1/6922 +f 6927/1/6927 6931/1/6931 6928/1/6928 +f 6928/1/6928 5494/1/5494 5492/1/5492 +f 6923/1/6923 6925/1/6925 6921/1/6921 +f 5490/1/5490 6926/1/6926 6929/1/6929 +f 6938/1/6938 6930/1/6930 5489/1/5489 +f 6938/1/6938 5489/1/5489 6939/1/6939 +f 5489/1/5489 5487/1/5487 6939/1/6939 +f 5492/1/5492 5493/1/5493 5490/1/5490 +f 5493/1/5493 6673/1/6673 6674/1/6674 +f 6674/1/6674 6654/1/6654 6651/1/6651 +f 6651/1/6651 6648/1/6648 6646/1/6646 +f 6678/1/6678 6677/1/6677 6679/1/6679 +f 6675/1/6675 6678/1/6678 6676/1/6676 +f 5488/1/5488 5491/1/5491 6676/1/6676 +f 6681/1/6681 6680/1/6680 6683/1/6683 +f 6683/1/6683 6682/1/6682 6685/1/6685 +f 6689/1/6689 6686/1/6686 6694/1/6694 +f 6694/1/6694 6686/1/6686 6695/1/6695 +f 6682/1/6682 6684/1/6684 6685/1/6685 +f 6686/1/6686 6644/1/6644 6642/1/6642 +f 6646/1/6646 6645/1/6645 6684/1/6684 +f 6647/1/6647 6919/1/6919 6645/1/6645 +f 6919/1/6919 6921/1/6921 6917/1/6917 +f 6917/1/6917 6924/1/6924 6940/1/6940 +f 6940/1/6940 6938/1/6938 6939/1/6939 +f 6918/1/6918 6942/1/6942 6945/1/6945 +f 6920/1/6920 6918/1/6918 6945/1/6945 +f 6643/1/6643 6916/1/6916 6920/1/6920 +f 6644/1/6644 6643/1/6643 6642/1/6642 +f 6686/1/6686 6642/1/6642 6695/1/6695 +f 6696/1/6696 6697/1/6697 6699/1/6699 +f 6698/1/6698 6696/1/6696 6699/1/6699 +f 6694/1/6694 6695/1/6695 6696/1/6696 +f 6690/1/6690 6689/1/6689 6694/1/6694 +f 6691/1/6691 6687/1/6687 6690/1/6690 +f 6691/1/6691 5488/1/5488 6688/1/6688 +f 6692/1/6692 6693/1/6693 5486/1/5486 +f 5488/1/5488 5487/1/5487 5489/1/5489 +f 5483/1/5483 5485/1/5485 5486/1/5486 +f 5487/1/5487 6941/1/6941 6939/1/6939 +f 6943/1/6943 6944/1/6944 6941/1/6941 +f 6948/1/6948 6946/1/6946 6944/1/6944 +f 6948/1/6948 6947/1/6947 6946/1/6946 +f 6638/1/6638 6641/1/6641 6947/1/6947 +f 6639/1/6639 6640/1/6640 6638/1/6638 +f 6714/1/6714 6704/1/6704 6634/1/6634 +f 5615/1/5615 6714/1/6714 6634/1/6634 +f 5613/1/5613 5615/1/5615 6634/1/6634 +f 5615/1/5615 5618/1/5618 6714/1/6714 +f 5622/1/5622 6714/1/6714 5618/1/5618 +f 5622/1/5622 5618/1/5618 5620/1/5620 +f 5622/1/5622 6713/1/6713 6714/1/6714 +f 5622/1/5622 5621/1/5621 6713/1/6713 +f 5621/1/5621 6711/1/6711 6713/1/6713 +f 6713/1/6713 6711/1/6711 6702/1/6702 +f 5621/1/5621 6712/1/6712 6711/1/6711 +f 6712/1/6712 6710/1/6710 6711/1/6711 +f 6711/1/6711 6710/1/6710 6709/1/6709 +f 6712/1/6712 5481/1/5481 6710/1/6710 +f 5616/1/5616 5618/1/5618 5615/1/5615 +f 5614/1/5614 5616/1/5616 5615/1/5615 +f 5512/1/5512 5614/1/5614 5615/1/5615 +f 5511/1/5511 5614/1/5614 5512/1/5512 +f 5510/1/5510 5511/1/5511 5512/1/5512 +f 5510/1/5510 5506/1/5506 5511/1/5511 +f 5506/1/5506 5504/1/5504 5511/1/5511 +f 5469/1/5469 5504/1/5504 5506/1/5506 +f 5505/1/5505 5469/1/5469 5506/1/5506 +f 5470/1/5470 5469/1/5469 5505/1/5505 +f 5508/1/5508 5470/1/5470 5505/1/5505 +f 5508/1/5508 5505/1/5505 5509/1/5509 +f 5514/1/5514 5508/1/5508 5509/1/5509 +f 5515/1/5515 5508/1/5508 5514/1/5514 +f 5509/1/5509 5505/1/5505 5510/1/5510 +f 5509/1/5509 5510/1/5510 5513/1/5513 +f 5507/1/5507 5470/1/5470 5508/1/5508 +f 5470/1/5470 5465/1/5465 5469/1/5469 +f 5465/1/5465 5468/1/5468 5469/1/5469 +f 5469/1/5469 5468/1/5468 5471/1/5471 +f 5468/1/5468 5467/1/5467 5471/1/5471 +f 5471/1/5471 5467/1/5467 5472/1/5472 +f 5471/1/5471 5472/1/5472 5504/1/5504 +f 5504/1/5504 5472/1/5472 5617/1/5617 +f 5504/1/5504 5617/1/5617 5614/1/5614 +f 5472/1/5472 5475/1/5475 5617/1/5617 +f 5467/1/5467 5473/1/5473 5472/1/5472 +f 5468/1/5468 5463/1/5463 5467/1/5467 +f 5465/1/5465 5463/1/5463 5468/1/5468 +f 5464/1/5464 5465/1/5465 5470/1/5470 +f 5469/1/5469 5471/1/5471 5504/1/5504 +f 5505/1/5505 5506/1/5506 5510/1/5510 +f 5511/1/5511 5504/1/5504 5614/1/5614 +f 5614/1/5614 5617/1/5617 5616/1/5616 +f 5617/1/5617 5619/1/5619 5616/1/5616 +f 5616/1/5616 5619/1/5619 5618/1/5618 +f 6714/1/6714 6713/1/6713 6704/1/6704 +f 6639/1/6639 6700/1/6700 6640/1/6640 +f 6713/1/6713 6702/1/6702 6704/1/6704 +f 6703/1/6703 6701/1/6701 6700/1/6700 +f 6711/1/6711 6709/1/6709 6702/1/6702 +f 6703/1/6703 6705/1/6705 6701/1/6701 +f 6710/1/6710 6708/1/6708 6709/1/6709 +f 5483/1/5483 6706/1/6706 6705/1/6705 +f 6710/1/6710 5481/1/5481 6708/1/6708 +f 5484/1/5484 5485/1/5485 5483/1/5483 +f 6952/1/6952 6949/1/6949 5484/1/5484 +f 6953/1/6953 6952/1/6952 7419/1/7419 +f 6717/1/6717 6953/1/6953 7419/1/7419 +f 6717/1/6717 6715/1/6715 6953/1/6953 +f 6631/1/6631 6630/1/6630 6716/1/6716 +f 6715/1/6715 6636/1/6636 6950/1/6950 +f 6633/1/6633 6637/1/6637 6636/1/6636 +f 6632/1/6632 6635/1/6635 6633/1/6633 +f 5613/1/5613 6634/1/6634 6632/1/6632 +f 5512/1/5512 5615/1/5615 5613/1/5613 +f 5513/1/5513 5510/1/5510 5512/1/5512 +f 5514/1/5514 5509/1/5509 5513/1/5513 +f 5516/1/5516 5515/1/5515 5514/1/5514 +f 5612/1/5612 5611/1/5611 5523/1/5523 +f 5530/1/5530 5612/1/5612 5523/1/5523 +f 5530/1/5530 5523/1/5523 5525/1/5525 +f 5530/1/5530 5541/1/5541 5612/1/5612 +f 5541/1/5541 5609/1/5609 5612/1/5612 +f 5541/1/5541 5455/1/5455 5609/1/5609 +f 5455/1/5455 5454/1/5454 5609/1/5609 +f 5537/1/5537 5541/1/5541 5530/1/5530 +f 5612/1/5612 5609/1/5609 5611/1/5611 +f 5515/1/5515 5507/1/5507 5508/1/5508 +f 5609/1/5609 5610/1/5610 5611/1/5611 +f 5507/1/5507 5464/1/5464 5470/1/5470 +f 5609/1/5609 5454/1/5454 5610/1/5610 +f 5464/1/5464 5458/1/5458 5465/1/5465 +f 5458/1/5458 5463/1/5463 5465/1/5465 +f 5463/1/5463 5466/1/5466 5467/1/5467 +f 5467/1/5467 5466/1/5466 5473/1/5473 +f 5472/1/5472 5473/1/5473 5475/1/5475 +f 5617/1/5617 5475/1/5475 5619/1/5619 +f 5620/1/5620 5618/1/5618 5619/1/5619 +f 5620/1/5620 5621/1/5621 5622/1/5622 +f 5502/1/5502 6712/1/6712 5621/1/5621 +f 5474/1/5474 5476/1/5476 5477/1/5477 +f 5502/1/5502 5503/1/5503 6712/1/6712 +f 5478/1/5478 5476/1/5476 5474/1/5474 +f 5503/1/5503 5481/1/5481 6712/1/6712 +f 5482/1/5482 5481/1/5481 5480/1/5480 +f 5462/1/5462 5461/1/5461 5478/1/5478 +f 6567/1/6567 5480/1/5480 5479/1/5479 +f 6562/1/6562 6716/1/6716 6567/1/6567 +f 6562/1/6562 6631/1/6631 6716/1/6716 +f 6628/1/6628 6630/1/6630 6631/1/6631 +f 6626/1/6626 6629/1/6629 6628/1/6628 +f 6625/1/6625 5519/1/5519 6626/1/6626 +f 6625/1/6625 6624/1/6624 6623/1/6623 +f 6577/1/6577 6578/1/6578 6718/1/6718 +f 6577/1/6577 6576/1/6576 6578/1/6578 +f 6624/1/6624 6719/1/6719 6619/1/6619 +f 6576/1/6576 6575/1/6575 6578/1/6578 +f 6572/1/6572 6575/1/6575 6576/1/6576 +f 6719/1/6719 6579/1/6579 6618/1/6618 +f 6619/1/6619 6719/1/6719 6618/1/6618 +f 6623/1/6623 6624/1/6624 6619/1/6619 +f 6625/1/6625 6623/1/6623 5526/1/5526 +f 5526/1/5526 5520/1/5520 5521/1/5521 +f 5520/1/5520 5522/1/5522 5517/1/5517 +f 5525/1/5525 5523/1/5523 5522/1/5522 +f 5528/1/5528 5530/1/5530 5525/1/5525 +f 5532/1/5532 5530/1/5530 5528/1/5528 +f 5529/1/5529 5524/1/5524 5527/1/5527 +f 5534/1/5534 5574/1/5574 5545/1/5545 +f 5534/1/5534 5545/1/5545 5539/1/5539 +f 5531/1/5531 5533/1/5533 5534/1/5534 +f 5531/1/5531 5532/1/5532 5528/1/5528 +f 5538/1/5538 5536/1/5536 5535/1/5535 +f 5532/1/5532 5537/1/5537 5530/1/5530 +f 5538/1/5538 5540/1/5540 5536/1/5536 +f 5537/1/5537 5455/1/5455 5541/1/5541 +f 5453/1/5453 5454/1/5454 5455/1/5455 +f 5456/1/5456 5457/1/5457 5453/1/5453 +f 5461/1/5461 5457/1/5457 5456/1/5456 +f 6565/1/6565 5461/1/5461 6561/1/6561 +f 6559/1/6559 6561/1/6561 6557/1/6557 +f 6557/1/6557 6558/1/6558 6559/1/6559 +f 6563/1/6563 6564/1/6564 6558/1/6558 +f 6577/1/6577 6627/1/6627 6563/1/6563 +f 6577/1/6577 6572/1/6572 6576/1/6576 +f 6570/1/6570 6560/1/6560 6569/1/6569 +f 6569/1/6569 6566/1/6566 6568/1/6568 +f 6572/1/6572 6571/1/6571 6575/1/6575 +f 6574/1/6574 6568/1/6568 6573/1/6573 +f 6581/1/6581 6580/1/6580 6575/1/6575 +f 6582/1/6582 6573/1/6573 6586/1/6586 +f 6583/1/6583 6584/1/6584 6580/1/6580 +f 6585/1/6585 6584/1/6584 6588/1/6588 +f 6594/1/6594 6607/1/6607 6593/1/6593 +f 6587/1/6587 6590/1/6590 6589/1/6589 +f 6586/1/6586 5460/1/5460 6590/1/6590 +f 5460/1/5460 5459/1/5459 5543/1/5543 +f 5607/1/5607 5549/1/5549 5608/1/5608 +f 5543/1/5543 5540/1/5540 5542/1/5542 +f 5542/1/5542 5544/1/5544 5548/1/5548 +f 5544/1/5544 5547/1/5547 5548/1/5548 +f 5553/1/5553 5556/1/5556 5559/1/5559 +f 5556/1/5556 5560/1/5560 5559/1/5559 +f 5547/1/5547 5551/1/5551 5552/1/5552 +f 5556/1/5556 5558/1/5558 5560/1/5560 +f 5558/1/5558 5562/1/5562 5560/1/5560 +f 5560/1/5560 5562/1/5562 5564/1/5564 +f 5560/1/5560 5564/1/5564 5565/1/5565 +f 5562/1/5562 5567/1/5567 5564/1/5564 +f 5564/1/5564 5567/1/5567 5578/1/5578 +f 5562/1/5562 5566/1/5566 5567/1/5567 +f 5546/1/5546 5557/1/5557 5551/1/5551 +f 5558/1/5558 5561/1/5561 5562/1/5562 +f 5575/1/5575 5568/1/5568 5557/1/5557 +f 5561/1/5561 5566/1/5566 5562/1/5562 +f 5573/1/5573 5571/1/5571 5568/1/5568 +f 5566/1/5566 5569/1/5569 5570/1/5570 +f 5527/1/5527 5572/1/5572 5571/1/5571 +f 5572/1/5572 6621/1/6621 6620/1/6620 +f 6620/1/6620 6617/1/6617 6616/1/6616 +f 6617/1/6617 6614/1/6614 6616/1/6616 +f 6614/1/6614 6588/1/6588 6607/1/6607 +f 6622/1/6622 6615/1/6615 6720/1/6720 +f 5569/1/5569 6622/1/6622 5570/1/5570 +f 5566/1/5566 5570/1/5570 5567/1/5567 +f 5578/1/5578 5567/1/5567 5577/1/5577 +f 5565/1/5565 5564/1/5564 5578/1/5578 +f 5560/1/5560 5565/1/5565 5563/1/5563 +f 5559/1/5559 5560/1/5560 5563/1/5563 +f 5553/1/5553 5559/1/5559 5599/1/5599 +f 5600/1/5600 5597/1/5597 5598/1/5598 +f 5598/1/5598 5583/1/5583 5585/1/5585 +f 5585/1/5585 5582/1/5582 5584/1/5584 +f 5582/1/5582 5581/1/5581 5584/1/5584 +f 5581/1/5581 5576/1/5576 5580/1/5580 +f 5587/1/5587 5586/1/5586 6142/1/6142 +f 6134/1/6134 5587/1/5587 6142/1/6142 +f 5606/1/5606 5588/1/5588 6134/1/6134 +f 6135/1/6135 5601/1/5601 5606/1/5606 +f 5604/1/5604 5602/1/5602 6135/1/6135 +f 6137/1/6137 5603/1/5603 5604/1/5604 +f 5554/1/5554 5599/1/5599 5603/1/5603 +f 5555/1/5555 5550/1/5550 5554/1/5554 +f 5608/1/5608 5549/1/5549 5555/1/5555 +f 6591/1/6591 5607/1/5607 5608/1/5608 +f 6593/1/6593 6591/1/6591 6594/1/6594 +f 6603/1/6603 6608/1/6608 6605/1/6605 +f 6594/1/6594 6606/1/6606 6607/1/6607 +f 6723/1/6723 6606/1/6606 6613/1/6613 +f 6723/1/6723 6613/1/6613 6722/1/6722 +f 6721/1/6721 6722/1/6722 6724/1/6724 +f 6726/1/6726 6727/1/6727 7122/1/7122 +f 6724/1/6724 6726/1/6726 6728/1/6728 +f 5589/1/5589 6728/1/6728 5590/1/5590 +f 5580/1/5580 5590/1/5590 5591/1/5591 +f 6143/1/6143 5591/1/5591 6050/1/6050 +f 6138/1/6138 6050/1/6050 6139/1/6139 +f 6131/1/6131 6141/1/6141 6138/1/6138 +f 6129/1/6129 6141/1/6141 6131/1/6131 +f 6132/1/6132 6129/1/6129 6128/1/6128 +f 6127/1/6127 6132/1/6132 6128/1/6128 +f 6121/1/6121 6133/1/6133 6127/1/6127 +f 6136/1/6136 6121/1/6121 6120/1/6120 +f 6118/1/6118 6122/1/6122 6123/1/6123 +f 6123/1/6123 6126/1/6126 6124/1/6124 +f 6124/1/6124 6130/1/6130 6140/1/6140 +f 6140/1/6140 6051/1/6051 6052/1/6052 +f 6114/1/6114 6125/1/6125 6144/1/6144 +f 6115/1/6115 6119/1/6119 6114/1/6114 +f 6120/1/6120 6115/1/6115 6116/1/6116 +f 6599/1/6599 6136/1/6136 6120/1/6120 +f 6596/1/6596 6136/1/6136 6599/1/6599 +f 6595/1/6595 5605/1/5605 6596/1/6596 +f 6592/1/6592 6595/1/6595 6597/1/6597 +f 6603/1/6603 6592/1/6592 6597/1/6597 +f 6603/1/6603 6609/1/6609 6608/1/6608 +f 6725/1/6725 6609/1/6609 6610/1/6610 +f 6604/1/6604 6598/1/6598 6612/1/6612 +f 6611/1/6611 7063/1/7063 6610/1/6610 +f 7060/1/7060 6598/1/6598 6600/1/6600 +f 7061/1/7061 7064/1/7064 7063/1/7063 +f 7062/1/7062 6600/1/6600 7057/1/7057 +f 7069/1/7069 7066/1/7066 7065/1/7065 +f 7065/1/7065 7066/1/7066 7064/1/7064 +f 7067/1/7067 7063/1/7063 7064/1/7064 +f 7121/1/7121 7067/1/7067 7120/1/7120 +f 7119/1/7119 7120/1/7120 7118/1/7118 +f 5592/1/5592 7119/1/7119 7118/1/7118 +f 7117/1/7117 7068/1/7068 7074/1/7074 +f 7074/1/7074 7073/1/7073 7075/1/7075 +f 7115/1/7115 7081/1/7081 7091/1/7091 +f 7114/1/7114 7076/1/7076 7115/1/7115 +f 5596/1/5596 7116/1/7116 7114/1/7114 +f 5594/1/5594 7116/1/7116 5596/1/5596 +f 5593/1/5593 5592/1/5592 5594/1/5594 +f 6047/1/6047 5593/1/5593 6046/1/6046 +f 6048/1/6048 6047/1/6047 6046/1/6046 +f 6052/1/6052 6048/1/6048 6053/1/6053 +f 6057/1/6057 6053/1/6053 6056/1/6056 +f 6112/1/6112 6056/1/6056 6111/1/6111 +f 6113/1/6113 6111/1/6111 6108/1/6108 +f 6110/1/6110 6058/1/6058 6059/1/6059 +f 6064/1/6064 6063/1/6063 6065/1/6065 +f 6055/1/6055 6060/1/6060 6059/1/6059 +f 6063/1/6063 6061/1/6061 6062/1/6062 +f 6055/1/6055 6054/1/6054 6060/1/6060 +f 6049/1/6049 6043/1/6043 6054/1/6054 +f 6043/1/6043 5595/1/5595 6042/1/6042 +f 6061/1/6061 6044/1/6044 6062/1/6062 +f 6063/1/6063 6062/1/6062 6065/1/6065 +f 6064/1/6064 6065/1/6065 6067/1/6067 +f 6068/1/6068 6066/1/6066 6074/1/6074 +f 6074/1/6074 6045/1/6045 6075/1/6075 +f 6073/1/6073 6076/1/6076 6078/1/6078 +f 6077/1/6077 6073/1/6073 6078/1/6078 +f 6071/1/6071 6073/1/6073 6077/1/6077 +f 6072/1/6072 6067/1/6067 6071/1/6071 +f 6107/1/6107 6070/1/6070 6072/1/6072 +f 6108/1/6108 6069/1/6069 6107/1/6107 +f 6117/1/6117 6113/1/6113 6108/1/6108 +f 6602/1/6602 6117/1/6117 7054/1/7054 +f 7056/1/7056 6601/1/6601 6602/1/6602 +f 7058/1/7058 7057/1/7057 7056/1/7056 +f 7058/1/7058 7071/1/7071 7070/1/7070 +f 7073/1/7073 7071/1/7071 7077/1/7077 +f 7059/1/7059 7055/1/7055 7078/1/7078 +f 7079/1/7079 7080/1/7080 7077/1/7077 +f 7084/1/7084 7088/1/7088 7080/1/7080 +f 7083/1/7083 7055/1/7055 7082/1/7082 +f 7085/1/7085 7088/1/7088 7084/1/7084 +f 7092/1/7092 7088/1/7088 7089/1/7089 +f 7093/1/7093 7092/1/7092 7089/1/7089 +f 7090/1/7090 7094/1/7094 7089/1/7089 +f 7086/1/7086 7082/1/7082 7087/1/7087 +f 7095/1/7095 7094/1/7094 7090/1/7090 +f 7093/1/7093 7089/1/7089 7094/1/7094 +f 7112/1/7112 7092/1/7092 7093/1/7093 +f 6041/1/6041 7113/1/7113 7112/1/7112 +f 6042/1/6042 6041/1/6041 6040/1/6040 +f 6075/1/6075 6040/1/6040 6084/1/6084 +f 6082/1/6082 6084/1/6084 6085/1/6085 +f 6083/1/6083 6085/1/6085 6087/1/6087 +f 6088/1/6088 6087/1/6087 6092/1/6092 +f 6093/1/6093 6088/1/6088 6092/1/6092 +f 6094/1/6094 6086/1/6086 6093/1/6093 +f 6081/1/6081 6080/1/6080 6094/1/6094 +f 6105/1/6105 6079/1/6079 6081/1/6081 +f 6109/1/6109 6105/1/6105 6106/1/6106 +f 7052/1/7052 6106/1/6106 7053/1/7053 +f 6101/1/6101 6096/1/6096 6097/1/6097 +f 6097/1/6097 6095/1/6095 6099/1/6099 +f 7128/1/7128 6104/1/6104 6160/1/6160 +f 6099/1/6099 6102/1/6102 6103/1/6103 +f 6098/1/6098 6145/1/6145 6102/1/6102 +f 6104/1/6104 6148/1/6148 6154/1/6154 +f 6148/1/6148 6147/1/6147 6152/1/6152 +f 6091/1/6091 6146/1/6146 6145/1/6145 +f 6147/1/6147 6150/1/6150 6152/1/6152 +f 6090/1/6090 6149/1/6149 6146/1/6146 +f 6150/1/6150 6035/1/6035 6036/1/6036 +f 6089/1/6089 6038/1/6038 6149/1/6149 +f 6038/1/6038 6039/1/6039 6037/1/6037 +f 6039/1/6039 7111/1/7111 6037/1/6037 +f 7111/1/7111 7110/1/7110 7109/1/7109 +f 7109/1/7109 7097/1/7097 7099/1/7099 +f 6034/1/6034 7108/1/7108 6029/1/6029 +f 7099/1/7099 6161/1/6161 6032/1/6032 +f 6030/1/6030 6033/1/6033 6031/1/6031 +f 6029/1/6029 6030/1/6030 6027/1/6027 +f 6028/1/6028 6034/1/6034 6029/1/6029 +f 6035/1/6035 6028/1/6028 6036/1/6036 +f 6151/1/6151 6036/1/6036 6155/1/6155 +f 6158/1/6158 6155/1/6155 7173/1/7173 +f 7175/1/7175 7173/1/7173 7174/1/7174 +f 7175/1/7175 7174/1/7174 7134/1/7134 +f 7133/1/7133 7132/1/7132 7134/1/7134 +f 7130/1/7130 7132/1/7132 7133/1/7133 +f 7126/1/7126 7129/1/7129 7130/1/7130 +f 7124/1/7124 6100/1/6100 7126/1/7126 +f 7106/1/7106 7123/1/7123 7124/1/7124 +f 7105/1/7105 7123/1/7123 7106/1/7106 +f 7102/1/7102 7053/1/7053 7105/1/7105 +f 7098/1/7098 7087/1/7087 7102/1/7102 +f 7098/1/7098 7100/1/7100 7096/1/7096 +f 7099/1/7099 7100/1/7100 6161/1/6161 +f 7101/1/7101 7104/1/7104 7103/1/7103 +f 7107/1/7107 5981/1/5981 6161/1/6161 +f 5980/1/5980 5978/1/5978 5981/1/5981 +f 5982/1/5982 7104/1/7104 5974/1/5974 +f 5979/1/5979 5978/1/5978 5980/1/5980 +f 5985/1/5985 5978/1/5978 5977/1/5977 +f 5983/1/5983 5985/1/5985 5977/1/5977 +f 5975/1/5975 5984/1/5984 5977/1/5977 +f 5973/1/5973 5974/1/5974 5969/1/5969 +f 5976/1/5976 5984/1/5984 5975/1/5975 +f 5983/1/5983 5977/1/5977 5984/1/5984 +f 5989/1/5989 5985/1/5985 5983/1/5983 +f 6026/1/6026 5989/1/5989 6025/1/6025 +f 6156/1/6156 6026/1/6026 6025/1/6025 +f 6157/1/6157 6156/1/6156 6159/1/6159 +f 7172/1/7172 6159/1/6159 7171/1/7171 +f 7141/1/7141 7171/1/7171 7139/1/7139 +f 7136/1/7136 7139/1/7139 7140/1/7140 +f 7137/1/7137 7136/1/7136 7140/1/7140 +f 7138/1/7138 7135/1/7135 7137/1/7137 +f 7125/1/7125 7127/1/7127 7138/1/7138 +f 5972/1/5972 7125/1/7125 5968/1/5968 +f 7153/1/7153 7147/1/7147 7148/1/7148 +f 7148/1/7148 7143/1/7143 7146/1/7146 +f 7151/1/7151 7150/1/7150 7155/1/7155 +f 7143/1/7143 7145/1/7145 7146/1/7146 +f 7150/1/7150 7149/1/7149 7157/1/7157 +f 7142/1/7142 7144/1/7144 7145/1/7145 +f 7144/1/7144 7169/1/7169 7167/1/7167 +f 7167/1/7167 7170/1/7170 7168/1/7168 +f 7149/1/7149 7163/1/7163 7157/1/7157 +f 7150/1/7150 7157/1/7157 7155/1/7155 +f 7151/1/7151 7155/1/7155 7156/1/7156 +f 7152/1/7152 7151/1/7151 7156/1/7156 +f 7159/1/7159 7158/1/7158 7161/1/7161 +f 7191/1/7191 7181/1/7181 7187/1/7187 +f 7181/1/7181 7180/1/7180 7187/1/7187 +f 7187/1/7187 7180/1/7180 7183/1/7183 +f 7180/1/7180 7178/1/7178 7183/1/7183 +f 7179/1/7179 7178/1/7178 7180/1/7180 +f 7158/1/7158 7160/1/7160 7161/1/7161 +f 7181/1/7181 7179/1/7179 7180/1/7180 +f 7162/1/7162 7165/1/7165 7160/1/7160 +f 7179/1/7179 7177/1/7177 7178/1/7178 +f 7164/1/7164 7166/1/7166 7165/1/7165 +f 7168/1/7168 6021/1/6021 7166/1/7166 +f 6024/1/6024 6022/1/6022 6021/1/6021 +f 6022/1/6022 5987/1/5987 5993/1/5993 +f 5987/1/5987 5990/1/5990 5993/1/5993 +f 5990/1/5990 5986/1/5986 5991/1/5991 +f 6016/1/6016 5994/1/5994 5995/1/5995 +f 6020/1/6020 6016/1/6016 6017/1/6017 +f 6014/1/6014 6013/1/6013 6009/1/6009 +f 6017/1/6017 6015/1/6015 6018/1/6018 +f 6023/1/6023 6020/1/6020 6017/1/6017 +f 7177/1/7177 6023/1/6023 7178/1/7178 +f 7183/1/7183 7178/1/7178 7182/1/7182 +f 7187/1/7187 7183/1/7183 7188/1/7188 +f 7191/1/7191 7187/1/7187 7189/1/7189 +f 7202/1/7202 7189/1/7189 7196/1/7196 +f 7203/1/7203 7235/1/7235 7202/1/7202 +f 7204/1/7204 7152/1/7152 7203/1/7203 +f 7200/1/7200 7197/1/7197 7201/1/7201 +f 7197/1/7197 7190/1/7190 7195/1/7195 +f 7195/1/7195 7194/1/7194 7198/1/7198 +f 7221/1/7221 7217/1/7217 7210/1/7210 +f 7210/1/7210 7217/1/7217 7215/1/7215 +f 7217/1/7217 7218/1/7218 7215/1/7215 +f 7217/1/7217 7220/1/7220 7218/1/7218 +f 7192/1/7192 7193/1/7193 7194/1/7194 +f 7186/1/7186 7184/1/7184 7193/1/7193 +f 7184/1/7184 6162/1/6162 7185/1/7185 +f 7220/1/7220 7222/1/7222 7218/1/7218 +f 7215/1/7215 7218/1/7218 7219/1/7219 +f 7210/1/7210 7215/1/7215 7211/1/7211 +f 7208/1/7208 7210/1/7210 7211/1/7211 +f 7209/1/7209 7211/1/7211 7212/1/7212 +f 7208/1/7208 7211/1/7211 7209/1/7209 +f 7206/1/7206 7210/1/7210 7208/1/7208 +f 7205/1/7205 7199/1/7199 7206/1/7206 +f 5960/1/5960 7205/1/7205 5957/1/5957 +f 5961/1/5961 7204/1/7204 5960/1/5960 +f 5964/1/5964 7204/1/7204 5961/1/5961 +f 5966/1/5966 7154/1/7154 5964/1/5964 +f 5967/1/5967 5968/1/5968 5966/1/5966 +f 5970/1/5970 5969/1/5969 5967/1/5967 +f 5970/1/5970 5996/1/5996 5992/1/5992 +f 5991/1/5991 5996/1/5996 5997/1/5997 +f 5971/1/5971 5965/1/5965 5998/1/5998 +f 5999/1/5999 6001/1/6001 5997/1/5997 +f 6002/1/6002 6005/1/6005 6001/1/6001 +f 6000/1/6000 5965/1/5965 5963/1/5963 +f 6003/1/6003 6005/1/6005 6002/1/6002 +f 6009/1/6009 6005/1/6005 6008/1/6008 +f 6010/1/6010 6012/1/6012 6008/1/6008 +f 6004/1/6004 5963/1/5963 5962/1/5962 +f 6171/1/6171 6012/1/6012 6010/1/6010 +f 6011/1/6011 6008/1/6008 6012/1/6012 +f 6019/1/6019 6011/1/6011 6163/1/6163 +f 6164/1/6164 6167/1/6167 6168/1/6168 +f 6168/1/6168 6174/1/6174 6175/1/6175 +f 6178/1/6178 6177/1/6177 7302/1/7302 +f 6176/1/6176 6178/1/6178 7301/1/7301 +f 6165/1/6165 6169/1/6169 6176/1/6176 +f 6166/1/6166 6019/1/6019 6165/1/6165 +f 7185/1/7185 6166/1/6166 7224/1/7224 +f 7223/1/7223 7224/1/7224 7225/1/7225 +f 7233/1/7233 7225/1/7225 7232/1/7232 +f 7234/1/7234 7233/1/7233 7232/1/7232 +f 7216/1/7216 7234/1/7234 7214/1/7214 +f 7213/1/7213 7214/1/7214 6214/1/6214 +f 6215/1/6215 6217/1/6217 6210/1/6210 +f 6210/1/6210 7231/1/7231 6208/1/6208 +f 6204/1/6204 6206/1/6206 5860/1/5860 +f 6208/1/6208 6209/1/6209 6205/1/6205 +f 7227/1/7227 7226/1/7226 6209/1/6209 +f 7226/1/7226 6180/1/6180 6181/1/6181 +f 6206/1/6206 5861/1/5861 5860/1/5860 +f 6204/1/6204 5860/1/5860 6202/1/6202 +f 6200/1/6200 6204/1/6204 6202/1/6202 +f 6196/1/6196 6203/1/6203 6200/1/6200 +f 6211/1/6211 6207/1/6207 6196/1/6196 +f 6194/1/6194 6212/1/6212 6211/1/6211 +f 6193/1/6193 6213/1/6213 6194/1/6194 +f 6216/1/6216 6214/1/6214 6193/1/6193 +f 5954/1/5954 7207/1/7207 6216/1/6216 +f 5956/1/5956 5954/1/5954 5952/1/5952 +f 5958/1/5958 5959/1/5959 5956/1/5956 +f 6173/1/6173 5962/1/5962 5958/1/5958 +f 6173/1/6173 6172/1/6172 6170/1/6170 +f 6168/1/6168 6172/1/6172 6174/1/6174 +f 6182/1/6182 5955/1/5955 6183/1/6183 +f 6184/1/6184 6179/1/6179 6174/1/6174 +f 6186/1/6186 7266/1/7266 6179/1/6179 +f 6185/1/6185 5955/1/5955 5953/1/5953 +f 7265/1/7265 7266/1/7266 6186/1/6186 +f 7270/1/7270 7266/1/7266 7267/1/7267 +f 7269/1/7269 7270/1/7270 7267/1/7267 +f 7269/1/7269 7267/1/7267 7268/1/7268 +f 7262/1/7262 7268/1/7268 7267/1/7267 +f 7261/1/7261 5953/1/5953 7260/1/7260 +f 7263/1/7263 7268/1/7268 7262/1/7262 +f 7269/1/7269 7268/1/7268 7272/1/7272 +f 7300/1/7300 7270/1/7270 7269/1/7269 +f 6181/1/6181 7300/1/7300 7228/1/7228 +f 7299/1/7299 7276/1/7276 7275/1/7275 +f 7275/1/7275 7274/1/7274 7279/1/7279 +f 7297/1/7297 7283/1/7283 7284/1/7284 +f 7295/1/7295 7278/1/7278 7297/1/7297 +f 7230/1/7230 7298/1/7298 7295/1/7295 +f 7229/1/7229 7298/1/7298 7230/1/7230 +f 5856/1/5856 7228/1/7228 7229/1/7229 +f 5857/1/5857 5856/1/5856 5855/1/5855 +f 5858/1/5858 5857/1/5857 5855/1/5855 +f 5863/1/5863 5862/1/5862 5858/1/5858 +f 6199/1/6199 5863/1/5863 6201/1/6201 +f 6198/1/6198 6199/1/6199 6201/1/6201 +f 6192/1/6192 6197/1/6197 6198/1/6198 +f 6191/1/6191 6197/1/6197 6192/1/6192 +f 6190/1/6190 6195/1/6195 6191/1/6191 +f 5951/1/5951 6190/1/6190 5949/1/5949 +f 5950/1/5950 5949/1/5949 5948/1/5948 +f 5947/1/5947 6187/1/6187 5888/1/5888 +f 5888/1/5888 6188/1/6188 6189/1/6189 +f 6189/1/6189 5868/1/5868 5867/1/5867 +f 5867/1/5867 5864/1/5864 5866/1/5866 +f 5866/1/5866 5859/1/5859 5865/1/5865 +f 5859/1/5859 5851/1/5851 5865/1/5865 +f 5851/1/5851 5852/1/5852 5850/1/5850 +f 5872/1/5872 5853/1/5853 5873/1/5873 +f 5874/1/5874 5872/1/5872 5873/1/5873 +f 5870/1/5870 5871/1/5871 5874/1/5874 +f 5885/1/5885 5869/1/5869 5870/1/5870 +f 5886/1/5886 5887/1/5887 5885/1/5885 +f 5889/1/5889 5886/1/5886 5890/1/5890 +f 5945/1/5945 5889/1/5889 5890/1/5890 +f 5884/1/5884 5880/1/5880 5881/1/5881 +f 5881/1/5881 5875/1/5875 5878/1/5878 +f 5878/1/5878 5876/1/5876 5879/1/5879 +f 5879/1/5879 5877/1/5877 5900/1/5900 +f 5900/1/5900 5854/1/5854 5944/1/5944 +f 5897/1/5897 5901/1/5901 5898/1/5898 +f 5896/1/5896 5897/1/5897 5898/1/5898 +f 5892/1/5892 5882/1/5882 5896/1/5896 +f 5891/1/5891 5883/1/5883 5892/1/5892 +f 5890/1/5890 5891/1/5891 5895/1/5895 +f 7252/1/7252 5890/1/5890 5895/1/5895 +f 5945/1/5945 5890/1/5890 7252/1/7252 +f 5946/1/5946 5889/1/5889 5945/1/5945 +f 7255/1/7255 5948/1/5948 5946/1/5946 +f 7264/1/7264 7260/1/7260 7255/1/7255 +f 7264/1/7264 7273/1/7273 7271/1/7271 +f 7274/1/7274 7273/1/7273 7277/1/7277 +f 7256/1/7256 7254/1/7254 7257/1/7257 +f 7258/1/7258 7280/1/7280 7277/1/7277 +f 7281/1/7281 7282/1/7282 7280/1/7280 +f 7259/1/7259 7254/1/7254 7253/1/7253 +f 7285/1/7285 7282/1/7282 7281/1/7281 +f 7289/1/7289 7282/1/7282 7287/1/7287 +f 7288/1/7288 7289/1/7289 7287/1/7287 +f 7243/1/7243 7237/1/7237 7287/1/7287 +f 7286/1/7286 7253/1/7253 7244/1/7244 +f 7238/1/7238 7237/1/7237 7243/1/7243 +f 7288/1/7288 7287/1/7287 7237/1/7237 +f 7292/1/7292 7289/1/7289 7288/1/7288 +f 5849/1/5849 7296/1/7296 7292/1/7292 +f 5850/1/5850 5849/1/5849 5848/1/5848 +f 5944/1/5944 5848/1/5848 5909/1/5909 +f 5902/1/5902 5909/1/5909 5906/1/5906 +f 5903/1/5903 5902/1/5902 5906/1/5906 +f 5899/1/5899 5903/1/5903 5905/1/5905 +f 5904/1/5904 5899/1/5899 5905/1/5905 +f 5894/1/5894 5893/1/5893 5904/1/5904 +f 5914/1/5914 5908/1/5908 5913/1/5913 +f 5913/1/5913 5907/1/5907 5912/1/5912 +f 5927/1/5927 5928/1/5928 5929/1/5929 +f 5907/1/5907 5911/1/5911 5912/1/5912 +f 5911/1/5911 5910/1/5910 5931/1/5931 +f 5910/1/5910 5846/1/5846 5931/1/5931 +f 5846/1/5846 5847/1/5847 5845/1/5845 +f 5847/1/5847 7290/1/7290 5845/1/5845 +f 7290/1/7290 7291/1/7291 7293/1/7293 +f 7293/1/7293 7239/1/7239 7242/1/7242 +f 5843/1/5843 7294/1/7294 5844/1/5844 +f 7242/1/7242 7247/1/7247 6220/1/6220 +f 6219/1/6219 6225/1/6225 6223/1/6223 +f 5844/1/5844 6219/1/6219 6218/1/6218 +f 5841/1/5841 5843/1/5843 5844/1/5844 +f 5842/1/5842 5841/1/5841 5839/1/5839 +f 5932/1/5932 5842/1/5842 5839/1/5839 +f 5928/1/5928 5932/1/5932 5929/1/5929 +f 5927/1/5927 5929/1/5929 5930/1/5930 +f 5917/1/5917 5927/1/5927 5922/1/5922 +f 5918/1/5918 5917/1/5917 5922/1/5922 +f 5916/1/5916 5915/1/5915 5918/1/5918 +f 5920/1/5920 5894/1/5894 5916/1/5916 +f 7250/1/7250 5920/1/5920 7251/1/7251 +f 7246/1/7246 7250/1/7250 7251/1/7251 +f 7240/1/7240 7244/1/7244 7246/1/7246 +f 7240/1/7240 7241/1/7241 7236/1/7236 +f 7242/1/7242 7241/1/7241 7247/1/7247 +f 7245/1/7245 7249/1/7249 7248/1/7248 +f 7417/1/7417 6226/1/6226 7247/1/7247 +f 7418/1/7418 7249/1/7249 5773/1/5773 +f 6228/1/6228 6224/1/6224 6226/1/6226 +f 6221/1/6221 6224/1/6224 6222/1/6222 +f 5771/1/5771 5774/1/5774 6222/1/6222 +f 5771/1/5771 5766/1/5766 5768/1/5768 +f 6227/1/6227 5773/1/5773 5772/1/5772 +f 5766/1/5766 7305/1/7305 5764/1/5764 +f 5766/1/5766 5764/1/5764 5763/1/5763 +f 7249/1/7249 7303/1/7303 5773/1/5773 +f 7303/1/7303 5921/1/5921 7304/1/7304 +f 5921/1/5921 5919/1/5919 7304/1/7304 +f 5919/1/5919 5923/1/5923 5924/1/5924 +f 5924/1/5924 5925/1/5925 5926/1/5926 +f 5925/1/5925 5936/1/5936 5926/1/5926 +f 5936/1/5936 5934/1/5934 5935/1/5935 +f 5935/1/5935 5933/1/5933 5937/1/5937 +f 5941/1/5941 5939/1/5939 7369/1/7369 +f 5942/1/5942 5941/1/5941 7369/1/7369 +f 7309/1/7309 5942/1/5942 7310/1/7310 +f 7306/1/7306 7310/1/7310 7307/1/7307 +f 7312/1/7312 7311/1/7311 7313/1/7313 +f 7313/1/7313 7367/1/7367 7364/1/7364 +f 7367/1/7367 7368/1/7368 7364/1/7364 +f 7365/1/7365 5943/1/5943 7366/1/7366 +f 5940/1/5940 5938/1/5938 7368/1/7368 +f 5937/1/5937 5838/1/5838 5938/1/5938 +f 5838/1/5838 5840/1/5840 5788/1/5788 +f 5788/1/5788 5789/1/5789 5784/1/5784 +f 5784/1/5784 5781/1/5781 5780/1/5780 +f 5780/1/5780 5776/1/5776 5778/1/5778 +f 5799/1/5799 5828/1/5828 5827/1/5827 +f 5785/1/5785 5779/1/5779 5799/1/5799 +f 5787/1/5787 5783/1/5783 5785/1/5785 +f 5791/1/5791 5786/1/5786 5787/1/5787 +f 5790/1/5790 5786/1/5786 5791/1/5791 +f 5943/1/5943 5790/1/5790 7370/1/7370 +f 7366/1/7366 5943/1/5943 7370/1/7370 +f 7363/1/7363 7365/1/7365 7366/1/7366 +f 7318/1/7318 7363/1/7363 7362/1/7362 +f 7316/1/7316 7315/1/7315 7318/1/7318 +f 7317/1/7317 7314/1/7314 7316/1/7316 +f 7308/1/7308 7307/1/7307 7317/1/7317 +f 7305/1/7305 7308/1/7308 5764/1/5764 +f 7322/1/7322 7320/1/7320 7321/1/7321 +f 7321/1/7321 7319/1/7319 7360/1/7360 +f 7361/1/7361 7355/1/7355 7354/1/7354 +f 7319/1/7319 7358/1/7358 7360/1/7360 +f 7358/1/7358 7359/1/7359 7356/1/7356 +f 7356/1/7356 7357/1/7357 7352/1/7352 +f 7352/1/7352 7351/1/7351 7350/1/7350 +f 7353/1/7353 7349/1/7349 7348/1/7348 +f 7355/1/7355 7353/1/7353 7354/1/7354 +f 7361/1/7361 7354/1/7354 7332/1/7332 +f 7324/1/7324 7361/1/7361 7332/1/7332 +f 7329/1/7329 7333/1/7333 7334/1/7334 +f 7336/1/7336 7339/1/7339 7343/1/7343 +f 7334/1/7334 7338/1/7338 7335/1/7335 +f 7339/1/7339 7342/1/7342 7344/1/7344 +f 7340/1/7340 7341/1/7341 7338/1/7338 +f 7346/1/7346 7347/1/7347 7341/1/7341 +f 7350/1/7350 5792/1/5792 7347/1/7347 +f 7342/1/7342 7345/1/7345 7344/1/7344 +f 7339/1/7339 7344/1/7344 7343/1/7343 +f 7336/1/7336 7343/1/7343 7379/1/7379 +f 7337/1/7337 7336/1/7336 7379/1/7379 +f 7331/1/7331 7336/1/7336 7337/1/7337 +f 7326/1/7326 7330/1/7330 7331/1/7331 +f 7325/1/7325 7324/1/7324 7326/1/7326 +f 5760/1/5760 7323/1/7323 7325/1/7325 +f 5762/1/5762 7323/1/7323 5760/1/5760 +f 5763/1/5763 5764/1/5764 5762/1/5762 +f 5765/1/5765 5766/1/5766 5763/1/5763 +f 5765/1/5765 5769/1/5769 5770/1/5770 +f 5776/1/5776 5769/1/5769 5777/1/5777 +f 5767/1/5767 5761/1/5761 5831/1/5831 +f 5830/1/5830 5826/1/5826 5777/1/5777 +f 5825/1/5825 5823/1/5823 5826/1/5826 +f 5829/1/5829 5761/1/5761 5759/1/5759 +f 5824/1/5824 5823/1/5823 5825/1/5825 +f 5800/1/5800 5823/1/5823 5822/1/5822 +f 5801/1/5801 5800/1/5800 5822/1/5822 +f 5756/1/5756 5813/1/5813 5822/1/5822 +f 5758/1/5758 5759/1/5759 5754/1/5754 +f 5757/1/5757 5813/1/5813 5756/1/5756 +f 5801/1/5801 5822/1/5822 5813/1/5813 +f 5798/1/5798 5800/1/5800 5801/1/5801 +f 5793/1/5793 5797/1/5797 5798/1/5798 +f 5792/1/5792 5793/1/5793 5794/1/5794 +f 7371/1/7371 5794/1/5794 7372/1/7372 +f 7373/1/7373 7372/1/7372 7374/1/7374 +f 7375/1/7375 7374/1/7374 7378/1/7378 +f 7380/1/7380 7378/1/7378 7382/1/7382 +f 7383/1/7383 7380/1/7380 7382/1/7382 +f 7384/1/7384 7381/1/7381 7383/1/7383 +f 7328/1/7328 7327/1/7327 7384/1/7384 +f 5755/1/5755 7328/1/7328 5751/1/5751 +f 5749/1/5749 7386/1/7386 7390/1/7390 +f 7390/1/7390 7385/1/7385 7389/1/7389 +f 7391/1/7391 7393/1/7393 7394/1/7394 +f 7385/1/7385 7388/1/7388 7389/1/7389 +f 7393/1/7393 7396/1/7396 7397/1/7397 +f 7387/1/7387 7416/1/7416 7388/1/7388 +f 7416/1/7416 7377/1/7377 7415/1/7415 +f 7415/1/7415 7376/1/7376 7414/1/7414 +f 7396/1/7396 7399/1/7399 7397/1/7397 +f 7393/1/7393 7397/1/7397 7394/1/7394 +f 7391/1/7391 7394/1/7394 7395/1/7395 +f 7392/1/7392 7391/1/7391 7395/1/7395 +f 5746/1/5746 7392/1/7392 5743/1/5743 +f 5745/1/5745 5746/1/5746 5743/1/5743 +f 6232/1/6232 6236/1/6236 6237/1/6237 +f 6236/1/6236 6242/1/6242 6237/1/6237 +f 6237/1/6237 6242/1/6242 6238/1/6238 +f 6237/1/6237 6238/1/6238 6233/1/6233 +f 6233/1/6233 6238/1/6238 6239/1/6239 +f 6242/1/6242 6243/1/6243 6238/1/6238 +f 6243/1/6243 6244/1/6244 6238/1/6238 +f 6238/1/6238 6244/1/6244 6241/1/6241 +f 6244/1/6244 6248/1/6248 6241/1/6241 +f 6244/1/6244 6249/1/6249 6248/1/6248 +f 6243/1/6243 6249/1/6249 6244/1/6244 +f 6243/1/6243 7410/1/7410 6249/1/6249 +f 7410/1/7410 7409/1/7409 6249/1/6249 +f 6249/1/6249 7409/1/7409 6250/1/6250 +f 7408/1/7408 7409/1/7409 7410/1/7410 +f 6253/1/6253 7410/1/7410 6243/1/6243 +f 6252/1/6252 6243/1/6243 6242/1/6242 +f 6235/1/6235 7404/1/7404 6251/1/6251 +f 6236/1/6236 6252/1/6252 6242/1/6242 +f 7404/1/7404 7403/1/7403 6251/1/6251 +f 6252/1/6252 6253/1/6253 6243/1/6243 +f 7398/1/7398 7402/1/7402 7403/1/7403 +f 6253/1/6253 7408/1/7408 7410/1/7410 +f 7401/1/7401 7405/1/7405 7402/1/7402 +f 7408/1/7408 7407/1/7407 7409/1/7409 +f 7400/1/7400 7406/1/7406 7405/1/7405 +f 7407/1/7407 7411/1/7411 7409/1/7409 +f 7409/1/7409 7411/1/7411 7412/1/7412 +f 7414/1/7414 7413/1/7413 7406/1/7406 +f 7411/1/7411 5807/1/5807 5821/1/5821 +f 5807/1/5807 5809/1/5809 5821/1/5821 +f 5821/1/5821 5809/1/5809 5820/1/5820 +f 5796/1/5796 5803/1/5803 7413/1/7413 +f 5807/1/5807 5806/1/5806 5809/1/5809 +f 5795/1/5795 5802/1/5802 5803/1/5803 +f 5802/1/5802 5804/1/5804 5805/1/5805 +f 5805/1/5805 5810/1/5810 5811/1/5811 +f 5806/1/5806 5808/1/5808 5809/1/5809 +f 5811/1/5811 5815/1/5815 5814/1/5814 +f 5818/1/5818 5817/1/5817 6761/1/6761 +f 5809/1/5809 5818/1/5818 5820/1/5820 +f 5821/1/5821 5820/1/5820 6758/1/6758 +f 7411/1/7411 5821/1/5821 7412/1/7412 +f 7409/1/7409 7412/1/7412 6250/1/6250 +f 6249/1/6249 6250/1/6250 6248/1/6248 +f 6241/1/6241 6248/1/6248 6247/1/6247 +f 6238/1/6238 6241/1/6241 6239/1/6239 +f 6233/1/6233 6239/1/6239 6234/1/6234 +f 6232/1/6232 6237/1/6237 6233/1/6233 +f 5743/1/5743 6232/1/6232 5740/1/5740 +f 5742/1/5742 5743/1/5743 5740/1/5740 +f 5745/1/5745 5743/1/5743 5742/1/5742 +f 5748/1/5748 5746/1/5746 5745/1/5745 +f 5750/1/5750 5751/1/5751 5748/1/5748 +f 5752/1/5752 5754/1/5754 5750/1/5750 +f 5752/1/5752 5816/1/5816 5812/1/5812 +f 5811/1/5811 5816/1/5816 5815/1/5815 +f 5753/1/5753 5747/1/5747 5832/1/5832 +f 5833/1/5833 5819/1/5819 5815/1/5815 +f 5835/1/5835 5837/1/5837 5819/1/5819 +f 5834/1/5834 5747/1/5747 5744/1/5744 +f 5836/1/5836 5837/1/5837 5835/1/5835 +f 6759/1/6759 5837/1/5837 6754/1/6754 +f 6752/1/6752 6751/1/6751 6754/1/6754 +f 6753/1/6753 5744/1/5744 5741/1/5741 +f 6744/1/6744 6751/1/6751 6752/1/6752 +f 6755/1/6755 6751/1/6751 6750/1/6750 +f 6757/1/6757 6750/1/6750 6762/1/6762 +f 6756/1/6756 6757/1/6757 6762/1/6762 +f 6760/1/6760 6756/1/6756 6763/1/6763 +f 5643/1/5643 6760/1/6760 6763/1/6763 +f 5647/1/5647 5643/1/5643 5644/1/5644 +f 5648/1/5648 5647/1/5647 5644/1/5644 +f 6245/1/6245 5648/1/5648 5649/1/5649 +f 6245/1/6245 5649/1/5649 6246/1/6246 +f 6230/1/6230 6240/1/6240 6246/1/6246 +f 6229/1/6229 6230/1/6230 5674/1/5674 +f 6231/1/6231 5653/1/5653 5654/1/5654 +f 5657/1/5657 5652/1/5652 5656/1/5656 +f 5653/1/5653 5650/1/5650 5654/1/5654 +f 5650/1/5650 5645/1/5645 5646/1/5646 +f 5646/1/5646 5642/1/5642 5638/1/5638 +f 5652/1/5652 5651/1/5651 5655/1/5655 +f 5652/1/5652 5655/1/5655 5656/1/5656 +f 5671/1/5671 5657/1/5657 5656/1/5656 +f 5672/1/5672 5673/1/5673 5671/1/5671 +f 5675/1/5675 5674/1/5674 5672/1/5672 +f 5737/1/5737 5738/1/5738 5675/1/5675 +f 6741/1/6741 5739/1/5739 5737/1/5737 +f 6742/1/6742 5741/1/5741 6741/1/6741 +f 6742/1/6742 6745/1/6745 6746/1/6746 +f 6749/1/6749 6745/1/6745 6748/1/6748 +f 6743/1/6743 6740/1/6740 6747/1/6747 +f 6775/1/6775 6774/1/6774 6748/1/6748 +f 6776/1/6776 6777/1/6777 6774/1/6774 +f 6778/1/6778 6740/1/6740 6739/1/6739 +f 6781/1/6781 6777/1/6777 6776/1/6776 +f 6773/1/6773 6777/1/6777 6780/1/6780 +f 6779/1/6779 6739/1/6739 6782/1/6782 +f 6798/1/6798 6796/1/6796 6780/1/6780 +f 6799/1/6799 6780/1/6780 6796/1/6796 +f 6799/1/6799 6773/1/6773 6780/1/6780 +f 6771/1/6771 6770/1/6770 6773/1/6773 +f 6767/1/6767 6770/1/6770 6771/1/6771 +f 6766/1/6766 6764/1/6764 6767/1/6767 +f 5639/1/5639 6766/1/6766 5637/1/5637 +f 5638/1/5638 5637/1/5637 5640/1/5640 +f 5658/1/5658 5640/1/5640 5659/1/5659 +f 5661/1/5661 5659/1/5659 5663/1/5663 +f 5662/1/5662 5660/1/5660 5661/1/5661 +f 5666/1/5666 5662/1/5662 5667/1/5667 +f 5670/1/5670 5666/1/5666 5667/1/5667 +f 5668/1/5668 5665/1/5665 5669/1/5669 +f 5665/1/5665 5664/1/5664 5669/1/5669 +f 5664/1/5664 5686/1/5686 5683/1/5683 +f 5686/1/5686 5641/1/5641 5735/1/5735 +f 5684/1/5684 5687/1/5687 5688/1/5688 +f 5682/1/5682 5684/1/5684 5685/1/5685 +f 5679/1/5679 5682/1/5682 5685/1/5685 +f 5677/1/5677 5678/1/5678 5679/1/5679 +f 5676/1/5676 5670/1/5670 5677/1/5677 +f 5736/1/5736 5676/1/5676 6738/1/6738 +f 6782/1/6782 6738/1/6738 6737/1/6737 +f 6795/1/6795 6782/1/6782 6784/1/6784 +f 6784/1/6784 6792/1/6792 6794/1/6794 +f 6787/1/6787 6790/1/6790 6786/1/6786 +f 6793/1/6793 6794/1/6794 6792/1/6792 +f 6800/1/6800 6797/1/6797 6793/1/6793 +f 6802/1/6802 6800/1/6800 6804/1/6804 +f 5634/1/5634 6803/1/6803 6802/1/6802 +f 5635/1/5635 5636/1/5636 5634/1/5634 +f 5735/1/5735 5635/1/5635 5695/1/5695 +f 5692/1/5692 5695/1/5695 5696/1/5696 +f 5689/1/5689 5692/1/5692 5693/1/5693 +f 5694/1/5694 5693/1/5693 5699/1/5699 +f 5700/1/5700 5694/1/5694 5699/1/5699 +f 5680/1/5680 5690/1/5690 5700/1/5700 +f 5681/1/5681 5680/1/5680 5706/1/5706 +f 5702/1/5702 5701/1/5701 5704/1/5704 +f 5709/1/5709 5712/1/5712 5713/1/5713 +f 5712/1/5712 5723/1/5723 5713/1/5713 +f 5704/1/5704 5711/1/5711 5708/1/5708 +f 5703/1/5703 5716/1/5716 5711/1/5711 +f 5712/1/5712 5719/1/5719 5723/1/5723 +f 5719/1/5719 5722/1/5722 5723/1/5723 +f 5723/1/5723 5722/1/5722 5724/1/5724 +f 5723/1/5723 5724/1/5724 5725/1/5725 +f 5719/1/5719 5718/1/5718 5722/1/5722 +f 5698/1/5698 5717/1/5717 5716/1/5716 +f 5718/1/5718 5721/1/5721 5722/1/5722 +f 5722/1/5722 5721/1/5721 5726/1/5726 +f 5697/1/5697 5720/1/5720 5717/1/5717 +f 5720/1/5720 5633/1/5633 5631/1/5631 +f 5631/1/5631 5632/1/5632 5630/1/5630 +f 5721/1/5721 5629/1/5629 5726/1/5726 +f 5722/1/5722 5726/1/5726 5724/1/5724 +f 5725/1/5725 5724/1/5724 5728/1/5728 +f 5713/1/5713 5723/1/5723 5725/1/5725 +f 5709/1/5709 5713/1/5713 5714/1/5714 +f 5710/1/5710 5709/1/5709 5714/1/5714 +f 6807/1/6807 5715/1/5715 5731/1/5731 +f 5715/1/5715 5729/1/5729 5731/1/5731 +f 5729/1/5729 5730/1/5730 6915/1/6915 +f 5730/1/5730 5727/1/5727 5732/1/5732 +f 6914/1/6914 5733/1/5733 6913/1/6913 +f 6811/1/6811 6914/1/6914 6812/1/6812 +f 6809/1/6809 6811/1/6811 6812/1/6812 +f 6735/1/6735 6808/1/6808 6809/1/6809 +f 6732/1/6732 5710/1/5710 6735/1/6735 +f 5707/1/5707 5705/1/5705 6732/1/6732 +f 6736/1/6736 5706/1/5706 5707/1/5707 +f 6783/1/6783 6736/1/6736 6785/1/6785 +f 6788/1/6788 6785/1/6785 6789/1/6789 +f 6789/1/6789 6324/1/6324 6788/1/6788 +f 6323/1/6323 6324/1/6324 6320/1/6320 +f 6806/1/6806 6790/1/6790 6323/1/6323 +f 6322/1/6322 6805/1/6805 6806/1/6806 +f 5630/1/5630 6322/1/6322 5628/1/5628 +f 6318/1/6318 6319/1/6319 6316/1/6316 +f 5624/1/5624 6315/1/6315 6256/1/6256 +f 5626/1/5626 5628/1/5628 5624/1/5624 +f 5732/1/5732 5626/1/5626 5734/1/5734 +f 6912/1/6912 5734/1/5734 6911/1/6911 +f 6822/1/6822 6912/1/6912 6823/1/6823 +f 6820/1/6820 6823/1/6823 6824/1/6824 +f 6816/1/6816 6820/1/6820 6821/1/6821 +f 6814/1/6814 6813/1/6813 6816/1/6816 +f 6733/1/6733 6810/1/6810 6814/1/6814 +f 6731/1/6731 6733/1/6733 6330/1/6330 +f 6332/1/6332 6734/1/6734 6731/1/6731 +f 6791/1/6791 6332/1/6332 6356/1/6356 +f 6356/1/6356 6321/1/6321 6791/1/6791 +f 6316/1/6316 6321/1/6321 6317/1/6317 +f 6313/1/6313 6317/1/6317 6314/1/6314 +f 6329/1/6329 6328/1/6328 6326/1/6326 +f 6311/1/6311 6314/1/6314 6325/1/6325 +f 6307/1/6307 6311/1/6311 6312/1/6312 +f 6307/1/6307 6312/1/6312 6300/1/6300 +f 6333/1/6333 6300/1/6300 6312/1/6312 +f 6327/1/6327 6328/1/6328 6331/1/6331 +f 6334/1/6334 6300/1/6300 6333/1/6333 +f 6307/1/6307 6300/1/6300 6303/1/6303 +f 6306/1/6306 6307/1/6307 6303/1/6303 +f 6257/1/6257 6308/1/6308 6306/1/6306 +f 5625/1/5625 6257/1/6257 6254/1/6254 +f 5627/1/5627 5625/1/5625 6254/1/6254 +f 6910/1/6910 5623/1/5623 5627/1/5627 +f 6830/1/6830 6910/1/6910 6829/1/6829 +f 6828/1/6828 6829/1/6829 6831/1/6831 +f 6825/1/6825 6828/1/6828 6827/1/6827 +f 6826/1/6826 6827/1/6827 6834/1/6834 +f 6833/1/6833 6832/1/6832 6835/1/6835 +f 6847/1/6847 6844/1/6844 6846/1/6846 +f 6835/1/6835 6841/1/6841 6842/1/6842 +f 6838/1/6838 6840/1/6840 6841/1/6841 +f 6839/1/6839 6255/1/6255 6840/1/6840 +f 6844/1/6844 6843/1/6843 6846/1/6846 +f 6851/1/6851 6852/1/6852 6853/1/6853 +f 6847/1/6847 6846/1/6846 6851/1/6851 +f 6848/1/6848 6847/1/6847 6849/1/6849 +f 6857/1/6857 6848/1/6848 6849/1/6849 +f 6857/1/6857 6849/1/6849 6854/1/6854 +f 6909/1/6909 6848/1/6848 6857/1/6857 +f 6837/1/6837 6836/1/6836 6909/1/6909 +f 6907/1/6907 6834/1/6834 6837/1/6837 +f 6906/1/6906 6817/1/6817 6907/1/6907 +f 6335/1/6335 6815/1/6815 6906/1/6906 +f 6331/1/6331 6335/1/6335 6298/1/6298 +f 6301/1/6301 6298/1/6298 6297/1/6297 +f 6297/1/6297 6295/1/6295 6301/1/6301 +f 6299/1/6299 6295/1/6295 6294/1/6294 +f 6302/1/6302 6299/1/6299 6294/1/6294 +f 6258/1/6258 6302/1/6302 6304/1/6304 +f 6259/1/6259 6304/1/6304 6305/1/6305 +f 6255/1/6255 6259/1/6259 6260/1/6260 +f 6845/1/6845 6260/1/6260 6896/1/6896 +f 6898/1/6898 6896/1/6896 6899/1/6899 +f 6861/1/6861 6899/1/6899 6901/1/6901 +f 6861/1/6861 6901/1/6901 6903/1/6903 +f 6862/1/6862 6861/1/6861 6903/1/6903 +f 6856/1/6856 6861/1/6861 6862/1/6862 +f 6855/1/6855 6850/1/6850 6856/1/6856 +f 6858/1/6858 6855/1/6855 6860/1/6860 +f 6867/1/6867 6908/1/6908 6858/1/6858 +f 6336/1/6336 6867/1/6867 6337/1/6337 +f 6293/1/6293 6336/1/6336 6337/1/6337 +f 6296/1/6296 6293/1/6293 6292/1/6292 +f 6292/1/6292 6291/1/6291 6296/1/6296 +f 6290/1/6290 6291/1/6291 6288/1/6288 +f 6287/1/6287 6288/1/6288 6282/1/6282 +f 6289/1/6289 6284/1/6284 6286/1/6286 +f 6278/1/6278 6282/1/6282 6281/1/6281 +f 6272/1/6272 6278/1/6278 6277/1/6277 +f 6267/1/6267 6272/1/6272 6269/1/6269 +f 6266/1/6266 6357/1/6357 6267/1/6267 +f 6261/1/6261 6266/1/6266 6263/1/6263 +f 6262/1/6262 6261/1/6261 6263/1/6263 +f 6897/1/6897 6262/1/6262 6902/1/6902 +f 6900/1/6900 6902/1/6902 6879/1/6879 +f 6878/1/6878 6900/1/6900 6879/1/6879 +f 6877/1/6877 6878/1/6878 6873/1/6873 +f 6872/1/6872 6877/1/6877 6873/1/6873 +f 6876/1/6876 6880/1/6880 6881/1/6881 +f 6881/1/6881 6880/1/6880 6884/1/6884 +f 6884/1/6884 6885/1/6885 6886/1/6886 +f 6882/1/6882 6887/1/6887 6888/1/6888 +f 6883/1/6883 6882/1/6882 6888/1/6888 +f 6875/1/6875 6882/1/6882 6883/1/6883 +f 6870/1/6870 6874/1/6874 6875/1/6875 +f 6869/1/6869 6874/1/6874 6870/1/6870 +f 6872/1/6872 6873/1/6873 6869/1/6869 +f 6863/1/6863 6877/1/6877 6872/1/6872 +f 6864/1/6864 6859/1/6859 6863/1/6863 +f 6865/1/6865 6864/1/6864 6343/1/6343 +f 6338/1/6338 6865/1/6865 6343/1/6343 +f 6284/1/6284 6338/1/6338 6285/1/6285 +f 6280/1/6280 6285/1/6285 6279/1/6279 +f 6355/1/6355 6274/1/6274 6279/1/6279 +f 6271/1/6271 6274/1/6274 6273/1/6273 +f 6271/1/6271 6273/1/6273 6270/1/6270 +f 6268/1/6268 6270/1/6270 5393/1/5393 +f 6265/1/6265 6264/1/6264 6268/1/6268 +f 6895/1/6895 6265/1/6265 6891/1/6891 +f 6886/1/6886 6891/1/6891 6889/1/6889 +f 6890/1/6890 6889/1/6889 6894/1/6894 +f 6546/1/6546 6894/1/6894 6457/1/6457 +f 6904/1/6904 6546/1/6546 6545/1/6545 +f 6541/1/6541 6545/1/6545 6542/1/6542 +f 6540/1/6540 6905/1/6905 6541/1/6541 +f 6868/1/6868 6871/1/6871 6540/1/6540 +f 6341/1/6341 6866/1/6866 6868/1/6868 +f 6339/1/6339 6341/1/6341 6342/1/6342 +f 6340/1/6340 6339/1/6339 6342/1/6342 +f 6354/1/6354 6340/1/6340 6352/1/6352 +f 6352/1/6352 6276/1/6276 6354/1/6354 +f 6275/1/6275 6276/1/6276 5319/1/5319 +f 6353/1/6353 6347/1/6347 6351/1/6351 +f 5312/1/5312 5318/1/5318 5319/1/5319 +f 5314/1/5314 5317/1/5317 5313/1/5313 +f 5320/1/5320 5321/1/5321 5318/1/5318 +f 5324/1/5324 5320/1/5320 5322/1/5322 +f 5331/1/5331 5321/1/5321 5320/1/5320 +f 5392/1/5392 5331/1/5331 5329/1/5329 +f 6892/1/6892 5392/1/5392 5329/1/5329 +f 6893/1/6893 6892/1/6892 6445/1/6445 +f 6455/1/6455 6445/1/6445 6454/1/6454 +f 6456/1/6456 6455/1/6455 6454/1/6454 +f 6543/1/6543 6456/1/6456 6544/1/6544 +f 6539/1/6539 6544/1/6544 6462/1/6462 +f 6538/1/6538 6539/1/6539 6462/1/6462 +f 6346/1/6346 6537/1/6537 6538/1/6538 +f 6345/1/6345 6344/1/6344 6346/1/6346 +f 6347/1/6347 6345/1/6345 5309/1/5309 +f 5313/1/5313 5309/1/5309 5314/1/5314 +f 5316/1/5316 5317/1/5317 5314/1/5314 +f 5323/1/5323 5316/1/5316 5315/1/5315 +f 5323/1/5323 5315/1/5315 5338/1/5338 +f 5323/1/5323 5338/1/5338 5334/1/5334 +f 5341/1/5341 5338/1/5338 5340/1/5340 +f 5341/1/5341 5342/1/5342 5338/1/5338 +f 5339/1/5339 5338/1/5338 5342/1/5342 +f 5340/1/5340 5305/1/5305 5341/1/5341 +f 5310/1/5310 5307/1/5307 5311/1/5311 +f 5307/1/5307 5308/1/5308 5306/1/5306 +f 5341/1/5341 5305/1/5305 5346/1/5346 +f 5346/1/5346 5342/1/5342 5341/1/5341 +f 5339/1/5339 5342/1/5342 5343/1/5343 +f 5334/1/5334 5338/1/5338 5339/1/5339 +f 5327/1/5327 5323/1/5323 5334/1/5334 +f 5328/1/5328 5325/1/5325 5327/1/5327 +f 5330/1/5330 5326/1/5326 5328/1/5328 +f 6441/1/6441 5330/1/5330 6438/1/6438 +f 6440/1/6440 6441/1/6441 6438/1/6438 +f 6443/1/6443 6440/1/6440 6444/1/6444 +f 6447/1/6447 6446/1/6446 6443/1/6443 +f 6453/1/6453 6447/1/6447 6458/1/6458 +f 6459/1/6459 6461/1/6461 6458/1/6458 +f 6463/1/6463 6459/1/6459 6464/1/6464 +f 6460/1/6460 6451/1/6451 6452/1/6452 +f 6452/1/6452 6448/1/6448 6450/1/6450 +f 6465/1/6465 6467/1/6467 6468/1/6468 +f 6472/1/6472 6471/1/6471 6475/1/6475 +f 6450/1/6450 6473/1/6473 6469/1/6469 +f 6473/1/6473 6449/1/6449 6474/1/6474 +f 6474/1/6474 6437/1/6437 6439/1/6439 +f 6471/1/6471 6476/1/6476 6475/1/6475 +f 6472/1/6472 6475/1/6475 6477/1/6477 +f 6478/1/6478 6472/1/6472 6477/1/6477 +f 6478/1/6478 6477/1/6477 6522/1/6522 +f 6470/1/6470 6472/1/6472 6478/1/6478 +f 6466/1/6466 6468/1/6468 6470/1/6470 +f 6349/1/6349 6464/1/6464 6466/1/6466 +f 5306/1/5306 6349/1/6349 5304/1/5304 +f 6350/1/6350 6521/1/6521 6520/1/6520 +f 6520/1/6520 6523/1/6523 6496/1/6496 +f 6497/1/6497 6490/1/6490 6493/1/6493 +f 6490/1/6490 6491/1/6491 6493/1/6493 +f 6493/1/6493 6491/1/6491 6494/1/6494 +f 6523/1/6523 6489/1/6489 6496/1/6496 +f 6490/1/6490 6488/1/6488 6491/1/6491 +f 6488/1/6488 6487/1/6487 6491/1/6491 +f 6491/1/6491 6487/1/6487 6492/1/6492 +f 6487/1/6487 6486/1/6486 6492/1/6492 +f 6485/1/6485 6486/1/6486 6487/1/6487 +f 6482/1/6482 6483/1/6483 6489/1/6489 +f 6488/1/6488 6485/1/6485 6487/1/6487 +f 6479/1/6479 6481/1/6481 6483/1/6483 +f 6485/1/6485 6484/1/6484 6486/1/6486 +f 6480/1/6480 6435/1/6435 6481/1/6481 +f 6484/1/6484 6434/1/6434 6486/1/6486 +f 6486/1/6486 6434/1/6434 6433/1/6433 +f 6439/1/6439 6436/1/6436 6435/1/6435 +f 6436/1/6436 5333/1/5333 5337/1/5337 +f 5337/1/5337 5332/1/5332 5336/1/5336 +f 5336/1/5336 5335/1/5335 5348/1/5348 +f 5391/1/5391 5351/1/5351 5356/1/5356 +f 6434/1/6434 5391/1/5391 6433/1/6433 +f 6486/1/6486 6433/1/6433 6536/1/6536 +f 6492/1/6492 6486/1/6486 6536/1/6536 +f 6491/1/6491 6492/1/6492 6495/1/6495 +f 6491/1/6491 6495/1/6495 6494/1/6494 +f 6498/1/6498 6493/1/6493 6494/1/6494 +f 6508/1/6508 6507/1/6507 6510/1/6510 +f 6499/1/6499 6501/1/6501 6502/1/6502 +f 6501/1/6501 6500/1/6500 6509/1/6509 +f 6509/1/6509 6535/1/6535 6534/1/6534 +f 6507/1/6507 6511/1/6511 6512/1/6512 +f 6507/1/6507 6512/1/6512 6510/1/6510 +f 6513/1/6513 6508/1/6508 6510/1/6510 +f 6506/1/6506 6508/1/6508 6513/1/6513 +f 6505/1/6505 6503/1/6503 6506/1/6506 +f 6504/1/6504 6498/1/6498 6505/1/6505 +f 5300/1/5300 6519/1/6519 6504/1/6504 +f 5301/1/5301 5300/1/5300 5299/1/5299 +f 5303/1/5303 5304/1/5304 5301/1/5301 +f 5344/1/5344 5303/1/5303 5347/1/5347 +f 5347/1/5347 5345/1/5345 5344/1/5344 +f 5348/1/5348 5345/1/5345 5350/1/5350 +f 5352/1/5352 5350/1/5350 5354/1/5354 +f 5349/1/5349 5302/1/5302 5353/1/5353 +f 5358/1/5358 5354/1/5354 5359/1/5359 +f 5362/1/5362 5358/1/5358 5361/1/5361 +f 5362/1/5362 5361/1/5361 5377/1/5377 +f 5363/1/5363 5377/1/5377 5361/1/5361 +f 5360/1/5360 5302/1/5302 5364/1/5364 +f 5367/1/5367 5377/1/5377 5363/1/5363 +f 5362/1/5362 5377/1/5377 5379/1/5379 +f 5378/1/5378 5362/1/5362 5379/1/5379 +f 5384/1/5384 5380/1/5380 5378/1/5378 +f 5390/1/5390 5384/1/5384 5386/1/5386 +f 6432/1/6432 5386/1/5386 6431/1/6431 +f 6534/1/6534 6431/1/6431 6530/1/6530 +f 6526/1/6526 6530/1/6530 6527/1/6527 +f 6525/1/6525 6527/1/6527 6529/1/6529 +f 6516/1/6516 6524/1/6524 6525/1/6525 +f 6515/1/6515 6516/1/6516 6517/1/6517 +f 5289/1/5289 6515/1/6515 6517/1/6517 +f 5288/1/5288 6518/1/6518 5287/1/5287 +f 6518/1/6518 6528/1/6528 5287/1/5287 +f 6528/1/6528 6532/1/6532 5395/1/5395 +f 6532/1/6532 6531/1/6531 6533/1/6533 +f 5277/1/5277 5396/1/5396 5272/1/5272 +f 5283/1/5283 5277/1/5277 5275/1/5275 +f 5282/1/5282 5283/1/5283 5275/1/5275 +f 5285/1/5285 5284/1/5284 5282/1/5282 +f 5290/1/5290 5289/1/5289 5285/1/5285 +f 5296/1/5296 6514/1/6514 5290/1/5290 +f 5297/1/5297 5298/1/5298 5296/1/5296 +f 5364/1/5364 5297/1/5297 5365/1/5365 +f 5368/1/5368 5365/1/5365 5369/1/5369 +f 5369/1/5369 5376/1/5376 5368/1/5368 +f 5381/1/5381 5376/1/5376 5388/1/5388 +f 5382/1/5382 5381/1/5381 5388/1/5388 +f 5383/1/5383 5382/1/5382 5385/1/5385 +f 5387/1/5387 5383/1/5383 5385/1/5385 +f 6548/1/6548 5389/1/5389 6547/1/6547 +f 6547/1/6547 5389/1/5389 6396/1/6396 +f 6402/1/6402 6394/1/6394 6397/1/6397 +f 6400/1/6400 6402/1/6402 6397/1/6397 +f 6406/1/6406 6400/1/6400 6404/1/6404 +f 6430/1/6430 5387/1/5387 6406/1/6406 +f 6533/1/6533 6430/1/6430 5271/1/5271 +f 5270/1/5270 5271/1/5271 5265/1/5265 +f 5273/1/5273 5270/1/5270 5268/1/5268 +f 5274/1/5274 5268/1/5268 5269/1/5269 +f 5278/1/5278 5274/1/5274 5269/1/5269 +f 5281/1/5281 5279/1/5279 5278/1/5278 +f 5291/1/5291 5286/1/5286 5281/1/5281 +f 5293/1/5293 5291/1/5291 5294/1/5294 +f 5366/1/5366 5295/1/5295 5293/1/5293 +f 5373/1/5373 5366/1/5366 5374/1/5374 +f 5374/1/5374 5375/1/5375 5373/1/5373 +f 5389/1/5389 5375/1/5375 6396/1/6396 +f 6547/1/6547 6396/1/6396 6395/1/6395 +f 5371/1/5371 5370/1/5370 5372/1/5372 +f 6390/1/6390 6395/1/6395 6388/1/6388 +f 6393/1/6393 6390/1/6390 6389/1/6389 +f 6387/1/6387 6392/1/6392 6389/1/6389 +f 6386/1/6386 5370/1/5370 6385/1/6385 +f 6391/1/6391 6392/1/6392 6387/1/6387 +f 6427/1/6427 6392/1/6392 6426/1/6426 +f 6427/1/6427 6426/1/6426 6419/1/6419 +f 6423/1/6423 6419/1/6419 6424/1/6424 +f 6428/1/6428 6384/1/6384 6425/1/6425 +f 6385/1/6385 5394/1/5394 6384/1/6384 +f 5394/1/5394 5292/1/5292 5208/1/5208 +f 5206/1/5206 5214/1/5214 5210/1/5210 +f 5292/1/5292 5216/1/5216 5208/1/5208 +f 5216/1/5216 5280/1/5280 5217/1/5217 +f 5217/1/5217 5267/1/5267 5221/1/5221 +f 5267/1/5267 5222/1/5222 5221/1/5221 +f 5224/1/5224 5260/1/5260 5259/1/5259 +f 5224/1/5224 5259/1/5259 5223/1/5223 +f 5266/1/5266 5262/1/5262 5222/1/5222 +f 5264/1/5264 5261/1/5261 5262/1/5262 +f 5261/1/5261 5263/1/5263 5258/1/5258 +f 5260/1/5260 5257/1/5257 5259/1/5259 +f 5223/1/5223 5259/1/5259 5229/1/5229 +f 5219/1/5219 5224/1/5224 5223/1/5223 +f 5218/1/5218 5219/1/5219 5215/1/5215 +f 5214/1/5214 5215/1/5215 5210/1/5210 +f 5211/1/5211 5220/1/5220 5226/1/5226 +f 5226/1/5226 5225/1/5225 5227/1/5227 +f 5212/1/5212 5228/1/5228 5213/1/5213 +f 5235/1/5235 5234/1/5234 5238/1/5238 +f 5234/1/5234 5239/1/5239 5238/1/5238 +f 5238/1/5238 5239/1/5239 5243/1/5243 +f 5239/1/5239 5248/1/5248 5243/1/5243 +f 5237/1/5237 5248/1/5248 5239/1/5239 +f 5227/1/5227 5233/1/5233 5231/1/5231 +f 5234/1/5234 5237/1/5237 5239/1/5239 +f 5227/1/5227 5232/1/5232 5233/1/5233 +f 5237/1/5237 5253/1/5253 5248/1/5248 +f 5230/1/5230 5254/1/5254 5232/1/5232 +f 5256/1/5256 5255/1/5255 5254/1/5254 +f 5258/1/5258 6405/1/6405 5255/1/5255 +f 6405/1/6405 6401/1/6401 6403/1/6403 +f 6403/1/6403 6399/1/6399 6410/1/6410 +f 6427/1/6427 6419/1/6419 6410/1/6410 +f 6411/1/6411 6417/1/6417 6412/1/6412 +f 6408/1/6408 6412/1/6412 6413/1/6413 +f 6409/1/6409 6413/1/6413 6414/1/6414 +f 5252/1/5252 6407/1/6407 6409/1/6409 +f 5253/1/5253 5252/1/5252 5248/1/5248 +f 5243/1/5243 5248/1/5248 5246/1/5246 +f 5238/1/5238 5243/1/5243 5241/1/5241 +f 5240/1/5240 5241/1/5241 5242/1/5242 +f 5194/1/5194 5240/1/5240 5242/1/5242 +f 5196/1/5196 5201/1/5201 5194/1/5194 +f 5200/1/5200 5201/1/5201 5196/1/5196 +f 5202/1/5202 5236/1/5236 5200/1/5200 +f 5209/1/5209 5213/1/5213 5202/1/5202 +f 5206/1/5206 5210/1/5210 5209/1/5209 +f 5207/1/5207 5206/1/5206 5205/1/5205 +f 6381/1/6381 5207/1/5207 5205/1/5205 +f 6424/1/6424 6381/1/6381 6423/1/6423 +f 6423/1/6423 6418/1/6418 6419/1/6419 +f 6416/1/6416 6418/1/6418 6421/1/6421 +f 6382/1/6382 6379/1/6379 6383/1/6383 +f 6377/1/6377 6421/1/6421 6378/1/6378 +f 6371/1/6371 6367/1/6367 6377/1/6377 +f 6366/1/6366 6367/1/6367 6371/1/6371 +f 6368/1/6368 6366/1/6366 6369/1/6369 +f 6375/1/6375 6376/1/6376 6370/1/6370 +f 6379/1/6379 5204/1/5204 6376/1/6376 +f 5204/1/5204 5203/1/5203 5198/1/5198 +f 5198/1/5198 5197/1/5197 5193/1/5193 +f 5193/1/5193 5192/1/5192 5190/1/5190 +f 5190/1/5190 5189/1/5189 5185/1/5185 +f 5189/1/5189 5186/1/5186 5185/1/5185 +f 5183/1/5183 5187/1/5187 5178/1/5178 +f 5187/1/5187 5398/1/5398 5177/1/5177 +f 5195/1/5195 5245/1/5245 5186/1/5186 +f 5398/1/5398 5251/1/5251 5177/1/5177 +f 5244/1/5244 5247/1/5247 5245/1/5245 +f 5247/1/5247 5249/1/5249 5250/1/5250 +f 5250/1/5250 6415/1/6415 6361/1/6361 +f 5251/1/5251 5397/1/5397 5172/1/5172 +f 5172/1/5172 5171/1/5171 5175/1/5175 +f 5165/1/5165 5167/1/5167 5168/1/5168 +f 5171/1/5171 5173/1/5173 5176/1/5176 +f 5174/1/5174 5180/1/5180 5173/1/5173 +f 5174/1/5174 5405/1/5405 5180/1/5180 +f 6976/1/6976 5405/1/5405 5174/1/5174 +f 6964/1/6964 5405/1/5405 6976/1/6976 +f 6957/1/6957 6964/1/6964 6963/1/6963 +f 6977/1/6977 5405/1/5405 6964/1/6964 +f 5180/1/5180 5405/1/5405 6977/1/6977 +f 5404/1/5404 5179/1/5179 5180/1/5180 +f 5401/1/5401 5179/1/5179 5404/1/5404 +f 5184/1/5184 5182/1/5182 5401/1/5401 +f 5191/1/5191 5188/1/5188 5184/1/5184 +f 5199/1/5199 5191/1/5191 5400/1/5400 +f 6549/1/6549 5199/1/5199 5400/1/5400 +f 6373/1/6373 6380/1/6380 6549/1/6549 +f 6369/1/6369 6373/1/6373 6368/1/6368 +f 6372/1/6372 6365/1/6365 6368/1/6368 +f 6365/1/6365 6360/1/6360 6363/1/6363 +f 5081/1/5081 5083/1/5083 6364/1/6364 +f 6359/1/6359 6363/1/6363 6360/1/6360 +f 6359/1/6359 6358/1/6358 6361/1/6361 +f 5087/1/5087 5088/1/5088 5091/1/5091 +f 5086/1/5086 5088/1/5088 5087/1/5087 +f 5086/1/5086 5089/1/5089 5088/1/5088 +f 6358/1/6358 5170/1/5170 6429/1/6429 +f 5166/1/5166 5168/1/5168 5170/1/5170 +f 5088/1/5088 5089/1/5089 5095/1/5095 +f 5095/1/5095 5089/1/5089 5094/1/5094 +f 5095/1/5095 5094/1/5094 5096/1/5096 +f 5166/1/5166 5165/1/5165 5168/1/5168 +f 5165/1/5165 6975/1/6975 5167/1/5167 +f 6974/1/6974 6965/1/6965 6975/1/6975 +f 6974/1/6974 6971/1/6971 6965/1/6965 +f 6972/1/6972 6970/1/6970 6971/1/6971 +f 5169/1/5169 5095/1/5095 5164/1/5164 +f 5164/1/5164 5095/1/5095 5096/1/5096 +f 6972/1/6972 5163/1/5163 6978/1/6978 +f 6978/1/6978 6981/1/6981 6979/1/6979 +f 6985/1/6985 6983/1/6983 6981/1/6981 +f 7051/1/7051 6991/1/6991 6980/1/6980 +f 7051/1/7051 7046/1/7046 6991/1/6991 +f 7041/1/7041 7046/1/7046 7051/1/7051 +f 6985/1/6985 6990/1/6990 6983/1/6983 +f 7046/1/7046 6992/1/6992 6991/1/6991 +f 7046/1/7046 7042/1/7042 6992/1/6992 +f 7042/1/7042 6993/1/6993 6992/1/6992 +f 7042/1/7042 7045/1/7045 6993/1/6993 +f 6988/1/6988 6983/1/6983 6990/1/6990 +f 6984/1/6984 6983/1/6983 6988/1/6988 +f 6987/1/6987 6982/1/6982 6984/1/6984 +f 6986/1/6986 6982/1/6982 6987/1/6987 +f 6961/1/6961 6969/1/6969 6986/1/6986 +f 6956/1/6956 6960/1/6960 6961/1/6961 +f 6954/1/6954 6958/1/6958 6956/1/6956 +f 5402/1/5402 6955/1/6955 6954/1/6954 +f 5399/1/5399 5402/1/5402 5403/1/5403 +f 6550/1/6550 5403/1/5403 6553/1/6553 +f 6551/1/6551 6550/1/6550 6553/1/6553 +f 6552/1/6552 6374/1/6374 6551/1/6551 +f 6552/1/6552 5081/1/5081 6364/1/6364 +f 5075/1/5075 5079/1/5079 5074/1/5074 +f 5082/1/5082 5083/1/5083 5081/1/5081 +f 5075/1/5075 5080/1/5080 5079/1/5079 +f 5078/1/5078 5080/1/5080 5075/1/5075 +f 5082/1/5082 5084/1/5084 5083/1/5083 +f 5087/1/5087 5084/1/5084 5086/1/5086 +f 5078/1/5078 5085/1/5085 5080/1/5080 +f 5090/1/5090 5089/1/5089 5086/1/5086 +f 5090/1/5090 5094/1/5094 5089/1/5089 +f 5096/1/5096 5094/1/5094 5097/1/5097 +f 5098/1/5098 5107/1/5107 5097/1/5097 +f 5106/1/5106 5107/1/5107 5098/1/5098 +f 5092/1/5092 5085/1/5085 5093/1/5093 +f 5098/1/5098 5101/1/5101 5105/1/5105 +f 5098/1/5098 5105/1/5105 5106/1/5106 +f 5106/1/5106 5109/1/5109 5107/1/5107 +f 5110/1/5110 5109/1/5109 5111/1/5111 +f 5114/1/5114 5111/1/5111 5115/1/5115 +f 7051/1/7051 5114/1/5114 7041/1/7041 +f 7041/1/7041 7042/1/7042 7046/1/7046 +f 7038/1/7038 7043/1/7043 7042/1/7042 +f 7033/1/7033 7037/1/7037 7038/1/7038 +f 7039/1/7039 7040/1/7040 7031/1/7031 +f 7030/1/7030 7029/1/7029 7033/1/7033 +f 7029/1/7029 7032/1/7032 7033/1/7033 +f 7025/1/7025 7024/1/7024 7027/1/7027 +f 7022/1/7022 7024/1/7024 7025/1/7025 +f 7024/1/7024 7015/1/7015 7027/1/7027 +f 7017/1/7017 7015/1/7015 7024/1/7024 +f 7017/1/7017 7013/1/7013 7015/1/7015 +f 7013/1/7013 7012/1/7012 7015/1/7015 +f 7012/1/7012 7013/1/7013 7011/1/7011 +f 7029/1/7029 7028/1/7028 7032/1/7032 +f 7033/1/7033 7032/1/7032 7037/1/7037 +f 7038/1/7038 7037/1/7037 7043/1/7043 +f 7043/1/7043 7045/1/7045 7042/1/7042 +f 6999/1/6999 6993/1/6993 7045/1/7045 +f 6997/1/6997 6994/1/6994 6999/1/6999 +f 6995/1/6995 6994/1/6994 6997/1/6997 +f 6996/1/6996 6989/1/6989 6995/1/6995 +f 6556/1/6556 6959/1/6959 6996/1/6996 +f 6555/1/6555 6959/1/6959 6556/1/6556 +f 5065/1/5065 6554/1/6554 6555/1/6555 +f 5070/1/5070 6554/1/6554 5065/1/5065 +f 5071/1/5071 5072/1/5072 5070/1/5070 +f 5074/1/5074 5071/1/5071 5075/1/5075 +f 5076/1/5076 5078/1/5078 5075/1/5075 +f 5078/1/5078 5093/1/5093 5085/1/5085 +f 5077/1/5077 5073/1/5073 5066/1/5066 +f 5099/1/5099 5100/1/5100 5093/1/5093 +f 5067/1/5067 5066/1/5066 5064/1/5064 +f 5068/1/5068 5102/1/5102 5100/1/5100 +f 5069/1/5069 5064/1/5064 5061/1/5061 +f 5122/1/5122 5119/1/5119 5123/1/5123 +f 5103/1/5103 5104/1/5104 5102/1/5102 +f 5122/1/5122 5118/1/5118 5119/1/5119 +f 5108/1/5108 5104/1/5104 5112/1/5112 +f 5108/1/5108 5112/1/5112 5113/1/5113 +f 5116/1/5116 5113/1/5113 5117/1/5117 +f 5129/1/5129 5148/1/5148 5121/1/5121 +f 5116/1/5116 5117/1/5117 5150/1/5150 +f 5150/1/5150 5151/1/5151 5116/1/5116 +f 5156/1/5156 5152/1/5152 5147/1/5147 +f 5154/1/5154 5151/1/5151 5153/1/5153 +f 7031/1/7031 5153/1/5153 7026/1/7026 +f 7025/1/7025 7026/1/7026 7022/1/7022 +f 7022/1/7022 7017/1/7017 7024/1/7024 +f 7017/1/7017 7016/1/7016 7013/1/7013 +f 7020/1/7020 7018/1/7018 7019/1/7019 +f 7020/1/7020 5055/1/5055 7018/1/7018 +f 5055/1/5055 7010/1/7010 7018/1/7018 +f 7011/1/7011 7013/1/7013 7016/1/7016 +f 7007/1/7007 7012/1/7012 7011/1/7011 +f 7015/1/7015 7012/1/7012 7014/1/7014 +f 7050/1/7050 7034/1/7034 7014/1/7014 +f 7049/1/7049 7034/1/7034 7050/1/7050 +f 7048/1/7048 7035/1/7035 7049/1/7049 +f 7047/1/7047 7036/1/7036 7048/1/7048 +f 7003/1/7003 7044/1/7044 7047/1/7047 +f 7000/1/7000 7001/1/7001 7003/1/7003 +f 5059/1/5059 6998/1/6998 7000/1/7000 +f 5060/1/5060 5059/1/5059 5058/1/5058 +f 5061/1/5061 5062/1/5062 5060/1/5060 +f 5123/1/5123 5061/1/5061 5122/1/5122 +f 5120/1/5120 5118/1/5118 5122/1/5122 +f 5120/1/5120 5121/1/5121 5118/1/5118 +f 5063/1/5063 5125/1/5125 5124/1/5124 +f 5126/1/5126 5129/1/5129 5121/1/5121 +f 5131/1/5131 5148/1/5148 5129/1/5129 +f 5128/1/5128 5125/1/5125 5127/1/5127 +f 5135/1/5135 5131/1/5131 5130/1/5130 +f 5135/1/5135 5149/1/5149 5131/1/5131 +f 5156/1/5156 5147/1/5147 5149/1/5149 +f 5156/1/5156 5157/1/5157 5152/1/5152 +f 5161/1/5161 5158/1/5158 5159/1/5159 +f 5155/1/5155 5152/1/5152 5157/1/5157 +f 5155/1/5155 7021/1/7021 7023/1/7023 +f 7019/1/7019 7021/1/7021 7020/1/7020 +f 5055/1/5055 7020/1/7020 4999/1/4999 +f 4999/1/4999 5054/1/5054 5055/1/5055 +f 5054/1/5054 4994/1/4994 5055/1/5055 +f 4999/1/4999 5053/1/5053 5054/1/5054 +f 4993/1/4993 5054/1/5054 5053/1/5053 +f 4999/1/4999 4997/1/4997 5053/1/5053 +f 4997/1/4997 4992/1/4992 5053/1/5053 +f 4988/1/4988 5053/1/5053 4992/1/4992 +f 4991/1/4991 4992/1/4992 4997/1/4997 +f 4997/1/4997 4995/1/4995 4991/1/4991 +f 4995/1/4995 4996/1/4996 4991/1/4991 +f 4990/1/4990 4991/1/4991 4996/1/4996 +f 4990/1/4990 4996/1/4996 5001/1/5001 +f 4985/1/4985 4990/1/4990 5001/1/5001 +f 4985/1/4985 5001/1/5001 5002/1/5002 +f 4985/1/4985 5002/1/5002 5007/1/5007 +f 5007/1/5007 5002/1/5002 5006/1/5006 +f 5007/1/5007 5006/1/5006 5008/1/5008 +f 4986/1/4986 5007/1/5007 5008/1/5008 +f 5008/1/5008 5006/1/5006 5009/1/5009 +f 5008/1/5008 5009/1/5009 5011/1/5011 +f 5012/1/5012 5008/1/5008 5011/1/5011 +f 5012/1/5012 5011/1/5011 5013/1/5013 +f 5012/1/5012 5013/1/5013 5014/1/5014 +f 5014/1/5014 5013/1/5013 5017/1/5017 +f 5014/1/5014 5017/1/5017 5019/1/5019 +f 5020/1/5020 5014/1/5014 5019/1/5019 +f 5020/1/5020 5019/1/5019 5037/1/5037 +f 5045/1/5045 5020/1/5020 5037/1/5037 +f 5045/1/5045 5037/1/5037 5446/1/5446 +f 5422/1/5422 5045/1/5045 5446/1/5446 +f 5422/1/5422 5446/1/5446 5447/1/5447 +f 5449/1/5449 5422/1/5422 5447/1/5447 +f 5449/1/5449 5447/1/5447 5450/1/5450 +f 5450/1/5450 5452/1/5452 5449/1/5449 +f 5449/1/5449 5452/1/5452 5448/1/5448 +f 5452/1/5452 5421/1/5421 5448/1/5448 +f 5448/1/5448 5421/1/5421 5420/1/5420 +f 5420/1/5420 5422/1/5422 5448/1/5448 +f 5419/1/5419 5422/1/5422 5420/1/5420 +f 5420/1/5420 5414/1/5414 5419/1/5419 +f 5419/1/5419 5414/1/5414 5413/1/5413 +f 5419/1/5419 5413/1/5413 5415/1/5415 +f 5415/1/5415 5418/1/5418 5419/1/5419 +f 5413/1/5413 5414/1/5414 5408/1/5408 +f 5413/1/5413 5408/1/5408 5412/1/5412 +f 5414/1/5414 5030/1/5030 5408/1/5408 +f 5408/1/5408 5030/1/5030 5025/1/5025 +f 5025/1/5025 5406/1/5406 5408/1/5408 +f 5406/1/5406 5025/1/5025 5024/1/5024 +f 5406/1/5406 5024/1/5024 5444/1/5444 +f 5024/1/5024 5004/1/5004 5444/1/5444 +f 5004/1/5004 5024/1/5024 5016/1/5016 +f 5016/1/5016 5010/1/5010 5004/1/5004 +f 5013/1/5013 5010/1/5010 5016/1/5016 +f 5013/1/5013 5016/1/5016 5018/1/5018 +f 5016/1/5016 5024/1/5024 5018/1/5018 +f 5018/1/5018 5024/1/5024 5022/1/5022 +f 5017/1/5017 5018/1/5018 5022/1/5022 +f 5017/1/5017 5022/1/5022 5023/1/5023 +f 5017/1/5017 5023/1/5023 5021/1/5021 +f 5021/1/5021 5023/1/5023 5026/1/5026 +f 5021/1/5021 5026/1/5026 5027/1/5027 +f 5019/1/5019 5021/1/5021 5027/1/5027 +f 5019/1/5019 5027/1/5027 5031/1/5031 +f 5031/1/5031 5027/1/5027 5032/1/5032 +f 5031/1/5031 5032/1/5032 5036/1/5036 +f 5031/1/5031 5036/1/5036 5038/1/5038 +f 5031/1/5031 5038/1/5038 5037/1/5037 +f 5037/1/5037 5038/1/5038 5043/1/5043 +f 5037/1/5037 5043/1/5043 5044/1/5044 +f 5043/1/5043 5451/1/5451 5044/1/5044 +f 5044/1/5044 5451/1/5451 5447/1/5447 +f 5451/1/5451 5043/1/5043 5052/1/5052 +f 5052/1/5052 5450/1/5450 5451/1/5451 +f 5450/1/5450 5052/1/5052 7420/1/7420 +f 5052/1/5052 5421/1/5421 7420/1/7420 +f 5052/1/5052 5035/1/5035 5421/1/5421 +f 5421/1/5421 5035/1/5035 5414/1/5414 +f 5052/1/5052 5039/1/5039 5035/1/5035 +f 5034/1/5034 5035/1/5035 5039/1/5039 +f 5034/1/5034 5039/1/5039 5036/1/5036 +f 5033/1/5033 5034/1/5034 5036/1/5036 +f 5033/1/5033 5030/1/5030 5034/1/5034 +f 5030/1/5030 5033/1/5033 5029/1/5029 +f 5032/1/5032 5029/1/5029 5033/1/5033 +f 5036/1/5036 5039/1/5039 5040/1/5040 +f 5039/1/5039 5041/1/5041 5040/1/5040 +f 5041/1/5041 5042/1/5042 5040/1/5040 +f 5040/1/5040 5042/1/5042 5043/1/5043 +f 5041/1/5041 5052/1/5052 5042/1/5042 +f 5030/1/5030 5035/1/5035 5034/1/5034 +f 5039/1/5039 5052/1/5052 5041/1/5041 +f 5043/1/5043 5042/1/5042 5052/1/5052 +f 5038/1/5038 5040/1/5040 5043/1/5043 +f 5036/1/5036 5040/1/5040 5038/1/5038 +f 5032/1/5032 5033/1/5033 5036/1/5036 +f 5027/1/5027 5029/1/5029 5032/1/5032 +f 5027/1/5027 5028/1/5028 5029/1/5029 +f 5028/1/5028 5025/1/5025 5029/1/5029 +f 5026/1/5026 5025/1/5025 5028/1/5028 +f 5027/1/5027 5026/1/5026 5028/1/5028 +f 5025/1/5025 5026/1/5026 5023/1/5023 +f 5022/1/5022 5024/1/5024 5023/1/5023 +f 5023/1/5023 5024/1/5024 5025/1/5025 +f 5029/1/5029 5025/1/5025 5030/1/5030 +f 5414/1/5414 5035/1/5035 5030/1/5030 +f 5419/1/5419 5418/1/5418 5422/1/5422 +f 5420/1/5420 5421/1/5421 5414/1/5414 +f 5452/1/5452 7420/1/7420 5421/1/5421 +f 5452/1/5452 5450/1/5450 7420/1/7420 +f 5450/1/5450 5447/1/5447 5451/1/5451 +f 5448/1/5448 5422/1/5422 5449/1/5449 +f 5447/1/5447 5446/1/5446 5044/1/5044 +f 5418/1/5418 5045/1/5045 5422/1/5422 +f 5418/1/5418 5046/1/5046 5045/1/5045 +f 5417/1/5417 5046/1/5046 5418/1/5418 +f 5446/1/5446 5037/1/5037 5044/1/5044 +f 5046/1/5046 5020/1/5020 5045/1/5045 +f 5046/1/5046 5015/1/5015 5020/1/5020 +f 5037/1/5037 5019/1/5019 5031/1/5031 +f 5015/1/5015 5014/1/5014 5020/1/5020 +f 5019/1/5019 5017/1/5017 5021/1/5021 +f 5013/1/5013 5018/1/5018 5017/1/5017 +f 5011/1/5011 5010/1/5010 5013/1/5013 +f 5011/1/5011 5009/1/5009 5010/1/5010 +f 5009/1/5009 5005/1/5005 5010/1/5010 +f 5006/1/5006 5005/1/5005 5009/1/5009 +f 5002/1/5002 5003/1/5003 5006/1/5006 +f 5001/1/5001 4998/1/4998 5002/1/5002 +f 5001/1/5001 4996/1/4996 4998/1/4998 +f 4989/1/4989 4991/1/4991 4990/1/4990 +f 4989/1/4989 4992/1/4992 4991/1/4991 +f 4997/1/4997 4999/1/4999 4995/1/4995 +f 5158/1/5158 5161/1/5161 5162/1/5162 +f 5141/1/5141 5441/1/5441 5162/1/5162 +f 5442/1/5442 4995/1/4995 4999/1/4999 +f 4996/1/4996 4995/1/4995 4998/1/4998 +f 5002/1/5002 4998/1/4998 5003/1/5003 +f 5006/1/5006 5003/1/5003 5005/1/5005 +f 5004/1/5004 5010/1/5010 5005/1/5005 +f 5000/1/5000 5437/1/5437 5434/1/5434 +f 5004/1/5004 5438/1/5438 5444/1/5444 +f 5406/1/5406 5444/1/5444 5410/1/5410 +f 5406/1/5406 5407/1/5407 5408/1/5408 +f 5412/1/5412 5408/1/5408 5407/1/5407 +f 5415/1/5415 5413/1/5413 5412/1/5412 +f 5415/1/5415 5417/1/5417 5418/1/5418 +f 5409/1/5409 5416/1/5416 5411/1/5411 +f 5417/1/5417 5047/1/5047 5046/1/5046 +f 5423/1/5423 5048/1/5048 5416/1/5416 +f 5423/1/5423 5049/1/5049 5048/1/5048 +f 5047/1/5047 5015/1/5015 5046/1/5046 +f 5049/1/5049 4982/1/4982 5048/1/5048 +f 5015/1/5015 5012/1/5012 5014/1/5014 +f 4986/1/4986 5008/1/5008 5012/1/5012 +f 4986/1/4986 4985/1/4985 5007/1/5007 +f 4984/1/4984 4990/1/4990 4985/1/4985 +f 4984/1/4984 4989/1/4989 4990/1/4990 +f 4988/1/4988 4992/1/4992 4989/1/4989 +f 4993/1/4993 5053/1/5053 4988/1/4988 +f 4994/1/4994 5054/1/5054 4993/1/4993 +f 5055/1/5055 4994/1/4994 7010/1/7010 +f 7006/1/7006 7009/1/7009 7010/1/7010 +f 4972/1/4972 7008/1/7008 7006/1/7006 +f 7004/1/7004 7005/1/7005 4972/1/4972 +f 4978/1/4978 7002/1/7002 7004/1/7004 +f 5056/1/5056 5057/1/5057 4978/1/4978 +f 5125/1/5125 5056/1/5056 5127/1/5127 +f 5132/1/5132 5127/1/5127 5133/1/5133 +f 5136/1/5136 5137/1/5137 5133/1/5133 +f 5141/1/5141 5160/1/5160 5137/1/5137 +f 5143/1/5143 5441/1/5441 5141/1/5141 +f 5142/1/5142 5440/1/5440 5143/1/5143 +f 5142/1/5142 5140/1/5140 5144/1/5144 +f 5138/1/5138 5134/1/5134 5139/1/5139 +f 5134/1/5134 4977/1/4977 4976/1/4976 +f 4976/1/4976 4975/1/4975 4971/1/4971 +f 5140/1/5140 4979/1/4979 5144/1/5144 +f 5432/1/5432 5144/1/5144 5145/1/5145 +f 5145/1/5145 5431/1/5431 5433/1/5433 +f 5430/1/5430 5434/1/5434 5431/1/5431 +f 5436/1/5436 5434/1/5434 5430/1/5430 +f 5445/1/5445 5443/1/5443 5436/1/5436 +f 5425/1/5425 5445/1/5445 5428/1/5428 +f 5428/1/5428 5424/1/5424 5425/1/5425 +f 5429/1/5429 5146/1/5146 5427/1/5427 +f 5424/1/5424 5049/1/5049 5423/1/5423 +f 5051/1/5051 5050/1/5050 5146/1/5146 +f 5049/1/5049 4981/1/4981 4982/1/4982 +f 5051/1/5051 4973/1/4973 5050/1/5050 +f 4981/1/4981 4980/1/4980 4982/1/4982 +f 4970/1/4970 4983/1/4983 4980/1/4980 +f 4971/1/4971 4968/1/4968 4973/1/4973 +f 4970/1/4970 4969/1/4969 4987/1/4987 +f 4968/1/4968 4974/1/4974 4969/1/4969 +f 7421/1/7421 7422/1/7422 7423/1/7423 +f 7421/1/7421 7423/1/7423 7424/1/7424 +f 7421/1/7421 7424/1/7424 7444/1/7444 +f 7444/1/7444 7526/1/7526 7421/1/7421 +f 7421/1/7421 7526/1/7526 7525/1/7525 +f 7421/1/7421 7525/1/7525 7425/1/7425 +f 7425/1/7425 7525/1/7525 7524/1/7524 +f 7425/1/7425 7524/1/7524 7427/1/7427 +f 7427/1/7427 7426/1/7426 7425/1/7425 +f 7425/1/7425 7426/1/7426 7422/1/7422 +f 7503/1/7503 7422/1/7422 7426/1/7426 +f 7503/1/7503 7426/1/7426 7504/1/7504 +f 7508/1/7508 7503/1/7503 7504/1/7504 +f 7508/1/7508 7504/1/7504 7505/1/7505 +f 7505/1/7505 7506/1/7506 7508/1/7508 +f 7508/1/7508 7506/1/7506 7507/1/7507 +f 7508/1/7508 7507/1/7507 7490/1/7490 +f 7490/1/7490 7489/1/7489 7508/1/7508 +f 7508/1/7508 7489/1/7489 7487/1/7487 +f 7508/1/7508 7487/1/7487 7486/1/7486 +f 7486/1/7486 7484/1/7484 7508/1/7508 +f 7508/1/7508 7484/1/7484 7483/1/7483 +f 7508/1/7508 7483/1/7483 7482/1/7482 +f 7482/1/7482 7481/1/7481 7508/1/7508 +f 7508/1/7508 7481/1/7481 7480/1/7480 +f 7508/1/7508 7480/1/7480 7479/1/7479 +f 7479/1/7479 7478/1/7478 7508/1/7508 +f 7508/1/7508 7478/1/7478 7477/1/7477 +f 7508/1/7508 7477/1/7477 7476/1/7476 +f 7476/1/7476 7475/1/7475 7508/1/7508 +f 7508/1/7508 7475/1/7475 7473/1/7473 +f 7508/1/7508 7473/1/7473 7474/1/7474 +f 7474/1/7474 7491/1/7491 7508/1/7508 +f 7508/1/7508 7491/1/7491 7492/1/7492 +f 7508/1/7508 7492/1/7492 7493/1/7493 +f 7493/1/7493 7494/1/7494 7508/1/7508 +f 7508/1/7508 7494/1/7494 7495/1/7495 +f 7508/1/7508 7495/1/7495 7496/1/7496 +f 7496/1/7496 7497/1/7497 7508/1/7508 +f 7508/1/7508 7497/1/7497 7498/1/7498 +f 7508/1/7508 7498/1/7498 7499/1/7499 +f 7499/1/7499 7500/1/7500 7508/1/7508 +f 7508/1/7508 7500/1/7500 7501/1/7501 +f 7508/1/7508 7501/1/7501 7502/1/7502 +f 7501/1/7501 7423/1/7423 7502/1/7502 +f 7500/1/7500 7424/1/7424 7501/1/7501 +f 7500/1/7500 7445/1/7445 7424/1/7424 +f 7499/1/7499 7445/1/7445 7500/1/7500 +f 7499/1/7499 7446/1/7446 7445/1/7445 +f 7444/1/7444 7445/1/7445 7446/1/7446 +f 7444/1/7444 7446/1/7446 7447/1/7447 +f 7447/1/7447 7527/1/7527 7444/1/7444 +f 7447/1/7447 7530/1/7530 7527/1/7527 +f 7511/1/7511 7527/1/7527 7530/1/7530 +f 7511/1/7511 7530/1/7530 7528/1/7528 +f 7528/1/7528 7529/1/7529 7511/1/7511 +f 7511/1/7511 7529/1/7529 7512/1/7512 +f 7511/1/7511 7512/1/7512 7509/1/7509 +f 7509/1/7509 7510/1/7510 7511/1/7511 +f 7511/1/7511 7510/1/7510 7513/1/7513 +f 7511/1/7511 7513/1/7513 7514/1/7514 +f 7514/1/7514 7515/1/7515 7511/1/7511 +f 7511/1/7511 7515/1/7515 7516/1/7516 +f 7511/1/7511 7516/1/7516 7517/1/7517 +f 7517/1/7517 7518/1/7518 7511/1/7511 +f 7511/1/7511 7518/1/7518 7519/1/7519 +f 7511/1/7511 7519/1/7519 7520/1/7520 +f 7520/1/7520 7521/1/7521 7511/1/7511 +f 7511/1/7511 7521/1/7521 7522/1/7522 +f 7511/1/7511 7522/1/7522 7523/1/7523 +f 7523/1/7523 7524/1/7524 7511/1/7511 +f 7430/1/7430 7523/1/7523 7522/1/7522 +f 7430/1/7430 7522/1/7522 7432/1/7432 +f 7432/1/7432 7431/1/7431 7430/1/7430 +f 7430/1/7430 7431/1/7431 7429/1/7429 +f 7430/1/7430 7429/1/7429 7427/1/7427 +f 7429/1/7429 7428/1/7428 7427/1/7427 +f 7505/1/7505 7428/1/7428 7429/1/7429 +f 7506/1/7506 7429/1/7429 7431/1/7431 +f 7432/1/7432 7433/1/7433 7431/1/7431 +f 7507/1/7507 7431/1/7431 7433/1/7433 +f 7432/1/7432 7435/1/7435 7433/1/7433 +f 7490/1/7490 7433/1/7433 7435/1/7435 +f 7434/1/7434 7435/1/7435 7432/1/7432 +f 7432/1/7432 7521/1/7521 7434/1/7434 +f 7434/1/7434 7437/1/7437 7435/1/7435 +f 7489/1/7489 7435/1/7435 7437/1/7437 +f 7436/1/7436 7437/1/7437 7434/1/7434 +f 7434/1/7434 7520/1/7520 7436/1/7436 +f 7436/1/7436 7488/1/7488 7437/1/7437 +f 7487/1/7487 7437/1/7437 7488/1/7488 +f 7436/1/7436 7439/1/7439 7488/1/7488 +f 7486/1/7486 7488/1/7488 7439/1/7439 +f 7438/1/7438 7439/1/7439 7436/1/7436 +f 7436/1/7436 7519/1/7519 7438/1/7438 +f 7438/1/7438 7485/1/7485 7439/1/7439 +f 7484/1/7484 7439/1/7439 7485/1/7485 +f 7438/1/7438 7441/1/7441 7485/1/7485 +f 7483/1/7483 7485/1/7485 7441/1/7441 +f 7440/1/7440 7441/1/7441 7438/1/7438 +f 7438/1/7438 7518/1/7518 7440/1/7440 +f 7440/1/7440 7443/1/7443 7441/1/7441 +f 7482/1/7482 7441/1/7441 7443/1/7443 +f 7442/1/7442 7443/1/7443 7440/1/7440 +f 7440/1/7440 7517/1/7517 7442/1/7442 +f 7442/1/7442 7454/1/7454 7443/1/7443 +f 7481/1/7481 7443/1/7443 7454/1/7454 +f 7442/1/7442 7453/1/7453 7454/1/7454 +f 7480/1/7480 7454/1/7454 7453/1/7453 +f 7450/1/7450 7453/1/7453 7442/1/7442 +f 7442/1/7442 7516/1/7516 7450/1/7450 +f 7450/1/7450 7449/1/7449 7453/1/7453 +f 7479/1/7479 7453/1/7453 7449/1/7449 +f 7448/1/7448 7449/1/7449 7450/1/7450 +f 7450/1/7450 7515/1/7515 7448/1/7448 +f 7448/1/7448 7472/1/7472 7449/1/7449 +f 7478/1/7478 7449/1/7449 7472/1/7472 +f 7448/1/7448 7452/1/7452 7472/1/7472 +f 7477/1/7477 7472/1/7472 7452/1/7452 +f 7451/1/7451 7452/1/7452 7448/1/7448 +f 7448/1/7448 7514/1/7514 7451/1/7451 +f 7451/1/7451 7456/1/7456 7452/1/7452 +f 7476/1/7476 7452/1/7452 7456/1/7456 +f 7455/1/7455 7456/1/7456 7451/1/7451 +f 7451/1/7451 7513/1/7513 7455/1/7455 +f 7455/1/7455 7459/1/7459 7456/1/7456 +f 7475/1/7475 7456/1/7456 7459/1/7459 +f 7455/1/7455 7458/1/7458 7459/1/7459 +f 7473/1/7473 7459/1/7459 7458/1/7458 +f 7457/1/7457 7458/1/7458 7455/1/7455 +f 7455/1/7455 7510/1/7510 7457/1/7457 +f 7457/1/7457 7461/1/7461 7458/1/7458 +f 7474/1/7474 7458/1/7458 7461/1/7461 +f 7460/1/7460 7461/1/7461 7457/1/7457 +f 7462/1/7462 7460/1/7460 7457/1/7457 +f 7457/1/7457 7509/1/7509 7462/1/7462 +f 7462/1/7462 7463/1/7463 7460/1/7460 +f 7492/1/7492 7460/1/7460 7463/1/7463 +f 7464/1/7464 7463/1/7463 7462/1/7462 +f 7462/1/7462 7512/1/7512 7464/1/7464 +f 7464/1/7464 7465/1/7465 7463/1/7463 +f 7493/1/7493 7463/1/7463 7465/1/7465 +f 7466/1/7466 7465/1/7465 7464/1/7464 +f 7467/1/7467 7466/1/7466 7464/1/7464 +f 7464/1/7464 7529/1/7529 7467/1/7467 +f 7467/1/7467 7468/1/7468 7466/1/7466 +f 7495/1/7495 7466/1/7466 7468/1/7468 +f 7469/1/7469 7468/1/7468 7467/1/7467 +f 7467/1/7467 7528/1/7528 7469/1/7469 +f 7469/1/7469 7470/1/7470 7468/1/7468 +f 7496/1/7496 7468/1/7468 7470/1/7470 +f 7469/1/7469 7471/1/7471 7470/1/7470 +f 7497/1/7497 7470/1/7470 7471/1/7471 +f 7447/1/7447 7471/1/7471 7469/1/7469 +f 7494/1/7494 7465/1/7465 7466/1/7466 +f 7491/1/7491 7461/1/7461 7460/1/7460 +f 7427/1/7427 7523/1/7523 7430/1/7430 +f 7432/1/7432 7522/1/7522 7521/1/7521 +f 7434/1/7434 7521/1/7521 7520/1/7520 +f 7436/1/7436 7520/1/7520 7519/1/7519 +f 7438/1/7438 7519/1/7519 7518/1/7518 +f 7440/1/7440 7518/1/7518 7517/1/7517 +f 7442/1/7442 7517/1/7517 7516/1/7516 +f 7450/1/7450 7516/1/7516 7515/1/7515 +f 7448/1/7448 7515/1/7515 7514/1/7514 +f 7451/1/7451 7514/1/7514 7513/1/7513 +f 7455/1/7455 7513/1/7513 7510/1/7510 +f 7457/1/7457 7510/1/7510 7509/1/7509 +f 7462/1/7462 7509/1/7509 7512/1/7512 +f 7464/1/7464 7512/1/7512 7529/1/7529 +f 7467/1/7467 7529/1/7529 7528/1/7528 +f 7469/1/7469 7528/1/7528 7530/1/7530 +f 7526/1/7526 7527/1/7527 7511/1/7511 +f 7469/1/7469 7530/1/7530 7447/1/7447 +f 7447/1/7447 7446/1/7446 7471/1/7471 +f 7498/1/7498 7471/1/7471 7446/1/7446 +f 7498/1/7498 7446/1/7446 7499/1/7499 +f 7497/1/7497 7471/1/7471 7498/1/7498 +f 7496/1/7496 7470/1/7470 7497/1/7497 +f 7495/1/7495 7468/1/7468 7496/1/7496 +f 7494/1/7494 7466/1/7466 7495/1/7495 +f 7493/1/7493 7465/1/7465 7494/1/7494 +f 7492/1/7492 7463/1/7463 7493/1/7493 +f 7491/1/7491 7460/1/7460 7492/1/7492 +f 7474/1/7474 7461/1/7461 7491/1/7491 +f 7473/1/7473 7458/1/7458 7474/1/7474 +f 7475/1/7475 7459/1/7459 7473/1/7473 +f 7476/1/7476 7456/1/7456 7475/1/7475 +f 7477/1/7477 7452/1/7452 7476/1/7476 +f 7478/1/7478 7472/1/7472 7477/1/7477 +f 7479/1/7479 7449/1/7449 7478/1/7478 +f 7480/1/7480 7453/1/7453 7479/1/7479 +f 7481/1/7481 7454/1/7454 7480/1/7480 +f 7482/1/7482 7443/1/7443 7481/1/7481 +f 7483/1/7483 7441/1/7441 7482/1/7482 +f 7484/1/7484 7485/1/7485 7483/1/7483 +f 7486/1/7486 7439/1/7439 7484/1/7484 +f 7487/1/7487 7488/1/7488 7486/1/7486 +f 7489/1/7489 7437/1/7437 7487/1/7487 +f 7490/1/7490 7435/1/7435 7489/1/7489 +f 7507/1/7507 7433/1/7433 7490/1/7490 +f 7506/1/7506 7431/1/7431 7507/1/7507 +f 7505/1/7505 7429/1/7429 7506/1/7506 +f 7504/1/7504 7428/1/7428 7505/1/7505 +f 7502/1/7502 7503/1/7503 7508/1/7508 +f 7504/1/7504 7426/1/7426 7428/1/7428 +f 7502/1/7502 7422/1/7422 7503/1/7503 +f 7427/1/7427 7428/1/7428 7426/1/7426 +f 7427/1/7427 7524/1/7524 7523/1/7523 +f 7511/1/7511 7524/1/7524 7525/1/7525 +f 7511/1/7511 7525/1/7525 7526/1/7526 +f 7444/1/7444 7527/1/7527 7526/1/7526 +f 7444/1/7444 7424/1/7424 7445/1/7445 +f 7501/1/7501 7424/1/7424 7423/1/7423 +f 7502/1/7502 7423/1/7423 7422/1/7422 +f 7425/1/7425 7422/1/7422 7421/1/7421 +f 7531/1/7531 7532/1/7532 7533/1/7533 +f 7531/1/7531 7533/1/7533 7534/1/7534 +f 7531/1/7531 7534/1/7534 7535/1/7535 +f 7535/1/7535 7636/1/7636 7531/1/7531 +f 7531/1/7531 7636/1/7636 7635/1/7635 +f 7531/1/7531 7635/1/7635 7536/1/7536 +f 7536/1/7536 7635/1/7635 7634/1/7634 +f 7536/1/7536 7634/1/7634 7538/1/7538 +f 7538/1/7538 7537/1/7537 7536/1/7536 +f 7536/1/7536 7537/1/7537 7532/1/7532 +f 7612/1/7612 7532/1/7532 7537/1/7537 +f 7612/1/7612 7537/1/7537 7613/1/7613 +f 7618/1/7618 7612/1/7612 7613/1/7613 +f 7618/1/7618 7613/1/7613 7614/1/7614 +f 7614/1/7614 7615/1/7615 7618/1/7618 +f 7618/1/7618 7615/1/7615 7616/1/7616 +f 7618/1/7618 7616/1/7616 7617/1/7617 +f 7617/1/7617 7601/1/7601 7618/1/7618 +f 7618/1/7618 7601/1/7601 7600/1/7600 +f 7618/1/7618 7600/1/7600 7599/1/7599 +f 7599/1/7599 7598/1/7598 7618/1/7618 +f 7618/1/7618 7598/1/7598 7597/1/7597 +f 7618/1/7618 7597/1/7597 7596/1/7596 +f 7596/1/7596 7595/1/7595 7618/1/7618 +f 7618/1/7618 7595/1/7595 7594/1/7594 +f 7618/1/7618 7594/1/7594 7593/1/7593 +f 7593/1/7593 7592/1/7592 7618/1/7618 +f 7618/1/7618 7592/1/7592 7591/1/7591 +f 7618/1/7618 7591/1/7591 7590/1/7590 +f 7590/1/7590 7587/1/7587 7618/1/7618 +f 7618/1/7618 7587/1/7587 7585/1/7585 +f 7618/1/7618 7585/1/7585 7586/1/7586 +f 7586/1/7586 7588/1/7588 7618/1/7618 +f 7618/1/7618 7588/1/7588 7589/1/7589 +f 7618/1/7618 7589/1/7589 7602/1/7602 +f 7602/1/7602 7603/1/7603 7618/1/7618 +f 7618/1/7618 7603/1/7603 7604/1/7604 +f 7618/1/7618 7604/1/7604 7605/1/7605 +f 7605/1/7605 7606/1/7606 7618/1/7618 +f 7618/1/7618 7606/1/7606 7607/1/7607 +f 7618/1/7618 7607/1/7607 7608/1/7608 +f 7608/1/7608 7609/1/7609 7618/1/7618 +f 7618/1/7618 7609/1/7609 7610/1/7610 +f 7618/1/7618 7610/1/7610 7611/1/7611 +f 7610/1/7610 7533/1/7533 7611/1/7611 +f 7609/1/7609 7534/1/7534 7610/1/7610 +f 7609/1/7609 7584/1/7584 7534/1/7534 +f 7608/1/7608 7584/1/7584 7609/1/7609 +f 7608/1/7608 7583/1/7583 7584/1/7584 +f 7535/1/7535 7584/1/7584 7583/1/7583 +f 7535/1/7535 7583/1/7583 7580/1/7580 +f 7580/1/7580 7637/1/7637 7535/1/7535 +f 7580/1/7580 7640/1/7640 7637/1/7637 +f 7621/1/7621 7637/1/7637 7640/1/7640 +f 7621/1/7621 7640/1/7640 7638/1/7638 +f 7638/1/7638 7639/1/7639 7621/1/7621 +f 7621/1/7621 7639/1/7639 7622/1/7622 +f 7621/1/7621 7622/1/7622 7619/1/7619 +f 7619/1/7619 7620/1/7620 7621/1/7621 +f 7621/1/7621 7620/1/7620 7623/1/7623 +f 7621/1/7621 7623/1/7623 7624/1/7624 +f 7624/1/7624 7625/1/7625 7621/1/7621 +f 7621/1/7621 7625/1/7625 7626/1/7626 +f 7621/1/7621 7626/1/7626 7627/1/7627 +f 7627/1/7627 7628/1/7628 7621/1/7621 +f 7621/1/7621 7628/1/7628 7629/1/7629 +f 7621/1/7621 7629/1/7629 7630/1/7630 +f 7630/1/7630 7631/1/7631 7621/1/7621 +f 7621/1/7621 7631/1/7631 7632/1/7632 +f 7621/1/7621 7632/1/7632 7633/1/7633 +f 7633/1/7633 7634/1/7634 7621/1/7621 +f 7540/1/7540 7633/1/7633 7632/1/7632 +f 7540/1/7540 7632/1/7632 7542/1/7542 +f 7542/1/7542 7543/1/7543 7540/1/7540 +f 7540/1/7540 7543/1/7543 7541/1/7541 +f 7540/1/7540 7541/1/7541 7538/1/7538 +f 7541/1/7541 7539/1/7539 7538/1/7538 +f 7614/1/7614 7539/1/7539 7541/1/7541 +f 7615/1/7615 7541/1/7541 7543/1/7543 +f 7542/1/7542 7546/1/7546 7543/1/7543 +f 7616/1/7616 7543/1/7543 7546/1/7546 +f 7542/1/7542 7545/1/7545 7546/1/7546 +f 7617/1/7617 7546/1/7546 7545/1/7545 +f 7544/1/7544 7545/1/7545 7542/1/7542 +f 7542/1/7542 7631/1/7631 7544/1/7544 +f 7544/1/7544 7548/1/7548 7545/1/7545 +f 7601/1/7601 7545/1/7545 7548/1/7548 +f 7547/1/7547 7548/1/7548 7544/1/7544 +f 7544/1/7544 7630/1/7630 7547/1/7547 +f 7547/1/7547 7551/1/7551 7548/1/7548 +f 7600/1/7600 7548/1/7548 7551/1/7551 +f 7547/1/7547 7550/1/7550 7551/1/7551 +f 7599/1/7599 7551/1/7551 7550/1/7550 +f 7549/1/7549 7550/1/7550 7547/1/7547 +f 7547/1/7547 7629/1/7629 7549/1/7549 +f 7549/1/7549 7554/1/7554 7550/1/7550 +f 7598/1/7598 7550/1/7550 7554/1/7554 +f 7549/1/7549 7553/1/7553 7554/1/7554 +f 7597/1/7597 7554/1/7554 7553/1/7553 +f 7552/1/7552 7553/1/7553 7549/1/7549 +f 7549/1/7549 7628/1/7628 7552/1/7552 +f 7552/1/7552 7556/1/7556 7553/1/7553 +f 7596/1/7596 7553/1/7553 7556/1/7556 +f 7555/1/7555 7556/1/7556 7552/1/7552 +f 7552/1/7552 7627/1/7627 7555/1/7555 +f 7555/1/7555 7559/1/7559 7556/1/7556 +f 7595/1/7595 7556/1/7556 7559/1/7559 +f 7555/1/7555 7558/1/7558 7559/1/7559 +f 7594/1/7594 7559/1/7559 7558/1/7558 +f 7557/1/7557 7558/1/7558 7555/1/7555 +f 7555/1/7555 7626/1/7626 7557/1/7557 +f 7557/1/7557 7561/1/7561 7558/1/7558 +f 7593/1/7593 7558/1/7558 7561/1/7561 +f 7560/1/7560 7561/1/7561 7557/1/7557 +f 7557/1/7557 7625/1/7625 7560/1/7560 +f 7560/1/7560 7564/1/7564 7561/1/7561 +f 7592/1/7592 7561/1/7561 7564/1/7564 +f 7560/1/7560 7563/1/7563 7564/1/7564 +f 7591/1/7591 7564/1/7564 7563/1/7563 +f 7562/1/7562 7563/1/7563 7560/1/7560 +f 7560/1/7560 7624/1/7624 7562/1/7562 +f 7562/1/7562 7566/1/7566 7563/1/7563 +f 7590/1/7590 7563/1/7563 7566/1/7566 +f 7565/1/7565 7566/1/7566 7562/1/7562 +f 7562/1/7562 7623/1/7623 7565/1/7565 +f 7565/1/7565 7569/1/7569 7566/1/7566 +f 7587/1/7587 7566/1/7566 7569/1/7569 +f 7565/1/7565 7568/1/7568 7569/1/7569 +f 7585/1/7585 7569/1/7569 7568/1/7568 +f 7567/1/7567 7568/1/7568 7565/1/7565 +f 7565/1/7565 7620/1/7620 7567/1/7567 +f 7567/1/7567 7571/1/7571 7568/1/7568 +f 7586/1/7586 7568/1/7568 7571/1/7571 +f 7570/1/7570 7571/1/7571 7567/1/7567 +f 7572/1/7572 7570/1/7570 7567/1/7567 +f 7567/1/7567 7619/1/7619 7572/1/7572 +f 7572/1/7572 7573/1/7573 7570/1/7570 +f 7589/1/7589 7570/1/7570 7573/1/7573 +f 7574/1/7574 7573/1/7573 7572/1/7572 +f 7572/1/7572 7622/1/7622 7574/1/7574 +f 7574/1/7574 7575/1/7575 7573/1/7573 +f 7602/1/7602 7573/1/7573 7575/1/7575 +f 7577/1/7577 7575/1/7575 7574/1/7574 +f 7576/1/7576 7577/1/7577 7574/1/7574 +f 7574/1/7574 7639/1/7639 7576/1/7576 +f 7576/1/7576 7579/1/7579 7577/1/7577 +f 7604/1/7604 7577/1/7577 7579/1/7579 +f 7578/1/7578 7579/1/7579 7576/1/7576 +f 7576/1/7576 7638/1/7638 7578/1/7578 +f 7578/1/7578 7582/1/7582 7579/1/7579 +f 7605/1/7605 7579/1/7579 7582/1/7582 +f 7578/1/7578 7581/1/7581 7582/1/7582 +f 7606/1/7606 7582/1/7582 7581/1/7581 +f 7580/1/7580 7581/1/7581 7578/1/7578 +f 7603/1/7603 7575/1/7575 7577/1/7577 +f 7588/1/7588 7571/1/7571 7570/1/7570 +f 7538/1/7538 7633/1/7633 7540/1/7540 +f 7542/1/7542 7632/1/7632 7631/1/7631 +f 7544/1/7544 7631/1/7631 7630/1/7630 +f 7547/1/7547 7630/1/7630 7629/1/7629 +f 7549/1/7549 7629/1/7629 7628/1/7628 +f 7552/1/7552 7628/1/7628 7627/1/7627 +f 7555/1/7555 7627/1/7627 7626/1/7626 +f 7557/1/7557 7626/1/7626 7625/1/7625 +f 7560/1/7560 7625/1/7625 7624/1/7624 +f 7562/1/7562 7624/1/7624 7623/1/7623 +f 7565/1/7565 7623/1/7623 7620/1/7620 +f 7567/1/7567 7620/1/7620 7619/1/7619 +f 7572/1/7572 7619/1/7619 7622/1/7622 +f 7574/1/7574 7622/1/7622 7639/1/7639 +f 7576/1/7576 7639/1/7639 7638/1/7638 +f 7578/1/7578 7638/1/7638 7640/1/7640 +f 7636/1/7636 7637/1/7637 7621/1/7621 +f 7578/1/7578 7640/1/7640 7580/1/7580 +f 7580/1/7580 7583/1/7583 7581/1/7581 +f 7607/1/7607 7581/1/7581 7583/1/7583 +f 7607/1/7607 7583/1/7583 7608/1/7608 +f 7606/1/7606 7581/1/7581 7607/1/7607 +f 7605/1/7605 7582/1/7582 7606/1/7606 +f 7604/1/7604 7579/1/7579 7605/1/7605 +f 7603/1/7603 7577/1/7577 7604/1/7604 +f 7602/1/7602 7575/1/7575 7603/1/7603 +f 7589/1/7589 7573/1/7573 7602/1/7602 +f 7588/1/7588 7570/1/7570 7589/1/7589 +f 7586/1/7586 7571/1/7571 7588/1/7588 +f 7585/1/7585 7568/1/7568 7586/1/7586 +f 7587/1/7587 7569/1/7569 7585/1/7585 +f 7590/1/7590 7566/1/7566 7587/1/7587 +f 7591/1/7591 7563/1/7563 7590/1/7590 +f 7592/1/7592 7564/1/7564 7591/1/7591 +f 7593/1/7593 7561/1/7561 7592/1/7592 +f 7594/1/7594 7558/1/7558 7593/1/7593 +f 7595/1/7595 7559/1/7559 7594/1/7594 +f 7596/1/7596 7556/1/7556 7595/1/7595 +f 7597/1/7597 7553/1/7553 7596/1/7596 +f 7598/1/7598 7554/1/7554 7597/1/7597 +f 7599/1/7599 7550/1/7550 7598/1/7598 +f 7600/1/7600 7551/1/7551 7599/1/7599 +f 7601/1/7601 7548/1/7548 7600/1/7600 +f 7617/1/7617 7545/1/7545 7601/1/7601 +f 7616/1/7616 7546/1/7546 7617/1/7617 +f 7615/1/7615 7543/1/7543 7616/1/7616 +f 7614/1/7614 7541/1/7541 7615/1/7615 +f 7613/1/7613 7539/1/7539 7614/1/7614 +f 7611/1/7611 7612/1/7612 7618/1/7618 +f 7613/1/7613 7537/1/7537 7539/1/7539 +f 7611/1/7611 7532/1/7532 7612/1/7612 +f 7538/1/7538 7539/1/7539 7537/1/7537 +f 7538/1/7538 7634/1/7634 7633/1/7633 +f 7621/1/7621 7634/1/7634 7635/1/7635 +f 7621/1/7621 7635/1/7635 7636/1/7636 +f 7535/1/7535 7637/1/7637 7636/1/7636 +f 7535/1/7535 7534/1/7534 7584/1/7584 +f 7610/1/7610 7534/1/7534 7533/1/7533 +f 7611/1/7611 7533/1/7533 7532/1/7532 +f 7536/1/7536 7532/1/7532 7531/1/7531 +f 7641/1/7641 7642/1/7642 7643/1/7643 +f 7641/1/7641 7643/1/7643 7644/1/7644 +f 7641/1/7641 7644/1/7644 7645/1/7645 +f 7645/1/7645 7746/1/7746 7641/1/7641 +f 7641/1/7641 7746/1/7746 7745/1/7745 +f 7641/1/7641 7745/1/7745 7646/1/7646 +f 7646/1/7646 7745/1/7745 7744/1/7744 +f 7646/1/7646 7744/1/7744 7648/1/7648 +f 7648/1/7648 7647/1/7647 7646/1/7646 +f 7646/1/7646 7647/1/7647 7642/1/7642 +f 7709/1/7709 7642/1/7642 7647/1/7647 +f 7709/1/7709 7647/1/7647 7710/1/7710 +f 7728/1/7728 7709/1/7709 7710/1/7710 +f 7728/1/7728 7710/1/7710 7711/1/7711 +f 7711/1/7711 7712/1/7712 7728/1/7728 +f 7728/1/7728 7712/1/7712 7713/1/7713 +f 7728/1/7728 7713/1/7713 7714/1/7714 +f 7714/1/7714 7715/1/7715 7728/1/7728 +f 7728/1/7728 7715/1/7715 7716/1/7716 +f 7728/1/7728 7716/1/7716 7717/1/7717 +f 7717/1/7717 7718/1/7718 7728/1/7728 +f 7728/1/7728 7718/1/7718 7719/1/7719 +f 7728/1/7728 7719/1/7719 7720/1/7720 +f 7720/1/7720 7721/1/7721 7728/1/7728 +f 7728/1/7728 7721/1/7721 7722/1/7722 +f 7728/1/7728 7722/1/7722 7723/1/7723 +f 7723/1/7723 7724/1/7724 7728/1/7728 +f 7728/1/7728 7724/1/7724 7725/1/7725 +f 7728/1/7728 7725/1/7725 7726/1/7726 +f 7726/1/7726 7727/1/7727 7728/1/7728 +f 7728/1/7728 7727/1/7727 7695/1/7695 +f 7728/1/7728 7695/1/7695 7696/1/7696 +f 7696/1/7696 7697/1/7697 7728/1/7728 +f 7728/1/7728 7697/1/7697 7698/1/7698 +f 7728/1/7728 7698/1/7698 7699/1/7699 +f 7699/1/7699 7700/1/7700 7728/1/7728 +f 7728/1/7728 7700/1/7700 7701/1/7701 +f 7728/1/7728 7701/1/7701 7702/1/7702 +f 7702/1/7702 7703/1/7703 7728/1/7728 +f 7728/1/7728 7703/1/7703 7704/1/7704 +f 7728/1/7728 7704/1/7704 7705/1/7705 +f 7705/1/7705 7706/1/7706 7728/1/7728 +f 7728/1/7728 7706/1/7706 7707/1/7707 +f 7728/1/7728 7707/1/7707 7708/1/7708 +f 7707/1/7707 7643/1/7643 7708/1/7708 +f 7706/1/7706 7644/1/7644 7707/1/7707 +f 7706/1/7706 7694/1/7694 7644/1/7644 +f 7705/1/7705 7694/1/7694 7706/1/7706 +f 7705/1/7705 7693/1/7693 7694/1/7694 +f 7645/1/7645 7694/1/7694 7693/1/7693 +f 7645/1/7645 7693/1/7693 7690/1/7690 +f 7690/1/7690 7747/1/7747 7645/1/7645 +f 7690/1/7690 7750/1/7750 7747/1/7747 +f 7731/1/7731 7747/1/7747 7750/1/7750 +f 7731/1/7731 7750/1/7750 7748/1/7748 +f 7748/1/7748 7749/1/7749 7731/1/7731 +f 7731/1/7731 7749/1/7749 7732/1/7732 +f 7731/1/7731 7732/1/7732 7729/1/7729 +f 7729/1/7729 7730/1/7730 7731/1/7731 +f 7731/1/7731 7730/1/7730 7733/1/7733 +f 7731/1/7731 7733/1/7733 7734/1/7734 +f 7734/1/7734 7735/1/7735 7731/1/7731 +f 7731/1/7731 7735/1/7735 7736/1/7736 +f 7731/1/7731 7736/1/7736 7737/1/7737 +f 7737/1/7737 7738/1/7738 7731/1/7731 +f 7731/1/7731 7738/1/7738 7739/1/7739 +f 7731/1/7731 7739/1/7739 7740/1/7740 +f 7740/1/7740 7741/1/7741 7731/1/7731 +f 7731/1/7731 7741/1/7741 7742/1/7742 +f 7731/1/7731 7742/1/7742 7743/1/7743 +f 7743/1/7743 7744/1/7744 7731/1/7731 +f 7650/1/7650 7743/1/7743 7742/1/7742 +f 7650/1/7650 7742/1/7742 7652/1/7652 +f 7652/1/7652 7653/1/7653 7650/1/7650 +f 7650/1/7650 7653/1/7653 7651/1/7651 +f 7650/1/7650 7651/1/7651 7648/1/7648 +f 7651/1/7651 7649/1/7649 7648/1/7648 +f 7711/1/7711 7649/1/7649 7651/1/7651 +f 7712/1/7712 7651/1/7651 7653/1/7653 +f 7652/1/7652 7656/1/7656 7653/1/7653 +f 7713/1/7713 7653/1/7653 7656/1/7656 +f 7652/1/7652 7655/1/7655 7656/1/7656 +f 7714/1/7714 7656/1/7656 7655/1/7655 +f 7654/1/7654 7655/1/7655 7652/1/7652 +f 7652/1/7652 7741/1/7741 7654/1/7654 +f 7654/1/7654 7658/1/7658 7655/1/7655 +f 7715/1/7715 7655/1/7655 7658/1/7658 +f 7657/1/7657 7658/1/7658 7654/1/7654 +f 7654/1/7654 7740/1/7740 7657/1/7657 +f 7657/1/7657 7661/1/7661 7658/1/7658 +f 7716/1/7716 7658/1/7658 7661/1/7661 +f 7657/1/7657 7660/1/7660 7661/1/7661 +f 7717/1/7717 7661/1/7661 7660/1/7660 +f 7659/1/7659 7660/1/7660 7657/1/7657 +f 7657/1/7657 7739/1/7739 7659/1/7659 +f 7659/1/7659 7664/1/7664 7660/1/7660 +f 7718/1/7718 7660/1/7660 7664/1/7664 +f 7659/1/7659 7663/1/7663 7664/1/7664 +f 7719/1/7719 7664/1/7664 7663/1/7663 +f 7662/1/7662 7663/1/7663 7659/1/7659 +f 7659/1/7659 7738/1/7738 7662/1/7662 +f 7662/1/7662 7666/1/7666 7663/1/7663 +f 7720/1/7720 7663/1/7663 7666/1/7666 +f 7665/1/7665 7666/1/7666 7662/1/7662 +f 7662/1/7662 7737/1/7737 7665/1/7665 +f 7665/1/7665 7669/1/7669 7666/1/7666 +f 7721/1/7721 7666/1/7666 7669/1/7669 +f 7665/1/7665 7668/1/7668 7669/1/7669 +f 7722/1/7722 7669/1/7669 7668/1/7668 +f 7667/1/7667 7668/1/7668 7665/1/7665 +f 7665/1/7665 7736/1/7736 7667/1/7667 +f 7667/1/7667 7671/1/7671 7668/1/7668 +f 7723/1/7723 7668/1/7668 7671/1/7671 +f 7670/1/7670 7671/1/7671 7667/1/7667 +f 7667/1/7667 7735/1/7735 7670/1/7670 +f 7670/1/7670 7674/1/7674 7671/1/7671 +f 7724/1/7724 7671/1/7671 7674/1/7674 +f 7670/1/7670 7673/1/7673 7674/1/7674 +f 7725/1/7725 7674/1/7674 7673/1/7673 +f 7672/1/7672 7673/1/7673 7670/1/7670 +f 7670/1/7670 7734/1/7734 7672/1/7672 +f 7672/1/7672 7676/1/7676 7673/1/7673 +f 7726/1/7726 7673/1/7673 7676/1/7676 +f 7675/1/7675 7676/1/7676 7672/1/7672 +f 7672/1/7672 7733/1/7733 7675/1/7675 +f 7675/1/7675 7679/1/7679 7676/1/7676 +f 7727/1/7727 7676/1/7676 7679/1/7679 +f 7675/1/7675 7678/1/7678 7679/1/7679 +f 7695/1/7695 7679/1/7679 7678/1/7678 +f 7677/1/7677 7678/1/7678 7675/1/7675 +f 7675/1/7675 7730/1/7730 7677/1/7677 +f 7677/1/7677 7681/1/7681 7678/1/7678 +f 7696/1/7696 7678/1/7678 7681/1/7681 +f 7680/1/7680 7681/1/7681 7677/1/7677 +f 7682/1/7682 7680/1/7680 7677/1/7677 +f 7677/1/7677 7729/1/7729 7682/1/7682 +f 7682/1/7682 7683/1/7683 7680/1/7680 +f 7698/1/7698 7680/1/7680 7683/1/7683 +f 7684/1/7684 7683/1/7683 7682/1/7682 +f 7682/1/7682 7732/1/7732 7684/1/7684 +f 7684/1/7684 7685/1/7685 7683/1/7683 +f 7699/1/7699 7683/1/7683 7685/1/7685 +f 7687/1/7687 7685/1/7685 7684/1/7684 +f 7686/1/7686 7687/1/7687 7684/1/7684 +f 7684/1/7684 7749/1/7749 7686/1/7686 +f 7686/1/7686 7689/1/7689 7687/1/7687 +f 7701/1/7701 7687/1/7687 7689/1/7689 +f 7688/1/7688 7689/1/7689 7686/1/7686 +f 7686/1/7686 7748/1/7748 7688/1/7688 +f 7688/1/7688 7692/1/7692 7689/1/7689 +f 7702/1/7702 7689/1/7689 7692/1/7692 +f 7688/1/7688 7691/1/7691 7692/1/7692 +f 7703/1/7703 7692/1/7692 7691/1/7691 +f 7690/1/7690 7691/1/7691 7688/1/7688 +f 7700/1/7700 7685/1/7685 7687/1/7687 +f 7697/1/7697 7681/1/7681 7680/1/7680 +f 7648/1/7648 7743/1/7743 7650/1/7650 +f 7652/1/7652 7742/1/7742 7741/1/7741 +f 7654/1/7654 7741/1/7741 7740/1/7740 +f 7657/1/7657 7740/1/7740 7739/1/7739 +f 7659/1/7659 7739/1/7739 7738/1/7738 +f 7662/1/7662 7738/1/7738 7737/1/7737 +f 7665/1/7665 7737/1/7737 7736/1/7736 +f 7667/1/7667 7736/1/7736 7735/1/7735 +f 7670/1/7670 7735/1/7735 7734/1/7734 +f 7672/1/7672 7734/1/7734 7733/1/7733 +f 7675/1/7675 7733/1/7733 7730/1/7730 +f 7677/1/7677 7730/1/7730 7729/1/7729 +f 7682/1/7682 7729/1/7729 7732/1/7732 +f 7684/1/7684 7732/1/7732 7749/1/7749 +f 7686/1/7686 7749/1/7749 7748/1/7748 +f 7688/1/7688 7748/1/7748 7750/1/7750 +f 7746/1/7746 7747/1/7747 7731/1/7731 +f 7688/1/7688 7750/1/7750 7690/1/7690 +f 7690/1/7690 7693/1/7693 7691/1/7691 +f 7704/1/7704 7691/1/7691 7693/1/7693 +f 7704/1/7704 7693/1/7693 7705/1/7705 +f 7703/1/7703 7691/1/7691 7704/1/7704 +f 7702/1/7702 7692/1/7692 7703/1/7703 +f 7701/1/7701 7689/1/7689 7702/1/7702 +f 7700/1/7700 7687/1/7687 7701/1/7701 +f 7699/1/7699 7685/1/7685 7700/1/7700 +f 7698/1/7698 7683/1/7683 7699/1/7699 +f 7697/1/7697 7680/1/7680 7698/1/7698 +f 7696/1/7696 7681/1/7681 7697/1/7697 +f 7695/1/7695 7678/1/7678 7696/1/7696 +f 7727/1/7727 7679/1/7679 7695/1/7695 +f 7726/1/7726 7676/1/7676 7727/1/7727 +f 7725/1/7725 7673/1/7673 7726/1/7726 +f 7724/1/7724 7674/1/7674 7725/1/7725 +f 7723/1/7723 7671/1/7671 7724/1/7724 +f 7722/1/7722 7668/1/7668 7723/1/7723 +f 7721/1/7721 7669/1/7669 7722/1/7722 +f 7720/1/7720 7666/1/7666 7721/1/7721 +f 7719/1/7719 7663/1/7663 7720/1/7720 +f 7718/1/7718 7664/1/7664 7719/1/7719 +f 7717/1/7717 7660/1/7660 7718/1/7718 +f 7716/1/7716 7661/1/7661 7717/1/7717 +f 7715/1/7715 7658/1/7658 7716/1/7716 +f 7714/1/7714 7655/1/7655 7715/1/7715 +f 7713/1/7713 7656/1/7656 7714/1/7714 +f 7712/1/7712 7653/1/7653 7713/1/7713 +f 7711/1/7711 7651/1/7651 7712/1/7712 +f 7710/1/7710 7649/1/7649 7711/1/7711 +f 7708/1/7708 7709/1/7709 7728/1/7728 +f 7710/1/7710 7647/1/7647 7649/1/7649 +f 7708/1/7708 7642/1/7642 7709/1/7709 +f 7648/1/7648 7649/1/7649 7647/1/7647 +f 7648/1/7648 7744/1/7744 7743/1/7743 +f 7731/1/7731 7744/1/7744 7745/1/7745 +f 7731/1/7731 7745/1/7745 7746/1/7746 +f 7645/1/7645 7747/1/7747 7746/1/7746 +f 7645/1/7645 7644/1/7644 7694/1/7694 +f 7707/1/7707 7644/1/7644 7643/1/7643 +f 7708/1/7708 7643/1/7643 7642/1/7642 +f 7646/1/7646 7642/1/7642 7641/1/7641 +f 7751/1/7751 7752/1/7752 7753/1/7753 +f 7751/1/7751 7753/1/7753 7754/1/7754 +f 7755/1/7755 7751/1/7751 7754/1/7754 +f 7755/1/7755 7754/1/7754 7759/1/7759 +f 7760/1/7760 7755/1/7755 7759/1/7759 +f 7760/1/7760 7759/1/7759 7761/1/7761 +f 7765/1/7765 7760/1/7760 7761/1/7761 +f 7765/1/7765 7761/1/7761 7766/1/7766 +f 7769/1/7769 7765/1/7765 7766/1/7766 +f 7770/1/7770 7769/1/7769 7766/1/7766 +f 7770/1/7770 7766/1/7766 7768/1/7768 +f 7802/1/7802 7770/1/7770 7768/1/7768 +f 7802/1/7802 7768/1/7768 7803/1/7803 +f 7803/1/7803 7804/1/7804 7802/1/7802 +f 7802/1/7802 7804/1/7804 7805/1/7805 +f 7802/1/7802 7805/1/7805 7800/1/7800 +f 7800/1/7800 7799/1/7799 7802/1/7802 +f 7800/1/7800 7801/1/7801 7799/1/7799 +f 7801/1/7801 7798/1/7798 7799/1/7799 +f 7799/1/7799 7798/1/7798 7769/1/7769 +f 7796/1/7796 7769/1/7769 7798/1/7798 +f 7797/1/7797 7796/1/7796 7798/1/7798 +f 7797/1/7797 7798/1/7798 7909/1/7909 +f 7905/1/7905 7797/1/7797 7909/1/7909 +f 7905/1/7905 7909/1/7909 7907/1/7907 +f 7907/1/7907 7908/1/7908 7905/1/7905 +f 7908/1/7908 7906/1/7906 7905/1/7905 +f 7905/1/7905 7906/1/7906 7904/1/7904 +f 7905/1/7905 7904/1/7904 7790/1/7790 +f 7790/1/7790 7904/1/7904 7791/1/7791 +f 7790/1/7790 7791/1/7791 7786/1/7786 +f 7786/1/7786 7789/1/7789 7790/1/7790 +f 7789/1/7789 7795/1/7795 7790/1/7790 +f 7790/1/7790 7795/1/7795 7797/1/7797 +f 7789/1/7789 7794/1/7794 7795/1/7795 +f 7795/1/7795 7794/1/7794 7796/1/7796 +f 7794/1/7794 7774/1/7774 7796/1/7796 +f 7794/1/7794 7793/1/7793 7774/1/7774 +f 7774/1/7774 7793/1/7793 7792/1/7792 +f 7774/1/7774 7792/1/7792 7775/1/7775 +f 7775/1/7775 7772/1/7772 7774/1/7774 +f 7774/1/7774 7772/1/7772 7771/1/7771 +f 7774/1/7774 7771/1/7771 7769/1/7769 +f 7772/1/7772 7773/1/7773 7771/1/7771 +f 7771/1/7771 7773/1/7773 7760/1/7760 +f 7772/1/7772 7776/1/7776 7773/1/7773 +f 7776/1/7776 7777/1/7777 7773/1/7773 +f 7773/1/7773 7777/1/7777 7755/1/7755 +f 7777/1/7777 7756/1/7756 7755/1/7755 +f 7777/1/7777 7779/1/7779 7756/1/7756 +f 7756/1/7756 7779/1/7779 7752/1/7752 +f 7779/1/7779 7782/1/7782 7752/1/7752 +f 7752/1/7752 7782/1/7782 7758/1/7758 +f 7782/1/7782 7902/1/7902 7758/1/7758 +f 7758/1/7758 7902/1/7902 7914/1/7914 +f 7758/1/7758 7914/1/7914 7952/1/7952 +f 7952/1/7952 7953/1/7953 7758/1/7758 +f 7758/1/7758 7953/1/7953 7757/1/7757 +f 7753/1/7753 7758/1/7758 7757/1/7757 +f 7954/1/7954 7757/1/7757 7953/1/7953 +f 7954/1/7954 7953/1/7953 7958/1/7958 +f 7759/1/7759 7954/1/7954 7958/1/7958 +f 7764/1/7764 7759/1/7759 7958/1/7958 +f 7958/1/7958 7960/1/7960 7764/1/7764 +f 7764/1/7764 7960/1/7960 7956/1/7956 +f 7764/1/7764 7956/1/7956 7763/1/7763 +f 7956/1/7956 7957/1/7957 7763/1/7763 +f 7763/1/7763 7957/1/7957 7955/1/7955 +f 7763/1/7763 7955/1/7955 7767/1/7767 +f 7767/1/7767 7762/1/7762 7763/1/7763 +f 7763/1/7763 7762/1/7762 7759/1/7759 +f 7766/1/7766 7762/1/7762 7767/1/7767 +f 7767/1/7767 7955/1/7955 7768/1/7768 +f 7957/1/7957 7967/1/7967 7955/1/7955 +f 7803/1/7803 7955/1/7955 7967/1/7967 +f 7957/1/7957 7966/1/7966 7967/1/7967 +f 7966/1/7966 7968/1/7968 7967/1/7967 +f 7968/1/7968 7812/1/7812 7967/1/7967 +f 7967/1/7967 7812/1/7812 7804/1/7804 +f 7968/1/7968 7993/1/7993 7812/1/7812 +f 7993/1/7993 7805/1/7805 7812/1/7812 +f 7993/1/7993 7994/1/7994 7805/1/7805 +f 7994/1/7994 7811/1/7811 7805/1/7805 +f 7805/1/7805 7811/1/7811 7809/1/7809 +f 7805/1/7805 7809/1/7809 7806/1/7806 +f 7809/1/7809 7810/1/7810 7806/1/7806 +f 7806/1/7806 7810/1/7810 7808/1/7808 +f 7807/1/7807 7806/1/7806 7808/1/7808 +f 7808/1/7808 7910/1/7910 7807/1/7807 +f 7807/1/7807 7910/1/7910 7907/1/7907 +f 7798/1/7798 7807/1/7807 7907/1/7907 +f 7819/1/7819 7910/1/7910 7808/1/7808 +f 7819/1/7819 7808/1/7808 7814/1/7814 +f 7818/1/7818 7819/1/7819 7814/1/7814 +f 7814/1/7814 7820/1/7820 7818/1/7818 +f 7820/1/7820 7824/1/7824 7818/1/7818 +f 7824/1/7824 7827/1/7827 7818/1/7818 +f 7818/1/7818 7827/1/7827 7911/1/7911 +f 7911/1/7911 7827/1/7827 7906/1/7906 +f 7906/1/7906 7827/1/7827 7826/1/7826 +f 7826/1/7826 7889/1/7889 7906/1/7906 +f 7906/1/7906 7889/1/7889 7885/1/7885 +f 7889/1/7889 7871/1/7871 7885/1/7885 +f 7871/1/7871 7884/1/7884 7885/1/7885 +f 7904/1/7904 7885/1/7885 7884/1/7884 +f 7871/1/7871 7888/1/7888 7884/1/7884 +f 7791/1/7791 7884/1/7884 7888/1/7888 +f 7791/1/7791 7888/1/7888 7787/1/7787 +f 7787/1/7787 7888/1/7888 7788/1/7788 +f 7787/1/7787 7788/1/7788 7784/1/7784 +f 7786/1/7786 7787/1/7787 7784/1/7784 +f 7786/1/7786 7784/1/7784 7781/1/7781 +f 7781/1/7781 7785/1/7785 7786/1/7786 +f 7781/1/7781 7775/1/7775 7785/1/7785 +f 7781/1/7781 7778/1/7778 7775/1/7775 +f 7775/1/7775 7778/1/7778 7776/1/7776 +f 7781/1/7781 7780/1/7780 7778/1/7778 +f 7778/1/7778 7780/1/7780 7779/1/7779 +f 7784/1/7784 7780/1/7780 7781/1/7781 +f 7784/1/7784 7783/1/7783 7780/1/7780 +f 7780/1/7780 7783/1/7783 7782/1/7782 +f 7788/1/7788 7783/1/7783 7784/1/7784 +f 7788/1/7788 7900/1/7900 7783/1/7783 +f 7902/1/7902 7783/1/7783 7900/1/7900 +f 7900/1/7900 7903/1/7903 7902/1/7902 +f 7902/1/7902 7903/1/7903 7912/1/7912 +f 7903/1/7903 7913/1/7913 7912/1/7912 +f 7912/1/7912 7913/1/7913 7916/1/7916 +f 7912/1/7912 7916/1/7916 7915/1/7915 +f 7914/1/7914 7912/1/7912 7915/1/7915 +f 7914/1/7914 7915/1/7915 7943/1/7943 +f 7943/1/7943 7915/1/7915 7942/1/7942 +f 7943/1/7943 7942/1/7942 7982/1/7982 +f 7952/1/7952 7943/1/7943 7982/1/7982 +f 7982/1/7982 7963/1/7963 7952/1/7952 +f 7963/1/7963 7959/1/7959 7952/1/7952 +f 7962/1/7962 7959/1/7959 7963/1/7963 +f 7962/1/7962 7963/1/7963 7981/1/7981 +f 7962/1/7962 7981/1/7981 7980/1/7980 +f 7965/1/7965 7962/1/7962 7980/1/7980 +f 7965/1/7965 7980/1/7980 7979/1/7979 +f 7979/1/7979 7978/1/7978 7965/1/7965 +f 7978/1/7978 7964/1/7964 7965/1/7965 +f 7964/1/7964 7961/1/7961 7965/1/7965 +f 7960/1/7960 7961/1/7961 7964/1/7964 +f 7974/1/7974 7964/1/7964 7978/1/7978 +f 7974/1/7974 7969/1/7969 7964/1/7964 +f 7969/1/7969 7966/1/7966 7964/1/7964 +f 7956/1/7956 7964/1/7964 7966/1/7966 +f 7969/1/7969 7970/1/7970 7966/1/7966 +f 7970/1/7970 7971/1/7971 7966/1/7966 +f 7970/1/7970 7989/1/7989 7971/1/7971 +f 7989/1/7989 7990/1/7990 7971/1/7971 +f 7971/1/7971 7990/1/7990 7993/1/7993 +f 7989/1/7989 7988/1/7988 7990/1/7990 +f 7988/1/7988 7992/1/7992 7990/1/7990 +f 7990/1/7990 7992/1/7992 7994/1/7994 +f 7992/1/7992 7995/1/7995 7994/1/7994 +f 7994/1/7994 7995/1/7995 7996/1/7996 +f 7995/1/7995 7997/1/7997 7996/1/7996 +f 7996/1/7996 7997/1/7997 7816/1/7816 +f 7996/1/7996 7816/1/7816 7811/1/7811 +f 7811/1/7811 7816/1/7816 7813/1/7813 +f 7816/1/7816 7815/1/7815 7813/1/7813 +f 7815/1/7815 7810/1/7810 7813/1/7813 +f 7814/1/7814 7810/1/7810 7815/1/7815 +f 7815/1/7815 7817/1/7817 7814/1/7814 +f 7815/1/7815 7821/1/7821 7817/1/7817 +f 7821/1/7821 7822/1/7822 7817/1/7817 +f 7817/1/7817 7822/1/7822 7823/1/7823 +f 7817/1/7817 7823/1/7823 7820/1/7820 +f 7822/1/7822 7828/1/7828 7823/1/7823 +f 7823/1/7823 7828/1/7828 7825/1/7825 +f 7823/1/7823 7825/1/7825 7824/1/7824 +f 7825/1/7825 7826/1/7826 7824/1/7824 +f 7825/1/7825 7830/1/7830 7826/1/7826 +f 7826/1/7826 7830/1/7830 7871/1/7871 +f 7871/1/7871 7830/1/7830 7872/1/7872 +f 7871/1/7871 7872/1/7872 7873/1/7873 +f 7873/1/7873 8060/1/8060 7871/1/7871 +f 8061/1/8061 7871/1/7871 8060/1/8060 +f 8060/1/8060 8059/1/8059 8061/1/8061 +f 8061/1/8061 8059/1/8059 8148/1/8148 +f 8148/1/8148 7890/1/7890 8061/1/8061 +f 8061/1/8061 7890/1/7890 7886/1/7886 +f 7890/1/7890 7891/1/7891 7886/1/7886 +f 7886/1/7886 7891/1/7891 7887/1/7887 +f 7886/1/7886 7887/1/7887 7871/1/7871 +f 7887/1/7887 7891/1/7891 7893/1/7893 +f 7893/1/7893 7898/1/7898 7887/1/7887 +f 7887/1/7887 7898/1/7898 7899/1/7899 +f 7887/1/7887 7899/1/7899 7900/1/7900 +f 7900/1/7900 7899/1/7899 7901/1/7901 +f 8056/1/8056 7901/1/7901 7899/1/7899 +f 8056/1/8056 7899/1/7899 8059/1/8059 +f 8059/1/8059 8051/1/8051 8056/1/8056 +f 8051/1/8051 8052/1/8052 8056/1/8056 +f 8056/1/8056 8052/1/8052 8053/1/8053 +f 8056/1/8056 8053/1/8053 8057/1/8057 +f 8057/1/8057 8053/1/8053 8058/1/8058 +f 8058/1/8058 8189/1/8189 8057/1/8057 +f 8057/1/8057 8189/1/8189 8186/1/8186 +f 8057/1/8057 8186/1/8186 8185/1/8185 +f 8185/1/8185 8183/1/8183 8057/1/8057 +f 8057/1/8057 8183/1/8183 8182/1/8182 +f 8057/1/8057 8182/1/8182 8180/1/8180 +f 8180/1/8180 8178/1/8178 8057/1/8057 +f 8057/1/8057 8178/1/8178 8175/1/8175 +f 8057/1/8057 8175/1/8175 8170/1/8170 +f 8170/1/8170 8168/1/8168 8057/1/8057 +f 8057/1/8057 8168/1/8168 8167/1/8167 +f 8057/1/8057 8167/1/8167 8166/1/8166 +f 8166/1/8166 8153/1/8153 8057/1/8057 +f 8153/1/8153 8150/1/8150 8057/1/8057 +f 8057/1/8057 8150/1/8150 8149/1/8149 +f 8057/1/8057 8149/1/8149 8115/1/8115 +f 8057/1/8057 8115/1/8115 8082/1/8082 +f 8057/1/8057 8082/1/8082 8113/1/8113 +f 8113/1/8113 7917/1/7917 8057/1/8057 +f 8057/1/8057 7917/1/7917 7901/1/7901 +f 7901/1/7901 7917/1/7917 7913/1/7913 +f 7913/1/7913 7917/1/7917 7918/1/7918 +f 7913/1/7913 7918/1/7918 7919/1/7919 +f 8118/1/8118 7913/1/7913 7919/1/7919 +f 8118/1/8118 7919/1/7919 8120/1/8120 +f 8119/1/8119 8118/1/8118 8120/1/8120 +f 8119/1/8119 8120/1/8120 8121/1/8121 +f 8119/1/8119 8121/1/8121 8122/1/8122 +f 8122/1/8122 7922/1/7922 8119/1/8119 +f 8119/1/8119 7922/1/7922 7920/1/7920 +f 8119/1/8119 7920/1/7920 8117/1/8117 +f 8117/1/8117 7920/1/7920 7918/1/7918 +f 8117/1/8117 7918/1/7918 8113/1/8113 +f 8113/1/8113 8114/1/8114 8117/1/8117 +f 8117/1/8117 8114/1/8114 8118/1/8118 +f 7921/1/7921 7920/1/7920 7922/1/7922 +f 7921/1/7921 7922/1/7922 7923/1/7923 +f 8121/1/8121 7921/1/7921 7923/1/7923 +f 8121/1/8121 7923/1/7923 8123/1/8123 +f 8123/1/8123 7923/1/7923 7925/1/7925 +f 8123/1/8123 7925/1/7925 8125/1/8125 +f 8123/1/8123 8125/1/8125 8124/1/8124 +f 8122/1/8122 8123/1/8123 8124/1/8124 +f 8124/1/8124 7924/1/7924 8122/1/8122 +f 8124/1/8124 7927/1/7927 7924/1/7924 +f 7926/1/7926 7924/1/7924 7927/1/7927 +f 7926/1/7926 7927/1/7927 7928/1/7928 +f 8126/1/8126 7926/1/7926 7928/1/7928 +f 8126/1/8126 7928/1/7928 8128/1/8128 +f 8127/1/8127 8126/1/8126 8128/1/8128 +f 8127/1/8127 8128/1/8128 8129/1/8129 +f 8129/1/8129 8130/1/8130 8127/1/8127 +f 8130/1/8130 7930/1/7930 8127/1/8127 +f 8127/1/8127 7930/1/7930 7927/1/7927 +f 7929/1/7929 7927/1/7927 7930/1/7930 +f 7929/1/7929 7930/1/7930 7931/1/7931 +f 8129/1/8129 7929/1/7929 7931/1/7931 +f 8129/1/8129 7931/1/7931 8131/1/8131 +f 8131/1/8131 7931/1/7931 7933/1/7933 +f 8131/1/8131 7933/1/7933 8132/1/8132 +f 8131/1/8131 8132/1/8132 8130/1/8130 +f 8130/1/8130 8132/1/8132 8133/1/8133 +f 8130/1/8130 8133/1/8133 8134/1/8134 +f 8134/1/8134 8135/1/8135 8130/1/8130 +f 8135/1/8135 8136/1/8136 8130/1/8130 +f 8130/1/8130 8136/1/8136 8137/1/8137 +f 8130/1/8130 8137/1/8137 8138/1/8138 +f 8138/1/8138 7938/1/7938 8130/1/8130 +f 8138/1/8138 7897/1/7897 7938/1/7938 +f 7897/1/7897 7940/1/7940 7938/1/7938 +f 7938/1/7938 7940/1/7940 7939/1/7939 +f 7938/1/7938 7939/1/7939 7930/1/7930 +f 7930/1/7930 7939/1/7939 7937/1/7937 +f 7930/1/7930 7937/1/7937 7936/1/7936 +f 7936/1/7936 7935/1/7935 7930/1/7930 +f 7930/1/7930 7935/1/7935 7934/1/7934 +f 7930/1/7930 7934/1/7934 7932/1/7932 +f 8133/1/8133 7932/1/7932 7934/1/7934 +f 7935/1/7935 8134/1/8134 7934/1/7934 +f 8136/1/8136 7935/1/7935 7936/1/7936 +f 8137/1/8137 7936/1/7936 7937/1/7937 +f 8137/1/8137 7937/1/7937 7939/1/7939 +f 8137/1/8137 7939/1/7939 8139/1/8139 +f 8139/1/8139 7939/1/7939 7940/1/7940 +f 8139/1/8139 7940/1/7940 8141/1/8141 +f 8140/1/8140 8139/1/8139 8141/1/8141 +f 8140/1/8140 8141/1/8141 8142/1/8142 +f 8140/1/8140 8142/1/8142 8143/1/8143 +f 8143/1/8143 7891/1/7891 8140/1/8140 +f 8140/1/8140 7891/1/7891 7897/1/7897 +f 7891/1/7891 7896/1/7896 7897/1/7897 +f 7891/1/7891 7895/1/7895 7896/1/7896 +f 8142/1/8142 7896/1/7896 7895/1/7895 +f 8142/1/8142 7895/1/7895 8144/1/8144 +f 8144/1/8144 7895/1/7895 7894/1/7894 +f 8144/1/8144 7894/1/7894 8146/1/8146 +f 8145/1/8145 8144/1/8144 8146/1/8146 +f 8145/1/8145 8146/1/8146 8059/1/8059 +f 8059/1/8059 7898/1/7898 8145/1/8145 +f 8059/1/8059 8146/1/8146 8147/1/8147 +f 8146/1/8146 7892/1/7892 8147/1/8147 +f 8147/1/8147 7892/1/7892 8148/1/8148 +f 8143/1/8143 8144/1/8144 8145/1/8145 +f 8145/1/8145 7893/1/7893 8143/1/8143 +f 8146/1/8146 7894/1/7894 7892/1/7892 +f 7891/1/7891 7892/1/7892 7894/1/7894 +f 7894/1/7894 7895/1/7895 7891/1/7891 +f 8143/1/8143 8142/1/8142 8144/1/8144 +f 8141/1/8141 7896/1/7896 8142/1/8142 +f 8138/1/8138 8139/1/8139 8140/1/8140 +f 8141/1/8141 7940/1/7940 7896/1/7896 +f 7897/1/7897 7896/1/7896 7940/1/7940 +f 8140/1/8140 7897/1/7897 8138/1/8138 +f 8138/1/8138 8137/1/8137 8139/1/8139 +f 8136/1/8136 7936/1/7936 8137/1/8137 +f 8135/1/8135 7935/1/7935 8136/1/8136 +f 8135/1/8135 8134/1/8134 7935/1/7935 +f 8133/1/8133 7934/1/7934 8134/1/8134 +f 8132/1/8132 7932/1/7932 8133/1/8133 +f 8132/1/8132 7933/1/7933 7932/1/7932 +f 7931/1/7931 7932/1/7932 7933/1/7933 +f 7931/1/7931 7930/1/7930 7932/1/7932 +f 8130/1/8130 7938/1/7938 7930/1/7930 +f 8131/1/8131 8130/1/8130 8129/1/8129 +f 8128/1/8128 7929/1/7929 8129/1/8129 +f 8124/1/8124 8126/1/8126 8127/1/8127 +f 8128/1/8128 7928/1/7928 7929/1/7929 +f 8125/1/8125 7926/1/7926 8126/1/8126 +f 7928/1/7928 7927/1/7927 7929/1/7929 +f 7925/1/7925 7924/1/7924 7926/1/7926 +f 7922/1/7922 7924/1/7924 7925/1/7925 +f 8127/1/8127 7927/1/7927 8124/1/8124 +f 8124/1/8124 8125/1/8125 8126/1/8126 +f 8125/1/8125 7925/1/7925 7926/1/7926 +f 7923/1/7923 7922/1/7922 7925/1/7925 +f 7919/1/7919 7920/1/7920 7921/1/7921 +f 8122/1/8122 7924/1/7924 7922/1/7922 +f 8122/1/8122 8121/1/8121 8123/1/8123 +f 8120/1/8120 7921/1/7921 8121/1/8121 +f 8117/1/8117 8118/1/8118 8119/1/8119 +f 8120/1/8120 7919/1/7919 7921/1/7921 +f 8118/1/8118 8114/1/8114 7913/1/7913 +f 7919/1/7919 7918/1/7918 7920/1/7920 +f 8113/1/8113 7918/1/7918 7917/1/7917 +f 8113/1/8113 8082/1/8082 8114/1/8114 +f 8114/1/8114 8082/1/8082 8331/1/8331 +f 8114/1/8114 8331/1/8331 8316/1/8316 +f 8315/1/8315 8114/1/8114 8316/1/8316 +f 8315/1/8315 8316/1/8316 8317/1/8317 +f 8317/1/8317 8370/1/8370 8315/1/8315 +f 8315/1/8315 8370/1/8370 8374/1/8374 +f 8315/1/8315 8374/1/8374 7916/1/7916 +f 7916/1/7916 8374/1/8374 7841/1/7841 +f 7841/1/7841 7944/1/7944 7916/1/7916 +f 7916/1/7916 7944/1/7944 7941/1/7941 +f 7944/1/7944 7942/1/7942 7941/1/7941 +f 7945/1/7945 7942/1/7942 7944/1/7944 +f 7946/1/7946 7945/1/7945 7944/1/7944 +f 7944/1/7944 7947/1/7947 7946/1/7946 +f 7946/1/7946 7947/1/7947 7948/1/7948 +f 7946/1/7946 7948/1/7948 7949/1/7949 +f 7979/1/7979 7946/1/7946 7949/1/7949 +f 7979/1/7979 7949/1/7949 7977/1/7977 +f 7977/1/7977 7974/1/7974 7979/1/7979 +f 7977/1/7977 7973/1/7973 7974/1/7974 +f 7976/1/7976 7973/1/7973 7977/1/7977 +f 7983/1/7983 7976/1/7976 7977/1/7977 +f 7977/1/7977 7951/1/7951 7983/1/7983 +f 7983/1/7983 7951/1/7951 8004/1/8004 +f 7983/1/7983 8004/1/8004 8002/1/8002 +f 7983/1/7983 8002/1/8002 7986/1/7986 +f 7986/1/7986 7984/1/7984 7983/1/7983 +f 7986/1/7986 7987/1/7987 7984/1/7984 +f 7984/1/7984 7987/1/7987 7985/1/7985 +f 7984/1/7984 7985/1/7985 7976/1/7976 +f 7985/1/7985 7975/1/7975 7976/1/7976 +f 7976/1/7976 7975/1/7975 7972/1/7972 +f 7972/1/7972 7975/1/7975 7970/1/7970 +f 7970/1/7970 7975/1/7975 7985/1/7985 +f 7970/1/7970 7985/1/7985 7987/1/7987 +f 7986/1/7986 7988/1/7988 7987/1/7987 +f 7991/1/7991 7988/1/7988 7986/1/7986 +f 7991/1/7991 7986/1/7986 8000/1/8000 +f 7991/1/7991 8000/1/8000 7998/1/7998 +f 7992/1/7992 7991/1/7991 7998/1/7998 +f 7998/1/7998 8000/1/8000 7999/1/7999 +f 7998/1/7998 7999/1/7999 7997/1/7997 +f 7997/1/7997 7999/1/7999 7815/1/7815 +f 8000/1/8000 8001/1/8001 7999/1/7999 +f 7999/1/7999 8001/1/8001 7821/1/7821 +f 7821/1/7821 8001/1/8001 7835/1/7835 +f 7835/1/7835 7832/1/7832 7821/1/7821 +f 7832/1/7832 7835/1/7835 7834/1/7834 +f 7834/1/7834 7833/1/7833 7832/1/7832 +f 7832/1/7832 7833/1/7833 7831/1/7831 +f 7832/1/7832 7831/1/7831 7822/1/7822 +f 8080/1/8080 7831/1/7831 7833/1/7833 +f 8080/1/8080 7833/1/7833 8084/1/8084 +f 8083/1/8083 8080/1/8080 8084/1/8084 +f 8083/1/8083 8084/1/8084 8085/1/8085 +f 8085/1/8085 7836/1/7836 8083/1/8083 +f 7841/1/7841 8083/1/8083 7836/1/7836 +f 7836/1/7836 7840/1/7840 7841/1/7841 +f 7841/1/7841 7840/1/7840 7950/1/7950 +f 7841/1/7841 7950/1/7950 7948/1/7948 +f 7951/1/7951 7950/1/7950 7840/1/7840 +f 7949/1/7949 7950/1/7950 7951/1/7951 +f 7836/1/7836 7838/1/7838 7840/1/7840 +f 7840/1/7840 7838/1/7838 8003/1/8003 +f 8004/1/8004 7840/1/7840 8003/1/8003 +f 7835/1/7835 8003/1/8003 7838/1/7838 +f 7834/1/7834 7838/1/7838 7836/1/7836 +f 7834/1/7834 7836/1/7836 7837/1/7837 +f 8086/1/8086 7834/1/7834 7837/1/7837 +f 8086/1/8086 7837/1/7837 8088/1/8088 +f 8087/1/8087 8086/1/8086 8088/1/8088 +f 8087/1/8087 8088/1/8088 8089/1/8089 +f 8089/1/8089 7842/1/7842 8087/1/8087 +f 8087/1/8087 7842/1/7842 7839/1/7839 +f 8087/1/8087 7839/1/7839 8085/1/8085 +f 7837/1/7837 7839/1/7839 7842/1/7842 +f 7837/1/7837 7842/1/7842 7843/1/7843 +f 7843/1/7843 7842/1/7842 7844/1/7844 +f 7843/1/7843 7844/1/7844 7845/1/7845 +f 8090/1/8090 7843/1/7843 7845/1/7845 +f 8090/1/8090 7845/1/7845 8092/1/8092 +f 8092/1/8092 8093/1/8093 8090/1/8090 +f 8090/1/8090 8093/1/8093 8091/1/8091 +f 8090/1/8090 8091/1/8091 8088/1/8088 +f 8093/1/8093 7846/1/7846 8091/1/8091 +f 8091/1/8091 7846/1/7846 7844/1/7844 +f 8091/1/8091 7844/1/7844 8089/1/8089 +f 8093/1/8093 7847/1/7847 7846/1/7846 +f 7845/1/7845 7846/1/7846 7847/1/7847 +f 7845/1/7845 7847/1/7847 7848/1/7848 +f 7848/1/7848 7847/1/7847 7849/1/7849 +f 7848/1/7848 7849/1/7849 7851/1/7851 +f 7850/1/7850 7848/1/7848 7851/1/7851 +f 7852/1/7852 7850/1/7850 7851/1/7851 +f 8097/1/8097 7852/1/7852 7851/1/7851 +f 8097/1/8097 7851/1/7851 8095/1/8095 +f 8097/1/8097 8095/1/8095 8094/1/8094 +f 8094/1/8094 8098/1/8098 8097/1/8097 +f 8094/1/8094 8099/1/8099 8098/1/8098 +f 8099/1/8099 7853/1/7853 8098/1/8098 +f 8098/1/8098 7853/1/7853 7852/1/7852 +f 8099/1/8099 7854/1/7854 7853/1/7853 +f 7854/1/7854 7855/1/7855 7853/1/7853 +f 7853/1/7853 7855/1/7855 7850/1/7850 +f 7855/1/7855 7856/1/7856 7850/1/7850 +f 7856/1/7856 7857/1/7857 7850/1/7850 +f 7850/1/7850 7857/1/7857 7858/1/7858 +f 7850/1/7850 7858/1/7858 7859/1/7859 +f 8105/1/8105 7850/1/7850 7859/1/7859 +f 8105/1/8105 7859/1/7859 8107/1/8107 +f 8106/1/8106 8105/1/8105 8107/1/8107 +f 8106/1/8106 8107/1/8107 8108/1/8108 +f 8108/1/8108 7862/1/7862 8106/1/8106 +f 8106/1/8106 7862/1/7862 7860/1/7860 +f 8106/1/8106 7860/1/7860 8104/1/8104 +f 8104/1/8104 7860/1/7860 7858/1/7858 +f 8104/1/8104 7858/1/7858 8103/1/8103 +f 8103/1/8103 8094/1/8094 8104/1/8104 +f 8104/1/8104 8094/1/8094 8105/1/8105 +f 8103/1/8103 8102/1/8102 8094/1/8094 +f 8094/1/8094 8102/1/8102 8101/1/8101 +f 8094/1/8094 8101/1/8101 8100/1/8100 +f 8100/1/8100 8101/1/8101 7855/1/7855 +f 8102/1/8102 7857/1/7857 8101/1/8101 +f 8103/1/8103 7858/1/7858 8102/1/8102 +f 7860/1/7860 7862/1/7862 7861/1/7861 +f 7859/1/7859 7860/1/7860 7861/1/7861 +f 7861/1/7861 7862/1/7862 7863/1/7863 +f 7861/1/7861 7863/1/7863 7864/1/7864 +f 8109/1/8109 7861/1/7861 7864/1/7864 +f 8109/1/8109 7864/1/7864 8112/1/8112 +f 8111/1/8111 8109/1/8109 8112/1/8112 +f 8111/1/8111 8112/1/8112 8066/1/8066 +f 8066/1/8066 7867/1/7867 8111/1/8111 +f 8111/1/8111 7867/1/7867 7865/1/7865 +f 8111/1/8111 7865/1/7865 8110/1/8110 +f 8110/1/8110 7865/1/7865 7863/1/7863 +f 8110/1/8110 7863/1/7863 8108/1/8108 +f 8108/1/8108 8109/1/8109 8110/1/8110 +f 7866/1/7866 7865/1/7865 7867/1/7867 +f 7866/1/7866 7867/1/7867 7829/1/7829 +f 8067/1/8067 7866/1/7866 7829/1/7829 +f 8067/1/8067 7829/1/7829 8077/1/8077 +f 8077/1/8077 8076/1/8076 8067/1/8067 +f 8067/1/8067 8076/1/8076 8075/1/8075 +f 8075/1/8075 8074/1/8074 8067/1/8067 +f 8067/1/8067 8074/1/8074 8073/1/8073 +f 8067/1/8067 8073/1/8073 8072/1/8072 +f 8072/1/8072 8071/1/8071 8067/1/8067 +f 8067/1/8067 8071/1/8071 8070/1/8070 +f 8067/1/8067 8070/1/8070 8069/1/8069 +f 8069/1/8069 8068/1/8068 8067/1/8067 +f 8067/1/8067 8068/1/8068 8065/1/8065 +f 8067/1/8067 8065/1/8065 8064/1/8064 +f 8066/1/8066 8067/1/8067 8064/1/8064 +f 8064/1/8064 7870/1/7870 8066/1/8066 +f 8066/1/8066 7870/1/7870 7868/1/7868 +f 7829/1/7829 7868/1/7868 7870/1/7870 +f 7869/1/7869 7829/1/7829 7870/1/7870 +f 7830/1/7830 7829/1/7829 7869/1/7869 +f 7830/1/7830 7869/1/7869 8062/1/8062 +f 8062/1/8062 7869/1/7869 8063/1/8063 +f 8063/1/8063 8036/1/8036 8062/1/8062 +f 8062/1/8062 8036/1/8036 8035/1/8035 +f 8062/1/8062 8035/1/8035 8034/1/8034 +f 8034/1/8034 8032/1/8032 8062/1/8062 +f 8062/1/8062 8032/1/8032 8030/1/8030 +f 8062/1/8062 8030/1/8030 8031/1/8031 +f 8031/1/8031 8038/1/8038 8062/1/8062 +f 8062/1/8062 8038/1/8038 8040/1/8040 +f 8040/1/8040 8041/1/8041 8062/1/8062 +f 8062/1/8062 8041/1/8041 8044/1/8044 +f 8062/1/8062 8044/1/8044 8060/1/8060 +f 8060/1/8060 8328/1/8328 8062/1/8062 +f 7872/1/7872 8062/1/8062 8328/1/8328 +f 7872/1/7872 8328/1/8328 7874/1/7874 +f 8328/1/8328 8330/1/8330 7874/1/7874 +f 7874/1/7874 8330/1/8330 7876/1/7876 +f 7876/1/7876 7875/1/7875 7874/1/7874 +f 7873/1/7873 7874/1/7874 7875/1/7875 +f 7875/1/7875 8321/1/8321 7873/1/7873 +f 7877/1/7877 8321/1/8321 7875/1/7875 +f 8322/1/8322 8321/1/8321 7877/1/7877 +f 7882/1/7882 8322/1/8322 7877/1/7877 +f 7881/1/7881 7882/1/7882 7877/1/7877 +f 7881/1/7881 7877/1/7877 7878/1/7878 +f 7878/1/7878 8325/1/8325 7881/1/7881 +f 7881/1/7881 8325/1/8325 8324/1/8324 +f 7881/1/7881 8324/1/8324 7883/1/7883 +f 7883/1/7883 8324/1/8324 8323/1/8323 +f 7883/1/7883 8323/1/8323 7882/1/7882 +f 8323/1/8323 8324/1/8324 8322/1/8322 +f 8322/1/8322 8324/1/8324 8325/1/8325 +f 8326/1/8326 8325/1/8325 7878/1/7878 +f 7879/1/7879 8326/1/8326 7878/1/7878 +f 7878/1/7878 7876/1/7876 7879/1/7879 +f 7879/1/7879 7876/1/7876 7880/1/7880 +f 7880/1/7880 8327/1/8327 7879/1/7879 +f 7880/1/7880 8329/1/8329 8327/1/8327 +f 8327/1/8327 8329/1/8329 8326/1/8326 +f 8326/1/8326 8329/1/8329 8330/1/8330 +f 7876/1/7876 8329/1/8329 7880/1/7880 +f 7879/1/7879 8327/1/8327 8326/1/8326 +f 8325/1/8325 8326/1/8326 8328/1/8328 +f 8321/1/8321 8325/1/8325 8328/1/8328 +f 7878/1/7878 7877/1/7877 7876/1/7876 +f 7883/1/7883 7882/1/7882 7881/1/7881 +f 7882/1/7882 8323/1/8323 8322/1/8322 +f 8322/1/8322 8325/1/8325 8321/1/8321 +f 7877/1/7877 7875/1/7875 7876/1/7876 +f 7876/1/7876 8330/1/8330 8329/1/8329 +f 8326/1/8326 8330/1/8330 8328/1/8328 +f 8321/1/8321 8328/1/8328 8060/1/8060 +f 8060/1/8060 8044/1/8044 8051/1/8051 +f 8044/1/8044 8046/1/8046 8051/1/8051 +f 8042/1/8042 8046/1/8046 8044/1/8044 +f 8042/1/8042 8045/1/8045 8046/1/8046 +f 8050/1/8050 8046/1/8046 8045/1/8045 +f 8049/1/8049 8050/1/8050 8045/1/8045 +f 8049/1/8049 8045/1/8045 8047/1/8047 +f 8049/1/8049 8047/1/8047 8048/1/8048 +f 8048/1/8048 8201/1/8201 8049/1/8049 +f 8049/1/8049 8201/1/8201 8202/1/8202 +f 8049/1/8049 8202/1/8202 8055/1/8055 +f 8055/1/8055 8202/1/8202 8192/1/8192 +f 8055/1/8055 8192/1/8192 8190/1/8190 +f 8190/1/8190 8054/1/8054 8055/1/8055 +f 8055/1/8055 8054/1/8054 8050/1/8050 +f 8053/1/8053 8050/1/8050 8054/1/8054 +f 8190/1/8190 8187/1/8187 8054/1/8054 +f 8187/1/8187 8189/1/8189 8054/1/8054 +f 8188/1/8188 8187/1/8187 8190/1/8190 +f 8191/1/8191 8188/1/8188 8190/1/8190 +f 8190/1/8190 8193/1/8193 8191/1/8191 +f 8194/1/8194 8191/1/8191 8193/1/8193 +f 8192/1/8192 8194/1/8194 8193/1/8193 +f 8192/1/8192 8198/1/8198 8194/1/8194 +f 8197/1/8197 8194/1/8194 8198/1/8198 +f 8197/1/8197 8198/1/8198 8200/1/8200 +f 8203/1/8203 8197/1/8197 8200/1/8200 +f 8016/1/8016 8203/1/8203 8200/1/8200 +f 8048/1/8048 8016/1/8016 8200/1/8200 +f 8017/1/8017 8016/1/8016 8048/1/8048 +f 8017/1/8017 8048/1/8048 8024/1/8024 +f 8017/1/8017 8024/1/8024 8018/1/8018 +f 8017/1/8017 8018/1/8018 8015/1/8015 +f 8015/1/8015 8018/1/8018 8019/1/8019 +f 8015/1/8015 8019/1/8019 8014/1/8014 +f 8014/1/8014 8012/1/8012 8015/1/8015 +f 8011/1/8011 8015/1/8015 8012/1/8012 +f 8011/1/8011 8012/1/8012 8007/1/8007 +f 8007/1/8007 8009/1/8009 8011/1/8011 +f 8011/1/8011 8009/1/8009 8203/1/8203 +f 8007/1/8007 8006/1/8006 8009/1/8009 +f 8006/1/8006 8010/1/8010 8009/1/8009 +f 8009/1/8009 8010/1/8010 8197/1/8197 +f 8205/1/8205 8197/1/8197 8010/1/8010 +f 8010/1/8010 8207/1/8207 8205/1/8205 +f 8205/1/8205 8207/1/8207 8208/1/8208 +f 8205/1/8205 8208/1/8208 8204/1/8204 +f 8204/1/8204 8208/1/8208 8211/1/8211 +f 8204/1/8204 8211/1/8211 8216/1/8216 +f 8216/1/8216 8196/1/8196 8204/1/8204 +f 8204/1/8204 8196/1/8196 8197/1/8197 +f 8216/1/8216 8219/1/8219 8196/1/8196 +f 8219/1/8219 8222/1/8222 8196/1/8196 +f 8196/1/8196 8222/1/8222 8199/1/8199 +f 8196/1/8196 8199/1/8199 8194/1/8194 +f 8199/1/8199 8195/1/8195 8194/1/8194 +f 8199/1/8199 8222/1/8222 8195/1/8195 +f 8195/1/8195 8222/1/8222 8219/1/8219 +f 8195/1/8195 8219/1/8219 8223/1/8223 +f 8223/1/8223 8179/1/8179 8195/1/8195 +f 8195/1/8195 8179/1/8179 8191/1/8191 +f 8223/1/8223 8176/1/8176 8179/1/8179 +f 8179/1/8179 8176/1/8176 8177/1/8177 +f 8177/1/8177 8181/1/8181 8179/1/8179 +f 8179/1/8179 8181/1/8181 8184/1/8184 +f 8179/1/8179 8184/1/8184 8188/1/8188 +f 8181/1/8181 8183/1/8183 8184/1/8184 +f 8177/1/8177 8180/1/8180 8181/1/8181 +f 8176/1/8176 8173/1/8173 8177/1/8177 +f 8177/1/8177 8173/1/8173 8175/1/8175 +f 8176/1/8176 8171/1/8171 8173/1/8173 +f 8171/1/8171 8169/1/8169 8173/1/8173 +f 8173/1/8173 8169/1/8169 8170/1/8170 +f 8171/1/8171 8172/1/8172 8169/1/8169 +f 8172/1/8172 8174/1/8174 8169/1/8169 +f 8169/1/8169 8174/1/8174 8164/1/8164 +f 8169/1/8169 8164/1/8164 8167/1/8167 +f 8165/1/8165 8164/1/8164 8174/1/8174 +f 8174/1/8174 8231/1/8231 8165/1/8165 +f 8165/1/8165 8231/1/8231 8232/1/8232 +f 8165/1/8165 8232/1/8232 8156/1/8156 +f 8156/1/8156 8154/1/8154 8165/1/8165 +f 8156/1/8156 8151/1/8151 8154/1/8154 +f 8150/1/8150 8154/1/8154 8151/1/8151 +f 8155/1/8155 8151/1/8151 8156/1/8156 +f 8233/1/8233 8155/1/8155 8156/1/8156 +f 8156/1/8156 8234/1/8234 8233/1/8233 +f 8233/1/8233 8234/1/8234 8232/1/8232 +f 8215/1/8215 8233/1/8233 8232/1/8232 +f 8215/1/8215 8232/1/8232 8212/1/8212 +f 8212/1/8212 8210/1/8210 8215/1/8215 +f 8214/1/8214 8215/1/8215 8210/1/8210 +f 8214/1/8214 8210/1/8210 8209/1/8209 +f 8209/1/8209 8236/1/8236 8214/1/8214 +f 8214/1/8214 8236/1/8236 8237/1/8237 +f 8214/1/8214 8237/1/8237 8238/1/8238 +f 8238/1/8238 8237/1/8237 8239/1/8239 +f 8239/1/8239 8241/1/8241 8238/1/8238 +f 8238/1/8238 8241/1/8241 8242/1/8242 +f 8215/1/8215 8238/1/8238 8242/1/8242 +f 8241/1/8241 8243/1/8243 8242/1/8242 +f 8242/1/8242 8243/1/8243 8233/1/8233 +f 8244/1/8244 8243/1/8243 8241/1/8241 +f 8246/1/8246 8244/1/8244 8241/1/8241 +f 8241/1/8241 8257/1/8257 8246/1/8246 +f 8246/1/8246 8257/1/8257 8250/1/8250 +f 8246/1/8246 8250/1/8250 8248/1/8248 +f 8248/1/8248 8160/1/8160 8246/1/8246 +f 8246/1/8246 8160/1/8160 8247/1/8247 +f 8160/1/8160 8158/1/8158 8247/1/8247 +f 8158/1/8158 8157/1/8157 8247/1/8247 +f 8247/1/8247 8157/1/8157 8245/1/8245 +f 8247/1/8247 8245/1/8245 8244/1/8244 +f 8157/1/8157 8152/1/8152 8245/1/8245 +f 8245/1/8245 8152/1/8152 8243/1/8243 +f 8243/1/8243 8152/1/8152 8155/1/8155 +f 8157/1/8157 8116/1/8116 8152/1/8152 +f 8115/1/8115 8152/1/8152 8116/1/8116 +f 8081/1/8081 8116/1/8116 8157/1/8157 +f 8082/1/8082 8116/1/8116 8081/1/8081 +f 8081/1/8081 8079/1/8079 8082/1/8082 +f 8082/1/8082 8079/1/8079 8080/1/8080 +f 8080/1/8080 8079/1/8079 8078/1/8078 +f 8078/1/8078 8079/1/8079 8077/1/8077 +f 8077/1/8077 7828/1/7828 8078/1/8078 +f 8078/1/8078 7828/1/7828 7831/1/7831 +f 8079/1/8079 8159/1/8159 8077/1/8077 +f 8079/1/8079 8158/1/8158 8159/1/8159 +f 8079/1/8079 8081/1/8081 8158/1/8158 +f 8158/1/8158 8081/1/8081 8157/1/8157 +f 8159/1/8159 8158/1/8158 8160/1/8160 +f 8159/1/8159 8160/1/8160 8076/1/8076 +f 8076/1/8076 8160/1/8160 8161/1/8161 +f 8248/1/8248 8161/1/8161 8160/1/8160 +f 8249/1/8249 8161/1/8161 8248/1/8248 +f 8248/1/8248 8251/1/8251 8249/1/8249 +f 8249/1/8249 8251/1/8251 8254/1/8254 +f 8249/1/8249 8254/1/8254 8252/1/8252 +f 8252/1/8252 8253/1/8253 8249/1/8249 +f 8253/1/8253 8162/1/8162 8249/1/8249 +f 8253/1/8253 8163/1/8163 8162/1/8162 +f 8163/1/8163 8073/1/8073 8162/1/8162 +f 8282/1/8282 8163/1/8163 8253/1/8253 +f 8282/1/8282 8283/1/8283 8163/1/8163 +f 8283/1/8283 8071/1/8071 8163/1/8163 +f 8281/1/8281 8283/1/8283 8282/1/8282 +f 8282/1/8282 8276/1/8276 8281/1/8281 +f 8037/1/8037 8281/1/8281 8276/1/8276 +f 8037/1/8037 8276/1/8276 8273/1/8273 +f 8273/1/8273 8033/1/8033 8037/1/8037 +f 8037/1/8037 8033/1/8033 8036/1/8036 +f 8037/1/8037 8036/1/8036 8065/1/8065 +f 8273/1/8273 8274/1/8274 8033/1/8033 +f 8274/1/8274 8029/1/8029 8033/1/8033 +f 8033/1/8033 8029/1/8029 8028/1/8028 +f 8033/1/8033 8028/1/8028 8034/1/8034 +f 8022/1/8022 8028/1/8028 8029/1/8029 +f 8029/1/8029 8020/1/8020 8022/1/8022 +f 8022/1/8022 8020/1/8020 8019/1/8019 +f 8022/1/8022 8019/1/8019 8023/1/8023 +f 8023/1/8023 8027/1/8027 8022/1/8022 +f 8023/1/8023 8026/1/8026 8027/1/8027 +f 8031/1/8031 8027/1/8027 8026/1/8026 +f 8025/1/8025 8026/1/8026 8023/1/8023 +f 8018/1/8018 8025/1/8025 8023/1/8023 +f 8023/1/8023 8021/1/8021 8018/1/8018 +f 8025/1/8025 8039/1/8039 8026/1/8026 +f 8038/1/8038 8026/1/8026 8039/1/8039 +f 8024/1/8024 8039/1/8039 8025/1/8025 +f 8043/1/8043 8039/1/8039 8024/1/8024 +f 8024/1/8024 8047/1/8047 8043/1/8043 +f 8042/1/8042 8039/1/8039 8043/1/8043 +f 8042/1/8042 8041/1/8041 8039/1/8039 +f 8023/1/8023 8019/1/8019 8021/1/8021 +f 8029/1/8029 8280/1/8280 8020/1/8020 +f 8014/1/8014 8020/1/8020 8280/1/8280 +f 8280/1/8280 8279/1/8279 8014/1/8014 +f 8279/1/8279 8265/1/8265 8014/1/8014 +f 8279/1/8279 8278/1/8278 8265/1/8265 +f 8265/1/8265 8278/1/8278 8271/1/8271 +f 8265/1/8265 8271/1/8271 8268/1/8268 +f 8268/1/8268 8264/1/8264 8265/1/8265 +f 8265/1/8265 8264/1/8264 8262/1/8262 +f 8265/1/8265 8262/1/8262 8012/1/8012 +f 8012/1/8012 8262/1/8262 8013/1/8013 +f 8012/1/8012 8013/1/8013 8008/1/8008 +f 8013/1/8013 8260/1/8260 8008/1/8008 +f 8008/1/8008 8260/1/8260 8261/1/8261 +f 8008/1/8008 8261/1/8261 8005/1/8005 +f 8007/1/8007 8008/1/8008 8005/1/8005 +f 8005/1/8005 8261/1/8261 8235/1/8235 +f 8235/1/8235 8206/1/8206 8005/1/8005 +f 8005/1/8005 8206/1/8206 8006/1/8006 +f 8206/1/8206 8235/1/8235 8209/1/8209 +f 8209/1/8209 8207/1/8207 8206/1/8206 +f 8235/1/8235 8261/1/8261 8236/1/8236 +f 8236/1/8236 8261/1/8261 8240/1/8240 +f 8260/1/8260 8240/1/8240 8261/1/8261 +f 8259/1/8259 8240/1/8240 8260/1/8260 +f 8259/1/8259 8258/1/8258 8240/1/8240 +f 8258/1/8258 8256/1/8256 8240/1/8240 +f 8240/1/8240 8256/1/8256 8255/1/8255 +f 8240/1/8240 8255/1/8255 8239/1/8239 +f 8257/1/8257 8239/1/8239 8255/1/8255 +f 8251/1/8251 8255/1/8255 8256/1/8256 +f 8250/1/8250 8255/1/8255 8251/1/8251 +f 8258/1/8258 8285/1/8285 8256/1/8256 +f 8285/1/8285 8284/1/8284 8256/1/8256 +f 8256/1/8256 8284/1/8284 8252/1/8252 +f 8284/1/8284 8282/1/8282 8252/1/8252 +f 8275/1/8275 8282/1/8282 8284/1/8284 +f 8284/1/8284 8267/1/8267 8275/1/8275 +f 8275/1/8275 8267/1/8267 8269/1/8269 +f 8269/1/8269 8276/1/8276 8275/1/8275 +f 8267/1/8267 8266/1/8266 8269/1/8269 +f 8266/1/8266 8270/1/8270 8269/1/8269 +f 8273/1/8273 8269/1/8269 8270/1/8270 +f 8268/1/8268 8270/1/8270 8266/1/8266 +f 8270/1/8270 8268/1/8268 8272/1/8272 +f 8270/1/8270 8272/1/8272 8274/1/8274 +f 8272/1/8272 8277/1/8277 8274/1/8274 +f 8272/1/8272 8271/1/8271 8277/1/8277 +f 8266/1/8266 8267/1/8267 8263/1/8263 +f 8264/1/8264 8266/1/8266 8263/1/8263 +f 8263/1/8263 8267/1/8267 8258/1/8258 +f 8267/1/8267 8286/1/8286 8258/1/8258 +f 8284/1/8284 8286/1/8286 8267/1/8267 +f 8285/1/8285 8286/1/8286 8284/1/8284 +f 8258/1/8258 8286/1/8286 8285/1/8285 +f 8263/1/8263 8258/1/8258 8259/1/8259 +f 8262/1/8262 8263/1/8263 8259/1/8259 +f 8013/1/8013 8259/1/8259 8260/1/8260 +f 8262/1/8262 8259/1/8259 8013/1/8013 +f 8264/1/8264 8263/1/8263 8262/1/8262 +f 8268/1/8268 8266/1/8266 8264/1/8264 +f 8272/1/8272 8268/1/8268 8271/1/8271 +f 8271/1/8271 8278/1/8278 8277/1/8277 +f 8277/1/8277 8278/1/8278 8279/1/8279 +f 8277/1/8277 8279/1/8279 8280/1/8280 +f 8277/1/8277 8280/1/8280 8029/1/8029 +f 8022/1/8022 8027/1/8027 8028/1/8028 +f 8030/1/8030 8028/1/8028 8027/1/8027 +f 8274/1/8274 8277/1/8277 8029/1/8029 +f 8270/1/8270 8274/1/8274 8273/1/8273 +f 8273/1/8273 8276/1/8276 8269/1/8269 +f 8065/1/8065 8281/1/8281 8037/1/8037 +f 8275/1/8275 8276/1/8276 8282/1/8282 +f 8281/1/8281 8069/1/8069 8283/1/8283 +f 8252/1/8252 8282/1/8282 8253/1/8253 +f 8256/1/8256 8252/1/8252 8254/1/8254 +f 8251/1/8251 8256/1/8256 8254/1/8254 +f 8249/1/8249 8162/1/8162 8161/1/8161 +f 8162/1/8162 8074/1/8074 8161/1/8161 +f 8248/1/8248 8250/1/8250 8251/1/8251 +f 8257/1/8257 8255/1/8255 8250/1/8250 +f 8246/1/8246 8247/1/8247 8244/1/8244 +f 8244/1/8244 8245/1/8245 8243/1/8243 +f 8241/1/8241 8239/1/8239 8257/1/8257 +f 8237/1/8237 8240/1/8240 8239/1/8239 +f 8236/1/8236 8240/1/8240 8237/1/8237 +f 8209/1/8209 8235/1/8235 8236/1/8236 +f 8209/1/8209 8210/1/8210 8207/1/8207 +f 8238/1/8238 8215/1/8215 8214/1/8214 +f 8212/1/8212 8213/1/8213 8210/1/8210 +f 8213/1/8213 8211/1/8211 8210/1/8210 +f 8213/1/8213 8217/1/8217 8211/1/8211 +f 8220/1/8220 8217/1/8217 8213/1/8213 +f 8213/1/8213 8227/1/8227 8220/1/8220 +f 8225/1/8225 8220/1/8220 8227/1/8227 +f 8225/1/8225 8227/1/8227 8226/1/8226 +f 8225/1/8225 8226/1/8226 8172/1/8172 +f 8224/1/8224 8225/1/8225 8172/1/8172 +f 8227/1/8227 8228/1/8228 8226/1/8226 +f 8226/1/8226 8228/1/8228 8229/1/8229 +f 8226/1/8226 8229/1/8229 8230/1/8230 +f 8226/1/8226 8230/1/8230 8174/1/8174 +f 8230/1/8230 8229/1/8229 8212/1/8212 +f 8212/1/8212 8231/1/8231 8230/1/8230 +f 8229/1/8229 8228/1/8228 8213/1/8213 +f 8224/1/8224 8220/1/8220 8225/1/8225 +f 8224/1/8224 8221/1/8221 8220/1/8220 +f 8220/1/8220 8221/1/8221 8218/1/8218 +f 8219/1/8219 8218/1/8218 8221/1/8221 +f 8221/1/8221 8224/1/8224 8171/1/8171 +f 8213/1/8213 8228/1/8228 8227/1/8227 +f 8218/1/8218 8217/1/8217 8220/1/8220 +f 8216/1/8216 8217/1/8217 8218/1/8218 +f 8229/1/8229 8213/1/8213 8212/1/8212 +f 8242/1/8242 8233/1/8233 8215/1/8215 +f 8233/1/8233 8243/1/8243 8155/1/8155 +f 8155/1/8155 8152/1/8152 8151/1/8151 +f 8149/1/8149 8151/1/8151 8152/1/8152 +f 8156/1/8156 8232/1/8232 8234/1/8234 +f 8212/1/8212 8232/1/8232 8231/1/8231 +f 8174/1/8174 8230/1/8230 8231/1/8231 +f 8165/1/8165 8154/1/8154 8164/1/8164 +f 8153/1/8153 8164/1/8164 8154/1/8154 +f 8172/1/8172 8226/1/8226 8174/1/8174 +f 8224/1/8224 8172/1/8172 8171/1/8171 +f 8221/1/8221 8171/1/8171 8176/1/8176 +f 8221/1/8221 8176/1/8176 8223/1/8223 +f 8223/1/8223 8219/1/8219 8221/1/8221 +f 8218/1/8218 8219/1/8219 8216/1/8216 +f 8216/1/8216 8211/1/8211 8217/1/8217 +f 8210/1/8210 8211/1/8211 8208/1/8208 +f 8210/1/8210 8208/1/8208 8207/1/8207 +f 8010/1/8010 8206/1/8206 8207/1/8207 +f 8204/1/8204 8197/1/8197 8205/1/8205 +f 8006/1/8006 8206/1/8206 8010/1/8010 +f 8005/1/8005 8006/1/8006 8007/1/8007 +f 8007/1/8007 8012/1/8012 8008/1/8008 +f 8016/1/8016 8015/1/8015 8011/1/8011 +f 8014/1/8014 8265/1/8265 8012/1/8012 +f 8014/1/8014 8019/1/8019 8020/1/8020 +f 8018/1/8018 8021/1/8021 8019/1/8019 +f 8018/1/8018 8024/1/8024 8025/1/8025 +f 8015/1/8015 8016/1/8016 8017/1/8017 +f 8011/1/8011 8203/1/8203 8016/1/8016 +f 8009/1/8009 8197/1/8197 8203/1/8203 +f 8201/1/8201 8200/1/8200 8198/1/8198 +f 8196/1/8196 8194/1/8194 8197/1/8197 +f 8194/1/8194 8195/1/8195 8191/1/8191 +f 8191/1/8191 8179/1/8179 8188/1/8188 +f 8188/1/8188 8184/1/8184 8187/1/8187 +f 8184/1/8184 8186/1/8186 8187/1/8187 +f 8190/1/8190 8192/1/8192 8193/1/8193 +f 8202/1/8202 8198/1/8198 8192/1/8192 +f 8201/1/8201 8198/1/8198 8202/1/8202 +f 8048/1/8048 8200/1/8200 8201/1/8201 +f 8024/1/8024 8048/1/8048 8047/1/8047 +f 8043/1/8043 8047/1/8047 8045/1/8045 +f 8055/1/8055 8050/1/8050 8049/1/8049 +f 8052/1/8052 8046/1/8046 8050/1/8050 +f 8043/1/8043 8045/1/8045 8042/1/8042 +f 8044/1/8044 8041/1/8041 8042/1/8042 +f 8040/1/8040 8039/1/8039 8041/1/8041 +f 8038/1/8038 8039/1/8039 8040/1/8040 +f 8031/1/8031 8026/1/8026 8038/1/8038 +f 8030/1/8030 8027/1/8027 8031/1/8031 +f 8032/1/8032 8028/1/8028 8030/1/8030 +f 8034/1/8034 8028/1/8028 8032/1/8032 +f 8034/1/8034 8035/1/8035 8033/1/8033 +f 8033/1/8033 8035/1/8035 8036/1/8036 +f 8064/1/8064 8036/1/8036 8063/1/8063 +f 8063/1/8063 7869/1/7869 8064/1/8064 +f 8064/1/8064 7869/1/7869 7870/1/7870 +f 8064/1/8064 8065/1/8065 8036/1/8036 +f 8065/1/8065 8068/1/8068 8281/1/8281 +f 8068/1/8068 8069/1/8069 8281/1/8281 +f 8069/1/8069 8070/1/8070 8283/1/8283 +f 8283/1/8283 8070/1/8070 8071/1/8071 +f 8071/1/8071 8072/1/8072 8163/1/8163 +f 8163/1/8163 8072/1/8072 8073/1/8073 +f 8162/1/8162 8073/1/8073 8074/1/8074 +f 8075/1/8075 8161/1/8161 8074/1/8074 +f 8076/1/8076 8161/1/8161 8075/1/8075 +f 8077/1/8077 8159/1/8159 8076/1/8076 +f 8077/1/8077 7829/1/7829 7828/1/7828 +f 8112/1/8112 7866/1/7866 8067/1/8067 +f 7829/1/7829 7867/1/7867 7868/1/7868 +f 7864/1/7864 7865/1/7865 7866/1/7866 +f 8066/1/8066 7868/1/7868 7867/1/7867 +f 8066/1/8066 8112/1/8112 8067/1/8067 +f 8110/1/8110 8109/1/8109 8111/1/8111 +f 8112/1/8112 7864/1/7864 7866/1/7866 +f 8107/1/8107 7861/1/7861 8109/1/8109 +f 7864/1/7864 7863/1/7863 7865/1/7865 +f 8108/1/8108 7863/1/7863 7862/1/7862 +f 8108/1/8108 8107/1/8107 8109/1/8109 +f 8104/1/8104 8105/1/8105 8106/1/8106 +f 8107/1/8107 7859/1/7859 7861/1/7861 +f 8094/1/8094 7850/1/7850 8105/1/8105 +f 7859/1/7859 7858/1/7858 7860/1/7860 +f 8102/1/8102 7858/1/7858 7857/1/7857 +f 8101/1/8101 7857/1/7857 7856/1/7856 +f 7855/1/7855 8101/1/8101 7856/1/7856 +f 8100/1/8100 7855/1/7855 7854/1/7854 +f 8100/1/8100 7854/1/7854 8099/1/8099 +f 8100/1/8100 8099/1/8099 8094/1/8094 +f 8094/1/8094 8095/1/8095 8092/1/8092 +f 8092/1/8092 7848/1/7848 8094/1/8094 +f 8095/1/8095 8096/1/8096 8092/1/8092 +f 8095/1/8095 7849/1/7849 8096/1/8096 +f 8098/1/8098 7852/1/7852 8097/1/8097 +f 7853/1/7853 7850/1/7850 7852/1/7852 +f 8094/1/8094 7848/1/7848 7850/1/7850 +f 8095/1/8095 7851/1/7851 7849/1/7849 +f 8096/1/8096 7849/1/7849 7847/1/7847 +f 8096/1/8096 7847/1/7847 8093/1/8093 +f 8092/1/8092 8096/1/8096 8093/1/8093 +f 8092/1/8092 7845/1/7845 7848/1/7848 +f 8088/1/8088 7843/1/7843 8090/1/8090 +f 7845/1/7845 7844/1/7844 7846/1/7846 +f 8089/1/8089 7844/1/7844 7842/1/7842 +f 8089/1/8089 8088/1/8088 8091/1/8091 +f 8085/1/8085 8086/1/8086 8087/1/8087 +f 8088/1/8088 7837/1/7837 7843/1/7843 +f 8084/1/8084 7834/1/7834 8086/1/8086 +f 7837/1/7837 7836/1/7836 7839/1/7839 +f 8082/1/8082 8083/1/8083 7841/1/7841 +f 8085/1/8085 7839/1/7839 7836/1/7836 +f 8085/1/8085 8084/1/8084 8086/1/8086 +f 8082/1/8082 8080/1/8080 8083/1/8083 +f 8078/1/8078 7831/1/7831 8080/1/8080 +f 8084/1/8084 7833/1/7833 7834/1/7834 +f 7834/1/7834 7835/1/7835 7838/1/7838 +f 8001/1/8001 8003/1/8003 7835/1/7835 +f 8001/1/8001 8002/1/8002 8003/1/8003 +f 8000/1/8000 8002/1/8002 8001/1/8001 +f 8000/1/8000 7986/1/7986 8002/1/8002 +f 8004/1/8004 8003/1/8003 8002/1/8002 +f 7951/1/7951 7840/1/7840 8004/1/8004 +f 7983/1/7983 7984/1/7984 7976/1/7976 +f 7976/1/7976 7972/1/7972 7973/1/7973 +f 7973/1/7973 7972/1/7972 7969/1/7969 +f 7977/1/7977 7949/1/7949 7951/1/7951 +f 7949/1/7949 7948/1/7948 7950/1/7950 +f 7948/1/7948 7947/1/7947 7841/1/7841 +f 7981/1/7981 7945/1/7945 7946/1/7946 +f 7981/1/7981 7982/1/7982 7945/1/7945 +f 7841/1/7841 7947/1/7947 7944/1/7944 +f 8374/1/8374 8331/1/8331 7841/1/7841 +f 8374/1/8374 8332/1/8332 8331/1/8331 +f 8370/1/8370 8332/1/8332 8374/1/8374 +f 8370/1/8370 8333/1/8333 8332/1/8332 +f 8318/1/8318 8332/1/8332 8333/1/8333 +f 8318/1/8318 8333/1/8333 8320/1/8320 +f 8319/1/8319 8318/1/8318 8320/1/8320 +f 8319/1/8319 8320/1/8320 8366/1/8366 +f 8304/1/8304 8319/1/8319 8366/1/8366 +f 8304/1/8304 8366/1/8366 8367/1/8367 +f 8367/1/8367 8303/1/8303 8304/1/8304 +f 8304/1/8304 8303/1/8303 8302/1/8302 +f 8302/1/8302 8364/1/8364 8304/1/8304 +f 8304/1/8304 8364/1/8364 8365/1/8365 +f 8364/1/8364 8338/1/8338 8365/1/8365 +f 8365/1/8365 8338/1/8338 8334/1/8334 +f 8365/1/8365 8334/1/8334 8369/1/8369 +f 8369/1/8369 8368/1/8368 8365/1/8365 +f 8368/1/8368 8319/1/8319 8365/1/8365 +f 8319/1/8319 8368/1/8368 8317/1/8317 +f 8369/1/8369 8371/1/8371 8368/1/8368 +f 8371/1/8371 8333/1/8333 8368/1/8368 +f 8371/1/8371 8336/1/8336 8333/1/8333 +f 8335/1/8335 8333/1/8333 8336/1/8336 +f 8388/1/8388 8335/1/8335 8336/1/8336 +f 8336/1/8336 8387/1/8387 8388/1/8388 +f 8389/1/8389 8388/1/8388 8387/1/8387 +f 8393/1/8393 8389/1/8389 8387/1/8387 +f 8393/1/8393 8387/1/8387 8395/1/8395 +f 8395/1/8395 8394/1/8394 8393/1/8393 +f 8393/1/8393 8394/1/8394 8392/1/8392 +f 8393/1/8393 8392/1/8392 8391/1/8391 +f 8391/1/8391 8392/1/8392 8390/1/8390 +f 8391/1/8391 8390/1/8390 8389/1/8389 +f 8392/1/8392 8388/1/8388 8390/1/8390 +f 8394/1/8394 8388/1/8388 8392/1/8392 +f 8394/1/8394 8385/1/8385 8388/1/8388 +f 8396/1/8396 8385/1/8385 8394/1/8394 +f 8396/1/8396 8400/1/8400 8385/1/8385 +f 8386/1/8386 8385/1/8385 8400/1/8400 +f 8386/1/8386 8400/1/8400 8399/1/8399 +f 8397/1/8397 8386/1/8386 8399/1/8399 +f 8399/1/8399 8398/1/8398 8397/1/8397 +f 8397/1/8397 8398/1/8398 8396/1/8396 +f 8397/1/8397 8396/1/8396 8395/1/8395 +f 8395/1/8395 8386/1/8386 8397/1/8397 +f 8399/1/8399 8400/1/8400 8398/1/8398 +f 8372/1/8372 8385/1/8385 8386/1/8386 +f 8387/1/8387 8372/1/8372 8386/1/8386 +f 8373/1/8373 8372/1/8372 8387/1/8387 +f 8372/1/8372 8373/1/8373 8371/1/8371 +f 8335/1/8335 8385/1/8385 8372/1/8372 +f 8369/1/8369 8335/1/8335 8372/1/8372 +f 8398/1/8398 8400/1/8400 8396/1/8396 +f 8396/1/8396 8394/1/8394 8395/1/8395 +f 8395/1/8395 8387/1/8387 8386/1/8386 +f 8391/1/8391 8389/1/8389 8393/1/8393 +f 8389/1/8389 8390/1/8390 8388/1/8388 +f 8373/1/8373 8387/1/8387 8336/1/8336 +f 8385/1/8385 8335/1/8335 8388/1/8388 +f 8334/1/8334 8333/1/8333 8335/1/8335 +f 8334/1/8334 8303/1/8303 8333/1/8333 +f 8373/1/8373 8336/1/8336 8371/1/8371 +f 8372/1/8372 8371/1/8371 8369/1/8369 +f 8369/1/8369 8334/1/8334 8335/1/8335 +f 8303/1/8303 8334/1/8334 8338/1/8338 +f 8303/1/8303 8338/1/8338 8301/1/8301 +f 8301/1/8301 8338/1/8338 8348/1/8348 +f 8301/1/8301 8348/1/8348 8299/1/8299 +f 8300/1/8300 8301/1/8301 8299/1/8299 +f 8300/1/8300 8299/1/8299 8298/1/8298 +f 8298/1/8298 8362/1/8362 8300/1/8300 +f 8300/1/8300 8362/1/8362 8363/1/8363 +f 8300/1/8300 8363/1/8363 8302/1/8302 +f 8362/1/8362 8349/1/8349 8363/1/8363 +f 8363/1/8363 8349/1/8349 8348/1/8348 +f 8363/1/8363 8348/1/8348 8364/1/8364 +f 8362/1/8362 8350/1/8350 8349/1/8349 +f 8297/1/8297 8349/1/8349 8350/1/8350 +f 8297/1/8297 8350/1/8350 8295/1/8295 +f 8296/1/8296 8297/1/8297 8295/1/8295 +f 8295/1/8295 8293/1/8293 8296/1/8296 +f 8296/1/8296 8293/1/8293 8294/1/8294 +f 8360/1/8360 8296/1/8296 8294/1/8294 +f 8291/1/8291 8360/1/8360 8294/1/8294 +f 8291/1/8291 8359/1/8359 8360/1/8360 +f 8352/1/8352 8360/1/8360 8359/1/8359 +f 8352/1/8352 8359/1/8359 8353/1/8353 +f 8287/1/8287 8352/1/8352 8353/1/8353 +f 8311/1/8311 8287/1/8287 8353/1/8353 +f 8311/1/8311 8353/1/8353 8355/1/8355 +f 8355/1/8355 8313/1/8313 8311/1/8311 +f 8312/1/8312 8311/1/8311 8313/1/8313 +f 8312/1/8312 8313/1/8313 8314/1/8314 +f 8314/1/8314 8357/1/8357 8312/1/8312 +f 8312/1/8312 8357/1/8357 8358/1/8358 +f 8312/1/8312 8358/1/8358 8356/1/8356 +f 8310/1/8310 8312/1/8312 8356/1/8356 +f 8288/1/8288 8310/1/8310 8356/1/8356 +f 8288/1/8288 8356/1/8356 8359/1/8359 +f 8292/1/8292 8310/1/8310 8288/1/8288 +f 8292/1/8292 8288/1/8288 8290/1/8290 +f 8292/1/8292 8290/1/8290 8305/1/8305 +f 8292/1/8292 8305/1/8305 8306/1/8306 +f 8306/1/8306 8308/1/8308 8292/1/8292 +f 8306/1/8306 8307/1/8307 8308/1/8308 +f 8308/1/8308 8307/1/8307 8309/1/8309 +f 8308/1/8308 8309/1/8309 8310/1/8310 +f 8311/1/8311 8310/1/8310 8309/1/8309 +f 8309/1/8309 8307/1/8307 8305/1/8305 +f 8306/1/8306 8305/1/8305 8307/1/8307 +f 8305/1/8305 8290/1/8290 8309/1/8309 +f 8309/1/8309 8290/1/8290 8287/1/8287 +f 8290/1/8290 8288/1/8288 8287/1/8287 +f 8287/1/8287 8288/1/8288 8289/1/8289 +f 8289/1/8289 8288/1/8288 8291/1/8291 +f 8289/1/8289 8291/1/8291 8293/1/8293 +f 8293/1/8293 8351/1/8351 8289/1/8289 +f 8289/1/8289 8351/1/8351 8352/1/8352 +f 8351/1/8351 8293/1/8293 8350/1/8350 +f 8351/1/8351 8350/1/8350 8360/1/8360 +f 8360/1/8360 8350/1/8350 8361/1/8361 +f 8292/1/8292 8308/1/8308 8310/1/8310 +f 8356/1/8356 8358/1/8358 8353/1/8353 +f 8357/1/8357 8355/1/8355 8358/1/8358 +f 8357/1/8357 8354/1/8354 8355/1/8355 +f 8314/1/8314 8354/1/8354 8357/1/8357 +f 8314/1/8314 8313/1/8313 8354/1/8354 +f 8312/1/8312 8310/1/8310 8311/1/8311 +f 8354/1/8354 8313/1/8313 8355/1/8355 +f 8353/1/8353 8358/1/8358 8355/1/8355 +f 8309/1/8309 8287/1/8287 8311/1/8311 +f 8289/1/8289 8352/1/8352 8287/1/8287 +f 8353/1/8353 8359/1/8359 8356/1/8356 +f 8351/1/8351 8360/1/8360 8352/1/8352 +f 8288/1/8288 8359/1/8359 8291/1/8291 +f 8361/1/8361 8296/1/8296 8360/1/8360 +f 8296/1/8296 8361/1/8361 8298/1/8298 +f 8293/1/8293 8291/1/8291 8294/1/8294 +f 8298/1/8298 8297/1/8297 8296/1/8296 +f 8350/1/8350 8293/1/8293 8295/1/8295 +f 8299/1/8299 8349/1/8349 8297/1/8297 +f 8361/1/8361 8350/1/8350 8362/1/8362 +f 8298/1/8298 8361/1/8361 8362/1/8362 +f 8298/1/8298 8299/1/8299 8297/1/8297 +f 8302/1/8302 8301/1/8301 8300/1/8300 +f 8299/1/8299 8348/1/8348 8349/1/8349 +f 8364/1/8364 8348/1/8348 8338/1/8338 +f 8302/1/8302 8363/1/8363 8364/1/8364 +f 8302/1/8302 8303/1/8303 8301/1/8301 +f 8367/1/8367 8339/1/8339 8303/1/8303 +f 8339/1/8339 8337/1/8337 8303/1/8303 +f 8303/1/8303 8337/1/8337 8320/1/8320 +f 8337/1/8337 8339/1/8339 8340/1/8340 +f 8340/1/8340 8375/1/8375 8337/1/8337 +f 8366/1/8366 8337/1/8337 8375/1/8375 +f 8377/1/8377 8375/1/8375 8340/1/8340 +f 8377/1/8377 8340/1/8340 8343/1/8343 +f 8377/1/8377 8343/1/8343 8381/1/8381 +f 8380/1/8380 8377/1/8377 8381/1/8381 +f 8381/1/8381 8347/1/8347 8380/1/8380 +f 8380/1/8380 8347/1/8347 8342/1/8342 +f 8380/1/8380 8342/1/8342 8379/1/8379 +f 8342/1/8342 8344/1/8344 8379/1/8379 +f 8379/1/8379 8344/1/8344 8382/1/8382 +f 8382/1/8382 8378/1/8378 8379/1/8379 +f 8379/1/8379 8378/1/8378 8377/1/8377 +f 8378/1/8378 8376/1/8376 8377/1/8377 +f 8378/1/8378 8339/1/8339 8376/1/8376 +f 8341/1/8341 8339/1/8339 8378/1/8378 +f 8383/1/8383 8341/1/8341 8378/1/8378 +f 8383/1/8383 8346/1/8346 8341/1/8341 +f 8345/1/8345 8341/1/8341 8346/1/8346 +f 8384/1/8384 8345/1/8345 8346/1/8346 +f 8382/1/8382 8345/1/8345 8384/1/8384 +f 8384/1/8384 8383/1/8383 8382/1/8382 +f 8344/1/8344 8341/1/8341 8345/1/8345 +f 8344/1/8344 8340/1/8340 8341/1/8341 +f 8384/1/8384 8346/1/8346 8383/1/8383 +f 8382/1/8382 8383/1/8383 8378/1/8378 +f 8382/1/8382 8344/1/8344 8345/1/8345 +f 8342/1/8342 8340/1/8340 8344/1/8344 +f 8347/1/8347 8343/1/8343 8342/1/8342 +f 8379/1/8379 8377/1/8377 8380/1/8380 +f 8381/1/8381 8343/1/8343 8347/1/8347 +f 8342/1/8342 8343/1/8343 8340/1/8340 +f 8377/1/8377 8376/1/8376 8375/1/8375 +f 8367/1/8367 8375/1/8375 8376/1/8376 +f 8340/1/8340 8339/1/8339 8341/1/8341 +f 8376/1/8376 8339/1/8339 8367/1/8367 +f 8367/1/8367 8366/1/8366 8375/1/8375 +f 8365/1/8365 8319/1/8319 8304/1/8304 +f 8366/1/8366 8320/1/8320 8337/1/8337 +f 8317/1/8317 8318/1/8318 8319/1/8319 +f 8333/1/8333 8303/1/8303 8320/1/8320 +f 8316/1/8316 8332/1/8332 8318/1/8318 +f 8368/1/8368 8333/1/8333 8370/1/8370 +f 8317/1/8317 8368/1/8368 8370/1/8370 +f 8317/1/8317 8316/1/8316 8318/1/8318 +f 7916/1/7916 8114/1/8114 8315/1/8315 +f 8316/1/8316 8331/1/8331 8332/1/8332 +f 7841/1/7841 8331/1/8331 8082/1/8082 +f 8082/1/8082 8115/1/8115 8116/1/8116 +f 8149/1/8149 8152/1/8152 8115/1/8115 +f 8150/1/8150 8151/1/8151 8149/1/8149 +f 8153/1/8153 8154/1/8154 8150/1/8150 +f 8166/1/8166 8164/1/8164 8153/1/8153 +f 8167/1/8167 8164/1/8164 8166/1/8166 +f 8167/1/8167 8168/1/8168 8169/1/8169 +f 8169/1/8169 8168/1/8168 8170/1/8170 +f 8173/1/8173 8170/1/8170 8175/1/8175 +f 8177/1/8177 8175/1/8175 8178/1/8178 +f 8178/1/8178 8180/1/8180 8177/1/8177 +f 8180/1/8180 8182/1/8182 8181/1/8181 +f 8181/1/8181 8182/1/8182 8183/1/8183 +f 8183/1/8183 8185/1/8185 8184/1/8184 +f 8184/1/8184 8185/1/8185 8186/1/8186 +f 8187/1/8187 8186/1/8186 8189/1/8189 +f 8058/1/8058 8054/1/8054 8189/1/8189 +f 8053/1/8053 8054/1/8054 8058/1/8058 +f 8052/1/8052 8050/1/8050 8053/1/8053 +f 8051/1/8051 8046/1/8046 8052/1/8052 +f 8057/1/8057 7901/1/7901 8056/1/8056 +f 8059/1/8059 7899/1/7899 7898/1/7898 +f 8145/1/8145 7898/1/7898 7893/1/7893 +f 8143/1/8143 7893/1/7893 7891/1/7891 +f 7890/1/7890 7892/1/7892 7891/1/7891 +f 8148/1/8148 7892/1/7892 7890/1/7890 +f 8059/1/8059 8147/1/8147 8148/1/8148 +f 8060/1/8060 8051/1/8051 8059/1/8059 +f 7886/1/7886 7871/1/7871 8061/1/8061 +f 7873/1/7873 8321/1/8321 8060/1/8060 +f 7873/1/7873 7872/1/7872 7874/1/7874 +f 7830/1/7830 8062/1/8062 7872/1/7872 +f 7825/1/7825 7829/1/7829 7830/1/7830 +f 7828/1/7828 7829/1/7829 7825/1/7825 +f 7822/1/7822 7831/1/7831 7828/1/7828 +f 7821/1/7821 7832/1/7832 7822/1/7822 +f 7999/1/7999 7821/1/7821 7815/1/7815 +f 7997/1/7997 7815/1/7815 7816/1/7816 +f 7995/1/7995 7998/1/7998 7997/1/7997 +f 7992/1/7992 7998/1/7998 7995/1/7995 +f 7988/1/7988 7991/1/7991 7992/1/7992 +f 7987/1/7987 7988/1/7988 7989/1/7989 +f 7987/1/7987 7989/1/7989 7970/1/7970 +f 7972/1/7972 7970/1/7970 7969/1/7969 +f 7973/1/7973 7969/1/7969 7974/1/7974 +f 7979/1/7979 7974/1/7974 7978/1/7978 +f 7980/1/7980 7946/1/7946 7979/1/7979 +f 7961/1/7961 7962/1/7962 7965/1/7965 +f 7980/1/7980 7981/1/7981 7946/1/7946 +f 7961/1/7961 7959/1/7959 7962/1/7962 +f 7961/1/7961 7958/1/7958 7959/1/7959 +f 7981/1/7981 7963/1/7963 7982/1/7982 +f 7945/1/7945 7982/1/7982 7942/1/7942 +f 7915/1/7915 7941/1/7941 7942/1/7942 +f 7916/1/7916 7941/1/7941 7915/1/7915 +f 7913/1/7913 8114/1/8114 7916/1/7916 +f 7903/1/7903 7901/1/7901 7913/1/7913 +f 7900/1/7900 7901/1/7901 7903/1/7903 +f 7887/1/7887 7900/1/7900 7788/1/7788 +f 7888/1/7888 7887/1/7887 7788/1/7788 +f 7871/1/7871 7887/1/7887 7888/1/7888 +f 7826/1/7826 7871/1/7871 7889/1/7889 +f 7824/1/7824 7826/1/7826 7827/1/7827 +f 7820/1/7820 7823/1/7823 7824/1/7824 +f 7814/1/7814 7817/1/7817 7820/1/7820 +f 7818/1/7818 7911/1/7911 7819/1/7819 +f 7819/1/7819 7911/1/7911 7910/1/7910 +f 7910/1/7910 7911/1/7911 7908/1/7908 +f 7801/1/7801 7806/1/7806 7807/1/7807 +f 7814/1/7814 7808/1/7808 7810/1/7810 +f 7809/1/7809 7813/1/7813 7810/1/7810 +f 7811/1/7811 7813/1/7813 7809/1/7809 +f 7994/1/7994 7996/1/7996 7811/1/7811 +f 7990/1/7990 7994/1/7994 7993/1/7993 +f 7971/1/7971 7993/1/7993 7968/1/7968 +f 7966/1/7966 7971/1/7971 7968/1/7968 +f 7956/1/7956 7966/1/7966 7957/1/7957 +f 7960/1/7960 7964/1/7964 7956/1/7956 +f 7960/1/7960 7958/1/7958 7961/1/7961 +f 7763/1/7763 7759/1/7759 7764/1/7764 +f 7958/1/7958 7953/1/7953 7959/1/7959 +f 7754/1/7754 7757/1/7757 7954/1/7954 +f 7952/1/7952 7959/1/7959 7953/1/7953 +f 7952/1/7952 7914/1/7914 7943/1/7943 +f 7902/1/7902 7912/1/7912 7914/1/7914 +f 7782/1/7782 7783/1/7783 7902/1/7902 +f 7779/1/7779 7780/1/7780 7782/1/7782 +f 7777/1/7777 7778/1/7778 7779/1/7779 +f 7776/1/7776 7778/1/7778 7777/1/7777 +f 7775/1/7775 7776/1/7776 7772/1/7772 +f 7785/1/7785 7775/1/7775 7792/1/7792 +f 7785/1/7785 7792/1/7792 7789/1/7789 +f 7792/1/7792 7793/1/7793 7789/1/7789 +f 7789/1/7789 7793/1/7793 7794/1/7794 +f 7786/1/7786 7785/1/7785 7789/1/7789 +f 7786/1/7786 7791/1/7791 7787/1/7787 +f 7904/1/7904 7884/1/7884 7791/1/7791 +f 7906/1/7906 7885/1/7885 7904/1/7904 +f 7908/1/7908 7911/1/7911 7906/1/7906 +f 7907/1/7907 7910/1/7910 7908/1/7908 +f 7790/1/7790 7797/1/7797 7905/1/7905 +f 7909/1/7909 7798/1/7798 7907/1/7907 +f 7795/1/7795 7796/1/7796 7797/1/7797 +f 7796/1/7796 7774/1/7774 7769/1/7769 +f 7801/1/7801 7807/1/7807 7798/1/7798 +f 7806/1/7806 7801/1/7801 7800/1/7800 +f 7800/1/7800 7805/1/7805 7806/1/7806 +f 7812/1/7812 7805/1/7805 7804/1/7804 +f 7967/1/7967 7804/1/7804 7803/1/7803 +f 7768/1/7768 7955/1/7955 7803/1/7803 +f 7799/1/7799 7770/1/7770 7802/1/7802 +f 7766/1/7766 7767/1/7767 7768/1/7768 +f 7799/1/7799 7769/1/7769 7770/1/7770 +f 7769/1/7769 7771/1/7771 7765/1/7765 +f 7761/1/7761 7762/1/7762 7766/1/7766 +f 7771/1/7771 7760/1/7760 7765/1/7765 +f 7761/1/7761 7759/1/7759 7762/1/7762 +f 7773/1/7773 7755/1/7755 7760/1/7760 +f 7759/1/7759 7754/1/7754 7954/1/7954 +f 7755/1/7755 7756/1/7756 7751/1/7751 +f 7754/1/7754 7753/1/7753 7757/1/7757 +f 7752/1/7752 7758/1/7758 7753/1/7753 +f 7756/1/7756 7752/1/7752 7751/1/7751 +f 8401/1/8401 8402/1/8402 8403/1/8403 +f 8401/1/8401 8403/1/8403 8404/1/8404 +f 8405/1/8405 8401/1/8401 8404/1/8404 +f 8405/1/8405 8404/1/8404 8410/1/8410 +f 8427/1/8427 8405/1/8405 8410/1/8410 +f 8427/1/8427 8410/1/8410 8428/1/8428 +f 8431/1/8431 8427/1/8427 8428/1/8428 +f 8431/1/8431 8428/1/8428 8571/1/8571 +f 8452/1/8452 8431/1/8431 8571/1/8571 +f 8567/1/8567 8452/1/8452 8571/1/8571 +f 8567/1/8567 8571/1/8571 8570/1/8570 +f 8565/1/8565 8567/1/8567 8570/1/8570 +f 8565/1/8565 8570/1/8570 8568/1/8568 +f 8568/1/8568 8569/1/8569 8565/1/8565 +f 8565/1/8565 8569/1/8569 8566/1/8566 +f 8565/1/8565 8566/1/8566 8563/1/8563 +f 8563/1/8563 8564/1/8564 8565/1/8565 +f 8563/1/8563 8562/1/8562 8564/1/8564 +f 8562/1/8562 8560/1/8560 8564/1/8564 +f 8564/1/8564 8560/1/8560 8452/1/8452 +f 8451/1/8451 8452/1/8452 8560/1/8560 +f 8572/1/8572 8451/1/8451 8560/1/8560 +f 8572/1/8572 8560/1/8560 8561/1/8561 +f 8559/1/8559 8572/1/8572 8561/1/8561 +f 8559/1/8559 8561/1/8561 8558/1/8558 +f 8558/1/8558 8552/1/8552 8559/1/8559 +f 8552/1/8552 8543/1/8543 8559/1/8559 +f 8559/1/8559 8543/1/8543 8573/1/8573 +f 8559/1/8559 8573/1/8573 8450/1/8450 +f 8450/1/8450 8573/1/8573 8453/1/8453 +f 8450/1/8450 8453/1/8453 8444/1/8444 +f 8444/1/8444 8446/1/8446 8450/1/8450 +f 8446/1/8446 8449/1/8449 8450/1/8450 +f 8450/1/8450 8449/1/8449 8572/1/8572 +f 8446/1/8446 8448/1/8448 8449/1/8449 +f 8449/1/8449 8448/1/8448 8451/1/8451 +f 8448/1/8448 8443/1/8443 8451/1/8451 +f 8448/1/8448 8447/1/8447 8443/1/8443 +f 8443/1/8443 8447/1/8447 8442/1/8442 +f 8443/1/8443 8442/1/8442 8440/1/8440 +f 8440/1/8440 8433/1/8433 8443/1/8443 +f 8443/1/8443 8433/1/8433 8429/1/8429 +f 8443/1/8443 8429/1/8429 8452/1/8452 +f 8433/1/8433 8430/1/8430 8429/1/8429 +f 8429/1/8429 8430/1/8430 8427/1/8427 +f 8433/1/8433 8434/1/8434 8430/1/8430 +f 8434/1/8434 8432/1/8432 8430/1/8430 +f 8430/1/8430 8432/1/8432 8405/1/8405 +f 8432/1/8432 8406/1/8406 8405/1/8405 +f 8432/1/8432 8436/1/8436 8406/1/8406 +f 8406/1/8406 8436/1/8436 8402/1/8402 +f 8436/1/8436 8438/1/8438 8402/1/8402 +f 8402/1/8402 8438/1/8438 8408/1/8408 +f 8438/1/8438 8459/1/8459 8408/1/8408 +f 8408/1/8408 8459/1/8459 8460/1/8460 +f 8408/1/8408 8460/1/8460 8414/1/8414 +f 8414/1/8414 8411/1/8411 8408/1/8408 +f 8408/1/8408 8411/1/8411 8407/1/8407 +f 8403/1/8403 8408/1/8408 8407/1/8407 +f 8409/1/8409 8407/1/8407 8411/1/8411 +f 8409/1/8409 8411/1/8411 8412/1/8412 +f 8410/1/8410 8409/1/8409 8412/1/8412 +f 8417/1/8417 8410/1/8410 8412/1/8412 +f 8412/1/8412 8415/1/8415 8417/1/8417 +f 8417/1/8417 8415/1/8415 8422/1/8422 +f 8417/1/8417 8422/1/8422 8423/1/8423 +f 8422/1/8422 8424/1/8424 8423/1/8423 +f 8423/1/8423 8424/1/8424 8644/1/8644 +f 8423/1/8423 8644/1/8644 8425/1/8425 +f 8425/1/8425 8426/1/8426 8423/1/8423 +f 8423/1/8423 8426/1/8426 8410/1/8410 +f 8571/1/8571 8426/1/8426 8425/1/8425 +f 8425/1/8425 8644/1/8644 8570/1/8570 +f 8424/1/8424 8642/1/8642 8644/1/8644 +f 8568/1/8568 8644/1/8644 8642/1/8642 +f 8424/1/8424 8471/1/8471 8642/1/8642 +f 8471/1/8471 8643/1/8643 8642/1/8642 +f 8643/1/8643 8578/1/8578 8642/1/8642 +f 8642/1/8642 8578/1/8578 8569/1/8569 +f 8643/1/8643 8577/1/8577 8578/1/8578 +f 8577/1/8577 8566/1/8566 8578/1/8578 +f 8577/1/8577 8574/1/8574 8566/1/8566 +f 8574/1/8574 8575/1/8575 8566/1/8566 +f 8566/1/8566 8575/1/8575 8576/1/8576 +f 8566/1/8566 8576/1/8576 8557/1/8557 +f 8576/1/8576 8554/1/8554 8557/1/8557 +f 8557/1/8557 8554/1/8554 8553/1/8553 +f 8556/1/8556 8557/1/8557 8553/1/8553 +f 8553/1/8553 8551/1/8551 8556/1/8556 +f 8556/1/8556 8551/1/8551 8558/1/8558 +f 8560/1/8560 8556/1/8556 8558/1/8558 +f 8550/1/8550 8551/1/8551 8553/1/8553 +f 8550/1/8550 8553/1/8553 8548/1/8548 +f 8544/1/8544 8550/1/8550 8548/1/8548 +f 8548/1/8548 8545/1/8545 8544/1/8544 +f 8545/1/8545 8540/1/8540 8544/1/8544 +f 8540/1/8540 8542/1/8542 8544/1/8544 +f 8544/1/8544 8542/1/8542 8549/1/8549 +f 8549/1/8549 8542/1/8542 8543/1/8543 +f 8543/1/8543 8542/1/8542 8528/1/8528 +f 8528/1/8528 8527/1/8527 8543/1/8543 +f 8543/1/8543 8527/1/8527 8526/1/8526 +f 8527/1/8527 8497/1/8497 8526/1/8526 +f 8497/1/8497 8525/1/8525 8526/1/8526 +f 8573/1/8573 8526/1/8526 8525/1/8525 +f 8497/1/8497 8473/1/8473 8525/1/8525 +f 8453/1/8453 8525/1/8525 8473/1/8473 +f 8453/1/8453 8473/1/8473 8454/1/8454 +f 8454/1/8454 8473/1/8473 8455/1/8455 +f 8454/1/8454 8455/1/8455 8445/1/8445 +f 8444/1/8444 8454/1/8454 8445/1/8445 +f 8444/1/8444 8445/1/8445 8439/1/8439 +f 8439/1/8439 8441/1/8441 8444/1/8444 +f 8439/1/8439 8440/1/8440 8441/1/8441 +f 8439/1/8439 8435/1/8435 8440/1/8440 +f 8440/1/8440 8435/1/8435 8434/1/8434 +f 8439/1/8439 8437/1/8437 8435/1/8435 +f 8435/1/8435 8437/1/8437 8436/1/8436 +f 8445/1/8445 8437/1/8437 8439/1/8439 +f 8445/1/8445 8456/1/8456 8437/1/8437 +f 8437/1/8437 8456/1/8456 8438/1/8438 +f 8455/1/8455 8456/1/8456 8445/1/8445 +f 8455/1/8455 8458/1/8458 8456/1/8456 +f 8459/1/8459 8456/1/8456 8458/1/8458 +f 8458/1/8458 8487/1/8487 8459/1/8459 +f 8459/1/8459 8487/1/8487 8485/1/8485 +f 8487/1/8487 8486/1/8486 8485/1/8485 +f 8485/1/8485 8486/1/8486 8484/1/8484 +f 8485/1/8485 8484/1/8484 8476/1/8476 +f 8460/1/8460 8485/1/8485 8476/1/8476 +f 8460/1/8460 8476/1/8476 8461/1/8461 +f 8461/1/8461 8476/1/8476 8463/1/8463 +f 8461/1/8461 8463/1/8463 8462/1/8462 +f 8414/1/8414 8461/1/8461 8462/1/8462 +f 8462/1/8462 8419/1/8419 8414/1/8414 +f 8419/1/8419 8413/1/8413 8414/1/8414 +f 8418/1/8418 8413/1/8413 8419/1/8419 +f 8418/1/8418 8419/1/8419 8464/1/8464 +f 8418/1/8418 8464/1/8464 8467/1/8467 +f 8421/1/8421 8418/1/8418 8467/1/8467 +f 8421/1/8421 8467/1/8467 8468/1/8468 +f 8468/1/8468 8469/1/8469 8421/1/8421 +f 8469/1/8469 8420/1/8420 8421/1/8421 +f 8420/1/8420 8416/1/8416 8421/1/8421 +f 8415/1/8415 8416/1/8416 8420/1/8420 +f 8472/1/8472 8420/1/8420 8469/1/8469 +f 8472/1/8472 8470/1/8470 8420/1/8420 +f 8470/1/8470 8471/1/8471 8420/1/8420 +f 8422/1/8422 8420/1/8420 8471/1/8471 +f 8470/1/8470 8599/1/8599 8471/1/8471 +f 8599/1/8599 8593/1/8593 8471/1/8471 +f 8599/1/8599 8592/1/8592 8593/1/8593 +f 8592/1/8592 8591/1/8591 8593/1/8593 +f 8593/1/8593 8591/1/8591 8577/1/8577 +f 8592/1/8592 8590/1/8590 8591/1/8591 +f 8590/1/8590 8587/1/8587 8591/1/8591 +f 8591/1/8591 8587/1/8587 8574/1/8574 +f 8587/1/8587 8585/1/8585 8574/1/8574 +f 8574/1/8574 8585/1/8585 8581/1/8581 +f 8585/1/8585 8582/1/8582 8581/1/8581 +f 8581/1/8581 8582/1/8582 8580/1/8580 +f 8581/1/8581 8580/1/8580 8575/1/8575 +f 8575/1/8575 8580/1/8580 8579/1/8579 +f 8580/1/8580 8555/1/8555 8579/1/8579 +f 8555/1/8555 8554/1/8554 8579/1/8579 +f 8548/1/8548 8554/1/8554 8555/1/8555 +f 8555/1/8555 8546/1/8546 8548/1/8548 +f 8555/1/8555 8584/1/8584 8546/1/8546 +f 8584/1/8584 8547/1/8547 8546/1/8546 +f 8546/1/8546 8547/1/8547 8541/1/8541 +f 8546/1/8546 8541/1/8541 8545/1/8545 +f 8547/1/8547 8539/1/8539 8541/1/8541 +f 8541/1/8541 8539/1/8539 8532/1/8532 +f 8541/1/8541 8532/1/8532 8540/1/8540 +f 8532/1/8532 8528/1/8528 8540/1/8540 +f 8532/1/8532 8529/1/8529 8528/1/8528 +f 8528/1/8528 8529/1/8529 8497/1/8497 +f 8497/1/8497 8529/1/8529 8530/1/8530 +f 8497/1/8497 8530/1/8530 8531/1/8531 +f 8531/1/8531 8720/1/8720 8497/1/8497 +f 8723/1/8723 8497/1/8497 8720/1/8720 +f 8720/1/8720 8722/1/8722 8723/1/8723 +f 8723/1/8723 8722/1/8722 8725/1/8725 +f 8725/1/8725 8498/1/8498 8723/1/8723 +f 8723/1/8723 8498/1/8498 8495/1/8495 +f 8498/1/8498 8496/1/8496 8495/1/8495 +f 8495/1/8495 8496/1/8496 8457/1/8457 +f 8495/1/8495 8457/1/8457 8497/1/8497 +f 8457/1/8457 8496/1/8496 8494/1/8494 +f 8494/1/8494 8493/1/8493 8457/1/8457 +f 8457/1/8457 8493/1/8493 8492/1/8492 +f 8457/1/8457 8492/1/8492 8458/1/8458 +f 8458/1/8458 8492/1/8492 8488/1/8488 +f 8724/1/8724 8488/1/8488 8492/1/8492 +f 8724/1/8724 8492/1/8492 8722/1/8722 +f 8722/1/8722 8721/1/8721 8724/1/8724 +f 8721/1/8721 8804/1/8804 8724/1/8724 +f 8724/1/8724 8804/1/8804 8761/1/8761 +f 8724/1/8724 8761/1/8761 8759/1/8759 +f 8759/1/8759 8761/1/8761 8762/1/8762 +f 8762/1/8762 8768/1/8768 8759/1/8759 +f 8759/1/8759 8768/1/8768 8769/1/8769 +f 8759/1/8759 8769/1/8769 8770/1/8770 +f 8770/1/8770 8774/1/8774 8759/1/8759 +f 8759/1/8759 8774/1/8774 8775/1/8775 +f 8759/1/8759 8775/1/8775 8776/1/8776 +f 8776/1/8776 8777/1/8777 8759/1/8759 +f 8759/1/8759 8777/1/8777 8778/1/8778 +f 8759/1/8759 8778/1/8778 8771/1/8771 +f 8771/1/8771 8772/1/8772 8759/1/8759 +f 8759/1/8759 8772/1/8772 8773/1/8773 +f 8759/1/8759 8773/1/8773 8763/1/8763 +f 8763/1/8763 8764/1/8764 8759/1/8759 +f 8764/1/8764 8766/1/8766 8759/1/8759 +f 8759/1/8759 8766/1/8766 8767/1/8767 +f 8759/1/8759 8767/1/8767 8765/1/8765 +f 8759/1/8759 8765/1/8765 8760/1/8760 +f 8759/1/8759 8760/1/8760 8757/1/8757 +f 8757/1/8757 8489/1/8489 8759/1/8759 +f 8759/1/8759 8489/1/8489 8488/1/8488 +f 8488/1/8488 8489/1/8489 8486/1/8486 +f 8486/1/8486 8489/1/8489 8490/1/8490 +f 8486/1/8486 8490/1/8490 8491/1/8491 +f 8755/1/8755 8486/1/8486 8491/1/8491 +f 8755/1/8755 8491/1/8491 8756/1/8756 +f 8752/1/8752 8755/1/8755 8756/1/8756 +f 8752/1/8752 8756/1/8756 8753/1/8753 +f 8752/1/8752 8753/1/8753 8749/1/8749 +f 8749/1/8749 8521/1/8521 8752/1/8752 +f 8752/1/8752 8521/1/8521 8524/1/8524 +f 8752/1/8752 8524/1/8524 8754/1/8754 +f 8754/1/8754 8524/1/8524 8490/1/8490 +f 8754/1/8754 8490/1/8490 8757/1/8757 +f 8757/1/8757 8758/1/8758 8754/1/8754 +f 8754/1/8754 8758/1/8758 8755/1/8755 +f 8523/1/8523 8524/1/8524 8521/1/8521 +f 8523/1/8523 8521/1/8521 8522/1/8522 +f 8753/1/8753 8523/1/8523 8522/1/8522 +f 8753/1/8753 8522/1/8522 8750/1/8750 +f 8750/1/8750 8522/1/8522 8520/1/8520 +f 8750/1/8750 8520/1/8520 8751/1/8751 +f 8750/1/8750 8751/1/8751 8747/1/8747 +f 8749/1/8749 8750/1/8750 8747/1/8747 +f 8747/1/8747 8519/1/8519 8749/1/8749 +f 8747/1/8747 8514/1/8514 8519/1/8519 +f 8518/1/8518 8519/1/8519 8514/1/8514 +f 8518/1/8518 8514/1/8514 8517/1/8517 +f 8748/1/8748 8518/1/8518 8517/1/8517 +f 8748/1/8748 8517/1/8517 8746/1/8746 +f 8745/1/8745 8748/1/8748 8746/1/8746 +f 8745/1/8745 8746/1/8746 8744/1/8744 +f 8744/1/8744 8736/1/8736 8745/1/8745 +f 8736/1/8736 8507/1/8507 8745/1/8745 +f 8745/1/8745 8507/1/8507 8514/1/8514 +f 8513/1/8513 8514/1/8514 8507/1/8507 +f 8513/1/8513 8507/1/8507 8515/1/8515 +f 8744/1/8744 8513/1/8513 8515/1/8515 +f 8744/1/8744 8515/1/8515 8743/1/8743 +f 8743/1/8743 8515/1/8515 8516/1/8516 +f 8743/1/8743 8516/1/8516 8742/1/8742 +f 8743/1/8743 8742/1/8742 8736/1/8736 +f 8736/1/8736 8742/1/8742 8741/1/8741 +f 8736/1/8736 8741/1/8741 8740/1/8740 +f 8740/1/8740 8739/1/8739 8736/1/8736 +f 8739/1/8739 8738/1/8738 8736/1/8736 +f 8736/1/8736 8738/1/8738 8737/1/8737 +f 8736/1/8736 8737/1/8737 8733/1/8733 +f 8733/1/8733 8505/1/8505 8736/1/8736 +f 8733/1/8733 8503/1/8503 8505/1/8505 +f 8503/1/8503 8504/1/8504 8505/1/8505 +f 8505/1/8505 8504/1/8504 8506/1/8506 +f 8505/1/8505 8506/1/8506 8507/1/8507 +f 8507/1/8507 8506/1/8506 8508/1/8508 +f 8507/1/8507 8508/1/8508 8509/1/8509 +f 8509/1/8509 8510/1/8510 8507/1/8507 +f 8507/1/8507 8510/1/8510 8511/1/8511 +f 8507/1/8507 8511/1/8511 8512/1/8512 +f 8741/1/8741 8512/1/8512 8511/1/8511 +f 8510/1/8510 8740/1/8740 8511/1/8511 +f 8738/1/8738 8510/1/8510 8509/1/8509 +f 8737/1/8737 8509/1/8509 8508/1/8508 +f 8737/1/8737 8508/1/8508 8506/1/8506 +f 8737/1/8737 8506/1/8506 8734/1/8734 +f 8734/1/8734 8506/1/8506 8504/1/8504 +f 8734/1/8734 8504/1/8504 8735/1/8735 +f 8731/1/8731 8734/1/8734 8735/1/8735 +f 8731/1/8731 8735/1/8735 8732/1/8732 +f 8731/1/8731 8732/1/8732 8729/1/8729 +f 8729/1/8729 8496/1/8496 8731/1/8731 +f 8731/1/8731 8496/1/8496 8503/1/8503 +f 8496/1/8496 8502/1/8502 8503/1/8503 +f 8496/1/8496 8501/1/8501 8502/1/8502 +f 8732/1/8732 8502/1/8502 8501/1/8501 +f 8732/1/8732 8501/1/8501 8730/1/8730 +f 8730/1/8730 8501/1/8501 8500/1/8500 +f 8730/1/8730 8500/1/8500 8727/1/8727 +f 8726/1/8726 8730/1/8730 8727/1/8727 +f 8726/1/8726 8727/1/8727 8722/1/8722 +f 8722/1/8722 8493/1/8493 8726/1/8726 +f 8722/1/8722 8727/1/8727 8728/1/8728 +f 8727/1/8727 8499/1/8499 8728/1/8728 +f 8728/1/8728 8499/1/8499 8725/1/8725 +f 8729/1/8729 8730/1/8730 8726/1/8726 +f 8726/1/8726 8494/1/8494 8729/1/8729 +f 8727/1/8727 8500/1/8500 8499/1/8499 +f 8496/1/8496 8499/1/8499 8500/1/8500 +f 8500/1/8500 8501/1/8501 8496/1/8496 +f 8729/1/8729 8732/1/8732 8730/1/8730 +f 8735/1/8735 8502/1/8502 8732/1/8732 +f 8733/1/8733 8734/1/8734 8731/1/8731 +f 8735/1/8735 8504/1/8504 8502/1/8502 +f 8503/1/8503 8502/1/8502 8504/1/8504 +f 8731/1/8731 8503/1/8503 8733/1/8733 +f 8733/1/8733 8737/1/8737 8734/1/8734 +f 8738/1/8738 8509/1/8509 8737/1/8737 +f 8739/1/8739 8510/1/8510 8738/1/8738 +f 8739/1/8739 8740/1/8740 8510/1/8510 +f 8741/1/8741 8511/1/8511 8740/1/8740 +f 8742/1/8742 8512/1/8512 8741/1/8741 +f 8742/1/8742 8516/1/8516 8512/1/8512 +f 8515/1/8515 8512/1/8512 8516/1/8516 +f 8515/1/8515 8507/1/8507 8512/1/8512 +f 8736/1/8736 8505/1/8505 8507/1/8507 +f 8743/1/8743 8736/1/8736 8744/1/8744 +f 8746/1/8746 8513/1/8513 8744/1/8744 +f 8747/1/8747 8748/1/8748 8745/1/8745 +f 8746/1/8746 8517/1/8517 8513/1/8513 +f 8751/1/8751 8518/1/8518 8748/1/8748 +f 8517/1/8517 8514/1/8514 8513/1/8513 +f 8520/1/8520 8519/1/8519 8518/1/8518 +f 8521/1/8521 8519/1/8519 8520/1/8520 +f 8745/1/8745 8514/1/8514 8747/1/8747 +f 8747/1/8747 8751/1/8751 8748/1/8748 +f 8751/1/8751 8520/1/8520 8518/1/8518 +f 8522/1/8522 8521/1/8521 8520/1/8520 +f 8491/1/8491 8524/1/8524 8523/1/8523 +f 8749/1/8749 8519/1/8519 8521/1/8521 +f 8749/1/8749 8753/1/8753 8750/1/8750 +f 8756/1/8756 8523/1/8523 8753/1/8753 +f 8754/1/8754 8755/1/8755 8752/1/8752 +f 8756/1/8756 8491/1/8491 8523/1/8523 +f 8755/1/8755 8758/1/8758 8486/1/8486 +f 8491/1/8491 8490/1/8490 8524/1/8524 +f 8757/1/8757 8490/1/8490 8489/1/8489 +f 8757/1/8757 8760/1/8760 8758/1/8758 +f 8758/1/8758 8760/1/8760 8975/1/8975 +f 8758/1/8758 8975/1/8975 8960/1/8960 +f 8959/1/8959 8758/1/8758 8960/1/8960 +f 8959/1/8959 8960/1/8960 8961/1/8961 +f 8961/1/8961 9020/1/9020 8959/1/8959 +f 8959/1/8959 9020/1/9020 9032/1/9032 +f 8959/1/8959 9032/1/9032 8484/1/8484 +f 8484/1/8484 9032/1/9032 8479/1/8479 +f 8479/1/8479 8474/1/8474 8484/1/8484 +f 8484/1/8484 8474/1/8474 8475/1/8475 +f 8474/1/8474 8463/1/8463 8475/1/8475 +f 8465/1/8465 8463/1/8463 8474/1/8474 +f 8466/1/8466 8465/1/8465 8474/1/8474 +f 8474/1/8474 8477/1/8477 8466/1/8466 +f 8466/1/8466 8477/1/8477 8478/1/8478 +f 8466/1/8466 8478/1/8478 8481/1/8481 +f 8468/1/8468 8466/1/8466 8481/1/8481 +f 8468/1/8468 8481/1/8481 8605/1/8605 +f 8605/1/8605 8472/1/8472 8468/1/8468 +f 8605/1/8605 8604/1/8604 8472/1/8472 +f 8603/1/8603 8604/1/8604 8605/1/8605 +f 8598/1/8598 8603/1/8603 8605/1/8605 +f 8605/1/8605 8606/1/8606 8598/1/8598 +f 8598/1/8598 8606/1/8606 8607/1/8607 +f 8598/1/8598 8607/1/8607 8597/1/8597 +f 8598/1/8598 8597/1/8597 8594/1/8594 +f 8594/1/8594 8596/1/8596 8598/1/8598 +f 8594/1/8594 8595/1/8595 8596/1/8596 +f 8596/1/8596 8595/1/8595 8600/1/8600 +f 8596/1/8596 8600/1/8600 8603/1/8603 +f 8600/1/8600 8602/1/8602 8603/1/8603 +f 8603/1/8603 8602/1/8602 8601/1/8601 +f 8601/1/8601 8602/1/8602 8599/1/8599 +f 8599/1/8599 8602/1/8602 8600/1/8600 +f 8599/1/8599 8600/1/8600 8595/1/8595 +f 8594/1/8594 8590/1/8590 8595/1/8595 +f 8588/1/8588 8590/1/8590 8594/1/8594 +f 8588/1/8588 8594/1/8594 8589/1/8589 +f 8588/1/8588 8589/1/8589 8586/1/8586 +f 8587/1/8587 8588/1/8588 8586/1/8586 +f 8586/1/8586 8589/1/8589 8583/1/8583 +f 8586/1/8586 8583/1/8583 8582/1/8582 +f 8582/1/8582 8583/1/8583 8555/1/8555 +f 8589/1/8589 8610/1/8610 8583/1/8583 +f 8583/1/8583 8610/1/8610 8584/1/8584 +f 8584/1/8584 8610/1/8610 8611/1/8611 +f 8611/1/8611 8612/1/8612 8584/1/8584 +f 8612/1/8612 8611/1/8611 8613/1/8613 +f 8613/1/8613 8615/1/8615 8612/1/8612 +f 8612/1/8612 8615/1/8615 8616/1/8616 +f 8612/1/8612 8616/1/8616 8547/1/8547 +f 8808/1/8808 8616/1/8616 8615/1/8615 +f 8808/1/8808 8615/1/8615 8814/1/8814 +f 8809/1/8809 8808/1/8808 8814/1/8814 +f 8809/1/8809 8814/1/8814 8815/1/8815 +f 8815/1/8815 8482/1/8482 8809/1/8809 +f 8479/1/8479 8809/1/8809 8482/1/8482 +f 8482/1/8482 8483/1/8483 8479/1/8479 +f 8479/1/8479 8483/1/8483 8480/1/8480 +f 8479/1/8479 8480/1/8480 8478/1/8478 +f 8606/1/8606 8480/1/8480 8483/1/8483 +f 8481/1/8481 8480/1/8480 8606/1/8606 +f 8482/1/8482 8609/1/8609 8483/1/8483 +f 8483/1/8483 8609/1/8609 8608/1/8608 +f 8607/1/8607 8483/1/8483 8608/1/8608 +f 8611/1/8611 8608/1/8608 8609/1/8609 +f 8613/1/8613 8609/1/8609 8482/1/8482 +f 8613/1/8613 8482/1/8482 8614/1/8614 +f 8816/1/8816 8613/1/8613 8614/1/8614 +f 8816/1/8816 8614/1/8614 8818/1/8818 +f 8817/1/8817 8816/1/8816 8818/1/8818 +f 8817/1/8817 8818/1/8818 8819/1/8819 +f 8819/1/8819 8617/1/8617 8817/1/8817 +f 8817/1/8817 8617/1/8617 8619/1/8619 +f 8817/1/8817 8619/1/8619 8815/1/8815 +f 8614/1/8614 8619/1/8619 8617/1/8617 +f 8614/1/8614 8617/1/8617 8618/1/8618 +f 8618/1/8618 8617/1/8617 8620/1/8620 +f 8618/1/8618 8620/1/8620 8621/1/8621 +f 8820/1/8820 8618/1/8618 8621/1/8621 +f 8820/1/8820 8621/1/8621 8822/1/8822 +f 8822/1/8822 8823/1/8823 8820/1/8820 +f 8820/1/8820 8823/1/8823 8821/1/8821 +f 8820/1/8820 8821/1/8821 8818/1/8818 +f 8823/1/8823 8622/1/8622 8821/1/8821 +f 8821/1/8821 8622/1/8622 8620/1/8620 +f 8821/1/8821 8620/1/8620 8819/1/8819 +f 8823/1/8823 8623/1/8623 8622/1/8622 +f 8621/1/8621 8622/1/8622 8623/1/8623 +f 8621/1/8621 8623/1/8623 8624/1/8624 +f 8624/1/8624 8623/1/8623 8625/1/8625 +f 8624/1/8624 8625/1/8625 8626/1/8626 +f 8627/1/8627 8624/1/8624 8626/1/8626 +f 8628/1/8628 8627/1/8627 8626/1/8626 +f 8827/1/8827 8628/1/8628 8626/1/8626 +f 8827/1/8827 8626/1/8626 8825/1/8825 +f 8827/1/8827 8825/1/8825 8824/1/8824 +f 8824/1/8824 8828/1/8828 8827/1/8827 +f 8824/1/8824 8829/1/8829 8828/1/8828 +f 8829/1/8829 8629/1/8629 8828/1/8828 +f 8828/1/8828 8629/1/8629 8628/1/8628 +f 8829/1/8829 8630/1/8630 8629/1/8629 +f 8630/1/8630 8631/1/8631 8629/1/8629 +f 8629/1/8629 8631/1/8631 8627/1/8627 +f 8631/1/8631 8632/1/8632 8627/1/8627 +f 8632/1/8632 8633/1/8633 8627/1/8627 +f 8627/1/8627 8633/1/8633 8634/1/8634 +f 8627/1/8627 8634/1/8634 8635/1/8635 +f 8835/1/8835 8627/1/8627 8635/1/8635 +f 8835/1/8835 8635/1/8635 8837/1/8837 +f 8836/1/8836 8835/1/8835 8837/1/8837 +f 8836/1/8836 8837/1/8837 8838/1/8838 +f 8838/1/8838 8638/1/8638 8836/1/8836 +f 8836/1/8836 8638/1/8638 8636/1/8636 +f 8836/1/8836 8636/1/8636 8834/1/8834 +f 8834/1/8834 8636/1/8636 8634/1/8634 +f 8834/1/8834 8634/1/8634 8833/1/8833 +f 8833/1/8833 8824/1/8824 8834/1/8834 +f 8834/1/8834 8824/1/8824 8835/1/8835 +f 8833/1/8833 8832/1/8832 8824/1/8824 +f 8824/1/8824 8832/1/8832 8831/1/8831 +f 8824/1/8824 8831/1/8831 8830/1/8830 +f 8830/1/8830 8831/1/8831 8631/1/8631 +f 8832/1/8832 8633/1/8633 8831/1/8831 +f 8833/1/8833 8634/1/8634 8832/1/8832 +f 8636/1/8636 8638/1/8638 8637/1/8637 +f 8635/1/8635 8636/1/8636 8637/1/8637 +f 8637/1/8637 8638/1/8638 8639/1/8639 +f 8637/1/8637 8639/1/8639 8640/1/8640 +f 8839/1/8839 8637/1/8637 8640/1/8640 +f 8839/1/8839 8640/1/8640 8842/1/8842 +f 8841/1/8841 8839/1/8839 8842/1/8842 +f 8841/1/8841 8842/1/8842 8843/1/8843 +f 8843/1/8843 8537/1/8537 8841/1/8841 +f 8841/1/8841 8537/1/8537 8641/1/8641 +f 8841/1/8841 8641/1/8641 8840/1/8840 +f 8840/1/8840 8641/1/8641 8639/1/8639 +f 8840/1/8840 8639/1/8639 8838/1/8838 +f 8838/1/8838 8839/1/8839 8840/1/8840 +f 8536/1/8536 8641/1/8641 8537/1/8537 +f 8536/1/8536 8537/1/8537 8533/1/8533 +f 8844/1/8844 8536/1/8536 8533/1/8533 +f 8844/1/8844 8533/1/8533 8811/1/8811 +f 8811/1/8811 8875/1/8875 8844/1/8844 +f 8844/1/8844 8875/1/8875 8874/1/8874 +f 8874/1/8874 8868/1/8868 8844/1/8844 +f 8844/1/8844 8868/1/8868 8867/1/8867 +f 8844/1/8844 8867/1/8867 8871/1/8871 +f 8871/1/8871 8870/1/8870 8844/1/8844 +f 8844/1/8844 8870/1/8870 8873/1/8873 +f 8844/1/8844 8873/1/8873 8872/1/8872 +f 8872/1/8872 8848/1/8848 8844/1/8844 +f 8844/1/8844 8848/1/8848 8846/1/8846 +f 8844/1/8844 8846/1/8846 8845/1/8845 +f 8843/1/8843 8844/1/8844 8845/1/8845 +f 8845/1/8845 8535/1/8535 8843/1/8843 +f 8843/1/8843 8535/1/8535 8538/1/8538 +f 8533/1/8533 8538/1/8538 8535/1/8535 +f 8534/1/8534 8533/1/8533 8535/1/8535 +f 8529/1/8529 8533/1/8533 8534/1/8534 +f 8529/1/8529 8534/1/8534 8715/1/8715 +f 8715/1/8715 8534/1/8534 8850/1/8850 +f 8850/1/8850 8847/1/8847 8715/1/8715 +f 8715/1/8715 8847/1/8847 8851/1/8851 +f 8715/1/8715 8851/1/8851 8883/1/8883 +f 8883/1/8883 8884/1/8884 8715/1/8715 +f 8715/1/8715 8884/1/8884 8714/1/8714 +f 8715/1/8715 8714/1/8714 8712/1/8712 +f 8712/1/8712 8713/1/8713 8715/1/8715 +f 8715/1/8715 8713/1/8713 8716/1/8716 +f 8716/1/8716 8717/1/8717 8715/1/8715 +f 8715/1/8715 8717/1/8717 8718/1/8718 +f 8715/1/8715 8718/1/8718 8720/1/8720 +f 8720/1/8720 8971/1/8971 8715/1/8715 +f 8530/1/8530 8715/1/8715 8971/1/8971 +f 8530/1/8530 8971/1/8971 8645/1/8645 +f 8971/1/8971 8974/1/8974 8645/1/8645 +f 8645/1/8645 8974/1/8974 8647/1/8647 +f 8647/1/8647 8646/1/8646 8645/1/8645 +f 8531/1/8531 8645/1/8645 8646/1/8646 +f 8646/1/8646 8965/1/8965 8531/1/8531 +f 8648/1/8648 8965/1/8965 8646/1/8646 +f 8966/1/8966 8965/1/8965 8648/1/8648 +f 8653/1/8653 8966/1/8966 8648/1/8648 +f 8652/1/8652 8653/1/8653 8648/1/8648 +f 8652/1/8652 8648/1/8648 8649/1/8649 +f 8649/1/8649 8969/1/8969 8652/1/8652 +f 8652/1/8652 8969/1/8969 8968/1/8968 +f 8652/1/8652 8968/1/8968 8654/1/8654 +f 8654/1/8654 8968/1/8968 8967/1/8967 +f 8654/1/8654 8967/1/8967 8653/1/8653 +f 8967/1/8967 8968/1/8968 8966/1/8966 +f 8966/1/8966 8968/1/8968 8969/1/8969 +f 8970/1/8970 8969/1/8969 8649/1/8649 +f 8650/1/8650 8970/1/8970 8649/1/8649 +f 8649/1/8649 8647/1/8647 8650/1/8650 +f 8650/1/8650 8647/1/8647 8651/1/8651 +f 8651/1/8651 8972/1/8972 8650/1/8650 +f 8651/1/8651 8973/1/8973 8972/1/8972 +f 8972/1/8972 8973/1/8973 8970/1/8970 +f 8970/1/8970 8973/1/8973 8974/1/8974 +f 8647/1/8647 8973/1/8973 8651/1/8651 +f 8650/1/8650 8972/1/8972 8970/1/8970 +f 8969/1/8969 8970/1/8970 8971/1/8971 +f 8965/1/8965 8969/1/8969 8971/1/8971 +f 8649/1/8649 8648/1/8648 8647/1/8647 +f 8654/1/8654 8653/1/8653 8652/1/8652 +f 8653/1/8653 8967/1/8967 8966/1/8966 +f 8966/1/8966 8969/1/8969 8965/1/8965 +f 8648/1/8648 8646/1/8646 8647/1/8647 +f 8647/1/8647 8974/1/8974 8973/1/8973 +f 8970/1/8970 8974/1/8974 8971/1/8971 +f 8965/1/8965 8971/1/8971 8720/1/8720 +f 8720/1/8720 8718/1/8718 8721/1/8721 +f 8718/1/8718 8803/1/8803 8721/1/8721 +f 8719/1/8719 8803/1/8803 8718/1/8718 +f 8719/1/8719 8798/1/8798 8803/1/8803 +f 8779/1/8779 8803/1/8803 8798/1/8798 +f 8793/1/8793 8779/1/8779 8798/1/8798 +f 8793/1/8793 8798/1/8798 8797/1/8797 +f 8793/1/8793 8797/1/8797 8796/1/8796 +f 8796/1/8796 8792/1/8792 8793/1/8793 +f 8793/1/8793 8792/1/8792 8789/1/8789 +f 8793/1/8793 8789/1/8789 8782/1/8782 +f 8782/1/8782 8789/1/8789 8787/1/8787 +f 8782/1/8782 8787/1/8787 8784/1/8784 +f 8784/1/8784 8780/1/8780 8782/1/8782 +f 8782/1/8782 8780/1/8780 8779/1/8779 +f 8761/1/8761 8779/1/8779 8780/1/8780 +f 8784/1/8784 8781/1/8781 8780/1/8780 +f 8781/1/8781 8768/1/8768 8780/1/8780 +f 8786/1/8786 8781/1/8781 8784/1/8784 +f 8925/1/8925 8786/1/8786 8784/1/8784 +f 8784/1/8784 8788/1/8788 8925/1/8925 +f 8791/1/8791 8925/1/8925 8788/1/8788 +f 8787/1/8787 8791/1/8791 8788/1/8788 +f 8787/1/8787 8790/1/8790 8791/1/8791 +f 8794/1/8794 8791/1/8791 8790/1/8790 +f 8794/1/8794 8790/1/8790 8795/1/8795 +f 8800/1/8800 8794/1/8794 8795/1/8795 +f 8799/1/8799 8800/1/8800 8795/1/8795 +f 8796/1/8796 8799/1/8799 8795/1/8795 +f 8706/1/8706 8799/1/8799 8796/1/8796 +f 8706/1/8706 8796/1/8796 8707/1/8707 +f 8706/1/8706 8707/1/8707 8703/1/8703 +f 8706/1/8706 8703/1/8703 8701/1/8701 +f 8701/1/8701 8703/1/8703 8702/1/8702 +f 8701/1/8701 8702/1/8702 8700/1/8700 +f 8700/1/8700 8662/1/8662 8701/1/8701 +f 8661/1/8661 8701/1/8701 8662/1/8662 +f 8661/1/8661 8662/1/8662 8657/1/8657 +f 8657/1/8657 8659/1/8659 8661/1/8661 +f 8661/1/8661 8659/1/8659 8800/1/8800 +f 8657/1/8657 8656/1/8656 8659/1/8659 +f 8656/1/8656 8660/1/8660 8659/1/8659 +f 8659/1/8659 8660/1/8660 8794/1/8794 +f 8801/1/8801 8794/1/8794 8660/1/8660 +f 8660/1/8660 8887/1/8887 8801/1/8801 +f 8801/1/8801 8887/1/8887 8930/1/8930 +f 8801/1/8801 8930/1/8930 8929/1/8929 +f 8929/1/8929 8930/1/8930 8931/1/8931 +f 8929/1/8929 8931/1/8931 8932/1/8932 +f 8932/1/8932 8927/1/8927 8929/1/8929 +f 8929/1/8929 8927/1/8927 8794/1/8794 +f 8932/1/8932 8935/1/8935 8927/1/8927 +f 8935/1/8935 8936/1/8936 8927/1/8927 +f 8927/1/8927 8936/1/8936 8928/1/8928 +f 8927/1/8927 8928/1/8928 8791/1/8791 +f 8928/1/8928 8926/1/8926 8791/1/8791 +f 8928/1/8928 8936/1/8936 8926/1/8926 +f 8926/1/8926 8936/1/8936 8935/1/8935 +f 8926/1/8926 8935/1/8935 8924/1/8924 +f 8924/1/8924 8923/1/8923 8926/1/8926 +f 8926/1/8926 8923/1/8923 8925/1/8925 +f 8924/1/8924 8921/1/8921 8923/1/8923 +f 8923/1/8923 8921/1/8921 8922/1/8922 +f 8922/1/8922 8785/1/8785 8923/1/8923 +f 8923/1/8923 8785/1/8785 8783/1/8783 +f 8923/1/8923 8783/1/8783 8786/1/8786 +f 8785/1/8785 8774/1/8774 8783/1/8783 +f 8922/1/8922 8776/1/8776 8785/1/8785 +f 8921/1/8921 8920/1/8920 8922/1/8922 +f 8922/1/8922 8920/1/8920 8778/1/8778 +f 8921/1/8921 8919/1/8919 8920/1/8920 +f 8919/1/8919 8906/1/8906 8920/1/8920 +f 8920/1/8920 8906/1/8906 8771/1/8771 +f 8919/1/8919 8909/1/8909 8906/1/8906 +f 8909/1/8909 8904/1/8904 8906/1/8906 +f 8906/1/8906 8904/1/8904 8882/1/8882 +f 8906/1/8906 8882/1/8882 8773/1/8773 +f 8901/1/8901 8882/1/8882 8904/1/8904 +f 8904/1/8904 8905/1/8905 8901/1/8901 +f 8901/1/8901 8905/1/8905 8902/1/8902 +f 8901/1/8901 8902/1/8902 8900/1/8900 +f 8900/1/8900 8881/1/8881 8901/1/8901 +f 8900/1/8900 8880/1/8880 8881/1/8881 +f 8766/1/8766 8881/1/8881 8880/1/8880 +f 8898/1/8898 8880/1/8880 8900/1/8900 +f 8899/1/8899 8898/1/8898 8900/1/8900 +f 8900/1/8900 8903/1/8903 8899/1/8899 +f 8899/1/8899 8903/1/8903 8902/1/8902 +f 8889/1/8889 8899/1/8899 8902/1/8902 +f 8889/1/8889 8902/1/8902 8910/1/8910 +f 8910/1/8910 8886/1/8886 8889/1/8889 +f 8885/1/8885 8889/1/8889 8886/1/8886 +f 8885/1/8885 8886/1/8886 8673/1/8673 +f 8673/1/8673 8665/1/8665 8885/1/8885 +f 8885/1/8885 8665/1/8665 8672/1/8672 +f 8885/1/8885 8672/1/8672 8888/1/8888 +f 8888/1/8888 8672/1/8672 8890/1/8890 +f 8890/1/8890 8891/1/8891 8888/1/8888 +f 8888/1/8888 8891/1/8891 8892/1/8892 +f 8889/1/8889 8888/1/8888 8892/1/8892 +f 8891/1/8891 8897/1/8897 8892/1/8892 +f 8892/1/8892 8897/1/8897 8899/1/8899 +f 8894/1/8894 8897/1/8897 8891/1/8891 +f 8877/1/8877 8894/1/8894 8891/1/8891 +f 8891/1/8891 8893/1/8893 8877/1/8877 +f 8877/1/8877 8893/1/8893 8861/1/8861 +f 8877/1/8877 8861/1/8861 8863/1/8863 +f 8863/1/8863 8876/1/8876 8877/1/8877 +f 8877/1/8877 8876/1/8876 8895/1/8895 +f 8876/1/8876 8812/1/8812 8895/1/8895 +f 8812/1/8812 8878/1/8878 8895/1/8895 +f 8895/1/8895 8878/1/8878 8896/1/8896 +f 8895/1/8895 8896/1/8896 8894/1/8894 +f 8878/1/8878 8879/1/8879 8896/1/8896 +f 8896/1/8896 8879/1/8879 8897/1/8897 +f 8897/1/8897 8879/1/8879 8898/1/8898 +f 8878/1/8878 8805/1/8805 8879/1/8879 +f 8765/1/8765 8879/1/8879 8805/1/8805 +f 8806/1/8806 8805/1/8805 8878/1/8878 +f 8760/1/8760 8805/1/8805 8806/1/8806 +f 8806/1/8806 8807/1/8807 8760/1/8760 +f 8760/1/8760 8807/1/8807 8808/1/8808 +f 8808/1/8808 8807/1/8807 8810/1/8810 +f 8810/1/8810 8807/1/8807 8811/1/8811 +f 8811/1/8811 8539/1/8539 8810/1/8810 +f 8810/1/8810 8539/1/8539 8616/1/8616 +f 8807/1/8807 8813/1/8813 8811/1/8811 +f 8807/1/8807 8812/1/8812 8813/1/8813 +f 8807/1/8807 8806/1/8806 8812/1/8812 +f 8812/1/8812 8806/1/8806 8878/1/8878 +f 8813/1/8813 8812/1/8812 8876/1/8876 +f 8813/1/8813 8876/1/8876 8875/1/8875 +f 8875/1/8875 8876/1/8876 8865/1/8865 +f 8863/1/8863 8865/1/8865 8876/1/8876 +f 8860/1/8860 8865/1/8865 8863/1/8863 +f 8863/1/8863 8857/1/8857 8860/1/8860 +f 8860/1/8860 8857/1/8857 8858/1/8858 +f 8860/1/8860 8858/1/8858 8855/1/8855 +f 8855/1/8855 8859/1/8859 8860/1/8860 +f 8859/1/8859 8864/1/8864 8860/1/8860 +f 8859/1/8859 8866/1/8866 8864/1/8864 +f 8866/1/8866 8867/1/8867 8864/1/8864 +f 8852/1/8852 8866/1/8866 8859/1/8859 +f 8852/1/8852 8869/1/8869 8866/1/8866 +f 8869/1/8869 8870/1/8870 8866/1/8866 +f 8849/1/8849 8869/1/8869 8852/1/8852 +f 8852/1/8852 8689/1/8689 8849/1/8849 +f 8690/1/8690 8849/1/8849 8689/1/8689 +f 8690/1/8690 8689/1/8689 8686/1/8686 +f 8686/1/8686 8691/1/8691 8690/1/8690 +f 8690/1/8690 8691/1/8691 8847/1/8847 +f 8690/1/8690 8847/1/8847 8846/1/8846 +f 8686/1/8686 8687/1/8687 8691/1/8691 +f 8687/1/8687 8693/1/8693 8691/1/8691 +f 8691/1/8691 8693/1/8693 8698/1/8698 +f 8691/1/8691 8698/1/8698 8883/1/8883 +f 8697/1/8697 8698/1/8698 8693/1/8693 +f 8693/1/8693 8699/1/8699 8697/1/8697 +f 8697/1/8697 8699/1/8699 8702/1/8702 +f 8697/1/8697 8702/1/8702 8705/1/8705 +f 8705/1/8705 8710/1/8710 8697/1/8697 +f 8705/1/8705 8709/1/8709 8710/1/8710 +f 8712/1/8712 8710/1/8710 8709/1/8709 +f 8708/1/8708 8709/1/8709 8705/1/8705 +f 8703/1/8703 8708/1/8708 8705/1/8705 +f 8705/1/8705 8704/1/8704 8703/1/8703 +f 8708/1/8708 8711/1/8711 8709/1/8709 +f 8713/1/8713 8709/1/8709 8711/1/8711 +f 8707/1/8707 8711/1/8711 8708/1/8708 +f 8802/1/8802 8711/1/8711 8707/1/8707 +f 8707/1/8707 8797/1/8797 8802/1/8802 +f 8719/1/8719 8711/1/8711 8802/1/8802 +f 8719/1/8719 8717/1/8717 8711/1/8711 +f 8705/1/8705 8702/1/8702 8704/1/8704 +f 8693/1/8693 8696/1/8696 8699/1/8699 +f 8700/1/8700 8699/1/8699 8696/1/8696 +f 8696/1/8696 8695/1/8695 8700/1/8700 +f 8695/1/8695 8678/1/8678 8700/1/8700 +f 8695/1/8695 8694/1/8694 8678/1/8678 +f 8678/1/8678 8694/1/8694 8684/1/8684 +f 8678/1/8678 8684/1/8684 8681/1/8681 +f 8681/1/8681 8677/1/8677 8678/1/8678 +f 8678/1/8678 8677/1/8677 8675/1/8675 +f 8678/1/8678 8675/1/8675 8662/1/8662 +f 8662/1/8662 8675/1/8675 8674/1/8674 +f 8662/1/8662 8674/1/8674 8658/1/8658 +f 8674/1/8674 8671/1/8671 8658/1/8658 +f 8658/1/8658 8671/1/8671 8663/1/8663 +f 8658/1/8658 8663/1/8663 8655/1/8655 +f 8657/1/8657 8658/1/8658 8655/1/8655 +f 8655/1/8655 8663/1/8663 8664/1/8664 +f 8664/1/8664 8667/1/8667 8655/1/8655 +f 8655/1/8655 8667/1/8667 8656/1/8656 +f 8667/1/8667 8664/1/8664 8673/1/8673 +f 8673/1/8673 8887/1/8887 8667/1/8667 +f 8664/1/8664 8663/1/8663 8665/1/8665 +f 8665/1/8665 8663/1/8663 8666/1/8666 +f 8671/1/8671 8666/1/8666 8663/1/8663 +f 8670/1/8670 8666/1/8666 8671/1/8671 +f 8670/1/8670 8668/1/8668 8666/1/8666 +f 8668/1/8668 8669/1/8669 8666/1/8666 +f 8666/1/8666 8669/1/8669 8862/1/8862 +f 8666/1/8666 8862/1/8862 8890/1/8890 +f 8893/1/8893 8890/1/8890 8862/1/8862 +f 8857/1/8857 8862/1/8862 8669/1/8669 +f 8861/1/8861 8862/1/8862 8857/1/8857 +f 8668/1/8668 8854/1/8854 8669/1/8669 +f 8854/1/8854 8853/1/8853 8669/1/8669 +f 8669/1/8669 8853/1/8853 8855/1/8855 +f 8853/1/8853 8852/1/8852 8855/1/8855 +f 8688/1/8688 8852/1/8852 8853/1/8853 +f 8853/1/8853 8680/1/8680 8688/1/8688 +f 8688/1/8688 8680/1/8680 8682/1/8682 +f 8682/1/8682 8689/1/8689 8688/1/8688 +f 8680/1/8680 8679/1/8679 8682/1/8682 +f 8679/1/8679 8683/1/8683 8682/1/8682 +f 8686/1/8686 8682/1/8682 8683/1/8683 +f 8681/1/8681 8683/1/8683 8679/1/8679 +f 8683/1/8683 8681/1/8681 8685/1/8685 +f 8683/1/8683 8685/1/8685 8687/1/8687 +f 8685/1/8685 8692/1/8692 8687/1/8687 +f 8685/1/8685 8684/1/8684 8692/1/8692 +f 8679/1/8679 8680/1/8680 8676/1/8676 +f 8677/1/8677 8679/1/8679 8676/1/8676 +f 8676/1/8676 8680/1/8680 8668/1/8668 +f 8680/1/8680 8856/1/8856 8668/1/8668 +f 8853/1/8853 8856/1/8856 8680/1/8680 +f 8854/1/8854 8856/1/8856 8853/1/8853 +f 8668/1/8668 8856/1/8856 8854/1/8854 +f 8676/1/8676 8668/1/8668 8670/1/8670 +f 8675/1/8675 8676/1/8676 8670/1/8670 +f 8674/1/8674 8670/1/8670 8671/1/8671 +f 8675/1/8675 8670/1/8670 8674/1/8674 +f 8677/1/8677 8676/1/8676 8675/1/8675 +f 8681/1/8681 8679/1/8679 8677/1/8677 +f 8685/1/8685 8681/1/8681 8684/1/8684 +f 8684/1/8684 8694/1/8694 8692/1/8692 +f 8692/1/8692 8694/1/8694 8695/1/8695 +f 8692/1/8692 8695/1/8695 8696/1/8696 +f 8692/1/8692 8696/1/8696 8693/1/8693 +f 8697/1/8697 8710/1/8710 8698/1/8698 +f 8714/1/8714 8698/1/8698 8710/1/8710 +f 8687/1/8687 8692/1/8692 8693/1/8693 +f 8683/1/8683 8687/1/8687 8686/1/8686 +f 8686/1/8686 8689/1/8689 8682/1/8682 +f 8846/1/8846 8849/1/8849 8690/1/8690 +f 8688/1/8688 8689/1/8689 8852/1/8852 +f 8849/1/8849 8872/1/8872 8869/1/8869 +f 8855/1/8855 8852/1/8852 8859/1/8859 +f 8669/1/8669 8855/1/8855 8858/1/8858 +f 8857/1/8857 8669/1/8669 8858/1/8858 +f 8860/1/8860 8864/1/8864 8865/1/8865 +f 8864/1/8864 8868/1/8868 8865/1/8865 +f 8863/1/8863 8861/1/8861 8857/1/8857 +f 8893/1/8893 8862/1/8862 8861/1/8861 +f 8877/1/8877 8895/1/8895 8894/1/8894 +f 8894/1/8894 8896/1/8896 8897/1/8897 +f 8891/1/8891 8890/1/8890 8893/1/8893 +f 8672/1/8672 8666/1/8666 8890/1/8890 +f 8665/1/8665 8666/1/8666 8672/1/8672 +f 8673/1/8673 8664/1/8664 8665/1/8665 +f 8673/1/8673 8886/1/8886 8887/1/8887 +f 8888/1/8888 8889/1/8889 8885/1/8885 +f 8910/1/8910 8912/1/8912 8886/1/8886 +f 8912/1/8912 8931/1/8931 8886/1/8886 +f 8912/1/8912 8933/1/8933 8931/1/8931 +f 8915/1/8915 8933/1/8933 8912/1/8912 +f 8912/1/8912 8914/1/8914 8915/1/8915 +f 8916/1/8916 8915/1/8915 8914/1/8914 +f 8916/1/8916 8914/1/8914 8907/1/8907 +f 8916/1/8916 8907/1/8907 8909/1/8909 +f 8917/1/8917 8916/1/8916 8909/1/8909 +f 8914/1/8914 8913/1/8913 8907/1/8907 +f 8907/1/8907 8913/1/8913 8911/1/8911 +f 8907/1/8907 8911/1/8911 8908/1/8908 +f 8907/1/8907 8908/1/8908 8904/1/8904 +f 8908/1/8908 8911/1/8911 8910/1/8910 +f 8910/1/8910 8905/1/8905 8908/1/8908 +f 8911/1/8911 8913/1/8913 8912/1/8912 +f 8917/1/8917 8915/1/8915 8916/1/8916 +f 8917/1/8917 8918/1/8918 8915/1/8915 +f 8915/1/8915 8918/1/8918 8934/1/8934 +f 8935/1/8935 8934/1/8934 8918/1/8918 +f 8918/1/8918 8917/1/8917 8919/1/8919 +f 8912/1/8912 8913/1/8913 8914/1/8914 +f 8934/1/8934 8933/1/8933 8915/1/8915 +f 8932/1/8932 8933/1/8933 8934/1/8934 +f 8911/1/8911 8912/1/8912 8910/1/8910 +f 8892/1/8892 8899/1/8899 8889/1/8889 +f 8899/1/8899 8897/1/8897 8898/1/8898 +f 8898/1/8898 8879/1/8879 8880/1/8880 +f 8767/1/8767 8880/1/8880 8879/1/8879 +f 8900/1/8900 8902/1/8902 8903/1/8903 +f 8910/1/8910 8902/1/8902 8905/1/8905 +f 8904/1/8904 8908/1/8908 8905/1/8905 +f 8901/1/8901 8881/1/8881 8882/1/8882 +f 8764/1/8764 8882/1/8882 8881/1/8881 +f 8909/1/8909 8907/1/8907 8904/1/8904 +f 8917/1/8917 8909/1/8909 8919/1/8919 +f 8918/1/8918 8919/1/8919 8921/1/8921 +f 8918/1/8918 8921/1/8921 8924/1/8924 +f 8924/1/8924 8935/1/8935 8918/1/8918 +f 8934/1/8934 8935/1/8935 8932/1/8932 +f 8932/1/8932 8931/1/8931 8933/1/8933 +f 8886/1/8886 8931/1/8931 8930/1/8930 +f 8886/1/8886 8930/1/8930 8887/1/8887 +f 8660/1/8660 8667/1/8667 8887/1/8887 +f 8929/1/8929 8794/1/8794 8801/1/8801 +f 8656/1/8656 8667/1/8667 8660/1/8660 +f 8655/1/8655 8656/1/8656 8657/1/8657 +f 8657/1/8657 8662/1/8662 8658/1/8658 +f 8799/1/8799 8701/1/8701 8661/1/8661 +f 8700/1/8700 8678/1/8678 8662/1/8662 +f 8700/1/8700 8702/1/8702 8699/1/8699 +f 8703/1/8703 8704/1/8704 8702/1/8702 +f 8703/1/8703 8707/1/8707 8708/1/8708 +f 8701/1/8701 8799/1/8799 8706/1/8706 +f 8661/1/8661 8800/1/8800 8799/1/8799 +f 8659/1/8659 8794/1/8794 8800/1/8800 +f 8792/1/8792 8795/1/8795 8790/1/8790 +f 8927/1/8927 8791/1/8791 8794/1/8794 +f 8791/1/8791 8926/1/8926 8925/1/8925 +f 8925/1/8925 8923/1/8923 8786/1/8786 +f 8786/1/8786 8783/1/8783 8781/1/8781 +f 8783/1/8783 8769/1/8769 8781/1/8781 +f 8784/1/8784 8787/1/8787 8788/1/8788 +f 8789/1/8789 8790/1/8790 8787/1/8787 +f 8792/1/8792 8790/1/8790 8789/1/8789 +f 8796/1/8796 8795/1/8795 8792/1/8792 +f 8707/1/8707 8796/1/8796 8797/1/8797 +f 8802/1/8802 8797/1/8797 8798/1/8798 +f 8782/1/8782 8779/1/8779 8793/1/8793 +f 8804/1/8804 8803/1/8803 8779/1/8779 +f 8802/1/8802 8798/1/8798 8719/1/8719 +f 8718/1/8718 8717/1/8717 8719/1/8719 +f 8716/1/8716 8711/1/8711 8717/1/8717 +f 8713/1/8713 8711/1/8711 8716/1/8716 +f 8712/1/8712 8709/1/8709 8713/1/8713 +f 8714/1/8714 8710/1/8710 8712/1/8712 +f 8884/1/8884 8698/1/8698 8714/1/8714 +f 8883/1/8883 8698/1/8698 8884/1/8884 +f 8883/1/8883 8851/1/8851 8691/1/8691 +f 8691/1/8691 8851/1/8851 8847/1/8847 +f 8845/1/8845 8847/1/8847 8850/1/8850 +f 8850/1/8850 8534/1/8534 8845/1/8845 +f 8845/1/8845 8534/1/8534 8535/1/8535 +f 8845/1/8845 8846/1/8846 8847/1/8847 +f 8846/1/8846 8848/1/8848 8849/1/8849 +f 8848/1/8848 8872/1/8872 8849/1/8849 +f 8872/1/8872 8873/1/8873 8869/1/8869 +f 8869/1/8869 8873/1/8873 8870/1/8870 +f 8870/1/8870 8871/1/8871 8866/1/8866 +f 8866/1/8866 8871/1/8871 8867/1/8867 +f 8864/1/8864 8867/1/8867 8868/1/8868 +f 8874/1/8874 8865/1/8865 8868/1/8868 +f 8875/1/8875 8865/1/8865 8874/1/8874 +f 8811/1/8811 8813/1/8813 8875/1/8875 +f 8811/1/8811 8533/1/8533 8539/1/8539 +f 8842/1/8842 8536/1/8536 8844/1/8844 +f 8533/1/8533 8537/1/8537 8538/1/8538 +f 8640/1/8640 8641/1/8641 8536/1/8536 +f 8843/1/8843 8538/1/8538 8537/1/8537 +f 8843/1/8843 8842/1/8842 8844/1/8844 +f 8840/1/8840 8839/1/8839 8841/1/8841 +f 8842/1/8842 8640/1/8640 8536/1/8536 +f 8837/1/8837 8637/1/8637 8839/1/8839 +f 8640/1/8640 8639/1/8639 8641/1/8641 +f 8838/1/8838 8639/1/8639 8638/1/8638 +f 8838/1/8838 8837/1/8837 8839/1/8839 +f 8834/1/8834 8835/1/8835 8836/1/8836 +f 8837/1/8837 8635/1/8635 8637/1/8637 +f 8824/1/8824 8627/1/8627 8835/1/8835 +f 8635/1/8635 8634/1/8634 8636/1/8636 +f 8832/1/8832 8634/1/8634 8633/1/8633 +f 8831/1/8831 8633/1/8633 8632/1/8632 +f 8631/1/8631 8831/1/8831 8632/1/8632 +f 8830/1/8830 8631/1/8631 8630/1/8630 +f 8830/1/8830 8630/1/8630 8829/1/8829 +f 8830/1/8830 8829/1/8829 8824/1/8824 +f 8824/1/8824 8825/1/8825 8822/1/8822 +f 8822/1/8822 8624/1/8624 8824/1/8824 +f 8825/1/8825 8826/1/8826 8822/1/8822 +f 8825/1/8825 8625/1/8625 8826/1/8826 +f 8828/1/8828 8628/1/8628 8827/1/8827 +f 8629/1/8629 8627/1/8627 8628/1/8628 +f 8824/1/8824 8624/1/8624 8627/1/8627 +f 8825/1/8825 8626/1/8626 8625/1/8625 +f 8826/1/8826 8625/1/8625 8623/1/8623 +f 8826/1/8826 8623/1/8623 8823/1/8823 +f 8822/1/8822 8826/1/8826 8823/1/8823 +f 8822/1/8822 8621/1/8621 8624/1/8624 +f 8818/1/8818 8618/1/8618 8820/1/8820 +f 8621/1/8621 8620/1/8620 8622/1/8622 +f 8819/1/8819 8620/1/8620 8617/1/8617 +f 8819/1/8819 8818/1/8818 8821/1/8821 +f 8815/1/8815 8816/1/8816 8817/1/8817 +f 8818/1/8818 8614/1/8614 8618/1/8618 +f 8814/1/8814 8613/1/8613 8816/1/8816 +f 8614/1/8614 8482/1/8482 8619/1/8619 +f 8760/1/8760 8809/1/8809 8479/1/8479 +f 8815/1/8815 8619/1/8619 8482/1/8482 +f 8815/1/8815 8814/1/8814 8816/1/8816 +f 8760/1/8760 8808/1/8808 8809/1/8809 +f 8810/1/8810 8616/1/8616 8808/1/8808 +f 8814/1/8814 8615/1/8615 8613/1/8613 +f 8613/1/8613 8611/1/8611 8609/1/8609 +f 8610/1/8610 8608/1/8608 8611/1/8611 +f 8610/1/8610 8597/1/8597 8608/1/8608 +f 8589/1/8589 8597/1/8597 8610/1/8610 +f 8589/1/8589 8594/1/8594 8597/1/8597 +f 8607/1/8607 8608/1/8608 8597/1/8597 +f 8606/1/8606 8483/1/8483 8607/1/8607 +f 8598/1/8598 8596/1/8596 8603/1/8603 +f 8603/1/8603 8601/1/8601 8604/1/8604 +f 8604/1/8604 8601/1/8601 8470/1/8470 +f 8605/1/8605 8481/1/8481 8606/1/8606 +f 8481/1/8481 8478/1/8478 8480/1/8480 +f 8478/1/8478 8477/1/8477 8479/1/8479 +f 8464/1/8464 8465/1/8465 8466/1/8466 +f 8464/1/8464 8462/1/8462 8465/1/8465 +f 8479/1/8479 8477/1/8477 8474/1/8474 +f 9032/1/9032 8975/1/8975 8479/1/8479 +f 9032/1/9032 8976/1/8976 8975/1/8975 +f 9020/1/9020 8976/1/8976 9032/1/9032 +f 9020/1/9020 8977/1/8977 8976/1/8976 +f 8962/1/8962 8976/1/8976 8977/1/8977 +f 8962/1/8962 8977/1/8977 8964/1/8964 +f 8963/1/8963 8962/1/8962 8964/1/8964 +f 8963/1/8963 8964/1/8964 9016/1/9016 +f 8954/1/8954 8963/1/8963 9016/1/9016 +f 8954/1/8954 9016/1/9016 9017/1/9017 +f 9017/1/9017 8953/1/8953 8954/1/8954 +f 8954/1/8954 8953/1/8953 8952/1/8952 +f 8952/1/8952 9014/1/9014 8954/1/8954 +f 8954/1/8954 9014/1/9014 9015/1/9015 +f 9014/1/9014 8982/1/8982 9015/1/9015 +f 9015/1/9015 8982/1/8982 8978/1/8978 +f 9015/1/9015 8978/1/8978 9019/1/9019 +f 9019/1/9019 9018/1/9018 9015/1/9015 +f 9018/1/9018 8963/1/8963 9015/1/9015 +f 8963/1/8963 9018/1/9018 8961/1/8961 +f 9019/1/9019 9021/1/9021 9018/1/9018 +f 9021/1/9021 8977/1/8977 9018/1/9018 +f 9021/1/9021 8980/1/8980 8977/1/8977 +f 8979/1/8979 8977/1/8977 8980/1/8980 +f 8986/1/8986 8979/1/8979 8980/1/8980 +f 8980/1/8980 9024/1/9024 8986/1/8986 +f 9027/1/9027 8986/1/8986 9024/1/9024 +f 9026/1/9026 9027/1/9027 9024/1/9024 +f 9026/1/9026 9024/1/9024 9028/1/9028 +f 9028/1/9028 8988/1/8988 9026/1/9026 +f 9026/1/9026 8988/1/8988 8989/1/8989 +f 9026/1/9026 8989/1/8989 9031/1/9031 +f 9031/1/9031 8989/1/8989 8990/1/8990 +f 9031/1/9031 8990/1/8990 9027/1/9027 +f 8989/1/8989 8986/1/8986 8990/1/8990 +f 8988/1/8988 8986/1/8986 8989/1/8989 +f 8988/1/8988 8987/1/8987 8986/1/8986 +f 8991/1/8991 8987/1/8987 8988/1/8988 +f 8991/1/8991 8992/1/8992 8987/1/8987 +f 9025/1/9025 8987/1/8987 8992/1/8992 +f 9025/1/9025 8992/1/8992 9030/1/9030 +f 9029/1/9029 9025/1/9025 9030/1/9030 +f 9030/1/9030 8993/1/8993 9029/1/9029 +f 9029/1/9029 8993/1/8993 8991/1/8991 +f 9029/1/9029 8991/1/8991 9028/1/9028 +f 9028/1/9028 9025/1/9025 9029/1/9029 +f 9030/1/9030 8992/1/8992 8993/1/8993 +f 9022/1/9022 8987/1/8987 9025/1/9025 +f 9024/1/9024 9022/1/9022 9025/1/9025 +f 9023/1/9023 9022/1/9022 9024/1/9024 +f 9022/1/9022 9023/1/9023 9021/1/9021 +f 8979/1/8979 8987/1/8987 9022/1/9022 +f 9019/1/9019 8979/1/8979 9022/1/9022 +f 8993/1/8993 8992/1/8992 8991/1/8991 +f 8991/1/8991 8988/1/8988 9028/1/9028 +f 9028/1/9028 9024/1/9024 9025/1/9025 +f 9031/1/9031 9027/1/9027 9026/1/9026 +f 9027/1/9027 8990/1/8990 8986/1/8986 +f 9023/1/9023 9024/1/9024 8980/1/8980 +f 8987/1/8987 8979/1/8979 8986/1/8986 +f 8978/1/8978 8977/1/8977 8979/1/8979 +f 8978/1/8978 8953/1/8953 8977/1/8977 +f 9023/1/9023 8980/1/8980 9021/1/9021 +f 9022/1/9022 9021/1/9021 9019/1/9019 +f 9019/1/9019 8978/1/8978 8979/1/8979 +f 8953/1/8953 8978/1/8978 8982/1/8982 +f 8953/1/8953 8982/1/8982 8951/1/8951 +f 8951/1/8951 8982/1/8982 8984/1/8984 +f 8951/1/8951 8984/1/8984 8949/1/8949 +f 8950/1/8950 8951/1/8951 8949/1/8949 +f 8950/1/8950 8949/1/8949 8948/1/8948 +f 8948/1/8948 9012/1/9012 8950/1/8950 +f 8950/1/8950 9012/1/9012 9013/1/9013 +f 8950/1/8950 9013/1/9013 8952/1/8952 +f 9012/1/9012 8985/1/8985 9013/1/9013 +f 9013/1/9013 8985/1/8985 8984/1/8984 +f 9013/1/9013 8984/1/8984 9014/1/9014 +f 9012/1/9012 8994/1/8994 8985/1/8985 +f 8947/1/8947 8985/1/8985 8994/1/8994 +f 8947/1/8947 8994/1/8994 8945/1/8945 +f 8946/1/8946 8947/1/8947 8945/1/8945 +f 8945/1/8945 8943/1/8943 8946/1/8946 +f 8946/1/8946 8943/1/8943 8944/1/8944 +f 9010/1/9010 8946/1/8946 8944/1/8944 +f 8941/1/8941 9010/1/9010 8944/1/8944 +f 8941/1/8941 9009/1/9009 9010/1/9010 +f 8996/1/8996 9010/1/9010 9009/1/9009 +f 8996/1/8996 9009/1/9009 8997/1/8997 +f 8937/1/8937 8996/1/8996 8997/1/8997 +f 9001/1/9001 8937/1/8937 8997/1/8997 +f 9001/1/9001 8997/1/8997 9000/1/9000 +f 9000/1/9000 8999/1/8999 9001/1/9001 +f 9003/1/9003 9001/1/9001 8999/1/8999 +f 9003/1/9003 8999/1/8999 9005/1/9005 +f 9005/1/9005 9006/1/9006 9003/1/9003 +f 9003/1/9003 9006/1/9006 9007/1/9007 +f 9003/1/9003 9007/1/9007 9008/1/9008 +f 9004/1/9004 9003/1/9003 9008/1/9008 +f 8938/1/8938 9004/1/9004 9008/1/9008 +f 8938/1/8938 9008/1/9008 9009/1/9009 +f 8942/1/8942 9004/1/9004 8938/1/8938 +f 8942/1/8942 8938/1/8938 8940/1/8940 +f 8942/1/8942 8940/1/8940 8955/1/8955 +f 8942/1/8942 8955/1/8955 8956/1/8956 +f 8956/1/8956 8958/1/8958 8942/1/8942 +f 8956/1/8956 8957/1/8957 8958/1/8958 +f 8958/1/8958 8957/1/8957 9002/1/9002 +f 8958/1/8958 9002/1/9002 9004/1/9004 +f 9001/1/9001 9004/1/9004 9002/1/9002 +f 9002/1/9002 8957/1/8957 8955/1/8955 +f 8956/1/8956 8955/1/8955 8957/1/8957 +f 8955/1/8955 8940/1/8940 9002/1/9002 +f 9002/1/9002 8940/1/8940 8937/1/8937 +f 8940/1/8940 8938/1/8938 8937/1/8937 +f 8937/1/8937 8938/1/8938 8939/1/8939 +f 8939/1/8939 8938/1/8938 8941/1/8941 +f 8939/1/8939 8941/1/8941 8943/1/8943 +f 8943/1/8943 8995/1/8995 8939/1/8939 +f 8939/1/8939 8995/1/8995 8996/1/8996 +f 8995/1/8995 8943/1/8943 8994/1/8994 +f 8995/1/8995 8994/1/8994 9010/1/9010 +f 9010/1/9010 8994/1/8994 9011/1/9011 +f 8942/1/8942 8958/1/8958 9004/1/9004 +f 9008/1/9008 9007/1/9007 8997/1/8997 +f 9006/1/9006 9000/1/9000 9007/1/9007 +f 9006/1/9006 8998/1/8998 9000/1/9000 +f 9005/1/9005 8998/1/8998 9006/1/9006 +f 9005/1/9005 8999/1/8999 8998/1/8998 +f 9003/1/9003 9004/1/9004 9001/1/9001 +f 8998/1/8998 8999/1/8999 9000/1/9000 +f 8997/1/8997 9007/1/9007 9000/1/9000 +f 9002/1/9002 8937/1/8937 9001/1/9001 +f 8939/1/8939 8996/1/8996 8937/1/8937 +f 8997/1/8997 9009/1/9009 9008/1/9008 +f 8995/1/8995 9010/1/9010 8996/1/8996 +f 8938/1/8938 9009/1/9009 8941/1/8941 +f 9011/1/9011 8946/1/8946 9010/1/9010 +f 8946/1/8946 9011/1/9011 8948/1/8948 +f 8943/1/8943 8941/1/8941 8944/1/8944 +f 8948/1/8948 8947/1/8947 8946/1/8946 +f 8994/1/8994 8943/1/8943 8945/1/8945 +f 8949/1/8949 8985/1/8985 8947/1/8947 +f 9011/1/9011 8994/1/8994 9012/1/9012 +f 8948/1/8948 9011/1/9011 9012/1/9012 +f 8948/1/8948 8949/1/8949 8947/1/8947 +f 8952/1/8952 8951/1/8951 8950/1/8950 +f 8949/1/8949 8984/1/8984 8985/1/8985 +f 9014/1/9014 8984/1/8984 8982/1/8982 +f 8952/1/8952 9013/1/9013 9014/1/9014 +f 8952/1/8952 8953/1/8953 8951/1/8951 +f 9017/1/9017 8983/1/8983 8953/1/8953 +f 8983/1/8983 8981/1/8981 8953/1/8953 +f 8953/1/8953 8981/1/8981 8964/1/8964 +f 8981/1/8981 8983/1/8983 9037/1/9037 +f 9037/1/9037 9033/1/9033 8981/1/8981 +f 9016/1/9016 8981/1/8981 9033/1/9033 +f 9038/1/9038 9033/1/9033 9037/1/9037 +f 9038/1/9038 9037/1/9037 9039/1/9039 +f 9038/1/9038 9039/1/9039 9040/1/9040 +f 9042/1/9042 9038/1/9038 9040/1/9040 +f 9040/1/9040 9041/1/9041 9042/1/9042 +f 9042/1/9042 9041/1/9041 9043/1/9043 +f 9042/1/9042 9043/1/9043 9044/1/9044 +f 9043/1/9043 9045/1/9045 9044/1/9044 +f 9044/1/9044 9045/1/9045 9046/1/9046 +f 9046/1/9046 9035/1/9035 9044/1/9044 +f 9044/1/9044 9035/1/9035 9038/1/9038 +f 9035/1/9035 9034/1/9034 9038/1/9038 +f 9035/1/9035 8983/1/8983 9034/1/9034 +f 9036/1/9036 8983/1/8983 9035/1/9035 +f 9050/1/9050 9036/1/9036 9035/1/9035 +f 9050/1/9050 9049/1/9049 9036/1/9036 +f 9047/1/9047 9036/1/9036 9049/1/9049 +f 9048/1/9048 9047/1/9047 9049/1/9049 +f 9046/1/9046 9047/1/9047 9048/1/9048 +f 9048/1/9048 9050/1/9050 9046/1/9046 +f 9045/1/9045 9036/1/9036 9047/1/9047 +f 9045/1/9045 9037/1/9037 9036/1/9036 +f 9048/1/9048 9049/1/9049 9050/1/9050 +f 9046/1/9046 9050/1/9050 9035/1/9035 +f 9046/1/9046 9045/1/9045 9047/1/9047 +f 9043/1/9043 9037/1/9037 9045/1/9045 +f 9041/1/9041 9039/1/9039 9043/1/9043 +f 9044/1/9044 9038/1/9038 9042/1/9042 +f 9040/1/9040 9039/1/9039 9041/1/9041 +f 9043/1/9043 9039/1/9039 9037/1/9037 +f 9038/1/9038 9034/1/9034 9033/1/9033 +f 9017/1/9017 9033/1/9033 9034/1/9034 +f 9037/1/9037 8983/1/8983 9036/1/9036 +f 9034/1/9034 8983/1/8983 9017/1/9017 +f 9017/1/9017 9016/1/9016 9033/1/9033 +f 9015/1/9015 8963/1/8963 8954/1/8954 +f 9016/1/9016 8964/1/8964 8981/1/8981 +f 8961/1/8961 8962/1/8962 8963/1/8963 +f 8977/1/8977 8953/1/8953 8964/1/8964 +f 8960/1/8960 8976/1/8976 8962/1/8962 +f 9018/1/9018 8977/1/8977 9020/1/9020 +f 8961/1/8961 9018/1/9018 9020/1/9020 +f 8961/1/8961 8960/1/8960 8962/1/8962 +f 8484/1/8484 8758/1/8758 8959/1/8959 +f 8960/1/8960 8975/1/8975 8976/1/8976 +f 8479/1/8479 8975/1/8975 8760/1/8760 +f 8760/1/8760 8765/1/8765 8805/1/8805 +f 8767/1/8767 8879/1/8879 8765/1/8765 +f 8766/1/8766 8880/1/8880 8767/1/8767 +f 8764/1/8764 8881/1/8881 8766/1/8766 +f 8763/1/8763 8882/1/8882 8764/1/8764 +f 8773/1/8773 8882/1/8882 8763/1/8763 +f 8773/1/8773 8772/1/8772 8906/1/8906 +f 8906/1/8906 8772/1/8772 8771/1/8771 +f 8920/1/8920 8771/1/8771 8778/1/8778 +f 8922/1/8922 8778/1/8778 8777/1/8777 +f 8777/1/8777 8776/1/8776 8922/1/8922 +f 8776/1/8776 8775/1/8775 8785/1/8785 +f 8785/1/8785 8775/1/8775 8774/1/8774 +f 8774/1/8774 8770/1/8770 8783/1/8783 +f 8783/1/8783 8770/1/8770 8769/1/8769 +f 8781/1/8781 8769/1/8769 8768/1/8768 +f 8762/1/8762 8780/1/8780 8768/1/8768 +f 8761/1/8761 8780/1/8780 8762/1/8762 +f 8804/1/8804 8779/1/8779 8761/1/8761 +f 8721/1/8721 8803/1/8803 8804/1/8804 +f 8759/1/8759 8488/1/8488 8724/1/8724 +f 8722/1/8722 8492/1/8492 8493/1/8493 +f 8726/1/8726 8493/1/8493 8494/1/8494 +f 8729/1/8729 8494/1/8494 8496/1/8496 +f 8498/1/8498 8499/1/8499 8496/1/8496 +f 8725/1/8725 8499/1/8499 8498/1/8498 +f 8722/1/8722 8728/1/8728 8725/1/8725 +f 8720/1/8720 8721/1/8721 8722/1/8722 +f 8495/1/8495 8497/1/8497 8723/1/8723 +f 8531/1/8531 8965/1/8965 8720/1/8720 +f 8531/1/8531 8530/1/8530 8645/1/8645 +f 8529/1/8529 8715/1/8715 8530/1/8530 +f 8532/1/8532 8533/1/8533 8529/1/8529 +f 8539/1/8539 8533/1/8533 8532/1/8532 +f 8547/1/8547 8616/1/8616 8539/1/8539 +f 8584/1/8584 8612/1/8612 8547/1/8547 +f 8583/1/8583 8584/1/8584 8555/1/8555 +f 8582/1/8582 8555/1/8555 8580/1/8580 +f 8585/1/8585 8586/1/8586 8582/1/8582 +f 8587/1/8587 8586/1/8586 8585/1/8585 +f 8590/1/8590 8588/1/8588 8587/1/8587 +f 8595/1/8595 8590/1/8590 8592/1/8592 +f 8595/1/8595 8592/1/8592 8599/1/8599 +f 8601/1/8601 8599/1/8599 8470/1/8470 +f 8604/1/8604 8470/1/8470 8472/1/8472 +f 8468/1/8468 8472/1/8472 8469/1/8469 +f 8467/1/8467 8466/1/8466 8468/1/8468 +f 8416/1/8416 8418/1/8418 8421/1/8421 +f 8467/1/8467 8464/1/8464 8466/1/8466 +f 8416/1/8416 8413/1/8413 8418/1/8418 +f 8416/1/8416 8412/1/8412 8413/1/8413 +f 8464/1/8464 8419/1/8419 8462/1/8462 +f 8465/1/8465 8462/1/8462 8463/1/8463 +f 8476/1/8476 8475/1/8475 8463/1/8463 +f 8484/1/8484 8475/1/8475 8476/1/8476 +f 8486/1/8486 8758/1/8758 8484/1/8484 +f 8487/1/8487 8488/1/8488 8486/1/8486 +f 8458/1/8458 8488/1/8488 8487/1/8487 +f 8457/1/8457 8458/1/8458 8455/1/8455 +f 8473/1/8473 8457/1/8457 8455/1/8455 +f 8497/1/8497 8457/1/8457 8473/1/8473 +f 8528/1/8528 8497/1/8497 8527/1/8527 +f 8540/1/8540 8528/1/8528 8542/1/8542 +f 8545/1/8545 8541/1/8541 8540/1/8540 +f 8548/1/8548 8546/1/8546 8545/1/8545 +f 8544/1/8544 8549/1/8549 8550/1/8550 +f 8550/1/8550 8549/1/8549 8551/1/8551 +f 8551/1/8551 8549/1/8549 8552/1/8552 +f 8562/1/8562 8557/1/8557 8556/1/8556 +f 8548/1/8548 8553/1/8553 8554/1/8554 +f 8576/1/8576 8579/1/8579 8554/1/8554 +f 8575/1/8575 8579/1/8579 8576/1/8576 +f 8574/1/8574 8581/1/8581 8575/1/8575 +f 8591/1/8591 8574/1/8574 8577/1/8577 +f 8593/1/8593 8577/1/8577 8643/1/8643 +f 8471/1/8471 8593/1/8593 8643/1/8643 +f 8422/1/8422 8471/1/8471 8424/1/8424 +f 8415/1/8415 8420/1/8420 8422/1/8422 +f 8415/1/8415 8412/1/8412 8416/1/8416 +f 8423/1/8423 8410/1/8410 8417/1/8417 +f 8412/1/8412 8411/1/8411 8413/1/8413 +f 8404/1/8404 8407/1/8407 8409/1/8409 +f 8414/1/8414 8413/1/8413 8411/1/8411 +f 8414/1/8414 8460/1/8460 8461/1/8461 +f 8459/1/8459 8485/1/8485 8460/1/8460 +f 8438/1/8438 8456/1/8456 8459/1/8459 +f 8436/1/8436 8437/1/8437 8438/1/8438 +f 8432/1/8432 8435/1/8435 8436/1/8436 +f 8434/1/8434 8435/1/8435 8432/1/8432 +f 8440/1/8440 8434/1/8434 8433/1/8433 +f 8441/1/8441 8440/1/8440 8442/1/8442 +f 8441/1/8441 8442/1/8442 8446/1/8446 +f 8442/1/8442 8447/1/8447 8446/1/8446 +f 8446/1/8446 8447/1/8447 8448/1/8448 +f 8444/1/8444 8441/1/8441 8446/1/8446 +f 8444/1/8444 8453/1/8453 8454/1/8454 +f 8573/1/8573 8525/1/8525 8453/1/8453 +f 8543/1/8543 8526/1/8526 8573/1/8573 +f 8552/1/8552 8549/1/8549 8543/1/8543 +f 8558/1/8558 8551/1/8551 8552/1/8552 +f 8450/1/8450 8572/1/8572 8559/1/8559 +f 8561/1/8561 8560/1/8560 8558/1/8558 +f 8449/1/8449 8451/1/8451 8572/1/8572 +f 8451/1/8451 8443/1/8443 8452/1/8452 +f 8562/1/8562 8556/1/8556 8560/1/8560 +f 8557/1/8557 8562/1/8562 8563/1/8563 +f 8563/1/8563 8566/1/8566 8557/1/8557 +f 8578/1/8578 8566/1/8566 8569/1/8569 +f 8642/1/8642 8569/1/8569 8568/1/8568 +f 8570/1/8570 8644/1/8644 8568/1/8568 +f 8564/1/8564 8567/1/8567 8565/1/8565 +f 8571/1/8571 8425/1/8425 8570/1/8570 +f 8564/1/8564 8452/1/8452 8567/1/8567 +f 8452/1/8452 8429/1/8429 8431/1/8431 +f 8428/1/8428 8426/1/8426 8571/1/8571 +f 8429/1/8429 8427/1/8427 8431/1/8431 +f 8428/1/8428 8410/1/8410 8426/1/8426 +f 8430/1/8430 8405/1/8405 8427/1/8427 +f 8410/1/8410 8404/1/8404 8409/1/8409 +f 8405/1/8405 8406/1/8406 8401/1/8401 +f 8404/1/8404 8403/1/8403 8407/1/8407 +f 8402/1/8402 8408/1/8408 8403/1/8403 +f 8406/1/8406 8402/1/8402 8401/1/8401 +f 9051/1/9051 9052/1/9052 9053/1/9053 +f 9051/1/9051 9053/1/9053 9054/1/9054 +f 9057/1/9057 9051/1/9051 9054/1/9054 +f 9057/1/9057 9054/1/9054 9059/1/9059 +f 9059/1/9059 9058/1/9058 9057/1/9057 +f 9057/1/9057 9058/1/9058 9056/1/9056 +f 9057/1/9057 9056/1/9056 9055/1/9055 +f 9055/1/9055 9056/1/9056 9052/1/9052 +f 9060/1/9060 9052/1/9052 9056/1/9056 +f 9060/1/9060 9056/1/9056 9058/1/9058 +f 9059/1/9059 9060/1/9060 9058/1/9058 +f 9199/1/9199 9060/1/9060 9059/1/9059 +f 9245/1/9245 9060/1/9060 9199/1/9199 +f 9245/1/9245 9199/1/9199 9243/1/9243 +f 9243/1/9243 9244/1/9244 9245/1/9245 +f 9245/1/9245 9244/1/9244 9246/1/9246 +f 9246/1/9246 9053/1/9053 9245/1/9245 +f 9069/1/9069 9053/1/9053 9246/1/9246 +f 9246/1/9246 9070/1/9070 9069/1/9069 +f 9068/1/9068 9069/1/9069 9070/1/9070 +f 9061/1/9061 9068/1/9068 9070/1/9070 +f 9200/1/9200 9061/1/9061 9070/1/9070 +f 9200/1/9200 9054/1/9054 9061/1/9061 +f 9061/1/9061 9054/1/9054 9062/1/9062 +f 9061/1/9061 9062/1/9062 9063/1/9063 +f 9061/1/9061 9063/1/9063 9064/1/9064 +f 9064/1/9064 9066/1/9066 9061/1/9061 +f 9064/1/9064 9065/1/9065 9066/1/9066 +f 9066/1/9066 9065/1/9065 9067/1/9067 +f 9066/1/9066 9067/1/9067 9068/1/9068 +f 9065/1/9065 9063/1/9063 9067/1/9067 +f 9064/1/9064 9063/1/9063 9065/1/9065 +f 9067/1/9067 9063/1/9063 9062/1/9062 +f 9067/1/9067 9062/1/9062 9069/1/9069 +f 9199/1/9199 9054/1/9054 9200/1/9200 +f 9199/1/9199 9200/1/9200 9198/1/9198 +f 9199/1/9199 9198/1/9198 9197/1/9197 +f 9197/1/9197 9198/1/9198 9100/1/9100 +f 9197/1/9197 9100/1/9100 9165/1/9165 +f 9166/1/9166 9197/1/9197 9165/1/9165 +f 9165/1/9165 9164/1/9164 9166/1/9166 +f 9123/1/9123 9166/1/9166 9164/1/9164 +f 9123/1/9123 9164/1/9164 9126/1/9126 +f 9125/1/9125 9123/1/9123 9126/1/9126 +f 9125/1/9125 9126/1/9126 9127/1/9127 +f 9127/1/9127 9161/1/9161 9125/1/9125 +f 9125/1/9125 9161/1/9161 9163/1/9163 +f 9125/1/9125 9163/1/9163 9124/1/9124 +f 9124/1/9124 9163/1/9163 9165/1/9165 +f 9161/1/9161 9162/1/9162 9163/1/9163 +f 9163/1/9163 9162/1/9162 9164/1/9164 +f 9161/1/9161 9159/1/9159 9162/1/9162 +f 9128/1/9128 9162/1/9162 9159/1/9159 +f 9128/1/9128 9159/1/9159 9130/1/9130 +f 9129/1/9129 9128/1/9128 9130/1/9130 +f 9235/1/9235 9129/1/9129 9130/1/9130 +f 9130/1/9130 9234/1/9234 9235/1/9235 +f 9234/1/9234 9236/1/9236 9235/1/9235 +f 9235/1/9235 9236/1/9236 9237/1/9237 +f 9235/1/9235 9237/1/9237 9238/1/9238 +f 9238/1/9238 9208/1/9208 9235/1/9235 +f 9238/1/9238 9204/1/9204 9208/1/9208 +f 9204/1/9204 9207/1/9207 9208/1/9208 +f 9208/1/9208 9207/1/9207 9209/1/9209 +f 9208/1/9208 9209/1/9209 9129/1/9129 +f 9129/1/9129 9209/1/9209 9210/1/9210 +f 9129/1/9129 9210/1/9210 9160/1/9160 +f 9129/1/9129 9160/1/9160 9127/1/9127 +f 9160/1/9160 9210/1/9210 9211/1/9211 +f 9160/1/9160 9211/1/9211 9212/1/9212 +f 9138/1/9138 9160/1/9160 9212/1/9212 +f 9138/1/9138 9212/1/9212 9192/1/9192 +f 9138/1/9138 9192/1/9192 9137/1/9137 +f 9137/1/9137 9135/1/9135 9138/1/9138 +f 9135/1/9135 9158/1/9158 9138/1/9138 +f 9156/1/9156 9158/1/9158 9135/1/9135 +f 9156/1/9156 9135/1/9135 9154/1/9154 +f 9156/1/9156 9154/1/9154 9155/1/9155 +f 9155/1/9155 9154/1/9154 9153/1/9153 +f 9145/1/9145 9155/1/9155 9153/1/9153 +f 9153/1/9153 9151/1/9151 9145/1/9145 +f 9145/1/9145 9151/1/9151 9149/1/9149 +f 9145/1/9145 9149/1/9149 9147/1/9147 +f 9147/1/9147 9146/1/9146 9145/1/9145 +f 9146/1/9146 9144/1/9144 9145/1/9145 +f 9145/1/9145 9144/1/9144 9143/1/9143 +f 9143/1/9143 9136/1/9136 9145/1/9145 +f 9132/1/9132 9136/1/9136 9143/1/9143 +f 9143/1/9143 9133/1/9133 9132/1/9132 +f 9131/1/9131 9132/1/9132 9133/1/9133 +f 9131/1/9131 9133/1/9133 9134/1/9134 +f 9131/1/9131 9134/1/9134 9140/1/9140 +f 9140/1/9140 9142/1/9142 9131/1/9131 +f 9131/1/9131 9142/1/9142 9144/1/9144 +f 9131/1/9131 9144/1/9144 9154/1/9154 +f 9140/1/9140 9141/1/9141 9142/1/9142 +f 9142/1/9142 9141/1/9141 9143/1/9143 +f 9141/1/9141 9139/1/9139 9143/1/9143 +f 9140/1/9140 9139/1/9139 9141/1/9141 +f 9134/1/9134 9139/1/9139 9140/1/9140 +f 9134/1/9134 9133/1/9133 9139/1/9139 +f 9135/1/9135 9132/1/9132 9131/1/9131 +f 9143/1/9143 9139/1/9139 9133/1/9133 +f 9136/1/9136 9132/1/9132 9135/1/9135 +f 9142/1/9142 9143/1/9143 9144/1/9144 +f 9154/1/9154 9144/1/9144 9146/1/9146 +f 9154/1/9154 9146/1/9146 9148/1/9148 +f 9150/1/9150 9154/1/9154 9148/1/9148 +f 9149/1/9149 9150/1/9150 9148/1/9148 +f 9150/1/9150 9152/1/9152 9154/1/9154 +f 9151/1/9151 9152/1/9152 9150/1/9150 +f 9147/1/9147 9148/1/9148 9146/1/9146 +f 9149/1/9149 9148/1/9148 9147/1/9147 +f 9151/1/9151 9150/1/9150 9149/1/9149 +f 9153/1/9153 9152/1/9152 9151/1/9151 +f 9145/1/9145 9136/1/9136 9155/1/9155 +f 9136/1/9136 9157/1/9157 9155/1/9155 +f 9157/1/9157 9158/1/9158 9155/1/9155 +f 9157/1/9157 9159/1/9159 9158/1/9158 +f 9158/1/9158 9159/1/9159 9160/1/9160 +f 9157/1/9157 9137/1/9137 9159/1/9159 +f 9159/1/9159 9137/1/9137 9233/1/9233 +f 9233/1/9233 9137/1/9137 9232/1/9232 +f 9232/1/9232 9212/1/9212 9233/1/9233 +f 9232/1/9232 9213/1/9213 9212/1/9212 +f 9213/1/9213 9186/1/9186 9212/1/9212 +f 9212/1/9212 9186/1/9186 9188/1/9188 +f 9212/1/9212 9188/1/9188 9190/1/9190 +f 9187/1/9187 9190/1/9190 9188/1/9188 +f 9189/1/9189 9190/1/9190 9187/1/9187 +f 9232/1/9232 9189/1/9189 9187/1/9187 +f 9232/1/9232 9187/1/9187 9231/1/9231 +f 9231/1/9231 9187/1/9187 9185/1/9185 +f 9231/1/9231 9185/1/9185 9230/1/9230 +f 9230/1/9230 9214/1/9214 9231/1/9231 +f 9231/1/9231 9214/1/9214 9213/1/9213 +f 9214/1/9214 9184/1/9184 9213/1/9213 +f 9214/1/9214 9182/1/9182 9184/1/9184 +f 9183/1/9183 9184/1/9184 9182/1/9182 +f 9183/1/9183 9182/1/9182 9181/1/9181 +f 9230/1/9230 9183/1/9183 9181/1/9181 +f 9230/1/9230 9181/1/9181 9229/1/9229 +f 9229/1/9229 9215/1/9215 9230/1/9230 +f 9229/1/9229 9216/1/9216 9215/1/9215 +f 9216/1/9216 9178/1/9178 9215/1/9215 +f 9215/1/9215 9178/1/9178 9180/1/9180 +f 9215/1/9215 9180/1/9180 9182/1/9182 +f 9179/1/9179 9180/1/9180 9178/1/9178 +f 9179/1/9179 9178/1/9178 9177/1/9177 +f 9228/1/9228 9179/1/9179 9177/1/9177 +f 9228/1/9228 9177/1/9177 9223/1/9223 +f 9223/1/9223 9217/1/9217 9228/1/9228 +f 9228/1/9228 9217/1/9217 9216/1/9216 +f 9217/1/9217 9176/1/9176 9216/1/9216 +f 9217/1/9217 9174/1/9174 9176/1/9176 +f 9173/1/9173 9176/1/9176 9174/1/9174 +f 9173/1/9173 9174/1/9174 9171/1/9171 +f 9223/1/9223 9173/1/9173 9171/1/9171 +f 9223/1/9223 9171/1/9171 9224/1/9224 +f 9222/1/9222 9223/1/9223 9224/1/9224 +f 9224/1/9224 9225/1/9225 9222/1/9222 +f 9222/1/9222 9225/1/9225 9226/1/9226 +f 9222/1/9222 9226/1/9226 9227/1/9227 +f 9227/1/9227 9205/1/9205 9222/1/9222 +f 9222/1/9222 9205/1/9205 9220/1/9220 +f 9221/1/9221 9220/1/9220 9205/1/9205 +f 9221/1/9221 9205/1/9205 9206/1/9206 +f 9226/1/9226 9221/1/9221 9206/1/9206 +f 9226/1/9226 9206/1/9206 9242/1/9242 +f 9242/1/9242 9206/1/9206 9202/1/9202 +f 9242/1/9242 9202/1/9202 9241/1/9241 +f 9227/1/9227 9242/1/9242 9241/1/9241 +f 9227/1/9227 9241/1/9241 9239/1/9239 +f 9239/1/9239 9203/1/9203 9227/1/9227 +f 9239/1/9239 9207/1/9207 9203/1/9203 +f 9237/1/9237 9207/1/9207 9239/1/9239 +f 9239/1/9239 9241/1/9241 9240/1/9240 +f 9239/1/9239 9240/1/9240 9238/1/9238 +f 9241/1/9241 9201/1/9201 9240/1/9240 +f 9240/1/9240 9201/1/9201 9204/1/9204 +f 9201/1/9201 9203/1/9203 9204/1/9204 +f 9201/1/9201 9202/1/9202 9203/1/9203 +f 9203/1/9203 9202/1/9202 9205/1/9205 +f 9241/1/9241 9202/1/9202 9201/1/9201 +f 9206/1/9206 9205/1/9205 9202/1/9202 +f 9219/1/9219 9220/1/9220 9221/1/9221 +f 9225/1/9225 9219/1/9219 9221/1/9221 +f 9219/1/9219 9217/1/9217 9220/1/9220 +f 9218/1/9218 9217/1/9217 9219/1/9219 +f 9224/1/9224 9218/1/9218 9219/1/9219 +f 9196/1/9196 9218/1/9218 9224/1/9224 +f 9224/1/9224 9167/1/9167 9196/1/9196 +f 9196/1/9196 9167/1/9167 9194/1/9194 +f 9194/1/9194 9195/1/9195 9196/1/9196 +f 9194/1/9194 9193/1/9193 9195/1/9195 +f 9193/1/9193 9169/1/9169 9195/1/9195 +f 9195/1/9195 9169/1/9169 9168/1/9168 +f 9195/1/9195 9168/1/9168 9218/1/9218 +f 9167/1/9167 9168/1/9168 9169/1/9169 +f 9167/1/9167 9169/1/9169 9170/1/9170 +f 9171/1/9171 9168/1/9168 9167/1/9167 +f 9172/1/9172 9168/1/9168 9171/1/9171 +f 9168/1/9168 9172/1/9172 9217/1/9217 +f 9170/1/9170 9169/1/9169 9193/1/9193 +f 9170/1/9170 9193/1/9193 9194/1/9194 +f 9167/1/9167 9170/1/9170 9194/1/9194 +f 9196/1/9196 9195/1/9195 9218/1/9218 +f 9218/1/9218 9168/1/9168 9217/1/9217 +f 9227/1/9227 9203/1/9203 9205/1/9205 +f 9227/1/9227 9226/1/9226 9242/1/9242 +f 9225/1/9225 9221/1/9221 9226/1/9226 +f 9224/1/9224 9219/1/9219 9225/1/9225 +f 9222/1/9222 9220/1/9220 9223/1/9223 +f 9224/1/9224 9171/1/9171 9167/1/9167 +f 9175/1/9175 9173/1/9173 9223/1/9223 +f 9171/1/9171 9174/1/9174 9172/1/9172 +f 9175/1/9175 9176/1/9176 9173/1/9173 +f 9177/1/9177 9176/1/9176 9175/1/9175 +f 9172/1/9172 9174/1/9174 9217/1/9217 +f 9223/1/9223 9220/1/9220 9217/1/9217 +f 9223/1/9223 9177/1/9177 9175/1/9175 +f 9229/1/9229 9179/1/9179 9228/1/9228 +f 9177/1/9177 9178/1/9178 9176/1/9176 +f 9181/1/9181 9180/1/9180 9179/1/9179 +f 9216/1/9216 9176/1/9176 9178/1/9178 +f 9228/1/9228 9216/1/9216 9229/1/9229 +f 9229/1/9229 9181/1/9181 9179/1/9179 +f 9181/1/9181 9182/1/9182 9180/1/9180 +f 9185/1/9185 9184/1/9184 9183/1/9183 +f 9185/1/9185 9186/1/9186 9184/1/9184 +f 9215/1/9215 9182/1/9182 9214/1/9214 +f 9230/1/9230 9215/1/9215 9214/1/9214 +f 9230/1/9230 9185/1/9185 9183/1/9183 +f 9187/1/9187 9186/1/9186 9185/1/9185 +f 9191/1/9191 9189/1/9189 9232/1/9232 +f 9191/1/9191 9192/1/9192 9189/1/9189 +f 9189/1/9189 9192/1/9192 9190/1/9190 +f 9187/1/9187 9188/1/9188 9186/1/9186 +f 9213/1/9213 9184/1/9184 9186/1/9186 +f 9231/1/9231 9213/1/9213 9232/1/9232 +f 9232/1/9232 9137/1/9137 9191/1/9191 +f 9137/1/9137 9157/1/9157 9136/1/9136 +f 9153/1/9153 9154/1/9154 9152/1/9152 +f 9154/1/9154 9135/1/9135 9131/1/9131 +f 9155/1/9155 9158/1/9158 9156/1/9156 +f 9136/1/9136 9135/1/9135 9137/1/9137 +f 9137/1/9137 9192/1/9192 9191/1/9191 +f 9192/1/9192 9212/1/9212 9190/1/9190 +f 9158/1/9158 9160/1/9160 9138/1/9138 +f 9233/1/9233 9212/1/9212 9211/1/9211 +f 9233/1/9233 9211/1/9211 9234/1/9234 +f 9234/1/9234 9211/1/9211 9210/1/9210 +f 9236/1/9236 9210/1/9210 9209/1/9209 +f 9237/1/9237 9209/1/9209 9207/1/9207 +f 9204/1/9204 9203/1/9203 9207/1/9207 +f 9240/1/9240 9204/1/9204 9238/1/9238 +f 9238/1/9238 9237/1/9237 9239/1/9239 +f 9236/1/9236 9209/1/9209 9237/1/9237 +f 9234/1/9234 9210/1/9210 9236/1/9236 +f 9130/1/9130 9233/1/9233 9234/1/9234 +f 9208/1/9208 9129/1/9129 9235/1/9235 +f 9127/1/9127 9128/1/9128 9129/1/9129 +f 9159/1/9159 9233/1/9233 9130/1/9130 +f 9126/1/9126 9162/1/9162 9128/1/9128 +f 9160/1/9160 9159/1/9159 9161/1/9161 +f 9127/1/9127 9160/1/9160 9161/1/9161 +f 9127/1/9127 9126/1/9126 9128/1/9128 +f 9124/1/9124 9123/1/9123 9125/1/9125 +f 9121/1/9121 9123/1/9123 9124/1/9124 +f 9121/1/9121 9124/1/9124 9100/1/9100 +f 9121/1/9121 9100/1/9100 9119/1/9119 +f 9119/1/9119 9120/1/9120 9121/1/9121 +f 9121/1/9121 9120/1/9120 9122/1/9122 +f 9120/1/9120 9099/1/9099 9122/1/9122 +f 9166/1/9166 9122/1/9122 9099/1/9099 +f 9166/1/9166 9099/1/9099 9243/1/9243 +f 9120/1/9120 9097/1/9097 9099/1/9099 +f 9098/1/9098 9099/1/9099 9097/1/9097 +f 9098/1/9098 9097/1/9097 9096/1/9096 +f 9117/1/9117 9098/1/9098 9096/1/9096 +f 9117/1/9117 9096/1/9096 9115/1/9115 +f 9115/1/9115 9116/1/9116 9117/1/9117 +f 9117/1/9117 9116/1/9116 9118/1/9118 +f 9117/1/9117 9118/1/9118 9119/1/9119 +f 9116/1/9116 9095/1/9095 9118/1/9118 +f 9118/1/9118 9095/1/9095 9097/1/9097 +f 9116/1/9116 9093/1/9093 9095/1/9095 +f 9094/1/9094 9095/1/9095 9093/1/9093 +f 9094/1/9094 9093/1/9093 9092/1/9092 +f 9114/1/9114 9094/1/9094 9092/1/9092 +f 9090/1/9090 9114/1/9114 9092/1/9092 +f 9092/1/9092 9089/1/9089 9090/1/9090 +f 9089/1/9089 9088/1/9088 9090/1/9090 +f 9112/1/9112 9090/1/9090 9088/1/9088 +f 9112/1/9112 9088/1/9088 9110/1/9110 +f 9109/1/9109 9112/1/9112 9110/1/9110 +f 9109/1/9109 9110/1/9110 9107/1/9107 +f 9107/1/9107 9086/1/9086 9109/1/9109 +f 9109/1/9109 9086/1/9086 9087/1/9087 +f 9109/1/9109 9087/1/9087 9111/1/9111 +f 9111/1/9111 9087/1/9087 9089/1/9089 +f 9091/1/9091 9111/1/9111 9089/1/9089 +f 9113/1/9113 9111/1/9111 9091/1/9091 +f 9113/1/9113 9091/1/9091 9093/1/9093 +f 9111/1/9111 9113/1/9113 9112/1/9112 +f 9112/1/9112 9113/1/9113 9114/1/9114 +f 9114/1/9114 9113/1/9113 9115/1/9115 +f 9086/1/9086 9085/1/9085 9087/1/9087 +f 9087/1/9087 9085/1/9085 9088/1/9088 +f 9086/1/9086 9084/1/9084 9085/1/9085 +f 9085/1/9085 9084/1/9084 9083/1/9083 +f 9083/1/9083 9075/1/9075 9085/1/9085 +f 9085/1/9085 9075/1/9075 9106/1/9106 +f 9085/1/9085 9106/1/9106 9108/1/9108 +f 9110/1/9110 9085/1/9085 9108/1/9108 +f 9108/1/9108 9106/1/9106 9107/1/9107 +f 9107/1/9107 9106/1/9106 9105/1/9105 +f 9105/1/9105 9084/1/9084 9107/1/9107 +f 9105/1/9105 9072/1/9072 9084/1/9084 +f 9072/1/9072 9076/1/9076 9084/1/9084 +f 9076/1/9076 9078/1/9078 9084/1/9084 +f 9084/1/9084 9078/1/9078 9080/1/9080 +f 9084/1/9084 9080/1/9080 9082/1/9082 +f 9081/1/9081 9082/1/9082 9080/1/9080 +f 9081/1/9081 9080/1/9080 9079/1/9079 +f 9075/1/9075 9081/1/9081 9079/1/9079 +f 9075/1/9075 9079/1/9079 9077/1/9077 +f 9077/1/9077 9076/1/9076 9075/1/9075 +f 9079/1/9079 9078/1/9078 9077/1/9077 +f 9083/1/9083 9082/1/9082 9081/1/9081 +f 9079/1/9079 9080/1/9080 9078/1/9078 +f 9077/1/9077 9078/1/9078 9076/1/9076 +f 9076/1/9076 9072/1/9072 9075/1/9075 +f 9075/1/9075 9072/1/9072 9071/1/9071 +f 9071/1/9071 9072/1/9072 9073/1/9073 +f 9071/1/9071 9073/1/9073 9074/1/9074 +f 9074/1/9074 9106/1/9106 9071/1/9071 +f 9074/1/9074 9104/1/9104 9106/1/9106 +f 9102/1/9102 9104/1/9104 9074/1/9074 +f 9074/1/9074 9101/1/9101 9102/1/9102 +f 9102/1/9102 9101/1/9101 9103/1/9103 +f 9101/1/9101 9073/1/9073 9103/1/9103 +f 9102/1/9102 9103/1/9103 9104/1/9104 +f 9104/1/9104 9103/1/9103 9105/1/9105 +f 9074/1/9074 9073/1/9073 9101/1/9101 +f 9103/1/9103 9073/1/9073 9072/1/9072 +f 9103/1/9103 9072/1/9072 9105/1/9105 +f 9104/1/9104 9105/1/9105 9106/1/9106 +f 9071/1/9071 9106/1/9106 9075/1/9075 +f 9083/1/9083 9081/1/9081 9075/1/9075 +f 9083/1/9083 9084/1/9084 9082/1/9082 +f 9107/1/9107 9084/1/9084 9086/1/9086 +f 9107/1/9107 9110/1/9110 9108/1/9108 +f 9111/1/9111 9112/1/9112 9109/1/9109 +f 9110/1/9110 9088/1/9088 9085/1/9085 +f 9087/1/9087 9088/1/9088 9089/1/9089 +f 9091/1/9091 9089/1/9089 9092/1/9092 +f 9112/1/9112 9114/1/9114 9090/1/9090 +f 9115/1/9115 9094/1/9094 9114/1/9114 +f 9092/1/9092 9093/1/9093 9091/1/9091 +f 9096/1/9096 9095/1/9095 9094/1/9094 +f 9113/1/9113 9093/1/9093 9116/1/9116 +f 9115/1/9115 9113/1/9113 9116/1/9116 +f 9115/1/9115 9096/1/9096 9094/1/9094 +f 9119/1/9119 9098/1/9098 9117/1/9117 +f 9096/1/9096 9097/1/9097 9095/1/9095 +f 9100/1/9100 9099/1/9099 9098/1/9098 +f 9099/1/9099 9100/1/9100 9244/1/9244 +f 9118/1/9118 9097/1/9097 9120/1/9120 +f 9119/1/9119 9118/1/9118 9120/1/9120 +f 9119/1/9119 9100/1/9100 9098/1/9098 +f 9122/1/9122 9123/1/9123 9121/1/9121 +f 9126/1/9126 9164/1/9164 9162/1/9162 +f 9123/1/9123 9122/1/9122 9166/1/9166 +f 9163/1/9163 9164/1/9164 9165/1/9165 +f 9243/1/9243 9197/1/9197 9166/1/9166 +f 9100/1/9100 9124/1/9124 9165/1/9165 +f 9244/1/9244 9100/1/9100 9198/1/9198 +f 9246/1/9246 9198/1/9198 9200/1/9200 +f 9061/1/9061 9066/1/9066 9068/1/9068 +f 9068/1/9068 9067/1/9067 9069/1/9069 +f 9200/1/9200 9070/1/9070 9246/1/9246 +f 9069/1/9069 9062/1/9062 9053/1/9053 +f 9244/1/9244 9198/1/9198 9246/1/9246 +f 9243/1/9243 9099/1/9099 9244/1/9244 +f 9243/1/9243 9199/1/9199 9197/1/9197 +f 9060/1/9060 9245/1/9245 9053/1/9053 +f 9059/1/9059 9054/1/9054 9199/1/9199 +f 9055/1/9055 9051/1/9051 9057/1/9057 +f 9062/1/9062 9054/1/9054 9053/1/9053 +f 9053/1/9053 9052/1/9052 9060/1/9060 +f 9055/1/9055 9052/1/9052 9051/1/9051 +f 9247/1/9247 9248/1/9248 9249/1/9249 +f 9247/1/9247 9249/1/9249 9250/1/9250 +f 9253/1/9253 9247/1/9247 9250/1/9250 +f 9253/1/9253 9250/1/9250 9255/1/9255 +f 9255/1/9255 9254/1/9254 9253/1/9253 +f 9253/1/9253 9254/1/9254 9252/1/9252 +f 9253/1/9253 9252/1/9252 9251/1/9251 +f 9251/1/9251 9252/1/9252 9248/1/9248 +f 9252/1/9252 9254/1/9254 9248/1/9248 +f 9248/1/9248 9254/1/9254 9256/1/9256 +f 9255/1/9255 9256/1/9256 9254/1/9254 +f 9255/1/9255 9257/1/9257 9256/1/9256 +f 9256/1/9256 9257/1/9257 9258/1/9258 +f 9258/1/9258 9266/1/9266 9256/1/9256 +f 9249/1/9249 9256/1/9256 9266/1/9266 +f 9249/1/9249 9266/1/9266 9442/1/9442 +f 9442/1/9442 9266/1/9266 9441/1/9441 +f 9442/1/9442 9441/1/9441 9439/1/9439 +f 9439/1/9439 9394/1/9394 9442/1/9442 +f 9442/1/9442 9394/1/9394 9396/1/9396 +f 9250/1/9250 9442/1/9442 9396/1/9396 +f 9396/1/9396 9395/1/9395 9250/1/9250 +f 9250/1/9250 9395/1/9395 9265/1/9265 +f 9250/1/9250 9265/1/9265 9257/1/9257 +f 9257/1/9257 9265/1/9265 9261/1/9261 +f 9257/1/9257 9261/1/9261 9259/1/9259 +f 9261/1/9261 9260/1/9260 9259/1/9259 +f 9259/1/9259 9260/1/9260 9258/1/9258 +f 9261/1/9261 9262/1/9262 9260/1/9260 +f 9262/1/9262 9264/1/9264 9260/1/9260 +f 9260/1/9260 9264/1/9264 9266/1/9266 +f 9265/1/9265 9266/1/9266 9264/1/9264 +f 9265/1/9265 9264/1/9264 9263/1/9263 +f 9263/1/9263 9264/1/9264 9262/1/9262 +f 9263/1/9263 9262/1/9262 9261/1/9261 +f 9265/1/9265 9263/1/9263 9261/1/9261 +f 9265/1/9265 9395/1/9395 9266/1/9266 +f 9394/1/9394 9395/1/9395 9396/1/9396 +f 9394/1/9394 9393/1/9393 9395/1/9395 +f 9440/1/9440 9395/1/9395 9393/1/9393 +f 9440/1/9440 9393/1/9393 9326/1/9326 +f 9352/1/9352 9440/1/9440 9326/1/9326 +f 9326/1/9326 9287/1/9287 9352/1/9352 +f 9289/1/9289 9352/1/9352 9287/1/9287 +f 9288/1/9288 9289/1/9289 9287/1/9287 +f 9287/1/9287 9285/1/9285 9288/1/9288 +f 9288/1/9288 9285/1/9285 9286/1/9286 +f 9288/1/9288 9286/1/9286 9351/1/9351 +f 9288/1/9288 9351/1/9351 9290/1/9290 +f 9290/1/9290 9351/1/9351 9349/1/9349 +f 9290/1/9290 9349/1/9349 9292/1/9292 +f 9292/1/9292 9291/1/9291 9290/1/9290 +f 9290/1/9290 9291/1/9291 9289/1/9289 +f 9291/1/9291 9350/1/9350 9289/1/9289 +f 9291/1/9291 9348/1/9348 9350/1/9350 +f 9347/1/9347 9350/1/9350 9348/1/9348 +f 9347/1/9347 9348/1/9348 9345/1/9345 +f 9294/1/9294 9347/1/9347 9345/1/9345 +f 9345/1/9345 9417/1/9417 9294/1/9294 +f 9294/1/9294 9417/1/9417 9400/1/9400 +f 9294/1/9294 9400/1/9400 9397/1/9397 +f 9294/1/9294 9397/1/9397 9293/1/9293 +f 9294/1/9294 9293/1/9293 9292/1/9292 +f 9293/1/9293 9397/1/9397 9438/1/9438 +f 9437/1/9437 9293/1/9293 9438/1/9438 +f 9437/1/9437 9438/1/9438 9435/1/9435 +f 9435/1/9435 9398/1/9398 9437/1/9437 +f 9437/1/9437 9398/1/9398 9401/1/9401 +f 9437/1/9437 9401/1/9401 9420/1/9420 +f 9420/1/9420 9401/1/9401 9400/1/9400 +f 9420/1/9420 9400/1/9400 9418/1/9418 +f 9418/1/9418 9346/1/9346 9420/1/9420 +f 9420/1/9420 9346/1/9346 9293/1/9293 +f 9293/1/9293 9346/1/9346 9348/1/9348 +f 9346/1/9346 9418/1/9418 9419/1/9419 +f 9362/1/9362 9346/1/9346 9419/1/9419 +f 9362/1/9362 9419/1/9419 9391/1/9391 +f 9391/1/9391 9361/1/9361 9362/1/9362 +f 9361/1/9361 9359/1/9359 9362/1/9362 +f 9359/1/9359 9342/1/9342 9362/1/9362 +f 9362/1/9362 9342/1/9342 9344/1/9344 +f 9341/1/9341 9344/1/9344 9342/1/9342 +f 9340/1/9340 9341/1/9341 9342/1/9342 +f 9342/1/9342 9332/1/9332 9340/1/9340 +f 9332/1/9332 9338/1/9338 9340/1/9340 +f 9338/1/9338 9339/1/9339 9340/1/9340 +f 9338/1/9338 9337/1/9337 9339/1/9339 +f 9337/1/9337 9331/1/9331 9339/1/9339 +f 9339/1/9339 9331/1/9331 9341/1/9341 +f 9341/1/9341 9331/1/9331 9360/1/9360 +f 9361/1/9361 9341/1/9341 9360/1/9360 +f 9343/1/9343 9341/1/9341 9361/1/9361 +f 9343/1/9343 9361/1/9361 9345/1/9345 +f 9345/1/9345 9344/1/9344 9343/1/9343 +f 9346/1/9346 9344/1/9344 9345/1/9345 +f 9360/1/9360 9331/1/9331 9327/1/9327 +f 9360/1/9360 9327/1/9327 9358/1/9358 +f 9358/1/9358 9359/1/9359 9360/1/9360 +f 9357/1/9357 9359/1/9359 9358/1/9358 +f 9356/1/9356 9357/1/9357 9358/1/9358 +f 9356/1/9356 9355/1/9355 9357/1/9357 +f 9355/1/9355 9328/1/9328 9357/1/9357 +f 9355/1/9355 9329/1/9329 9328/1/9328 +f 9327/1/9327 9328/1/9328 9329/1/9329 +f 9327/1/9327 9329/1/9329 9330/1/9330 +f 9330/1/9330 9354/1/9354 9327/1/9327 +f 9327/1/9327 9354/1/9354 9356/1/9356 +f 9330/1/9330 9353/1/9353 9354/1/9354 +f 9354/1/9354 9353/1/9353 9355/1/9355 +f 9330/1/9330 9329/1/9329 9353/1/9353 +f 9353/1/9353 9329/1/9329 9355/1/9355 +f 9354/1/9354 9355/1/9355 9356/1/9356 +f 9357/1/9357 9328/1/9328 9359/1/9359 +f 9327/1/9327 9356/1/9356 9358/1/9358 +f 9327/1/9327 9331/1/9331 9328/1/9328 +f 9328/1/9328 9331/1/9331 9332/1/9332 +f 9332/1/9332 9331/1/9331 9333/1/9333 +f 9332/1/9332 9333/1/9333 9334/1/9334 +f 9334/1/9334 9336/1/9336 9332/1/9332 +f 9334/1/9334 9335/1/9335 9336/1/9336 +f 9336/1/9336 9335/1/9335 9337/1/9337 +f 9335/1/9335 9333/1/9333 9337/1/9337 +f 9334/1/9334 9333/1/9333 9335/1/9335 +f 9337/1/9337 9333/1/9333 9331/1/9331 +f 9336/1/9336 9337/1/9337 9338/1/9338 +f 9332/1/9332 9336/1/9336 9338/1/9338 +f 9342/1/9342 9328/1/9328 9332/1/9332 +f 9339/1/9339 9341/1/9341 9340/1/9340 +f 9343/1/9343 9344/1/9344 9341/1/9341 +f 9359/1/9359 9328/1/9328 9342/1/9342 +f 9360/1/9360 9359/1/9359 9361/1/9361 +f 9392/1/9392 9361/1/9361 9391/1/9391 +f 9391/1/9391 9390/1/9390 9392/1/9392 +f 9392/1/9392 9390/1/9390 9416/1/9416 +f 9416/1/9416 9390/1/9390 9387/1/9387 +f 9416/1/9416 9387/1/9387 9415/1/9415 +f 9421/1/9421 9416/1/9416 9415/1/9415 +f 9421/1/9421 9415/1/9415 9422/1/9422 +f 9422/1/9422 9384/1/9384 9421/1/9421 +f 9421/1/9421 9384/1/9384 9386/1/9386 +f 9421/1/9421 9386/1/9386 9419/1/9419 +f 9419/1/9419 9386/1/9386 9388/1/9388 +f 9419/1/9419 9388/1/9388 9389/1/9389 +f 9388/1/9388 9387/1/9387 9389/1/9389 +f 9386/1/9386 9387/1/9387 9388/1/9388 +f 9386/1/9386 9385/1/9385 9387/1/9387 +f 9384/1/9384 9385/1/9385 9386/1/9386 +f 9384/1/9384 9383/1/9383 9385/1/9385 +f 9414/1/9414 9385/1/9385 9383/1/9383 +f 9414/1/9414 9383/1/9383 9381/1/9381 +f 9414/1/9414 9381/1/9381 9413/1/9413 +f 9423/1/9423 9414/1/9414 9413/1/9413 +f 9423/1/9423 9413/1/9413 9424/1/9424 +f 9424/1/9424 9378/1/9378 9423/1/9423 +f 9423/1/9423 9378/1/9378 9380/1/9380 +f 9423/1/9423 9380/1/9380 9382/1/9382 +f 9423/1/9423 9382/1/9382 9422/1/9422 +f 9380/1/9380 9381/1/9381 9382/1/9382 +f 9380/1/9380 9379/1/9379 9381/1/9381 +f 9378/1/9378 9379/1/9379 9380/1/9380 +f 9378/1/9378 9377/1/9377 9379/1/9379 +f 9412/1/9412 9379/1/9379 9377/1/9377 +f 9412/1/9412 9377/1/9377 9409/1/9409 +f 9425/1/9425 9412/1/9412 9409/1/9409 +f 9425/1/9425 9409/1/9409 9428/1/9428 +f 9427/1/9427 9425/1/9425 9428/1/9428 +f 9427/1/9427 9428/1/9428 9429/1/9429 +f 9429/1/9429 9411/1/9411 9427/1/9427 +f 9427/1/9427 9411/1/9411 9410/1/9410 +f 9427/1/9427 9410/1/9410 9426/1/9426 +f 9426/1/9426 9410/1/9410 9364/1/9364 +f 9426/1/9426 9364/1/9364 9363/1/9363 +f 9363/1/9363 9370/1/9370 9426/1/9426 +f 9426/1/9426 9370/1/9370 9425/1/9425 +f 9370/1/9370 9372/1/9372 9425/1/9425 +f 9372/1/9372 9373/1/9373 9425/1/9425 +f 9425/1/9425 9373/1/9373 9375/1/9375 +f 9425/1/9425 9375/1/9375 9424/1/9424 +f 9373/1/9373 9374/1/9374 9375/1/9375 +f 9375/1/9375 9374/1/9374 9376/1/9376 +f 9375/1/9375 9376/1/9376 9377/1/9377 +f 9376/1/9376 9374/1/9374 9409/1/9409 +f 9409/1/9409 9374/1/9374 9371/1/9371 +f 9409/1/9409 9371/1/9371 9410/1/9410 +f 9406/1/9406 9409/1/9409 9410/1/9410 +f 9410/1/9410 9371/1/9371 9369/1/9369 +f 9369/1/9369 9371/1/9371 9370/1/9370 +f 9368/1/9368 9369/1/9369 9370/1/9370 +f 9368/1/9368 9367/1/9367 9369/1/9369 +f 9369/1/9369 9367/1/9367 9365/1/9365 +f 9364/1/9364 9369/1/9369 9365/1/9365 +f 9366/1/9366 9365/1/9365 9367/1/9367 +f 9363/1/9363 9365/1/9365 9366/1/9366 +f 9366/1/9366 9368/1/9368 9363/1/9363 +f 9366/1/9366 9367/1/9367 9368/1/9368 +f 9373/1/9373 9371/1/9371 9374/1/9374 +f 9372/1/9372 9371/1/9371 9373/1/9373 +f 9370/1/9370 9371/1/9371 9372/1/9372 +f 9363/1/9363 9368/1/9368 9370/1/9370 +f 9363/1/9363 9364/1/9364 9365/1/9365 +f 9410/1/9410 9369/1/9369 9364/1/9364 +f 9410/1/9410 9411/1/9411 9406/1/9406 +f 9406/1/9406 9411/1/9411 9407/1/9407 +f 9406/1/9406 9407/1/9407 9404/1/9404 +f 9430/1/9430 9406/1/9406 9404/1/9404 +f 9430/1/9430 9404/1/9404 9433/1/9433 +f 9432/1/9432 9430/1/9430 9433/1/9433 +f 9433/1/9433 9434/1/9434 9432/1/9432 +f 9434/1/9434 9405/1/9405 9432/1/9432 +f 9432/1/9432 9405/1/9405 9408/1/9408 +f 9432/1/9432 9408/1/9408 9431/1/9431 +f 9431/1/9431 9408/1/9408 9407/1/9407 +f 9431/1/9431 9407/1/9407 9429/1/9429 +f 9429/1/9429 9430/1/9430 9431/1/9431 +f 9404/1/9404 9408/1/9408 9405/1/9405 +f 9404/1/9404 9405/1/9405 9402/1/9402 +f 9402/1/9402 9405/1/9405 9403/1/9403 +f 9402/1/9402 9403/1/9403 9399/1/9399 +f 9399/1/9399 9398/1/9398 9402/1/9402 +f 9397/1/9397 9398/1/9398 9399/1/9399 +f 9436/1/9436 9399/1/9399 9403/1/9403 +f 9436/1/9436 9403/1/9403 9434/1/9434 +f 9438/1/9438 9399/1/9399 9436/1/9436 +f 9434/1/9434 9403/1/9403 9405/1/9405 +f 9433/1/9433 9436/1/9436 9434/1/9434 +f 9435/1/9435 9436/1/9436 9433/1/9433 +f 9433/1/9433 9402/1/9402 9435/1/9435 +f 9431/1/9431 9430/1/9430 9432/1/9432 +f 9433/1/9433 9404/1/9404 9402/1/9402 +f 9428/1/9428 9406/1/9406 9430/1/9430 +f 9404/1/9404 9407/1/9407 9408/1/9408 +f 9429/1/9429 9407/1/9407 9411/1/9411 +f 9429/1/9429 9428/1/9428 9430/1/9430 +f 9426/1/9426 9425/1/9425 9427/1/9427 +f 9428/1/9428 9409/1/9409 9406/1/9406 +f 9424/1/9424 9412/1/9412 9425/1/9425 +f 9409/1/9409 9377/1/9377 9376/1/9376 +f 9413/1/9413 9379/1/9379 9412/1/9412 +f 9375/1/9375 9377/1/9377 9378/1/9378 +f 9424/1/9424 9375/1/9375 9378/1/9378 +f 9424/1/9424 9413/1/9413 9412/1/9412 +f 9422/1/9422 9414/1/9414 9423/1/9423 +f 9413/1/9413 9381/1/9381 9379/1/9379 +f 9382/1/9382 9381/1/9381 9383/1/9383 +f 9415/1/9415 9385/1/9385 9414/1/9414 +f 9382/1/9382 9383/1/9383 9384/1/9384 +f 9422/1/9422 9382/1/9382 9384/1/9384 +f 9422/1/9422 9415/1/9415 9414/1/9414 +f 9419/1/9419 9416/1/9416 9421/1/9421 +f 9419/1/9419 9417/1/9417 9416/1/9416 +f 9417/1/9417 9361/1/9361 9416/1/9416 +f 9415/1/9415 9387/1/9387 9385/1/9385 +f 9389/1/9389 9387/1/9387 9390/1/9390 +f 9389/1/9389 9390/1/9390 9391/1/9391 +f 9416/1/9416 9361/1/9361 9392/1/9392 +f 9391/1/9391 9419/1/9419 9389/1/9389 +f 9344/1/9344 9346/1/9346 9362/1/9362 +f 9418/1/9418 9417/1/9417 9419/1/9419 +f 9397/1/9397 9401/1/9401 9398/1/9398 +f 9435/1/9435 9402/1/9402 9398/1/9398 +f 9435/1/9435 9438/1/9438 9436/1/9436 +f 9420/1/9420 9293/1/9293 9437/1/9437 +f 9438/1/9438 9397/1/9397 9399/1/9399 +f 9397/1/9397 9400/1/9400 9401/1/9401 +f 9418/1/9418 9400/1/9400 9417/1/9417 +f 9345/1/9345 9361/1/9361 9417/1/9417 +f 9292/1/9292 9347/1/9347 9294/1/9294 +f 9345/1/9345 9348/1/9348 9346/1/9346 +f 9349/1/9349 9350/1/9350 9347/1/9347 +f 9349/1/9349 9352/1/9352 9350/1/9350 +f 9293/1/9293 9348/1/9348 9291/1/9291 +f 9292/1/9292 9293/1/9293 9291/1/9291 +f 9292/1/9292 9349/1/9349 9347/1/9347 +f 9351/1/9351 9352/1/9352 9349/1/9349 +f 9352/1/9352 9351/1/9351 9439/1/9439 +f 9351/1/9351 9286/1/9286 9325/1/9325 +f 9351/1/9351 9325/1/9325 9393/1/9393 +f 9286/1/9286 9323/1/9323 9325/1/9325 +f 9323/1/9323 9324/1/9324 9325/1/9325 +f 9325/1/9325 9324/1/9324 9326/1/9326 +f 9285/1/9285 9326/1/9326 9324/1/9324 +f 9285/1/9285 9324/1/9324 9283/1/9283 +f 9284/1/9284 9285/1/9285 9283/1/9283 +f 9284/1/9284 9283/1/9283 9282/1/9282 +f 9282/1/9282 9321/1/9321 9284/1/9284 +f 9284/1/9284 9321/1/9321 9323/1/9323 +f 9321/1/9321 9322/1/9322 9323/1/9323 +f 9321/1/9321 9320/1/9320 9322/1/9322 +f 9281/1/9281 9322/1/9322 9320/1/9320 +f 9281/1/9281 9320/1/9320 9279/1/9279 +f 9280/1/9280 9281/1/9281 9279/1/9279 +f 9280/1/9280 9279/1/9279 9278/1/9278 +f 9278/1/9278 9318/1/9318 9280/1/9280 +f 9280/1/9280 9318/1/9318 9319/1/9319 +f 9280/1/9280 9319/1/9319 9282/1/9282 +f 9318/1/9318 9317/1/9317 9319/1/9319 +f 9319/1/9319 9317/1/9317 9320/1/9320 +f 9316/1/9316 9317/1/9317 9318/1/9318 +f 9318/1/9318 9276/1/9276 9316/1/9316 +f 9274/1/9274 9316/1/9316 9276/1/9276 +f 9275/1/9275 9274/1/9274 9276/1/9276 +f 9278/1/9278 9275/1/9275 9276/1/9276 +f 9277/1/9277 9275/1/9275 9278/1/9278 +f 9275/1/9275 9277/1/9277 9315/1/9315 +f 9275/1/9275 9315/1/9315 9273/1/9273 +f 9273/1/9273 9315/1/9315 9313/1/9313 +f 9273/1/9273 9313/1/9313 9272/1/9272 +f 9272/1/9272 9271/1/9271 9273/1/9273 +f 9273/1/9273 9271/1/9271 9274/1/9274 +f 9271/1/9271 9314/1/9314 9274/1/9274 +f 9271/1/9271 9312/1/9312 9314/1/9314 +f 9311/1/9311 9314/1/9314 9312/1/9312 +f 9310/1/9310 9311/1/9311 9312/1/9312 +f 9312/1/9312 9302/1/9302 9310/1/9310 +f 9310/1/9310 9302/1/9302 9306/1/9306 +f 9310/1/9310 9306/1/9306 9308/1/9308 +f 9308/1/9308 9309/1/9309 9310/1/9310 +f 9308/1/9308 9307/1/9307 9309/1/9309 +f 9307/1/9307 9301/1/9301 9309/1/9309 +f 9309/1/9309 9301/1/9301 9311/1/9311 +f 9311/1/9311 9301/1/9301 9272/1/9272 +f 9272/1/9272 9301/1/9301 9299/1/9299 +f 9272/1/9272 9299/1/9299 9268/1/9268 +f 9268/1/9268 9299/1/9299 9295/1/9295 +f 9268/1/9268 9295/1/9295 9269/1/9269 +f 9267/1/9267 9268/1/9268 9269/1/9269 +f 9267/1/9267 9269/1/9269 9270/1/9270 +f 9267/1/9267 9270/1/9270 9300/1/9300 +f 9300/1/9300 9271/1/9271 9267/1/9267 +f 9300/1/9300 9270/1/9270 9296/1/9296 +f 9300/1/9300 9296/1/9296 9298/1/9298 +f 9298/1/9298 9299/1/9299 9300/1/9300 +f 9298/1/9298 9297/1/9297 9299/1/9299 +f 9296/1/9296 9297/1/9297 9298/1/9298 +f 9296/1/9296 9295/1/9295 9297/1/9297 +f 9270/1/9270 9295/1/9295 9296/1/9296 +f 9267/1/9267 9271/1/9271 9268/1/9268 +f 9270/1/9270 9269/1/9269 9295/1/9295 +f 9299/1/9299 9297/1/9297 9295/1/9295 +f 9299/1/9299 9301/1/9301 9300/1/9300 +f 9300/1/9300 9301/1/9301 9302/1/9302 +f 9302/1/9302 9301/1/9301 9303/1/9303 +f 9302/1/9302 9303/1/9303 9304/1/9304 +f 9304/1/9304 9303/1/9303 9305/1/9305 +f 9304/1/9304 9305/1/9305 9306/1/9306 +f 9306/1/9306 9305/1/9305 9307/1/9307 +f 9305/1/9305 9303/1/9303 9307/1/9307 +f 9307/1/9307 9303/1/9303 9301/1/9301 +f 9306/1/9306 9307/1/9307 9308/1/9308 +f 9302/1/9302 9304/1/9304 9306/1/9306 +f 9312/1/9312 9300/1/9300 9302/1/9302 +f 9309/1/9309 9311/1/9311 9310/1/9310 +f 9313/1/9313 9314/1/9314 9311/1/9311 +f 9313/1/9313 9316/1/9316 9314/1/9314 +f 9271/1/9271 9300/1/9300 9312/1/9312 +f 9268/1/9268 9271/1/9271 9272/1/9272 +f 9272/1/9272 9313/1/9313 9311/1/9311 +f 9315/1/9315 9316/1/9316 9313/1/9313 +f 9315/1/9315 9277/1/9277 9317/1/9317 +f 9279/1/9279 9317/1/9317 9277/1/9277 +f 9273/1/9273 9274/1/9274 9275/1/9275 +f 9274/1/9274 9314/1/9314 9316/1/9316 +f 9315/1/9315 9317/1/9317 9316/1/9316 +f 9278/1/9278 9276/1/9276 9318/1/9318 +f 9278/1/9278 9279/1/9279 9277/1/9277 +f 9282/1/9282 9281/1/9281 9280/1/9280 +f 9279/1/9279 9320/1/9320 9317/1/9317 +f 9283/1/9283 9322/1/9322 9281/1/9281 +f 9319/1/9319 9320/1/9320 9321/1/9321 +f 9282/1/9282 9319/1/9319 9321/1/9321 +f 9282/1/9282 9283/1/9283 9281/1/9281 +f 9283/1/9283 9324/1/9324 9322/1/9322 +f 9323/1/9323 9322/1/9322 9324/1/9324 +f 9284/1/9284 9323/1/9323 9286/1/9286 +f 9286/1/9286 9285/1/9285 9284/1/9284 +f 9290/1/9290 9289/1/9289 9288/1/9288 +f 9289/1/9289 9350/1/9350 9352/1/9352 +f 9285/1/9285 9287/1/9287 9326/1/9326 +f 9439/1/9439 9440/1/9440 9352/1/9352 +f 9326/1/9326 9393/1/9393 9325/1/9325 +f 9441/1/9441 9395/1/9395 9440/1/9440 +f 9351/1/9351 9393/1/9393 9394/1/9394 +f 9439/1/9439 9351/1/9351 9394/1/9394 +f 9439/1/9439 9441/1/9441 9440/1/9440 +f 9266/1/9266 9395/1/9395 9441/1/9441 +f 9260/1/9260 9266/1/9266 9258/1/9258 +f 9259/1/9259 9258/1/9258 9257/1/9257 +f 9255/1/9255 9250/1/9250 9257/1/9257 +f 9251/1/9251 9247/1/9247 9253/1/9253 +f 9249/1/9249 9442/1/9442 9250/1/9250 +f 9248/1/9248 9256/1/9256 9249/1/9249 +f 9251/1/9251 9248/1/9248 9247/1/9247 +f 9443/1/9443 9444/1/9444 9445/1/9445 +f 9443/1/9443 9445/1/9445 9446/1/9446 +f 9443/1/9443 9446/1/9446 9447/1/9447 +f 9447/1/9447 9456/1/9456 9443/1/9443 +f 9443/1/9443 9456/1/9456 9459/1/9459 +f 9456/1/9456 9457/1/9457 9459/1/9459 +f 9457/1/9457 9458/1/9458 9459/1/9459 +f 9459/1/9459 9458/1/9458 9460/1/9460 +f 9461/1/9461 9459/1/9459 9460/1/9460 +f 9463/1/9463 9461/1/9461 9460/1/9460 +f 9463/1/9463 9460/1/9460 9464/1/9464 +f 9464/1/9464 9469/1/9469 9463/1/9463 +f 9469/1/9469 9471/1/9471 9463/1/9463 +f 9463/1/9463 9471/1/9471 9462/1/9462 +f 9462/1/9462 9471/1/9471 9473/1/9473 +f 9462/1/9462 9473/1/9473 9466/1/9466 +f 9466/1/9466 9467/1/9467 9462/1/9462 +f 9462/1/9462 9467/1/9467 9461/1/9461 +f 9467/1/9467 9468/1/9468 9461/1/9461 +f 9468/1/9468 9454/1/9454 9461/1/9461 +f 9461/1/9461 9454/1/9454 9453/1/9453 +f 9453/1/9453 9454/1/9454 9452/1/9452 +f 9453/1/9453 9452/1/9452 9451/1/9451 +f 9449/1/9449 9453/1/9453 9451/1/9451 +f 9451/1/9451 9450/1/9450 9449/1/9449 +f 9449/1/9449 9450/1/9450 9448/1/9448 +f 9449/1/9449 9448/1/9448 9444/1/9444 +f 9450/1/9450 9452/1/9452 9448/1/9448 +f 9444/1/9444 9453/1/9453 9449/1/9449 +f 9444/1/9444 9459/1/9459 9453/1/9453 +f 9451/1/9451 9452/1/9452 9450/1/9450 +f 9448/1/9448 9452/1/9452 9454/1/9454 +f 9448/1/9448 9454/1/9454 9445/1/9445 +f 9445/1/9445 9454/1/9454 9457/1/9457 +f 9458/1/9458 9454/1/9454 9468/1/9468 +f 9471/1/9471 9458/1/9458 9468/1/9468 +f 9467/1/9467 9474/1/9474 9468/1/9468 +f 9473/1/9473 9468/1/9468 9474/1/9474 +f 9466/1/9466 9474/1/9474 9467/1/9467 +f 9466/1/9466 9473/1/9473 9474/1/9474 +f 9471/1/9471 9468/1/9468 9473/1/9473 +f 9469/1/9469 9458/1/9458 9471/1/9471 +f 9469/1/9469 9470/1/9470 9458/1/9458 +f 9472/1/9472 9470/1/9470 9469/1/9469 +f 9465/1/9465 9470/1/9470 9472/1/9472 +f 9465/1/9465 9472/1/9472 9464/1/9464 +f 9460/1/9460 9470/1/9470 9465/1/9465 +f 9464/1/9464 9472/1/9472 9469/1/9469 +f 9464/1/9464 9460/1/9460 9465/1/9465 +f 9462/1/9462 9461/1/9461 9463/1/9463 +f 9453/1/9453 9459/1/9459 9461/1/9461 +f 9460/1/9460 9458/1/9458 9470/1/9470 +f 9457/1/9457 9454/1/9454 9458/1/9458 +f 9456/1/9456 9455/1/9455 9457/1/9457 +f 9446/1/9446 9457/1/9457 9455/1/9455 +f 9447/1/9447 9455/1/9455 9456/1/9456 +f 9447/1/9447 9446/1/9446 9455/1/9455 +f 9445/1/9445 9457/1/9457 9446/1/9446 +f 9445/1/9445 9444/1/9444 9448/1/9448 +f 9443/1/9443 9459/1/9459 9444/1/9444 +f 9475/1/9475 9476/1/9476 9477/1/9477 +f 9479/1/9479 9475/1/9475 9477/1/9477 +f 9479/1/9479 9477/1/9477 9875/1/9875 +f 9875/1/9875 9496/1/9496 9479/1/9479 +f 9495/1/9495 9479/1/9479 9496/1/9496 +f 9495/1/9495 9496/1/9496 9497/1/9497 +f 9497/1/9497 9612/1/9612 9495/1/9495 +f 9495/1/9495 9612/1/9612 9613/1/9613 +f 9495/1/9495 9613/1/9613 9614/1/9614 +f 9478/1/9478 9495/1/9495 9614/1/9614 +f 9614/1/9614 9475/1/9475 9478/1/9478 +f 9613/1/9613 9876/1/9876 9614/1/9614 +f 9614/1/9614 9876/1/9876 9875/1/9875 +f 9614/1/9614 9875/1/9875 9601/1/9601 +f 9601/1/9601 9485/1/9485 9614/1/9614 +f 9614/1/9614 9485/1/9485 9483/1/9483 +f 9614/1/9614 9483/1/9483 9481/1/9481 +f 9481/1/9481 9476/1/9476 9614/1/9614 +f 9476/1/9476 9481/1/9481 9480/1/9480 +f 9480/1/9480 9481/1/9481 9482/1/9482 +f 9875/1/9875 9480/1/9480 9482/1/9482 +f 9482/1/9482 9484/1/9484 9875/1/9875 +f 9875/1/9875 9484/1/9484 9486/1/9486 +f 9875/1/9875 9486/1/9486 9874/1/9874 +f 9874/1/9874 9486/1/9486 9488/1/9488 +f 9874/1/9874 9488/1/9488 9871/1/9871 +f 9599/1/9599 9874/1/9874 9871/1/9871 +f 9599/1/9599 9871/1/9871 9602/1/9602 +f 9600/1/9600 9599/1/9599 9602/1/9602 +f 9602/1/9602 9603/1/9603 9600/1/9600 +f 9600/1/9600 9603/1/9603 9604/1/9604 +f 9600/1/9600 9604/1/9604 9605/1/9605 +f 9605/1/9605 9607/1/9607 9600/1/9600 +f 9600/1/9600 9607/1/9607 9642/1/9642 +f 9600/1/9600 9642/1/9642 9652/1/9652 +f 9652/1/9652 9653/1/9653 9600/1/9600 +f 9600/1/9600 9653/1/9653 9654/1/9654 +f 9600/1/9600 9654/1/9654 9655/1/9655 +f 9655/1/9655 9656/1/9656 9600/1/9600 +f 9600/1/9600 9656/1/9656 9657/1/9657 +f 9600/1/9600 9657/1/9657 9658/1/9658 +f 9658/1/9658 9659/1/9659 9600/1/9600 +f 9600/1/9600 9659/1/9659 9660/1/9660 +f 9600/1/9600 9660/1/9660 9661/1/9661 +f 9661/1/9661 9662/1/9662 9600/1/9600 +f 9600/1/9600 9662/1/9662 9663/1/9663 +f 9600/1/9600 9663/1/9663 9597/1/9597 +f 9597/1/9597 9490/1/9490 9600/1/9600 +f 9597/1/9597 9492/1/9492 9490/1/9490 +f 9491/1/9491 9490/1/9490 9492/1/9492 +f 9491/1/9491 9492/1/9492 9493/1/9493 +f 9870/1/9870 9491/1/9491 9493/1/9493 +f 9870/1/9870 9493/1/9493 9980/1/9980 +f 9974/1/9974 9870/1/9870 9980/1/9980 +f 9974/1/9974 9980/1/9980 9834/1/9834 +f 9972/1/9972 9974/1/9974 9834/1/9834 +f 9834/1/9834 9971/1/9971 9972/1/9972 +f 9714/1/9714 9972/1/9972 9971/1/9971 +f 9714/1/9714 9971/1/9971 9712/1/9712 +f 9713/1/9713 9714/1/9714 9712/1/9712 +f 9709/1/9709 9713/1/9713 9712/1/9712 +f 9709/1/9709 9712/1/9712 9711/1/9711 +f 9711/1/9711 9710/1/9710 9709/1/9709 +f 9709/1/9709 9710/1/9710 9708/1/9708 +f 9709/1/9709 9708/1/9708 9703/1/9703 +f 9703/1/9703 9772/1/9772 9709/1/9709 +f 9709/1/9709 9772/1/9772 9773/1/9773 +f 9773/1/9773 9774/1/9774 9709/1/9709 +f 9709/1/9709 9774/1/9774 9775/1/9775 +f 9709/1/9709 9775/1/9775 9776/1/9776 +f 9776/1/9776 9777/1/9777 9709/1/9709 +f 9709/1/9709 9777/1/9777 9801/1/9801 +f 9709/1/9709 9801/1/9801 9722/1/9722 +f 9722/1/9722 9801/1/9801 9802/1/9802 +f 9722/1/9722 9802/1/9802 9799/1/9799 +f 9799/1/9799 9800/1/9800 9722/1/9722 +f 9722/1/9722 9800/1/9800 9782/1/9782 +f 9722/1/9722 9782/1/9782 9768/1/9768 +f 9768/1/9768 9778/1/9778 9722/1/9722 +f 9722/1/9722 9778/1/9778 9784/1/9784 +f 9722/1/9722 9784/1/9784 9785/1/9785 +f 9786/1/9786 9722/1/9722 9785/1/9785 +f 9785/1/9785 9830/1/9830 9786/1/9786 +f 9786/1/9786 9830/1/9830 9829/1/9829 +f 9786/1/9786 9829/1/9829 9787/1/9787 +f 9787/1/9787 9829/1/9829 9832/1/9832 +f 9787/1/9787 9832/1/9832 9788/1/9788 +f 9788/1/9788 9761/1/9761 9787/1/9787 +f 9787/1/9787 9761/1/9761 9723/1/9723 +f 9787/1/9787 9723/1/9723 9722/1/9722 +f 9722/1/9722 9723/1/9723 9713/1/9713 +f 9723/1/9723 9730/1/9730 9713/1/9713 +f 9713/1/9713 9730/1/9730 9731/1/9731 +f 9713/1/9713 9731/1/9731 9732/1/9732 +f 9732/1/9732 9733/1/9733 9713/1/9713 +f 9713/1/9713 9733/1/9733 9734/1/9734 +f 9713/1/9713 9734/1/9734 9726/1/9726 +f 9726/1/9726 9727/1/9727 9713/1/9713 +f 9727/1/9727 9728/1/9728 9713/1/9713 +f 9713/1/9713 9728/1/9728 9729/1/9729 +f 9713/1/9713 9729/1/9729 9725/1/9725 +f 9724/1/9724 9713/1/9713 9725/1/9725 +f 9724/1/9724 9725/1/9725 9803/1/9803 +f 9803/1/9803 9804/1/9804 9724/1/9724 +f 9724/1/9724 9804/1/9804 9805/1/9805 +f 9724/1/9724 9805/1/9805 9806/1/9806 +f 9806/1/9806 9807/1/9807 9724/1/9724 +f 9724/1/9724 9807/1/9807 9808/1/9808 +f 9724/1/9724 9808/1/9808 9809/1/9809 +f 9809/1/9809 9810/1/9810 9724/1/9724 +f 9724/1/9724 9810/1/9810 9811/1/9811 +f 9724/1/9724 9811/1/9811 9812/1/9812 +f 9812/1/9812 9813/1/9813 9724/1/9724 +f 9724/1/9724 9813/1/9813 9814/1/9814 +f 9724/1/9724 9814/1/9814 9739/1/9739 +f 9739/1/9739 9571/1/9571 9724/1/9724 +f 9724/1/9724 9571/1/9571 9573/1/9573 +f 9724/1/9724 9573/1/9573 9718/1/9718 +f 9718/1/9718 9573/1/9573 9494/1/9494 +f 9718/1/9718 9494/1/9494 9598/1/9598 +f 9598/1/9598 9716/1/9716 9718/1/9718 +f 9718/1/9718 9716/1/9716 9713/1/9713 +f 9716/1/9716 9715/1/9715 9713/1/9713 +f 9716/1/9716 9696/1/9696 9715/1/9715 +f 9721/1/9721 9715/1/9715 9696/1/9696 +f 9721/1/9721 9696/1/9696 9720/1/9720 +f 9720/1/9720 10045/1/10045 9721/1/9721 +f 9721/1/9721 10045/1/10045 9979/1/9979 +f 10045/1/10045 9842/1/9842 9979/1/9979 +f 9979/1/9979 9842/1/9842 9973/1/9973 +f 9979/1/9979 9973/1/9973 9972/1/9972 +f 9715/1/9715 9979/1/9979 9972/1/9972 +f 9842/1/9842 9976/1/9976 9973/1/9973 +f 9973/1/9973 9976/1/9976 9977/1/9977 +f 9973/1/9973 9977/1/9977 9978/1/9978 +f 9978/1/9978 10061/1/10061 9973/1/9973 +f 10062/1/10062 9973/1/9973 10061/1/10061 +f 9818/1/9818 10062/1/10062 10061/1/10061 +f 9818/1/9818 10061/1/10061 9697/1/9697 +f 9696/1/9696 9818/1/9818 9697/1/9697 +f 9696/1/9696 9697/1/9697 9694/1/9694 +f 9694/1/9694 9700/1/9700 9696/1/9696 +f 9696/1/9696 9700/1/9700 9719/1/9719 +f 9700/1/9700 10047/1/10047 9719/1/9719 +f 9719/1/9719 10047/1/10047 10046/1/10046 +f 9719/1/9719 10046/1/10046 9720/1/9720 +f 10046/1/10046 10047/1/10047 9842/1/9842 +f 9842/1/9842 10047/1/10047 10048/1/10048 +f 9842/1/9842 10048/1/10048 9843/1/9843 +f 9529/1/9529 9842/1/9842 9843/1/9843 +f 9529/1/9529 9843/1/9843 9844/1/9844 +f 9845/1/9845 9529/1/9529 9844/1/9844 +f 9705/1/9705 9845/1/9845 9844/1/9844 +f 9705/1/9705 9844/1/9844 9695/1/9695 +f 9695/1/9695 9530/1/9530 9705/1/9705 +f 9705/1/9705 9530/1/9530 9704/1/9704 +f 9703/1/9703 9704/1/9704 9530/1/9530 +f 9703/1/9703 9530/1/9530 9527/1/9527 +f 9527/1/9527 9768/1/9768 9703/1/9703 +f 9703/1/9703 9768/1/9768 9781/1/9781 +f 9703/1/9703 9781/1/9781 9769/1/9769 +f 9769/1/9769 9770/1/9770 9703/1/9703 +f 9770/1/9770 9771/1/9771 9703/1/9703 +f 9770/1/9770 10057/1/10057 9771/1/9771 +f 9771/1/9771 10057/1/10057 10056/1/10056 +f 9771/1/9771 10056/1/10056 9772/1/9772 +f 9772/1/9772 10056/1/10056 10055/1/10055 +f 10054/1/10054 9772/1/9772 10055/1/10055 +f 9840/1/9840 10054/1/10054 10055/1/10055 +f 9835/1/9835 10054/1/10054 9840/1/9840 +f 9840/1/9840 9966/1/9966 9835/1/9835 +f 9835/1/9835 9966/1/9966 9967/1/9967 +f 9835/1/9835 9967/1/9967 9968/1/9968 +f 9968/1/9968 9969/1/9969 9835/1/9835 +f 9835/1/9835 9969/1/9969 9970/1/9970 +f 9835/1/9835 9970/1/9970 9834/1/9834 +f 9834/1/9834 9823/1/9823 9835/1/9835 +f 9835/1/9835 9823/1/9823 9828/1/9828 +f 9835/1/9835 9828/1/9828 10052/1/10052 +f 10050/1/10050 9835/1/9835 10052/1/10052 +f 9777/1/9777 10050/1/10050 10052/1/10052 +f 10050/1/10050 10051/1/10051 9835/1/9835 +f 10051/1/10051 10053/1/10053 9835/1/9835 +f 9775/1/9775 10053/1/10053 10051/1/10051 +f 9776/1/9776 10051/1/10051 10050/1/10050 +f 9828/1/9828 9777/1/9777 10052/1/10052 +f 9823/1/9823 9827/1/9827 9828/1/9828 +f 9802/1/9802 9828/1/9828 9827/1/9827 +f 9823/1/9823 9826/1/9826 9827/1/9827 +f 9799/1/9799 9827/1/9827 9826/1/9826 +f 9825/1/9825 9826/1/9826 9823/1/9823 +f 9823/1/9823 9824/1/9824 9825/1/9825 +f 9782/1/9782 9825/1/9825 9824/1/9824 +f 9820/1/9820 9782/1/9782 9824/1/9824 +f 9783/1/9783 9782/1/9782 9820/1/9820 +f 9783/1/9783 9820/1/9820 9779/1/9779 +f 9768/1/9768 9783/1/9783 9779/1/9779 +f 9779/1/9779 9780/1/9780 9768/1/9768 +f 9779/1/9779 9819/1/9819 9780/1/9780 +f 9780/1/9780 9819/1/9819 9822/1/9822 +f 9780/1/9780 9822/1/9822 9781/1/9781 +f 9781/1/9781 9822/1/9822 9838/1/9838 +f 10058/1/10058 9781/1/9781 9838/1/9838 +f 9840/1/9840 10058/1/10058 9838/1/9838 +f 9840/1/9840 9838/1/9838 9821/1/9821 +f 9821/1/9821 9525/1/9525 9840/1/9840 +f 9840/1/9840 9525/1/9525 9529/1/9529 +f 9525/1/9525 9527/1/9527 9529/1/9529 +f 9525/1/9525 9524/1/9524 9527/1/9527 +f 9524/1/9524 9766/1/9766 9527/1/9527 +f 9524/1/9524 9765/1/9765 9766/1/9766 +f 9765/1/9765 9841/1/9841 9766/1/9766 +f 9766/1/9766 9841/1/9841 9839/1/9839 +f 9766/1/9766 9839/1/9839 9767/1/9767 +f 9766/1/9766 9767/1/9767 9768/1/9768 +f 9767/1/9767 9839/1/9839 9837/1/9837 +f 9767/1/9767 9837/1/9837 9778/1/9778 +f 9778/1/9778 9837/1/9837 9836/1/9836 +f 9821/1/9821 9836/1/9836 9837/1/9837 +f 9821/1/9821 9831/1/9831 9836/1/9836 +f 9784/1/9784 9836/1/9836 9831/1/9831 +f 9823/1/9823 9831/1/9831 9821/1/9821 +f 9821/1/9821 9820/1/9820 9823/1/9823 +f 9819/1/9819 9820/1/9820 9821/1/9821 +f 9823/1/9823 9830/1/9830 9831/1/9831 +f 9837/1/9837 9839/1/9839 9821/1/9821 +f 9523/1/9523 9839/1/9839 9841/1/9841 +f 9523/1/9523 9841/1/9841 10001/1/10001 +f 10001/1/10001 9526/1/9526 9523/1/9523 +f 9523/1/9523 9526/1/9526 9524/1/9524 +f 9524/1/9524 9526/1/9526 9528/1/9528 +f 9528/1/9528 9763/1/9763 9524/1/9524 +f 9528/1/9528 9762/1/9762 9763/1/9763 +f 9764/1/9764 9763/1/9763 9762/1/9762 +f 9762/1/9762 9793/1/9793 9764/1/9764 +f 9793/1/9793 10003/1/10003 9764/1/9764 +f 9764/1/9764 10003/1/10003 10002/1/10002 +f 10000/1/10000 10002/1/10002 10003/1/10003 +f 10000/1/10000 10003/1/10003 9999/1/9999 +f 9541/1/9541 10000/1/10000 9999/1/9999 +f 9541/1/9541 9999/1/9999 9544/1/9544 +f 9543/1/9543 9541/1/9541 9544/1/9544 +f 9543/1/9543 9544/1/9544 9545/1/9545 +f 9760/1/9760 9543/1/9543 9545/1/9545 +f 9760/1/9760 9545/1/9545 9761/1/9761 +f 9789/1/9789 9760/1/9760 9761/1/9761 +f 9790/1/9790 9760/1/9760 9789/1/9789 +f 9789/1/9789 10006/1/10006 9790/1/9790 +f 9790/1/9790 10006/1/10006 10005/1/10005 +f 9790/1/9790 10005/1/10005 9791/1/9791 +f 9791/1/9791 10005/1/10005 10004/1/10004 +f 9791/1/9791 10004/1/10004 9792/1/9792 +f 9760/1/9760 9791/1/9791 9792/1/9792 +f 9760/1/9760 9792/1/9792 9762/1/9762 +f 9762/1/9762 9542/1/9542 9760/1/9760 +f 9540/1/9540 9542/1/9542 9762/1/9762 +f 9762/1/9762 9538/1/9538 9540/1/9540 +f 9537/1/9537 9540/1/9540 9538/1/9538 +f 9537/1/9537 9538/1/9538 9535/1/9535 +f 9535/1/9535 9536/1/9536 9537/1/9537 +f 9537/1/9537 9536/1/9536 9534/1/9534 +f 10000/1/10000 9537/1/9537 9534/1/9534 +f 10000/1/10000 9534/1/9534 10001/1/10001 +f 9539/1/9539 9537/1/9537 10000/1/10000 +f 9535/1/9535 9534/1/9534 9536/1/9536 +f 9533/1/9533 9534/1/9534 9535/1/9535 +f 9533/1/9533 9535/1/9535 9762/1/9762 +f 9533/1/9533 9526/1/9526 9534/1/9534 +f 9539/1/9539 9540/1/9540 9537/1/9537 +f 9762/1/9762 9535/1/9535 9538/1/9538 +f 9539/1/9539 9542/1/9542 9540/1/9540 +f 9541/1/9541 9542/1/9542 9539/1/9539 +f 9792/1/9792 10004/1/10004 10007/1/10007 +f 9792/1/9792 10007/1/10007 9793/1/9793 +f 9999/1/9999 10007/1/10007 10004/1/10004 +f 10004/1/10004 10005/1/10005 9999/1/9999 +f 9999/1/9999 10005/1/10005 10006/1/10006 +f 9999/1/9999 10006/1/10006 9990/1/9990 +f 9990/1/9990 10006/1/10006 10008/1/10008 +f 9990/1/9990 10008/1/10008 9832/1/9832 +f 9832/1/9832 9833/1/9833 9990/1/9990 +f 9833/1/9833 9989/1/9989 9990/1/9990 +f 9990/1/9990 9989/1/9989 9991/1/9991 +f 9991/1/9991 9992/1/9992 9990/1/9990 +f 9990/1/9990 9992/1/9992 9993/1/9993 +f 9990/1/9990 9993/1/9993 9994/1/9994 +f 9548/1/9548 9990/1/9990 9994/1/9994 +f 9548/1/9548 9994/1/9994 9550/1/9550 +f 9550/1/9550 9547/1/9547 9548/1/9548 +f 9547/1/9547 9546/1/9546 9548/1/9548 +f 9545/1/9545 9546/1/9546 9547/1/9547 +f 9545/1/9545 9547/1/9547 9758/1/9758 +f 9547/1/9547 9549/1/9549 9758/1/9758 +f 9758/1/9758 9549/1/9549 9551/1/9551 +f 9758/1/9758 9551/1/9551 9553/1/9553 +f 9553/1/9553 9555/1/9555 9758/1/9758 +f 9557/1/9557 9758/1/9758 9555/1/9555 +f 9557/1/9557 9555/1/9555 9558/1/9558 +f 9558/1/9558 9559/1/9559 9557/1/9557 +f 9560/1/9560 9559/1/9559 9558/1/9558 +f 9994/1/9994 9560/1/9560 9558/1/9558 +f 9994/1/9994 9558/1/9558 9556/1/9556 +f 9556/1/9556 9554/1/9554 9994/1/9994 +f 9994/1/9994 9554/1/9554 9552/1/9552 +f 9553/1/9553 9552/1/9552 9554/1/9554 +f 9556/1/9556 9553/1/9553 9554/1/9554 +f 9562/1/9562 9560/1/9560 9994/1/9994 +f 9998/1/9998 9562/1/9562 9994/1/9994 +f 9998/1/9998 9994/1/9994 9997/1/9997 +f 9759/1/9759 9998/1/9998 9997/1/9997 +f 9759/1/9759 9997/1/9997 9797/1/9797 +f 9758/1/9758 9759/1/9759 9797/1/9797 +f 9758/1/9758 9797/1/9797 9798/1/9798 +f 9794/1/9794 9758/1/9758 9798/1/9798 +f 9798/1/9798 9995/1/9995 9794/1/9794 +f 9794/1/9794 9995/1/9995 9993/1/9993 +f 9794/1/9794 9993/1/9993 9796/1/9796 +f 9796/1/9796 9761/1/9761 9794/1/9794 +f 9795/1/9795 9761/1/9761 9796/1/9796 +f 9796/1/9796 9992/1/9992 9795/1/9795 +f 9798/1/9798 9996/1/9996 9995/1/9995 +f 9994/1/9994 9995/1/9995 9996/1/9996 +f 9761/1/9761 9758/1/9758 9794/1/9794 +f 9797/1/9797 9996/1/9996 9798/1/9798 +f 9757/1/9757 9759/1/9759 9758/1/9758 +f 9559/1/9559 9757/1/9757 9758/1/9758 +f 9561/1/9561 9757/1/9757 9559/1/9559 +f 9561/1/9561 9563/1/9563 9757/1/9757 +f 9757/1/9757 9563/1/9563 9565/1/9565 +f 9757/1/9757 9565/1/9565 9756/1/9756 +f 9756/1/9756 9984/1/9984 9757/1/9757 +f 9757/1/9757 9984/1/9984 9998/1/9998 +f 9566/1/9566 9998/1/9998 9984/1/9984 +f 9566/1/9566 9984/1/9984 9568/1/9568 +f 9568/1/9568 9565/1/9565 9566/1/9566 +f 9567/1/9567 9565/1/9565 9568/1/9568 +f 9568/1/9568 9569/1/9569 9567/1/9567 +f 9755/1/9755 9567/1/9567 9569/1/9569 +f 9755/1/9755 9569/1/9569 9739/1/9739 +f 9739/1/9739 9754/1/9754 9755/1/9755 +f 9754/1/9754 9985/1/9985 9755/1/9755 +f 9755/1/9755 9985/1/9985 9983/1/9983 +f 9755/1/9755 9983/1/9983 9756/1/9756 +f 9985/1/9985 9982/1/9982 9983/1/9983 +f 9570/1/9570 9983/1/9983 9982/1/9982 +f 9570/1/9570 9982/1/9982 9572/1/9572 +f 9572/1/9572 9571/1/9571 9570/1/9570 +f 9570/1/9570 9571/1/9571 9569/1/9569 +f 9572/1/9572 9982/1/9982 9981/1/9981 +f 9572/1/9572 9981/1/9981 9574/1/9574 +f 9574/1/9574 9573/1/9573 9572/1/9572 +f 9980/1/9980 9574/1/9574 9981/1/9981 +f 9982/1/9982 10044/1/10044 9981/1/9981 +f 9981/1/9981 10044/1/10044 10031/1/10031 +f 9981/1/9981 10031/1/10031 10030/1/10030 +f 10029/1/10029 9981/1/9981 10030/1/10030 +f 10030/1/10030 9812/1/9812 10029/1/10029 +f 10029/1/10029 10028/1/10028 9981/1/9981 +f 10028/1/10028 10027/1/10027 9981/1/9981 +f 9981/1/9981 10027/1/10027 10026/1/10026 +f 9981/1/9981 10026/1/10026 10025/1/10025 +f 10025/1/10025 10024/1/10024 9981/1/9981 +f 10024/1/10024 10023/1/10023 9981/1/9981 +f 9981/1/9981 10023/1/10023 10022/1/10022 +f 9981/1/9981 10022/1/10022 10021/1/10021 +f 9981/1/9981 10021/1/10021 10020/1/10020 +f 9834/1/9834 9981/1/9981 10020/1/10020 +f 9834/1/9834 10020/1/10020 10010/1/10010 +f 10010/1/10010 9833/1/9833 9834/1/9834 +f 10010/1/10010 10011/1/10011 9833/1/9833 +f 10011/1/10011 10015/1/10015 9833/1/9833 +f 9833/1/9833 10015/1/10015 10016/1/10016 +f 9833/1/9833 10016/1/10016 10017/1/10017 +f 10017/1/10017 10018/1/10018 9833/1/9833 +f 9833/1/9833 10018/1/10018 10019/1/10019 +f 9833/1/9833 10019/1/10019 10012/1/10012 +f 10012/1/10012 10013/1/10013 9833/1/9833 +f 9833/1/9833 10013/1/10013 10014/1/10014 +f 9833/1/9833 10014/1/10014 10009/1/10009 +f 9833/1/9833 10009/1/10009 9982/1/9982 +f 9982/1/9982 9988/1/9988 9833/1/9833 +f 9982/1/9982 9987/1/9987 9988/1/9988 +f 9752/1/9752 9988/1/9988 9987/1/9987 +f 9752/1/9752 9987/1/9987 9753/1/9753 +f 9752/1/9752 9753/1/9753 9739/1/9739 +f 9739/1/9739 9751/1/9751 9752/1/9752 +f 9750/1/9750 9751/1/9751 9739/1/9739 +f 9750/1/9750 9739/1/9739 9723/1/9723 +f 9750/1/9750 9723/1/9723 9795/1/9795 +f 9795/1/9795 9991/1/9991 9750/1/9750 +f 9723/1/9723 9739/1/9739 9737/1/9737 +f 9723/1/9723 9737/1/9737 9736/1/9736 +f 9736/1/9736 9735/1/9735 9723/1/9723 +f 9735/1/9735 9736/1/9736 10009/1/10009 +f 10009/1/10009 9736/1/9736 10032/1/10032 +f 9736/1/9736 9737/1/9737 10032/1/10032 +f 10032/1/10032 9737/1/9737 10033/1/10033 +f 9982/1/9982 10032/1/10032 10033/1/10033 +f 10033/1/10033 10034/1/10034 9982/1/9982 +f 9982/1/9982 10034/1/10034 10035/1/10035 +f 9982/1/9982 10035/1/10035 10036/1/10036 +f 10036/1/10036 10037/1/10037 9982/1/9982 +f 9982/1/9982 10037/1/10037 10038/1/10038 +f 9982/1/9982 10038/1/10038 10039/1/10039 +f 10039/1/10039 10040/1/10040 9982/1/9982 +f 9982/1/9982 10040/1/10040 10041/1/10041 +f 9982/1/9982 10041/1/10041 10042/1/10042 +f 10042/1/10042 10043/1/10043 9982/1/9982 +f 10042/1/10042 9748/1/9748 10043/1/10043 +f 9748/1/9748 9749/1/9749 10043/1/10043 +f 10043/1/10043 9749/1/9749 10044/1/10044 +f 9749/1/9749 9814/1/9814 10044/1/10044 +f 9739/1/9739 9749/1/9749 9748/1/9748 +f 9748/1/9748 9747/1/9747 9739/1/9739 +f 9739/1/9739 9747/1/9747 9746/1/9746 +f 9739/1/9739 9746/1/9746 9745/1/9745 +f 9745/1/9745 9744/1/9744 9739/1/9739 +f 9739/1/9739 9744/1/9744 9743/1/9743 +f 9739/1/9739 9743/1/9743 9742/1/9742 +f 9742/1/9742 9741/1/9741 9739/1/9739 +f 9739/1/9739 9741/1/9741 9740/1/9740 +f 9739/1/9739 9740/1/9740 9738/1/9738 +f 9738/1/9738 9740/1/9740 10034/1/10034 +f 9740/1/9740 9741/1/9741 10035/1/10035 +f 9741/1/9741 9742/1/9742 10036/1/10036 +f 9742/1/9742 9743/1/9743 10037/1/10037 +f 9743/1/9743 9744/1/9744 10038/1/10038 +f 9744/1/9744 9745/1/9745 10039/1/10039 +f 9745/1/9745 9746/1/9746 10040/1/10040 +f 9746/1/9746 9747/1/9747 10041/1/10041 +f 9747/1/9747 9748/1/9748 10042/1/10042 +f 10041/1/10041 9747/1/9747 10042/1/10042 +f 10040/1/10040 9746/1/9746 10041/1/10041 +f 10039/1/10039 9745/1/9745 10040/1/10040 +f 10038/1/10038 9744/1/9744 10039/1/10039 +f 10037/1/10037 9743/1/9743 10038/1/10038 +f 10036/1/10036 9742/1/9742 10037/1/10037 +f 10035/1/10035 9741/1/9741 10036/1/10036 +f 10034/1/10034 9740/1/9740 10035/1/10035 +f 10033/1/10033 9738/1/9738 10034/1/10034 +f 9737/1/9737 9738/1/9738 10033/1/10033 +f 9738/1/9738 9737/1/9737 9739/1/9739 +f 9750/1/9750 9989/1/9989 9751/1/9751 +f 9751/1/9751 9989/1/9989 9988/1/9988 +f 9753/1/9753 9987/1/9987 9986/1/9986 +f 9753/1/9753 9986/1/9986 9754/1/9754 +f 9751/1/9751 9988/1/9988 9752/1/9752 +f 9986/1/9986 9987/1/9987 9982/1/9982 +f 9982/1/9982 10009/1/10009 10032/1/10032 +f 10014/1/10014 9735/1/9735 10009/1/10009 +f 9730/1/9730 9735/1/9735 10014/1/10014 +f 10013/1/10013 9730/1/9730 10014/1/10014 +f 10012/1/10012 9731/1/9731 10013/1/10013 +f 10019/1/10019 9732/1/9732 10012/1/10012 +f 10018/1/10018 9733/1/9733 10019/1/10019 +f 10017/1/10017 9734/1/9734 10018/1/10018 +f 10016/1/10016 9726/1/9726 10017/1/10017 +f 10015/1/10015 9727/1/9727 10016/1/10016 +f 10011/1/10011 9728/1/9728 10015/1/10015 +f 10010/1/10010 9729/1/9729 10011/1/10011 +f 10020/1/10020 9725/1/9725 10010/1/10010 +f 10021/1/10021 9803/1/9803 10020/1/10020 +f 10022/1/10022 9804/1/9804 10021/1/10021 +f 10023/1/10023 9805/1/9805 10022/1/10022 +f 10024/1/10024 9806/1/9806 10023/1/10023 +f 10025/1/10025 9807/1/9807 10024/1/10024 +f 10026/1/10026 9808/1/9808 10025/1/10025 +f 10027/1/10027 9809/1/9809 10026/1/10026 +f 10028/1/10028 9810/1/9810 10027/1/10027 +f 10029/1/10029 9811/1/9811 10028/1/10028 +f 10031/1/10031 9813/1/9813 10030/1/10030 +f 10044/1/10044 9814/1/9814 10031/1/10031 +f 9982/1/9982 10043/1/10043 10044/1/10044 +f 9568/1/9568 9983/1/9983 9570/1/9570 +f 9986/1/9986 9982/1/9982 9985/1/9985 +f 9754/1/9754 9986/1/9986 9985/1/9985 +f 9739/1/9739 9753/1/9753 9754/1/9754 +f 9756/1/9756 9567/1/9567 9755/1/9755 +f 9570/1/9570 9569/1/9569 9568/1/9568 +f 9568/1/9568 9984/1/9984 9983/1/9983 +f 9564/1/9564 9998/1/9998 9566/1/9566 +f 9566/1/9566 9563/1/9563 9564/1/9564 +f 9756/1/9756 9983/1/9983 9984/1/9984 +f 9756/1/9756 9565/1/9565 9567/1/9567 +f 9565/1/9565 9563/1/9563 9566/1/9566 +f 9563/1/9563 9561/1/9561 9564/1/9564 +f 9564/1/9564 9561/1/9561 9562/1/9562 +f 9797/1/9797 9997/1/9997 9996/1/9996 +f 9757/1/9757 9998/1/9998 9759/1/9759 +f 9997/1/9997 9994/1/9994 9996/1/9996 +f 9564/1/9564 9562/1/9562 9998/1/9998 +f 9562/1/9562 9561/1/9561 9560/1/9560 +f 9560/1/9560 9561/1/9561 9559/1/9559 +f 9558/1/9558 9555/1/9555 9556/1/9556 +f 9559/1/9559 9758/1/9758 9557/1/9557 +f 9555/1/9555 9553/1/9553 9556/1/9556 +f 9551/1/9551 9552/1/9552 9553/1/9553 +f 9551/1/9551 9550/1/9550 9552/1/9552 +f 9549/1/9549 9550/1/9550 9551/1/9551 +f 9549/1/9549 9547/1/9547 9550/1/9550 +f 9994/1/9994 9552/1/9552 9550/1/9550 +f 9546/1/9546 9990/1/9990 9548/1/9548 +f 9544/1/9544 9990/1/9990 9546/1/9546 +f 9994/1/9994 9993/1/9993 9995/1/9995 +f 9796/1/9796 9993/1/9993 9992/1/9992 +f 9795/1/9795 9992/1/9992 9991/1/9991 +f 9750/1/9750 9991/1/9991 9989/1/9989 +f 9833/1/9833 9988/1/9988 9989/1/9989 +f 9832/1/9832 9823/1/9823 9833/1/9833 +f 9789/1/9789 10008/1/10008 10006/1/10006 +f 9788/1/9788 10008/1/10008 9789/1/9789 +f 9790/1/9790 9791/1/9791 9760/1/9760 +f 9761/1/9761 9545/1/9545 9758/1/9758 +f 9542/1/9542 9543/1/9543 9760/1/9760 +f 9545/1/9545 9544/1/9544 9546/1/9546 +f 9542/1/9542 9541/1/9541 9543/1/9543 +f 9544/1/9544 9999/1/9999 9990/1/9990 +f 9539/1/9539 10000/1/10000 9541/1/9541 +f 9999/1/9999 10003/1/10003 10007/1/10007 +f 10001/1/10001 10002/1/10002 10000/1/10000 +f 9763/1/9763 10002/1/10002 10001/1/10001 +f 9763/1/9763 10001/1/10001 9765/1/9765 +f 9793/1/9793 10007/1/10007 10003/1/10003 +f 9762/1/9762 9792/1/9792 9793/1/9793 +f 9764/1/9764 10002/1/10002 9763/1/9763 +f 9533/1/9533 9762/1/9762 9528/1/9528 +f 9528/1/9528 9526/1/9526 9533/1/9533 +f 10001/1/10001 9534/1/9534 9526/1/9526 +f 9525/1/9525 9839/1/9839 9523/1/9523 +f 9765/1/9765 10001/1/10001 9841/1/9841 +f 9763/1/9763 9765/1/9765 9524/1/9524 +f 9523/1/9523 9524/1/9524 9525/1/9525 +f 9821/1/9821 9839/1/9839 9525/1/9525 +f 10057/1/10057 10058/1/10058 9840/1/9840 +f 9821/1/9821 9838/1/9838 9822/1/9822 +f 9821/1/9821 9822/1/9822 9819/1/9819 +f 9779/1/9779 9820/1/9820 9819/1/9819 +f 9823/1/9823 9820/1/9820 9824/1/9824 +f 9800/1/9800 9826/1/9826 9825/1/9825 +f 9834/1/9834 9833/1/9833 9823/1/9823 +f 9711/1/9711 9970/1/9970 9969/1/9969 +f 9710/1/9710 9969/1/9969 9968/1/9968 +f 9708/1/9708 9968/1/9968 9967/1/9967 +f 9708/1/9708 9967/1/9967 9707/1/9707 +f 9707/1/9707 9967/1/9967 9966/1/9966 +f 9707/1/9707 9966/1/9966 9706/1/9706 +f 9703/1/9703 9707/1/9707 9706/1/9706 +f 9706/1/9706 9966/1/9966 9965/1/9965 +f 9706/1/9706 9965/1/9965 9704/1/9704 +f 9704/1/9704 9965/1/9965 9845/1/9845 +f 9845/1/9845 9965/1/9965 9840/1/9840 +f 9840/1/9840 9965/1/9965 9966/1/9966 +f 9835/1/9835 10053/1/10053 10054/1/10054 +f 9774/1/9774 10054/1/10054 10053/1/10053 +f 9840/1/9840 10055/1/10055 10056/1/10056 +f 9840/1/9840 10056/1/10056 10057/1/10057 +f 9770/1/9770 10058/1/10058 10057/1/10057 +f 9769/1/9769 10058/1/10058 9770/1/9770 +f 9769/1/9769 9781/1/9781 10058/1/10058 +f 9768/1/9768 9780/1/9780 9781/1/9781 +f 9527/1/9527 9766/1/9766 9768/1/9768 +f 9529/1/9529 9527/1/9527 9530/1/9530 +f 9529/1/9529 9530/1/9530 9531/1/9531 +f 9531/1/9531 9530/1/9530 9532/1/9532 +f 9531/1/9531 9532/1/9532 9521/1/9521 +f 9521/1/9521 9846/1/9846 9531/1/9531 +f 9846/1/9846 10049/1/10049 9531/1/9531 +f 9531/1/9531 10049/1/10049 9842/1/9842 +f 9693/1/9693 10049/1/10049 9846/1/9846 +f 9693/1/9693 9846/1/9846 9691/1/9691 +f 9693/1/9693 9691/1/9691 9522/1/9522 +f 9693/1/9693 9522/1/9522 9532/1/9532 +f 9693/1/9693 9532/1/9532 9701/1/9701 +f 9694/1/9694 9701/1/9701 9532/1/9532 +f 9694/1/9694 9532/1/9532 9695/1/9695 +f 9695/1/9695 9699/1/9699 9694/1/9694 +f 9695/1/9695 9843/1/9843 9699/1/9699 +f 9702/1/9702 9701/1/9701 9694/1/9694 +f 9694/1/9694 9698/1/9698 9702/1/9702 +f 9698/1/9698 9977/1/9977 9702/1/9702 +f 9702/1/9702 9976/1/9976 9701/1/9701 +f 9701/1/9701 9976/1/9976 10049/1/10049 +f 9522/1/9522 9691/1/9691 9577/1/9577 +f 9522/1/9522 9577/1/9577 9520/1/9520 +f 9519/1/9519 9522/1/9522 9520/1/9520 +f 9519/1/9519 9520/1/9520 9517/1/9517 +f 9852/1/9852 9519/1/9519 9517/1/9517 +f 9852/1/9852 9517/1/9517 9949/1/9949 +f 9949/1/9949 9950/1/9950 9852/1/9852 +f 9852/1/9852 9950/1/9950 9951/1/9951 +f 9852/1/9852 9951/1/9951 9901/1/9901 +f 9901/1/9901 9959/1/9959 9852/1/9852 +f 9852/1/9852 9959/1/9959 9960/1/9960 +f 9852/1/9852 9960/1/9960 9961/1/9961 +f 9963/1/9963 9852/1/9852 9961/1/9961 +f 9638/1/9638 9963/1/9963 9961/1/9961 +f 9638/1/9638 9961/1/9961 9632/1/9632 +f 9582/1/9582 9638/1/9638 9632/1/9632 +f 9629/1/9629 9582/1/9582 9632/1/9632 +f 9629/1/9629 9632/1/9632 9633/1/9633 +f 9633/1/9633 9634/1/9634 9629/1/9629 +f 9629/1/9629 9634/1/9634 9635/1/9635 +f 9629/1/9629 9635/1/9635 9636/1/9636 +f 9636/1/9636 9637/1/9637 9629/1/9629 +f 9629/1/9629 9637/1/9637 9680/1/9680 +f 9629/1/9629 9680/1/9680 9585/1/9585 +f 9585/1/9585 9607/1/9607 9629/1/9629 +f 9629/1/9629 9607/1/9607 9617/1/9617 +f 9629/1/9629 9617/1/9617 9631/1/9631 +f 9630/1/9630 9629/1/9629 9631/1/9631 +f 9631/1/9631 9954/1/9954 9630/1/9630 +f 9630/1/9630 9954/1/9954 9953/1/9953 +f 9630/1/9630 9953/1/9953 9628/1/9628 +f 9628/1/9628 9953/1/9953 9952/1/9952 +f 9628/1/9628 9952/1/9952 9627/1/9627 +f 9628/1/9628 9627/1/9627 9582/1/9582 +f 9582/1/9582 9627/1/9627 9626/1/9626 +f 9582/1/9582 9626/1/9626 9625/1/9625 +f 9518/1/9518 9582/1/9582 9625/1/9625 +f 9518/1/9518 9625/1/9625 9516/1/9516 +f 9515/1/9515 9518/1/9518 9516/1/9516 +f 9514/1/9514 9515/1/9515 9516/1/9516 +f 9514/1/9514 9516/1/9516 9512/1/9512 +f 9512/1/9512 9513/1/9513 9514/1/9514 +f 9512/1/9512 9511/1/9511 9513/1/9513 +f 9511/1/9511 9947/1/9947 9513/1/9513 +f 9513/1/9513 9947/1/9947 9515/1/9515 +f 9948/1/9948 9515/1/9515 9947/1/9947 +f 9623/1/9623 9948/1/9948 9947/1/9947 +f 9623/1/9623 9947/1/9947 9622/1/9622 +f 9622/1/9622 9507/1/9507 9623/1/9623 +f 9509/1/9509 9623/1/9623 9507/1/9507 +f 9507/1/9507 9508/1/9508 9509/1/9509 +f 9508/1/9508 9510/1/9510 9509/1/9509 +f 9509/1/9509 9510/1/9510 9511/1/9511 +f 9510/1/9510 9508/1/9508 9511/1/9511 +f 9507/1/9507 9506/1/9506 9508/1/9508 +f 9506/1/9506 9944/1/9944 9508/1/9508 +f 9508/1/9508 9944/1/9944 9945/1/9945 +f 9508/1/9508 9945/1/9945 9946/1/9946 +f 9946/1/9946 9947/1/9947 9508/1/9508 +f 9621/1/9621 9946/1/9946 9945/1/9945 +f 9621/1/9621 9945/1/9945 9620/1/9620 +f 9620/1/9620 9505/1/9505 9621/1/9621 +f 9621/1/9621 9505/1/9505 9507/1/9507 +f 9620/1/9620 9503/1/9503 9505/1/9505 +f 9503/1/9503 9504/1/9504 9505/1/9505 +f 9505/1/9505 9504/1/9504 9506/1/9506 +f 9504/1/9504 9943/1/9943 9506/1/9506 +f 9504/1/9504 9942/1/9942 9943/1/9943 +f 9618/1/9618 9943/1/9943 9942/1/9942 +f 9618/1/9618 9942/1/9942 9615/1/9615 +f 9503/1/9503 9618/1/9618 9615/1/9615 +f 9503/1/9503 9615/1/9615 9501/1/9501 +f 9501/1/9501 9502/1/9502 9503/1/9503 +f 9501/1/9501 9500/1/9500 9502/1/9502 +f 9500/1/9500 9879/1/9879 9502/1/9502 +f 9502/1/9502 9879/1/9879 9880/1/9880 +f 9502/1/9502 9880/1/9880 9881/1/9881 +f 9502/1/9502 9881/1/9881 9882/1/9882 +f 9882/1/9882 9902/1/9902 9502/1/9502 +f 9502/1/9502 9902/1/9902 9941/1/9941 +f 9502/1/9502 9941/1/9941 9940/1/9940 +f 9940/1/9940 9504/1/9504 9502/1/9502 +f 9616/1/9616 9940/1/9940 9941/1/9941 +f 9616/1/9616 9941/1/9941 9617/1/9617 +f 9501/1/9501 9616/1/9616 9617/1/9617 +f 9615/1/9615 9940/1/9940 9616/1/9616 +f 9617/1/9617 9941/1/9941 9902/1/9902 +f 9882/1/9882 9901/1/9901 9902/1/9902 +f 9954/1/9954 9902/1/9902 9901/1/9901 +f 9900/1/9900 9901/1/9901 9882/1/9882 +f 9882/1/9882 9867/1/9867 9900/1/9900 +f 9867/1/9867 9912/1/9912 9900/1/9900 +f 9900/1/9900 9912/1/9912 9914/1/9914 +f 9900/1/9900 9914/1/9914 9915/1/9915 +f 9916/1/9916 9900/1/9900 9915/1/9915 +f 9587/1/9587 9916/1/9916 9915/1/9915 +f 9587/1/9587 9915/1/9915 9588/1/9588 +f 9588/1/9588 9585/1/9585 9587/1/9587 +f 9585/1/9585 9586/1/9586 9587/1/9587 +f 9585/1/9585 9584/1/9584 9586/1/9586 +f 9584/1/9584 9917/1/9917 9586/1/9586 +f 9586/1/9586 9917/1/9917 9916/1/9916 +f 9917/1/9917 9851/1/9851 9916/1/9916 +f 9917/1/9917 9918/1/9918 9851/1/9851 +f 9918/1/9918 9850/1/9850 9851/1/9851 +f 9851/1/9851 9850/1/9850 9519/1/9519 +f 9849/1/9849 9519/1/9519 9850/1/9850 +f 9580/1/9580 9849/1/9849 9850/1/9850 +f 9580/1/9580 9850/1/9850 9583/1/9583 +f 9580/1/9580 9583/1/9583 9581/1/9581 +f 9580/1/9580 9581/1/9581 9520/1/9520 +f 9520/1/9520 9579/1/9579 9580/1/9580 +f 9520/1/9520 9576/1/9576 9579/1/9579 +f 9576/1/9576 9848/1/9848 9579/1/9579 +f 9579/1/9579 9848/1/9848 9849/1/9849 +f 9576/1/9576 9853/1/9853 9848/1/9848 +f 9847/1/9847 9848/1/9848 9853/1/9853 +f 9847/1/9847 9853/1/9853 9854/1/9854 +f 9854/1/9854 9860/1/9860 9847/1/9847 +f 9847/1/9847 9860/1/9860 10059/1/10059 +f 9847/1/9847 10059/1/10059 9863/1/9863 +f 9863/1/9863 9864/1/9864 9847/1/9847 +f 9847/1/9847 9864/1/9864 9865/1/9865 +f 9865/1/9865 9866/1/9866 9847/1/9847 +f 9847/1/9847 9866/1/9866 9521/1/9521 +f 9692/1/9692 9866/1/9866 9865/1/9865 +f 9692/1/9692 9865/1/9865 9686/1/9686 +f 9577/1/9577 9692/1/9692 9686/1/9686 +f 9577/1/9577 9686/1/9686 9593/1/9593 +f 9593/1/9593 9690/1/9690 9577/1/9577 +f 9577/1/9577 9690/1/9690 9578/1/9578 +f 9577/1/9577 9578/1/9578 9575/1/9575 +f 9575/1/9575 9576/1/9576 9577/1/9577 +f 9578/1/9578 9855/1/9855 9575/1/9575 +f 9575/1/9575 9855/1/9855 9853/1/9853 +f 9578/1/9578 9856/1/9856 9855/1/9855 +f 9854/1/9854 9855/1/9855 9856/1/9856 +f 9856/1/9856 9857/1/9857 9854/1/9854 +f 9854/1/9854 9857/1/9857 9858/1/9858 +f 9854/1/9854 9858/1/9858 9859/1/9859 +f 9862/1/9862 9854/1/9854 9859/1/9859 +f 9862/1/9862 9859/1/9859 9867/1/9867 +f 9867/1/9867 9869/1/9869 9862/1/9862 +f 9862/1/9862 9869/1/9869 9870/1/9870 +f 9867/1/9867 9913/1/9913 9869/1/9869 +f 9913/1/9913 9932/1/9932 9869/1/9869 +f 9869/1/9869 9932/1/9932 9933/1/9933 +f 9933/1/9933 9934/1/9934 9869/1/9869 +f 9869/1/9869 9934/1/9934 9935/1/9935 +f 9869/1/9869 9935/1/9935 9927/1/9927 +f 9927/1/9927 9928/1/9928 9869/1/9869 +f 9928/1/9928 9929/1/9929 9869/1/9869 +f 9869/1/9869 9929/1/9929 9930/1/9930 +f 9869/1/9869 9930/1/9930 9931/1/9931 +f 9931/1/9931 9936/1/9936 9869/1/9869 +f 9869/1/9869 9936/1/9936 9937/1/9937 +f 9869/1/9869 9937/1/9937 9938/1/9938 +f 9939/1/9939 9869/1/9869 9938/1/9938 +f 9938/1/9938 9677/1/9677 9939/1/9939 +f 9677/1/9677 9663/1/9663 9939/1/9939 +f 9939/1/9939 9663/1/9663 9895/1/9895 +f 9939/1/9939 9895/1/9895 9872/1/9872 +f 9872/1/9872 9895/1/9895 9896/1/9896 +f 9872/1/9872 9896/1/9896 9887/1/9887 +f 9887/1/9887 9888/1/9888 9872/1/9872 +f 9888/1/9888 9889/1/9889 9872/1/9872 +f 9872/1/9872 9889/1/9889 9890/1/9890 +f 9872/1/9872 9890/1/9890 9891/1/9891 +f 9891/1/9891 9892/1/9892 9872/1/9872 +f 9872/1/9872 9892/1/9892 9893/1/9893 +f 9872/1/9872 9893/1/9893 9894/1/9894 +f 9894/1/9894 9897/1/9897 9872/1/9872 +f 9872/1/9872 9897/1/9897 9898/1/9898 +f 9872/1/9872 9898/1/9898 9882/1/9882 +f 9882/1/9882 9883/1/9883 9872/1/9872 +f 9872/1/9872 9883/1/9883 9884/1/9884 +f 9872/1/9872 9884/1/9884 9885/1/9885 +f 9885/1/9885 9886/1/9886 9872/1/9872 +f 9872/1/9872 9886/1/9886 9873/1/9873 +f 9872/1/9872 9873/1/9873 9871/1/9871 +f 9871/1/9871 9489/1/9489 9872/1/9872 +f 9872/1/9872 9489/1/9489 9869/1/9869 +f 9489/1/9489 9491/1/9491 9869/1/9869 +f 9603/1/9603 9873/1/9873 9886/1/9886 +f 9604/1/9604 9886/1/9886 9885/1/9885 +f 9605/1/9605 9885/1/9885 9884/1/9884 +f 9605/1/9605 9884/1/9884 9606/1/9606 +f 9606/1/9606 9884/1/9884 9883/1/9883 +f 9606/1/9606 9883/1/9883 9608/1/9608 +f 9501/1/9501 9606/1/9606 9608/1/9608 +f 9501/1/9501 9608/1/9608 9609/1/9609 +f 9499/1/9499 9501/1/9501 9609/1/9609 +f 9609/1/9609 9610/1/9610 9499/1/9499 +f 9499/1/9499 9610/1/9610 9611/1/9611 +f 9499/1/9499 9611/1/9611 9497/1/9497 +f 9499/1/9499 9497/1/9497 9500/1/9500 +f 9500/1/9500 9497/1/9497 9498/1/9498 +f 9498/1/9498 9878/1/9878 9500/1/9500 +f 9498/1/9498 9877/1/9877 9878/1/9878 +f 9612/1/9612 9878/1/9878 9877/1/9877 +f 9611/1/9611 9878/1/9878 9612/1/9612 +f 9611/1/9611 9879/1/9879 9878/1/9878 +f 9496/1/9496 9877/1/9877 9498/1/9498 +f 9496/1/9496 9876/1/9876 9877/1/9877 +f 9610/1/9610 9879/1/9879 9611/1/9611 +f 9609/1/9609 9880/1/9880 9610/1/9610 +f 9608/1/9608 9881/1/9881 9609/1/9609 +f 9607/1/9607 9606/1/9606 9501/1/9501 +f 9608/1/9608 9883/1/9883 9881/1/9881 +f 9882/1/9882 9898/1/9898 9899/1/9899 +f 9898/1/9898 9642/1/9642 9899/1/9899 +f 9642/1/9642 9646/1/9646 9899/1/9899 +f 9899/1/9899 9646/1/9646 9903/1/9903 +f 9867/1/9867 9899/1/9899 9903/1/9903 +f 9903/1/9903 9904/1/9904 9867/1/9867 +f 9867/1/9867 9904/1/9904 9905/1/9905 +f 9867/1/9867 9905/1/9905 9906/1/9906 +f 9906/1/9906 9907/1/9907 9867/1/9867 +f 9867/1/9867 9907/1/9907 9908/1/9908 +f 9867/1/9867 9908/1/9908 9909/1/9909 +f 9910/1/9910 9867/1/9867 9909/1/9909 +f 9909/1/9909 9648/1/9648 9910/1/9910 +f 9648/1/9648 9647/1/9647 9910/1/9910 +f 9910/1/9910 9647/1/9647 9911/1/9911 +f 9647/1/9647 9664/1/9664 9911/1/9911 +f 9911/1/9911 9664/1/9664 9913/1/9913 +f 9664/1/9664 9666/1/9666 9913/1/9913 +f 9666/1/9666 9664/1/9664 9591/1/9591 +f 9665/1/9665 9666/1/9666 9591/1/9591 +f 9665/1/9665 9591/1/9591 9597/1/9597 +f 9667/1/9667 9665/1/9665 9597/1/9597 +f 9597/1/9597 9668/1/9668 9667/1/9667 +f 9667/1/9667 9668/1/9668 9934/1/9934 +f 9597/1/9597 9669/1/9669 9668/1/9668 +f 9668/1/9668 9669/1/9669 9935/1/9935 +f 9670/1/9670 9669/1/9669 9597/1/9597 +f 9597/1/9597 9671/1/9671 9670/1/9670 +f 9670/1/9670 9671/1/9671 9928/1/9928 +f 9597/1/9597 9672/1/9672 9671/1/9671 +f 9671/1/9671 9672/1/9672 9929/1/9929 +f 9673/1/9673 9672/1/9672 9597/1/9597 +f 9597/1/9597 9674/1/9674 9673/1/9673 +f 9673/1/9673 9674/1/9674 9931/1/9931 +f 9597/1/9597 9675/1/9675 9674/1/9674 +f 9674/1/9674 9675/1/9675 9936/1/9936 +f 9676/1/9676 9675/1/9675 9597/1/9597 +f 9597/1/9597 9677/1/9677 9676/1/9676 +f 9675/1/9675 9676/1/9676 9937/1/9937 +f 9672/1/9672 9673/1/9673 9930/1/9930 +f 9669/1/9669 9670/1/9670 9927/1/9927 +f 9665/1/9665 9667/1/9667 9933/1/9933 +f 9597/1/9597 9591/1/9591 9594/1/9594 +f 9597/1/9597 9594/1/9594 9598/1/9598 +f 9592/1/9592 9594/1/9594 9591/1/9591 +f 9592/1/9592 9591/1/9591 9590/1/9590 +f 9590/1/9590 9868/1/9868 9592/1/9592 +f 9592/1/9592 9868/1/9868 9859/1/9859 +f 9592/1/9592 9859/1/9859 9688/1/9688 +f 9593/1/9593 9592/1/9592 9688/1/9688 +f 9688/1/9688 9689/1/9689 9593/1/9593 +f 9688/1/9688 9858/1/9858 9689/1/9689 +f 9590/1/9590 9912/1/9912 9868/1/9868 +f 9589/1/9589 9912/1/9912 9590/1/9590 +f 9590/1/9590 9591/1/9591 9589/1/9589 +f 9589/1/9589 9591/1/9591 9585/1/9585 +f 9593/1/9593 9594/1/9594 9592/1/9592 +f 9593/1/9593 9596/1/9596 9594/1/9594 +f 9595/1/9595 9594/1/9594 9596/1/9596 +f 9596/1/9596 9861/1/9861 9595/1/9595 +f 9595/1/9595 9861/1/9861 10060/1/10060 +f 9595/1/9595 10060/1/10060 9717/1/9717 +f 9717/1/9717 9716/1/9716 9595/1/9595 +f 9717/1/9717 10060/1/10060 9975/1/9975 +f 9717/1/9717 9975/1/9975 9817/1/9817 +f 9696/1/9696 9717/1/9717 9817/1/9817 +f 9817/1/9817 9975/1/9975 10062/1/10062 +f 9975/1/9975 10060/1/10060 9862/1/9862 +f 9862/1/9862 9974/1/9974 9975/1/9975 +f 9975/1/9975 9974/1/9974 9973/1/9973 +f 9862/1/9862 10060/1/10060 9861/1/9861 +f 9596/1/9596 9860/1/9860 9861/1/9861 +f 9816/1/9816 9860/1/9860 9596/1/9596 +f 9595/1/9595 9716/1/9716 9594/1/9594 +f 9816/1/9816 9596/1/9596 9593/1/9593 +f 9815/1/9815 9816/1/9816 9593/1/9593 +f 9593/1/9593 9687/1/9687 9815/1/9815 +f 9687/1/9687 9863/1/9863 9815/1/9815 +f 9815/1/9815 10059/1/10059 9816/1/9816 +f 9666/1/9666 9665/1/9665 9932/1/9932 +f 9591/1/9591 9664/1/9664 9647/1/9647 +f 9591/1/9591 9647/1/9647 9607/1/9607 +f 9607/1/9607 9647/1/9647 9648/1/9648 +f 9607/1/9607 9648/1/9648 9649/1/9649 +f 9649/1/9649 9650/1/9650 9607/1/9607 +f 9607/1/9607 9650/1/9650 9651/1/9651 +f 9607/1/9607 9651/1/9651 9643/1/9643 +f 9643/1/9643 9644/1/9644 9607/1/9607 +f 9644/1/9644 9645/1/9645 9607/1/9607 +f 9607/1/9607 9645/1/9645 9646/1/9646 +f 9645/1/9645 9644/1/9644 9904/1/9904 +f 9644/1/9644 9643/1/9643 9905/1/9905 +f 9643/1/9643 9651/1/9651 9906/1/9906 +f 9651/1/9651 9650/1/9650 9907/1/9907 +f 9650/1/9650 9649/1/9649 9908/1/9908 +f 9649/1/9649 9648/1/9648 9909/1/9909 +f 9910/1/9910 9911/1/9911 9867/1/9867 +f 9908/1/9908 9649/1/9649 9909/1/9909 +f 9907/1/9907 9650/1/9650 9908/1/9908 +f 9906/1/9906 9651/1/9651 9907/1/9907 +f 9905/1/9905 9643/1/9643 9906/1/9906 +f 9904/1/9904 9644/1/9644 9905/1/9905 +f 9903/1/9903 9645/1/9645 9904/1/9904 +f 9646/1/9646 9645/1/9645 9903/1/9903 +f 9897/1/9897 9652/1/9652 9898/1/9898 +f 9894/1/9894 9653/1/9653 9897/1/9897 +f 9893/1/9893 9654/1/9654 9894/1/9894 +f 9892/1/9892 9655/1/9655 9893/1/9893 +f 9891/1/9891 9656/1/9656 9892/1/9892 +f 9890/1/9890 9657/1/9657 9891/1/9891 +f 9889/1/9889 9658/1/9658 9890/1/9890 +f 9888/1/9888 9659/1/9659 9889/1/9889 +f 9887/1/9887 9660/1/9660 9888/1/9888 +f 9896/1/9896 9661/1/9661 9887/1/9887 +f 9895/1/9895 9662/1/9662 9896/1/9896 +f 9676/1/9676 9677/1/9677 9938/1/9938 +f 9872/1/9872 9869/1/9869 9939/1/9939 +f 9937/1/9937 9676/1/9676 9938/1/9938 +f 9936/1/9936 9675/1/9675 9937/1/9937 +f 9931/1/9931 9674/1/9674 9936/1/9936 +f 9930/1/9930 9673/1/9673 9931/1/9931 +f 9929/1/9929 9672/1/9672 9930/1/9930 +f 9928/1/9928 9671/1/9671 9929/1/9929 +f 9927/1/9927 9670/1/9670 9928/1/9928 +f 9935/1/9935 9669/1/9669 9927/1/9927 +f 9934/1/9934 9668/1/9668 9935/1/9935 +f 9933/1/9933 9667/1/9667 9934/1/9934 +f 9932/1/9932 9665/1/9665 9933/1/9933 +f 9913/1/9913 9666/1/9666 9932/1/9932 +f 9911/1/9911 9913/1/9913 9867/1/9867 +f 9867/1/9867 9859/1/9859 9868/1/9868 +f 9861/1/9861 9854/1/9854 9862/1/9862 +f 9688/1/9688 9859/1/9859 9858/1/9858 +f 9689/1/9689 9858/1/9858 9857/1/9857 +f 9689/1/9689 9857/1/9857 9690/1/9690 +f 9690/1/9690 9857/1/9857 9856/1/9856 +f 9690/1/9690 9856/1/9856 9578/1/9578 +f 9593/1/9593 9689/1/9689 9690/1/9690 +f 9593/1/9593 9686/1/9686 9687/1/9687 +f 9686/1/9686 9864/1/9864 9687/1/9687 +f 9691/1/9691 9866/1/9866 9692/1/9692 +f 9686/1/9686 9865/1/9865 9864/1/9864 +f 9687/1/9687 9864/1/9864 9863/1/9863 +f 9815/1/9815 9863/1/9863 10059/1/10059 +f 9816/1/9816 10059/1/10059 9860/1/9860 +f 9854/1/9854 9861/1/9861 9860/1/9860 +f 9854/1/9854 9853/1/9853 9855/1/9855 +f 9847/1/9847 9521/1/9521 9848/1/9848 +f 9848/1/9848 9521/1/9521 9519/1/9519 +f 9575/1/9575 9853/1/9853 9576/1/9576 +f 9520/1/9520 9581/1/9581 9582/1/9582 +f 9581/1/9581 9685/1/9685 9582/1/9582 +f 9582/1/9582 9685/1/9685 9641/1/9641 +f 9582/1/9582 9641/1/9641 9639/1/9639 +f 9639/1/9639 9640/1/9640 9582/1/9582 +f 9639/1/9639 9962/1/9962 9640/1/9640 +f 9640/1/9640 9962/1/9962 9963/1/9963 +f 9639/1/9639 9964/1/9964 9962/1/9962 +f 9962/1/9962 9964/1/9964 9852/1/9852 +f 9852/1/9852 9964/1/9964 9921/1/9921 +f 9852/1/9852 9921/1/9921 9851/1/9851 +f 9851/1/9851 9921/1/9921 9922/1/9922 +f 9851/1/9851 9922/1/9922 9919/1/9919 +f 9919/1/9919 9920/1/9920 9851/1/9851 +f 9851/1/9851 9920/1/9920 9900/1/9900 +f 9920/1/9920 9923/1/9923 9900/1/9900 +f 9900/1/9900 9923/1/9923 9924/1/9924 +f 9900/1/9900 9924/1/9924 9925/1/9925 +f 9925/1/9925 9926/1/9926 9900/1/9900 +f 9681/1/9681 9926/1/9926 9925/1/9925 +f 9681/1/9681 9925/1/9925 9679/1/9679 +f 9585/1/9585 9681/1/9681 9679/1/9679 +f 9678/1/9678 9585/1/9585 9679/1/9679 +f 9679/1/9679 9924/1/9924 9678/1/9678 +f 9678/1/9678 9581/1/9581 9585/1/9585 +f 9682/1/9682 9581/1/9581 9678/1/9678 +f 9682/1/9682 9678/1/9678 9920/1/9920 +f 9682/1/9682 9920/1/9920 9683/1/9683 +f 9682/1/9682 9683/1/9683 9581/1/9581 +f 9683/1/9683 9684/1/9684 9581/1/9581 +f 9683/1/9683 9919/1/9919 9684/1/9684 +f 9680/1/9680 9926/1/9926 9681/1/9681 +f 9679/1/9679 9925/1/9925 9924/1/9924 +f 9678/1/9678 9924/1/9924 9923/1/9923 +f 9920/1/9920 9678/1/9678 9923/1/9923 +f 9683/1/9683 9920/1/9920 9919/1/9919 +f 9684/1/9684 9919/1/9919 9922/1/9922 +f 9684/1/9684 9922/1/9922 9685/1/9685 +f 9685/1/9685 9922/1/9922 9921/1/9921 +f 9964/1/9964 9685/1/9685 9921/1/9921 +f 9641/1/9641 9964/1/9964 9639/1/9639 +f 9641/1/9641 9685/1/9685 9964/1/9964 +f 9581/1/9581 9684/1/9684 9685/1/9685 +f 9581/1/9581 9583/1/9583 9584/1/9584 +f 9583/1/9583 9918/1/9918 9584/1/9584 +f 9579/1/9579 9849/1/9849 9580/1/9580 +f 9848/1/9848 9519/1/9519 9849/1/9849 +f 9583/1/9583 9850/1/9850 9918/1/9918 +f 9584/1/9584 9918/1/9918 9917/1/9917 +f 9581/1/9581 9584/1/9584 9585/1/9585 +f 9588/1/9588 9589/1/9589 9585/1/9585 +f 9588/1/9588 9914/1/9914 9589/1/9589 +f 9586/1/9586 9916/1/9916 9587/1/9587 +f 9851/1/9851 9900/1/9900 9916/1/9916 +f 9588/1/9588 9915/1/9915 9914/1/9914 +f 9589/1/9589 9914/1/9914 9912/1/9912 +f 9867/1/9867 9868/1/9868 9912/1/9912 +f 9882/1/9882 9899/1/9899 9867/1/9867 +f 9900/1/9900 9926/1/9926 9901/1/9901 +f 9926/1/9926 9955/1/9955 9901/1/9901 +f 9901/1/9901 9955/1/9955 9956/1/9956 +f 9901/1/9901 9956/1/9956 9957/1/9957 +f 9957/1/9957 9958/1/9958 9901/1/9901 +f 9635/1/9635 9958/1/9958 9957/1/9957 +f 9636/1/9636 9957/1/9957 9956/1/9956 +f 9637/1/9637 9956/1/9956 9955/1/9955 +f 9926/1/9926 9637/1/9637 9955/1/9955 +f 9882/1/9882 9881/1/9881 9883/1/9883 +f 9609/1/9609 9881/1/9881 9880/1/9880 +f 9610/1/9610 9880/1/9880 9879/1/9879 +f 9500/1/9500 9878/1/9878 9879/1/9879 +f 9499/1/9499 9500/1/9500 9501/1/9501 +f 9615/1/9615 9616/1/9616 9501/1/9501 +f 9619/1/9619 9618/1/9618 9503/1/9503 +f 9615/1/9615 9942/1/9942 9940/1/9940 +f 9619/1/9619 9943/1/9943 9618/1/9618 +f 9619/1/9619 9944/1/9944 9943/1/9943 +f 9620/1/9620 9944/1/9944 9619/1/9619 +f 9940/1/9940 9942/1/9942 9504/1/9504 +f 9503/1/9503 9502/1/9502 9504/1/9504 +f 9619/1/9619 9503/1/9503 9620/1/9620 +f 9622/1/9622 9946/1/9946 9621/1/9621 +f 9620/1/9620 9945/1/9945 9944/1/9944 +f 9506/1/9506 9943/1/9943 9944/1/9944 +f 9505/1/9505 9506/1/9506 9507/1/9507 +f 9512/1/9512 9623/1/9623 9509/1/9509 +f 9621/1/9621 9507/1/9507 9622/1/9622 +f 9622/1/9622 9947/1/9947 9946/1/9946 +f 9624/1/9624 9948/1/9948 9623/1/9623 +f 9516/1/9516 9624/1/9624 9623/1/9623 +f 9624/1/9624 9949/1/9949 9948/1/9948 +f 9625/1/9625 9949/1/9949 9624/1/9624 +f 9949/1/9949 9515/1/9515 9948/1/9948 +f 9511/1/9511 9508/1/9508 9947/1/9947 +f 9509/1/9509 9511/1/9511 9512/1/9512 +f 9512/1/9512 9516/1/9516 9623/1/9623 +f 9514/1/9514 9513/1/9513 9515/1/9515 +f 9517/1/9517 9518/1/9518 9515/1/9515 +f 9516/1/9516 9625/1/9625 9624/1/9624 +f 9520/1/9520 9582/1/9582 9518/1/9518 +f 9626/1/9626 9950/1/9950 9625/1/9625 +f 9627/1/9627 9951/1/9951 9626/1/9626 +f 9627/1/9627 9952/1/9952 9951/1/9951 +f 9901/1/9901 9952/1/9952 9953/1/9953 +f 9954/1/9954 9901/1/9901 9953/1/9953 +f 9631/1/9631 9902/1/9902 9954/1/9954 +f 9628/1/9628 9629/1/9629 9630/1/9630 +f 9617/1/9617 9902/1/9902 9631/1/9631 +f 9501/1/9501 9617/1/9617 9607/1/9607 +f 9585/1/9585 9591/1/9591 9607/1/9607 +f 9585/1/9585 9680/1/9680 9681/1/9681 +f 9680/1/9680 9637/1/9637 9926/1/9926 +f 9636/1/9636 9956/1/9956 9637/1/9637 +f 9635/1/9635 9957/1/9957 9636/1/9636 +f 9634/1/9634 9958/1/9958 9635/1/9635 +f 9634/1/9634 9959/1/9959 9958/1/9958 +f 9633/1/9633 9959/1/9959 9634/1/9634 +f 9633/1/9633 9632/1/9632 9959/1/9959 +f 9628/1/9628 9582/1/9582 9629/1/9629 +f 9582/1/9582 9640/1/9640 9638/1/9638 +f 9640/1/9640 9963/1/9963 9638/1/9638 +f 9962/1/9962 9852/1/9852 9963/1/9963 +f 9632/1/9632 9961/1/9961 9960/1/9960 +f 9959/1/9959 9632/1/9632 9960/1/9960 +f 9901/1/9901 9958/1/9958 9959/1/9959 +f 9901/1/9901 9951/1/9951 9952/1/9952 +f 9626/1/9626 9951/1/9951 9950/1/9950 +f 9625/1/9625 9950/1/9950 9949/1/9949 +f 9949/1/9949 9517/1/9517 9515/1/9515 +f 9851/1/9851 9519/1/9519 9852/1/9852 +f 9517/1/9517 9520/1/9520 9518/1/9518 +f 9521/1/9521 9522/1/9522 9519/1/9519 +f 9520/1/9520 9577/1/9577 9576/1/9576 +f 9691/1/9691 9692/1/9692 9577/1/9577 +f 9691/1/9691 9846/1/9846 9866/1/9866 +f 9701/1/9701 10049/1/10049 9693/1/9693 +f 9866/1/9866 9846/1/9846 9521/1/9521 +f 9521/1/9521 9532/1/9532 9522/1/9522 +f 9706/1/9706 9704/1/9704 9703/1/9703 +f 9695/1/9695 9532/1/9532 9530/1/9530 +f 9704/1/9704 9845/1/9845 9705/1/9705 +f 9840/1/9840 9529/1/9529 9845/1/9845 +f 9695/1/9695 9844/1/9844 9843/1/9843 +f 9531/1/9531 9842/1/9842 9529/1/9529 +f 9699/1/9699 9843/1/9843 10048/1/10048 +f 9699/1/9699 10048/1/10048 9700/1/9700 +f 9700/1/9700 10048/1/10048 10047/1/10047 +f 9694/1/9694 9699/1/9699 9700/1/9700 +f 9694/1/9694 9697/1/9697 9698/1/9698 +f 9697/1/9697 9978/1/9978 9698/1/9698 +f 9817/1/9817 9818/1/9818 9696/1/9696 +f 9817/1/9817 10062/1/10062 9818/1/9818 +f 9975/1/9975 9973/1/9973 10062/1/10062 +f 9697/1/9697 10061/1/10061 9978/1/9978 +f 9698/1/9698 9978/1/9978 9977/1/9977 +f 9702/1/9702 9977/1/9977 9976/1/9976 +f 9842/1/9842 10049/1/10049 9976/1/9976 +f 10045/1/10045 10046/1/10046 9842/1/9842 +f 9720/1/9720 10046/1/10046 10045/1/10045 +f 9696/1/9696 9719/1/9719 9720/1/9720 +f 9721/1/9721 9979/1/9979 9715/1/9715 +f 9717/1/9717 9696/1/9696 9716/1/9716 +f 9598/1/9598 9594/1/9594 9716/1/9716 +f 9598/1/9598 9494/1/9494 9492/1/9492 +f 9574/1/9574 9494/1/9494 9573/1/9573 +f 9493/1/9493 9494/1/9494 9574/1/9574 +f 9572/1/9572 9573/1/9573 9571/1/9571 +f 9739/1/9739 9569/1/9569 9571/1/9571 +f 9739/1/9739 9814/1/9814 9749/1/9749 +f 9814/1/9814 9813/1/9813 10031/1/10031 +f 9813/1/9813 9812/1/9812 10030/1/10030 +f 9812/1/9812 9811/1/9811 10029/1/10029 +f 9811/1/9811 9810/1/9810 10028/1/10028 +f 9810/1/9810 9809/1/9809 10027/1/10027 +f 9809/1/9809 9808/1/9808 10026/1/10026 +f 9808/1/9808 9807/1/9807 10025/1/10025 +f 9807/1/9807 9806/1/9806 10024/1/10024 +f 9806/1/9806 9805/1/9805 10023/1/10023 +f 9805/1/9805 9804/1/9804 10022/1/10022 +f 9804/1/9804 9803/1/9803 10021/1/10021 +f 9803/1/9803 9725/1/9725 10020/1/10020 +f 9718/1/9718 9713/1/9713 9724/1/9724 +f 9725/1/9725 9729/1/9729 10010/1/10010 +f 9729/1/9729 9728/1/9728 10011/1/10011 +f 9728/1/9728 9727/1/9727 10015/1/10015 +f 9727/1/9727 9726/1/9726 10016/1/10016 +f 9726/1/9726 9734/1/9734 10017/1/10017 +f 9734/1/9734 9733/1/9733 10018/1/10018 +f 9733/1/9733 9732/1/9732 10019/1/10019 +f 9732/1/9732 9731/1/9731 10012/1/10012 +f 9731/1/9731 9730/1/9730 10013/1/10013 +f 9723/1/9723 9735/1/9735 9730/1/9730 +f 9795/1/9795 9723/1/9723 9761/1/9761 +f 9789/1/9789 9761/1/9761 9788/1/9788 +f 9788/1/9788 9832/1/9832 10008/1/10008 +f 9829/1/9829 9823/1/9823 9832/1/9832 +f 9829/1/9829 9830/1/9830 9823/1/9823 +f 9785/1/9785 9831/1/9831 9830/1/9830 +f 9787/1/9787 9722/1/9722 9786/1/9786 +f 9784/1/9784 9831/1/9831 9785/1/9785 +f 9778/1/9778 9836/1/9836 9784/1/9784 +f 9768/1/9768 9767/1/9767 9778/1/9778 +f 9768/1/9768 9782/1/9782 9783/1/9783 +f 9800/1/9800 9825/1/9825 9782/1/9782 +f 9799/1/9799 9826/1/9826 9800/1/9800 +f 9802/1/9802 9827/1/9827 9799/1/9799 +f 9801/1/9801 9828/1/9828 9802/1/9802 +f 9801/1/9801 9777/1/9777 9828/1/9828 +f 9776/1/9776 10050/1/10050 9777/1/9777 +f 9775/1/9775 10051/1/10051 9776/1/9776 +f 9774/1/9774 10053/1/10053 9775/1/9775 +f 9773/1/9773 10054/1/10054 9774/1/9774 +f 9773/1/9773 9772/1/9772 10054/1/10054 +f 9703/1/9703 9771/1/9771 9772/1/9772 +f 9703/1/9703 9708/1/9708 9707/1/9707 +f 9710/1/9710 9968/1/9968 9708/1/9708 +f 9711/1/9711 9969/1/9969 9710/1/9710 +f 9712/1/9712 9970/1/9970 9711/1/9711 +f 9722/1/9722 9713/1/9713 9709/1/9709 +f 9713/1/9713 9715/1/9715 9714/1/9714 +f 9712/1/9712 9971/1/9971 9970/1/9970 +f 9715/1/9715 9972/1/9972 9714/1/9714 +f 9834/1/9834 9970/1/9970 9971/1/9971 +f 9972/1/9972 9973/1/9973 9974/1/9974 +f 9980/1/9980 9981/1/9981 9834/1/9834 +f 9862/1/9862 9870/1/9870 9974/1/9974 +f 9493/1/9493 9574/1/9574 9980/1/9980 +f 9869/1/9869 9491/1/9491 9870/1/9870 +f 9493/1/9493 9492/1/9492 9494/1/9494 +f 9489/1/9489 9490/1/9490 9491/1/9491 +f 9489/1/9489 9487/1/9487 9490/1/9490 +f 9490/1/9490 9487/1/9487 9599/1/9599 +f 9599/1/9599 9487/1/9487 9601/1/9601 +f 9488/1/9488 9487/1/9487 9489/1/9489 +f 9598/1/9598 9492/1/9492 9597/1/9597 +f 9597/1/9597 9663/1/9663 9677/1/9677 +f 9663/1/9663 9662/1/9662 9895/1/9895 +f 9662/1/9662 9661/1/9661 9896/1/9896 +f 9661/1/9661 9660/1/9660 9887/1/9887 +f 9660/1/9660 9659/1/9659 9888/1/9888 +f 9659/1/9659 9658/1/9658 9889/1/9889 +f 9658/1/9658 9657/1/9657 9890/1/9890 +f 9657/1/9657 9656/1/9656 9891/1/9891 +f 9656/1/9656 9655/1/9655 9892/1/9892 +f 9655/1/9655 9654/1/9654 9893/1/9893 +f 9654/1/9654 9653/1/9653 9894/1/9894 +f 9653/1/9653 9652/1/9652 9897/1/9897 +f 9652/1/9652 9642/1/9642 9898/1/9898 +f 9607/1/9607 9646/1/9646 9642/1/9642 +f 9605/1/9605 9606/1/9606 9607/1/9607 +f 9604/1/9604 9885/1/9885 9605/1/9605 +f 9603/1/9603 9886/1/9886 9604/1/9604 +f 9602/1/9602 9873/1/9873 9603/1/9603 +f 9600/1/9600 9490/1/9490 9599/1/9599 +f 9602/1/9602 9871/1/9871 9873/1/9873 +f 9601/1/9601 9874/1/9874 9599/1/9599 +f 9871/1/9871 9488/1/9488 9489/1/9489 +f 9486/1/9486 9487/1/9487 9488/1/9488 +f 9485/1/9485 9487/1/9487 9486/1/9486 +f 9484/1/9484 9485/1/9485 9486/1/9486 +f 9482/1/9482 9483/1/9483 9484/1/9484 +f 9481/1/9481 9483/1/9483 9482/1/9482 +f 9483/1/9483 9485/1/9485 9484/1/9484 +f 9601/1/9601 9487/1/9487 9485/1/9485 +f 9601/1/9601 9875/1/9875 9874/1/9874 +f 9613/1/9613 9877/1/9877 9876/1/9876 +f 9612/1/9612 9877/1/9877 9613/1/9613 +f 9497/1/9497 9611/1/9611 9612/1/9612 +f 9497/1/9497 9496/1/9496 9498/1/9498 +f 9478/1/9478 9479/1/9479 9495/1/9495 +f 9875/1/9875 9876/1/9876 9496/1/9496 +f 9875/1/9875 9477/1/9477 9480/1/9480 +f 9478/1/9478 9475/1/9475 9479/1/9479 +f 9477/1/9477 9476/1/9476 9480/1/9480 +f 9614/1/9614 9476/1/9476 9475/1/9475 +f 10063/1/10063 10064/1/10064 10065/1/10065 +f 10063/1/10063 10065/1/10065 10066/1/10066 +f 10083/1/10083 10063/1/10063 10066/1/10066 +f 10083/1/10083 10066/1/10066 10080/1/10080 +f 10080/1/10080 10082/1/10082 10083/1/10083 +f 10083/1/10083 10082/1/10082 10089/1/10089 +f 10083/1/10083 10089/1/10089 10090/1/10090 +f 10089/1/10089 10093/1/10093 10090/1/10090 +f 10093/1/10093 10067/1/10067 10090/1/10090 +f 10090/1/10090 10067/1/10067 10063/1/10063 +f 10063/1/10063 10067/1/10067 10068/1/10068 +f 10068/1/10068 10067/1/10067 10076/1/10076 +f 10068/1/10068 10076/1/10076 10077/1/10077 +f 10094/1/10094 10068/1/10068 10077/1/10077 +f 10094/1/10094 10077/1/10077 10105/1/10105 +f 10098/1/10098 10094/1/10094 10105/1/10105 +f 10098/1/10098 10105/1/10105 10100/1/10100 +f 10099/1/10099 10098/1/10098 10100/1/10100 +f 10099/1/10099 10100/1/10100 10101/1/10101 +f 10128/1/10128 10099/1/10099 10101/1/10101 +f 10128/1/10128 10101/1/10101 10103/1/10103 +f 10103/1/10103 10130/1/10130 10128/1/10128 +f 10129/1/10129 10128/1/10128 10130/1/10130 +f 10129/1/10129 10130/1/10130 10155/1/10155 +f 10104/1/10104 10129/1/10129 10155/1/10155 +f 10154/1/10154 10104/1/10104 10155/1/10155 +f 10162/1/10162 10154/1/10154 10155/1/10155 +f 10155/1/10155 10171/1/10171 10162/1/10162 +f 10162/1/10162 10171/1/10171 10178/1/10178 +f 10162/1/10162 10178/1/10178 10161/1/10161 +f 10161/1/10161 10178/1/10178 10177/1/10177 +f 10176/1/10176 10161/1/10161 10177/1/10177 +f 10173/1/10173 10176/1/10176 10177/1/10177 +f 10173/1/10173 10177/1/10177 10169/1/10169 +f 10154/1/10154 10173/1/10173 10169/1/10169 +f 10154/1/10154 10169/1/10169 10209/1/10209 +f 10186/1/10186 10154/1/10154 10209/1/10209 +f 10186/1/10186 10209/1/10209 10182/1/10182 +f 10182/1/10182 10185/1/10185 10186/1/10186 +f 10186/1/10186 10185/1/10185 10187/1/10187 +f 10186/1/10186 10187/1/10187 10152/1/10152 +f 10152/1/10152 10187/1/10187 10170/1/10170 +f 10170/1/10170 10147/1/10147 10152/1/10152 +f 10147/1/10147 10151/1/10151 10152/1/10152 +f 10152/1/10152 10151/1/10151 10153/1/10153 +f 10152/1/10152 10153/1/10153 10154/1/10154 +f 10154/1/10154 10153/1/10153 10156/1/10156 +f 10164/1/10164 10156/1/10156 10153/1/10153 +f 10164/1/10164 10153/1/10153 10165/1/10165 +f 10165/1/10165 10170/1/10170 10164/1/10164 +f 10164/1/10164 10170/1/10170 10163/1/10163 +f 10169/1/10169 10163/1/10163 10170/1/10170 +f 10169/1/10169 10103/1/10103 10163/1/10163 +f 10103/1/10103 10104/1/10104 10163/1/10163 +f 10163/1/10163 10104/1/10104 10156/1/10156 +f 10103/1/10103 10102/1/10102 10104/1/10104 +f 10102/1/10102 10127/1/10127 10104/1/10104 +f 10102/1/10102 10125/1/10125 10127/1/10127 +f 10125/1/10125 10126/1/10126 10127/1/10127 +f 10127/1/10127 10126/1/10126 10128/1/10128 +f 10125/1/10125 10124/1/10124 10126/1/10126 +f 10124/1/10124 10099/1/10099 10126/1/10126 +f 10122/1/10122 10099/1/10099 10124/1/10124 +f 10123/1/10123 10122/1/10122 10124/1/10124 +f 10119/1/10119 10122/1/10122 10123/1/10123 +f 10119/1/10119 10123/1/10123 10100/1/10100 +f 10100/1/10100 10123/1/10123 10125/1/10125 +f 10119/1/10119 10118/1/10118 10122/1/10122 +f 10118/1/10118 10106/1/10106 10122/1/10122 +f 10106/1/10106 10097/1/10097 10122/1/10122 +f 10106/1/10106 10079/1/10079 10097/1/10097 +f 10079/1/10079 10095/1/10095 10097/1/10097 +f 10097/1/10097 10095/1/10095 10098/1/10098 +f 10095/1/10095 10079/1/10079 10096/1/10096 +f 10095/1/10095 10096/1/10096 10091/1/10091 +f 10091/1/10091 10094/1/10094 10095/1/10095 +f 10091/1/10091 10096/1/10096 10092/1/10092 +f 10091/1/10091 10092/1/10092 10089/1/10089 +f 10089/1/10089 10064/1/10064 10091/1/10091 +f 10091/1/10091 10064/1/10064 10068/1/10068 +f 10096/1/10096 10078/1/10078 10092/1/10092 +f 10092/1/10092 10078/1/10078 10076/1/10076 +f 10092/1/10092 10076/1/10076 10093/1/10093 +f 10096/1/10096 10079/1/10079 10078/1/10078 +f 10077/1/10077 10078/1/10078 10079/1/10079 +f 10077/1/10077 10079/1/10079 10106/1/10106 +f 10118/1/10118 10108/1/10108 10106/1/10106 +f 10107/1/10107 10106/1/10106 10108/1/10108 +f 10107/1/10107 10108/1/10108 10109/1/10109 +f 10107/1/10107 10109/1/10109 10134/1/10134 +f 10134/1/10134 10132/1/10132 10107/1/10107 +f 10107/1/10107 10132/1/10132 10120/1/10120 +f 10107/1/10107 10120/1/10120 10105/1/10105 +f 10105/1/10105 10120/1/10120 10117/1/10117 +f 10105/1/10105 10117/1/10117 10119/1/10119 +f 10120/1/10120 10121/1/10121 10117/1/10117 +f 10117/1/10117 10121/1/10121 10118/1/10118 +f 10118/1/10118 10121/1/10121 10110/1/10110 +f 10121/1/10121 10131/1/10131 10110/1/10110 +f 10110/1/10110 10131/1/10131 10133/1/10133 +f 10110/1/10110 10133/1/10133 10135/1/10135 +f 10135/1/10135 10112/1/10112 10110/1/10110 +f 10111/1/10111 10110/1/10110 10112/1/10112 +f 10111/1/10111 10112/1/10112 10113/1/10113 +f 10136/1/10136 10111/1/10111 10113/1/10113 +f 10136/1/10136 10113/1/10113 10138/1/10138 +f 10138/1/10138 10137/1/10137 10136/1/10136 +f 10136/1/10136 10137/1/10137 10135/1/10135 +f 10136/1/10136 10135/1/10135 10134/1/10134 +f 10137/1/10137 10114/1/10114 10135/1/10135 +f 10114/1/10114 10137/1/10137 10140/1/10140 +f 10146/1/10146 10114/1/10114 10140/1/10140 +f 10146/1/10146 10140/1/10140 10144/1/10144 +f 10144/1/10144 10145/1/10145 10146/1/10146 +f 10146/1/10146 10145/1/10145 10116/1/10116 +f 10116/1/10116 10145/1/10145 10115/1/10115 +f 10115/1/10115 10114/1/10114 10116/1/10116 +f 10113/1/10113 10114/1/10114 10115/1/10115 +f 10115/1/10115 10139/1/10139 10113/1/10113 +f 10145/1/10145 10139/1/10139 10115/1/10115 +f 10145/1/10145 10141/1/10141 10139/1/10139 +f 10140/1/10140 10139/1/10139 10141/1/10141 +f 10140/1/10140 10141/1/10141 10142/1/10142 +f 10142/1/10142 10141/1/10141 10143/1/10143 +f 10142/1/10142 10143/1/10143 10144/1/10144 +f 10143/1/10143 10141/1/10141 10145/1/10145 +f 10144/1/10144 10143/1/10143 10145/1/10145 +f 10144/1/10144 10140/1/10140 10142/1/10142 +f 10116/1/10116 10114/1/10114 10146/1/10146 +f 10137/1/10137 10139/1/10139 10140/1/10140 +f 10138/1/10138 10139/1/10139 10137/1/10137 +f 10139/1/10139 10138/1/10138 10113/1/10113 +f 10134/1/10134 10111/1/10111 10136/1/10136 +f 10113/1/10113 10112/1/10112 10114/1/10114 +f 10109/1/10109 10110/1/10110 10111/1/10111 +f 10135/1/10135 10114/1/10114 10112/1/10112 +f 10134/1/10134 10135/1/10135 10133/1/10133 +f 10132/1/10132 10133/1/10133 10131/1/10131 +f 10120/1/10120 10131/1/10131 10121/1/10121 +f 10132/1/10132 10131/1/10131 10120/1/10120 +f 10134/1/10134 10133/1/10133 10132/1/10132 +f 10134/1/10134 10109/1/10109 10111/1/10111 +f 10109/1/10109 10108/1/10108 10110/1/10110 +f 10105/1/10105 10106/1/10106 10107/1/10107 +f 10110/1/10110 10108/1/10108 10118/1/10118 +f 10117/1/10117 10118/1/10118 10119/1/10119 +f 10122/1/10122 10097/1/10097 10099/1/10099 +f 10123/1/10123 10124/1/10124 10125/1/10125 +f 10100/1/10100 10125/1/10125 10102/1/10102 +f 10169/1/10169 10171/1/10171 10103/1/10103 +f 10165/1/10165 10172/1/10172 10170/1/10170 +f 10166/1/10166 10172/1/10172 10165/1/10165 +f 10150/1/10150 10166/1/10166 10165/1/10165 +f 10150/1/10150 10165/1/10165 10151/1/10151 +f 10149/1/10149 10166/1/10166 10150/1/10150 +f 10149/1/10149 10150/1/10150 10147/1/10147 +f 10147/1/10147 10148/1/10148 10149/1/10149 +f 10148/1/10148 10167/1/10167 10149/1/10149 +f 10148/1/10148 10168/1/10168 10167/1/10167 +f 10167/1/10167 10168/1/10168 10166/1/10166 +f 10147/1/10147 10168/1/10168 10148/1/10148 +f 10147/1/10147 10172/1/10172 10168/1/10168 +f 10149/1/10149 10167/1/10167 10166/1/10166 +f 10166/1/10166 10168/1/10168 10172/1/10172 +f 10163/1/10163 10156/1/10156 10164/1/10164 +f 10165/1/10165 10153/1/10153 10151/1/10151 +f 10147/1/10147 10150/1/10150 10151/1/10151 +f 10172/1/10172 10147/1/10147 10170/1/10170 +f 10187/1/10187 10169/1/10169 10170/1/10170 +f 10187/1/10187 10208/1/10208 10169/1/10169 +f 10185/1/10185 10208/1/10208 10187/1/10187 +f 10185/1/10185 10204/1/10204 10208/1/10208 +f 10207/1/10207 10208/1/10208 10204/1/10204 +f 10207/1/10207 10204/1/10204 10203/1/10203 +f 10179/1/10179 10207/1/10207 10203/1/10203 +f 10179/1/10179 10203/1/10203 10193/1/10193 +f 10179/1/10179 10193/1/10193 10191/1/10191 +f 10191/1/10191 10180/1/10180 10179/1/10179 +f 10179/1/10179 10180/1/10180 10181/1/10181 +f 10179/1/10179 10181/1/10181 10182/1/10182 +f 10181/1/10181 10180/1/10180 10183/1/10183 +f 10183/1/10183 10192/1/10192 10181/1/10181 +f 10181/1/10181 10192/1/10192 10194/1/10194 +f 10181/1/10181 10194/1/10194 10201/1/10201 +f 10181/1/10181 10201/1/10201 10204/1/10204 +f 10216/1/10216 10201/1/10201 10194/1/10194 +f 10216/1/10216 10194/1/10194 10218/1/10218 +f 10217/1/10217 10216/1/10216 10218/1/10218 +f 10219/1/10219 10217/1/10217 10218/1/10218 +f 10221/1/10221 10219/1/10219 10218/1/10218 +f 10218/1/10218 10195/1/10195 10221/1/10221 +f 10221/1/10221 10195/1/10195 10200/1/10200 +f 10199/1/10199 10221/1/10221 10200/1/10200 +f 10199/1/10199 10200/1/10200 10198/1/10198 +f 10199/1/10199 10198/1/10198 10197/1/10197 +f 10199/1/10199 10197/1/10197 10196/1/10196 +f 10196/1/10196 10217/1/10217 10199/1/10199 +f 10199/1/10199 10217/1/10217 10222/1/10222 +f 10217/1/10217 10220/1/10220 10222/1/10222 +f 10221/1/10221 10222/1/10222 10220/1/10220 +f 10196/1/10196 10215/1/10215 10217/1/10217 +f 10193/1/10193 10215/1/10215 10196/1/10196 +f 10195/1/10195 10193/1/10193 10196/1/10196 +f 10194/1/10194 10193/1/10193 10195/1/10195 +f 10197/1/10197 10195/1/10195 10196/1/10196 +f 10197/1/10197 10198/1/10198 10195/1/10195 +f 10222/1/10222 10221/1/10221 10199/1/10199 +f 10195/1/10195 10198/1/10198 10200/1/10200 +f 10221/1/10221 10220/1/10220 10219/1/10219 +f 10219/1/10219 10220/1/10220 10217/1/10217 +f 10215/1/10215 10216/1/10216 10217/1/10217 +f 10215/1/10215 10213/1/10213 10216/1/10216 +f 10214/1/10214 10213/1/10213 10215/1/10215 +f 10203/1/10203 10214/1/10214 10215/1/10215 +f 10205/1/10205 10214/1/10214 10203/1/10203 +f 10203/1/10203 10202/1/10202 10205/1/10205 +f 10206/1/10206 10205/1/10205 10202/1/10202 +f 10206/1/10206 10202/1/10202 10213/1/10213 +f 10213/1/10213 10211/1/10211 10206/1/10206 +f 10211/1/10211 10210/1/10210 10206/1/10206 +f 10211/1/10211 10212/1/10212 10210/1/10210 +f 10210/1/10210 10212/1/10212 10205/1/10205 +f 10213/1/10213 10212/1/10212 10211/1/10211 +f 10213/1/10213 10202/1/10202 10201/1/10201 +f 10206/1/10206 10210/1/10210 10205/1/10205 +f 10201/1/10201 10202/1/10202 10203/1/10203 +f 10205/1/10205 10212/1/10212 10214/1/10214 +f 10213/1/10213 10214/1/10214 10212/1/10212 +f 10218/1/10218 10194/1/10194 10195/1/10195 +f 10213/1/10213 10201/1/10201 10216/1/10216 +f 10191/1/10191 10194/1/10194 10192/1/10192 +f 10191/1/10191 10192/1/10192 10190/1/10190 +f 10191/1/10191 10190/1/10190 10189/1/10189 +f 10189/1/10189 10184/1/10184 10191/1/10191 +f 10189/1/10189 10188/1/10188 10184/1/10184 +f 10184/1/10184 10188/1/10188 10183/1/10183 +f 10188/1/10188 10190/1/10190 10183/1/10183 +f 10189/1/10189 10190/1/10190 10188/1/10188 +f 10183/1/10183 10190/1/10190 10192/1/10192 +f 10184/1/10184 10183/1/10183 10180/1/10180 +f 10191/1/10191 10184/1/10184 10180/1/10180 +f 10193/1/10193 10194/1/10194 10191/1/10191 +f 10193/1/10193 10203/1/10203 10215/1/10215 +f 10182/1/10182 10207/1/10207 10179/1/10179 +f 10203/1/10203 10204/1/10204 10201/1/10201 +f 10209/1/10209 10208/1/10208 10207/1/10207 +f 10181/1/10181 10204/1/10204 10185/1/10185 +f 10182/1/10182 10181/1/10181 10185/1/10185 +f 10182/1/10182 10209/1/10209 10207/1/10207 +f 10152/1/10152 10154/1/10154 10186/1/10186 +f 10209/1/10209 10169/1/10169 10208/1/10208 +f 10160/1/10160 10173/1/10173 10154/1/10154 +f 10161/1/10161 10160/1/10160 10154/1/10154 +f 10159/1/10159 10160/1/10160 10161/1/10161 +f 10159/1/10159 10158/1/10158 10160/1/10160 +f 10157/1/10157 10158/1/10158 10159/1/10159 +f 10175/1/10175 10157/1/10157 10159/1/10159 +f 10175/1/10175 10159/1/10159 10176/1/10176 +f 10174/1/10174 10157/1/10157 10175/1/10175 +f 10173/1/10173 10174/1/10174 10175/1/10175 +f 10173/1/10173 10158/1/10158 10174/1/10174 +f 10174/1/10174 10158/1/10158 10157/1/10157 +f 10173/1/10173 10160/1/10160 10158/1/10158 +f 10175/1/10175 10176/1/10176 10173/1/10173 +f 10176/1/10176 10159/1/10159 10161/1/10161 +f 10169/1/10169 10177/1/10177 10178/1/10178 +f 10169/1/10169 10178/1/10178 10171/1/10171 +f 10161/1/10161 10154/1/10154 10162/1/10162 +f 10154/1/10154 10156/1/10156 10104/1/10104 +f 10104/1/10104 10127/1/10127 10129/1/10129 +f 10155/1/10155 10130/1/10130 10171/1/10171 +f 10127/1/10127 10128/1/10128 10129/1/10129 +f 10103/1/10103 10171/1/10171 10130/1/10130 +f 10101/1/10101 10102/1/10102 10103/1/10103 +f 10126/1/10126 10099/1/10099 10128/1/10128 +f 10101/1/10101 10100/1/10100 10102/1/10102 +f 10097/1/10097 10098/1/10098 10099/1/10099 +f 10100/1/10100 10105/1/10105 10119/1/10119 +f 10095/1/10095 10094/1/10094 10098/1/10098 +f 10105/1/10105 10077/1/10077 10106/1/10106 +f 10091/1/10091 10068/1/10068 10094/1/10094 +f 10077/1/10077 10076/1/10076 10078/1/10078 +f 10093/1/10093 10076/1/10076 10067/1/10067 +f 10089/1/10089 10092/1/10092 10093/1/10093 +f 10082/1/10082 10065/1/10065 10089/1/10089 +f 10082/1/10082 10069/1/10069 10065/1/10065 +f 10081/1/10081 10069/1/10069 10082/1/10082 +f 10081/1/10081 10071/1/10071 10069/1/10069 +f 10069/1/10069 10071/1/10071 10070/1/10070 +f 10066/1/10066 10069/1/10069 10070/1/10070 +f 10070/1/10070 10071/1/10071 10072/1/10072 +f 10070/1/10070 10072/1/10072 10073/1/10073 +f 10073/1/10073 10084/1/10084 10070/1/10070 +f 10070/1/10070 10084/1/10084 10080/1/10080 +f 10081/1/10081 10080/1/10080 10084/1/10084 +f 10086/1/10086 10081/1/10081 10084/1/10084 +f 10086/1/10086 10084/1/10084 10087/1/10087 +f 10087/1/10087 10072/1/10072 10086/1/10086 +f 10086/1/10086 10072/1/10072 10085/1/10085 +f 10087/1/10087 10074/1/10074 10072/1/10072 +f 10072/1/10072 10074/1/10074 10075/1/10075 +f 10088/1/10088 10075/1/10075 10074/1/10074 +f 10084/1/10084 10075/1/10075 10088/1/10088 +f 10088/1/10088 10074/1/10074 10087/1/10087 +f 10087/1/10087 10084/1/10084 10088/1/10088 +f 10085/1/10085 10081/1/10081 10086/1/10086 +f 10084/1/10084 10073/1/10073 10075/1/10075 +f 10073/1/10073 10072/1/10072 10075/1/10075 +f 10085/1/10085 10072/1/10072 10071/1/10071 +f 10085/1/10085 10071/1/10071 10081/1/10081 +f 10080/1/10080 10081/1/10081 10082/1/10082 +f 10080/1/10080 10066/1/10066 10070/1/10070 +f 10090/1/10090 10063/1/10063 10083/1/10083 +f 10066/1/10066 10065/1/10065 10069/1/10069 +f 10089/1/10089 10065/1/10065 10064/1/10064 +f 10068/1/10068 10064/1/10064 10063/1/10063 +# 20456 faces, 5 coords texture + +# End of File From d8c430abf61c2537720270603796b368f00642d2 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 27 Nov 2018 17:54:53 +0100 Subject: [PATCH 0523/1292] Fix typing --- cura/CuraActions.py | 14 ++++++++------ cura/PrintInformation.py | 7 +++---- .../PostProcessingPlugin/PostProcessingPlugin.py | 4 ++-- plugins/USBPrinting/AutoDetectBaudJob.py | 11 ++++++----- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/cura/CuraActions.py b/cura/CuraActions.py index 93a18318df..49f7e740a9 100644 --- a/cura/CuraActions.py +++ b/cura/CuraActions.py @@ -3,7 +3,7 @@ from PyQt5.QtCore import QObject, QUrl from PyQt5.QtGui import QDesktopServices -from typing import List, TYPE_CHECKING +from typing import List, TYPE_CHECKING, cast from UM.Event import CallFunctionEvent from UM.FlameProfiler import pyqtSlot @@ -61,8 +61,10 @@ class CuraActions(QObject): operation = GroupedOperation() for node in Selection.getAllSelectedObjects(): current_node = node - while current_node.getParent() and current_node.getParent().callDecoration("isGroup"): - current_node = current_node.getParent() + parent_node = current_node.getParent() + while parent_node and parent_node.callDecoration("isGroup"): + current_node = parent_node + parent_node = current_node.getParent() # This was formerly done with SetTransformOperation but because of # unpredictable matrix deconstruction it was possible that mirrors @@ -150,13 +152,13 @@ class CuraActions(QObject): root = cura.CuraApplication.CuraApplication.getInstance().getController().getScene().getRoot() - nodes_to_change = [] + nodes_to_change = [] # type: List[SceneNode] for node in Selection.getAllSelectedObjects(): parent_node = node # Find the parent node to change instead while parent_node.getParent() != root: - parent_node = parent_node.getParent() + parent_node = cast(SceneNode, parent_node.getParent()) - for single_node in BreadthFirstIterator(parent_node): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax. + for single_node in BreadthFirstIterator(parent_node): # type: ignore #Ignore type error because iter() should get called automatically by Python syntax. nodes_to_change.append(single_node) if not nodes_to_change: diff --git a/cura/PrintInformation.py b/cura/PrintInformation.py index e11f70a54c..22c3eb1734 100644 --- a/cura/PrintInformation.py +++ b/cura/PrintInformation.py @@ -14,8 +14,7 @@ from UM.Logger import Logger from UM.Qt.Duration import Duration from UM.Scene.SceneNode import SceneNode from UM.i18n import i18nCatalog -from UM.MimeTypeDatabase import MimeTypeDatabase - +from UM.MimeTypeDatabase import MimeTypeDatabase, MimeTypeNotFoundError from typing import TYPE_CHECKING @@ -361,7 +360,7 @@ class PrintInformation(QObject): try: mime_type = MimeTypeDatabase.getMimeTypeForFile(name) data = mime_type.stripExtension(name) - except: + except MimeTypeNotFoundError: Logger.log("w", "Unsupported Mime Type Database file extension %s", name) if data is not None and check_name is not None: @@ -416,7 +415,7 @@ class PrintInformation(QObject): return ''.join(char for char in unicodedata.normalize('NFD', to_strip) if unicodedata.category(char) != 'Mn') @pyqtSlot(result = "QVariantMap") - def getFeaturePrintTimes(self): + def getFeaturePrintTimes(self) -> Dict[str, Duration]: result = {} if self._active_build_plate not in self._print_times_per_feature: self._initPrintTimesPerFeature(self._active_build_plate) diff --git a/plugins/PostProcessingPlugin/PostProcessingPlugin.py b/plugins/PostProcessingPlugin/PostProcessingPlugin.py index 11ee610bec..78f9cc0516 100644 --- a/plugins/PostProcessingPlugin/PostProcessingPlugin.py +++ b/plugins/PostProcessingPlugin/PostProcessingPlugin.py @@ -55,14 +55,14 @@ class PostProcessingPlugin(QObject, Extension): def selectedScriptDefinitionId(self) -> Optional[str]: try: return self._script_list[self._selected_script_index].getDefinitionId() - except: + except IndexError: return "" @pyqtProperty(str, notify=selectedIndexChanged) def selectedScriptStackId(self) -> Optional[str]: try: return self._script_list[self._selected_script_index].getStackId() - except: + except IndexError: return "" ## Execute all post-processing scripts on the gcode. diff --git a/plugins/USBPrinting/AutoDetectBaudJob.py b/plugins/USBPrinting/AutoDetectBaudJob.py index 8b37c4b29d..6f1af6727a 100644 --- a/plugins/USBPrinting/AutoDetectBaudJob.py +++ b/plugins/USBPrinting/AutoDetectBaudJob.py @@ -3,6 +3,7 @@ from UM.Job import Job from UM.Logger import Logger +from plugins.USBPrinting.avr_isp import ispBase from .avr_isp.stk500v2 import Stk500v2 @@ -14,12 +15,12 @@ from serial import Serial, SerialException # It tries a pre-set list of baud rates. All these baud rates are validated by requesting the temperature a few times # and checking if the results make sense. If getResult() is not None, it was able to find a correct baud rate. class AutoDetectBaudJob(Job): - def __init__(self, serial_port): + def __init__(self, serial_port: int) -> None: super().__init__() self._serial_port = serial_port self._all_baud_rates = [115200, 250000, 230400, 57600, 38400, 19200, 9600] - def run(self): + def run(self) -> None: Logger.log("d", "Auto detect baud rate started.") wait_response_timeouts = [3, 15, 30] wait_bootloader_times = [1.5, 5, 15] @@ -32,7 +33,7 @@ class AutoDetectBaudJob(Job): try: programmer.connect(self._serial_port) serial = programmer.leaveISP() - except: + except ispBase.IspError: programmer.close() for retry in range(tries): @@ -58,7 +59,7 @@ class AutoDetectBaudJob(Job): # We already have a serial connection, just change the baud rate. try: serial.baudrate = baud_rate - except: + except ValueError: continue sleep(wait_bootloader) # Ensure that we are not talking to the boot loader. 1.5 seconds seems to be the magic number successful_responses = 0 @@ -81,5 +82,5 @@ class AutoDetectBaudJob(Job): return serial.write(b"M105\n") - sleep(15) # Give the printer some time to init and try again. + sleep(15) # Give the printer some time to init and try again. self.setResult(None) # Unable to detect the correct baudrate. From c1c5eb221913dd7ce7538ef9d4120f7b69866729 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 28 Nov 2018 09:44:37 +0100 Subject: [PATCH 0524/1292] Rename the properties to quickly identify that they are a boolean Contributes to CURA-5984. --- resources/qml/Toolbar.qml | 8 ++++---- resources/qml/ToolbarButton.qml | 12 ++++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/resources/qml/Toolbar.qml b/resources/qml/Toolbar.qml index 0207c8ec49..d16f949014 100644 --- a/resources/qml/Toolbar.qml +++ b/resources/qml/Toolbar.qml @@ -61,8 +61,8 @@ Item checked: model.active enabled: model.enabled && UM.Selection.hasSelection && UM.Controller.toolsEnabled - topElement: toolsModel.getItem(0).id == model.id - bottomElement: toolsModel.getItem(toolsModel.rowCount() - 1).id == model.id + isTopElement: toolsModel.getItem(0).id == model.id + isBottomElement: toolsModel.getItem(toolsModel.rowCount() - 1).id == model.id toolItem: UM.RecolorImage { @@ -137,8 +137,8 @@ Item delegate: ExtruderButton { extruder: model - topElement: extrudersModel.getItem(0).id == model.id - bottomElement: extrudersModel.getItem(extrudersModel.rowCount() - 1).id == model.id + isTopElement: extrudersModel.getItem(0).id == model.id + isBottomElement: extrudersModel.getItem(extrudersModel.rowCount() - 1).id == model.id } } } diff --git a/resources/qml/ToolbarButton.qml b/resources/qml/ToolbarButton.qml index b5e5aab475..9e81939ba2 100644 --- a/resources/qml/ToolbarButton.qml +++ b/resources/qml/ToolbarButton.qml @@ -12,8 +12,12 @@ Button id: base property alias toolItem: contentItemLoader.sourceComponent - property bool topElement: false - property bool bottomElement: false + + // These two properties indicate whether the toolbar button is at the top of the toolbar column or at the bottom. + // If it is somewhere in the middle, then both has to be false. If there is only one element in the column, then + // both properties have to be set to true. This is used to create a rounded corner. + property bool isTopElement: false + property bool isBottomElement: false hoverEnabled: true @@ -49,7 +53,7 @@ Button top: parent.top } height: parent.radius - color: base.topElement ? "transparent" : parent.color + color: base.isTopElement ? "transparent" : parent.color } Rectangle @@ -62,7 +66,7 @@ Button bottom: parent.bottom } height: parent.radius - color: base.bottomElement ? "transparent" : parent.color + color: base.isBottomElement ? "transparent" : parent.color } Rectangle From bfebb33123f34894887719f114c942485a48b540 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 28 Nov 2018 10:28:16 +0100 Subject: [PATCH 0525/1292] Code style CURA-5984 Co-Authored-By: diegopradogesto --- resources/qml/Toolbar.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Toolbar.qml b/resources/qml/Toolbar.qml index d16f949014..07522dd535 100644 --- a/resources/qml/Toolbar.qml +++ b/resources/qml/Toolbar.qml @@ -66,7 +66,7 @@ Item toolItem: UM.RecolorImage { - source: (UM.Theme.getIcon(model.icon) != "") ? UM.Theme.getIcon(model.icon) : "file:///" + model.location + "/" + model.icon + source: UM.Theme.getIcon(model.icon) != "" ? UM.Theme.getIcon(model.icon) : "file:///" + model.location + "/" + model.icon color: UM.Theme.getColor("toolbar_button_text") sourceSize: UM.Theme.getSize("button_icon") From 454b47e3a0e7c9d50a5e8ebad5933182872f0782 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 28 Nov 2018 10:29:35 +0100 Subject: [PATCH 0526/1292] Change visibility behavior of the rectangle CURA-5984 Co-Authored-By: diegopradogesto --- resources/qml/ToolbarButton.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/qml/ToolbarButton.qml b/resources/qml/ToolbarButton.qml index 9e81939ba2..90e9160d3d 100644 --- a/resources/qml/ToolbarButton.qml +++ b/resources/qml/ToolbarButton.qml @@ -66,7 +66,8 @@ Button bottom: parent.bottom } height: parent.radius - color: base.isBottomElement ? "transparent" : parent.color + color: parent.color + visible: base.isBottomElement } Rectangle From d0da70a7eea8c6991afebc5488e7a2c39fae9ab1 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 28 Nov 2018 10:29:53 +0100 Subject: [PATCH 0527/1292] Change visibility of the rectangle CURA-5984 Co-Authored-By: diegopradogesto --- resources/qml/ToolbarButton.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/qml/ToolbarButton.qml b/resources/qml/ToolbarButton.qml index 90e9160d3d..157c6a34ac 100644 --- a/resources/qml/ToolbarButton.qml +++ b/resources/qml/ToolbarButton.qml @@ -53,7 +53,8 @@ Button top: parent.top } height: parent.radius - color: base.isTopElement ? "transparent" : parent.color + color: parent.color + visible: base.isTopElement } Rectangle From 709750c9e2c4fac776651039ac56055714056276 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 28 Nov 2018 10:39:32 +0100 Subject: [PATCH 0528/1292] Add global quality to the Anycubic i3 Mega Fixes #4876. --- .../quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg | 1 + .../quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg | 1 + .../quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg | 1 + 3 files changed, 3 insertions(+) diff --git a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg index bb47f68574..e94b9f01d1 100644 --- a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg +++ b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg @@ -8,6 +8,7 @@ setting_version = 5 type = quality quality_type = draft weight = 0 +global_quality = True [values] acceleration_enabled = True diff --git a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg index a3ae98deba..c8c4bf9a81 100644 --- a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg +++ b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg @@ -8,6 +8,7 @@ setting_version = 5 type = quality quality_type = high weight = 2 +global_quality = True [values] acceleration_enabled = True diff --git a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg index 13846b9702..399c3ebc55 100644 --- a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg +++ b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg @@ -8,6 +8,7 @@ setting_version = 5 type = quality quality_type = normal weight = 1 +global_quality = True [values] acceleration_enabled = True From 255a7fa1fbf97ea237c1bda9259480732b4e3398 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Wed, 28 Nov 2018 10:45:46 +0100 Subject: [PATCH 0529/1292] Fix binding loop Contributes to CL-1150 --- .../UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml index d1d9bec351..8507c8d2c8 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml @@ -180,12 +180,12 @@ Item verticalCenter: parent.verticalCenter } width: printerImage.width - height: childrenRect.height + height: 60 * screenScaleFactor // TODO: Theme! MonitorPrintJobPreview { anchors.centerIn: parent printJob: base.printer.activePrintJob - size: 60 * screenScaleFactor // TODO: Theme! + size: parent.height } } From bfa2ff5f5ed84a06460f29a79f1b5cd0e1979187 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 28 Nov 2018 10:46:07 +0100 Subject: [PATCH 0530/1292] Invert visibility of bottom & topsquare It got derped. --- resources/qml/ToolbarButton.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/ToolbarButton.qml b/resources/qml/ToolbarButton.qml index 157c6a34ac..adff73fb7c 100644 --- a/resources/qml/ToolbarButton.qml +++ b/resources/qml/ToolbarButton.qml @@ -54,7 +54,7 @@ Button } height: parent.radius color: parent.color - visible: base.isTopElement + visible: !base.isTopElement } Rectangle @@ -68,7 +68,7 @@ Button } height: parent.radius color: parent.color - visible: base.isBottomElement + visible: !base.isBottomElement } Rectangle From d54a1cb41b815831e8b745cc0c03e590d08abc6a Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Wed, 28 Nov 2018 10:46:12 +0100 Subject: [PATCH 0531/1292] Handle null print job more elegantly Contributes to CL-1150 --- .../qml/MonitorPrintJobProgressBar.qml | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml index 6e16d026a1..f70e1175a1 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml @@ -97,16 +97,19 @@ Item id: progressItem; color: { - var state = printJob.state - var inactiveStates = [ - "pausing", - "paused", - "resuming", - "wait_cleanup" - ] - if (inactiveStates.indexOf(state) > -1 && remainingTime > 0) + if (printJob) { - return UM.Theme.getColor("monitor_progress_fill_inactive") + var state = printJob.state + var inactiveStates = [ + "pausing", + "paused", + "resuming", + "wait_cleanup" + ] + if (inactiveStates.indexOf(state) > -1 && remainingTime > 0) + { + return UM.Theme.getColor("monitor_progress_fill_inactive") + } } return "#0a0850" // TODO: Theme! } From 370fa0fd14a9893a09da9a72827221d59a88b8f4 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Wed, 28 Nov 2018 10:46:22 +0100 Subject: [PATCH 0532/1292] Remove old sidebar Contributes to CL-1150 --- plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index 8314b0f089..3b124faf66 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -65,7 +65,6 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): self._received_print_jobs = False # type: bool self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../resources/qml/ClusterMonitorItem.qml") - self._control_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../resources/qml/ClusterControlItem.qml") # See comments about this hack with the clusterPrintersChanged signal self.printersChanged.connect(self.clusterPrintersChanged) From 9029d10ed01dff02a28679935c6f15cb7a87869c Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Wed, 28 Nov 2018 10:47:34 +0100 Subject: [PATCH 0533/1292] Remove debug statement Contributes to CL-1150 --- .../UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml index 8507c8d2c8..975fe12244 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml @@ -56,11 +56,7 @@ Item width: 108 * screenScaleFactor // TODO: Theme! height: 108 * screenScaleFactor // TODO: Theme! fillMode: Image.PreserveAspectFit - source: - { - console.log(printer.type) - return "../png/"+printer.type+".png" - } + source: "../png/" + printer.type + ".png" mipmap: true } From 5ed2acadd09fa062553f0fc4fddd2a79610e1142 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 28 Nov 2018 11:09:34 +0100 Subject: [PATCH 0534/1292] Re-add wizard_progress size I was a bit over enthosiastic deleting it as it was still used for the UMO first run wizard --- resources/themes/cura-light/theme.json | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index d2358e36ff..dfad5cfd17 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -470,6 +470,7 @@ "modal_window_minimum": [60.0, 45], "license_window_minimum": [45, 45], + "wizard_progress": [10.0, 0.0], "message": [30.0, 5.0], "message_close": [1, 1], From d09d8a6ae34f75b3a7a3d6bc0a20add4671c7e9c Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 28 Nov 2018 11:18:36 +0100 Subject: [PATCH 0535/1292] Minor codestyle fixes CURA-5879 --- resources/qml/Menus/ProfileMenu.qml | 17 ++++++++--------- resources/themes/cura-light/theme.json | 2 +- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/resources/qml/Menus/ProfileMenu.qml b/resources/qml/Menus/ProfileMenu.qml index b503b7de85..fd46d2ef72 100644 --- a/resources/qml/Menus/ProfileMenu.qml +++ b/resources/qml/Menus/ProfileMenu.qml @@ -17,22 +17,21 @@ Menu MenuItem { - text: { - var full_text = (model.layer_height != "") ? model.name + " - " + model.layer_height + model.layer_height_unit : model.name; - full_text += model.is_experimental ? " - Experimental" : ""; - return full_text; + text: + { + var full_text = (model.layer_height != "") ? model.name + " - " + model.layer_height + model.layer_height_unit : model.name + full_text += model.is_experimental ? " - Experimental" : "" + return full_text } checkable: true checked: Cura.MachineManager.activeQualityOrQualityChangesName == model.name exclusiveGroup: group - onTriggered: { - Cura.MachineManager.setQualityGroup(model.quality_group) - } + onTriggered: Cura.MachineManager.setQualityGroup(model.quality_group) visible: model.available } - onObjectAdded: menu.insertItem(index, object); - onObjectRemoved: menu.removeItem(object); + onObjectAdded: menu.insertItem(index, object) + onObjectRemoved: menu.removeItem(object) } MenuSeparator diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 25c9a678c1..303383e6a4 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -480,7 +480,7 @@ "toolbox_footer_button": [8.0, 2.5], "toolbox_showcase_spacing": [1.0, 1.0], "toolbox_header_tab": [8.0, 4.0], - "toolbox_detail_header": [1.0, 14.0], + "toolbox_detail_header": [1.0, 14.0],https://github.com/Ultimaker/Cura/pull/4883 "toolbox_detail_tile": [1.0, 8.0], "toolbox_back_column": [6.0, 1.0], "toolbox_back_button": [4.0, 2.0], From d9c3faaae2e78e543cacfb19f8ba295b15540d38 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 28 Nov 2018 11:19:37 +0100 Subject: [PATCH 0536/1292] Codestyle CURA-5879 --- resources/qml/Settings/SettingView.qml | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 5d916aed7c..5d79eef249 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -64,14 +64,18 @@ Item activeFocusOnPress: true menu: ProfileMenu { } - function generateActiveQualityText () { - var result = Cura.MachineManager.activeQualityOrQualityChangesName; - if (Cura.MachineManager.isActiveQualityExperimental) { - result += " (Experimental)"; + function generateActiveQualityText () + { + var result = Cura.MachineManager.activeQualityOrQualityChangesName + if (Cura.MachineManager.isActiveQualityExperimental) + { + result += " (Experimental)" } - if (Cura.MachineManager.isActiveQualitySupported) { - if (Cura.MachineManager.activeQualityLayerHeight > 0) { + if (Cura.MachineManager.isActiveQualitySupported) + { + if (Cura.MachineManager.activeQualityLayerHeight > 0) + { result += " " result += " - " result += Cura.MachineManager.activeQualityLayerHeight + "mm" From c0d1c35a2ba8c20d8988c5e07dfce8eb9cff23ae Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 28 Nov 2018 11:35:48 +0100 Subject: [PATCH 0537/1292] Removed accidental copy paste --- resources/themes/cura-light/theme.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 303383e6a4..25c9a678c1 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -480,7 +480,7 @@ "toolbox_footer_button": [8.0, 2.5], "toolbox_showcase_spacing": [1.0, 1.0], "toolbox_header_tab": [8.0, 4.0], - "toolbox_detail_header": [1.0, 14.0],https://github.com/Ultimaker/Cura/pull/4883 + "toolbox_detail_header": [1.0, 14.0], "toolbox_detail_tile": [1.0, 8.0], "toolbox_back_column": [6.0, 1.0], "toolbox_back_button": [4.0, 2.0], From 0baa4d20b3f426fef2e40123c10c2a779dc28775 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 28 Nov 2018 11:42:54 +0100 Subject: [PATCH 0538/1292] Gracefully handle the case where machine definition is no in the map --- cura/Machines/VariantManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Machines/VariantManager.py b/cura/Machines/VariantManager.py index f6feb70e09..eaaa9fc5f0 100644 --- a/cura/Machines/VariantManager.py +++ b/cura/Machines/VariantManager.py @@ -107,7 +107,7 @@ class VariantManager: break return variant_node - return self._machine_to_variant_dict_map[machine_definition_id].get(variant_type, {}).get(variant_name) + return self._machine_to_variant_dict_map.get(machine_definition_id, {}).get(variant_type, {}).get(variant_name) def getVariantNodes(self, machine: "GlobalStack", variant_type: "VariantType") -> Dict[str, ContainerNode]: machine_definition_id = machine.definition.getId() From 7d42fdf183656e39e1f5a90e8436d5bb6e8d198d Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 28 Nov 2018 11:52:30 +0100 Subject: [PATCH 0539/1292] Add missing typing --- cura/Scene/ConvexHullNode.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/cura/Scene/ConvexHullNode.py b/cura/Scene/ConvexHullNode.py index 4c79c7d5dc..886ed93ad3 100644 --- a/cura/Scene/ConvexHullNode.py +++ b/cura/Scene/ConvexHullNode.py @@ -1,7 +1,10 @@ # Copyright (c) 2015 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +from typing import Optional from UM.Application import Application +from UM.Math.Polygon import Polygon +from UM.Qt.QtApplication import QtApplication from UM.Scene.SceneNode import SceneNode from UM.Resources import Resources from UM.Math.Color import Color @@ -16,7 +19,7 @@ class ConvexHullNode(SceneNode): # location an object uses on the buildplate. This area (or area's in case of one at a time printing) is # then displayed as a transparent shadow. If the adhesion type is set to raft, the area is extruded # to represent the raft as well. - def __init__(self, node, hull, thickness, parent = None): + def __init__(self, node: SceneNode, hull: Optional[Polygon], thickness: float, parent: Optional[SceneNode] = None) -> None: super().__init__(parent) self.setCalculateBoundingBox(False) @@ -25,7 +28,11 @@ class ConvexHullNode(SceneNode): # Color of the drawn convex hull if not Application.getInstance().getIsHeadLess(): - self._color = Color(*Application.getInstance().getTheme().getColor("convex_hull").getRgb()) + theme = QtApplication.getInstance().getTheme() + if theme: + self._color = Color(*theme.getColor("convex_hull").getRgb()) + else: + self._color = Color(0, 0, 0) else: self._color = Color(0, 0, 0) @@ -75,7 +82,7 @@ class ConvexHullNode(SceneNode): return True - def _onNodeDecoratorsChanged(self, node): + def _onNodeDecoratorsChanged(self, node: SceneNode) -> None: convex_hull_head = self._node.callDecoration("getConvexHullHead") if convex_hull_head: convex_hull_head_builder = MeshBuilder() From 14cee32ceccb85ae034c3f9cc5689822a249663c Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Wed, 28 Nov 2018 12:20:09 +0100 Subject: [PATCH 0540/1292] Improve monitor tab temporary scroll bar --- .../resources/qml/ClusterMonitorItem.qml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml b/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml index 6bbc338c17..adf5ea5e1c 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml @@ -52,12 +52,13 @@ Component id: printers anchors { - left: parent.left - right: parent.right + left: queue.left + right: queue.right top: parent.top topMargin: 48 * screenScaleFactor // TODO: Theme! } height: 264 * screenScaleFactor // TODO: Theme! + Row { spacing: 60 * screenScaleFactor // TODO: Theme! @@ -77,13 +78,13 @@ Component Item { id: queue + width: Math.min(834 * screenScaleFactor, maximumWidth) anchors { bottom: parent.bottom - left: parent.left - right: parent.right + horizontalCenter: parent.horizontalCenter top: printers.bottom - topMargin: 48 + topMargin: 48 * screenScaleFactor // TODO: Theme! } Label @@ -134,7 +135,6 @@ Component text: catalog.i18nc("@label link to connect manager", "Manage queue in Cura Connect") } } - MouseArea { @@ -217,7 +217,7 @@ Component } style: UM.Theme.styles.scrollview visible: OutputDevice.receivedPrintJobs - width: Math.min(834 * screenScaleFactor, maximumWidth) + width: parent.width ListView { @@ -244,5 +244,4 @@ Component visible: OutputDevice.activeCameraUrl != "" } } - } From 85b34d60053b5c2c3d2f6cf279d2ecc243c2929b Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 28 Nov 2018 13:07:39 +0100 Subject: [PATCH 0541/1292] Refactor the PrintSetupSelector The file was splitted in several other files to improve readability. There is a new folder called PrintSetupSelector where all those files will be. Contributes to CURA-5941. --- plugins/PrepareStage/PrepareMenu.qml | 1 - resources/qml/PrintSetupSelector.qml | 392 ------------------ .../CustomPrintSetup.qml} | 4 +- .../PrintSetupSelector/PrintSetupSelector.qml | 68 +++ .../PrintSetupSelectorContents.qml | 276 ++++++++++++ .../PrintSetupSelectorHeader.qml | 69 +++ .../RecommendedPrintSetup.qml} | 8 +- 7 files changed, 419 insertions(+), 399 deletions(-) delete mode 100644 resources/qml/PrintSetupSelector.qml rename resources/qml/{SidebarAdvanced.qml => PrintSetupSelector/CustomPrintSetup.qml} (68%) create mode 100644 resources/qml/PrintSetupSelector/PrintSetupSelector.qml create mode 100644 resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml create mode 100644 resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml rename resources/qml/{SidebarSimple.qml => PrintSetupSelector/RecommendedPrintSetup.qml} (99%) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index 10b4262f01..7c01b1f8b0 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -45,7 +45,6 @@ Item Cura.MachineSelector { id: machineSelection - z: openFileButton.z - 1 //Ensure that the tooltip of the open file button stays above the item row. headerCornerSide: Cura.RoundedRectangle.Direction.Left Layout.minimumWidth: UM.Theme.getSize("machine_selector_widget").width Layout.maximumWidth: UM.Theme.getSize("machine_selector_widget").width diff --git a/resources/qml/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector.qml deleted file mode 100644 index 253a13c0f0..0000000000 --- a/resources/qml/PrintSetupSelector.qml +++ /dev/null @@ -1,392 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.7 -import QtQuick.Controls 2.0 -import QtQuick.Layouts 1.3 - -import UM 1.3 as UM -import Cura 1.0 as Cura -import "Menus" -import "Menus/ConfigurationMenu" - -Cura.ExpandableComponent -{ - id: base - - property int currentModeIndex: -1 - property bool hideSettings: PrintInformation.preSliced - - property string enabledText: catalog.i18nc("@label:Should be short", "On") - property string disabledText: catalog.i18nc("@label:Should be short", "Off") - - // This widget doesn't show tooltips by itself. Instead it emits signals so others can do something with it. - signal showTooltip(Item item, point location, string text) - signal hideTooltip() - - implicitWidth: 200 * screenScaleFactor - height: childrenRect.height - iconSource: UM.Theme.getIcon("pencil") - - popupPadding : 0 - popupSpacingY: UM.Theme.getSize("narrow_margin").width - - popupClosePolicy: Popup.CloseOnEscape - - onCurrentModeIndexChanged: UM.Preferences.setValue("cura/active_mode", currentModeIndex) - - Component.onCompleted: - { - popupItemWrapper.width = base.width - } - - UM.I18nCatalog - { - id: catalog - name: "cura" - } - - Timer - { - id: tooltipDelayTimer - interval: 500 - repeat: false - property var item - property string text - - onTriggered: base.showTooltip(base, {x: 0, y: item.y}, text) - } - - headerItem: RowLayout - { - anchors.fill: parent - - IconWithText - { - source: UM.Theme.getIcon("category_layer_height") - text: Cura.MachineManager.activeStack ? Cura.MachineManager.activeQualityOrQualityChangesName + " " + layerHeight.properties.value + "mm" : "" - - UM.SettingPropertyProvider - { - id: layerHeight - containerStack: Cura.MachineManager.activeStack - key: "layer_height" - watchedProperties: ["value"] - } - } - - IconWithText - { - source: UM.Theme.getIcon("category_infill") - text: Cura.MachineManager.activeStack ? parseInt(infillDensity.properties.value) + "%" : "0%" - - UM.SettingPropertyProvider - { - id: infillDensity - containerStack: Cura.MachineManager.activeStack - key: "infill_sparse_density" - watchedProperties: ["value"] - } - } - - IconWithText - { - source: UM.Theme.getIcon("category_support") - text: supportEnabled.properties.value == "True" ? enabledText : disabledText - - - UM.SettingPropertyProvider - { - id: supportEnabled - containerStack: Cura.MachineManager.activeMachine - key: "support_enable" - watchedProperties: ["value"] - } - } - - IconWithText - { - source: UM.Theme.getIcon("category_adhesion") - text: platformAdhesionType.properties.value != "skirt" && platformAdhesionType.properties.value != "none" ? enabledText : disabledText - - UM.SettingPropertyProvider - { - id: platformAdhesionType - containerStack: Cura.MachineManager.activeMachine - key: "adhesion_type" - watchedProperties: [ "value"] - } - } - } - - Cura.ExtrudersModel - { - id: extrudersModel - } - - popupItem: Rectangle - { - property var total_height: popupItemHeader.height + popupItemContent.height + footerControll.height + UM.Theme.getSize("narrow_margin").height * 2 - id: popupItemWrapper - height: total_height - - border.width: UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("lining") - - Item - { - id: popupItemHeader - height: 36 - - anchors - { - top: parent.top - right: parent.right - left: parent.left - } - - Label - { - id: popupItemHeaderText - text: catalog.i18nc("@label", "Print settings"); - font: UM.Theme.getFont("default") - renderType: Text.NativeRendering - verticalAlignment: Text.AlignVCenter - color: UM.Theme.getColor("text") - height: parent.height - - anchors - { - topMargin: UM.Theme.getSize("sidebar_margin").height - left: parent.left - leftMargin: UM.Theme.getSize("narrow_margin").height - } - } - - Rectangle - { - width: parent.width - height: UM.Theme.getSize("default_lining").height - anchors.top: popupItemHeaderText.bottom - color: UM.Theme.getColor("action_button_border") - - - } - - Button - { - id: closeButton; - width: UM.Theme.getSize("message_close").width; - height: UM.Theme.getSize("message_close").height; - - anchors - { - right: parent.right; - rightMargin: UM.Theme.getSize("default_margin").width; - top: parent.top; - topMargin: 10 - } - - UM.RecolorImage - { - anchors.fill: parent; - sourceSize.width: width - sourceSize.height: width - color: UM.Theme.getColor("message_text") - source: UM.Theme.getIcon("cross1") - } - - onClicked: base.togglePopup() // Will hide the popup item - - background: Rectangle - { - color: UM.Theme.getColor("message_background") - } - } - } - - Rectangle - { - id: popupItemContent - width: parent.width - height: tabBar.height + sidebarContents.height - anchors - { - top: popupItemHeader.bottom - topMargin: UM.Theme.getSize("narrow_margin").height - right: parent.right - left: parent.left - leftMargin: UM.Theme.getSize("default_margin").width - rightMargin: UM.Theme.getSize("default_margin").width - } - - UM.TabRow - { - id: tabBar - anchors.topMargin: UM.Theme.getSize("default_margin").height - onCurrentIndexChanged: Cura.ExtruderManager.setActiveExtruderIndex(currentIndex) - z: 1 - Repeater - { - model: extrudersModel - delegate: UM.TabRowButton - { - contentItem: Rectangle - { - z: 2 - Cura.ExtruderIcon - { - anchors.horizontalCenter: parent.horizontalCenter - materialColor: model.color - extruderEnabled: model.enabled - width: parent.height - height: parent.height - } - } - - background: Rectangle - { - - width: parent.width - z: 1 - border.width: UM.Theme.getSize("default_lining").width * 2 - border.color: UM.Theme.getColor("action_button_border") - - visible: - { - return index == tabBar.currentIndex - } - - // overlap bottom border - Rectangle - { - width: parent.width - UM.Theme.getSize("default_lining").width * 4 - height: UM.Theme.getSize("default_lining").width * 4 - anchors.bottom: parent.bottom - anchors.bottomMargin: - (UM.Theme.getSize("default_lining").width * 2) - anchors.leftMargin: UM.Theme.getSize("default_lining").width * 2 - anchors.left: parent.left - - } - } - } - } - } - - Rectangle - { - id: sidebarContents - anchors.top: tabBar.bottom - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - height: UM.Theme.getSize("print_setup_widget").height - - border.width: UM.Theme.getSize("default_lining").width * 2 - border.color: UM.Theme.getColor("action_button_border") - - SidebarSimple - { - anchors.topMargin: UM.Theme.getSize("print_setup_content_top_margin").height - anchors.fill: parent - visible: currentModeIndex != 1 - onShowTooltip: base.showTooltip(item, location, text) - onHideTooltip: base.hideTooltip() - } - - SidebarAdvanced - { - anchors.topMargin: UM.Theme.getSize("print_setup_content_top_margin").height - anchors.bottomMargin: 2 //don't overlap bottom border - anchors.fill: parent - visible: currentModeIndex == 1 - onShowTooltip: base.showTooltip(item, location, text) - onHideTooltip: base.hideTooltip() - } - } - } - - Item - { - id: footerControll - anchors.top: popupItemContent.bottom - anchors.topMargin: UM.Theme.getSize("narrow_margin").height * 2 - width: parent.width - height: settingControlButton.height + UM.Theme.getSize("default_lining").height * 4 - Rectangle - { - width: parent.width - height: UM.Theme.getSize("default_lining").height - color: UM.Theme.getColor("action_button_border") - } - - Cura.ActionButton - { - id: settingControlButton - leftPadding: UM.Theme.getSize("default_margin").width - rightPadding: UM.Theme.getSize("default_margin").width - height: UM.Theme.getSize("action_panel_button").height - text: catalog.i18nc("@button", "Custom") - color: UM.Theme.getColor("secondary") - hoverColor: UM.Theme.getColor("secondary") - textColor: UM.Theme.getColor("primary") - textHoverColor: UM.Theme.getColor("text") - iconSourceRight: UM.Theme.getIcon("arrow_right") - width: UM.Theme.getSize("print_setup_action_button").width - fixedWidthMode: true - visible: currentModeIndex == 0 - anchors - { - top: parent.top - topMargin: UM.Theme.getSize("narrow_margin").height * 2 - bottomMargin: UM.Theme.getSize("narrow_margin").height * 2 - right: parent.right - rightMargin: UM.Theme.getSize("narrow_margin").height - } - - onClicked: currentModeIndex = 1 - } - - Cura.ActionButton - { - height: UM.Theme.getSize("action_panel_button").height - text: catalog.i18nc("@button", "Recommended") - color: UM.Theme.getColor("secondary") - hoverColor: UM.Theme.getColor("secondary") - textColor: UM.Theme.getColor("primary") - textHoverColor: UM.Theme.getColor("text") - iconSource: UM.Theme.getIcon("arrow_left") - width: UM.Theme.getSize("print_setup_action_button").width - fixedWidthMode: true - visible: currentModeIndex == 1 - anchors - { - top: parent.top - topMargin: UM.Theme.getSize("narrow_margin").height * 2 - bottomMargin: UM.Theme.getSize("narrow_margin").height * 2 - left: parent.left - leftMargin: UM.Theme.getSize("narrow_margin").height - } - - MouseArea { - anchors.fill: parent - onClicked: currentModeIndex = 0 - } - } - } - - Component.onCompleted: - { - var index = Math.round(UM.Preferences.getValue("cura/active_mode")) - - if(index != null && !isNaN(index)) - { - currentModeIndex = index - } - else - { - currentModeIndex = 0 - } - } - } -} \ No newline at end of file diff --git a/resources/qml/SidebarAdvanced.qml b/resources/qml/PrintSetupSelector/CustomPrintSetup.qml similarity index 68% rename from resources/qml/SidebarAdvanced.qml rename to resources/qml/PrintSetupSelector/CustomPrintSetup.qml index ff5f545c80..f58695b48f 100644 --- a/resources/qml/SidebarAdvanced.qml +++ b/resources/qml/PrintSetupSelector/CustomPrintSetup.qml @@ -1,10 +1,10 @@ -// Copyright (c) 2015 Ultimaker B.V. +// Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 import QtQuick.Controls 2.0 -import "Settings" +import "../Settings" SettingView { } diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector/PrintSetupSelector.qml new file mode 100644 index 0000000000..c69dd56520 --- /dev/null +++ b/resources/qml/PrintSetupSelector/PrintSetupSelector.qml @@ -0,0 +1,68 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.0 + +import UM 1.3 as UM +import Cura 1.0 as Cura + +Cura.ExpandableComponent +{ + id: base + + property int currentModeIndex: -1 + property bool hideSettings: PrintInformation.preSliced + + property string enabledText: catalog.i18nc("@label:Should be short", "On") + property string disabledText: catalog.i18nc("@label:Should be short", "Off") + + // This widget doesn't show tooltips by itself. Instead it emits signals so others can do something with it. + signal showTooltip(Item item, point location, string text) + signal hideTooltip() + + iconSource: UM.Theme.getIcon("pencil") + popupPadding: UM.Theme.getSize("default_lining").width + popupSpacingY: UM.Theme.getSize("narrow_margin").width + + popupClosePolicy: Popup.CloseOnEscape + + onCurrentModeIndexChanged: UM.Preferences.setValue("cura/active_mode", currentModeIndex) + + Component.onCompleted: + { + popupItemWrapper.width = base.width + } + + UM.I18nCatalog + { + id: catalog + name: "cura" + } + + Timer + { + id: tooltipDelayTimer + interval: 500 + repeat: false + property var item + property string text + + onTriggered: base.showTooltip(base, {x: 0, y: item.y}, text) + } + + headerItem: PrintSetupSelectorHeader + { + anchors.fill: parent + } + + Cura.ExtrudersModel + { + id: extrudersModel + } + + popupItem: PrintSetupSelectorContents + { + + } +} \ No newline at end of file diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml new file mode 100644 index 0000000000..e7b3b94b11 --- /dev/null +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml @@ -0,0 +1,276 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.3 +import QtQuick.Layouts 1.3 + +import UM 1.3 as UM +import Cura 1.0 as Cura + +Rectangle +{ + property var total_height: popupItemHeader.height + popupItemContent.height + footerControll.height + UM.Theme.getSize("narrow_margin").height * 2 + id: popupItemWrapper + height: total_height + + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("lining") + + Item + { + id: popupItemHeader + height: 36 + + anchors + { + top: parent.top + right: parent.right + left: parent.left + } + + Label + { + id: popupItemHeaderText + text: catalog.i18nc("@label", "Print settings"); + font: UM.Theme.getFont("default") + renderType: Text.NativeRendering + verticalAlignment: Text.AlignVCenter + color: UM.Theme.getColor("text") + height: parent.height + + anchors + { + topMargin: UM.Theme.getSize("sidebar_margin").height + left: parent.left + leftMargin: UM.Theme.getSize("narrow_margin").height + } + } + + Rectangle + { + width: parent.width + height: UM.Theme.getSize("default_lining").height + anchors.top: popupItemHeaderText.bottom + color: UM.Theme.getColor("action_button_border") + + + } + + Button + { + id: closeButton; + width: UM.Theme.getSize("message_close").width; + height: UM.Theme.getSize("message_close").height; + + anchors + { + right: parent.right; + rightMargin: UM.Theme.getSize("default_margin").width; + top: parent.top; + topMargin: 10 + } + + UM.RecolorImage + { + anchors.fill: parent; + sourceSize.width: width + sourceSize.height: width + color: UM.Theme.getColor("message_text") + source: UM.Theme.getIcon("cross1") + } + + onClicked: base.togglePopup() // Will hide the popup item + + background: Rectangle + { + color: UM.Theme.getColor("message_background") + } + } + } + + Rectangle + { + id: popupItemContent + width: parent.width + height: tabBar.height + sidebarContents.height + + anchors + { + top: popupItemHeader.bottom + topMargin: UM.Theme.getSize("narrow_margin").height + right: parent.right + left: parent.left + leftMargin: UM.Theme.getSize("default_margin").width + rightMargin: UM.Theme.getSize("default_margin").width + } + + UM.TabRow + { + id: tabBar + anchors.topMargin: UM.Theme.getSize("default_margin").height + onCurrentIndexChanged: Cura.ExtruderManager.setActiveExtruderIndex(currentIndex) + z: 1 + Repeater + { + model: extrudersModel + delegate: UM.TabRowButton + { + contentItem: Rectangle + { + z: 2 + Cura.ExtruderIcon + { + anchors.horizontalCenter: parent.horizontalCenter + materialColor: model.color + extruderEnabled: model.enabled + width: parent.height + height: parent.height + } + } + + background: Rectangle + { + + width: parent.width + z: 1 + border.width: UM.Theme.getSize("default_lining").width * 2 + border.color: UM.Theme.getColor("action_button_border") + + visible: + { + return index == tabBar.currentIndex + } + + // overlap bottom border + Rectangle + { + width: parent.width - UM.Theme.getSize("default_lining").width * 4 + height: UM.Theme.getSize("default_lining").width * 4 + anchors.bottom: parent.bottom + anchors.bottomMargin: - (UM.Theme.getSize("default_lining").width * 2) + anchors.leftMargin: UM.Theme.getSize("default_lining").width * 2 + anchors.left: parent.left + + } + } + } + } + } + + Rectangle + { + id: sidebarContents + anchors.top: tabBar.bottom + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + height: UM.Theme.getSize("print_setup_widget").height + + border.width: UM.Theme.getSize("default_lining").width * 2 + border.color: UM.Theme.getColor("action_button_border") + + RecommendedPrintSetup + { + anchors.topMargin: UM.Theme.getSize("print_setup_content_top_margin").height + anchors.fill: parent + visible: currentModeIndex != 1 + onShowTooltip: base.showTooltip(item, location, text) + onHideTooltip: base.hideTooltip() + } + + CustomPrintSetup + { + anchors.topMargin: UM.Theme.getSize("print_setup_content_top_margin").height + anchors.bottomMargin: 2 //don't overlap bottom border + anchors.fill: parent + visible: currentModeIndex == 1 + onShowTooltip: base.showTooltip(item, location, text) + onHideTooltip: base.hideTooltip() + } + } + } + + Item + { + id: footerControll + anchors.top: popupItemContent.bottom + anchors.topMargin: UM.Theme.getSize("narrow_margin").height * 2 + width: parent.width + height: settingControlButton.height + UM.Theme.getSize("default_lining").height * 4 + Rectangle + { + width: parent.width + height: UM.Theme.getSize("default_lining").height + color: UM.Theme.getColor("action_button_border") + } + + Cura.ActionButton + { + id: settingControlButton + leftPadding: UM.Theme.getSize("default_margin").width + rightPadding: UM.Theme.getSize("default_margin").width + height: UM.Theme.getSize("action_panel_button").height + text: catalog.i18nc("@button", "Custom") + color: UM.Theme.getColor("secondary") + hoverColor: UM.Theme.getColor("secondary") + textColor: UM.Theme.getColor("primary") + textHoverColor: UM.Theme.getColor("text") + iconSourceRight: UM.Theme.getIcon("arrow_right") + width: UM.Theme.getSize("print_setup_action_button").width + fixedWidthMode: true + visible: currentModeIndex == 0 + anchors + { + top: parent.top + topMargin: UM.Theme.getSize("narrow_margin").height * 2 + bottomMargin: UM.Theme.getSize("narrow_margin").height * 2 + right: parent.right + rightMargin: UM.Theme.getSize("narrow_margin").height + } + + onClicked: currentModeIndex = 1 + } + + Cura.ActionButton + { + height: UM.Theme.getSize("action_panel_button").height + text: catalog.i18nc("@button", "Recommended") + color: UM.Theme.getColor("secondary") + hoverColor: UM.Theme.getColor("secondary") + textColor: UM.Theme.getColor("primary") + textHoverColor: UM.Theme.getColor("text") + iconSource: UM.Theme.getIcon("arrow_left") + width: UM.Theme.getSize("print_setup_action_button").width + fixedWidthMode: true + visible: currentModeIndex == 1 + anchors + { + top: parent.top + topMargin: UM.Theme.getSize("narrow_margin").height * 2 + bottomMargin: UM.Theme.getSize("narrow_margin").height * 2 + left: parent.left + leftMargin: UM.Theme.getSize("narrow_margin").height + } + + MouseArea { + anchors.fill: parent + onClicked: currentModeIndex = 0 + } + } + } + + Component.onCompleted: + { + var index = Math.round(UM.Preferences.getValue("cura/active_mode")) + + if(index != null && !isNaN(index)) + { + currentModeIndex = index + } + else + { + currentModeIndex = 0 + } + } +} \ No newline at end of file diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml new file mode 100644 index 0000000000..f8fb246085 --- /dev/null +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml @@ -0,0 +1,69 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.3 +import QtQuick.Layouts 1.3 + +import UM 1.3 as UM +import Cura 1.0 as Cura + +RowLayout +{ + Cura.IconLabel + { + source: UM.Theme.getIcon("category_layer_height") + text: Cura.MachineManager.activeStack ? Cura.MachineManager.activeQualityOrQualityChangesName + " " + layerHeight.properties.value + "mm" : "" + + UM.SettingPropertyProvider + { + id: layerHeight + containerStack: Cura.MachineManager.activeStack + key: "layer_height" + watchedProperties: ["value"] + } + } + + Cura.IconLabel + { + source: UM.Theme.getIcon("category_infill") + text: Cura.MachineManager.activeStack ? parseInt(infillDensity.properties.value) + "%" : "0%" + + UM.SettingPropertyProvider + { + id: infillDensity + containerStack: Cura.MachineManager.activeStack + key: "infill_sparse_density" + watchedProperties: ["value"] + } + } + + Cura.IconLabel + { + source: UM.Theme.getIcon("category_support") + text: supportEnabled.properties.value == "True" ? enabledText : disabledText + + + UM.SettingPropertyProvider + { + id: supportEnabled + containerStack: Cura.MachineManager.activeMachine + key: "support_enable" + watchedProperties: ["value"] + } + } + + Cura.IconLabel + { + source: UM.Theme.getIcon("category_adhesion") + text: platformAdhesionType.properties.value != "skirt" && platformAdhesionType.properties.value != "none" ? enabledText : disabledText + + UM.SettingPropertyProvider + { + id: platformAdhesionType + containerStack: Cura.MachineManager.activeMachine + key: "adhesion_type" + watchedProperties: [ "value"] + } + } +} \ No newline at end of file diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/PrintSetupSelector/RecommendedPrintSetup.qml similarity index 99% rename from resources/qml/SidebarSimple.qml rename to resources/qml/PrintSetupSelector/RecommendedPrintSetup.qml index f2e998f526..a11eae3218 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/PrintSetupSelector/RecommendedPrintSetup.qml @@ -188,7 +188,7 @@ Item } } - IconWithText + Cura.IconLabel { id: qualityRowTitle source: UM.Theme.getIcon("category_layer_height") @@ -496,7 +496,7 @@ Item width: Math.round(UM.Theme.getSize("print_setup_widget").width * .45) - UM.Theme.getSize("thick_margin").width - IconWithText + Cura.IconLabel { id: infillLabel source: UM.Theme.getIcon("category_infill") @@ -818,7 +818,7 @@ Item // // Enable support // - IconWithText + Cura.IconLabel { id: enableSupportLabel visible: enableSupportCheckBox.visible @@ -942,7 +942,7 @@ Item } - IconWithText + Cura.IconLabel { id: adhesionHelperLabel visible: adhesionCheckBox.visible From 0fdaebaaf83b3d34d94995dd628e246f63c8322c Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Wed, 28 Nov 2018 13:51:54 +0100 Subject: [PATCH 0542/1292] Updated action button CURA-5941 --- resources/qml/ActionButton.qml | 50 +++++++++++----------------- resources/qml/PrintSetupSelector.qml | 24 +++++++------ 2 files changed, 33 insertions(+), 41 deletions(-) diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index 732858c67f..e754365033 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -1,22 +1,17 @@ // Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. - import QtQuick 2.7 import QtQuick.Controls 2.1 - import QtGraphicalEffects 1.0 // For the dropshadow - import UM 1.1 as UM - Button { id: button - property alias iconSource: buttonIcon.source - property alias iconSourceRight: buttonIconRight.source + property alias iconSource: buttonIconLeft.source + property var iconOnRightSide: false property alias textFont: buttonText.font property alias cornerRadius: backgroundRect.radius property alias tooltip: tooltip.text - property color color: UM.Theme.getColor("primary") property color hoverColor: UM.Theme.getColor("primary_hover") property color disabledColor: color @@ -26,33 +21,31 @@ Button property color outlineColor: color property color outlineHoverColor: hoverColor property color outlineDisabledColor: outlineColor - hoverEnabled: true - property alias shadowColor: shadow.color property alias shadowEnabled: shadow.visible - // This property is used to indicate whether the button has a fixed width or the width would depend on the contents // Be careful when using fixedWidthMode, the translated texts can be too long that they won't fit. In any case, // we elide the text to the right so the text will be cut off with the three dots at the end. property var fixedWidthMode: false - - width: buttonIcon.width + buttonText.width + buttonIconRight.width - contentItem: Item + leftPadding: UM.Theme.getSize("default_margin").width + rightPadding: UM.Theme.getSize("default_margin").width + height: UM.Theme.getSize("action_button").height + contentItem: Row { + //Icon if displayed on the left side. UM.RecolorImage { - id: buttonIcon + id: buttonIconLeft source: "" - height: Math.round(0.6 * parent.height) - width: height + height: buttonText.height + width: visible ? height : 0 sourceSize.width: width sourceSize.height: height color: button.hovered ? button.textHoverColor : button.textColor - visible: source != "" + visible: source != "" && !button.iconOnRightSide anchors.verticalCenter: parent.verticalCenter } - Label { id: buttonText @@ -66,22 +59,21 @@ Button horizontalAlignment: Text.AlignHCenter elide: Text.ElideRight } - + //Icon if displayed on the right side. UM.RecolorImage { id: buttonIconRight - source: "" - height: Math.round(0.6 * parent.height) - width: height + source: buttonIconLeft.source + anchors.right: parent.right + height: buttonText.height + width: visible ? height : 0 sourceSize.width: width sourceSize.height: height - color: button.hovered ? button.textHoverColor : button.textColor - visible: source != "" - anchors.verticalCenter: parent.verticalCenter - anchors.right: source != "" ? parent.right : undefined + color: buttonIconLeft.color + visible: source != "" && button.iconOnRightSide + anchors.verticalCenter: buttonIconLeft.verticalCenter } } - background: Rectangle { id: backgroundRect @@ -90,7 +82,6 @@ Button border.width: UM.Theme.getSize("default_lining").width border.color: button.enabled ? (button.hovered ? button.outlineHoverColor : button.outlineColor) : button.outlineDisabledColor } - DropShadow { id: shadow @@ -103,7 +94,6 @@ Button // Should always be drawn behind the background. z: backgroundRect.z - 1 } - ToolTip { id: tooltip @@ -111,4 +101,4 @@ Button delay: 500 visible: text != "" && button.hovered } -} +} \ No newline at end of file diff --git a/resources/qml/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector.qml index 253a13c0f0..85472bae8d 100644 --- a/resources/qml/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector.qml @@ -323,18 +323,9 @@ Cura.ExpandableComponent Cura.ActionButton { id: settingControlButton - leftPadding: UM.Theme.getSize("default_margin").width - rightPadding: UM.Theme.getSize("default_margin").width - height: UM.Theme.getSize("action_panel_button").height - text: catalog.i18nc("@button", "Custom") - color: UM.Theme.getColor("secondary") - hoverColor: UM.Theme.getColor("secondary") - textColor: UM.Theme.getColor("primary") - textHoverColor: UM.Theme.getColor("text") - iconSourceRight: UM.Theme.getIcon("arrow_right") - width: UM.Theme.getSize("print_setup_action_button").width - fixedWidthMode: true visible: currentModeIndex == 0 + text: catalog.i18nc("@button", "Custom") + width: UM.Theme.getSize("print_setup_action_button").width anchors { top: parent.top @@ -344,6 +335,13 @@ Cura.ExpandableComponent rightMargin: UM.Theme.getSize("narrow_margin").height } + color: UM.Theme.getColor("secondary") + hoverColor: UM.Theme.getColor("secondary") + textColor: UM.Theme.getColor("primary") + textHoverColor: UM.Theme.getColor("text") + iconSource: UM.Theme.getIcon("arrow_right") + iconOnRightSide: true + onClicked: currentModeIndex = 1 } @@ -351,13 +349,17 @@ Cura.ExpandableComponent { height: UM.Theme.getSize("action_panel_button").height text: catalog.i18nc("@button", "Recommended") + color: UM.Theme.getColor("secondary") hoverColor: UM.Theme.getColor("secondary") textColor: UM.Theme.getColor("primary") textHoverColor: UM.Theme.getColor("text") + iconSource: UM.Theme.getIcon("arrow_left") + width: UM.Theme.getSize("print_setup_action_button").width fixedWidthMode: true + visible: currentModeIndex == 1 anchors { From 990c653af4eaf11e22dc49a9f9ea1c96d61a43d4 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 28 Nov 2018 17:29:25 +0100 Subject: [PATCH 0543/1292] Refactor the code a bit more to better align the components in the recommended mode. Contributes to CURA-5941. --- resources/qml/ActionButton.qml | 18 +- resources/qml/ExpandableComponent.qml | 2 +- resources/qml/IconLabel.qml | 5 +- .../PrintSetupSelector/PrintSetupSelector.qml | 13 +- .../PrintSetupSelectorContents.qml | 294 +-- .../PrintSetupSelectorHeader.qml | 8 +- .../RecommendedPrintSetup.qml | 2034 ++++++++--------- resources/qml/qmldir | 1 + resources/themes/cura-light/theme.json | 1 + 9 files changed, 1134 insertions(+), 1242 deletions(-) diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index 732858c67f..b9a04f3b46 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -12,7 +12,6 @@ Button { id: button property alias iconSource: buttonIcon.source - property alias iconSourceRight: buttonIconRight.source property alias textFont: buttonText.font property alias cornerRadius: backgroundRect.radius property alias tooltip: tooltip.text @@ -37,8 +36,7 @@ Button // we elide the text to the right so the text will be cut off with the three dots at the end. property var fixedWidthMode: false - width: buttonIcon.width + buttonText.width + buttonIconRight.width - contentItem: Item + contentItem: Row { UM.RecolorImage { @@ -66,20 +64,6 @@ Button horizontalAlignment: Text.AlignHCenter elide: Text.ElideRight } - - UM.RecolorImage - { - id: buttonIconRight - source: "" - height: Math.round(0.6 * parent.height) - width: height - sourceSize.width: width - sourceSize.height: height - color: button.hovered ? button.textHoverColor : button.textColor - visible: source != "" - anchors.verticalCenter: parent.verticalCenter - anchors.right: source != "" ? parent.right : undefined - } } background: Rectangle diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index 897d44d941..0c3a8f80b9 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -74,7 +74,7 @@ Item function togglePopup() { - if(popup.visible) + if (popup.visible) { popup.close() } diff --git a/resources/qml/IconLabel.qml b/resources/qml/IconLabel.qml index 0941254e7b..ee4a1254ec 100644 --- a/resources/qml/IconLabel.qml +++ b/resources/qml/IconLabel.qml @@ -2,8 +2,7 @@ // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.3 +import QtQuick.Controls 2.3 import UM 1.1 as UM @@ -48,7 +47,7 @@ Item text: "Empty label" elide: Text.ElideRight color: UM.Theme.getColor("text") - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") renderType: Text.NativeRendering } } \ No newline at end of file diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector/PrintSetupSelector.qml index c69dd56520..1794a54cdf 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelector.qml @@ -11,7 +11,6 @@ Cura.ExpandableComponent { id: base - property int currentModeIndex: -1 property bool hideSettings: PrintInformation.preSliced property string enabledText: catalog.i18nc("@label:Should be short", "On") @@ -27,13 +26,6 @@ Cura.ExpandableComponent popupClosePolicy: Popup.CloseOnEscape - onCurrentModeIndexChanged: UM.Preferences.setValue("cura/active_mode", currentModeIndex) - - Component.onCompleted: - { - popupItemWrapper.width = base.width - } - UM.I18nCatalog { id: catalog @@ -61,8 +53,5 @@ Cura.ExpandableComponent id: extrudersModel } - popupItem: PrintSetupSelectorContents - { - - } + popupItem: PrintSetupSelectorContents {} } \ No newline at end of file diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml index e7b3b94b11..c36a0fbb80 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml @@ -3,24 +3,26 @@ import QtQuick 2.7 import QtQuick.Controls 2.3 -import QtQuick.Layouts 1.3 import UM 1.3 as UM import Cura 1.0 as Cura -Rectangle +Item { - property var total_height: popupItemHeader.height + popupItemContent.height + footerControll.height + UM.Theme.getSize("narrow_margin").height * 2 - id: popupItemWrapper - height: total_height + id: popup - border.width: UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("lining") + width: UM.Theme.getSize("print_setup_widget").width + height: childrenRect.height - Item + property int currentModeIndex: -1 + onCurrentModeIndexChanged: UM.Preferences.setValue("cura/active_mode", currentModeIndex) + + // Header of the popup + Rectangle { - id: popupItemHeader - height: 36 + id: header + height: UM.Theme.getSize("print_setup_widget_header").height + color: UM.Theme.getColor("action_button_hovered") // TODO: It's not clear the color that we need to use here anchors { @@ -31,8 +33,8 @@ Rectangle Label { - id: popupItemHeaderText - text: catalog.i18nc("@label", "Print settings"); + id: headerLabel + text: catalog.i18nc("@label", "Print settings") font: UM.Theme.getFont("default") renderType: Text.NativeRendering verticalAlignment: Text.AlignVCenter @@ -47,221 +49,153 @@ Rectangle } } - Rectangle - { - width: parent.width - height: UM.Theme.getSize("default_lining").height - anchors.top: popupItemHeaderText.bottom - color: UM.Theme.getColor("action_button_border") - - - } - Button { - id: closeButton; - width: UM.Theme.getSize("message_close").width; - height: UM.Theme.getSize("message_close").height; + id: closeButton + width: UM.Theme.getSize("message_close").width + height: UM.Theme.getSize("message_close").height anchors { - right: parent.right; - rightMargin: UM.Theme.getSize("default_margin").width; - top: parent.top; - topMargin: 10 + right: parent.right + rightMargin: UM.Theme.getSize("default_margin").width + verticalCenter: parent.verticalCenter } - UM.RecolorImage + contentItem: UM.RecolorImage { - anchors.fill: parent; + anchors.fill: parent sourceSize.width: width sourceSize.height: width color: UM.Theme.getColor("message_text") source: UM.Theme.getIcon("cross1") } - onClicked: base.togglePopup() // Will hide the popup item + background: Item {} - background: Rectangle - { - color: UM.Theme.getColor("message_background") - } + onClicked: togglePopup() // Will hide the popup item } } Rectangle { - id: popupItemContent - width: parent.width - height: tabBar.height + sidebarContents.height + id: topSeparator + anchors.bottom: header.bottom + width: parent.width + height: UM.Theme.getSize("default_lining").height + color: UM.Theme.getColor("lining") + } + + Loader + { + id: loader + width: parent.width anchors { - top: popupItemHeader.bottom - topMargin: UM.Theme.getSize("narrow_margin").height - right: parent.right - left: parent.left + top: header.bottom leftMargin: UM.Theme.getSize("default_margin").width rightMargin: UM.Theme.getSize("default_margin").width } + sourceComponent: currentModeIndex == 0 ? recommendedPrintSetup : customPrintSetup + } - UM.TabRow - { - id: tabBar - anchors.topMargin: UM.Theme.getSize("default_margin").height - onCurrentIndexChanged: Cura.ExtruderManager.setActiveExtruderIndex(currentIndex) - z: 1 - Repeater - { - model: extrudersModel - delegate: UM.TabRowButton - { - contentItem: Rectangle - { - z: 2 - Cura.ExtruderIcon - { - anchors.horizontalCenter: parent.horizontalCenter - materialColor: model.color - extruderEnabled: model.enabled - width: parent.height - height: parent.height - } - } +// Item +// { +// id: content +// width: parent.width +// height: 100 +////// height: tabBar.height + sidebarContents.height +//// +// anchors +// { +// top: header.bottom +// leftMargin: UM.Theme.getSize("default_margin").width +// rightMargin: UM.Theme.getSize("default_margin").width +// } +//// +//// Rectangle +//// { +//// id: sidebarContents +//// anchors.top: tabBar.bottom +//// anchors.bottom: parent.bottom +//// anchors.left: parent.left +//// anchors.right: parent.right +//// height: UM.Theme.getSize("print_setup_widget").height +//// +//// border.width: UM.Theme.getSize("default_lining").width * 2 +//// border.color: UM.Theme.getColor("action_button_border") +//// } +// } - background: Rectangle - { + Rectangle + { + id: buttonsSeparator - width: parent.width - z: 1 - border.width: UM.Theme.getSize("default_lining").width * 2 - border.color: UM.Theme.getColor("action_button_border") - - visible: - { - return index == tabBar.currentIndex - } - - // overlap bottom border - Rectangle - { - width: parent.width - UM.Theme.getSize("default_lining").width * 4 - height: UM.Theme.getSize("default_lining").width * 4 - anchors.bottom: parent.bottom - anchors.bottomMargin: - (UM.Theme.getSize("default_lining").width * 2) - anchors.leftMargin: UM.Theme.getSize("default_lining").width * 2 - anchors.left: parent.left - - } - } - } - } - } - - Rectangle - { - id: sidebarContents - anchors.top: tabBar.bottom - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - height: UM.Theme.getSize("print_setup_widget").height - - border.width: UM.Theme.getSize("default_lining").width * 2 - border.color: UM.Theme.getColor("action_button_border") - - RecommendedPrintSetup - { - anchors.topMargin: UM.Theme.getSize("print_setup_content_top_margin").height - anchors.fill: parent - visible: currentModeIndex != 1 - onShowTooltip: base.showTooltip(item, location, text) - onHideTooltip: base.hideTooltip() - } - - CustomPrintSetup - { - anchors.topMargin: UM.Theme.getSize("print_setup_content_top_margin").height - anchors.bottomMargin: 2 //don't overlap bottom border - anchors.fill: parent - visible: currentModeIndex == 1 - onShowTooltip: base.showTooltip(item, location, text) - onHideTooltip: base.hideTooltip() - } - } + anchors.top: loader.bottom + width: parent.width + height: UM.Theme.getSize("default_lining").height + color: UM.Theme.getColor("lining") } Item { - id: footerControll - anchors.top: popupItemContent.bottom - anchors.topMargin: UM.Theme.getSize("narrow_margin").height * 2 - width: parent.width - height: settingControlButton.height + UM.Theme.getSize("default_lining").height * 4 - Rectangle + id: buttonRow + height: childrenRect.height + + // The buttonsSeparator is inside the buttonRow. This is to avoid some weird behaviours with the scroll bar. + anchors { - width: parent.width - height: UM.Theme.getSize("default_lining").height - color: UM.Theme.getColor("action_button_border") + top: buttonsSeparator.top + left: parent.left + right: parent.right } - Cura.ActionButton + Cura.SecondaryButton { - id: settingControlButton + anchors.left: parent.left leftPadding: UM.Theme.getSize("default_margin").width rightPadding: UM.Theme.getSize("default_margin").width - height: UM.Theme.getSize("action_panel_button").height - text: catalog.i18nc("@button", "Custom") - color: UM.Theme.getColor("secondary") - hoverColor: UM.Theme.getColor("secondary") - textColor: UM.Theme.getColor("primary") - textHoverColor: UM.Theme.getColor("text") - iconSourceRight: UM.Theme.getIcon("arrow_right") - width: UM.Theme.getSize("print_setup_action_button").width - fixedWidthMode: true - visible: currentModeIndex == 0 - anchors - { - top: parent.top - topMargin: UM.Theme.getSize("narrow_margin").height * 2 - bottomMargin: UM.Theme.getSize("narrow_margin").height * 2 - right: parent.right - rightMargin: UM.Theme.getSize("narrow_margin").height - } - - onClicked: currentModeIndex = 1 + text: catalog.i18nc("@button", "Recommended") + visible: currentModeIndex == 1 + onClicked: currentModeIndex = 0 } - Cura.ActionButton + Cura.SecondaryButton { - height: UM.Theme.getSize("action_panel_button").height - text: catalog.i18nc("@button", "Recommended") - color: UM.Theme.getColor("secondary") - hoverColor: UM.Theme.getColor("secondary") - textColor: UM.Theme.getColor("primary") - textHoverColor: UM.Theme.getColor("text") - iconSource: UM.Theme.getIcon("arrow_left") - width: UM.Theme.getSize("print_setup_action_button").width - fixedWidthMode: true - visible: currentModeIndex == 1 - anchors - { - top: parent.top - topMargin: UM.Theme.getSize("narrow_margin").height * 2 - bottomMargin: UM.Theme.getSize("narrow_margin").height * 2 - left: parent.left - leftMargin: UM.Theme.getSize("narrow_margin").height - } - - MouseArea { - anchors.fill: parent - onClicked: currentModeIndex = 0 - } + anchors.right: parent.right + leftPadding: UM.Theme.getSize("default_margin").width + rightPadding: UM.Theme.getSize("default_margin").width + text: catalog.i18nc("@button", "Custom") + visible: currentModeIndex == 0 + onClicked: currentModeIndex = 1 } } + Component + { + id: recommendedPrintSetup + RecommendedPrintSetup + { + onShowTooltip: base.showTooltip(item, location, text) + onHideTooltip: base.hideTooltip() + } + } + + Component + { + id: customPrintSetup + CustomPrintSetup + { + onShowTooltip: base.showTooltip(item, location, text) + onHideTooltip: base.hideTooltip() + } + } + + Component.onCompleted: { + print(height, "!!!!!!!!!!!!!!!!!!!!!!!") var index = Math.round(UM.Preferences.getValue("cura/active_mode")) if(index != null && !isNaN(index)) diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml index f8fb246085..d4057289f6 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml @@ -10,7 +10,7 @@ import Cura 1.0 as Cura RowLayout { - Cura.IconLabel + Cura.IconWithText { source: UM.Theme.getIcon("category_layer_height") text: Cura.MachineManager.activeStack ? Cura.MachineManager.activeQualityOrQualityChangesName + " " + layerHeight.properties.value + "mm" : "" @@ -24,7 +24,7 @@ RowLayout } } - Cura.IconLabel + Cura.IconWithText { source: UM.Theme.getIcon("category_infill") text: Cura.MachineManager.activeStack ? parseInt(infillDensity.properties.value) + "%" : "0%" @@ -38,7 +38,7 @@ RowLayout } } - Cura.IconLabel + Cura.IconWithText { source: UM.Theme.getIcon("category_support") text: supportEnabled.properties.value == "True" ? enabledText : disabledText @@ -53,7 +53,7 @@ RowLayout } } - Cura.IconLabel + Cura.IconWithText { source: UM.Theme.getIcon("category_adhesion") text: platformAdhesionType.properties.value != "skirt" && platformAdhesionType.properties.value != "none" ? enabledText : disabledText diff --git a/resources/qml/PrintSetupSelector/RecommendedPrintSetup.qml b/resources/qml/PrintSetupSelector/RecommendedPrintSetup.qml index a11eae3218..5d195bdde4 100644 --- a/resources/qml/PrintSetupSelector/RecommendedPrintSetup.qml +++ b/resources/qml/PrintSetupSelector/RecommendedPrintSetup.qml @@ -4,7 +4,6 @@ import QtQuick 2.7 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 -import QtQuick.Layouts 1.3 import UM 1.2 as UM import Cura 1.0 as Cura @@ -15,6 +14,7 @@ Item signal showTooltip(Item item, point location, string text) signal hideTooltip() + height: childrenRect.height property Action configureSettings @@ -26,1088 +26,1072 @@ Item name: "cura" } - ScrollView + // + // Quality profile + // + Item { - visible: Cura.MachineManager.activeMachineName != "" // If no printers added then the view is invisible - anchors.fill: parent - style: UM.Theme.styles.scrollview - flickableItem.flickableDirection: Flickable.VerticalFlick + id: qualityRow - Item + height: UM.Theme.getSize("thick_margin").height + anchors.topMargin: UM.Theme.getSize("thick_margin").height + anchors.left: parent.left + anchors.right: parent.right + + Timer { - width: childrenRect.width - height: childrenRect.height - - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("default_margin").width - // - // Quality profile - // - Item + id: qualitySliderChangeTimer + interval: 50 + running: false + repeat: false + onTriggered: { - id: qualityRow + var item = Cura.QualityProfilesDropDownMenuModel.getItem(qualitySlider.value); + Cura.MachineManager.activeQualityGroup = item.quality_group; + } + } - height: UM.Theme.getSize("thick_margin").height - anchors.topMargin: UM.Theme.getSize("thick_margin").height - anchors.left: parent.left - anchors.right: parent.right + Component.onCompleted: qualityModel.update() - Timer + Connections + { + target: Cura.QualityProfilesDropDownMenuModel + onItemsChanged: qualityModel.update() + } + + Connections { + target: base + onVisibleChanged: + { + // update needs to be called when the widgets are visible, otherwise the step width calculation + // will fail because the width of an invisible item is 0. + if (visible) { - id: qualitySliderChangeTimer - interval: 50 - running: false - repeat: false - onTriggered: - { - var item = Cura.QualityProfilesDropDownMenuModel.getItem(qualitySlider.value); - Cura.MachineManager.activeQualityGroup = item.quality_group; - } + qualityModel.update(); } + } + } - Component.onCompleted: qualityModel.update() + ListModel + { + id: qualityModel - Connections + property var totalTicks: 0 + property var availableTotalTicks: 0 + property var existingQualityProfile: 0 + + property var qualitySliderActiveIndex: 0 + property var qualitySliderStepWidth: 0 + property var qualitySliderAvailableMin: 0 + property var qualitySliderAvailableMax: 0 + property var qualitySliderMarginRight: 0 + + function update () + { + reset() + + var availableMin = -1 + var availableMax = -1 + + for (var i = 0; i < Cura.QualityProfilesDropDownMenuModel.rowCount(); i++) { - target: Cura.QualityProfilesDropDownMenuModel - onItemsChanged: qualityModel.update() - } + var qualityItem = Cura.QualityProfilesDropDownMenuModel.getItem(i) - Connections { - target: base - onVisibleChanged: + // Add each quality item to the UI quality model + qualityModel.append(qualityItem) + + // Set selected value + if (Cura.MachineManager.activeQualityType == qualityItem.quality_type) { - // update needs to be called when the widgets are visible, otherwise the step width calculation - // will fail because the width of an invisible item is 0. - if (visible) + // set to -1 when switching to user created profile so all ticks are clickable + if (Cura.SimpleModeSettingsManager.isProfileUserCreated) { - qualityModel.update(); - } - } - } - - ListModel - { - id: qualityModel - - property var totalTicks: 0 - property var availableTotalTicks: 0 - property var existingQualityProfile: 0 - - property var qualitySliderActiveIndex: 0 - property var qualitySliderStepWidth: 0 - property var qualitySliderAvailableMin: 0 - property var qualitySliderAvailableMax: 0 - property var qualitySliderMarginRight: 0 - - function update () - { - reset() - - var availableMin = -1 - var availableMax = -1 - - for (var i = 0; i < Cura.QualityProfilesDropDownMenuModel.rowCount(); i++) - { - var qualityItem = Cura.QualityProfilesDropDownMenuModel.getItem(i) - - // Add each quality item to the UI quality model - qualityModel.append(qualityItem) - - // Set selected value - if (Cura.MachineManager.activeQualityType == qualityItem.quality_type) - { - // set to -1 when switching to user created profile so all ticks are clickable - if (Cura.SimpleModeSettingsManager.isProfileUserCreated) - { - qualityModel.qualitySliderActiveIndex = -1 - } - else - { - qualityModel.qualitySliderActiveIndex = i - } - - qualityModel.existingQualityProfile = 1 - } - - // Set min available - if (qualityItem.available && availableMin == -1) - { - availableMin = i - } - - // Set max available - if (qualityItem.available) - { - availableMax = i - } - } - - // Set total available ticks for active slider part - if (availableMin != -1) - { - qualityModel.availableTotalTicks = availableMax - availableMin + 1 - } - - // Calculate slider values - calculateSliderStepWidth(qualityModel.totalTicks) - calculateSliderMargins(availableMin, availableMax, qualityModel.totalTicks) - - qualityModel.qualitySliderAvailableMin = availableMin - qualityModel.qualitySliderAvailableMax = availableMax - } - - function calculateSliderStepWidth (totalTicks) - { - qualityModel.qualitySliderStepWidth = totalTicks != 0 ? Math.round((base.width * 0.55) / (totalTicks)) : 0 - } - - function calculateSliderMargins (availableMin, availableMax, totalTicks) - { - if (availableMin == -1 || (availableMin == 0 && availableMax == 0)) - { - qualityModel.qualitySliderMarginRight = Math.round(base.width * 0.55) - } - else if (availableMin == availableMax) - { - qualityModel.qualitySliderMarginRight = Math.round((totalTicks - availableMin) * qualitySliderStepWidth) + qualityModel.qualitySliderActiveIndex = -1 } else { - qualityModel.qualitySliderMarginRight = Math.round((totalTicks - availableMax) * qualitySliderStepWidth) + qualityModel.qualitySliderActiveIndex = i } + + qualityModel.existingQualityProfile = 1 } - function reset () { - qualityModel.clear() - qualityModel.availableTotalTicks = 0 - qualityModel.existingQualityProfile = 0 + // Set min available + if (qualityItem.available && availableMin == -1) + { + availableMin = i + } - // check, the ticks count cannot be less than zero - qualityModel.totalTicks = Math.max(0, Cura.QualityProfilesDropDownMenuModel.rowCount() - 1) + // Set max available + if (qualityItem.available) + { + availableMax = i } } - Cura.IconLabel + // Set total available ticks for active slider part + if (availableMin != -1) { - id: qualityRowTitle - source: UM.Theme.getIcon("category_layer_height") - text: catalog.i18nc("@label", "Layer Height") - anchors.bottom: speedSlider.bottom + qualityModel.availableTotalTicks = availableMax - availableMin + 1 } - // Show titles for the each quality slider ticks - Item + // Calculate slider values + calculateSliderStepWidth(qualityModel.totalTicks) + calculateSliderMargins(availableMin, availableMax, qualityModel.totalTicks) + + qualityModel.qualitySliderAvailableMin = availableMin + qualityModel.qualitySliderAvailableMax = availableMax + } + + function calculateSliderStepWidth (totalTicks) + { + qualityModel.qualitySliderStepWidth = totalTicks != 0 ? Math.round((base.width * 0.55) / (totalTicks)) : 0 + } + + function calculateSliderMargins (availableMin, availableMax, totalTicks) + { + if (availableMin == -1 || (availableMin == 0 && availableMax == 0)) { - anchors.left: speedSlider.left - anchors.top: speedSlider.bottom - Repeater - { - model: qualityModel - - Label - { - anchors.verticalCenter: parent.verticalCenter - anchors.top: parent.bottom - color: (Cura.MachineManager.activeMachine != null && Cura.QualityProfilesDropDownMenuModel.getItem(index).available) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") - text: - { - var result = "" - if(Cura.MachineManager.activeMachine != null) - { - result = Cura.QualityProfilesDropDownMenuModel.getItem(index).layer_height - - if(result == undefined) - { - result = ""; - } - else - { - result = Number(Math.round(result + "e+2") + "e-2"); //Round to 2 decimals. Javascript makes this difficult... - if (result == undefined || result != result) //Parse failure. - { - result = ""; - } - } - } - return result - } - - x: - { - // Make sure the text aligns correctly with each tick - if (qualityModel.totalTicks == 0) - { - // If there is only one tick, align it centrally - return Math.round(((base.width * 0.55) - width) / 2) - } - else if (index == 0) - { - return Math.round(base.width * 0.55 / qualityModel.totalTicks) * index - } - else if (index == qualityModel.totalTicks) - { - return Math.round(base.width * 0.55 / qualityModel.totalTicks) * index - width - } - else - { - return Math.round((base.width * 0.55 / qualityModel.totalTicks) * index - (width / 2)) - } - } - } - } + qualityModel.qualitySliderMarginRight = Math.round(base.width * 0.55) } - - //Print speed slider - Rectangle + else if (availableMin == availableMax) { - id: speedSlider - width: Math.round(base.width * 0.55) - height: UM.Theme.getSize("thick_margin").height - anchors.right: parent.right - anchors.top: parent.top - anchors.topMargin: UM.Theme.getSize("thick_margin").height - - // This Item is used only for tooltip, for slider area which is unavailable - Item - { - function showTooltip (showTooltip) - { - if (showTooltip) - { - var content = catalog.i18nc("@tooltip", "This quality profile is not available for you current material and nozzle configuration. Please change these to enable this quality profile") - base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), content) - } - else - { - base.hideTooltip() - } - } - - id: unavailableLineToolTip - height: 20 * screenScaleFactor // hovered area height - z: parent.z + 1 // should be higher, otherwise the area can be hovered - x: 0 - anchors.verticalCenter: qualitySlider.verticalCenter - - Rectangle - { - id: leftArea - width: - { - if (qualityModel.availableTotalTicks == 0) - { - return qualityModel.qualitySliderStepWidth * qualityModel.totalTicks - } - return qualityModel.qualitySliderStepWidth * qualityModel.qualitySliderAvailableMin - 10 - } - height: parent.height - color: "transparent" - - MouseArea - { - anchors.fill: parent - hoverEnabled: true - enabled: Cura.SimpleModeSettingsManager.isProfileUserCreated == false - onEntered: unavailableLineToolTip.showTooltip(true) - onExited: unavailableLineToolTip.showTooltip(false) - } - } - - Item - { - id: rightArea - width: - { - if(qualityModel.availableTotalTicks == 0) - return 0 - - return qualityModel.qualitySliderMarginRight - 10 - } - height: parent.height - x: - { - if (qualityModel.availableTotalTicks == 0) - { - return 0 - } - - var leftUnavailableArea = qualityModel.qualitySliderStepWidth * qualityModel.qualitySliderAvailableMin - var totalGap = qualityModel.qualitySliderStepWidth * (qualityModel.availableTotalTicks -1) + leftUnavailableArea + 10 - - return totalGap - } - - MouseArea - { - anchors.fill: parent - hoverEnabled: true - enabled: Cura.SimpleModeSettingsManager.isProfileUserCreated == false - onEntered: unavailableLineToolTip.showTooltip(true) - onExited: unavailableLineToolTip.showTooltip(false) - } - } - } - - // Draw Unavailable line - Rectangle - { - id: groovechildrect - width: Math.round(base.width * 0.55) - height: 2 * screenScaleFactor - color: UM.Theme.getColor("quality_slider_unavailable") - anchors.verticalCenter: qualitySlider.verticalCenter - x: 0 - } - - // Draw ticks - Repeater - { - id: qualityRepeater - model: qualityModel.totalTicks > 0 ? qualityModel : 0 - - Rectangle - { - color: Cura.QualityProfilesDropDownMenuModel.getItem(index).available ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") - implicitWidth: 5 * screenScaleFactor - implicitHeight: implicitWidth - anchors.verticalCenter: qualitySlider.verticalCenter - x: Math.round(qualityModel.qualitySliderStepWidth * index) - radius: Math.round(implicitWidth / 2) - } - } - - Slider - { - id: qualitySlider - height: UM.Theme.getSize("thick_margin").height - anchors.bottom: speedSlider.bottom - enabled: qualityModel.totalTicks > 0 && !Cura.SimpleModeSettingsManager.isProfileCustomized - visible: qualityModel.availableTotalTicks > 0 - updateValueWhileDragging : false - - minimumValue: qualityModel.qualitySliderAvailableMin >= 0 ? qualityModel.qualitySliderAvailableMin : 0 - // maximumValue must be greater than minimumValue to be able to see the handle. While the value is strictly - // speaking not always correct, it seems to have the correct behavior (switching from 0 available to 1 available) - maximumValue: qualityModel.qualitySliderAvailableMax >= 1 ? qualityModel.qualitySliderAvailableMax : 1 - stepSize: 1 - - value: qualityModel.qualitySliderActiveIndex - - width: qualityModel.qualitySliderStepWidth * (qualityModel.availableTotalTicks - 1) - - anchors.right: parent.right - anchors.rightMargin: qualityModel.qualitySliderMarginRight - - style: SliderStyle - { - //Draw Available line - groove: Rectangle - { - implicitHeight: 2 * screenScaleFactor - color: UM.Theme.getColor("quality_slider_available") - radius: Math.round(height / 2) - } - handle: Item - { - Rectangle - { - id: qualityhandleButton - anchors.centerIn: parent - color: UM.Theme.getColor("quality_slider_available") - implicitWidth: 10 * screenScaleFactor - implicitHeight: implicitWidth - radius: Math.round(implicitWidth / 2) - visible: !Cura.SimpleModeSettingsManager.isProfileCustomized && !Cura.SimpleModeSettingsManager.isProfileUserCreated && qualityModel.existingQualityProfile - } - } - } - - onValueChanged: - { - // only change if an active machine is set and the slider is visible at all. - if (Cura.MachineManager.activeMachine != null && visible) - { - // prevent updating during view initializing. Trigger only if the value changed by user - if (qualitySlider.value != qualityModel.qualitySliderActiveIndex && qualityModel.qualitySliderActiveIndex != -1) - { - // start updating with short delay - qualitySliderChangeTimer.start() - } - } - } - } - - MouseArea - { - id: speedSliderMouseArea - anchors.fill: parent - hoverEnabled: true - enabled: Cura.SimpleModeSettingsManager.isProfileUserCreated - - onEntered: - { - var content = catalog.i18nc("@tooltip","A custom profile is currently active. To enable the quality slider, choose a default quality profile in Custom tab") - base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), content) - } - onExited: base.hideTooltip() - } + qualityModel.qualitySliderMarginRight = Math.round((totalTicks - availableMin) * qualitySliderStepWidth) } - - UM.SimpleButton + else { - id: customisedSettings - - visible: Cura.SimpleModeSettingsManager.isProfileCustomized || Cura.SimpleModeSettingsManager.isProfileUserCreated - height: Math.round(speedSlider.height * 0.8) - width: Math.round(speedSlider.height * 0.8) - - anchors.verticalCenter: speedSlider.verticalCenter - anchors.right: speedSlider.left - anchors.rightMargin: Math.round(UM.Theme.getSize("thick_margin").width / 2) - - color: hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button"); - iconSource: UM.Theme.getIcon("reset"); - - onClicked: - { - // if the current profile is user-created, switch to a built-in quality - Cura.MachineManager.resetToUseDefaultQuality() - } - onEntered: - { - var content = catalog.i18nc("@tooltip","You have modified some profile settings. If you want to change these go to custom mode.") - base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), content) - } - onExited: base.hideTooltip() + qualityModel.qualitySliderMarginRight = Math.round((totalTicks - availableMax) * qualitySliderStepWidth) } } - // - // Infill - // - Item - { - id: infillCellLeft + function reset () { + qualityModel.clear() + qualityModel.availableTotalTicks = 0 + qualityModel.existingQualityProfile = 0 - anchors.top: qualityRow.bottom - anchors.topMargin: UM.Theme.getSize("thick_margin").height * 2 - anchors.left: parent.left - - width: Math.round(UM.Theme.getSize("print_setup_widget").width * .45) - UM.Theme.getSize("thick_margin").width - - Cura.IconLabel - { - id: infillLabel - source: UM.Theme.getIcon("category_infill") - text: catalog.i18nc("@label", "Infill") + " (%)" - - anchors - { - top: parent.top - topMargin: Math.round(UM.Theme.getSize("thick_margin").height * 1.7) - left: parent.left - } - } + // check, the ticks count cannot be less than zero + qualityModel.totalTicks = Math.max(0, Cura.QualityProfilesDropDownMenuModel.rowCount() - 1) } + } - Item + Cura.IconWithText + { + id: qualityRowTitle + source: UM.Theme.getIcon("category_layer_height") + text: catalog.i18nc("@label", "Layer Height") + anchors.bottom: speedSlider.bottom + } + + // Show titles for the each quality slider ticks + Item + { + anchors.left: speedSlider.left + anchors.top: speedSlider.bottom + Repeater { - id: infillCellRight - - height: infillSlider.height + UM.Theme.getSize("thick_margin").height + enableGradualInfillCheckBox.visible * (enableGradualInfillCheckBox.height + UM.Theme.getSize("thick_margin").height) - width: Math.round(UM.Theme.getSize("print_setup_widget").width * .55) - - anchors.left: infillCellLeft.right - anchors.top: infillCellLeft.top - anchors.topMargin: UM.Theme.getSize("thick_margin").height - - Label { - id: selectedInfillRateText - - anchors.left: infillSlider.left - anchors.right: parent.right - - text: parseInt(infillDensity.properties.value) + "%" - horizontalAlignment: Text.AlignLeft - - color: infillSlider.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") - } - - // We use a binding to make sure that after manually setting infillSlider.value it is still bound to the property provider - Binding - { - target: infillSlider - property: "value" - value: parseInt(infillDensity.properties.value) - } - - Slider - { - id: infillSlider - - anchors.top: selectedInfillRateText.bottom - anchors.left: parent.left - anchors.right: infillIcon.left - anchors.rightMargin: UM.Theme.getSize("thick_margin").width - - height: UM.Theme.getSize("thick_margin").height - width: parseInt(infillCellRight.width - UM.Theme.getSize("thick_margin").width - style.handleWidth) - - minimumValue: 0 - maximumValue: 100 - stepSize: 1 - tickmarksEnabled: true - - // disable slider when gradual support is enabled - enabled: parseInt(infillSteps.properties.value) == 0 - - // set initial value from stack - value: parseInt(infillDensity.properties.value) - - onValueChanged: - { - - // Don't round the value if it's already the same - if (parseInt(infillDensity.properties.value) == infillSlider.value) - { - return - } - - // Round the slider value to the nearest multiple of 10 (simulate step size of 10) - var roundedSliderValue = Math.round(infillSlider.value / 10) * 10 - - // Update the slider value to represent the rounded value - infillSlider.value = roundedSliderValue - - // Update value only if the Recomended mode is Active, - // Otherwise if I change the value in the Custom mode the Recomended view will try to repeat - // same operation - var active_mode = UM.Preferences.getValue("cura/active_mode") - - if (active_mode == 0 || active_mode == "simple") - { - Cura.MachineManager.setSettingForAllExtruders("infill_sparse_density", "value", roundedSliderValue) - Cura.MachineManager.resetSettingForAllExtruders("infill_line_distance") - } - } - - style: SliderStyle - { - groove: Rectangle - { - id: groove - implicitWidth: 200 * screenScaleFactor - implicitHeight: 2 * screenScaleFactor - color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") - radius: 1 - } - - handle: Item - { - Rectangle - { - id: handleButton - anchors.centerIn: parent - color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") - implicitWidth: 10 * screenScaleFactor - implicitHeight: 10 * screenScaleFactor - radius: 10 * screenScaleFactor - } - } - - tickmarks: Repeater - { - id: repeater - model: control.maximumValue / control.stepSize + 1 - - // check if a tick should be shown based on it's index and wether the infill density is a multiple of 10 (slider step size) - function shouldShowTick (index) - { - if (index % 10 == 0) - { - return true - } - return false - } - - Rectangle - { - anchors.verticalCenter: parent.verticalCenter - color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") - width: 1 * screenScaleFactor - height: 6 * screenScaleFactor - x: Math.round(styleData.handleWidth / 2 + index * ((repeater.width - styleData.handleWidth) / (repeater.count-1))) - visible: shouldShowTick(index) - } - } - } - } - - Rectangle - { - id: infillIcon - - width: Math.round((parent.width / 5) - (UM.Theme.getSize("thick_margin").width)) - height: width - - anchors.right: parent.right - anchors.top: parent.top - anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height / 2) - - // we loop over all density icons and only show the one that has the current density and steps - Repeater - { - id: infillIconList - model: infillModel - anchors.fill: parent - - function activeIndex () - { - for (var i = 0; i < infillModel.count; i++) - { - var density = Math.round(infillDensity.properties.value) - var steps = Math.round(infillSteps.properties.value) - var infillModelItem = infillModel.get(i) - - if (infillModelItem != "undefined" - && density >= infillModelItem.percentageMin - && density <= infillModelItem.percentageMax - && steps >= infillModelItem.stepsMin - && steps <= infillModelItem.stepsMax) - { - return i - } - } - return -1 - } - - Rectangle - { - anchors.fill: parent - visible: infillIconList.activeIndex() == index - - border.width: UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("quality_slider_unavailable") - - UM.RecolorImage - { - anchors.fill: parent - anchors.margins: 2 * screenScaleFactor - sourceSize.width: width - sourceSize.height: width - source: UM.Theme.getIcon(model.icon) - color: UM.Theme.getColor("quality_slider_unavailable") - } - } - } - } - - // Gradual Support Infill Checkbox - CheckBox - { - id: enableGradualInfillCheckBox - property alias _hovered: enableGradualInfillMouseArea.containsMouse - - anchors.top: infillSlider.bottom - anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height / 2) // closer to slider since it belongs to the same category - anchors.left: infillCellRight.left - - style: UM.Theme.styles.checkbox - enabled: base.settingsEnabled - visible: infillSteps.properties.enabled == "True" - checked: parseInt(infillSteps.properties.value) > 0 - - MouseArea - { - id: enableGradualInfillMouseArea - - anchors.fill: parent - hoverEnabled: true - enabled: true - - property var previousInfillDensity: parseInt(infillDensity.properties.value) - - onClicked: - { - // Set to 90% only when enabling gradual infill - var newInfillDensity; - if (parseInt(infillSteps.properties.value) == 0) - { - previousInfillDensity = parseInt(infillDensity.properties.value) - newInfillDensity = 90 - } else { - newInfillDensity = previousInfillDensity - } - Cura.MachineManager.setSettingForAllExtruders("infill_sparse_density", "value", String(newInfillDensity)) - - var infill_steps_value = 0 - if (parseInt(infillSteps.properties.value) == 0) - { - infill_steps_value = 5 - } - - Cura.MachineManager.setSettingForAllExtruders("gradual_infill_steps", "value", infill_steps_value) - } - - onEntered: base.showTooltip(enableGradualInfillCheckBox, Qt.point(-infillCellRight.x, 0), - catalog.i18nc("@label", "Gradual infill will gradually increase the amount of infill towards the top.")) - - onExited: base.hideTooltip() - - } - - Label - { - id: gradualInfillLabel - height: parent.height - anchors.left: enableGradualInfillCheckBox.right - anchors.leftMargin: Math.round(UM.Theme.getSize("thick_margin").width / 2) - verticalAlignment: Text.AlignVCenter; - text: catalog.i18nc("@label", "Enable gradual") - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - } - } - - // Infill list model for mapping icon - ListModel - { - id: infillModel - Component.onCompleted: - { - infillModel.append({ - percentageMin: -1, - percentageMax: 0, - stepsMin: -1, - stepsMax: 0, - icon: "hollow" - }) - infillModel.append({ - percentageMin: 0, - percentageMax: 40, - stepsMin: -1, - stepsMax: 0, - icon: "sparse" - }) - infillModel.append({ - percentageMin: 40, - percentageMax: 89, - stepsMin: -1, - stepsMax: 0, - icon: "dense" - }) - infillModel.append({ - percentageMin: 90, - percentageMax: 9999999999, - stepsMin: -1, - stepsMax: 0, - icon: "solid" - }) - infillModel.append({ - percentageMin: 0, - percentageMax: 9999999999, - stepsMin: 1, - stepsMax: 9999999999, - icon: "gradual" - }) - } - } - } - - // - // Enable support - // - Cura.IconLabel - { - id: enableSupportLabel - visible: enableSupportCheckBox.visible - source: UM.Theme.getIcon("category_support") - text: catalog.i18nc("@label", "Support") - - anchors - { - top: infillCellRight.bottom - topMargin: Math.round(UM.Theme.getSize("thick_margin").height * 1.5) - left: parent.left - right: infillCellLeft.right - rightMargin: UM.Theme.getSize("thick_margin").width - verticalCenter: enableSupportCheckBox.verticalCenter - } - } - - CheckBox - { - id: enableSupportCheckBox - property alias _hovered: enableSupportMouseArea.containsMouse - - anchors.top: enableSupportLabel.top - anchors.left: infillCellRight.left - - style: UM.Theme.styles.checkbox - enabled: base.settingsEnabled - - visible: supportEnabled.properties.enabled == "True" - checked: supportEnabled.properties.value == "True" - - MouseArea - { - id: enableSupportMouseArea - anchors.fill: parent - hoverEnabled: true - onClicked: supportEnabled.setPropertyValue("value", supportEnabled.properties.value != "True") - - onEntered: base.showTooltip(enableSupportCheckBox, Qt.point(-enableSupportCheckBox.x, 0), - catalog.i18nc("@label", "Generate structures to support parts of the model which have overhangs. Without these structures, such parts would collapse during printing.")) - - onExited: base.hideTooltip() - - } - } - - ComboBox - { - id: supportExtruderCombobox - visible: enableSupportCheckBox.visible && (supportEnabled.properties.value == "True") && (extrudersEnabledCount.properties.value > 1) - model: extruderModel - - property string color_override: "" // for manually setting values - property string color: // is evaluated automatically, but the first time is before extruderModel being filled - { - var current_extruder = extruderModel.get(currentIndex); - color_override = ""; - if (current_extruder === undefined) return "" - return (current_extruder.color) ? current_extruder.color : ""; - } - - textRole: "text" // this solves that the combobox isn't populated in the first time Cura is started - - anchors.top: enableSupportCheckBox.top - - anchors.left: enableSupportCheckBox.right - anchors.leftMargin: Math.round(UM.Theme.getSize("thick_margin").width / 2) - - width: Math.round(UM.Theme.getSize("print_setup_widget").width * .55) - Math.round(UM.Theme.getSize("thick_margin").width / 2) - enableSupportCheckBox.width - height: ((supportEnabled.properties.value == "True") && (machineExtruderCount.properties.value > 1)) ? UM.Theme.getSize("setting_control").height : 0 - - Behavior on height { NumberAnimation { duration: 100 } } - - style: UM.Theme.styles.combobox_color - enabled: base.settingsEnabled - property alias _hovered: supportExtruderMouseArea.containsMouse - - currentIndex: - { - if (supportExtruderNr.properties == null) - { - return Cura.MachineManager.defaultExtruderPosition - } - else - { - var extruder = parseInt(supportExtruderNr.properties.value) - if ( extruder === -1) - { - return Cura.MachineManager.defaultExtruderPosition - } - return extruder; - } - } - - onActivated: supportExtruderNr.setPropertyValue("value", String(index)) - - MouseArea - { - id: supportExtruderMouseArea - anchors.fill: parent - hoverEnabled: true - enabled: base.settingsEnabled - acceptedButtons: Qt.NoButton - onEntered: - { - base.showTooltip(supportExtruderCombobox, Qt.point(-supportExtruderCombobox.x, 0), - catalog.i18nc("@label", "Select which extruder to use for support. This will build up supporting structures below the model to prevent the model from sagging or printing in mid air.")); - } - onExited: base.hideTooltip() - - } - - function updateCurrentColor() - { - var current_extruder = extruderModel.get(currentIndex) - if (current_extruder !== undefined) - { - supportExtruderCombobox.color_override = current_extruder.color - } - } - - } - - Cura.IconLabel - { - id: adhesionHelperLabel - visible: adhesionCheckBox.visible - source: UM.Theme.getIcon("category_adhesion") - text: catalog.i18nc("@label", "Adhesion") - - anchors - { - left: parent.left - right: infillCellLeft.right - rightMargin: UM.Theme.getSize("thick_margin").width - verticalCenter: adhesionCheckBox.verticalCenter - } - } - - CheckBox - { - id: adhesionCheckBox - property alias _hovered: adhesionMouseArea.containsMouse - - anchors.top: enableSupportCheckBox.bottom - anchors.topMargin: UM.Theme.getSize("thick_margin").height - anchors.left: infillCellRight.left - - //: Setting enable printing build-plate adhesion helper checkbox - style: UM.Theme.styles.checkbox - enabled: base.settingsEnabled - - visible: platformAdhesionType.properties.enabled == "True" - checked: platformAdhesionType.properties.value != "skirt" && platformAdhesionType.properties.value != "none" - - MouseArea - { - id: adhesionMouseArea - anchors.fill: parent - hoverEnabled: true - enabled: base.settingsEnabled - onClicked: - { - var adhesionType = "skirt" - if(!parent.checked) - { - // Remove the "user" setting to see if the rest of the stack prescribes a brim or a raft - platformAdhesionType.removeFromContainer(0) - adhesionType = platformAdhesionType.properties.value - if(adhesionType == "skirt" || adhesionType == "none") - { - // If the rest of the stack doesn't prescribe an adhesion-type, default to a brim - adhesionType = "brim" - } - } - platformAdhesionType.setPropertyValue("value", adhesionType) - } - onEntered: - { - base.showTooltip(adhesionCheckBox, Qt.point(-adhesionCheckBox.x, 0), - catalog.i18nc("@label", "Enable printing a brim or raft. This will add a flat area around or under your object which is easy to cut off afterwards.")); - } - onExited: base.hideTooltip() - - } - } - - ListModel - { - id: extruderModel - Component.onCompleted: populateExtruderModel() - } - - //: Model used to populate the extrudelModel - Cura.ExtrudersModel - { - id: extruders - onModelChanged: populateExtruderModel() - } - - Item - { - id: tipsCell - anchors.top: adhesionCheckBox.visible ? adhesionCheckBox.bottom : (enableSupportCheckBox.visible ? supportExtruderCombobox.bottom : infillCellRight.bottom) - anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height * 2) - anchors.left: parent.left - width: parent.width - height: tipsText.contentHeight * tipsText.lineCount + model: qualityModel Label { - id: tipsText - anchors.left: parent.left - anchors.right: parent.right - anchors.rightMargin: UM.Theme.getSize("thick_margin").width - anchors.top: parent.top - wrapMode: Text.WordWrap - text: catalog.i18nc("@label", "Need help improving your prints?
    Read the Ultimaker Troubleshooting Guides").arg("https://ultimaker.com/en/troubleshooting") - font: UM.Theme.getFont("default"); - color: UM.Theme.getColor("text"); - linkColor: UM.Theme.getColor("text_link") - onLinkActivated: Qt.openUrlExternally(link) + anchors.verticalCenter: parent.verticalCenter + anchors.top: parent.bottom + color: (Cura.MachineManager.activeMachine != null && Cura.QualityProfilesDropDownMenuModel.getItem(index).available) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") + text: + { + var result = "" + if(Cura.MachineManager.activeMachine != null) + { + result = Cura.QualityProfilesDropDownMenuModel.getItem(index).layer_height + + if(result == undefined) + { + result = ""; + } + else + { + result = Number(Math.round(result + "e+2") + "e-2"); //Round to 2 decimals. Javascript makes this difficult... + if (result == undefined || result != result) //Parse failure. + { + result = ""; + } + } + } + return result + } + + x: + { + // Make sure the text aligns correctly with each tick + if (qualityModel.totalTicks == 0) + { + // If there is only one tick, align it centrally + return Math.round(((base.width * 0.55) - width) / 2) + } + else if (index == 0) + { + return Math.round(base.width * 0.55 / qualityModel.totalTicks) * index + } + else if (index == qualityModel.totalTicks) + { + return Math.round(base.width * 0.55 / qualityModel.totalTicks) * index - width + } + else + { + return Math.round((base.width * 0.55 / qualityModel.totalTicks) * index - (width / 2)) + } + } + } + } + } + + //Print speed slider + Rectangle + { + id: speedSlider + width: Math.round(base.width * 0.55) + height: UM.Theme.getSize("thick_margin").height + anchors.right: parent.right + anchors.top: parent.top + anchors.topMargin: UM.Theme.getSize("thick_margin").height + + // This Item is used only for tooltip, for slider area which is unavailable + Item + { + function showTooltip (showTooltip) + { + if (showTooltip) + { + var content = catalog.i18nc("@tooltip", "This quality profile is not available for you current material and nozzle configuration. Please change these to enable this quality profile") + base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), content) + } + else + { + base.hideTooltip() + } + } + + id: unavailableLineToolTip + height: 20 * screenScaleFactor // hovered area height + z: parent.z + 1 // should be higher, otherwise the area can be hovered + x: 0 + anchors.verticalCenter: qualitySlider.verticalCenter + + Rectangle + { + id: leftArea + width: + { + if (qualityModel.availableTotalTicks == 0) + { + return qualityModel.qualitySliderStepWidth * qualityModel.totalTicks + } + return qualityModel.qualitySliderStepWidth * qualityModel.qualitySliderAvailableMin - 10 + } + height: parent.height + color: "transparent" + + MouseArea + { + anchors.fill: parent + hoverEnabled: true + enabled: Cura.SimpleModeSettingsManager.isProfileUserCreated == false + onEntered: unavailableLineToolTip.showTooltip(true) + onExited: unavailableLineToolTip.showTooltip(false) + } + } + + Item + { + id: rightArea + width: + { + if(qualityModel.availableTotalTicks == 0) + return 0 + + return qualityModel.qualitySliderMarginRight - 10 + } + height: parent.height + x: + { + if (qualityModel.availableTotalTicks == 0) + { + return 0 + } + + var leftUnavailableArea = qualityModel.qualitySliderStepWidth * qualityModel.qualitySliderAvailableMin + var totalGap = qualityModel.qualitySliderStepWidth * (qualityModel.availableTotalTicks -1) + leftUnavailableArea + 10 + + return totalGap + } + + MouseArea + { + anchors.fill: parent + hoverEnabled: true + enabled: Cura.SimpleModeSettingsManager.isProfileUserCreated == false + onEntered: unavailableLineToolTip.showTooltip(true) + onExited: unavailableLineToolTip.showTooltip(false) + } } } - UM.SettingPropertyProvider + // Draw Unavailable line + Rectangle { - id: infillExtruderNumber - containerStackId: Cura.MachineManager.activeStackId - key: "infill_extruder_nr" - watchedProperties: [ "value" ] - storeIndex: 0 + id: groovechildrect + width: Math.round(base.width * 0.55) + height: 2 * screenScaleFactor + color: UM.Theme.getColor("quality_slider_unavailable") + anchors.verticalCenter: qualitySlider.verticalCenter + x: 0 } - UM.SettingPropertyProvider + // Draw ticks + Repeater { - id: infillDensity - containerStackId: Cura.MachineManager.activeStackId - key: "infill_sparse_density" - watchedProperties: [ "value" ] - storeIndex: 0 + id: qualityRepeater + model: qualityModel.totalTicks > 0 ? qualityModel : 0 + + Rectangle + { + color: Cura.QualityProfilesDropDownMenuModel.getItem(index).available ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") + implicitWidth: 5 * screenScaleFactor + implicitHeight: implicitWidth + anchors.verticalCenter: qualitySlider.verticalCenter + x: Math.round(qualityModel.qualitySliderStepWidth * index) + radius: Math.round(implicitWidth / 2) + } } - UM.SettingPropertyProvider + Slider { - id: infillSteps - containerStackId: Cura.MachineManager.activeStackId - key: "gradual_infill_steps" - watchedProperties: ["value", "enabled"] - storeIndex: 0 + id: qualitySlider + height: UM.Theme.getSize("thick_margin").height + anchors.bottom: speedSlider.bottom + enabled: qualityModel.totalTicks > 0 && !Cura.SimpleModeSettingsManager.isProfileCustomized + visible: qualityModel.availableTotalTicks > 0 + updateValueWhileDragging : false + + minimumValue: qualityModel.qualitySliderAvailableMin >= 0 ? qualityModel.qualitySliderAvailableMin : 0 + // maximumValue must be greater than minimumValue to be able to see the handle. While the value is strictly + // speaking not always correct, it seems to have the correct behavior (switching from 0 available to 1 available) + maximumValue: qualityModel.qualitySliderAvailableMax >= 1 ? qualityModel.qualitySliderAvailableMax : 1 + stepSize: 1 + + value: qualityModel.qualitySliderActiveIndex + + width: qualityModel.qualitySliderStepWidth * (qualityModel.availableTotalTicks - 1) + + anchors.right: parent.right + anchors.rightMargin: qualityModel.qualitySliderMarginRight + + style: SliderStyle + { + //Draw Available line + groove: Rectangle + { + implicitHeight: 2 * screenScaleFactor + color: UM.Theme.getColor("quality_slider_available") + radius: Math.round(height / 2) + } + handle: Item + { + Rectangle + { + id: qualityhandleButton + anchors.centerIn: parent + color: UM.Theme.getColor("quality_slider_available") + implicitWidth: 10 * screenScaleFactor + implicitHeight: implicitWidth + radius: Math.round(implicitWidth / 2) + visible: !Cura.SimpleModeSettingsManager.isProfileCustomized && !Cura.SimpleModeSettingsManager.isProfileUserCreated && qualityModel.existingQualityProfile + } + } + } + + onValueChanged: + { + // only change if an active machine is set and the slider is visible at all. + if (Cura.MachineManager.activeMachine != null && visible) + { + // prevent updating during view initializing. Trigger only if the value changed by user + if (qualitySlider.value != qualityModel.qualitySliderActiveIndex && qualityModel.qualitySliderActiveIndex != -1) + { + // start updating with short delay + qualitySliderChangeTimer.start() + } + } + } } - UM.SettingPropertyProvider + MouseArea { - id: platformAdhesionType - containerStack: Cura.MachineManager.activeMachine - removeUnusedValue: false //Doesn't work with settings that are resolved. - key: "adhesion_type" - watchedProperties: [ "value", "enabled" ] - storeIndex: 0 - } + id: speedSliderMouseArea + anchors.fill: parent + hoverEnabled: true + enabled: Cura.SimpleModeSettingsManager.isProfileUserCreated - UM.SettingPropertyProvider - { - id: supportEnabled - containerStack: Cura.MachineManager.activeMachine - key: "support_enable" - watchedProperties: [ "value", "enabled", "description" ] - storeIndex: 0 - } - - UM.SettingPropertyProvider - { - id: extrudersEnabledCount - containerStack: Cura.MachineManager.activeMachine - key: "extruders_enabled_count" - watchedProperties: [ "value" ] - storeIndex: 0 - } - - UM.SettingPropertyProvider - { - id: supportExtruderNr - containerStack: Cura.MachineManager.activeMachine - key: "support_extruder_nr" - watchedProperties: [ "value" ] - storeIndex: 0 + onEntered: + { + var content = catalog.i18nc("@tooltip","A custom profile is currently active. To enable the quality slider, choose a default quality profile in Custom tab") + base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), content) + } + onExited: base.hideTooltip() } } + + UM.SimpleButton + { + id: customisedSettings + + visible: Cura.SimpleModeSettingsManager.isProfileCustomized || Cura.SimpleModeSettingsManager.isProfileUserCreated + height: Math.round(speedSlider.height * 0.8) + width: Math.round(speedSlider.height * 0.8) + + anchors.verticalCenter: speedSlider.verticalCenter + anchors.right: speedSlider.left + anchors.rightMargin: Math.round(UM.Theme.getSize("thick_margin").width / 2) + + color: hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button"); + iconSource: UM.Theme.getIcon("reset"); + + onClicked: + { + // if the current profile is user-created, switch to a built-in quality + Cura.MachineManager.resetToUseDefaultQuality() + } + onEntered: + { + var content = catalog.i18nc("@tooltip","You have modified some profile settings. If you want to change these go to custom mode.") + base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), content) + } + onExited: base.hideTooltip() + } + } + + // + // Infill + // + Item + { + id: infillCellLeft + + anchors.top: qualityRow.bottom + anchors.topMargin: UM.Theme.getSize("thick_margin").height * 2 + anchors.left: parent.left + + width: Math.round(UM.Theme.getSize("print_setup_widget").width * .45) - UM.Theme.getSize("thick_margin").width + + Cura.IconWithText + { + id: infillLabel + source: UM.Theme.getIcon("category_infill") + text: catalog.i18nc("@label", "Infill") + " (%)" + + anchors + { + top: parent.top + topMargin: Math.round(UM.Theme.getSize("thick_margin").height * 1.7) + left: parent.left + } + } + } + + Item + { + id: infillCellRight + + height: infillSlider.height + UM.Theme.getSize("thick_margin").height + enableGradualInfillCheckBox.visible * (enableGradualInfillCheckBox.height + UM.Theme.getSize("thick_margin").height) + width: Math.round(UM.Theme.getSize("print_setup_widget").width * .55) + + anchors.left: infillCellLeft.right + anchors.top: infillCellLeft.top + anchors.topMargin: UM.Theme.getSize("thick_margin").height + + Label { + id: selectedInfillRateText + + anchors.left: infillSlider.left + anchors.right: parent.right + + text: parseInt(infillDensity.properties.value) + "%" + horizontalAlignment: Text.AlignLeft + + color: infillSlider.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") + } + + // We use a binding to make sure that after manually setting infillSlider.value it is still bound to the property provider + Binding + { + target: infillSlider + property: "value" + value: parseInt(infillDensity.properties.value) + } + + Slider + { + id: infillSlider + + anchors.top: selectedInfillRateText.bottom + anchors.left: parent.left + anchors.right: infillIcon.left + anchors.rightMargin: UM.Theme.getSize("thick_margin").width + + height: UM.Theme.getSize("thick_margin").height + width: parseInt(infillCellRight.width - UM.Theme.getSize("thick_margin").width - style.handleWidth) + + minimumValue: 0 + maximumValue: 100 + stepSize: 1 + tickmarksEnabled: true + + // disable slider when gradual support is enabled + enabled: parseInt(infillSteps.properties.value) == 0 + + // set initial value from stack + value: parseInt(infillDensity.properties.value) + + onValueChanged: + { + + // Don't round the value if it's already the same + if (parseInt(infillDensity.properties.value) == infillSlider.value) + { + return + } + + // Round the slider value to the nearest multiple of 10 (simulate step size of 10) + var roundedSliderValue = Math.round(infillSlider.value / 10) * 10 + + // Update the slider value to represent the rounded value + infillSlider.value = roundedSliderValue + + // Update value only if the Recomended mode is Active, + // Otherwise if I change the value in the Custom mode the Recomended view will try to repeat + // same operation + var active_mode = UM.Preferences.getValue("cura/active_mode") + + if (active_mode == 0 || active_mode == "simple") + { + Cura.MachineManager.setSettingForAllExtruders("infill_sparse_density", "value", roundedSliderValue) + Cura.MachineManager.resetSettingForAllExtruders("infill_line_distance") + } + } + + style: SliderStyle + { + groove: Rectangle + { + id: groove + implicitWidth: 200 * screenScaleFactor + implicitHeight: 2 * screenScaleFactor + color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") + radius: 1 + } + + handle: Item + { + Rectangle + { + id: handleButton + anchors.centerIn: parent + color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") + implicitWidth: 10 * screenScaleFactor + implicitHeight: 10 * screenScaleFactor + radius: 10 * screenScaleFactor + } + } + + tickmarks: Repeater + { + id: repeater + model: control.maximumValue / control.stepSize + 1 + + // check if a tick should be shown based on it's index and wether the infill density is a multiple of 10 (slider step size) + function shouldShowTick (index) + { + if (index % 10 == 0) + { + return true + } + return false + } + + Rectangle + { + anchors.verticalCenter: parent.verticalCenter + color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") + width: 1 * screenScaleFactor + height: 6 * screenScaleFactor + x: Math.round(styleData.handleWidth / 2 + index * ((repeater.width - styleData.handleWidth) / (repeater.count-1))) + visible: shouldShowTick(index) + } + } + } + } + + Rectangle + { + id: infillIcon + + width: Math.round((parent.width / 5) - (UM.Theme.getSize("thick_margin").width)) + height: width + + anchors.right: parent.right + anchors.top: parent.top + anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height / 2) + + // we loop over all density icons and only show the one that has the current density and steps + Repeater + { + id: infillIconList + model: infillModel + anchors.fill: parent + + function activeIndex () + { + for (var i = 0; i < infillModel.count; i++) + { + var density = Math.round(infillDensity.properties.value) + var steps = Math.round(infillSteps.properties.value) + var infillModelItem = infillModel.get(i) + + if (infillModelItem != "undefined" + && density >= infillModelItem.percentageMin + && density <= infillModelItem.percentageMax + && steps >= infillModelItem.stepsMin + && steps <= infillModelItem.stepsMax) + { + return i + } + } + return -1 + } + + Rectangle + { + anchors.fill: parent + visible: infillIconList.activeIndex() == index + + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("quality_slider_unavailable") + + UM.RecolorImage + { + anchors.fill: parent + anchors.margins: 2 * screenScaleFactor + sourceSize.width: width + sourceSize.height: width + source: UM.Theme.getIcon(model.icon) + color: UM.Theme.getColor("quality_slider_unavailable") + } + } + } + } + + // Gradual Support Infill Checkbox + CheckBox + { + id: enableGradualInfillCheckBox + property alias _hovered: enableGradualInfillMouseArea.containsMouse + + anchors.top: infillSlider.bottom + anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height / 2) // closer to slider since it belongs to the same category + anchors.left: infillCellRight.left + + style: UM.Theme.styles.checkbox + enabled: base.settingsEnabled + visible: infillSteps.properties.enabled == "True" + checked: parseInt(infillSteps.properties.value) > 0 + + MouseArea + { + id: enableGradualInfillMouseArea + + anchors.fill: parent + hoverEnabled: true + enabled: true + + property var previousInfillDensity: parseInt(infillDensity.properties.value) + + onClicked: + { + // Set to 90% only when enabling gradual infill + var newInfillDensity; + if (parseInt(infillSteps.properties.value) == 0) + { + previousInfillDensity = parseInt(infillDensity.properties.value) + newInfillDensity = 90 + } else { + newInfillDensity = previousInfillDensity + } + Cura.MachineManager.setSettingForAllExtruders("infill_sparse_density", "value", String(newInfillDensity)) + + var infill_steps_value = 0 + if (parseInt(infillSteps.properties.value) == 0) + { + infill_steps_value = 5 + } + + Cura.MachineManager.setSettingForAllExtruders("gradual_infill_steps", "value", infill_steps_value) + } + + onEntered: base.showTooltip(enableGradualInfillCheckBox, Qt.point(-infillCellRight.x, 0), + catalog.i18nc("@label", "Gradual infill will gradually increase the amount of infill towards the top.")) + + onExited: base.hideTooltip() + + } + + Label + { + id: gradualInfillLabel + height: parent.height + anchors.left: enableGradualInfillCheckBox.right + anchors.leftMargin: Math.round(UM.Theme.getSize("thick_margin").width / 2) + verticalAlignment: Text.AlignVCenter; + text: catalog.i18nc("@label", "Enable gradual") + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + } + } + + // Infill list model for mapping icon + ListModel + { + id: infillModel + Component.onCompleted: + { + infillModel.append({ + percentageMin: -1, + percentageMax: 0, + stepsMin: -1, + stepsMax: 0, + icon: "hollow" + }) + infillModel.append({ + percentageMin: 0, + percentageMax: 40, + stepsMin: -1, + stepsMax: 0, + icon: "sparse" + }) + infillModel.append({ + percentageMin: 40, + percentageMax: 89, + stepsMin: -1, + stepsMax: 0, + icon: "dense" + }) + infillModel.append({ + percentageMin: 90, + percentageMax: 9999999999, + stepsMin: -1, + stepsMax: 0, + icon: "solid" + }) + infillModel.append({ + percentageMin: 0, + percentageMax: 9999999999, + stepsMin: 1, + stepsMax: 9999999999, + icon: "gradual" + }) + } + } + } + + // + // Enable support + // + Cura.IconWithText + { + id: enableSupportLabel + visible: enableSupportCheckBox.visible + source: UM.Theme.getIcon("category_support") + text: catalog.i18nc("@label", "Support") + + anchors + { + top: infillCellRight.bottom + topMargin: Math.round(UM.Theme.getSize("thick_margin").height * 1.5) + left: parent.left + right: infillCellLeft.right + rightMargin: UM.Theme.getSize("thick_margin").width + verticalCenter: enableSupportCheckBox.verticalCenter + } + } + + CheckBox + { + id: enableSupportCheckBox + property alias _hovered: enableSupportMouseArea.containsMouse + + anchors.top: enableSupportLabel.top + anchors.left: infillCellRight.left + + style: UM.Theme.styles.checkbox + enabled: base.settingsEnabled + + visible: supportEnabled.properties.enabled == "True" + checked: supportEnabled.properties.value == "True" + + MouseArea + { + id: enableSupportMouseArea + anchors.fill: parent + hoverEnabled: true + onClicked: supportEnabled.setPropertyValue("value", supportEnabled.properties.value != "True") + + onEntered: base.showTooltip(enableSupportCheckBox, Qt.point(-enableSupportCheckBox.x, 0), + catalog.i18nc("@label", "Generate structures to support parts of the model which have overhangs. Without these structures, such parts would collapse during printing.")) + + onExited: base.hideTooltip() + + } + } + + ComboBox + { + id: supportExtruderCombobox + visible: enableSupportCheckBox.visible && (supportEnabled.properties.value == "True") && (extrudersEnabledCount.properties.value > 1) + model: extruderModel + + property string color_override: "" // for manually setting values + property string color: // is evaluated automatically, but the first time is before extruderModel being filled + { + var current_extruder = extruderModel.get(currentIndex); + color_override = ""; + if (current_extruder === undefined) return "" + return (current_extruder.color) ? current_extruder.color : ""; + } + + textRole: "text" // this solves that the combobox isn't populated in the first time Cura is started + + anchors.top: enableSupportCheckBox.top + + anchors.left: enableSupportCheckBox.right + anchors.leftMargin: Math.round(UM.Theme.getSize("thick_margin").width / 2) + + width: Math.round(UM.Theme.getSize("print_setup_widget").width * .55) - Math.round(UM.Theme.getSize("thick_margin").width / 2) - enableSupportCheckBox.width + height: ((supportEnabled.properties.value == "True") && (machineExtruderCount.properties.value > 1)) ? UM.Theme.getSize("setting_control").height : 0 + + Behavior on height { NumberAnimation { duration: 100 } } + + style: UM.Theme.styles.combobox_color + enabled: base.settingsEnabled + property alias _hovered: supportExtruderMouseArea.containsMouse + + currentIndex: + { + if (supportExtruderNr.properties == null) + { + return Cura.MachineManager.defaultExtruderPosition + } + else + { + var extruder = parseInt(supportExtruderNr.properties.value) + if ( extruder === -1) + { + return Cura.MachineManager.defaultExtruderPosition + } + return extruder; + } + } + + onActivated: supportExtruderNr.setPropertyValue("value", String(index)) + + MouseArea + { + id: supportExtruderMouseArea + anchors.fill: parent + hoverEnabled: true + enabled: base.settingsEnabled + acceptedButtons: Qt.NoButton + onEntered: + { + base.showTooltip(supportExtruderCombobox, Qt.point(-supportExtruderCombobox.x, 0), + catalog.i18nc("@label", "Select which extruder to use for support. This will build up supporting structures below the model to prevent the model from sagging or printing in mid air.")); + } + onExited: base.hideTooltip() + + } + + function updateCurrentColor() + { + var current_extruder = extruderModel.get(currentIndex) + if (current_extruder !== undefined) + { + supportExtruderCombobox.color_override = current_extruder.color + } + } + + } + + Cura.IconWithText + { + id: adhesionHelperLabel + visible: adhesionCheckBox.visible + source: UM.Theme.getIcon("category_adhesion") + text: catalog.i18nc("@label", "Adhesion") + + anchors + { + left: parent.left + right: infillCellLeft.right + rightMargin: UM.Theme.getSize("thick_margin").width + verticalCenter: adhesionCheckBox.verticalCenter + } + } + + CheckBox + { + id: adhesionCheckBox + property alias _hovered: adhesionMouseArea.containsMouse + + anchors.top: enableSupportCheckBox.bottom + anchors.topMargin: UM.Theme.getSize("thick_margin").height + anchors.left: infillCellRight.left + + //: Setting enable printing build-plate adhesion helper checkbox + style: UM.Theme.styles.checkbox + enabled: base.settingsEnabled + + visible: platformAdhesionType.properties.enabled == "True" + checked: platformAdhesionType.properties.value != "skirt" && platformAdhesionType.properties.value != "none" + + MouseArea + { + id: adhesionMouseArea + anchors.fill: parent + hoverEnabled: true + enabled: base.settingsEnabled + onClicked: + { + var adhesionType = "skirt" + if(!parent.checked) + { + // Remove the "user" setting to see if the rest of the stack prescribes a brim or a raft + platformAdhesionType.removeFromContainer(0) + adhesionType = platformAdhesionType.properties.value + if(adhesionType == "skirt" || adhesionType == "none") + { + // If the rest of the stack doesn't prescribe an adhesion-type, default to a brim + adhesionType = "brim" + } + } + platformAdhesionType.setPropertyValue("value", adhesionType) + } + onEntered: + { + base.showTooltip(adhesionCheckBox, Qt.point(-adhesionCheckBox.x, 0), + catalog.i18nc("@label", "Enable printing a brim or raft. This will add a flat area around or under your object which is easy to cut off afterwards.")); + } + onExited: base.hideTooltip() + + } + } + + ListModel + { + id: extruderModel + Component.onCompleted: populateExtruderModel() + } + + //: Model used to populate the extrudelModel + Cura.ExtrudersModel + { + id: extruders + onModelChanged: populateExtruderModel() + } + + Item + { + id: tipsCell + anchors.top: adhesionCheckBox.visible ? adhesionCheckBox.bottom : (enableSupportCheckBox.visible ? supportExtruderCombobox.bottom : infillCellRight.bottom) + anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height * 2) + anchors.left: parent.left + width: parent.width + height: tipsText.contentHeight * tipsText.lineCount + + Label + { + id: tipsText + anchors.left: parent.left + anchors.right: parent.right + anchors.rightMargin: UM.Theme.getSize("thick_margin").width + anchors.top: parent.top + wrapMode: Text.WordWrap + text: catalog.i18nc("@label", "Need help improving your prints?
    Read the Ultimaker Troubleshooting Guides").arg("https://ultimaker.com/en/troubleshooting") + font: UM.Theme.getFont("default"); + color: UM.Theme.getColor("text"); + linkColor: UM.Theme.getColor("text_link") + onLinkActivated: Qt.openUrlExternally(link) + } + } + + UM.SettingPropertyProvider + { + id: infillExtruderNumber + containerStackId: Cura.MachineManager.activeStackId + key: "infill_extruder_nr" + watchedProperties: [ "value" ] + storeIndex: 0 + } + + UM.SettingPropertyProvider + { + id: infillDensity + containerStackId: Cura.MachineManager.activeStackId + key: "infill_sparse_density" + watchedProperties: [ "value" ] + storeIndex: 0 + } + + UM.SettingPropertyProvider + { + id: infillSteps + containerStackId: Cura.MachineManager.activeStackId + key: "gradual_infill_steps" + watchedProperties: ["value", "enabled"] + storeIndex: 0 + } + + UM.SettingPropertyProvider + { + id: platformAdhesionType + containerStack: Cura.MachineManager.activeMachine + removeUnusedValue: false //Doesn't work with settings that are resolved. + key: "adhesion_type" + watchedProperties: [ "value", "enabled" ] + storeIndex: 0 + } + + UM.SettingPropertyProvider + { + id: supportEnabled + containerStack: Cura.MachineManager.activeMachine + key: "support_enable" + watchedProperties: [ "value", "enabled", "description" ] + storeIndex: 0 + } + + UM.SettingPropertyProvider + { + id: extrudersEnabledCount + containerStack: Cura.MachineManager.activeMachine + key: "extruders_enabled_count" + watchedProperties: [ "value" ] + storeIndex: 0 + } + + UM.SettingPropertyProvider + { + id: supportExtruderNr + containerStack: Cura.MachineManager.activeMachine + key: "support_extruder_nr" + watchedProperties: [ "value" ] + storeIndex: 0 } function populateExtruderModel() diff --git a/resources/qml/qmldir b/resources/qml/qmldir index 2475f398f8..6db8e0c544 100644 --- a/resources/qml/qmldir +++ b/resources/qml/qmldir @@ -9,6 +9,7 @@ MaterialMenu 1.0 MaterialMenu.qml NozzleMenu 1.0 NozzleMenu.qml ActionPanelWidget 1.0 ActionPanelWidget.qml IconLabel 1.0 IconLabel.qml +IconWithText 1.0 IconWithText.qml OutputDevicesActionButton 1.0 OutputDevicesActionButton.qml ExpandableComponent 1.0 ExpandableComponent.qml PrinterTypeLabel 1.0 PrinterTypeLabel.qml diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 08ea73a7c5..dfaa9008f7 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -372,6 +372,7 @@ "print_setup_mode_toggle": [0.0, 2.0], "print_setup_item": [0.0, 2.0], "print_setup_extruder_box": [0.0, 6.0], + "print_setup_widget_header": [0.0, 3.0], "configuration_selector_mode_tabs": [0.0, 3.0], From b9d9a3586809b7e517550d402d31a9cf419e59ba Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Thu, 29 Nov 2018 00:00:22 +0100 Subject: [PATCH 0544/1292] Move profile dropdown to another file CURA-5941 --- resources/qml/GlobalProfileButton.qml | 89 ++++++++++++++++++++++++++ resources/qml/PrintSetupSelector.qml | 46 +++++++------ resources/qml/Settings/SettingView.qml | 89 +------------------------- 3 files changed, 115 insertions(+), 109 deletions(-) create mode 100644 resources/qml/GlobalProfileButton.qml diff --git a/resources/qml/GlobalProfileButton.qml b/resources/qml/GlobalProfileButton.qml new file mode 100644 index 0000000000..bac2732037 --- /dev/null +++ b/resources/qml/GlobalProfileButton.qml @@ -0,0 +1,89 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 +import QtQuick.Layouts 1.2 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +import "Menus" + +Item +{ + id: globalProfileRow + height: UM.Theme.getSize("print_setup_item").height + + Label + { + id: globalProfileLabel + text: catalog.i18nc("@label","Profile:") + textFormat: Text.PlainText + width: Math.round(parent.width * 0.45 - UM.Theme.getSize("thick_margin").width - 2) + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + verticalAlignment: Text.AlignVCenter + anchors.top: parent.top + anchors.bottom: parent.bottom + } + + ToolButton + { + id: globalProfileSelection + + text: generateActiveQualityText() + width: Math.round(parent.width * 0.55) + height: UM.Theme.getSize("setting_control").height + anchors.left: globalProfileLabel.right + anchors.right: parent.right + tooltip: Cura.MachineManager.activeQualityOrQualityChangesName + style: UM.Theme.styles.sidebar_header_button + activeFocusOnPress: true + menu: ProfileMenu { } + + function generateActiveQualityText () { + var result = Cura.MachineManager.activeQualityOrQualityChangesName; + + if (Cura.MachineManager.isActiveQualitySupported) { + if (Cura.MachineManager.activeQualityLayerHeight > 0) { + result += " " + result += " - " + result += Cura.MachineManager.activeQualityLayerHeight + "mm" + result += "" + } + } + + return result + } + + UM.SimpleButton + { + id: customisedSettings + + visible: Cura.MachineManager.hasUserSettings + height: Math.round(parent.height * 0.6) + width: Math.round(parent.height * 0.6) + + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: Math.round(UM.Theme.getSize("setting_preferences_button_margin").width - UM.Theme.getSize("thick_margin").width) + + color: hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button"); + iconSource: UM.Theme.getIcon("star"); + + onClicked: + { + forceActiveFocus(); + Cura.Actions.manageProfiles.trigger() + } + onEntered: + { + var content = catalog.i18nc("@tooltip","Some setting/override values are different from the values stored in the profile.\n\nClick to open the profile manager.") + base.showTooltip(globalProfileRow, Qt.point(-UM.Theme.getSize("thick_margin").width, 0), content) + } + onExited: base.hideTooltip() + } + } +} \ No newline at end of file diff --git a/resources/qml/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector.qml index 85472bae8d..855af9f9fa 100644 --- a/resources/qml/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector.qml @@ -126,7 +126,9 @@ Cura.ExpandableComponent popupItem: Rectangle { - property var total_height: popupItemHeader.height + popupItemContent.height + footerControll.height + UM.Theme.getSize("narrow_margin").height * 2 + + property var totalMargins: UM.Theme.getSize("narrow_margin").height * 11 + property var total_height: popupItemHeader.height + popupItemContent.height + totalMargins id: popupItemWrapper height: total_height @@ -157,9 +159,9 @@ Cura.ExpandableComponent anchors { - topMargin: UM.Theme.getSize("sidebar_margin").height + //topMargin: UM.Theme.getSize("sidebar_margin").height left: parent.left - leftMargin: UM.Theme.getSize("narrow_margin").height + leftMargin: UM.Theme.getSize("narrow_margin").height * 2 } } @@ -169,8 +171,6 @@ Cura.ExpandableComponent height: UM.Theme.getSize("default_lining").height anchors.top: popupItemHeaderText.bottom color: UM.Theme.getColor("action_button_border") - - } Button @@ -209,21 +209,33 @@ Cura.ExpandableComponent { id: popupItemContent width: parent.width - height: tabBar.height + sidebarContents.height + height: globalProfileRow.height + tabBar.height + UM.Theme.getSize("print_setup_widget").height - UM.Theme.getSize("print_setup_item").height anchors { top: popupItemHeader.bottom - topMargin: UM.Theme.getSize("narrow_margin").height + topMargin: UM.Theme.getSize("default_margin").height * 1.5 right: parent.right left: parent.left leftMargin: UM.Theme.getSize("default_margin").width rightMargin: UM.Theme.getSize("default_margin").width } + GlobalProfileButton + { + id: globalProfileRow + anchors + { + top: parent.top + left: parent.left + right: parent.right + } + } + UM.TabRow { id: tabBar - anchors.topMargin: UM.Theme.getSize("default_margin").height + anchors.top: globalProfileRow.bottom + anchors.topMargin: UM.Theme.getSize("default_margin").height * 1.5 onCurrentIndexChanged: Cura.ExtruderManager.setActiveExtruderIndex(currentIndex) z: 1 Repeater @@ -280,8 +292,6 @@ Cura.ExpandableComponent anchors.bottom: parent.bottom anchors.left: parent.left anchors.right: parent.right - height: UM.Theme.getSize("print_setup_widget").height - border.width: UM.Theme.getSize("default_lining").width * 2 border.color: UM.Theme.getColor("action_button_border") @@ -296,8 +306,8 @@ Cura.ExpandableComponent SidebarAdvanced { - anchors.topMargin: UM.Theme.getSize("print_setup_content_top_margin").height - anchors.bottomMargin: 2 //don't overlap bottom border + anchors.topMargin: Math.round(UM.Theme.getSize("wide_margin").height / 1.7) + anchors.bottomMargin: 2 //prevent bottom line overlapping anchors.fill: parent visible: currentModeIndex == 1 onShowTooltip: base.showTooltip(item, location, text) @@ -312,7 +322,6 @@ Cura.ExpandableComponent anchors.top: popupItemContent.bottom anchors.topMargin: UM.Theme.getSize("narrow_margin").height * 2 width: parent.width - height: settingControlButton.height + UM.Theme.getSize("default_lining").height * 4 Rectangle { width: parent.width @@ -330,9 +339,8 @@ Cura.ExpandableComponent { top: parent.top topMargin: UM.Theme.getSize("narrow_margin").height * 2 - bottomMargin: UM.Theme.getSize("narrow_margin").height * 2 right: parent.right - rightMargin: UM.Theme.getSize("narrow_margin").height + rightMargin: UM.Theme.getSize("narrow_margin").height * 2 } color: UM.Theme.getColor("secondary") @@ -349,14 +357,11 @@ Cura.ExpandableComponent { height: UM.Theme.getSize("action_panel_button").height text: catalog.i18nc("@button", "Recommended") - color: UM.Theme.getColor("secondary") hoverColor: UM.Theme.getColor("secondary") textColor: UM.Theme.getColor("primary") textHoverColor: UM.Theme.getColor("text") - iconSource: UM.Theme.getIcon("arrow_left") - width: UM.Theme.getSize("print_setup_action_button").width fixedWidthMode: true @@ -365,9 +370,8 @@ Cura.ExpandableComponent { top: parent.top topMargin: UM.Theme.getSize("narrow_margin").height * 2 - bottomMargin: UM.Theme.getSize("narrow_margin").height * 2 left: parent.left - leftMargin: UM.Theme.getSize("narrow_margin").height + leftMargin: UM.Theme.getSize("narrow_margin").height * 2 } MouseArea { @@ -376,7 +380,7 @@ Cura.ExpandableComponent } } } - + Component.onCompleted: { var index = Math.round(UM.Preferences.getValue("cura/active_mode")) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index cd9701aab6..3960f99aaa 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -21,92 +21,6 @@ Item signal showTooltip(Item item, point location, string text) signal hideTooltip() - Item - { - id: globalProfileRow - height: UM.Theme.getSize("print_setup_item").height - - anchors - { - top: parent.top - left: parent.left - leftMargin: Math.round(UM.Theme.getSize("thick_margin").width) - right: parent.right - rightMargin: Math.round(UM.Theme.getSize("thick_margin").width) - } - - Label - { - id: globalProfileLabel - text: catalog.i18nc("@label","Profile:") - textFormat: Text.PlainText - width: Math.round(parent.width * 0.45 - UM.Theme.getSize("thick_margin").width - 2) - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - verticalAlignment: Text.AlignVCenter - anchors.top: parent.top - anchors.bottom: parent.bottom - } - - ToolButton - { - id: globalProfileSelection - - text: generateActiveQualityText() - width: Math.round(parent.width * 0.55) - height: UM.Theme.getSize("setting_control").height - anchors.left: globalProfileLabel.right - anchors.right: parent.right - tooltip: Cura.MachineManager.activeQualityOrQualityChangesName - style: UM.Theme.styles.sidebar_header_button - activeFocusOnPress: true - menu: ProfileMenu { } - - function generateActiveQualityText () { - var result = Cura.MachineManager.activeQualityOrQualityChangesName; - - if (Cura.MachineManager.isActiveQualitySupported) { - if (Cura.MachineManager.activeQualityLayerHeight > 0) { - result += " " - result += " - " - result += Cura.MachineManager.activeQualityLayerHeight + "mm" - result += "" - } - } - - return result - } - - UM.SimpleButton - { - id: customisedSettings - - visible: Cura.MachineManager.hasUserSettings - height: Math.round(parent.height * 0.6) - width: Math.round(parent.height * 0.6) - - anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - anchors.rightMargin: Math.round(UM.Theme.getSize("setting_preferences_button_margin").width - UM.Theme.getSize("thick_margin").width) - - color: hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button"); - iconSource: UM.Theme.getIcon("star"); - - onClicked: - { - forceActiveFocus(); - Cura.Actions.manageProfiles.trigger() - } - onEntered: - { - var content = catalog.i18nc("@tooltip","Some setting/override values are different from the values stored in the profile.\n\nClick to open the profile manager.") - base.showTooltip(globalProfileRow, Qt.point(-UM.Theme.getSize("thick_margin").width, 0), content) - } - onExited: base.hideTooltip() - } - } - } - ToolButton { id: settingVisibilityMenu @@ -115,7 +29,6 @@ Item height: UM.Theme.getSize("setting_control").height anchors { - top: globalProfileRow.bottom topMargin: UM.Theme.getSize("thick_margin").height right: parent.right rightMargin: UM.Theme.getSize("thick_margin").width @@ -168,7 +81,7 @@ Item anchors { - top: globalProfileRow.bottom + //top: globalProfileRow.bottom topMargin: UM.Theme.getSize("thick_margin").height left: parent.left leftMargin: UM.Theme.getSize("thick_margin").width From 706fc311bccb730e82e48bf6c752e4bd0a3bf856 Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Thu, 29 Nov 2018 00:47:25 +0100 Subject: [PATCH 0545/1292] Added margins to the setting list CURA-5941 --- resources/qml/Settings/SettingCategory.qml | 4 ++-- resources/qml/Settings/SettingItem.qml | 4 ++-- resources/qml/Settings/SettingView.qml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/resources/qml/Settings/SettingCategory.qml b/resources/qml/Settings/SettingCategory.qml index aafe36c546..4ec6294d61 100644 --- a/resources/qml/Settings/SettingCategory.qml +++ b/resources/qml/Settings/SettingCategory.qml @@ -12,8 +12,8 @@ Button id: base anchors.left: parent.left anchors.right: parent.right - anchors.leftMargin: UM.Theme.getSize("thick_margin").width - anchors.rightMargin: UM.Theme.getSize("thick_margin").width + anchors.leftMargin: UM.Theme.getSize("default_margin").width + anchors.rightMargin: UM.Theme.getSize("default_margin").width * 3 hoverEnabled: true background: Rectangle diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index cad6a28bd6..036dcfeba4 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -108,7 +108,7 @@ Item { id: label; anchors.left: parent.left; - anchors.leftMargin: doDepthIndentation ? Math.round((UM.Theme.getSize("section_icon_column").width + 5) + ((definition.depth - 1) * UM.Theme.getSize("setting_control_depth_margin").width)) : 0 + anchors.leftMargin: doDepthIndentation ? Math.round((UM.Theme.getSize("section_icon_column").width / 1.2) + ((definition.depth - 1) * UM.Theme.getSize("setting_control_depth_margin").width)) : 0 anchors.right: settingControls.left; anchors.verticalCenter: parent.verticalCenter @@ -290,7 +290,7 @@ Item { enabled: propertyProvider.isValueUsed anchors.right: parent.right; - anchors.rightMargin: UM.Theme.getSize("thick_margin").width + anchors.rightMargin: UM.Theme.getSize("default_margin").width * 3 anchors.verticalCenter: parent.verticalCenter; width: UM.Theme.getSize("setting_control").width; height: UM.Theme.getSize("setting_control").height diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 3960f99aaa..8a336a7ed1 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -81,10 +81,9 @@ Item anchors { - //top: globalProfileRow.bottom topMargin: UM.Theme.getSize("thick_margin").height left: parent.left - leftMargin: UM.Theme.getSize("thick_margin").width + leftMargin: UM.Theme.getSize("default_margin").width right: settingVisibilityMenu.left rightMargin: Math.floor(UM.Theme.getSize("default_margin").width / 2) } @@ -202,6 +201,7 @@ Item anchors.right: parent.right; anchors.left: parent.left; anchors.topMargin: UM.Theme.getSize("thick_margin").height + anchors.rightMargin: UM.Theme.getSize("narrow_margin").height / 3 style: UM.Theme.styles.scrollview; flickableItem.flickableDirection: Flickable.VerticalFlick; From b44ddec01fcae8d748914a22062f11413870c7e2 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 29 Nov 2018 08:35:38 +0100 Subject: [PATCH 0546/1292] Change normal layer height of cocoon to 0.10 CURA-5902 So it's different from Fine 0.15, otherwise you get duplicates. --- resources/definitions/cocoon_create_modelmaker.def.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/definitions/cocoon_create_modelmaker.def.json b/resources/definitions/cocoon_create_modelmaker.def.json index 204d5b9492..921b20624a 100644 --- a/resources/definitions/cocoon_create_modelmaker.def.json +++ b/resources/definitions/cocoon_create_modelmaker.def.json @@ -51,7 +51,7 @@ "default_value": 220 }, "layer_height": { - "default_value": 0.15 + "default_value": 0.10 }, "layer_height_0": { "default_value": 0.2 From 7639983925f712a48a3a64bd71d221d2dcf3b4f2 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 29 Nov 2018 08:54:04 +0100 Subject: [PATCH 0547/1292] Clean the recommended mode print setup Contributes to CURA-5941 --- .../PrintSetupSelectorContents.qml | 31 - .../RecommendedPrintSetup.qml | 1205 ++++++++--------- 2 files changed, 580 insertions(+), 656 deletions(-) diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml index c36a0fbb80..6e71526f25 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml @@ -94,40 +94,10 @@ Item anchors { top: header.bottom - leftMargin: UM.Theme.getSize("default_margin").width - rightMargin: UM.Theme.getSize("default_margin").width } sourceComponent: currentModeIndex == 0 ? recommendedPrintSetup : customPrintSetup } -// Item -// { -// id: content -// width: parent.width -// height: 100 -////// height: tabBar.height + sidebarContents.height -//// -// anchors -// { -// top: header.bottom -// leftMargin: UM.Theme.getSize("default_margin").width -// rightMargin: UM.Theme.getSize("default_margin").width -// } -//// -//// Rectangle -//// { -//// id: sidebarContents -//// anchors.top: tabBar.bottom -//// anchors.bottom: parent.bottom -//// anchors.left: parent.left -//// anchors.right: parent.right -//// height: UM.Theme.getSize("print_setup_widget").height -//// -//// border.width: UM.Theme.getSize("default_lining").width * 2 -//// border.color: UM.Theme.getColor("action_button_border") -//// } -// } - Rectangle { id: buttonsSeparator @@ -195,7 +165,6 @@ Item Component.onCompleted: { - print(height, "!!!!!!!!!!!!!!!!!!!!!!!") var index = Math.round(UM.Preferences.getValue("cura/active_mode")) if(index != null && !isNaN(index)) diff --git a/resources/qml/PrintSetupSelector/RecommendedPrintSetup.qml b/resources/qml/PrintSetupSelector/RecommendedPrintSetup.qml index 5d195bdde4..b48282135b 100644 --- a/resources/qml/PrintSetupSelector/RecommendedPrintSetup.qml +++ b/resources/qml/PrintSetupSelector/RecommendedPrintSetup.qml @@ -8,17 +8,22 @@ import QtQuick.Controls.Styles 1.4 import UM 1.2 as UM import Cura 1.0 as Cura -Item +Column { id: base signal showTooltip(Item item, point location, string text) signal hideTooltip() - height: childrenRect.height + height: childrenRect.height + 2 * padding + + padding: UM.Theme.getSize("thick_margin").width + spacing: UM.Theme.getSize("default_margin").height property Action configureSettings property bool settingsEnabled: Cura.ExtruderManager.activeExtruderStackId || extrudersEnabledCount.properties.value == 1 + property real labelColumnWidth: Math.round(width / 3) + property real settingsColumnWidth: width - labelColumnWidth UM.I18nCatalog { @@ -33,10 +38,9 @@ Item { id: qualityRow - height: UM.Theme.getSize("thick_margin").height - anchors.topMargin: UM.Theme.getSize("thick_margin").height anchors.left: parent.left anchors.right: parent.right + height: childrenRect.height Timer { @@ -145,14 +149,14 @@ Item function calculateSliderStepWidth (totalTicks) { - qualityModel.qualitySliderStepWidth = totalTicks != 0 ? Math.round((base.width * 0.55) / (totalTicks)) : 0 + qualityModel.qualitySliderStepWidth = totalTicks != 0 ? Math.round((settingsColumnWidth) / (totalTicks)) : 0 } function calculateSliderMargins (availableMin, availableMax, totalTicks) { if (availableMin == -1 || (availableMin == 0 && availableMax == 0)) { - qualityModel.qualitySliderMarginRight = Math.round(base.width * 0.55) + qualityModel.qualitySliderMarginRight = Math.round(settingsColumnWidth) } else if (availableMin == availableMax) { @@ -180,6 +184,7 @@ Item source: UM.Theme.getIcon("category_layer_height") text: catalog.i18nc("@label", "Layer Height") anchors.bottom: speedSlider.bottom + width: labelColumnWidth } // Show titles for the each quality slider ticks @@ -187,6 +192,7 @@ Item { anchors.left: speedSlider.left anchors.top: speedSlider.bottom + Repeater { model: qualityModel @@ -194,7 +200,7 @@ Item Label { anchors.verticalCenter: parent.verticalCenter - anchors.top: parent.bottom + anchors.top: parent.top color: (Cura.MachineManager.activeMachine != null && Cura.QualityProfilesDropDownMenuModel.getItem(index).available) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") text: { @@ -225,19 +231,19 @@ Item if (qualityModel.totalTicks == 0) { // If there is only one tick, align it centrally - return Math.round(((base.width * 0.55) - width) / 2) + return Math.round(((settingsColumnWidth) - width) / 2) } else if (index == 0) { - return Math.round(base.width * 0.55 / qualityModel.totalTicks) * index + return Math.round(settingsColumnWidth / qualityModel.totalTicks) * index } else if (index == qualityModel.totalTicks) { - return Math.round(base.width * 0.55 / qualityModel.totalTicks) * index - width + return Math.round(settingsColumnWidth / qualityModel.totalTicks) * index - width } else { - return Math.round((base.width * 0.55 / qualityModel.totalTicks) * index - (width / 2)) + return Math.round((settingsColumnWidth / qualityModel.totalTicks) * index - (width / 2)) } } } @@ -248,126 +254,127 @@ Item Rectangle { id: speedSlider - width: Math.round(base.width * 0.55) - height: UM.Theme.getSize("thick_margin").height - anchors.right: parent.right - anchors.top: parent.top - anchors.topMargin: UM.Theme.getSize("thick_margin").height + + anchors + { + left: qualityRowTitle.right + right: parent.right + } // This Item is used only for tooltip, for slider area which is unavailable - Item - { - function showTooltip (showTooltip) - { - if (showTooltip) - { - var content = catalog.i18nc("@tooltip", "This quality profile is not available for you current material and nozzle configuration. Please change these to enable this quality profile") - base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), content) - } - else - { - base.hideTooltip() - } - } - - id: unavailableLineToolTip - height: 20 * screenScaleFactor // hovered area height - z: parent.z + 1 // should be higher, otherwise the area can be hovered - x: 0 - anchors.verticalCenter: qualitySlider.verticalCenter - - Rectangle - { - id: leftArea - width: - { - if (qualityModel.availableTotalTicks == 0) - { - return qualityModel.qualitySliderStepWidth * qualityModel.totalTicks - } - return qualityModel.qualitySliderStepWidth * qualityModel.qualitySliderAvailableMin - 10 - } - height: parent.height - color: "transparent" - - MouseArea - { - anchors.fill: parent - hoverEnabled: true - enabled: Cura.SimpleModeSettingsManager.isProfileUserCreated == false - onEntered: unavailableLineToolTip.showTooltip(true) - onExited: unavailableLineToolTip.showTooltip(false) - } - } - - Item - { - id: rightArea - width: - { - if(qualityModel.availableTotalTicks == 0) - return 0 - - return qualityModel.qualitySliderMarginRight - 10 - } - height: parent.height - x: - { - if (qualityModel.availableTotalTicks == 0) - { - return 0 - } - - var leftUnavailableArea = qualityModel.qualitySliderStepWidth * qualityModel.qualitySliderAvailableMin - var totalGap = qualityModel.qualitySliderStepWidth * (qualityModel.availableTotalTicks -1) + leftUnavailableArea + 10 - - return totalGap - } - - MouseArea - { - anchors.fill: parent - hoverEnabled: true - enabled: Cura.SimpleModeSettingsManager.isProfileUserCreated == false - onEntered: unavailableLineToolTip.showTooltip(true) - onExited: unavailableLineToolTip.showTooltip(false) - } - } - } +// Item +// { +// function showTooltip (showTooltip) +// { +// if (showTooltip) +// { +// var content = catalog.i18nc("@tooltip", "This quality profile is not available for you current material and nozzle configuration. Please change these to enable this quality profile") +// base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), content) +// } +// else +// { +// base.hideTooltip() +// } +// } +// +// id: unavailableLineToolTip +// height: 20 * screenScaleFactor // hovered area height +// z: parent.z + 1 // should be higher, otherwise the area can be hovered +// x: 0 +// anchors.verticalCenter: qualitySlider.verticalCenter +// +// Rectangle +// { +// id: leftArea +// width: +// { +// if (qualityModel.availableTotalTicks == 0) +// { +// return qualityModel.qualitySliderStepWidth * qualityModel.totalTicks +// } +// return qualityModel.qualitySliderStepWidth * qualityModel.qualitySliderAvailableMin - 10 +// } +// height: parent.height +// color: "transparent" +// +// MouseArea +// { +// anchors.fill: parent +// hoverEnabled: true +// enabled: Cura.SimpleModeSettingsManager.isProfileUserCreated == false +// onEntered: unavailableLineToolTip.showTooltip(true) +// onExited: unavailableLineToolTip.showTooltip(false) +// } +// } +// +// Item +// { +// id: rightArea +// width: +// { +// if(qualityModel.availableTotalTicks == 0) +// return 0 +// +// return qualityModel.qualitySliderMarginRight - 10 +// } +// height: parent.height +// x: +// { +// if (qualityModel.availableTotalTicks == 0) +// { +// return 0 +// } +// +// var leftUnavailableArea = qualityModel.qualitySliderStepWidth * qualityModel.qualitySliderAvailableMin +// var totalGap = qualityModel.qualitySliderStepWidth * (qualityModel.availableTotalTicks -1) + leftUnavailableArea + 10 +// +// return totalGap +// } +// +// MouseArea +// { +// anchors.fill: parent +// hoverEnabled: true +// enabled: Cura.SimpleModeSettingsManager.isProfileUserCreated == false +// onEntered: unavailableLineToolTip.showTooltip(true) +// onExited: unavailableLineToolTip.showTooltip(false) +// } +// } +// } // Draw Unavailable line Rectangle { id: groovechildrect - width: Math.round(base.width * 0.55) + width: parent.width height: 2 * screenScaleFactor color: UM.Theme.getColor("quality_slider_unavailable") anchors.verticalCenter: qualitySlider.verticalCenter - x: 0 - } - // Draw ticks - Repeater - { - id: qualityRepeater - model: qualityModel.totalTicks > 0 ? qualityModel : 0 - - Rectangle + // Draw ticks + Repeater { - color: Cura.QualityProfilesDropDownMenuModel.getItem(index).available ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") - implicitWidth: 5 * screenScaleFactor - implicitHeight: implicitWidth - anchors.verticalCenter: qualitySlider.verticalCenter - x: Math.round(qualityModel.qualitySliderStepWidth * index) - radius: Math.round(implicitWidth / 2) + id: qualityRepeater + model: qualityModel.totalTicks > 0 ? qualityModel : 0 + + Rectangle + { + color: Cura.QualityProfilesDropDownMenuModel.getItem(index).available ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") + implicitWidth: 4 * screenScaleFactor + implicitHeight: implicitWidth + anchors.verticalCenter: parent.verticalCenter + x: Math.round(qualityModel.qualitySliderStepWidth * index) + radius: Math.round(implicitWidth / 2) + } } } + // Draw available slider Slider { id: qualitySlider height: UM.Theme.getSize("thick_margin").height - anchors.bottom: speedSlider.bottom + anchors.bottom: parent.bottom enabled: qualityModel.totalTicks > 0 && !Cura.SimpleModeSettingsManager.isProfileCustomized visible: qualityModel.availableTotalTicks > 0 updateValueWhileDragging : false @@ -394,18 +401,15 @@ Item color: UM.Theme.getColor("quality_slider_available") radius: Math.round(height / 2) } - handle: Item + + handle: Rectangle { - Rectangle - { - id: qualityhandleButton - anchors.centerIn: parent - color: UM.Theme.getColor("quality_slider_available") - implicitWidth: 10 * screenScaleFactor - implicitHeight: implicitWidth - radius: Math.round(implicitWidth / 2) - visible: !Cura.SimpleModeSettingsManager.isProfileCustomized && !Cura.SimpleModeSettingsManager.isProfileUserCreated && qualityModel.existingQualityProfile - } + id: qualityhandleButton + color: UM.Theme.getColor("quality_slider_available") + implicitWidth: 12 * screenScaleFactor + implicitHeight: implicitWidth + radius: Math.round(implicitWidth / 2) + visible: !Cura.SimpleModeSettingsManager.isProfileCustomized && !Cura.SimpleModeSettingsManager.isProfileUserCreated && qualityModel.existingQualityProfile } } @@ -433,7 +437,7 @@ Item onEntered: { - var content = catalog.i18nc("@tooltip","A custom profile is currently active. To enable the quality slider, choose a default quality profile in Custom tab") + var content = catalog.i18nc("@tooltip", "A custom profile is currently active. To enable the quality slider, choose a default quality profile in Custom tab") base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), content) } onExited: base.hideTooltip() @@ -474,329 +478,319 @@ Item // Item { - id: infillCellLeft - - anchors.top: qualityRow.bottom - anchors.topMargin: UM.Theme.getSize("thick_margin").height * 2 anchors.left: parent.left - - width: Math.round(UM.Theme.getSize("print_setup_widget").width * .45) - UM.Theme.getSize("thick_margin").width + anchors.right: parent.right + height: childrenRect.height Cura.IconWithText { - id: infillLabel + id: infillRowTitle source: UM.Theme.getIcon("category_infill") text: catalog.i18nc("@label", "Infill") + " (%)" - - anchors - { - top: parent.top - topMargin: Math.round(UM.Theme.getSize("thick_margin").height * 1.7) - left: parent.left - } + anchors.bottom: parent.bottom + width: labelColumnWidth } - } - Item - { - id: infillCellRight + Item + { + id: infillCellRight - height: infillSlider.height + UM.Theme.getSize("thick_margin").height + enableGradualInfillCheckBox.visible * (enableGradualInfillCheckBox.height + UM.Theme.getSize("thick_margin").height) - width: Math.round(UM.Theme.getSize("print_setup_widget").width * .55) + height: infillSlider.height + UM.Theme.getSize("thick_margin").height + enableGradualInfillCheckBox.visible * (enableGradualInfillCheckBox.height + UM.Theme.getSize("thick_margin").height) - anchors.left: infillCellLeft.right - anchors.top: infillCellLeft.top - anchors.topMargin: UM.Theme.getSize("thick_margin").height - - Label { - id: selectedInfillRateText - - anchors.left: infillSlider.left + anchors.left: infillRowTitle.right anchors.right: parent.right - text: parseInt(infillDensity.properties.value) + "%" - horizontalAlignment: Text.AlignLeft - - color: infillSlider.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") - } - - // We use a binding to make sure that after manually setting infillSlider.value it is still bound to the property provider - Binding - { - target: infillSlider - property: "value" - value: parseInt(infillDensity.properties.value) - } - - Slider - { - id: infillSlider - - anchors.top: selectedInfillRateText.bottom - anchors.left: parent.left - anchors.right: infillIcon.left - anchors.rightMargin: UM.Theme.getSize("thick_margin").width - - height: UM.Theme.getSize("thick_margin").height - width: parseInt(infillCellRight.width - UM.Theme.getSize("thick_margin").width - style.handleWidth) - - minimumValue: 0 - maximumValue: 100 - stepSize: 1 - tickmarksEnabled: true - - // disable slider when gradual support is enabled - enabled: parseInt(infillSteps.properties.value) == 0 - - // set initial value from stack - value: parseInt(infillDensity.properties.value) - - onValueChanged: - { - - // Don't round the value if it's already the same - if (parseInt(infillDensity.properties.value) == infillSlider.value) - { - return - } - - // Round the slider value to the nearest multiple of 10 (simulate step size of 10) - var roundedSliderValue = Math.round(infillSlider.value / 10) * 10 - - // Update the slider value to represent the rounded value - infillSlider.value = roundedSliderValue - - // Update value only if the Recomended mode is Active, - // Otherwise if I change the value in the Custom mode the Recomended view will try to repeat - // same operation - var active_mode = UM.Preferences.getValue("cura/active_mode") - - if (active_mode == 0 || active_mode == "simple") - { - Cura.MachineManager.setSettingForAllExtruders("infill_sparse_density", "value", roundedSliderValue) - Cura.MachineManager.resetSettingForAllExtruders("infill_line_distance") - } - } - - style: SliderStyle - { - groove: Rectangle - { - id: groove - implicitWidth: 200 * screenScaleFactor - implicitHeight: 2 * screenScaleFactor - color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") - radius: 1 - } - - handle: Item - { - Rectangle - { - id: handleButton - anchors.centerIn: parent - color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") - implicitWidth: 10 * screenScaleFactor - implicitHeight: 10 * screenScaleFactor - radius: 10 * screenScaleFactor - } - } - - tickmarks: Repeater - { - id: repeater - model: control.maximumValue / control.stepSize + 1 - - // check if a tick should be shown based on it's index and wether the infill density is a multiple of 10 (slider step size) - function shouldShowTick (index) - { - if (index % 10 == 0) - { - return true - } - return false - } - - Rectangle - { - anchors.verticalCenter: parent.verticalCenter - color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") - width: 1 * screenScaleFactor - height: 6 * screenScaleFactor - x: Math.round(styleData.handleWidth / 2 + index * ((repeater.width - styleData.handleWidth) / (repeater.count-1))) - visible: shouldShowTick(index) - } - } - } - } - - Rectangle - { - id: infillIcon - - width: Math.round((parent.width / 5) - (UM.Theme.getSize("thick_margin").width)) - height: width - - anchors.right: parent.right - anchors.top: parent.top - anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height / 2) - - // we loop over all density icons and only show the one that has the current density and steps - Repeater - { - id: infillIconList - model: infillModel - anchors.fill: parent - - function activeIndex () - { - for (var i = 0; i < infillModel.count; i++) - { - var density = Math.round(infillDensity.properties.value) - var steps = Math.round(infillSteps.properties.value) - var infillModelItem = infillModel.get(i) - - if (infillModelItem != "undefined" - && density >= infillModelItem.percentageMin - && density <= infillModelItem.percentageMax - && steps >= infillModelItem.stepsMin - && steps <= infillModelItem.stepsMax) - { - return i - } - } - return -1 - } - - Rectangle - { - anchors.fill: parent - visible: infillIconList.activeIndex() == index - - border.width: UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("quality_slider_unavailable") - - UM.RecolorImage - { - anchors.fill: parent - anchors.margins: 2 * screenScaleFactor - sourceSize.width: width - sourceSize.height: width - source: UM.Theme.getIcon(model.icon) - color: UM.Theme.getColor("quality_slider_unavailable") - } - } - } - } - - // Gradual Support Infill Checkbox - CheckBox - { - id: enableGradualInfillCheckBox - property alias _hovered: enableGradualInfillMouseArea.containsMouse - - anchors.top: infillSlider.bottom - anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height / 2) // closer to slider since it belongs to the same category - anchors.left: infillCellRight.left - - style: UM.Theme.styles.checkbox - enabled: base.settingsEnabled - visible: infillSteps.properties.enabled == "True" - checked: parseInt(infillSteps.properties.value) > 0 - - MouseArea - { - id: enableGradualInfillMouseArea - - anchors.fill: parent - hoverEnabled: true - enabled: true - - property var previousInfillDensity: parseInt(infillDensity.properties.value) - - onClicked: - { - // Set to 90% only when enabling gradual infill - var newInfillDensity; - if (parseInt(infillSteps.properties.value) == 0) - { - previousInfillDensity = parseInt(infillDensity.properties.value) - newInfillDensity = 90 - } else { - newInfillDensity = previousInfillDensity - } - Cura.MachineManager.setSettingForAllExtruders("infill_sparse_density", "value", String(newInfillDensity)) - - var infill_steps_value = 0 - if (parseInt(infillSteps.properties.value) == 0) - { - infill_steps_value = 5 - } - - Cura.MachineManager.setSettingForAllExtruders("gradual_infill_steps", "value", infill_steps_value) - } - - onEntered: base.showTooltip(enableGradualInfillCheckBox, Qt.point(-infillCellRight.x, 0), - catalog.i18nc("@label", "Gradual infill will gradually increase the amount of infill towards the top.")) - - onExited: base.hideTooltip() - - } - Label { - id: gradualInfillLabel - height: parent.height - anchors.left: enableGradualInfillCheckBox.right - anchors.leftMargin: Math.round(UM.Theme.getSize("thick_margin").width / 2) - verticalAlignment: Text.AlignVCenter; - text: catalog.i18nc("@label", "Enable gradual") - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - } - } + id: selectedInfillRateText - // Infill list model for mapping icon - ListModel - { - id: infillModel - Component.onCompleted: + anchors.left: infillSlider.left + anchors.right: parent.right + + text: parseInt(infillDensity.properties.value) + "%" + horizontalAlignment: Text.AlignLeft + + color: infillSlider.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") + } + + // We use a binding to make sure that after manually setting infillSlider.value it is still bound to the property provider + Binding { - infillModel.append({ - percentageMin: -1, - percentageMax: 0, - stepsMin: -1, - stepsMax: 0, - icon: "hollow" - }) - infillModel.append({ - percentageMin: 0, - percentageMax: 40, - stepsMin: -1, - stepsMax: 0, - icon: "sparse" - }) - infillModel.append({ - percentageMin: 40, - percentageMax: 89, - stepsMin: -1, - stepsMax: 0, - icon: "dense" - }) - infillModel.append({ - percentageMin: 90, - percentageMax: 9999999999, - stepsMin: -1, - stepsMax: 0, - icon: "solid" - }) - infillModel.append({ - percentageMin: 0, - percentageMax: 9999999999, - stepsMin: 1, - stepsMax: 9999999999, - icon: "gradual" - }) + target: infillSlider + property: "value" + value: parseInt(infillDensity.properties.value) + } + + Slider + { + id: infillSlider + + anchors.top: selectedInfillRateText.bottom + anchors.left: parent.left + anchors.right: infillIcon.left + anchors.rightMargin: UM.Theme.getSize("thick_margin").width + + height: UM.Theme.getSize("thick_margin").height + width: parseInt(infillCellRight.width - UM.Theme.getSize("thick_margin").width - style.handleWidth) + + minimumValue: 0 + maximumValue: 100 + stepSize: 1 + tickmarksEnabled: true + + // disable slider when gradual support is enabled + enabled: parseInt(infillSteps.properties.value) == 0 + + // set initial value from stack + value: parseInt(infillDensity.properties.value) + + onValueChanged: + { + + // Don't round the value if it's already the same + if (parseInt(infillDensity.properties.value) == infillSlider.value) + { + return + } + + // Round the slider value to the nearest multiple of 10 (simulate step size of 10) + var roundedSliderValue = Math.round(infillSlider.value / 10) * 10 + + // Update the slider value to represent the rounded value + infillSlider.value = roundedSliderValue + + // Update value only if the Recomended mode is Active, + // Otherwise if I change the value in the Custom mode the Recomended view will try to repeat + // same operation + var active_mode = UM.Preferences.getValue("cura/active_mode") + + if (active_mode == 0 || active_mode == "simple") + { + Cura.MachineManager.setSettingForAllExtruders("infill_sparse_density", "value", roundedSliderValue) + Cura.MachineManager.resetSettingForAllExtruders("infill_line_distance") + } + } + + style: SliderStyle + { + groove: Rectangle + { + id: groove + implicitWidth: 200 * screenScaleFactor + implicitHeight: 2 * screenScaleFactor + color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") + radius: 1 + } + + handle: Item + { + Rectangle + { + id: handleButton + anchors.centerIn: parent + color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") + implicitWidth: 10 * screenScaleFactor + implicitHeight: 10 * screenScaleFactor + radius: 10 * screenScaleFactor + } + } + + tickmarks: Repeater + { + id: repeater + model: control.maximumValue / control.stepSize + 1 + + // check if a tick should be shown based on it's index and wether the infill density is a multiple of 10 (slider step size) + function shouldShowTick (index) + { + if (index % 10 == 0) + { + return true + } + return false + } + + Rectangle + { + anchors.verticalCenter: parent.verticalCenter + color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") + width: 1 * screenScaleFactor + height: 6 * screenScaleFactor + x: Math.round(styleData.handleWidth / 2 + index * ((repeater.width - styleData.handleWidth) / (repeater.count-1))) + visible: shouldShowTick(index) + } + } + } + } + + Rectangle + { + id: infillIcon + + width: Math.round((parent.width / 5) - (UM.Theme.getSize("thick_margin").width)) + height: width + + anchors.right: parent.right + anchors.top: parent.top + anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height / 2) + + // we loop over all density icons and only show the one that has the current density and steps + Repeater + { + id: infillIconList + model: infillModel + anchors.fill: parent + + function activeIndex () + { + for (var i = 0; i < infillModel.count; i++) + { + var density = Math.round(infillDensity.properties.value) + var steps = Math.round(infillSteps.properties.value) + var infillModelItem = infillModel.get(i) + + if (infillModelItem != "undefined" + && density >= infillModelItem.percentageMin + && density <= infillModelItem.percentageMax + && steps >= infillModelItem.stepsMin + && steps <= infillModelItem.stepsMax) + { + return i + } + } + return -1 + } + + Rectangle + { + anchors.fill: parent + visible: infillIconList.activeIndex() == index + + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("quality_slider_unavailable") + + UM.RecolorImage + { + anchors.fill: parent + anchors.margins: 2 * screenScaleFactor + sourceSize.width: width + sourceSize.height: width + source: UM.Theme.getIcon(model.icon) + color: UM.Theme.getColor("quality_slider_unavailable") + } + } + } + } + + // Gradual Support Infill Checkbox + CheckBox + { + id: enableGradualInfillCheckBox + property alias _hovered: enableGradualInfillMouseArea.containsMouse + + anchors.top: infillSlider.bottom + anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height / 2) // closer to slider since it belongs to the same category + anchors.left: infillCellRight.left + + style: UM.Theme.styles.checkbox + enabled: base.settingsEnabled + visible: infillSteps.properties.enabled == "True" + checked: parseInt(infillSteps.properties.value) > 0 + + MouseArea + { + id: enableGradualInfillMouseArea + + anchors.fill: parent + hoverEnabled: true + enabled: true + + property var previousInfillDensity: parseInt(infillDensity.properties.value) + + onClicked: + { + // Set to 90% only when enabling gradual infill + var newInfillDensity; + if (parseInt(infillSteps.properties.value) == 0) + { + previousInfillDensity = parseInt(infillDensity.properties.value) + newInfillDensity = 90 + } else { + newInfillDensity = previousInfillDensity + } + Cura.MachineManager.setSettingForAllExtruders("infill_sparse_density", "value", String(newInfillDensity)) + + var infill_steps_value = 0 + if (parseInt(infillSteps.properties.value) == 0) + { + infill_steps_value = 5 + } + + Cura.MachineManager.setSettingForAllExtruders("gradual_infill_steps", "value", infill_steps_value) + } + + onEntered: base.showTooltip(enableGradualInfillCheckBox, Qt.point(-infillCellRight.x, 0), + catalog.i18nc("@label", "Gradual infill will gradually increase the amount of infill towards the top.")) + + onExited: base.hideTooltip() + + } + + Label + { + id: gradualInfillLabel + height: parent.height + anchors.left: enableGradualInfillCheckBox.right + anchors.leftMargin: Math.round(UM.Theme.getSize("thick_margin").width / 2) + verticalAlignment: Text.AlignVCenter; + text: catalog.i18nc("@label", "Enable gradual") + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + } + } + + // Infill list model for mapping icon + ListModel + { + id: infillModel + Component.onCompleted: + { + infillModel.append({ + percentageMin: -1, + percentageMax: 0, + stepsMin: -1, + stepsMax: 0, + icon: "hollow" + }) + infillModel.append({ + percentageMin: 0, + percentageMax: 40, + stepsMin: -1, + stepsMax: 0, + icon: "sparse" + }) + infillModel.append({ + percentageMin: 40, + percentageMax: 89, + stepsMin: -1, + stepsMax: 0, + icon: "dense" + }) + infillModel.append({ + percentageMin: 90, + percentageMax: 9999999999, + stepsMin: -1, + stepsMax: 0, + icon: "solid" + }) + infillModel.append({ + percentageMin: 0, + percentageMax: 9999999999, + stepsMin: 1, + stepsMax: 9999999999, + icon: "gradual" + }) + } } } } @@ -804,191 +798,177 @@ Item // // Enable support // - Cura.IconWithText + Row { - id: enableSupportLabel - visible: enableSupportCheckBox.visible - source: UM.Theme.getIcon("category_support") - text: catalog.i18nc("@label", "Support") + anchors.left: parent.left + anchors.right: parent.right + height: childrenRect.height - anchors + Cura.IconWithText { - top: infillCellRight.bottom - topMargin: Math.round(UM.Theme.getSize("thick_margin").height * 1.5) - left: parent.left - right: infillCellLeft.right - rightMargin: UM.Theme.getSize("thick_margin").width - verticalCenter: enableSupportCheckBox.verticalCenter - } - } - - CheckBox - { - id: enableSupportCheckBox - property alias _hovered: enableSupportMouseArea.containsMouse - - anchors.top: enableSupportLabel.top - anchors.left: infillCellRight.left - - style: UM.Theme.styles.checkbox - enabled: base.settingsEnabled - - visible: supportEnabled.properties.enabled == "True" - checked: supportEnabled.properties.value == "True" - - MouseArea - { - id: enableSupportMouseArea - anchors.fill: parent - hoverEnabled: true - onClicked: supportEnabled.setPropertyValue("value", supportEnabled.properties.value != "True") - - onEntered: base.showTooltip(enableSupportCheckBox, Qt.point(-enableSupportCheckBox.x, 0), - catalog.i18nc("@label", "Generate structures to support parts of the model which have overhangs. Without these structures, such parts would collapse during printing.")) - - onExited: base.hideTooltip() - - } - } - - ComboBox - { - id: supportExtruderCombobox - visible: enableSupportCheckBox.visible && (supportEnabled.properties.value == "True") && (extrudersEnabledCount.properties.value > 1) - model: extruderModel - - property string color_override: "" // for manually setting values - property string color: // is evaluated automatically, but the first time is before extruderModel being filled - { - var current_extruder = extruderModel.get(currentIndex); - color_override = ""; - if (current_extruder === undefined) return "" - return (current_extruder.color) ? current_extruder.color : ""; + id: enableSupportLabel + visible: enableSupportCheckBox.visible + source: UM.Theme.getIcon("category_support") + text: catalog.i18nc("@label", "Support") + width: labelColumnWidth } - textRole: "text" // this solves that the combobox isn't populated in the first time Cura is started - - anchors.top: enableSupportCheckBox.top - - anchors.left: enableSupportCheckBox.right - anchors.leftMargin: Math.round(UM.Theme.getSize("thick_margin").width / 2) - - width: Math.round(UM.Theme.getSize("print_setup_widget").width * .55) - Math.round(UM.Theme.getSize("thick_margin").width / 2) - enableSupportCheckBox.width - height: ((supportEnabled.properties.value == "True") && (machineExtruderCount.properties.value > 1)) ? UM.Theme.getSize("setting_control").height : 0 - - Behavior on height { NumberAnimation { duration: 100 } } - - style: UM.Theme.styles.combobox_color - enabled: base.settingsEnabled - property alias _hovered: supportExtruderMouseArea.containsMouse - - currentIndex: + CheckBox { - if (supportExtruderNr.properties == null) + id: enableSupportCheckBox + property alias _hovered: enableSupportMouseArea.containsMouse + + style: UM.Theme.styles.checkbox + enabled: base.settingsEnabled + + visible: supportEnabled.properties.enabled == "True" + checked: supportEnabled.properties.value == "True" + + MouseArea { - return Cura.MachineManager.defaultExtruderPosition + id: enableSupportMouseArea + anchors.fill: parent + hoverEnabled: true + onClicked: supportEnabled.setPropertyValue("value", supportEnabled.properties.value != "True") + + onEntered: base.showTooltip(enableSupportCheckBox, Qt.point(-enableSupportCheckBox.x, 0), + catalog.i18nc("@label", "Generate structures to support parts of the model which have overhangs. Without these structures, such parts would collapse during printing.")) + + onExited: base.hideTooltip() + } - else + } + + ComboBox + { + id: supportExtruderCombobox + visible: enableSupportCheckBox.visible && (supportEnabled.properties.value == "True") && (extrudersEnabledCount.properties.value > 1) + model: extruderModel + + property string color_override: "" // for manually setting values + property string color: // is evaluated automatically, but the first time is before extruderModel being filled { - var extruder = parseInt(supportExtruderNr.properties.value) - if ( extruder === -1) + var current_extruder = extruderModel.get(currentIndex); + color_override = ""; + if (current_extruder === undefined) return "" + return (current_extruder.color) ? current_extruder.color : ""; + } + + textRole: "text" // this solves that the combobox isn't populated in the first time Cura is started + + width: Math.round(UM.Theme.getSize("print_setup_widget").width * .55) - Math.round(UM.Theme.getSize("thick_margin").width / 2) - enableSupportCheckBox.width + height: ((supportEnabled.properties.value == "True") && (machineExtruderCount.properties.value > 1)) ? UM.Theme.getSize("setting_control").height : 0 + + Behavior on height { NumberAnimation { duration: 100 } } + + style: UM.Theme.styles.combobox_color + enabled: base.settingsEnabled + property alias _hovered: supportExtruderMouseArea.containsMouse + + currentIndex: + { + if (supportExtruderNr.properties == null) { return Cura.MachineManager.defaultExtruderPosition } - return extruder; - } - } - - onActivated: supportExtruderNr.setPropertyValue("value", String(index)) - - MouseArea - { - id: supportExtruderMouseArea - anchors.fill: parent - hoverEnabled: true - enabled: base.settingsEnabled - acceptedButtons: Qt.NoButton - onEntered: - { - base.showTooltip(supportExtruderCombobox, Qt.point(-supportExtruderCombobox.x, 0), - catalog.i18nc("@label", "Select which extruder to use for support. This will build up supporting structures below the model to prevent the model from sagging or printing in mid air.")); - } - onExited: base.hideTooltip() - - } - - function updateCurrentColor() - { - var current_extruder = extruderModel.get(currentIndex) - if (current_extruder !== undefined) - { - supportExtruderCombobox.color_override = current_extruder.color - } - } - - } - - Cura.IconWithText - { - id: adhesionHelperLabel - visible: adhesionCheckBox.visible - source: UM.Theme.getIcon("category_adhesion") - text: catalog.i18nc("@label", "Adhesion") - - anchors - { - left: parent.left - right: infillCellLeft.right - rightMargin: UM.Theme.getSize("thick_margin").width - verticalCenter: adhesionCheckBox.verticalCenter - } - } - - CheckBox - { - id: adhesionCheckBox - property alias _hovered: adhesionMouseArea.containsMouse - - anchors.top: enableSupportCheckBox.bottom - anchors.topMargin: UM.Theme.getSize("thick_margin").height - anchors.left: infillCellRight.left - - //: Setting enable printing build-plate adhesion helper checkbox - style: UM.Theme.styles.checkbox - enabled: base.settingsEnabled - - visible: platformAdhesionType.properties.enabled == "True" - checked: platformAdhesionType.properties.value != "skirt" && platformAdhesionType.properties.value != "none" - - MouseArea - { - id: adhesionMouseArea - anchors.fill: parent - hoverEnabled: true - enabled: base.settingsEnabled - onClicked: - { - var adhesionType = "skirt" - if(!parent.checked) + else { - // Remove the "user" setting to see if the rest of the stack prescribes a brim or a raft - platformAdhesionType.removeFromContainer(0) - adhesionType = platformAdhesionType.properties.value - if(adhesionType == "skirt" || adhesionType == "none") + var extruder = parseInt(supportExtruderNr.properties.value) + if ( extruder === -1) { - // If the rest of the stack doesn't prescribe an adhesion-type, default to a brim - adhesionType = "brim" + return Cura.MachineManager.defaultExtruderPosition } + return extruder; } - platformAdhesionType.setPropertyValue("value", adhesionType) } - onEntered: - { - base.showTooltip(adhesionCheckBox, Qt.point(-adhesionCheckBox.x, 0), - catalog.i18nc("@label", "Enable printing a brim or raft. This will add a flat area around or under your object which is easy to cut off afterwards.")); - } - onExited: base.hideTooltip() + onActivated: supportExtruderNr.setPropertyValue("value", String(index)) + + MouseArea + { + id: supportExtruderMouseArea + anchors.fill: parent + hoverEnabled: true + enabled: base.settingsEnabled + acceptedButtons: Qt.NoButton + onEntered: + { + base.showTooltip(supportExtruderCombobox, Qt.point(-supportExtruderCombobox.x, 0), + catalog.i18nc("@label", "Select which extruder to use for support. This will build up supporting structures below the model to prevent the model from sagging or printing in mid air.")); + } + onExited: base.hideTooltip() + + } + + function updateCurrentColor() + { + var current_extruder = extruderModel.get(currentIndex) + if (current_extruder !== undefined) + { + supportExtruderCombobox.color_override = current_extruder.color + } + } + + } + } + + // Adhesion + Row + { + anchors.left: parent.left + anchors.right: parent.right + height: childrenRect.height + + Cura.IconWithText + { + id: adhesionHelperLabel + visible: adhesionCheckBox.visible + source: UM.Theme.getIcon("category_adhesion") + text: catalog.i18nc("@label", "Adhesion") + width: labelColumnWidth + } + + CheckBox + { + id: adhesionCheckBox + property alias _hovered: adhesionMouseArea.containsMouse + + //: Setting enable printing build-plate adhesion helper checkbox + style: UM.Theme.styles.checkbox + enabled: base.settingsEnabled + + visible: platformAdhesionType.properties.enabled == "True" + checked: platformAdhesionType.properties.value != "skirt" && platformAdhesionType.properties.value != "none" + + MouseArea + { + id: adhesionMouseArea + anchors.fill: parent + hoverEnabled: true + enabled: base.settingsEnabled + onClicked: + { + var adhesionType = "skirt" + if(!parent.checked) + { + // Remove the "user" setting to see if the rest of the stack prescribes a brim or a raft + platformAdhesionType.removeFromContainer(0) + adhesionType = platformAdhesionType.properties.value + if(adhesionType == "skirt" || adhesionType == "none") + { + // If the rest of the stack doesn't prescribe an adhesion-type, default to a brim + adhesionType = "brim" + } + } + platformAdhesionType.setPropertyValue("value", adhesionType) + } + onEntered: + { + base.showTooltip(adhesionCheckBox, Qt.point(-adhesionCheckBox.x, 0), + catalog.i18nc("@label", "Enable printing a brim or raft. This will add a flat area around or under your object which is easy to cut off afterwards.")); + } + onExited: base.hideTooltip() + } } } @@ -1005,31 +985,6 @@ Item onModelChanged: populateExtruderModel() } - Item - { - id: tipsCell - anchors.top: adhesionCheckBox.visible ? adhesionCheckBox.bottom : (enableSupportCheckBox.visible ? supportExtruderCombobox.bottom : infillCellRight.bottom) - anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height * 2) - anchors.left: parent.left - width: parent.width - height: tipsText.contentHeight * tipsText.lineCount - - Label - { - id: tipsText - anchors.left: parent.left - anchors.right: parent.right - anchors.rightMargin: UM.Theme.getSize("thick_margin").width - anchors.top: parent.top - wrapMode: Text.WordWrap - text: catalog.i18nc("@label", "Need help improving your prints?
    Read the Ultimaker Troubleshooting Guides").arg("https://ultimaker.com/en/troubleshooting") - font: UM.Theme.getFont("default"); - color: UM.Theme.getColor("text"); - linkColor: UM.Theme.getColor("text_link") - onLinkActivated: Qt.openUrlExternally(link) - } - } - UM.SettingPropertyProvider { id: infillExtruderNumber @@ -1096,8 +1051,8 @@ Item function populateExtruderModel() { - extruderModel.clear(); - for(var extruderNumber = 0; extruderNumber < extruders.rowCount() ; extruderNumber++) + extruderModel.clear() + for (var extruderNumber = 0; extruderNumber < extruders.rowCount(); extruderNumber++) { extruderModel.append({ text: extruders.getItem(extruderNumber).name, From d88a465737410f09b22498a8448f0ffdd550a5b3 Mon Sep 17 00:00:00 2001 From: Mark Date: Thu, 29 Nov 2018 14:45:42 +0100 Subject: [PATCH 0548/1292] Increase possible visible description lines in the Marketplace --- plugins/Toolbox/resources/qml/ToolboxDetailTile.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml index 7425ab2ba7..1d701543ce 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml @@ -37,7 +37,7 @@ Item anchors.top: packageName.bottom width: parent.width text: model.description - maximumLineCount: 12 + maximumLineCount: 25 elide: Text.ElideRight wrapMode: Text.WordWrap color: UM.Theme.getColor("text") From c545d9df7777db7e8d47ab3143997d310145b81d Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 29 Nov 2018 15:16:37 +0100 Subject: [PATCH 0549/1292] =?UTF-8?q?Add=20key=20check=20before=20accessin?= =?UTF-8?q?g=20in=20=C2=83StartSliceJob?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CURA-5901 --- plugins/CuraEngineBackend/StartSliceJob.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index 273dc0b6f6..9679360ad5 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -72,7 +72,7 @@ class GcodeStartEndFormatter(Formatter): # "-1" is global stack, and if the setting value exists in the global stack, use it as the fallback value. if key in kwargs["-1"]: value = kwargs["-1"] - if key in kwargs[str(extruder_nr)]: + if str(extruder_nr) in kwargs and key in kwargs[str(extruder_nr)]: value = kwargs[str(extruder_nr)][key] if value == default_value_str: From 90aa8c1264662ba176c4a696260afae7e80d7ba2 Mon Sep 17 00:00:00 2001 From: Mark Date: Thu, 29 Nov 2018 15:29:51 +0100 Subject: [PATCH 0550/1292] point people to a good example --- .../scripts/ExampleScript.md | 3 ++ .../scripts/ExampleScript.py | 43 ------------------- 2 files changed, 3 insertions(+), 43 deletions(-) create mode 100644 plugins/PostProcessingPlugin/scripts/ExampleScript.md delete mode 100644 plugins/PostProcessingPlugin/scripts/ExampleScript.py diff --git a/plugins/PostProcessingPlugin/scripts/ExampleScript.md b/plugins/PostProcessingPlugin/scripts/ExampleScript.md new file mode 100644 index 0000000000..08652132aa --- /dev/null +++ b/plugins/PostProcessingPlugin/scripts/ExampleScript.md @@ -0,0 +1,3 @@ +A good example script is SearchAndReplace.py. +If you have any questions please ask them at: +https://github.com/Ultimaker/Cura/issues \ No newline at end of file diff --git a/plugins/PostProcessingPlugin/scripts/ExampleScript.py b/plugins/PostProcessingPlugin/scripts/ExampleScript.py deleted file mode 100644 index 416a5f5404..0000000000 --- a/plugins/PostProcessingPlugin/scripts/ExampleScript.py +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright (c) 2015 Jaime van Kessel, Ultimaker B.V. -# The PostProcessingPlugin is released under the terms of the AGPLv3 or higher. -from ..Script import Script - -class ExampleScript(Script): - def __init__(self): - super().__init__() - - def getSettingDataString(self): - return """{ - "name":"Example script", - "key": "ExampleScript", - "metadata": {}, - "version": 2, - "settings": - { - "test": - { - "label": "Test", - "description": "None", - "unit": "mm", - "type": "float", - "default_value": 0.5, - "minimum_value": "0", - "minimum_value_warning": "0.1", - "maximum_value_warning": "1" - }, - "derp": - { - "label": "zomg", - "description": "afgasgfgasfgasf", - "unit": "mm", - "type": "float", - "default_value": 0.5, - "minimum_value": "0", - "minimum_value_warning": "0.1", - "maximum_value_warning": "1" - } - } - }""" - - def execute(self, data): - return data \ No newline at end of file From bc8bf8780959db152ba572a39a4dc545d1900006 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 29 Nov 2018 15:54:02 +0100 Subject: [PATCH 0551/1292] Align the buttons at the bottom of the panel Contributes to CURA-5941. --- resources/qml/ExpandableComponent.qml | 3 +- .../PrintSetupSelectorContents.qml | 71 +++++++++++-------- 2 files changed, 45 insertions(+), 29 deletions(-) diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index 0c3a8f80b9..47fa226e9d 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -163,6 +163,7 @@ Item onExited: background.color = headerBackgroundColor } } + DropShadow { id: shadow @@ -182,7 +183,7 @@ Item id: popup // Ensure that the popup is located directly below the headerItem - y: headerItemLoader.height + 2 * background.padding + base.shadowOffset + popupSpacingY + y: background.height + base.shadowOffset + popupSpacingY // Make the popup aligned with the rest, using the property popupAlignment to decide whether is right or left. // In case of right alignment, the 3x padding is due to left, right and padding between the button & text. diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml index 6e71526f25..309d612fae 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml @@ -11,7 +11,7 @@ Item { id: popup - width: UM.Theme.getSize("print_setup_widget").width + width: UM.Theme.getSize("print_setup_widget").width - 2 * UM.Theme.getSize("default_margin").width height: childrenRect.height property int currentModeIndex: -1 @@ -87,22 +87,50 @@ Item color: UM.Theme.getColor("lining") } - Loader + Item { - id: loader - width: parent.width + id: contents + height: childrenRect.height + anchors { top: header.bottom + left: parent.left + right: parent.right + } + + RecommendedPrintSetup + { + anchors + { + left: parent.left + right: parent.right + top: parent.top + } + onShowTooltip: base.showTooltip(item, location, text) + onHideTooltip: base.hideTooltip() + visible: currentModeIndex == 0 + } + + CustomPrintSetup + { + anchors + { + left: parent.left + right: parent.right + top: parent.top + } + onShowTooltip: base.showTooltip(item, location, text) + onHideTooltip: base.hideTooltip() + visible: currentModeIndex == 1 } - sourceComponent: currentModeIndex == 0 ? recommendedPrintSetup : customPrintSetup } Rectangle { id: buttonsSeparator - anchors.top: loader.bottom + anchors.top: contents.bottom width: parent.width height: UM.Theme.getSize("default_lining").height color: UM.Theme.getColor("lining") @@ -111,7 +139,8 @@ Item Item { id: buttonRow - height: childrenRect.height + property real padding: UM.Theme.getSize("default_margin").width + height: childrenRect.height + 2 * padding // The buttonsSeparator is inside the buttonRow. This is to avoid some weird behaviours with the scroll bar. anchors @@ -123,46 +152,32 @@ Item Cura.SecondaryButton { + anchors.top: parent.top anchors.left: parent.left + anchors.margins: parent.padding leftPadding: UM.Theme.getSize("default_margin").width rightPadding: UM.Theme.getSize("default_margin").width text: catalog.i18nc("@button", "Recommended") + iconSource: UM.Theme.getIcon("arrow_left") visible: currentModeIndex == 1 onClicked: currentModeIndex = 0 } Cura.SecondaryButton { + anchors.top: parent.top anchors.right: parent.right + anchors.margins: UM.Theme.getSize("default_margin").width leftPadding: UM.Theme.getSize("default_margin").width rightPadding: UM.Theme.getSize("default_margin").width text: catalog.i18nc("@button", "Custom") + iconSource: UM.Theme.getIcon("arrow_right") + iconOnRightSide: true visible: currentModeIndex == 0 onClicked: currentModeIndex = 1 } } - Component - { - id: recommendedPrintSetup - RecommendedPrintSetup - { - onShowTooltip: base.showTooltip(item, location, text) - onHideTooltip: base.hideTooltip() - } - } - - Component - { - id: customPrintSetup - CustomPrintSetup - { - onShowTooltip: base.showTooltip(item, location, text) - onHideTooltip: base.hideTooltip() - } - } - - Component.onCompleted: { var index = Math.round(UM.Preferences.getValue("cura/active_mode")) From 763291821f9b8afa3af231a7346fc56231619625 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Thu, 29 Nov 2018 17:03:11 +0100 Subject: [PATCH 0552/1292] Added models to process the data from the api results Added code to update the UI models --- .../src/Cloud/CloudOutputDevice.py | 208 +++++++++++++++--- .../src/Cloud/CloudOutputDeviceManager.py | 6 +- .../UM3NetworkPrinting/src/Cloud/Models.py | 63 ++++++ 3 files changed, 246 insertions(+), 31 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 79a3d46949..06e5656392 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -1,18 +1,23 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import json +import os from typing import List, Optional, Dict -from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, QUrl +from PyQt5.QtCore import QObject, pyqtSignal, QUrl, pyqtProperty from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest from UM import i18nCatalog from UM.FileHandler.FileHandler import FileHandler from UM.Logger import Logger from UM.Scene.SceneNode import SceneNode +from UM.Settings import ContainerRegistry from cura.CuraApplication import CuraApplication +from cura.PrinterOutput import PrinterOutputController, PrintJobOutputModel +from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice, AuthState from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel +from .Models import CloudClusterPrinter, CloudClusterPrinterConfiguration, CloudClusterPrinterConfigurationMaterial, CloudClusterPrintJob, CloudClusterPrintJobConstraint from .CloudOutputController import CloudOutputController from ..UM3PrintJobOutputModel import UM3PrintJobOutputModel @@ -38,17 +43,23 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # Signal triggered when the print jobs in the queue were changed. printJobsChanged = pyqtSignal() - + def __init__(self, device_id: str, parent: QObject = None): super().__init__(device_id = device_id, address = "", properties = {}, parent = parent) self._setInterfaceElements() self._device_id = device_id self._account = CuraApplication.getInstance().getCuraAPI().account + + # We re-use the Cura Connect monitor tab to get the most functionality right away. + self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), + "../../resources/qml/ClusterMonitorItem.qml") + self._control_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), + "../../resources/qml/ClusterControlItem.qml") # Properties to populate later on with received cloud data. - self._printers = [] - self._print_jobs = [] + self._printers = {} # type: Dict[str, PrinterOutputModel] + self._print_jobs = {} # type: Dict[str, PrintJobOutputModel] self._number_of_extruders = 2 # All networked printers are dual-extrusion Ultimaker machines. ## We need to override _createEmptyRequest to work for the cloud. @@ -90,8 +101,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## Get remote print jobs. @pyqtProperty("QVariantList", notify = printJobsChanged) - def printJobs(self) -> List[UM3PrintJobOutputModel]: - return self._print_jobs + def queuedPrintJobs(self) -> List[UM3PrintJobOutputModel]: + return [print_job for print_job in self._print_jobs if print_job.state == "queued" or print_job.state == "error"] ## Called when the connection to the cluster changes. def connect(self) -> None: @@ -111,41 +122,182 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): .format(status_code, reply.readAll())) return - data = self._parseStatusResponse(reply) - if data is None: + printers, print_jobs = self._parseStatusResponse(reply) + if not printers and not print_jobs: return # Update all data from the cluster. - self._updatePrinters(data.get("printers", [])) - self._updatePrintJobs(data.get("print_jobs", [])) + self._updatePrinters(printers) + self._updatePrintJobs(print_jobs) @staticmethod - def _parseStatusResponse(reply: QNetworkReply) -> Optional[dict]: + def _parseStatusResponse(reply: QNetworkReply): # Optional[(CloudClusterPrinter, CloudClusterPrintJob)] doesn't work + + printers = [] + print_jobs = [] + s = '' try: - result = json.loads(bytes(reply.readAll()).decode("utf-8")) - # TODO: use model or named tuple here. - return result + s = json.loads(bytes(reply.readAll()).decode("utf-8")) + + for p in s["printers"]: + printer = CloudClusterPrinter(**p) + configuration = printer.configuration + printer.configuration = [] + for c in configuration: + extruder = CloudClusterPrinterConfiguration(**c) + extruder.material = CloudClusterPrinterConfigurationMaterial(extruder.material) + printer.configuration.append(extruder) + + printers.append(printer) + + for j in s["print_jobs"]: + job = CloudClusterPrintJob(**j) + constraints = job.constraints + job.constraints = [] + for c in constraints: + job.constraints.append(CloudClusterPrintJobConstraint(**c)) + + configuration = job.configuration + job.configuration = [] + for c in configuration: + configuration = CloudClusterPrinterConfiguration(**c) + configuration.material = CloudClusterPrinterConfigurationMaterial(configuration.material) + job.configuration.append(configuration) + + print_jobs.append(job) + except json.decoder.JSONDecodeError: Logger.logException("w", "Unable to decode JSON from reply.") return None - def _updatePrinters(self, remote_printers: List[Dict[str, any]]) -> None: - # TODO: use model or tuple for remote_printers data - for printer in remote_printers: - - # If the printer does not exist yet, create it. - if not self._getPrinterByKey(printer["uuid"]): - self._printers.append(PrinterOutputModel( - output_controller = CloudOutputController(self), - number_of_extruders = self._number_of_extruders - )) - + return printers, print_jobs + + def _updatePrinters(self, printers: List[CloudClusterPrinter]) -> None: + remote_printers = {p.uuid: p for p in printers} + + removed_printers = set(self._printers.keys()).difference(set(remote_printers.keys())) + new_printers = set(remote_printers.keys()).difference(set(self._printers.keys())) + updated_printers = set(self._printers.keys()).intersection(set(remote_printers.keys())) + + for p in removed_printers: + self._removePrinter(p) + + for p in new_printers: + self._addPrinter(printers[p]) + self._updatePrinter(printers[p]) + + for p in updated_printers: + self._updatePrinter(printers[p]) + # TODO: properly handle removed and updated printers self.printersChanged.emit() - def _updatePrintJobs(self, remote_print_jobs: List[Dict[str, any]]) -> None: - # TODO: use model or tuple for remote_print_jobs data - pass + + def _addPrinter(self, printer): + self._printers[printer.uuid] = self._createPrinterOutputModel(self, printer) + + def _createPrinterOutputModel(self, printer: CloudClusterPrinter) -> PrinterOutputModel: + return PrinterOutputModel(PrinterOutputController(self), len(printer.configuration), + firmware_version=printer.firmware_version) + + def _updatePrinter(self, guid : str, printer : CloudClusterPrinter): + model = self._printers[guid] + self._printers[guid] = self._updatePrinterOutputModel(self, printer) + + def _updatePrinterOutputModel(self, printer: CloudClusterPrinter, model : PrinterOutputModel) -> PrinterOutputModel: + model.updateKey(printer.uuid) + model.updateName(printer.friendly_name) + model.updateType(printer.machine_variant) + model.updateState(printer.status if printer.enabled else "disabled") + + for index in range(0, len(printer.configuration)): + try: + extruder = model.extruders[index] + extruder_data = printer.configuration[index] + except IndexError: + break + + extruder.updateHotendID(extruder_data.print_core_id) + + material_data = extruder_data.material + if extruder.activeMaterial is None or extruder.activeMaterial.guid != material.guid: + material = self._createMaterialOutputModel(material_data) + extruder.updateActiveMaterial(material) + + def _createMaterialOutputModel(self, material: CloudClusterPrinterConfigurationMaterial) -> MaterialOutputModel: + material_manager = CuraApplication.getInstance().getMaterialManager() + material_group_list = material_manager.getMaterialGroupListByGUID(material.guid) or [] + + # Sort the material groups by "is_read_only = True" first, and then the name alphabetically. + read_only_material_group_list = list(filter(lambda x: x.is_read_only, material_group_list)) + non_read_only_material_group_list = list(filter(lambda x: not x.is_read_only, material_group_list)) + material_group = None + if read_only_material_group_list: + read_only_material_group_list = sorted(read_only_material_group_list, key=lambda x: x.name) + material_group = read_only_material_group_list[0] + elif non_read_only_material_group_list: + non_read_only_material_group_list = sorted(non_read_only_material_group_list, key=lambda x: x.name) + material_group = non_read_only_material_group_list[0] + + if material_group: + container = material_group.root_material_node.getContainer() + color = container.getMetaDataEntry("color_code") + brand = container.getMetaDataEntry("brand") + material_type = container.getMetaDataEntry("material") + name = container.getName() + else: + Logger.log("w", + "Unable to find material with guid {guid}. Using data as provided by cluster".format( + guid=material.guid)) + color = material.color + brand = material.brand + material_type = material.material + name = "Empty" if material.material == "empty" else "Unknown" + + return MaterialOutputModel(guid=material.guid, type=material_type, brand=brand, color=color, name=name) + + + def _removePrinter(self, guid): + del self._printers[guid] + + def _updatePrintJobs(self, jobs: List[CloudClusterPrintJob]) -> None: + remote_jobs = {j.uuid: j for j in jobs} + + removed_jobs = set(self._print_jobs.keys()).difference(set(remote_jobs.keys())) + new_jobs = set(remote_jobs.keys()).difference(set(self._print_jobs.keys())) + updated_jobs = set(self._print_jobs.keys()).intersection(set(remote_jobs.keys())) + + for j in removed_jobs: + self._removePrintJob(j) + + for j in new_jobs: + self._addPrintJob(jobs[j]) + + for j in updated_jobs: + self._updatePrintJob(jobs[j]) + + # TODO: properly handle removed and updated printers + self.printJobsChanged() + + def _addPrintJob(self, job: CloudClusterPrintJob): + self._print_jobs[job.uuid] = self._createPrintJobOutputModel(job) + + def _createPrintJobOutputModel(self, job:CloudClusterPrintJob) -> PrintJobOutputModel: + controller = self._printers[job.printer_uuid]._controller # TODO: Can we access this property? + model = PrintJobOutputModel(controller, job.uuid, job.name) + assigned_printer = self._printes[job.printer_uuid] # TODO: Or do we have to use the assigned_to field? + model.updateAssignedPrinter(assigned_printer) + + def _updatePrintJobOutputModel(self, guid: str, job:CloudClusterPrintJob): + model =self._print_jobs[guid] + + model.updateTimeTotal(job.time_total) + model.updateTimeElapsed(job.time_elapsed) + model.updateOwner(job.owner) + model.updateState(job.status) + + def _removePrintJob(self, guid:str): + del self._print_jobs[guid] def _addPrintJobToQueue(self): # TODO: implement this diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 4de7263df1..f6542e3c76 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -124,9 +124,9 @@ class CloudOutputDeviceManager(NetworkClient): local_device_id = active_machine.getMetaDataEntry("um_network_key") if local_device_id: - active_output_device = CuraApplication.getInstance().getOutputDeviceManager().getActiveDevice() - active_output_device.id - + active_output_device = self._output_device_manager.getActiveDevice() + # We must find a match for the active machine and a cloud device + stored_cluster_id = active_machine.getMetaDataEntry("um_cloud_cluster_id") if stored_cluster_id not in self._remote_clusters.keys(): # Currently authenticated user does not have access to stored cluster or no user is signed in. diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models.py b/plugins/UM3NetworkPrinting/src/Cloud/Models.py index e98d848d51..7d6db9c8c0 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models.py @@ -16,3 +16,66 @@ class CloudCluster(BaseModel): def validate(self): if not self.cluster_id: raise ValueError("cluster_id is required on CloudCluster") + + +## Class representing a cloud cluster printer configuration +class CloudClusterPrinterConfigurationMaterial(BaseModel): + def __init__(self, **kwargs): + self.guid = None # type: str + self.brand = None # type: str + self.color = None # type: str + self.material = None # type: str + super().__init__(**kwargs) + + +## Class representing a cloud cluster printer configuration +class CloudClusterPrinterConfiguration(BaseModel): + def __init__(self, **kwargs): + self.extruder_index = None # type: str + self.material = None # type: CloudClusterPrinterConfigurationMaterial + self.nozzle_diameter = None # type: str + self.printer_core_id = None # type: str + super().__init__(**kwargs) + + +## Class representing a cluster printer +class CloudClusterPrinter(BaseModel): + def __init__(self, **kwargs): + self.configuration = None # type: CloudClusterPrinterConfiguration + self.enabled = None # type: str + self.firmware_version = None # type: str + self.friendly_name = None # type: str + self.ip_address = None # type: str + self.machine_variant = None # type: str + self.status = None # type: str + self.unique_name = None # type: str + self.uuid = None # type: str + super().__init__(**kwargs) + + +## Class representing a cloud cluster print job constraint +class CloudClusterPrintJobConstraint(BaseModel): + def __init__(self, **kwargs): + self.require_printer_name: None # type: str + super().__init__(**kwargs) + +## Class representing a print job +class CloudClusterPrintJob(BaseModel): + def __init__(self, **kwargs): + self.assigned_to = None # type: str + self.configuration = None # type: str + self.constraints = None # type: str + self.created_at = None # type: str + self.force = None # type: str + self.last_seen = None # type: str + self.machine_variant = None # type: str + self.name = None # type: str + self.network_error_count = None # type: str + self.owner = None # type: str + self.printer_uuid = None # type: str + self.started = None # type: str + self.status = None # type: str + self.time_elapsed = None # type: str + self.time_total = None # type: str + self.uuid = None # type: str + super().__init__(**kwargs) From 1c96c81ba98f9887cae38fe8de939db4131da9e4 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 30 Nov 2018 11:11:17 +0100 Subject: [PATCH 0553/1292] Remove unnecessary extra setMetaDataEntry This is a relic from when you first had to add the metadata entry. Now it does nothing any more because it's being set directly afterwards to the actual value that is desired in the end. Contributes to issue CURA-5876. --- cura/Settings/ExtruderStack.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/cura/Settings/ExtruderStack.py b/cura/Settings/ExtruderStack.py index d7faedb71c..ed758db183 100644 --- a/cura/Settings/ExtruderStack.py +++ b/cura/Settings/ExtruderStack.py @@ -52,8 +52,6 @@ class ExtruderStack(CuraContainerStack): return super().getNextStack() def setEnabled(self, enabled: bool) -> None: - if "enabled" not in self._metadata: - self.setMetaDataEntry("enabled", "True") self.setMetaDataEntry("enabled", str(enabled)) self.enabledChanged.emit() From 4e2f51e7e8cbc58b647260885cc96d06c00727df Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 30 Nov 2018 11:13:04 +0100 Subject: [PATCH 0554/1292] Use public activeExtruderIndex rather than internal _activeExtruderIndex So that this getter still does what it needs to do if we ever decide to add side-effects. Contributes to issue CURA-5876. --- cura/Settings/ExtruderManager.py | 4 ++-- cura/Settings/MachineManager.py | 2 +- plugins/CuraEngineBackend/ProcessSlicedLayersJob.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index 9089ba96e9..b0bcf3b100 100755 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -63,7 +63,7 @@ class ExtruderManager(QObject): if not self._application.getGlobalContainerStack(): return None # No active machine, so no active extruder. try: - return self._extruder_trains[self._application.getGlobalContainerStack().getId()][str(self._active_extruder_index)].getId() + return self._extruder_trains[self._application.getGlobalContainerStack().getId()][str(self.activeExtruderIndex)].getId() except KeyError: # Extruder index could be -1 if the global tab is selected, or the entry doesn't exist if the machine definition is wrong. return None @@ -144,7 +144,7 @@ class ExtruderManager(QObject): @pyqtSlot(result = QObject) def getActiveExtruderStack(self) -> Optional["ExtruderStack"]: - return self.getExtruderStack(self._active_extruder_index) + return self.getExtruderStack(self.activeExtruderIndex) ## Get an extruder stack by index def getExtruderStack(self, index) -> Optional["ExtruderStack"]: diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 226a352602..40a3bfc563 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -866,7 +866,7 @@ class MachineManager(QObject): caution_message = Message(catalog.i18nc( "@info:generic", "Settings have been changed to match the current availability of extruders: [%s]" % ", ".join(add_user_changes)), - lifetime=0, + lifetime = 0, title = catalog.i18nc("@info:title", "Settings updated")) caution_message.show() diff --git a/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py b/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py index 594bf3a43e..71c96880e8 100644 --- a/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py +++ b/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py @@ -195,7 +195,7 @@ class ProcessSlicedLayersJob(Job): if extruders: material_color_map = numpy.zeros((len(extruders), 4), dtype=numpy.float32) for extruder in extruders: - position = int(extruder.getMetaDataEntry("position", default="0")) # Get the position + position = int(extruder.getMetaDataEntry("position", default = "0")) try: default_color = ExtrudersModel.defaultColors[position] except IndexError: From 17945c6b16ca3d0be7274a6946f68f4d381c8d48 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 30 Nov 2018 11:32:24 +0100 Subject: [PATCH 0555/1292] [WIP] Separate components in different files Contributes to CURA-5941 --- resources/qml/ExpandableComponent.qml | 3 + .../{ => Custom}/CustomPrintSetup.qml | 4 +- .../PrintSetupSelectorContents.qml | 31 +- .../RecommendedInfillDensitySelector.qml | 348 ++++++ .../Recommended/RecommendedPrintSetup.qml | 162 +++ .../RecommendedQualityProfileSelector.qml | 464 +++++++ .../RecommendedSupportSelector.qml | 175 +++ .../RecommendedPrintSetup.qml | 1064 ----------------- resources/qml/qmldir | 3 +- 9 files changed, 1173 insertions(+), 1081 deletions(-) rename resources/qml/PrintSetupSelector/{ => Custom}/CustomPrintSetup.qml (77%) create mode 100644 resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml create mode 100644 resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml create mode 100644 resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml create mode 100644 resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml delete mode 100644 resources/qml/PrintSetupSelector/RecommendedPrintSetup.qml diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index 47fa226e9d..82747d1c5b 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -27,6 +27,9 @@ Item // The popupItem holds the QML item that is shown when the "open" button is pressed property var popupItem + // The popupItem holds the QML item that is shown when the "open" button is pressed + property var componentItem + property color popupBackgroundColor: UM.Theme.getColor("action_button") property color headerBackgroundColor: UM.Theme.getColor("action_button") diff --git a/resources/qml/PrintSetupSelector/CustomPrintSetup.qml b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml similarity index 77% rename from resources/qml/PrintSetupSelector/CustomPrintSetup.qml rename to resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml index f58695b48f..51cd8eff0d 100644 --- a/resources/qml/PrintSetupSelector/CustomPrintSetup.qml +++ b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml @@ -4,7 +4,7 @@ import QtQuick 2.7 import QtQuick.Controls 2.0 -import "../Settings" +import Cura 1.0 as Cura -SettingView { +Cura.SettingView { } diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml index 309d612fae..f21253acd7 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml @@ -7,6 +7,9 @@ import QtQuick.Controls 2.3 import UM 1.3 as UM import Cura 1.0 as Cura +import "Recommended" +import "Custom" + Item { id: popup @@ -22,7 +25,7 @@ Item { id: header height: UM.Theme.getSize("print_setup_widget_header").height - color: UM.Theme.getColor("action_button_hovered") // TODO: It's not clear the color that we need to use here + color: "transparent" //UM.Theme.getColor("action_button_hovered") // TODO: It's not clear the color that we need to use here anchors { @@ -111,19 +114,19 @@ Item onHideTooltip: base.hideTooltip() visible: currentModeIndex == 0 } - - CustomPrintSetup - { - anchors - { - left: parent.left - right: parent.right - top: parent.top - } - onShowTooltip: base.showTooltip(item, location, text) - onHideTooltip: base.hideTooltip() - visible: currentModeIndex == 1 - } +// +// CustomPrintSetup +// { +// anchors +// { +// left: parent.left +// right: parent.right +// top: parent.top +// } +// onShowTooltip: base.showTooltip(item, location, text) +// onHideTooltip: base.hideTooltip() +// visible: currentModeIndex == 1 +// } } Rectangle diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml new file mode 100644 index 0000000000..34cb8f2f20 --- /dev/null +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml @@ -0,0 +1,348 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 + +import UM 1.2 as UM +import Cura 1.0 as Cura + + +// +// Infill +// +Item +{ + id: infillRow + + Cura.IconWithText + { + id: infillRowTitle + source: UM.Theme.getIcon("category_infill") + text: catalog.i18nc("@label", "Infill") + " (%)" + anchors.bottom: parent.bottom + width: labelColumnWidth + } + + Item + { + id: infillCellRight + + height: infillSlider.height + UM.Theme.getSize("thick_margin").height + enableGradualInfillCheckBox.visible * (enableGradualInfillCheckBox.height + UM.Theme.getSize("thick_margin").height) + + anchors.left: infillRowTitle.right + anchors.right: parent.right + + Label + { + id: selectedInfillRateText + + anchors.left: infillSlider.left + anchors.right: parent.right + + text: parseInt(infillDensity.properties.value) + "%" + horizontalAlignment: Text.AlignLeft + + color: infillSlider.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") + } + + // We use a binding to make sure that after manually setting infillSlider.value it is still bound to the property provider + Binding + { + target: infillSlider + property: "value" + value: parseInt(infillDensity.properties.value) + } + + Slider + { + id: infillSlider + + anchors.top: selectedInfillRateText.bottom + anchors.left: parent.left + anchors.right: infillIcon.left + anchors.rightMargin: UM.Theme.getSize("thick_margin").width + + height: UM.Theme.getSize("thick_margin").height + width: parseInt(infillCellRight.width - UM.Theme.getSize("thick_margin").width - style.handleWidth) + + minimumValue: 0 + maximumValue: 100 + stepSize: 1 + tickmarksEnabled: true + + // disable slider when gradual support is enabled + enabled: parseInt(infillSteps.properties.value) == 0 + + // set initial value from stack + value: parseInt(infillDensity.properties.value) + + onValueChanged: + { + + // Don't round the value if it's already the same + if (parseInt(infillDensity.properties.value) == infillSlider.value) + { + return + } + + // Round the slider value to the nearest multiple of 10 (simulate step size of 10) + var roundedSliderValue = Math.round(infillSlider.value / 10) * 10 + + // Update the slider value to represent the rounded value + infillSlider.value = roundedSliderValue + + // Update value only if the Recomended mode is Active, + // Otherwise if I change the value in the Custom mode the Recomended view will try to repeat + // same operation + var active_mode = UM.Preferences.getValue("cura/active_mode") + + if (active_mode == 0 || active_mode == "simple") + { + Cura.MachineManager.setSettingForAllExtruders("infill_sparse_density", "value", roundedSliderValue) + Cura.MachineManager.resetSettingForAllExtruders("infill_line_distance") + } + } + + style: SliderStyle + { + groove: Rectangle + { + id: groove + implicitWidth: 200 * screenScaleFactor + implicitHeight: 2 * screenScaleFactor + color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") + radius: 1 + } + + handle: Item + { + Rectangle + { + id: handleButton + anchors.centerIn: parent + color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") + implicitWidth: 10 * screenScaleFactor + implicitHeight: 10 * screenScaleFactor + radius: 10 * screenScaleFactor + } + } + + tickmarks: Repeater + { + id: repeater + model: control.maximumValue / control.stepSize + 1 + + // check if a tick should be shown based on it's index and wether the infill density is a multiple of 10 (slider step size) + function shouldShowTick (index) + { + if (index % 10 == 0) + { + return true + } + return false + } + + Rectangle + { + anchors.verticalCenter: parent.verticalCenter + color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") + width: 1 * screenScaleFactor + height: 6 * screenScaleFactor + x: Math.round(styleData.handleWidth / 2 + index * ((repeater.width - styleData.handleWidth) / (repeater.count-1))) + visible: shouldShowTick(index) + } + } + } + } + + Rectangle + { + id: infillIcon + + width: Math.round((parent.width / 5) - (UM.Theme.getSize("thick_margin").width)) + height: width + + anchors.right: parent.right + anchors.top: parent.top + anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height / 2) + + // we loop over all density icons and only show the one that has the current density and steps + Repeater + { + id: infillIconList + model: infillModel + anchors.fill: parent + + function activeIndex () + { + for (var i = 0; i < infillModel.count; i++) + { + var density = Math.round(infillDensity.properties.value) + var steps = Math.round(infillSteps.properties.value) + var infillModelItem = infillModel.get(i) + + if (infillModelItem != "undefined" + && density >= infillModelItem.percentageMin + && density <= infillModelItem.percentageMax + && steps >= infillModelItem.stepsMin + && steps <= infillModelItem.stepsMax) + { + return i + } + } + return -1 + } + + Rectangle + { + anchors.fill: parent + visible: infillIconList.activeIndex() == index + + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("quality_slider_unavailable") + + UM.RecolorImage + { + anchors.fill: parent + anchors.margins: 2 * screenScaleFactor + sourceSize.width: width + sourceSize.height: width + source: UM.Theme.getIcon(model.icon) + color: UM.Theme.getColor("quality_slider_unavailable") + } + } + } + } + + // Gradual Support Infill Checkbox + CheckBox + { + id: enableGradualInfillCheckBox + property alias _hovered: enableGradualInfillMouseArea.containsMouse + + anchors.top: infillSlider.bottom + anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height / 2) // closer to slider since it belongs to the same category + anchors.left: infillCellRight.left + + style: UM.Theme.styles.checkbox + enabled: base.settingsEnabled + visible: infillSteps.properties.enabled == "True" + checked: parseInt(infillSteps.properties.value) > 0 + + MouseArea + { + id: enableGradualInfillMouseArea + + anchors.fill: parent + hoverEnabled: true + enabled: true + + property var previousInfillDensity: parseInt(infillDensity.properties.value) + + onClicked: + { + // Set to 90% only when enabling gradual infill + var newInfillDensity; + if (parseInt(infillSteps.properties.value) == 0) + { + previousInfillDensity = parseInt(infillDensity.properties.value) + newInfillDensity = 90 + } else { + newInfillDensity = previousInfillDensity + } + Cura.MachineManager.setSettingForAllExtruders("infill_sparse_density", "value", String(newInfillDensity)) + + var infill_steps_value = 0 + if (parseInt(infillSteps.properties.value) == 0) + { + infill_steps_value = 5 + } + + Cura.MachineManager.setSettingForAllExtruders("gradual_infill_steps", "value", infill_steps_value) + } + + onEntered: base.showTooltip(enableGradualInfillCheckBox, Qt.point(-infillCellRight.x, 0), + catalog.i18nc("@label", "Gradual infill will gradually increase the amount of infill towards the top.")) + + onExited: base.hideTooltip() + + } + + Label + { + id: gradualInfillLabel + height: parent.height + anchors.left: enableGradualInfillCheckBox.right + anchors.leftMargin: Math.round(UM.Theme.getSize("thick_margin").width / 2) + verticalAlignment: Text.AlignVCenter; + text: catalog.i18nc("@label", "Enable gradual") + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + } + } + + // Infill list model for mapping icon + ListModel + { + id: infillModel + Component.onCompleted: + { + infillModel.append({ + percentageMin: -1, + percentageMax: 0, + stepsMin: -1, + stepsMax: 0, + icon: "hollow" + }) + infillModel.append({ + percentageMin: 0, + percentageMax: 40, + stepsMin: -1, + stepsMax: 0, + icon: "sparse" + }) + infillModel.append({ + percentageMin: 40, + percentageMax: 89, + stepsMin: -1, + stepsMax: 0, + icon: "dense" + }) + infillModel.append({ + percentageMin: 90, + percentageMax: 9999999999, + stepsMin: -1, + stepsMax: 0, + icon: "solid" + }) + infillModel.append({ + percentageMin: 0, + percentageMax: 9999999999, + stepsMin: 1, + stepsMax: 9999999999, + icon: "gradual" + }) + } + } + } + + UM.SettingPropertyProvider + { + id: infillDensity + containerStackId: Cura.MachineManager.activeStackId + key: "infill_sparse_density" + watchedProperties: [ "value" ] + storeIndex: 0 + } + + UM.SettingPropertyProvider + { + id: infillSteps + containerStackId: Cura.MachineManager.activeStackId + key: "gradual_infill_steps" + watchedProperties: ["value", "enabled"] + storeIndex: 0 + } +} \ No newline at end of file diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml new file mode 100644 index 0000000000..2d4308c8be --- /dev/null +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml @@ -0,0 +1,162 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +Rectangle +{ + id: base + + signal showTooltip(Item item, point location, string text) + signal hideTooltip() +// width: parent.width + height: childrenRect.height + 2 * padding + color: "red" + opacity: 0.5 + + property Action configureSettings + + property bool settingsEnabled: Cura.ExtruderManager.activeExtruderStackId || extrudersEnabledCount.properties.value == 1 + property real padding: UM.Theme.getSize("thick_margin").width + + UM.I18nCatalog + { + id: catalog + name: "cura" + } + +// Rectangle +// { +// width: parent.width - 2 * parent.padding +// anchors +// { +// left: parent.left +// right: parent.right +// top: parent.top +// margins: parent.padding +// } +// color: "blue" +// height: 50 +// } + + Column + { + width: parent.width - 2 * parent.padding + spacing: UM.Theme.getSize("default_margin").height + anchors + { + left: parent.left + right: parent.right + top: parent.top + margins: parent.padding + } + + // TODO + property real labelColumnWidth: Math.round(width / 3) + property real settingsColumnWidth: width - labelColumnWidth + + RecommendedQualityProfileSelector + { + width: parent.width + // TODO Create a reusable component with these properties to not define them separately for each component + property real labelColumnWidth: parent.labelColumnWidth + property real settingsColumnWidth: parent.settingsColumnWidth + } + +// RecommendedInfillDensitySelector +// { +// width: parent.width +// height: childrenRect.height +// // TODO Create a reusable component with these properties to not define them separately for each component +// property real labelColumnWidth: parent.labelColumnWidth +// property real settingsColumnWidth: parent.settingsColumnWidth +// } +// +// RecommendedSupportSelector +// { +// width: parent.width +// height: childrenRect.height +// // TODO Create a reusable component with these properties to not define them separately for each component +// property real labelColumnWidth: parent.labelColumnWidth +// property real settingsColumnWidth: parent.settingsColumnWidth +// } + + +// +// // Adhesion +// Row +// { +// anchors.left: parent.left +// anchors.right: parent.right +// height: childrenRect.height +// +// Cura.IconWithText +// { +// id: adhesionHelperLabel +// visible: adhesionCheckBox.visible +// source: UM.Theme.getIcon("category_adhesion") +// text: catalog.i18nc("@label", "Adhesion") +// width: labelColumnWidth +// } +// +// CheckBox +// { +// id: adhesionCheckBox +// property alias _hovered: adhesionMouseArea.containsMouse +// +// //: Setting enable printing build-plate adhesion helper checkbox +// style: UM.Theme.styles.checkbox +// enabled: base.settingsEnabled +// +// visible: platformAdhesionType.properties.enabled == "True" +// checked: platformAdhesionType.properties.value != "skirt" && platformAdhesionType.properties.value != "none" +// +// MouseArea +// { +// id: adhesionMouseArea +// anchors.fill: parent +// hoverEnabled: true +// enabled: base.settingsEnabled +// onClicked: +// { +// var adhesionType = "skirt" +// if(!parent.checked) +// { +// // Remove the "user" setting to see if the rest of the stack prescribes a brim or a raft +// platformAdhesionType.removeFromContainer(0) +// adhesionType = platformAdhesionType.properties.value +// if(adhesionType == "skirt" || adhesionType == "none") +// { +// // If the rest of the stack doesn't prescribe an adhesion-type, default to a brim +// adhesionType = "brim" +// } +// } +// platformAdhesionType.setPropertyValue("value", adhesionType) +// } +// onEntered: +// { +// base.showTooltip(adhesionCheckBox, Qt.point(-adhesionCheckBox.x, 0), +// catalog.i18nc("@label", "Enable printing a brim or raft. This will add a flat area around or under your object which is easy to cut off afterwards.")); +// } +// onExited: base.hideTooltip() +// } +// } +// } + } + + + UM.SettingPropertyProvider + { + id: platformAdhesionType + containerStack: Cura.MachineManager.activeMachine + removeUnusedValue: false //Doesn't work with settings that are resolved. + key: "adhesion_type" + watchedProperties: [ "value", "enabled" ] + storeIndex: 0 + } +} diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml new file mode 100644 index 0000000000..3bf93c0c07 --- /dev/null +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml @@ -0,0 +1,464 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 + +import UM 1.2 as UM +import Cura 1.0 as Cura + + +// +// Quality profile +// +Item +{ + id: qualityRow + height: childrenRect.height + + Timer + { + id: qualitySliderChangeTimer + interval: 50 + running: false + repeat: false + onTriggered: + { + var item = Cura.QualityProfilesDropDownMenuModel.getItem(qualitySlider.value); + Cura.MachineManager.activeQualityGroup = item.quality_group; + } + } + + Component.onCompleted: qualityModel.update() + + Connections + { + target: Cura.QualityProfilesDropDownMenuModel + onItemsChanged: qualityModel.update() + } + + Connections { + target: base + onVisibleChanged: + { + // update needs to be called when the widgets are visible, otherwise the step width calculation + // will fail because the width of an invisible item is 0. + if (visible) + { + qualityModel.update(); + } + } + } + + ListModel + { + id: qualityModel + + property var totalTicks: 0 + property var availableTotalTicks: 0 + property var existingQualityProfile: 0 + + property var qualitySliderActiveIndex: 0 + property var qualitySliderStepWidth: 0 + property var qualitySliderAvailableMin: 0 + property var qualitySliderAvailableMax: 0 + property var qualitySliderMarginRight: 0 + + function update () + { + reset() + + var availableMin = -1 + var availableMax = -1 + + for (var i = 0; i < Cura.QualityProfilesDropDownMenuModel.rowCount(); i++) + { + var qualityItem = Cura.QualityProfilesDropDownMenuModel.getItem(i) + + // Add each quality item to the UI quality model + qualityModel.append(qualityItem) + + // Set selected value + if (Cura.MachineManager.activeQualityType == qualityItem.quality_type) + { + // set to -1 when switching to user created profile so all ticks are clickable + if (Cura.SimpleModeSettingsManager.isProfileUserCreated) + { + qualityModel.qualitySliderActiveIndex = -1 + } + else + { + qualityModel.qualitySliderActiveIndex = i + } + + qualityModel.existingQualityProfile = 1 + } + + // Set min available + if (qualityItem.available && availableMin == -1) + { + availableMin = i + } + + // Set max available + if (qualityItem.available) + { + availableMax = i + } + } + + // Set total available ticks for active slider part + if (availableMin != -1) + { + qualityModel.availableTotalTicks = availableMax - availableMin + 1 + } + + // Calculate slider values + calculateSliderStepWidth(qualityModel.totalTicks) + calculateSliderMargins(availableMin, availableMax, qualityModel.totalTicks) + + qualityModel.qualitySliderAvailableMin = availableMin + qualityModel.qualitySliderAvailableMax = availableMax + } + + function calculateSliderStepWidth (totalTicks) + { + qualityModel.qualitySliderStepWidth = totalTicks != 0 ? Math.round((settingsColumnWidth) / (totalTicks)) : 0 + } + + function calculateSliderMargins (availableMin, availableMax, totalTicks) + { + if (availableMin == -1 || (availableMin == 0 && availableMax == 0)) + { + qualityModel.qualitySliderMarginRight = Math.round(settingsColumnWidth) + } + else if (availableMin == availableMax) + { + qualityModel.qualitySliderMarginRight = Math.round((totalTicks - availableMin) * qualitySliderStepWidth) + } + else + { + qualityModel.qualitySliderMarginRight = Math.round((totalTicks - availableMax) * qualitySliderStepWidth) + } + } + + function reset () { + qualityModel.clear() + qualityModel.availableTotalTicks = 0 + qualityModel.existingQualityProfile = 0 + + // check, the ticks count cannot be less than zero + qualityModel.totalTicks = Math.max(0, Cura.QualityProfilesDropDownMenuModel.rowCount() - 1) + } + } + + Cura.IconWithText + { + id: qualityRowTitle + source: UM.Theme.getIcon("category_layer_height") + text: catalog.i18nc("@label", "Layer Height") +// anchors.bottom: speedSlider.bottom + width: labelColumnWidth + } + + //Print speed slider + Rectangle + { + id: speedSlider + + anchors + { + left: qualityRowTitle.right + right: parent.right + } + + color: "green" + height: 20 + } +// +// // Show titles for the each quality slider ticks +// Item +// { +// anchors.left: speedSlider.left +// anchors.top: speedSlider.bottom +// +// Repeater +// { +// model: qualityModel +// +// Label +// { +// anchors.verticalCenter: parent.verticalCenter +// anchors.top: parent.top +// color: (Cura.MachineManager.activeMachine != null && Cura.QualityProfilesDropDownMenuModel.getItem(index).available) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") +// text: +// { +// var result = "" +// if(Cura.MachineManager.activeMachine != null) +// { +// result = Cura.QualityProfilesDropDownMenuModel.getItem(index).layer_height +// +// if(result == undefined) +// { +// result = ""; +// } +// else +// { +// result = Number(Math.round(result + "e+2") + "e-2"); //Round to 2 decimals. Javascript makes this difficult... +// if (result == undefined || result != result) //Parse failure. +// { +// result = ""; +// } +// } +// } +// return result +// } +// +// x: +// { +// // Make sure the text aligns correctly with each tick +// if (qualityModel.totalTicks == 0) +// { +// // If there is only one tick, align it centrally +// return Math.round(((settingsColumnWidth) - width) / 2) +// } +// else if (index == 0) +// { +// return Math.round(settingsColumnWidth / qualityModel.totalTicks) * index +// } +// else if (index == qualityModel.totalTicks) +// { +// return Math.round(settingsColumnWidth / qualityModel.totalTicks) * index - width +// } +// else +// { +// return Math.round((settingsColumnWidth / qualityModel.totalTicks) * index - (width / 2)) +// } +// } +// } +// } +// } +// +// //Print speed slider +// Rectangle +// { +// id: speedSlider +// +// anchors +// { +// left: qualityRowTitle.right +// right: parent.right +// } +// +// // This Item is used only for tooltip, for slider area which is unavailable +//// Item +//// { +//// function showTooltip (showTooltip) +//// { +//// if (showTooltip) +//// { +//// var content = catalog.i18nc("@tooltip", "This quality profile is not available for you current material and nozzle configuration. Please change these to enable this quality profile") +//// base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), content) +//// } +//// else +//// { +//// base.hideTooltip() +//// } +//// } +//// +//// id: unavailableLineToolTip +//// height: 20 * screenScaleFactor // hovered area height +//// z: parent.z + 1 // should be higher, otherwise the area can be hovered +//// x: 0 +//// anchors.verticalCenter: qualitySlider.verticalCenter +//// +//// Rectangle +//// { +//// id: leftArea +//// width: +//// { +//// if (qualityModel.availableTotalTicks == 0) +//// { +//// return qualityModel.qualitySliderStepWidth * qualityModel.totalTicks +//// } +//// return qualityModel.qualitySliderStepWidth * qualityModel.qualitySliderAvailableMin - 10 +//// } +//// height: parent.height +//// color: "transparent" +//// +//// MouseArea +//// { +//// anchors.fill: parent +//// hoverEnabled: true +//// enabled: Cura.SimpleModeSettingsManager.isProfileUserCreated == false +//// onEntered: unavailableLineToolTip.showTooltip(true) +//// onExited: unavailableLineToolTip.showTooltip(false) +//// } +//// } +//// +//// Item +//// { +//// id: rightArea +//// width: +//// { +//// if(qualityModel.availableTotalTicks == 0) +//// return 0 +//// +//// return qualityModel.qualitySliderMarginRight - 10 +//// } +//// height: parent.height +//// x: +//// { +//// if (qualityModel.availableTotalTicks == 0) +//// { +//// return 0 +//// } +//// +//// var leftUnavailableArea = qualityModel.qualitySliderStepWidth * qualityModel.qualitySliderAvailableMin +//// var totalGap = qualityModel.qualitySliderStepWidth * (qualityModel.availableTotalTicks -1) + leftUnavailableArea + 10 +//// +//// return totalGap +//// } +//// +//// MouseArea +//// { +//// anchors.fill: parent +//// hoverEnabled: true +//// enabled: Cura.SimpleModeSettingsManager.isProfileUserCreated == false +//// onEntered: unavailableLineToolTip.showTooltip(true) +//// onExited: unavailableLineToolTip.showTooltip(false) +//// } +//// } +//// } +// +// // Draw Unavailable line +// Rectangle +// { +// id: groovechildrect +// width: parent.width +// height: 2 * screenScaleFactor +// color: UM.Theme.getColor("quality_slider_unavailable") +// anchors.verticalCenter: qualitySlider.verticalCenter +// +// // Draw ticks +// Repeater +// { +// id: qualityRepeater +// model: qualityModel.totalTicks > 0 ? qualityModel : 0 +// +// Rectangle +// { +// color: Cura.QualityProfilesDropDownMenuModel.getItem(index).available ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") +// implicitWidth: 4 * screenScaleFactor +// implicitHeight: implicitWidth +// anchors.verticalCenter: parent.verticalCenter +// x: Math.round(qualityModel.qualitySliderStepWidth * index) +// radius: Math.round(implicitWidth / 2) +// } +// } +// } +// +// // Draw available slider +// Slider +// { +// id: qualitySlider +// height: UM.Theme.getSize("thick_margin").height +// anchors.bottom: parent.bottom +// enabled: qualityModel.totalTicks > 0 && !Cura.SimpleModeSettingsManager.isProfileCustomized +// visible: qualityModel.availableTotalTicks > 0 +// updateValueWhileDragging : false +// +// minimumValue: qualityModel.qualitySliderAvailableMin >= 0 ? qualityModel.qualitySliderAvailableMin : 0 +// // maximumValue must be greater than minimumValue to be able to see the handle. While the value is strictly +// // speaking not always correct, it seems to have the correct behavior (switching from 0 available to 1 available) +// maximumValue: qualityModel.qualitySliderAvailableMax >= 1 ? qualityModel.qualitySliderAvailableMax : 1 +// stepSize: 1 +// +// value: qualityModel.qualitySliderActiveIndex +// +// width: qualityModel.qualitySliderStepWidth * (qualityModel.availableTotalTicks - 1) +// +// anchors.right: parent.right +// anchors.rightMargin: qualityModel.qualitySliderMarginRight +// +// style: SliderStyle +// { +// //Draw Available line +// groove: Rectangle +// { +// implicitHeight: 2 * screenScaleFactor +// color: UM.Theme.getColor("quality_slider_available") +// radius: Math.round(height / 2) +// } +// +// handle: Rectangle +// { +// id: qualityhandleButton +// color: UM.Theme.getColor("quality_slider_available") +// implicitWidth: 12 * screenScaleFactor +// implicitHeight: implicitWidth +// radius: Math.round(implicitWidth / 2) +// visible: !Cura.SimpleModeSettingsManager.isProfileCustomized && !Cura.SimpleModeSettingsManager.isProfileUserCreated && qualityModel.existingQualityProfile +// } +// } +// +// onValueChanged: +// { +// // only change if an active machine is set and the slider is visible at all. +// if (Cura.MachineManager.activeMachine != null && visible) +// { +// // prevent updating during view initializing. Trigger only if the value changed by user +// if (qualitySlider.value != qualityModel.qualitySliderActiveIndex && qualityModel.qualitySliderActiveIndex != -1) +// { +// // start updating with short delay +// qualitySliderChangeTimer.start() +// } +// } +// } +// } +// +// MouseArea +// { +// id: speedSliderMouseArea +// anchors.fill: parent +// hoverEnabled: true +// enabled: Cura.SimpleModeSettingsManager.isProfileUserCreated +// +// onEntered: +// { +// var content = catalog.i18nc("@tooltip", "A custom profile is currently active. To enable the quality slider, choose a default quality profile in Custom tab") +// base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), content) +// } +// onExited: base.hideTooltip() +// } +// } +// +// UM.SimpleButton +// { +// id: customisedSettings +// +// visible: Cura.SimpleModeSettingsManager.isProfileCustomized || Cura.SimpleModeSettingsManager.isProfileUserCreated +// height: Math.round(speedSlider.height * 0.8) +// width: Math.round(speedSlider.height * 0.8) +// +// anchors.verticalCenter: speedSlider.verticalCenter +// anchors.right: speedSlider.left +// anchors.rightMargin: Math.round(UM.Theme.getSize("thick_margin").width / 2) +// +// color: hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button"); +// iconSource: UM.Theme.getIcon("reset"); +// +// onClicked: +// { +// // if the current profile is user-created, switch to a built-in quality +// Cura.MachineManager.resetToUseDefaultQuality() +// } +// onEntered: +// { +// var content = catalog.i18nc("@tooltip","You have modified some profile settings. If you want to change these go to custom mode.") +// base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), content) +// } +// onExited: base.hideTooltip() +// } +} \ No newline at end of file diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml new file mode 100644 index 0000000000..9c4e5ed576 --- /dev/null +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml @@ -0,0 +1,175 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +// +// Enable support +// +Row +{ + + Cura.IconWithText + { + id: enableSupportLabel + visible: enableSupportCheckBox.visible + source: UM.Theme.getIcon("category_support") + text: catalog.i18nc("@label", "Support") + width: labelColumnWidth + } + + CheckBox + { + id: enableSupportCheckBox + property alias _hovered: enableSupportMouseArea.containsMouse + + style: UM.Theme.styles.checkbox + enabled: base.settingsEnabled + + visible: supportEnabled.properties.enabled == "True" + checked: supportEnabled.properties.value == "True" + + MouseArea + { + id: enableSupportMouseArea + anchors.fill: parent + hoverEnabled: true + onClicked: supportEnabled.setPropertyValue("value", supportEnabled.properties.value != "True") + + onEntered: base.showTooltip(enableSupportCheckBox, Qt.point(-enableSupportCheckBox.x, 0), + catalog.i18nc("@label", "Generate structures to support parts of the model which have overhangs. Without these structures, such parts would collapse during printing.")) + + onExited: base.hideTooltip() + + } + } + + ComboBox + { + id: supportExtruderCombobox + visible: enableSupportCheckBox.visible && (supportEnabled.properties.value == "True") && (extrudersEnabledCount.properties.value > 1) + model: extruderModel + + property string color_override: "" // for manually setting values + property string color: // is evaluated automatically, but the first time is before extruderModel being filled + { + var current_extruder = extruderModel.get(currentIndex); + color_override = ""; + if (current_extruder === undefined) return "" + return (current_extruder.color) ? current_extruder.color : ""; + } + + textRole: "text" // this solves that the combobox isn't populated in the first time Cura is started + + width: Math.round(UM.Theme.getSize("print_setup_widget").width * .55) - Math.round(UM.Theme.getSize("thick_margin").width / 2) - enableSupportCheckBox.width + height: ((supportEnabled.properties.value == "True") && (machineExtruderCount.properties.value > 1)) ? UM.Theme.getSize("setting_control").height : 0 + + Behavior on height { NumberAnimation { duration: 100 } } + + style: UM.Theme.styles.combobox_color + enabled: base.settingsEnabled + property alias _hovered: supportExtruderMouseArea.containsMouse + + currentIndex: + { + if (supportExtruderNr.properties == null) + { + return Cura.MachineManager.defaultExtruderPosition + } + else + { + var extruder = parseInt(supportExtruderNr.properties.value) + if ( extruder === -1) + { + return Cura.MachineManager.defaultExtruderPosition + } + return extruder; + } + } + + onActivated: supportExtruderNr.setPropertyValue("value", String(index)) + + MouseArea + { + id: supportExtruderMouseArea + anchors.fill: parent + hoverEnabled: true + enabled: base.settingsEnabled + acceptedButtons: Qt.NoButton + onEntered: + { + base.showTooltip(supportExtruderCombobox, Qt.point(-supportExtruderCombobox.x, 0), + catalog.i18nc("@label", "Select which extruder to use for support. This will build up supporting structures below the model to prevent the model from sagging or printing in mid air.")); + } + onExited: base.hideTooltip() + + } + + function updateCurrentColor() + { + var current_extruder = extruderModel.get(currentIndex) + if (current_extruder !== undefined) + { + supportExtruderCombobox.color_override = current_extruder.color + } + } + } + + ListModel + { + id: extruderModel + Component.onCompleted: populateExtruderModel() + } + + //: Model used to populate the extrudelModel + Cura.ExtrudersModel + { + id: extruders + onModelChanged: populateExtruderModel() + } + + UM.SettingPropertyProvider + { + id: supportEnabled + containerStack: Cura.MachineManager.activeMachine + key: "support_enable" + watchedProperties: [ "value", "enabled", "description" ] + storeIndex: 0 + } + + UM.SettingPropertyProvider + { + id: extrudersEnabledCount + containerStack: Cura.MachineManager.activeMachine + key: "extruders_enabled_count" + watchedProperties: [ "value" ] + storeIndex: 0 + } + + UM.SettingPropertyProvider + { + id: supportExtruderNr + containerStack: Cura.MachineManager.activeMachine + key: "support_extruder_nr" + watchedProperties: [ "value" ] + storeIndex: 0 + } + + function populateExtruderModel() + { + extruderModel.clear() + for (var extruderNumber = 0; extruderNumber < extruders.rowCount(); extruderNumber++) + { + extruderModel.append({ + text: extruders.getItem(extruderNumber).name, + color: extruders.getItem(extruderNumber).color + }) + } + supportExtruderCombobox.updateCurrentColor() + } +} \ No newline at end of file diff --git a/resources/qml/PrintSetupSelector/RecommendedPrintSetup.qml b/resources/qml/PrintSetupSelector/RecommendedPrintSetup.qml deleted file mode 100644 index b48282135b..0000000000 --- a/resources/qml/PrintSetupSelector/RecommendedPrintSetup.qml +++ /dev/null @@ -1,1064 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.7 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 - -import UM 1.2 as UM -import Cura 1.0 as Cura - -Column -{ - id: base - - signal showTooltip(Item item, point location, string text) - signal hideTooltip() - height: childrenRect.height + 2 * padding - - padding: UM.Theme.getSize("thick_margin").width - spacing: UM.Theme.getSize("default_margin").height - - property Action configureSettings - - property bool settingsEnabled: Cura.ExtruderManager.activeExtruderStackId || extrudersEnabledCount.properties.value == 1 - property real labelColumnWidth: Math.round(width / 3) - property real settingsColumnWidth: width - labelColumnWidth - - UM.I18nCatalog - { - id: catalog - name: "cura" - } - - // - // Quality profile - // - Item - { - id: qualityRow - - anchors.left: parent.left - anchors.right: parent.right - height: childrenRect.height - - Timer - { - id: qualitySliderChangeTimer - interval: 50 - running: false - repeat: false - onTriggered: - { - var item = Cura.QualityProfilesDropDownMenuModel.getItem(qualitySlider.value); - Cura.MachineManager.activeQualityGroup = item.quality_group; - } - } - - Component.onCompleted: qualityModel.update() - - Connections - { - target: Cura.QualityProfilesDropDownMenuModel - onItemsChanged: qualityModel.update() - } - - Connections { - target: base - onVisibleChanged: - { - // update needs to be called when the widgets are visible, otherwise the step width calculation - // will fail because the width of an invisible item is 0. - if (visible) - { - qualityModel.update(); - } - } - } - - ListModel - { - id: qualityModel - - property var totalTicks: 0 - property var availableTotalTicks: 0 - property var existingQualityProfile: 0 - - property var qualitySliderActiveIndex: 0 - property var qualitySliderStepWidth: 0 - property var qualitySliderAvailableMin: 0 - property var qualitySliderAvailableMax: 0 - property var qualitySliderMarginRight: 0 - - function update () - { - reset() - - var availableMin = -1 - var availableMax = -1 - - for (var i = 0; i < Cura.QualityProfilesDropDownMenuModel.rowCount(); i++) - { - var qualityItem = Cura.QualityProfilesDropDownMenuModel.getItem(i) - - // Add each quality item to the UI quality model - qualityModel.append(qualityItem) - - // Set selected value - if (Cura.MachineManager.activeQualityType == qualityItem.quality_type) - { - // set to -1 when switching to user created profile so all ticks are clickable - if (Cura.SimpleModeSettingsManager.isProfileUserCreated) - { - qualityModel.qualitySliderActiveIndex = -1 - } - else - { - qualityModel.qualitySliderActiveIndex = i - } - - qualityModel.existingQualityProfile = 1 - } - - // Set min available - if (qualityItem.available && availableMin == -1) - { - availableMin = i - } - - // Set max available - if (qualityItem.available) - { - availableMax = i - } - } - - // Set total available ticks for active slider part - if (availableMin != -1) - { - qualityModel.availableTotalTicks = availableMax - availableMin + 1 - } - - // Calculate slider values - calculateSliderStepWidth(qualityModel.totalTicks) - calculateSliderMargins(availableMin, availableMax, qualityModel.totalTicks) - - qualityModel.qualitySliderAvailableMin = availableMin - qualityModel.qualitySliderAvailableMax = availableMax - } - - function calculateSliderStepWidth (totalTicks) - { - qualityModel.qualitySliderStepWidth = totalTicks != 0 ? Math.round((settingsColumnWidth) / (totalTicks)) : 0 - } - - function calculateSliderMargins (availableMin, availableMax, totalTicks) - { - if (availableMin == -1 || (availableMin == 0 && availableMax == 0)) - { - qualityModel.qualitySliderMarginRight = Math.round(settingsColumnWidth) - } - else if (availableMin == availableMax) - { - qualityModel.qualitySliderMarginRight = Math.round((totalTicks - availableMin) * qualitySliderStepWidth) - } - else - { - qualityModel.qualitySliderMarginRight = Math.round((totalTicks - availableMax) * qualitySliderStepWidth) - } - } - - function reset () { - qualityModel.clear() - qualityModel.availableTotalTicks = 0 - qualityModel.existingQualityProfile = 0 - - // check, the ticks count cannot be less than zero - qualityModel.totalTicks = Math.max(0, Cura.QualityProfilesDropDownMenuModel.rowCount() - 1) - } - } - - Cura.IconWithText - { - id: qualityRowTitle - source: UM.Theme.getIcon("category_layer_height") - text: catalog.i18nc("@label", "Layer Height") - anchors.bottom: speedSlider.bottom - width: labelColumnWidth - } - - // Show titles for the each quality slider ticks - Item - { - anchors.left: speedSlider.left - anchors.top: speedSlider.bottom - - Repeater - { - model: qualityModel - - Label - { - anchors.verticalCenter: parent.verticalCenter - anchors.top: parent.top - color: (Cura.MachineManager.activeMachine != null && Cura.QualityProfilesDropDownMenuModel.getItem(index).available) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") - text: - { - var result = "" - if(Cura.MachineManager.activeMachine != null) - { - result = Cura.QualityProfilesDropDownMenuModel.getItem(index).layer_height - - if(result == undefined) - { - result = ""; - } - else - { - result = Number(Math.round(result + "e+2") + "e-2"); //Round to 2 decimals. Javascript makes this difficult... - if (result == undefined || result != result) //Parse failure. - { - result = ""; - } - } - } - return result - } - - x: - { - // Make sure the text aligns correctly with each tick - if (qualityModel.totalTicks == 0) - { - // If there is only one tick, align it centrally - return Math.round(((settingsColumnWidth) - width) / 2) - } - else if (index == 0) - { - return Math.round(settingsColumnWidth / qualityModel.totalTicks) * index - } - else if (index == qualityModel.totalTicks) - { - return Math.round(settingsColumnWidth / qualityModel.totalTicks) * index - width - } - else - { - return Math.round((settingsColumnWidth / qualityModel.totalTicks) * index - (width / 2)) - } - } - } - } - } - - //Print speed slider - Rectangle - { - id: speedSlider - - anchors - { - left: qualityRowTitle.right - right: parent.right - } - - // This Item is used only for tooltip, for slider area which is unavailable -// Item -// { -// function showTooltip (showTooltip) -// { -// if (showTooltip) -// { -// var content = catalog.i18nc("@tooltip", "This quality profile is not available for you current material and nozzle configuration. Please change these to enable this quality profile") -// base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), content) -// } -// else -// { -// base.hideTooltip() -// } -// } -// -// id: unavailableLineToolTip -// height: 20 * screenScaleFactor // hovered area height -// z: parent.z + 1 // should be higher, otherwise the area can be hovered -// x: 0 -// anchors.verticalCenter: qualitySlider.verticalCenter -// -// Rectangle -// { -// id: leftArea -// width: -// { -// if (qualityModel.availableTotalTicks == 0) -// { -// return qualityModel.qualitySliderStepWidth * qualityModel.totalTicks -// } -// return qualityModel.qualitySliderStepWidth * qualityModel.qualitySliderAvailableMin - 10 -// } -// height: parent.height -// color: "transparent" -// -// MouseArea -// { -// anchors.fill: parent -// hoverEnabled: true -// enabled: Cura.SimpleModeSettingsManager.isProfileUserCreated == false -// onEntered: unavailableLineToolTip.showTooltip(true) -// onExited: unavailableLineToolTip.showTooltip(false) -// } -// } -// -// Item -// { -// id: rightArea -// width: -// { -// if(qualityModel.availableTotalTicks == 0) -// return 0 -// -// return qualityModel.qualitySliderMarginRight - 10 -// } -// height: parent.height -// x: -// { -// if (qualityModel.availableTotalTicks == 0) -// { -// return 0 -// } -// -// var leftUnavailableArea = qualityModel.qualitySliderStepWidth * qualityModel.qualitySliderAvailableMin -// var totalGap = qualityModel.qualitySliderStepWidth * (qualityModel.availableTotalTicks -1) + leftUnavailableArea + 10 -// -// return totalGap -// } -// -// MouseArea -// { -// anchors.fill: parent -// hoverEnabled: true -// enabled: Cura.SimpleModeSettingsManager.isProfileUserCreated == false -// onEntered: unavailableLineToolTip.showTooltip(true) -// onExited: unavailableLineToolTip.showTooltip(false) -// } -// } -// } - - // Draw Unavailable line - Rectangle - { - id: groovechildrect - width: parent.width - height: 2 * screenScaleFactor - color: UM.Theme.getColor("quality_slider_unavailable") - anchors.verticalCenter: qualitySlider.verticalCenter - - // Draw ticks - Repeater - { - id: qualityRepeater - model: qualityModel.totalTicks > 0 ? qualityModel : 0 - - Rectangle - { - color: Cura.QualityProfilesDropDownMenuModel.getItem(index).available ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") - implicitWidth: 4 * screenScaleFactor - implicitHeight: implicitWidth - anchors.verticalCenter: parent.verticalCenter - x: Math.round(qualityModel.qualitySliderStepWidth * index) - radius: Math.round(implicitWidth / 2) - } - } - } - - // Draw available slider - Slider - { - id: qualitySlider - height: UM.Theme.getSize("thick_margin").height - anchors.bottom: parent.bottom - enabled: qualityModel.totalTicks > 0 && !Cura.SimpleModeSettingsManager.isProfileCustomized - visible: qualityModel.availableTotalTicks > 0 - updateValueWhileDragging : false - - minimumValue: qualityModel.qualitySliderAvailableMin >= 0 ? qualityModel.qualitySliderAvailableMin : 0 - // maximumValue must be greater than minimumValue to be able to see the handle. While the value is strictly - // speaking not always correct, it seems to have the correct behavior (switching from 0 available to 1 available) - maximumValue: qualityModel.qualitySliderAvailableMax >= 1 ? qualityModel.qualitySliderAvailableMax : 1 - stepSize: 1 - - value: qualityModel.qualitySliderActiveIndex - - width: qualityModel.qualitySliderStepWidth * (qualityModel.availableTotalTicks - 1) - - anchors.right: parent.right - anchors.rightMargin: qualityModel.qualitySliderMarginRight - - style: SliderStyle - { - //Draw Available line - groove: Rectangle - { - implicitHeight: 2 * screenScaleFactor - color: UM.Theme.getColor("quality_slider_available") - radius: Math.round(height / 2) - } - - handle: Rectangle - { - id: qualityhandleButton - color: UM.Theme.getColor("quality_slider_available") - implicitWidth: 12 * screenScaleFactor - implicitHeight: implicitWidth - radius: Math.round(implicitWidth / 2) - visible: !Cura.SimpleModeSettingsManager.isProfileCustomized && !Cura.SimpleModeSettingsManager.isProfileUserCreated && qualityModel.existingQualityProfile - } - } - - onValueChanged: - { - // only change if an active machine is set and the slider is visible at all. - if (Cura.MachineManager.activeMachine != null && visible) - { - // prevent updating during view initializing. Trigger only if the value changed by user - if (qualitySlider.value != qualityModel.qualitySliderActiveIndex && qualityModel.qualitySliderActiveIndex != -1) - { - // start updating with short delay - qualitySliderChangeTimer.start() - } - } - } - } - - MouseArea - { - id: speedSliderMouseArea - anchors.fill: parent - hoverEnabled: true - enabled: Cura.SimpleModeSettingsManager.isProfileUserCreated - - onEntered: - { - var content = catalog.i18nc("@tooltip", "A custom profile is currently active. To enable the quality slider, choose a default quality profile in Custom tab") - base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), content) - } - onExited: base.hideTooltip() - } - } - - UM.SimpleButton - { - id: customisedSettings - - visible: Cura.SimpleModeSettingsManager.isProfileCustomized || Cura.SimpleModeSettingsManager.isProfileUserCreated - height: Math.round(speedSlider.height * 0.8) - width: Math.round(speedSlider.height * 0.8) - - anchors.verticalCenter: speedSlider.verticalCenter - anchors.right: speedSlider.left - anchors.rightMargin: Math.round(UM.Theme.getSize("thick_margin").width / 2) - - color: hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button"); - iconSource: UM.Theme.getIcon("reset"); - - onClicked: - { - // if the current profile is user-created, switch to a built-in quality - Cura.MachineManager.resetToUseDefaultQuality() - } - onEntered: - { - var content = catalog.i18nc("@tooltip","You have modified some profile settings. If you want to change these go to custom mode.") - base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), content) - } - onExited: base.hideTooltip() - } - } - - // - // Infill - // - Item - { - anchors.left: parent.left - anchors.right: parent.right - height: childrenRect.height - - Cura.IconWithText - { - id: infillRowTitle - source: UM.Theme.getIcon("category_infill") - text: catalog.i18nc("@label", "Infill") + " (%)" - anchors.bottom: parent.bottom - width: labelColumnWidth - } - - Item - { - id: infillCellRight - - height: infillSlider.height + UM.Theme.getSize("thick_margin").height + enableGradualInfillCheckBox.visible * (enableGradualInfillCheckBox.height + UM.Theme.getSize("thick_margin").height) - - anchors.left: infillRowTitle.right - anchors.right: parent.right - - Label - { - id: selectedInfillRateText - - anchors.left: infillSlider.left - anchors.right: parent.right - - text: parseInt(infillDensity.properties.value) + "%" - horizontalAlignment: Text.AlignLeft - - color: infillSlider.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") - } - - // We use a binding to make sure that after manually setting infillSlider.value it is still bound to the property provider - Binding - { - target: infillSlider - property: "value" - value: parseInt(infillDensity.properties.value) - } - - Slider - { - id: infillSlider - - anchors.top: selectedInfillRateText.bottom - anchors.left: parent.left - anchors.right: infillIcon.left - anchors.rightMargin: UM.Theme.getSize("thick_margin").width - - height: UM.Theme.getSize("thick_margin").height - width: parseInt(infillCellRight.width - UM.Theme.getSize("thick_margin").width - style.handleWidth) - - minimumValue: 0 - maximumValue: 100 - stepSize: 1 - tickmarksEnabled: true - - // disable slider when gradual support is enabled - enabled: parseInt(infillSteps.properties.value) == 0 - - // set initial value from stack - value: parseInt(infillDensity.properties.value) - - onValueChanged: - { - - // Don't round the value if it's already the same - if (parseInt(infillDensity.properties.value) == infillSlider.value) - { - return - } - - // Round the slider value to the nearest multiple of 10 (simulate step size of 10) - var roundedSliderValue = Math.round(infillSlider.value / 10) * 10 - - // Update the slider value to represent the rounded value - infillSlider.value = roundedSliderValue - - // Update value only if the Recomended mode is Active, - // Otherwise if I change the value in the Custom mode the Recomended view will try to repeat - // same operation - var active_mode = UM.Preferences.getValue("cura/active_mode") - - if (active_mode == 0 || active_mode == "simple") - { - Cura.MachineManager.setSettingForAllExtruders("infill_sparse_density", "value", roundedSliderValue) - Cura.MachineManager.resetSettingForAllExtruders("infill_line_distance") - } - } - - style: SliderStyle - { - groove: Rectangle - { - id: groove - implicitWidth: 200 * screenScaleFactor - implicitHeight: 2 * screenScaleFactor - color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") - radius: 1 - } - - handle: Item - { - Rectangle - { - id: handleButton - anchors.centerIn: parent - color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") - implicitWidth: 10 * screenScaleFactor - implicitHeight: 10 * screenScaleFactor - radius: 10 * screenScaleFactor - } - } - - tickmarks: Repeater - { - id: repeater - model: control.maximumValue / control.stepSize + 1 - - // check if a tick should be shown based on it's index and wether the infill density is a multiple of 10 (slider step size) - function shouldShowTick (index) - { - if (index % 10 == 0) - { - return true - } - return false - } - - Rectangle - { - anchors.verticalCenter: parent.verticalCenter - color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") - width: 1 * screenScaleFactor - height: 6 * screenScaleFactor - x: Math.round(styleData.handleWidth / 2 + index * ((repeater.width - styleData.handleWidth) / (repeater.count-1))) - visible: shouldShowTick(index) - } - } - } - } - - Rectangle - { - id: infillIcon - - width: Math.round((parent.width / 5) - (UM.Theme.getSize("thick_margin").width)) - height: width - - anchors.right: parent.right - anchors.top: parent.top - anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height / 2) - - // we loop over all density icons and only show the one that has the current density and steps - Repeater - { - id: infillIconList - model: infillModel - anchors.fill: parent - - function activeIndex () - { - for (var i = 0; i < infillModel.count; i++) - { - var density = Math.round(infillDensity.properties.value) - var steps = Math.round(infillSteps.properties.value) - var infillModelItem = infillModel.get(i) - - if (infillModelItem != "undefined" - && density >= infillModelItem.percentageMin - && density <= infillModelItem.percentageMax - && steps >= infillModelItem.stepsMin - && steps <= infillModelItem.stepsMax) - { - return i - } - } - return -1 - } - - Rectangle - { - anchors.fill: parent - visible: infillIconList.activeIndex() == index - - border.width: UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("quality_slider_unavailable") - - UM.RecolorImage - { - anchors.fill: parent - anchors.margins: 2 * screenScaleFactor - sourceSize.width: width - sourceSize.height: width - source: UM.Theme.getIcon(model.icon) - color: UM.Theme.getColor("quality_slider_unavailable") - } - } - } - } - - // Gradual Support Infill Checkbox - CheckBox - { - id: enableGradualInfillCheckBox - property alias _hovered: enableGradualInfillMouseArea.containsMouse - - anchors.top: infillSlider.bottom - anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height / 2) // closer to slider since it belongs to the same category - anchors.left: infillCellRight.left - - style: UM.Theme.styles.checkbox - enabled: base.settingsEnabled - visible: infillSteps.properties.enabled == "True" - checked: parseInt(infillSteps.properties.value) > 0 - - MouseArea - { - id: enableGradualInfillMouseArea - - anchors.fill: parent - hoverEnabled: true - enabled: true - - property var previousInfillDensity: parseInt(infillDensity.properties.value) - - onClicked: - { - // Set to 90% only when enabling gradual infill - var newInfillDensity; - if (parseInt(infillSteps.properties.value) == 0) - { - previousInfillDensity = parseInt(infillDensity.properties.value) - newInfillDensity = 90 - } else { - newInfillDensity = previousInfillDensity - } - Cura.MachineManager.setSettingForAllExtruders("infill_sparse_density", "value", String(newInfillDensity)) - - var infill_steps_value = 0 - if (parseInt(infillSteps.properties.value) == 0) - { - infill_steps_value = 5 - } - - Cura.MachineManager.setSettingForAllExtruders("gradual_infill_steps", "value", infill_steps_value) - } - - onEntered: base.showTooltip(enableGradualInfillCheckBox, Qt.point(-infillCellRight.x, 0), - catalog.i18nc("@label", "Gradual infill will gradually increase the amount of infill towards the top.")) - - onExited: base.hideTooltip() - - } - - Label - { - id: gradualInfillLabel - height: parent.height - anchors.left: enableGradualInfillCheckBox.right - anchors.leftMargin: Math.round(UM.Theme.getSize("thick_margin").width / 2) - verticalAlignment: Text.AlignVCenter; - text: catalog.i18nc("@label", "Enable gradual") - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - } - } - - // Infill list model for mapping icon - ListModel - { - id: infillModel - Component.onCompleted: - { - infillModel.append({ - percentageMin: -1, - percentageMax: 0, - stepsMin: -1, - stepsMax: 0, - icon: "hollow" - }) - infillModel.append({ - percentageMin: 0, - percentageMax: 40, - stepsMin: -1, - stepsMax: 0, - icon: "sparse" - }) - infillModel.append({ - percentageMin: 40, - percentageMax: 89, - stepsMin: -1, - stepsMax: 0, - icon: "dense" - }) - infillModel.append({ - percentageMin: 90, - percentageMax: 9999999999, - stepsMin: -1, - stepsMax: 0, - icon: "solid" - }) - infillModel.append({ - percentageMin: 0, - percentageMax: 9999999999, - stepsMin: 1, - stepsMax: 9999999999, - icon: "gradual" - }) - } - } - } - } - - // - // Enable support - // - Row - { - anchors.left: parent.left - anchors.right: parent.right - height: childrenRect.height - - Cura.IconWithText - { - id: enableSupportLabel - visible: enableSupportCheckBox.visible - source: UM.Theme.getIcon("category_support") - text: catalog.i18nc("@label", "Support") - width: labelColumnWidth - } - - CheckBox - { - id: enableSupportCheckBox - property alias _hovered: enableSupportMouseArea.containsMouse - - style: UM.Theme.styles.checkbox - enabled: base.settingsEnabled - - visible: supportEnabled.properties.enabled == "True" - checked: supportEnabled.properties.value == "True" - - MouseArea - { - id: enableSupportMouseArea - anchors.fill: parent - hoverEnabled: true - onClicked: supportEnabled.setPropertyValue("value", supportEnabled.properties.value != "True") - - onEntered: base.showTooltip(enableSupportCheckBox, Qt.point(-enableSupportCheckBox.x, 0), - catalog.i18nc("@label", "Generate structures to support parts of the model which have overhangs. Without these structures, such parts would collapse during printing.")) - - onExited: base.hideTooltip() - - } - } - - ComboBox - { - id: supportExtruderCombobox - visible: enableSupportCheckBox.visible && (supportEnabled.properties.value == "True") && (extrudersEnabledCount.properties.value > 1) - model: extruderModel - - property string color_override: "" // for manually setting values - property string color: // is evaluated automatically, but the first time is before extruderModel being filled - { - var current_extruder = extruderModel.get(currentIndex); - color_override = ""; - if (current_extruder === undefined) return "" - return (current_extruder.color) ? current_extruder.color : ""; - } - - textRole: "text" // this solves that the combobox isn't populated in the first time Cura is started - - width: Math.round(UM.Theme.getSize("print_setup_widget").width * .55) - Math.round(UM.Theme.getSize("thick_margin").width / 2) - enableSupportCheckBox.width - height: ((supportEnabled.properties.value == "True") && (machineExtruderCount.properties.value > 1)) ? UM.Theme.getSize("setting_control").height : 0 - - Behavior on height { NumberAnimation { duration: 100 } } - - style: UM.Theme.styles.combobox_color - enabled: base.settingsEnabled - property alias _hovered: supportExtruderMouseArea.containsMouse - - currentIndex: - { - if (supportExtruderNr.properties == null) - { - return Cura.MachineManager.defaultExtruderPosition - } - else - { - var extruder = parseInt(supportExtruderNr.properties.value) - if ( extruder === -1) - { - return Cura.MachineManager.defaultExtruderPosition - } - return extruder; - } - } - - onActivated: supportExtruderNr.setPropertyValue("value", String(index)) - - MouseArea - { - id: supportExtruderMouseArea - anchors.fill: parent - hoverEnabled: true - enabled: base.settingsEnabled - acceptedButtons: Qt.NoButton - onEntered: - { - base.showTooltip(supportExtruderCombobox, Qt.point(-supportExtruderCombobox.x, 0), - catalog.i18nc("@label", "Select which extruder to use for support. This will build up supporting structures below the model to prevent the model from sagging or printing in mid air.")); - } - onExited: base.hideTooltip() - - } - - function updateCurrentColor() - { - var current_extruder = extruderModel.get(currentIndex) - if (current_extruder !== undefined) - { - supportExtruderCombobox.color_override = current_extruder.color - } - } - - } - } - - // Adhesion - Row - { - anchors.left: parent.left - anchors.right: parent.right - height: childrenRect.height - - Cura.IconWithText - { - id: adhesionHelperLabel - visible: adhesionCheckBox.visible - source: UM.Theme.getIcon("category_adhesion") - text: catalog.i18nc("@label", "Adhesion") - width: labelColumnWidth - } - - CheckBox - { - id: adhesionCheckBox - property alias _hovered: adhesionMouseArea.containsMouse - - //: Setting enable printing build-plate adhesion helper checkbox - style: UM.Theme.styles.checkbox - enabled: base.settingsEnabled - - visible: platformAdhesionType.properties.enabled == "True" - checked: platformAdhesionType.properties.value != "skirt" && platformAdhesionType.properties.value != "none" - - MouseArea - { - id: adhesionMouseArea - anchors.fill: parent - hoverEnabled: true - enabled: base.settingsEnabled - onClicked: - { - var adhesionType = "skirt" - if(!parent.checked) - { - // Remove the "user" setting to see if the rest of the stack prescribes a brim or a raft - platformAdhesionType.removeFromContainer(0) - adhesionType = platformAdhesionType.properties.value - if(adhesionType == "skirt" || adhesionType == "none") - { - // If the rest of the stack doesn't prescribe an adhesion-type, default to a brim - adhesionType = "brim" - } - } - platformAdhesionType.setPropertyValue("value", adhesionType) - } - onEntered: - { - base.showTooltip(adhesionCheckBox, Qt.point(-adhesionCheckBox.x, 0), - catalog.i18nc("@label", "Enable printing a brim or raft. This will add a flat area around or under your object which is easy to cut off afterwards.")); - } - onExited: base.hideTooltip() - } - } - } - - ListModel - { - id: extruderModel - Component.onCompleted: populateExtruderModel() - } - - //: Model used to populate the extrudelModel - Cura.ExtrudersModel - { - id: extruders - onModelChanged: populateExtruderModel() - } - - UM.SettingPropertyProvider - { - id: infillExtruderNumber - containerStackId: Cura.MachineManager.activeStackId - key: "infill_extruder_nr" - watchedProperties: [ "value" ] - storeIndex: 0 - } - - UM.SettingPropertyProvider - { - id: infillDensity - containerStackId: Cura.MachineManager.activeStackId - key: "infill_sparse_density" - watchedProperties: [ "value" ] - storeIndex: 0 - } - - UM.SettingPropertyProvider - { - id: infillSteps - containerStackId: Cura.MachineManager.activeStackId - key: "gradual_infill_steps" - watchedProperties: ["value", "enabled"] - storeIndex: 0 - } - - UM.SettingPropertyProvider - { - id: platformAdhesionType - containerStack: Cura.MachineManager.activeMachine - removeUnusedValue: false //Doesn't work with settings that are resolved. - key: "adhesion_type" - watchedProperties: [ "value", "enabled" ] - storeIndex: 0 - } - - UM.SettingPropertyProvider - { - id: supportEnabled - containerStack: Cura.MachineManager.activeMachine - key: "support_enable" - watchedProperties: [ "value", "enabled", "description" ] - storeIndex: 0 - } - - UM.SettingPropertyProvider - { - id: extrudersEnabledCount - containerStack: Cura.MachineManager.activeMachine - key: "extruders_enabled_count" - watchedProperties: [ "value" ] - storeIndex: 0 - } - - UM.SettingPropertyProvider - { - id: supportExtruderNr - containerStack: Cura.MachineManager.activeMachine - key: "support_extruder_nr" - watchedProperties: [ "value" ] - storeIndex: 0 - } - - function populateExtruderModel() - { - extruderModel.clear() - for (var extruderNumber = 0; extruderNumber < extruders.rowCount(); extruderNumber++) - { - extruderModel.append({ - text: extruders.getItem(extruderNumber).name, - color: extruders.getItem(extruderNumber).color - }) - } - supportExtruderCombobox.updateCurrentColor() - } -} diff --git a/resources/qml/qmldir b/resources/qml/qmldir index 6db8e0c544..c0a8bac0ae 100644 --- a/resources/qml/qmldir +++ b/resources/qml/qmldir @@ -14,4 +14,5 @@ OutputDevicesActionButton 1.0 OutputDevicesActionButton.qml ExpandableComponent 1.0 ExpandableComponent.qml PrinterTypeLabel 1.0 PrinterTypeLabel.qml ViewsSelector 1.0 ViewsSelector.qml -ToolbarButton 1.0 ToolbarButton.qml \ No newline at end of file +ToolbarButton 1.0 ToolbarButton.qml +SettingView 1.0 SettingView.qml \ No newline at end of file From 6d4a460e58d81c66e849bcf17b444c3b164272ef Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 30 Nov 2018 13:53:53 +0100 Subject: [PATCH 0556/1292] Move USB sidebar into the main view of the monitorstage CURA-5943 --- plugins/MonitorStage/MonitorMain.qml | 40 +++ plugins/MonitorStage/MonitorMainView.qml | 64 ----- plugins/MonitorStage/MonitorMenu.qml | 14 + plugins/MonitorStage/MonitorStage.py | 17 +- plugins/USBPrinting/MonitorItem.qml | 27 ++ plugins/USBPrinting/USBPrinterOutputDevice.py | 5 +- resources/qml/Cura.qml | 11 +- resources/qml/PrintMonitor.qml | 256 ++++++++++-------- 8 files changed, 250 insertions(+), 184 deletions(-) create mode 100644 plugins/MonitorStage/MonitorMain.qml delete mode 100644 plugins/MonitorStage/MonitorMainView.qml create mode 100644 plugins/MonitorStage/MonitorMenu.qml create mode 100644 plugins/USBPrinting/MonitorItem.qml diff --git a/plugins/MonitorStage/MonitorMain.qml b/plugins/MonitorStage/MonitorMain.qml new file mode 100644 index 0000000000..1f287fc0fa --- /dev/null +++ b/plugins/MonitorStage/MonitorMain.qml @@ -0,0 +1,40 @@ +// Copyright (c) 2017 Ultimaker B.V. + +import QtQuick 2.10 +import QtQuick.Controls 1.4 + +import UM 1.3 as UM +import Cura 1.0 as Cura + + +Item +{ + // We show a nice overlay on the 3D viewer when the current output device has no monitor view + Rectangle + { + id: viewportOverlay + + color: UM.Theme.getColor("viewport_overlay") + anchors.fill: parent + MouseArea + { + anchors.fill: parent + acceptedButtons: Qt.AllButtons + onWheel: wheel.accepted = true + } + } + + Loader + { + id: monitorViewComponent + + anchors.fill: parent + + height: parent.height + + property real maximumWidth: parent.width + property real maximumHeight: parent.height + + sourceComponent: Cura.MachineManager.printerOutputDevices.length > 0 ? Cura.MachineManager.printerOutputDevices[0].monitorItem: null + } +} diff --git a/plugins/MonitorStage/MonitorMainView.qml b/plugins/MonitorStage/MonitorMainView.qml deleted file mode 100644 index f5696bbf54..0000000000 --- a/plugins/MonitorStage/MonitorMainView.qml +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) 2017 Ultimaker B.V. - -import QtQuick 2.10 -import QtQuick.Controls 1.4 - -import UM 1.3 as UM -import Cura 1.0 as Cura - - -Item -{ - // parent could be undefined as this component is not visible at all times - width: parent ? parent.width : 0 - height: parent ? parent.height : 0 - - // We show a nice overlay on the 3D viewer when the current output device has no monitor view - Rectangle - { - id: viewportOverlay - - color: UM.Theme.getColor("viewport_overlay") - width: parent.width - height: parent.height - - MouseArea - { - anchors.fill: parent - acceptedButtons: Qt.AllButtons - onWheel: wheel.accepted = true - } - } - - Loader - { - id: monitorViewComponent - - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.left: parent.left - - // If the sidebar is not set, the view should take the complete space. - property var widthFactor: monitorSidebarComponent.source == "" ? 1.0 : 0.7 - - width: Math.round(parent.width * widthFactor) - height: parent.height - - property real maximumWidth: parent.width - property real maximumHeight: parent.height - - sourceComponent: Cura.MachineManager.printerOutputDevices.length > 0 ? Cura.MachineManager.printerOutputDevices[0].monitorItem: null - } - - Loader - { - id: monitorSidebarComponent - - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.left: monitorViewComponent.right - anchors.right: parent.right - - source: UM.Controller.activeStage.sidebarComponent != null ? UM.Controller.activeStage.sidebarComponent : "" - } -} diff --git a/plugins/MonitorStage/MonitorMenu.qml b/plugins/MonitorStage/MonitorMenu.qml new file mode 100644 index 0000000000..4dec719313 --- /dev/null +++ b/plugins/MonitorStage/MonitorMenu.qml @@ -0,0 +1,14 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.3 + +import UM 1.3 as UM +import Cura 1.1 as Cura + +Item +{ + signal showTooltip(Item item, point location, string text) + signal hideTooltip() +} \ No newline at end of file diff --git a/plugins/MonitorStage/MonitorStage.py b/plugins/MonitorStage/MonitorStage.py index ace201e994..69b7f20f4e 100644 --- a/plugins/MonitorStage/MonitorStage.py +++ b/plugins/MonitorStage/MonitorStage.py @@ -65,15 +65,10 @@ class MonitorStage(CuraStage): # We can only connect now, as we need to be sure that everything is loaded (plugins get created quite early) Application.getInstance().getMachineManager().outputDevicesChanged.connect(self._onOutputDevicesChanged) self._onOutputDevicesChanged() - self._updateMainOverlay() - self._updateSidebar() - def _updateMainOverlay(self): - main_component_path = os.path.join(PluginRegistry.getInstance().getPluginPath("MonitorStage"), - "MonitorMainView.qml") - self.addDisplayComponent("main", main_component_path) - - def _updateSidebar(self): - sidebar_component_path = os.path.join(Resources.getPath(Application.getInstance().ResourceTypes.QmlFiles), - "MonitorSidebar.qml") - self.addDisplayComponent("sidebar", sidebar_component_path) + plugin_path = Application.getInstance().getPluginRegistry().getPluginPath(self.getPluginId()) + if plugin_path is not None: + menu_component_path = os.path.join(plugin_path, "MonitorMenu.qml") + main_component_path = os.path.join(plugin_path, "MonitorMain.qml") + self.addDisplayComponent("menu", menu_component_path) + self.addDisplayComponent("main", main_component_path) diff --git a/plugins/USBPrinting/MonitorItem.qml b/plugins/USBPrinting/MonitorItem.qml new file mode 100644 index 0000000000..a93b3eb69b --- /dev/null +++ b/plugins/USBPrinting/MonitorItem.qml @@ -0,0 +1,27 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.10 +import QtQuick.Controls 2.0 +import QtQuick.Layouts 1.3 + +import UM 1.2 as UM +import Cura 1.0 as Cura +Component +{ + Item + { + Rectangle + { + anchors.right: parent.right + width: parent.width * 0.3 + anchors.top: parent.top + anchors.bottom: parent.bottom + + Cura.PrintMonitor + { + anchors.fill: parent + } + } + } +} \ No newline at end of file diff --git a/plugins/USBPrinting/USBPrinterOutputDevice.py b/plugins/USBPrinting/USBPrinterOutputDevice.py index e1c39ff8fa..1d42e70366 100644 --- a/plugins/USBPrinting/USBPrinterOutputDevice.py +++ b/plugins/USBPrinting/USBPrinterOutputDevice.py @@ -1,5 +1,6 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +import os from UM.Logger import Logger from UM.i18n import i18nCatalog @@ -64,7 +65,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice): self._accepts_commands = True self._paused = False - self._printer_busy = False # when printer is preheating and waiting (M190/M109), or when waiting for action on the printer + self._printer_busy = False # When printer is preheating and waiting (M190/M109), or when waiting for action on the printer self.setConnectionText(catalog.i18nc("@info:status", "Connected via USB")) @@ -77,6 +78,8 @@ class USBPrinterOutputDevice(PrinterOutputDevice): self._firmware_name_requested = False self._firmware_updater = AvrFirmwareUpdater(self) + self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "MonitorItem.qml") + CuraApplication.getInstance().getOnExitCallbackManager().addCallback(self._checkActivePrintingUponAppExit) # This is a callback function that checks if there is any printing in progress via USB when the application tries diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 36f5758fa3..3578888886 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -146,6 +146,7 @@ UM.MainWindow Rectangle { + id: stageMenuBackground anchors { left: parent.left @@ -153,7 +154,7 @@ UM.MainWindow top: parent.top } visible: stageMenu.source != "" - height: Math.round(UM.Theme.getSize("stage_menu").height / 2) + height: visible ? Math.round(UM.Theme.getSize("stage_menu").height / 2) : 0 LinearGradient { @@ -254,7 +255,13 @@ UM.MainWindow // A stage can control this area. If nothing is set, it will therefore show the 3D view. id: main - anchors.fill: parent + anchors + { + top: stageMenuBackground.bottom + left: parent.left + right: parent.right + bottom: parent.bottom + } source: UM.Controller.activeStage != null ? UM.Controller.activeStage.mainComponent : "" } diff --git a/resources/qml/PrintMonitor.qml b/resources/qml/PrintMonitor.qml index 723279847a..3cc161cbe7 100644 --- a/resources/qml/PrintMonitor.qml +++ b/resources/qml/PrintMonitor.qml @@ -11,136 +11,180 @@ import Cura 1.0 as Cura import "PrinterOutput" -Column + +Rectangle { - id: printMonitor + id: base + UM.I18nCatalog { id: catalog; name: "cura"} + + function showTooltip(item, position, text) + { + tooltip.text = text; + position = item.mapToItem(base, position.x - UM.Theme.getSize("default_arrow").width, position.y); + tooltip.show(position); + } + + function hideTooltip() + { + tooltip.hide(); + } + + function strPadLeft(string, pad, length) { + return (new Array(length + 1).join(pad) + string).slice(-length); + } + + function getPrettyTime(time) + { + var hours = Math.floor(time / 3600) + time -= hours * 3600 + var minutes = Math.floor(time / 60); + time -= minutes * 60 + var seconds = Math.floor(time); + + var finalTime = strPadLeft(hours, "0", 2) + ":" + strPadLeft(minutes, "0", 2) + ":" + strPadLeft(seconds, "0", 2); + return finalTime; + } + property var connectedDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null property var activePrinter: connectedDevice != null ? connectedDevice.activePrinter : null property var activePrintJob: activePrinter != null ? activePrinter.activePrintJob: null - Cura.ExtrudersModel + SidebarTooltip { - id: extrudersModel - simpleNames: true + id: tooltip } - OutputDeviceHeader + Column { - outputDevice: connectedDevice - } + id: printMonitor - Rectangle - { - color: UM.Theme.getColor("wide_lining") - width: parent.width - height: childrenRect.height + anchors.fill: parent - Flow + Cura.ExtrudersModel { - id: extrudersGrid - spacing: UM.Theme.getSize("thick_lining").width + id: extrudersModel + simpleNames: true + } + + OutputDeviceHeader + { + outputDevice: connectedDevice + } + + Rectangle + { + color: UM.Theme.getColor("wide_lining") width: parent.width + height: childrenRect.height - Repeater + Flow { - id: extrudersRepeater - model: activePrinter != null ? activePrinter.extruders : null + id: extrudersGrid + spacing: UM.Theme.getSize("thick_lining").width + width: parent.width - ExtruderBox + Repeater { - color: UM.Theme.getColor("main_background") - width: index == machineExtruderCount.properties.value - 1 && index % 2 == 0 ? extrudersGrid.width : Math.round(extrudersGrid.width / 2 - UM.Theme.getSize("thick_lining").width / 2) - extruderModel: modelData + id: extrudersRepeater + model: activePrinter != null ? activePrinter.extruders : null + + ExtruderBox + { + color: UM.Theme.getColor("main_background") + width: index == machineExtruderCount.properties.value - 1 && index % 2 == 0 ? extrudersGrid.width : Math.round(extrudersGrid.width / 2 - UM.Theme.getSize("thick_lining").width / 2) + extruderModel: modelData + } } } } - } - Rectangle - { - color: UM.Theme.getColor("wide_lining") - width: parent.width - height: UM.Theme.getSize("thick_lining").width - } - - HeatedBedBox - { - visible: { - if(activePrinter != null && activePrinter.bedTemperature != -1) - { - return true - } - return false - } - printerModel: activePrinter - } - - UM.SettingPropertyProvider - { - id: bedTemperature - containerStack: Cura.MachineManager.activeMachine - key: "material_bed_temperature" - watchedProperties: ["value", "minimum_value", "maximum_value", "resolve"] - storeIndex: 0 - - property var resolve: Cura.MachineManager.activeStack != Cura.MachineManager.activeMachine ? properties.resolve : "None" - } - - UM.SettingPropertyProvider - { - id: machineExtruderCount - containerStack: Cura.MachineManager.activeMachine - key: "machine_extruder_count" - watchedProperties: ["value"] - } - - ManualPrinterControl - { - printerModel: activePrinter - visible: activePrinter != null ? activePrinter.canControlManually : false - } - - - MonitorSection - { - label: catalog.i18nc("@label", "Active print") - width: base.width - visible: activePrinter != null - } - - - MonitorItem - { - label: catalog.i18nc("@label", "Job Name") - value: activePrintJob != null ? activePrintJob.name : "" - width: base.width - visible: activePrinter != null - } - - MonitorItem - { - label: catalog.i18nc("@label", "Printing Time") - value: activePrintJob != null ? getPrettyTime(activePrintJob.timeTotal) : "" - width: base.width - visible: activePrinter != null - } - - MonitorItem - { - label: catalog.i18nc("@label", "Estimated time left") - value: activePrintJob != null ? getPrettyTime(activePrintJob.timeTotal - activePrintJob.timeElapsed) : "" - visible: + Rectangle { - if(activePrintJob == null) + color: UM.Theme.getColor("wide_lining") + width: parent.width + height: UM.Theme.getSize("thick_lining").width + } + + HeatedBedBox + { + visible: { + if(activePrinter != null && activePrinter.bedTemperature != -1) + { + return true + } return false } - - return (activePrintJob.state == "printing" || - activePrintJob.state == "resuming" || - activePrintJob.state == "pausing" || - activePrintJob.state == "paused") + printerModel: activePrinter + } + + UM.SettingPropertyProvider + { + id: bedTemperature + containerStack: Cura.MachineManager.activeMachine + key: "material_bed_temperature" + watchedProperties: ["value", "minimum_value", "maximum_value", "resolve"] + storeIndex: 0 + + property var resolve: Cura.MachineManager.activeStack != Cura.MachineManager.activeMachine ? properties.resolve : "None" + } + + UM.SettingPropertyProvider + { + id: machineExtruderCount + containerStack: Cura.MachineManager.activeMachine + key: "machine_extruder_count" + watchedProperties: ["value"] + } + + ManualPrinterControl + { + printerModel: activePrinter + visible: activePrinter != null ? activePrinter.canControlManually : false + } + + + MonitorSection + { + label: catalog.i18nc("@label", "Active print") + width: base.width + visible: activePrinter != null + } + + + MonitorItem + { + label: catalog.i18nc("@label", "Job Name") + value: activePrintJob != null ? activePrintJob.name : "" + width: base.width + visible: activePrinter != null + } + + MonitorItem + { + label: catalog.i18nc("@label", "Printing Time") + value: activePrintJob != null ? getPrettyTime(activePrintJob.timeTotal) : "" + width: base.width + visible: activePrinter != null + } + + MonitorItem + { + label: catalog.i18nc("@label", "Estimated time left") + value: activePrintJob != null ? getPrettyTime(activePrintJob.timeTotal - activePrintJob.timeElapsed) : "" + visible: + { + if(activePrintJob == null) + { + return false + } + + return (activePrintJob.state == "printing" || + activePrintJob.state == "resuming" || + activePrintJob.state == "pausing" || + activePrintJob.state == "paused") + } + width: base.width } - width: base.width } -} +} \ No newline at end of file From 48bdb735f2bfa9ef044065e5a9e0ca2a60e17361 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 30 Nov 2018 13:58:44 +0100 Subject: [PATCH 0557/1292] Added MachineSelector to monitor menu CURA-5943 --- plugins/MonitorStage/MonitorMenu.qml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plugins/MonitorStage/MonitorMenu.qml b/plugins/MonitorStage/MonitorMenu.qml index 4dec719313..bc95c276e8 100644 --- a/plugins/MonitorStage/MonitorMenu.qml +++ b/plugins/MonitorStage/MonitorMenu.qml @@ -11,4 +11,13 @@ Item { signal showTooltip(Item item, point location, string text) signal hideTooltip() + + Cura.MachineSelector + { + id: machineSelection + headerCornerSide: Cura.RoundedRectangle.Direction.All + width: UM.Theme.getSize("machine_selector_widget").width + height: parent.height + anchors.centerIn: parent + } } \ No newline at end of file From 59a81be65c395628962d3587d24d62819d69259c Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 30 Nov 2018 14:10:42 +0100 Subject: [PATCH 0558/1292] Fixed some leftover graphical issues CURA-5943 --- plugins/USBPrinting/MonitorItem.qml | 19 +++++++++++++++++++ .../qml/PrinterOutput/OutputDeviceHeader.qml | 4 ++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/plugins/USBPrinting/MonitorItem.qml b/plugins/USBPrinting/MonitorItem.qml index a93b3eb69b..8041698ef0 100644 --- a/plugins/USBPrinting/MonitorItem.qml +++ b/plugins/USBPrinting/MonitorItem.qml @@ -22,6 +22,25 @@ Component { anchors.fill: parent } + + Rectangle + { + id: footerSeparator + width: parent.width + height: UM.Theme.getSize("wide_lining").height + color: UM.Theme.getColor("wide_lining") + anchors.bottom: monitorButton.top + anchors.bottomMargin: UM.Theme.getSize("thick_margin").height + } + + // MonitorButton is actually the bottom footer panel. + Cura.MonitorButton + { + id: monitorButton + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + } } } } \ No newline at end of file diff --git a/resources/qml/PrinterOutput/OutputDeviceHeader.qml b/resources/qml/PrinterOutput/OutputDeviceHeader.qml index b5ed1b7b4e..e6328546ef 100644 --- a/resources/qml/PrinterOutput/OutputDeviceHeader.qml +++ b/resources/qml/PrinterOutput/OutputDeviceHeader.qml @@ -45,8 +45,8 @@ Item text: (outputDevice != null && outputDevice.address != null) ? outputDevice.address : "" font: UM.Theme.getFont("small") color: UM.Theme.getColor("text_inactive") - anchors.top: parent.top - anchors.right: parent.right + anchors.top: outputDeviceNameLabel.bottom + anchors.left: parent.left anchors.margins: UM.Theme.getSize("default_margin").width } From 1a778b30782f1e6c19aeca2f4882936d98d9c3c6 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 30 Nov 2018 14:18:07 +0100 Subject: [PATCH 0559/1292] Fix qualiy slider alignments Contributes to CURA-5941. --- .../qml/MonitorBuildplateConfiguration.qml | 2 +- .../PrintSetupSelectorContents.qml | 27 +- .../RecommendedQualityProfileSelector.qml | 391 ++++++++++-------- resources/themes/cura-light/theme.json | 8 +- 4 files changed, 241 insertions(+), 187 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml index 9ffb1eabb4..75cbf3b11d 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml @@ -27,7 +27,7 @@ Item Row { height: parent.height - spacing: 12 * screenScaleFactor // TODO: Theme! (Should be same as extruder spacing) + spacing: UM.Theme.getSize("print_setup_slider_handle").width // TODO: Theme! (Should be same as extruder spacing) // This wrapper ensures that the buildplate icon is located centered // below an extruder icon. diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml index f21253acd7..5f22e4c337 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml @@ -114,19 +114,20 @@ Item onHideTooltip: base.hideTooltip() visible: currentModeIndex == 0 } -// -// CustomPrintSetup -// { -// anchors -// { -// left: parent.left -// right: parent.right -// top: parent.top -// } -// onShowTooltip: base.showTooltip(item, location, text) -// onHideTooltip: base.hideTooltip() -// visible: currentModeIndex == 1 -// } + + CustomPrintSetup + { + anchors + { + left: parent.left + right: parent.right + top: parent.top + } + height: 500 + onShowTooltip: base.showTooltip(item, location, text) + onHideTooltip: base.hideTooltip() + visible: currentModeIndex == 1 + } } Rectangle diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml index 3bf93c0c07..c7a9439b00 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml @@ -124,22 +124,27 @@ Item function calculateSliderStepWidth (totalTicks) { - qualityModel.qualitySliderStepWidth = totalTicks != 0 ? Math.round((settingsColumnWidth) / (totalTicks)) : 0 + // Do not use Math.round otherwise the tickmarks won't be aligned + qualityModel.qualitySliderStepWidth = totalTicks != 0 ? + ((settingsColumnWidth - UM.Theme.getSize("print_setup_slider_handle").width) / (totalTicks)) : 0 } function calculateSliderMargins (availableMin, availableMax, totalTicks) { if (availableMin == -1 || (availableMin == 0 && availableMax == 0)) { - qualityModel.qualitySliderMarginRight = Math.round(settingsColumnWidth) + // Do not use Math.round otherwise the tickmarks won't be aligned + qualityModel.qualitySliderMarginRight = settingsColumnWidth } else if (availableMin == availableMax) { - qualityModel.qualitySliderMarginRight = Math.round((totalTicks - availableMin) * qualitySliderStepWidth) + // Do not use Math.round otherwise the tickmarks won't be aligned + qualityModel.qualitySliderMarginRight = (totalTicks - availableMin) * qualitySliderStepWidth } else { - qualityModel.qualitySliderMarginRight = Math.round((totalTicks - availableMax) * qualitySliderStepWidth) + // Do not use Math.round otherwise the tickmarks won't be aligned + qualityModel.qualitySliderMarginRight = (totalTicks - availableMax) * qualitySliderStepWidth } } @@ -162,20 +167,6 @@ Item width: labelColumnWidth } - //Print speed slider - Rectangle - { - id: speedSlider - - anchors - { - left: qualityRowTitle.right - right: parent.right - } - - color: "green" - height: 20 - } // // // Show titles for the each quality slider ticks // Item @@ -240,104 +231,107 @@ Item // } // } // -// //Print speed slider -// Rectangle -// { -// id: speedSlider + //Print speed slider + Rectangle + { + id: speedSlider + + anchors + { + left: qualityRowTitle.right + right: parent.right + } + + color: "green" + height: childrenRect.height + + // This Item is used only for tooltip, for slider area which is unavailable +// Item +// { +// function showTooltip (showTooltip) +// { +// if (showTooltip) +// { +// var content = catalog.i18nc("@tooltip", "This quality profile is not available for you current material and nozzle configuration. Please change these to enable this quality profile") +// base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), content) +// } +// else +// { +// base.hideTooltip() +// } +// } // -// anchors -// { -// left: qualityRowTitle.right -// right: parent.right -// } +// id: unavailableLineToolTip +// height: 20 * screenScaleFactor // hovered area height +// z: parent.z + 1 // should be higher, otherwise the area can be hovered +// x: 0 +// anchors.verticalCenter: qualitySlider.verticalCenter // -// // This Item is used only for tooltip, for slider area which is unavailable -//// Item -//// { -//// function showTooltip (showTooltip) -//// { -//// if (showTooltip) -//// { -//// var content = catalog.i18nc("@tooltip", "This quality profile is not available for you current material and nozzle configuration. Please change these to enable this quality profile") -//// base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), content) -//// } -//// else -//// { -//// base.hideTooltip() -//// } -//// } -//// -//// id: unavailableLineToolTip -//// height: 20 * screenScaleFactor // hovered area height -//// z: parent.z + 1 // should be higher, otherwise the area can be hovered -//// x: 0 -//// anchors.verticalCenter: qualitySlider.verticalCenter -//// -//// Rectangle -//// { -//// id: leftArea -//// width: -//// { -//// if (qualityModel.availableTotalTicks == 0) -//// { -//// return qualityModel.qualitySliderStepWidth * qualityModel.totalTicks -//// } -//// return qualityModel.qualitySliderStepWidth * qualityModel.qualitySliderAvailableMin - 10 -//// } -//// height: parent.height -//// color: "transparent" -//// -//// MouseArea -//// { -//// anchors.fill: parent -//// hoverEnabled: true -//// enabled: Cura.SimpleModeSettingsManager.isProfileUserCreated == false -//// onEntered: unavailableLineToolTip.showTooltip(true) -//// onExited: unavailableLineToolTip.showTooltip(false) -//// } -//// } -//// -//// Item -//// { -//// id: rightArea -//// width: -//// { -//// if(qualityModel.availableTotalTicks == 0) -//// return 0 -//// -//// return qualityModel.qualitySliderMarginRight - 10 -//// } -//// height: parent.height -//// x: -//// { -//// if (qualityModel.availableTotalTicks == 0) -//// { -//// return 0 -//// } -//// -//// var leftUnavailableArea = qualityModel.qualitySliderStepWidth * qualityModel.qualitySliderAvailableMin -//// var totalGap = qualityModel.qualitySliderStepWidth * (qualityModel.availableTotalTicks -1) + leftUnavailableArea + 10 -//// -//// return totalGap -//// } -//// -//// MouseArea -//// { -//// anchors.fill: parent -//// hoverEnabled: true -//// enabled: Cura.SimpleModeSettingsManager.isProfileUserCreated == false -//// onEntered: unavailableLineToolTip.showTooltip(true) -//// onExited: unavailableLineToolTip.showTooltip(false) -//// } -//// } -//// } +// Rectangle +// { +// id: leftArea +// width: +// { +// if (qualityModel.availableTotalTicks == 0) +// { +// return qualityModel.qualitySliderStepWidth * qualityModel.totalTicks +// } +// return qualityModel.qualitySliderStepWidth * qualityModel.qualitySliderAvailableMin - 10 +// } +// height: parent.height +// color: "transparent" // +// MouseArea +// { +// anchors.fill: parent +// hoverEnabled: true +// enabled: Cura.SimpleModeSettingsManager.isProfileUserCreated == false +// onEntered: unavailableLineToolTip.showTooltip(true) +// onExited: unavailableLineToolTip.showTooltip(false) +// } +// } +// +// Item +// { +// id: rightArea +// width: +// { +// if(qualityModel.availableTotalTicks == 0) +// return 0 +// +// return qualityModel.qualitySliderMarginRight - 10 +// } +// height: parent.height +// x: +// { +// if (qualityModel.availableTotalTicks == 0) +// { +// return 0 +// } +// +// var leftUnavailableArea = qualityModel.qualitySliderStepWidth * qualityModel.qualitySliderAvailableMin +// var totalGap = qualityModel.qualitySliderStepWidth * (qualityModel.availableTotalTicks -1) + leftUnavailableArea + 10 +// +// return totalGap +// } +// +// MouseArea +// { +// anchors.fill: parent +// hoverEnabled: true +// enabled: Cura.SimpleModeSettingsManager.isProfileUserCreated == false +// onEntered: unavailableLineToolTip.showTooltip(true) +// onExited: unavailableLineToolTip.showTooltip(false) +// } +// } +// } + // // Draw Unavailable line // Rectangle // { // id: groovechildrect // width: parent.width -// height: 2 * screenScaleFactor +// height: 2 * UM.Theme.getSize("default_lining").height // color: UM.Theme.getColor("quality_slider_unavailable") // anchors.verticalCenter: qualitySlider.verticalCenter // @@ -358,66 +352,125 @@ Item // } // } // } -// -// // Draw available slider -// Slider -// { -// id: qualitySlider -// height: UM.Theme.getSize("thick_margin").height -// anchors.bottom: parent.bottom -// enabled: qualityModel.totalTicks > 0 && !Cura.SimpleModeSettingsManager.isProfileCustomized -// visible: qualityModel.availableTotalTicks > 0 -// updateValueWhileDragging : false -// -// minimumValue: qualityModel.qualitySliderAvailableMin >= 0 ? qualityModel.qualitySliderAvailableMin : 0 -// // maximumValue must be greater than minimumValue to be able to see the handle. While the value is strictly -// // speaking not always correct, it seems to have the correct behavior (switching from 0 available to 1 available) -// maximumValue: qualityModel.qualitySliderAvailableMax >= 1 ? qualityModel.qualitySliderAvailableMax : 1 -// stepSize: 1 -// -// value: qualityModel.qualitySliderActiveIndex -// -// width: qualityModel.qualitySliderStepWidth * (qualityModel.availableTotalTicks - 1) -// -// anchors.right: parent.right -// anchors.rightMargin: qualityModel.qualitySliderMarginRight -// -// style: SliderStyle -// { -// //Draw Available line -// groove: Rectangle -// { -// implicitHeight: 2 * screenScaleFactor -// color: UM.Theme.getColor("quality_slider_available") -// radius: Math.round(height / 2) -// } -// -// handle: Rectangle -// { -// id: qualityhandleButton -// color: UM.Theme.getColor("quality_slider_available") -// implicitWidth: 12 * screenScaleFactor -// implicitHeight: implicitWidth -// radius: Math.round(implicitWidth / 2) -// visible: !Cura.SimpleModeSettingsManager.isProfileCustomized && !Cura.SimpleModeSettingsManager.isProfileUserCreated && qualityModel.existingQualityProfile -// } -// } -// -// onValueChanged: -// { -// // only change if an active machine is set and the slider is visible at all. -// if (Cura.MachineManager.activeMachine != null && visible) -// { -// // prevent updating during view initializing. Trigger only if the value changed by user -// if (qualitySlider.value != qualityModel.qualitySliderActiveIndex && qualityModel.qualitySliderActiveIndex != -1) -// { -// // start updating with short delay -// qualitySliderChangeTimer.start() -// } -// } -// } -// } -// + + // Draw unavailable slider + Slider + { + id: unavailableSlider + height: UM.Theme.getSize("thick_margin").height + updateValueWhileDragging : false + tickmarksEnabled: true + + minimumValue: 0 + // maximumValue must be greater than minimumValue to be able to see the handle. While the value is strictly + // speaking not always correct, it seems to have the correct behavior (switching from 0 available to 1 available) + maximumValue: qualityModel.totalTicks + stepSize: 1 + + width: parent.width + + style: SliderStyle + { + //Draw Unvailable line + groove: Item + { + Rectangle + { + height: UM.Theme.getSize("print_setup_slider_groove").height + width: control.width - UM.Theme.getSize("print_setup_slider_handle").width + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + color: UM.Theme.getColor("quality_slider_unavailable") + } + } + + handle: Item {} + + tickmarks: Repeater + { + id: qualityRepeater + model: qualityModel.totalTicks > 0 ? qualityModel : 0 + + Rectangle + { + color: Cura.QualityProfilesDropDownMenuModel.getItem(index).available ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") + implicitWidth: UM.Theme.getSize("print_setup_slider_tickmarks").width + implicitHeight: UM.Theme.getSize("print_setup_slider_tickmarks").height + anchors.verticalCenter: parent.verticalCenter + + // Do not use Math.round otherwise the tickmarks won't be aligned + x: ((UM.Theme.getSize("print_setup_slider_handle").width / 2) - (UM.Theme.getSize("print_setup_slider_tickmarks").width / 2) + (qualityModel.qualitySliderStepWidth * index)) + radius: Math.round(implicitWidth / 2) + } + } + } + } + + // Draw available slider + Slider + { + id: qualitySlider + height: UM.Theme.getSize("thick_margin").height + enabled: qualityModel.totalTicks > 0 && !Cura.SimpleModeSettingsManager.isProfileCustomized + visible: qualityModel.availableTotalTicks > 0 + updateValueWhileDragging : false + + minimumValue: qualityModel.qualitySliderAvailableMin >= 0 ? qualityModel.qualitySliderAvailableMin : 0 + // maximumValue must be greater than minimumValue to be able to see the handle. While the value is strictly + // speaking not always correct, it seems to have the correct behavior (switching from 0 available to 1 available) + maximumValue: qualityModel.qualitySliderAvailableMax >= 1 ? qualityModel.qualitySliderAvailableMax : 1 + stepSize: 1 + + value: qualityModel.qualitySliderActiveIndex + + width: qualityModel.qualitySliderStepWidth * (qualityModel.availableTotalTicks - 1) + UM.Theme.getSize("print_setup_slider_handle").width + + anchors.right: parent.right + anchors.rightMargin: qualityModel.qualitySliderMarginRight + + style: SliderStyle + { + // Draw Available line + groove: Item + { + Rectangle + { + height: UM.Theme.getSize("print_setup_slider_groove").height + width: control.width - UM.Theme.getSize("print_setup_slider_handle").width + anchors.verticalCenter: parent.verticalCenter + + // Do not use Math.round otherwise the tickmarks won't be aligned + x: UM.Theme.getSize("print_setup_slider_handle").width / 2 + color: UM.Theme.getColor("quality_slider_available") + } + } + + handle: Rectangle + { + id: qualityhandleButton + color: UM.Theme.getColor("primary") + implicitWidth: UM.Theme.getSize("print_setup_slider_handle").width + implicitHeight: implicitWidth + radius: Math.round(implicitWidth / 2) + visible: !Cura.SimpleModeSettingsManager.isProfileCustomized && !Cura.SimpleModeSettingsManager.isProfileUserCreated && qualityModel.existingQualityProfile + } + } + + onValueChanged: + { + // only change if an active machine is set and the slider is visible at all. + if (Cura.MachineManager.activeMachine != null && visible) + { + // prevent updating during view initializing. Trigger only if the value changed by user + if (qualitySlider.value != qualityModel.qualitySliderActiveIndex && qualityModel.qualitySliderActiveIndex != -1) + { + // start updating with short delay + qualitySliderChangeTimer.start() + } + } + } + } + // MouseArea // { // id: speedSliderMouseArea @@ -432,7 +485,7 @@ Item // } // onExited: base.hideTooltip() // } -// } + } // // UM.SimpleButton // { diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index dfaa9008f7..9bf0bf19aa 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -373,6 +373,9 @@ "print_setup_item": [0.0, 2.0], "print_setup_extruder_box": [0.0, 6.0], "print_setup_widget_header": [0.0, 3.0], + "print_setup_slider_groove": [0.16, 0.16], + "print_setup_slider_handle": [1.0, 1.0], + "print_setup_slider_tickmarks": [0.32, 0.32], "configuration_selector_mode_tabs": [0.0, 3.0], @@ -521,9 +524,6 @@ "monitor_thick_lining": [0.16, 0.16], "monitor_corner_radius": [0.3, 0.3], "monitor_shadow_radius": [0.4, 0.4], - "monitor_shadow_offset": [0.15, 0.15], - - "print_setup_action_button": [13, 5], - "print_setup_content_top_margin": [3, 3] + "monitor_shadow_offset": [0.15, 0.15] } } From 73568d74737fb32006ece5355c6ef4c13ce97ae7 Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Fri, 30 Nov 2018 14:51:55 +0100 Subject: [PATCH 0560/1292] Added icon to the search field which filters settings CURA-5941 --- resources/qml/Settings/SettingView.qml | 4 ++-- resources/themes/cura-light/icons/search.svg | 25 ++++++++++++++++---- resources/themes/cura-light/theme.json | 1 + 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 8a336a7ed1..0a7102ff45 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -105,12 +105,12 @@ Item anchors.right: clearFilterButton.left anchors.rightMargin: Math.round(UM.Theme.getSize("thick_margin").width) - placeholderText: catalog.i18nc("@label:textbox", "Search...") + placeholderText: "" + "

    " + catalog.i18nc("@label:textbox", "search settings") style: TextFieldStyle { textColor: UM.Theme.getColor("setting_control_text"); - placeholderTextColor: UM.Theme.getColor("setting_control_text") + placeholderTextColor: UM.Theme.getColor("setting_filter_field") font: UM.Theme.getFont("default"); background: Item {} } diff --git a/resources/themes/cura-light/icons/search.svg b/resources/themes/cura-light/icons/search.svg index 8272991300..a9ccb612fd 100644 --- a/resources/themes/cura-light/icons/search.svg +++ b/resources/themes/cura-light/icons/search.svg @@ -1,4 +1,21 @@ - - - + + + + Shape + Created with Sketch. + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index dfaa9008f7..4e39ffdf22 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -221,6 +221,7 @@ "setting_validation_warning_background": [255, 145, 62, 255], "setting_validation_warning": [127, 127, 127, 255], "setting_validation_ok": [255, 255, 255, 255], + "setting_filter_field" : [153, 153, 153, 255], "material_compatibility_warning": [0, 0, 0, 255], From e93bbf07a4e377bb55e7b5c62292487344fcc29a Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 30 Nov 2018 14:53:10 +0100 Subject: [PATCH 0561/1292] Fix circular dependency with tab index and active stack Only when actually clicking the tab should it change the active extruder index; not when the current index is changed for any other reason. Next up: Don't change the current index for any other reason. Contributes to issue CURA-5876. --- .../qml/Menus/ConfigurationMenu/CustomConfiguration.qml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index 87096c3a14..8ad512349b 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -35,7 +35,7 @@ Item anchors.top: header.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height - onCurrentIndexChanged: Cura.ExtruderManager.setActiveExtruderIndex(currentIndex) + currentIndex: Math.max(Cura.ExtruderManager.activeExtruderIndex, 0) Repeater { @@ -53,6 +53,10 @@ Item height: parent.height } } + onClicked: + { + Cura.ExtruderManager.setActiveExtruderIndex(tabBar.currentIndex) + } } } } From 1fbcff2cb9a0df2b35c054ffef638e863eeb54f4 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 30 Nov 2018 15:06:53 +0100 Subject: [PATCH 0562/1292] Fix the tooltips in the profile selector in the recommended mode Contributes to CURA-5941. --- .../Recommended/RecommendedPrintSetup.qml | 4 +- .../RecommendedQualityProfileSelector.qml | 226 ++++++------------ 2 files changed, 70 insertions(+), 160 deletions(-) diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml index 2d4308c8be..40a1910c69 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml @@ -8,7 +8,7 @@ import QtQuick.Controls.Styles 1.4 import UM 1.2 as UM import Cura 1.0 as Cura -Rectangle +Item { id: base @@ -16,8 +16,6 @@ Rectangle signal hideTooltip() // width: parent.width height: childrenRect.height + 2 * padding - color: "red" - opacity: 0.5 property Action configureSettings diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml index c7a9439b00..755af9311f 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml @@ -163,7 +163,6 @@ Item id: qualityRowTitle source: UM.Theme.getIcon("category_layer_height") text: catalog.i18nc("@label", "Layer Height") -// anchors.bottom: speedSlider.bottom width: labelColumnWidth } @@ -232,9 +231,10 @@ Item // } // //Print speed slider - Rectangle + Item { id: speedSlider + height: childrenRect.height anchors { @@ -242,122 +242,11 @@ Item right: parent.right } - color: "green" - height: childrenRect.height - - // This Item is used only for tooltip, for slider area which is unavailable -// Item -// { -// function showTooltip (showTooltip) -// { -// if (showTooltip) -// { -// var content = catalog.i18nc("@tooltip", "This quality profile is not available for you current material and nozzle configuration. Please change these to enable this quality profile") -// base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), content) -// } -// else -// { -// base.hideTooltip() -// } -// } -// -// id: unavailableLineToolTip -// height: 20 * screenScaleFactor // hovered area height -// z: parent.z + 1 // should be higher, otherwise the area can be hovered -// x: 0 -// anchors.verticalCenter: qualitySlider.verticalCenter -// -// Rectangle -// { -// id: leftArea -// width: -// { -// if (qualityModel.availableTotalTicks == 0) -// { -// return qualityModel.qualitySliderStepWidth * qualityModel.totalTicks -// } -// return qualityModel.qualitySliderStepWidth * qualityModel.qualitySliderAvailableMin - 10 -// } -// height: parent.height -// color: "transparent" -// -// MouseArea -// { -// anchors.fill: parent -// hoverEnabled: true -// enabled: Cura.SimpleModeSettingsManager.isProfileUserCreated == false -// onEntered: unavailableLineToolTip.showTooltip(true) -// onExited: unavailableLineToolTip.showTooltip(false) -// } -// } -// -// Item -// { -// id: rightArea -// width: -// { -// if(qualityModel.availableTotalTicks == 0) -// return 0 -// -// return qualityModel.qualitySliderMarginRight - 10 -// } -// height: parent.height -// x: -// { -// if (qualityModel.availableTotalTicks == 0) -// { -// return 0 -// } -// -// var leftUnavailableArea = qualityModel.qualitySliderStepWidth * qualityModel.qualitySliderAvailableMin -// var totalGap = qualityModel.qualitySliderStepWidth * (qualityModel.availableTotalTicks -1) + leftUnavailableArea + 10 -// -// return totalGap -// } -// -// MouseArea -// { -// anchors.fill: parent -// hoverEnabled: true -// enabled: Cura.SimpleModeSettingsManager.isProfileUserCreated == false -// onEntered: unavailableLineToolTip.showTooltip(true) -// onExited: unavailableLineToolTip.showTooltip(false) -// } -// } -// } - -// // Draw Unavailable line -// Rectangle -// { -// id: groovechildrect -// width: parent.width -// height: 2 * UM.Theme.getSize("default_lining").height -// color: UM.Theme.getColor("quality_slider_unavailable") -// anchors.verticalCenter: qualitySlider.verticalCenter -// -// // Draw ticks -// Repeater -// { -// id: qualityRepeater -// model: qualityModel.totalTicks > 0 ? qualityModel : 0 -// -// Rectangle -// { -// color: Cura.QualityProfilesDropDownMenuModel.getItem(index).available ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") -// implicitWidth: 4 * screenScaleFactor -// implicitHeight: implicitWidth -// anchors.verticalCenter: parent.verticalCenter -// x: Math.round(qualityModel.qualitySliderStepWidth * index) -// radius: Math.round(implicitWidth / 2) -// } -// } -// } - // Draw unavailable slider Slider { id: unavailableSlider - height: UM.Theme.getSize("thick_margin").height + height: qualitySlider.height // Same height as the slider that is on top updateValueWhileDragging : false tickmarksEnabled: true @@ -404,13 +293,27 @@ Item } } } + + // Create a mouse area on top of the unavailable profiles to show a specific tooltip + MouseArea + { + anchors.fill: parent + hoverEnabled: true + enabled: !Cura.SimpleModeSettingsManager.isProfileUserCreated + onEntered: + { + var tooltipContent: catalog.i18nc("@tooltip", "This quality profile is not available for you current material and nozzle configuration. Please change these to enable this quality profile") + base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), unavailableSlider.tooltipContent) + } + onExited: base.hideTooltip() + } } // Draw available slider Slider { id: qualitySlider - height: UM.Theme.getSize("thick_margin").height + height: UM.Theme.getSize("print_setup_slider_handle").height // The handle is the widest element of the slider enabled: qualityModel.totalTicks > 0 && !Cura.SimpleModeSettingsManager.isProfileCustomized visible: qualityModel.availableTotalTicks > 0 updateValueWhileDragging : false @@ -469,49 +372,58 @@ Item } } } + + // This mouse area is only used to capture the onHover state and don't propagate it to the unavailable mouse area + MouseArea + { + anchors.fill: parent + hoverEnabled: true + enabled: !Cura.SimpleModeSettingsManager.isProfileUserCreated + } } -// MouseArea -// { -// id: speedSliderMouseArea -// anchors.fill: parent -// hoverEnabled: true -// enabled: Cura.SimpleModeSettingsManager.isProfileUserCreated -// -// onEntered: -// { -// var content = catalog.i18nc("@tooltip", "A custom profile is currently active. To enable the quality slider, choose a default quality profile in Custom tab") -// base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), content) -// } -// onExited: base.hideTooltip() -// } + // This mouse area will only take the mouse events and show a tooltip when the profile in use is + // a user created profile + MouseArea + { + anchors.fill: parent + hoverEnabled: true + visible: Cura.SimpleModeSettingsManager.isProfileUserCreated + + onEntered: + { + var content = catalog.i18nc("@tooltip", "A custom profile is currently active. To enable the quality slider, choose a default quality profile in Custom tab") + base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), content) + } + onExited: base.hideTooltip() + } + } + + UM.SimpleButton + { + id: customisedSettings + + visible: Cura.SimpleModeSettingsManager.isProfileCustomized || Cura.SimpleModeSettingsManager.isProfileUserCreated + height: Math.round(speedSlider.height * 0.8) + width: Math.round(speedSlider.height * 0.8) + + anchors.verticalCenter: speedSlider.verticalCenter + anchors.right: speedSlider.left + anchors.rightMargin: Math.round(UM.Theme.getSize("thick_margin").width / 2) + + color: hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button"); + iconSource: UM.Theme.getIcon("reset"); + + onClicked: + { + // if the current profile is user-created, switch to a built-in quality + Cura.MachineManager.resetToUseDefaultQuality() + } + onEntered: + { + var content = catalog.i18nc("@tooltip","You have modified some profile settings. If you want to change these go to custom mode.") + base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), content) + } + onExited: base.hideTooltip() } -// -// UM.SimpleButton -// { -// id: customisedSettings -// -// visible: Cura.SimpleModeSettingsManager.isProfileCustomized || Cura.SimpleModeSettingsManager.isProfileUserCreated -// height: Math.round(speedSlider.height * 0.8) -// width: Math.round(speedSlider.height * 0.8) -// -// anchors.verticalCenter: speedSlider.verticalCenter -// anchors.right: speedSlider.left -// anchors.rightMargin: Math.round(UM.Theme.getSize("thick_margin").width / 2) -// -// color: hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button"); -// iconSource: UM.Theme.getIcon("reset"); -// -// onClicked: -// { -// // if the current profile is user-created, switch to a built-in quality -// Cura.MachineManager.resetToUseDefaultQuality() -// } -// onEntered: -// { -// var content = catalog.i18nc("@tooltip","You have modified some profile settings. If you want to change these go to custom mode.") -// base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), content) -// } -// onExited: base.hideTooltip() -// } } \ No newline at end of file From 1a79372afd3e231fbbcde1ee864d71e7f354d5ab Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 30 Nov 2018 15:16:37 +0100 Subject: [PATCH 0563/1292] Fixed name of cocoon create For some reason it was added as if it was 2 machines at once. Since we already have a wanhao I3, i've changed this one to only be a profile for the Cocoon. --- resources/definitions/cocoon_create_modelmaker.def.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/definitions/cocoon_create_modelmaker.def.json b/resources/definitions/cocoon_create_modelmaker.def.json index 921b20624a..22aa75d09e 100644 --- a/resources/definitions/cocoon_create_modelmaker.def.json +++ b/resources/definitions/cocoon_create_modelmaker.def.json @@ -1,11 +1,11 @@ { - "name": "Cocoon Create ModelMaker & Wanhao Duplicator i3 Mini", + "name": "Cocoon Create ModelMaker", "version": 2, "inherits": "fdmprinter", "metadata": { "visible": true, "author": "Samuel Pinches", - "manufacturer": "Cocoon Create / Wanhao", + "manufacturer": "Cocoon Create", "file_formats": "text/x-gcode", "preferred_quality_type": "fine", "machine_extruder_trains": @@ -15,7 +15,7 @@ }, "overrides": { "machine_name": { - "default_value": "Cocoon Create ModelMaker & Wanhao Duplicator i3 Mini" + "default_value": "Cocoon Create ModelMaker" }, "machine_start_gcode": { "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 ;home all axis\nG92 E0 ;zero the extruded length\nG1 Z1 F1000 ;move up slightly\nG1 X60.0 Z0 E9.0 F1000.0;intro line\nG1 X100.0 E21.5 F1000.0 ;continue line\nG92 E0 ;zero the extruded length again\n; -- end of START GCODE --" From 47b7d7bed8f1953297a78628ec7571e40c1cef78 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 30 Nov 2018 15:17:59 +0100 Subject: [PATCH 0564/1292] Make the slider available for clicking This was accidentally removed in the previous commit. Contributes to CURA-5941. --- .../RecommendedQualityProfileSelector.qml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml index 755af9311f..50da35814c 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml @@ -231,6 +231,8 @@ Item // } // //Print speed slider + // Two sliders are created, one at the bottom with the unavailable qualities + // and the other at the top with the available quality profiles and so the handle to select them. Item { id: speedSlider @@ -302,8 +304,8 @@ Item enabled: !Cura.SimpleModeSettingsManager.isProfileUserCreated onEntered: { - var tooltipContent: catalog.i18nc("@tooltip", "This quality profile is not available for you current material and nozzle configuration. Please change these to enable this quality profile") - base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), unavailableSlider.tooltipContent) + var tooltipContent = catalog.i18nc("@tooltip", "This quality profile is not available for you current material and nozzle configuration. Please change these to enable this quality profile") + base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), tooltipContent) } onExited: base.hideTooltip() } @@ -378,6 +380,7 @@ Item { anchors.fill: parent hoverEnabled: true + acceptedButtons: Qt.NoButton enabled: !Cura.SimpleModeSettingsManager.isProfileUserCreated } } @@ -392,8 +395,8 @@ Item onEntered: { - var content = catalog.i18nc("@tooltip", "A custom profile is currently active. To enable the quality slider, choose a default quality profile in Custom tab") - base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), content) + var tooltipContent = catalog.i18nc("@tooltip", "A custom profile is currently active. To enable the quality slider, choose a default quality profile in Custom tab") + base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), tooltipContent) } onExited: base.hideTooltip() } @@ -421,8 +424,8 @@ Item } onEntered: { - var content = catalog.i18nc("@tooltip","You have modified some profile settings. If you want to change these go to custom mode.") - base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), content) + var tooltipContent = catalog.i18nc("@tooltip","You have modified some profile settings. If you want to change these go to custom mode.") + base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), tooltipContent) } onExited: base.hideTooltip() } From a4a619370ea064609d04791b95c2881c3f41467a Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 30 Nov 2018 15:33:57 +0100 Subject: [PATCH 0565/1292] Fix QML warnings --- resources/qml/Preferences/GeneralPage.qml | 3 --- 1 file changed, 3 deletions(-) diff --git a/resources/qml/Preferences/GeneralPage.qml b/resources/qml/Preferences/GeneralPage.qml index bba2cf764a..5006ae2777 100644 --- a/resources/qml/Preferences/GeneralPage.qml +++ b/resources/qml/Preferences/GeneralPage.qml @@ -151,7 +151,6 @@ UM.PreferencesPage { id: languageLabel text: catalog.i18nc("@label","Language:") - anchors.verticalCenter: languageComboBox.verticalCenter } ComboBox @@ -219,7 +218,6 @@ UM.PreferencesPage { id: currencyLabel text: catalog.i18nc("@label","Currency:") - anchors.verticalCenter: currencyField.verticalCenter } TextField @@ -233,7 +231,6 @@ UM.PreferencesPage { id: themeLabel text: catalog.i18nc("@label","Theme:") - anchors.verticalCenter: themeComboBox.verticalCenter } ComboBox From 2c5f5170c2d05f5ffce1da5c471ff14b8289cc5b Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 30 Nov 2018 15:38:28 +0100 Subject: [PATCH 0566/1292] Add the labels of the layer height to the slider Contributes to CURA-5941. --- .../RecommendedQualityProfileSelector.qml | 205 +++++++++--------- 1 file changed, 108 insertions(+), 97 deletions(-) diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml index 50da35814c..f7e1d870c9 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml @@ -158,78 +158,116 @@ Item } } - Cura.IconWithText + Item { - id: qualityRowTitle - source: UM.Theme.getIcon("category_layer_height") - text: catalog.i18nc("@label", "Layer Height") + id: titleRow width: labelColumnWidth + height: childrenRect.height + + Cura.IconWithText + { + id: qualityRowTitle + source: UM.Theme.getIcon("category_layer_height") + text: catalog.i18nc("@label", "Layer Height") + anchors.left: parent.left + anchors.right: customisedSettings.left + } + + UM.SimpleButton + { + id: customisedSettings + + visible: Cura.SimpleModeSettingsManager.isProfileCustomized || Cura.SimpleModeSettingsManager.isProfileUserCreated + height: visible ? Math.round(0.8 * qualityRowTitle.height) : 0 + width: height + anchors + { + right: parent.right + rightMargin: UM.Theme.getSize("default_margin").width + leftMargin: UM.Theme.getSize("default_margin").width + verticalCenter: parent.verticalCenter + } + + color: hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button") + iconSource: UM.Theme.getIcon("reset") + + onClicked: + { + // if the current profile is user-created, switch to a built-in quality + Cura.MachineManager.resetToUseDefaultQuality() + } + onEntered: + { + var tooltipContent = catalog.i18nc("@tooltip","You have modified some profile settings. If you want to change these go to custom mode.") + base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), tooltipContent) + } + onExited: base.hideTooltip() + } + } + + // Show titles for the each quality slider ticks + Item + { + anchors.left: speedSlider.left + anchors.top: speedSlider.bottom + + Repeater + { + model: qualityModel + + Label + { + anchors.verticalCenter: parent.verticalCenter + anchors.top: parent.top + color: (Cura.MachineManager.activeMachine != null && Cura.QualityProfilesDropDownMenuModel.getItem(index).available) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") + text: + { + var result = "" + if(Cura.MachineManager.activeMachine != null) + { + result = Cura.QualityProfilesDropDownMenuModel.getItem(index).layer_height + + if(result == undefined) + { + result = ""; + } + else + { + result = Number(Math.round(result + "e+2") + "e-2"); //Round to 2 decimals. Javascript makes this difficult... + if (result == undefined || result != result) //Parse failure. + { + result = ""; + } + } + } + return result + } + + x: + { + // Make sure the text aligns correctly with each tick + if (qualityModel.totalTicks == 0) + { + // If there is only one tick, align it centrally + return Math.round(((settingsColumnWidth) - width) / 2) + } + else if (index == 0) + { + return Math.round(settingsColumnWidth / qualityModel.totalTicks) * index + } + else if (index == qualityModel.totalTicks) + { + return Math.round(settingsColumnWidth / qualityModel.totalTicks) * index - width + } + else + { + return Math.round((settingsColumnWidth / qualityModel.totalTicks) * index - (width / 2)) + } + } + } + } } -// -// // Show titles for the each quality slider ticks -// Item -// { -// anchors.left: speedSlider.left -// anchors.top: speedSlider.bottom -// -// Repeater -// { -// model: qualityModel -// -// Label -// { -// anchors.verticalCenter: parent.verticalCenter -// anchors.top: parent.top -// color: (Cura.MachineManager.activeMachine != null && Cura.QualityProfilesDropDownMenuModel.getItem(index).available) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") -// text: -// { -// var result = "" -// if(Cura.MachineManager.activeMachine != null) -// { -// result = Cura.QualityProfilesDropDownMenuModel.getItem(index).layer_height -// -// if(result == undefined) -// { -// result = ""; -// } -// else -// { -// result = Number(Math.round(result + "e+2") + "e-2"); //Round to 2 decimals. Javascript makes this difficult... -// if (result == undefined || result != result) //Parse failure. -// { -// result = ""; -// } -// } -// } -// return result -// } -// -// x: -// { -// // Make sure the text aligns correctly with each tick -// if (qualityModel.totalTicks == 0) -// { -// // If there is only one tick, align it centrally -// return Math.round(((settingsColumnWidth) - width) / 2) -// } -// else if (index == 0) -// { -// return Math.round(settingsColumnWidth / qualityModel.totalTicks) * index -// } -// else if (index == qualityModel.totalTicks) -// { -// return Math.round(settingsColumnWidth / qualityModel.totalTicks) * index - width -// } -// else -// { -// return Math.round((settingsColumnWidth / qualityModel.totalTicks) * index - (width / 2)) -// } -// } -// } -// } -// } -// //Print speed slider // Two sliders are created, one at the bottom with the unavailable qualities // and the other at the top with the available quality profiles and so the handle to select them. @@ -240,8 +278,9 @@ Item anchors { - left: qualityRowTitle.right + left: titleRow.right right: parent.right + verticalCenter: titleRow.verticalCenter } // Draw unavailable slider @@ -401,32 +440,4 @@ Item onExited: base.hideTooltip() } } - - UM.SimpleButton - { - id: customisedSettings - - visible: Cura.SimpleModeSettingsManager.isProfileCustomized || Cura.SimpleModeSettingsManager.isProfileUserCreated - height: Math.round(speedSlider.height * 0.8) - width: Math.round(speedSlider.height * 0.8) - - anchors.verticalCenter: speedSlider.verticalCenter - anchors.right: speedSlider.left - anchors.rightMargin: Math.round(UM.Theme.getSize("thick_margin").width / 2) - - color: hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button"); - iconSource: UM.Theme.getIcon("reset"); - - onClicked: - { - // if the current profile is user-created, switch to a built-in quality - Cura.MachineManager.resetToUseDefaultQuality() - } - onEntered: - { - var tooltipContent = catalog.i18nc("@tooltip","You have modified some profile settings. If you want to change these go to custom mode.") - base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), tooltipContent) - } - onExited: base.hideTooltip() - } } \ No newline at end of file From 1d9a13cac27c4e8c571c53757ec81882d1c8994a Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 30 Nov 2018 15:40:59 +0100 Subject: [PATCH 0567/1292] Reset tab index when repeater's model is rebuilt We can't prevent the model from being rebuilt. At least, not without a major refactor. Contributes to issue CURA-5876. --- .../Menus/ConfigurationMenu/CustomConfiguration.qml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index 8ad512349b..bdf5ccfaa1 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -39,6 +39,7 @@ Item Repeater { + id: repeater model: extrudersModel delegate: UM.TabRowButton { @@ -59,6 +60,18 @@ Item } } } + + //When the model of the extruders is rebuilt, the list of extruders is briefly emptied and rebuilt. + //This causes the currentIndex of the tab to be in an invalid position which resets it to 0. + //Therefore we need to change it back to what it was: The active extruder index. + Connections + { + target: repeater.model + onModelChanged: + { + tabBar.currentIndex = Math.max(Cura.ExtruderManager.activeExtruderIndex, 0) + } + } } Rectangle From 18bb403413330fa4891ec80d4cb6177b8caa71b3 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 30 Nov 2018 15:42:46 +0100 Subject: [PATCH 0568/1292] No longer switch away from extruder when disabling It feels confusing when this happens. Contributes to issue CURA-5876. --- cura/Settings/ExtrudersModel.py | 4 ++-- cura/Settings/MachineManager.py | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/cura/Settings/ExtrudersModel.py b/cura/Settings/ExtrudersModel.py index 14a8dadc69..955bd9dbb2 100644 --- a/cura/Settings/ExtrudersModel.py +++ b/cura/Settings/ExtrudersModel.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. from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot, pyqtProperty, QTimer @@ -177,7 +177,7 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): machine_extruder_count = global_container_stack.getProperty("machine_extruder_count", "value") for extruder in Application.getInstance().getExtruderManager().getActiveExtruderStacks(): - position = extruder.getMetaDataEntry("position", default = "0") # Get the position + position = extruder.getMetaDataEntry("position", default = "0") try: position = int(position) except ValueError: diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 40a3bfc563..be4a4e2b4e 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -993,10 +993,6 @@ class MachineManager(QObject): self.updateNumberExtrudersEnabled() self.correctExtruderSettings() - # In case this extruder is being disabled and it's the currently selected one, switch to the default extruder - if not enabled and position == ExtruderManager.getInstance().activeExtruderIndex: - ExtruderManager.getInstance().setActiveExtruderIndex(int(self._default_extruder_position)) - # ensure that the quality profile is compatible with current combination, or choose a compatible one if available self._updateQualityWithMaterial() self.extruderChanged.emit() From ede50ef3cad83e1c6c6a8b282bf27d9b261f17a9 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 30 Nov 2018 15:44:15 +0100 Subject: [PATCH 0569/1292] Simplify dependencies on activeStack The properties, being formulas, were not properly updated when the active stack changed. Contributes to issue CURA-5876. --- .../Menus/ConfigurationMenu/CustomConfiguration.qml | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index bdf5ccfaa1..8044d86347 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -135,7 +135,7 @@ Item OldControls.CheckBox { - checked: selectors.model != null ? Cura.MachineManager.getExtruder(selectors.model.index).isEnabled: false + checked: Cura.MachineManager.activeStack != null ? Cura.MachineManager.activeStack.isEnabled : false onClicked: Cura.MachineManager.setExtruderEnabled(selectors.model.index, checked) height: UM.Theme.getSize("setting_control").height style: UM.Theme.styles.checkbox @@ -160,14 +160,11 @@ Item { id: materialSelection - property var activeExtruder: Cura.MachineManager.activeStack - property var hasActiveExtruder: activeExtruder != null - property var currentRootMaterialName: hasActiveExtruder ? activeExtruder.material.name : "" - property var valueError: hasActiveExtruder ? Cura.ContainerManager.getContainerMetaDataEntry(activeExtruder.material.id, "compatible", "") != "True" : true + property var valueError: Cura.MachineManager.activeStack != null ? Cura.ContainerManager.getContainerMetaDataEntry(Cura.MachineManager.activeStack.material.id, "compatible", "") != "True" : true property var valueWarning: !Cura.MachineManager.isActiveQualitySupported - text: currentRootMaterialName - tooltip: currentRootMaterialName + text: Cura.MachineManager.activeStack != null ? Cura.MachineManager.activeStack.material.name : "" + tooltip: text visible: Cura.MachineManager.hasMaterials enabled: Cura.ExtruderManager.activeExtruderIndex > -1 From ed37e692a38e6effb5f25a97409623330c6ea78f Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 30 Nov 2018 15:45:04 +0100 Subject: [PATCH 0570/1292] Don't disable enable checkbox before machine is loaded It is unnecessary because you can't see it or click on it before adding a machine. Contributes to issue CURA-5876. --- resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml | 2 -- 1 file changed, 2 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index 8044d86347..605d0444e6 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -167,8 +167,6 @@ Item tooltip: text visible: Cura.MachineManager.hasMaterials - enabled: Cura.ExtruderManager.activeExtruderIndex > -1 - height: UM.Theme.getSize("setting_control").height width: selectors.controlWidth From ad26962cb91a3d7e4e9deb32fddb63e5955bae16 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 30 Nov 2018 15:49:50 +0100 Subject: [PATCH 0571/1292] Fix setting visibility not working in settingVisibilityPage CURA-5981 --- resources/qml/Preferences/SettingVisibilityPage.qml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/qml/Preferences/SettingVisibilityPage.qml b/resources/qml/Preferences/SettingVisibilityPage.qml index 8896d0611e..e319069502 100644 --- a/resources/qml/Preferences/SettingVisibilityPage.qml +++ b/resources/qml/Preferences/SettingVisibilityPage.qml @@ -117,7 +117,7 @@ UM.PreferencesPage { for(var i = 0; i < settingVisibilityPresetsModel.items.length; ++i) { - if(settingVisibilityPresetsModel.items[i].id == settingVisibilityPresetsModel.activePreset) + if(settingVisibilityPresetsModel.items[i].presetId == settingVisibilityPresetsModel.activePreset) { currentIndex = i; return; @@ -128,8 +128,8 @@ UM.PreferencesPage onActivated: { - var preset_id = settingVisibilityPresetsModel.items[index].id; - settingVisibilityPresetsModel.setActivePreset(preset_id); + var preset_id = settingVisibilityPresetsModel.items[index].presetId + settingVisibilityPresetsModel.setActivePreset(preset_id) } } From 8b42b8461846a7a11cb06bf2e984c8bf15c88750 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Fri, 30 Nov 2018 16:07:20 +0100 Subject: [PATCH 0572/1292] Made a start with uploading jobs to the printer --- .../src/Cloud/CloudOutputDevice.py | 122 ++++++++++++++++-- .../UM3NetworkPrinting/src/Cloud/Models.py | 68 ++++++---- 2 files changed, 151 insertions(+), 39 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 06e5656392..5d2d140704 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -1,25 +1,27 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +import io import json import os -from typing import List, Optional, Dict +from typing import List, Optional, Dict, cast from PyQt5.QtCore import QObject, pyqtSignal, QUrl, pyqtProperty from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest from UM import i18nCatalog +from UM.FileHandler import FileWriter from UM.FileHandler.FileHandler import FileHandler from UM.Logger import Logger +from UM.OutputDevice import OutputDeviceError from UM.Scene.SceneNode import SceneNode -from UM.Settings import ContainerRegistry +from UM.Version import Version from cura.CuraApplication import CuraApplication from cura.PrinterOutput import PrinterOutputController, PrintJobOutputModel from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice, AuthState from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel -from .Models import CloudClusterPrinter, CloudClusterPrinterConfiguration, CloudClusterPrinterConfigurationMaterial, CloudClusterPrintJob, CloudClusterPrintJobConstraint - -from .CloudOutputController import CloudOutputController +from .Models import CloudClusterPrinter, CloudClusterPrinterConfiguration, CloudClusterPrinterConfigurationMaterial, \ + CloudClusterPrintJob, CloudClusterPrintJobConstraint, JobUploadRequest from ..UM3PrintJobOutputModel import UM3PrintJobOutputModel @@ -36,8 +38,11 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # The cloud URL to use for this remote cluster. # TODO: Make sure that this url goes to the live api before release - API_ROOT_PATH_FORMAT = "https://api-staging.ultimaker.com/connect/v1/clusters/{cluster_id}" - + ROOT_PATH= "https://api-staging.ultimaker.com" + CLUSTER_API_ROOT = "{}/connect/v1/".format(ROOT_PATH) + CURA_API_ROOT = "{}/cura/v1/".format(ROOT_PATH) + CURA_DRIVE_API_ROOT = "{}/cura-drive/v1/".format(ROOT_PATH) + # Signal triggered when the printers in the remote cluster were changed. printersChanged = pyqtSignal() @@ -64,7 +69,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## We need to override _createEmptyRequest to work for the cloud. def _createEmptyRequest(self, path: str, content_type: Optional[str] = "application/json") -> QNetworkRequest: - url = QUrl(self.API_ROOT_PATH_FORMAT.format(cluster_id = self._device_id) + path) + #url = QUrl(self.CLUSTER_API_ROOT_PATH_FORMAT.format(cluster_id = self._device_id) + path) + url = QUrl(path) request = QNetworkRequest(url) request.setHeader(QNetworkRequest.ContentTypeHeader, content_type) request.setHeader(QNetworkRequest.UserAgentHeader, self._user_agent) @@ -92,7 +98,72 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def requestWrite(self, nodes: List[SceneNode], file_name: Optional[str] = None, limit_mime_types: bool = False, file_handler: Optional[FileHandler] = None, **kwargs: str) -> None: self.writeStarted.emit(self) - self._addPrintJobToQueue() + file_format = self._determineFileFormat(file_handler) + writer = self._determineWriter(file_format) + + # This function pauses with the yield, waiting on instructions on which printer it needs to print with. + if not writer: + Logger.log("e", "Missing file or mesh writer!") + return + + stream = io.BytesIO() # type: Union[io.BytesIO, io.StringIO]# Binary mode. + if file_format["mode"] == FileWriter.OutputMode.TextMode: + stream = io.StringIO() + + writer.write(stream, nodes) + + stream.seek(0, io.SEEK_END) + size = stream.tell() + stream.seek(0, io.SEEK_SET) + + request = JobUploadRequest() + request.job_name = file_name + request.file_size = size + + self._addPrintJobToQueue(stream, request) + + # TODO: This is yanked right out of ClusterUM3OoutputDevice, great candidate for a utility or base class + def _determineFileFormat(self, file_handler) -> None: + # Formats supported by this application (file types that we can actually write). + if file_handler: + file_formats = file_handler.getSupportedFileTypesWrite() + else: + file_formats = CuraApplication.getInstance().getMeshFileHandler().getSupportedFileTypesWrite() + + global_stack = CuraApplication.getInstance().getGlobalContainerStack() + # Create a list from the supported file formats string. + if not global_stack: + Logger.log("e", "Missing global stack!") + return + + machine_file_formats = global_stack.getMetaDataEntry("file_formats").split(";") + machine_file_formats = [file_type.strip() for file_type in machine_file_formats] + # Exception for UM3 firmware version >=4.4: UFP is now supported and should be the preferred file format. + if "application/x-ufp" not in machine_file_formats and Version(self.firmwareVersion) >= Version("4.4"): + machine_file_formats = ["application/x-ufp"] + machine_file_formats + + # Take the intersection between file_formats and machine_file_formats. + format_by_mimetype = {format["mime_type"]: format for format in file_formats} + file_formats = [format_by_mimetype[mimetype] for mimetype in machine_file_formats] #Keep them ordered according to the preference in machine_file_formats. + + if len(file_formats) == 0: + Logger.log("e", "There are no file formats available to write with!") + raise OutputDeviceError.WriteRequestFailedError(self.I18N_CATALOG.i18nc("@info:status", "There are no file formats available to write with!")) + return file_formats[0] + + # TODO: This is yanked right out of ClusterUM3OoutputDevice, great candidate for a utility or base class + def _determineWriter(self, file_handler, file_format): + # Just take the first file format available. + if file_handler is not None: + writer = file_handler.getWriterByMimeType(cast(str, file_format["mime_type"])) + else: + writer = CuraApplication.getInstance().getMeshFileHandler().getWriterByMimeType(cast(str, file_format["mime_type"])) + + if not writer: + Logger.log("e", "Unexpected error when trying to get the FileWriter") + return + + return writer ## Get remote printers. @pyqtProperty("QVariantList", notify = printersChanged) @@ -111,7 +182,9 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## Called when the network data should be updated. def _update(self) -> None: super()._update() - self.get("/status", on_finished = self._onStatusCallFinished) + self.get("{root}/cluster/{cluster_id}/status".format(self.CLUSTER_API_ROOT, self._device_id), + on_finished = self._onStatusCallFinished) + ## Method called when HTTP request to status endpoint is finished. # Contains both printers and print jobs statuses in a single response. @@ -201,7 +274,6 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): firmware_version=printer.firmware_version) def _updatePrinter(self, guid : str, printer : CloudClusterPrinter): - model = self._printers[guid] self._printers[guid] = self._updatePrinterOutputModel(self, printer) def _updatePrinterOutputModel(self, printer: CloudClusterPrinter, model : PrinterOutputModel) -> PrinterOutputModel: @@ -299,6 +371,28 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def _removePrintJob(self, guid:str): del self._print_jobs[guid] - def _addPrintJobToQueue(self): - # TODO: implement this - pass + def _addPrintJobToQueue(self, stream, request:JobUploadRequest): + self.put("{}/jobs/upload".format(self.CURA_API_ROOT), data = json.dumps(request.__dict__), + on_finished = lambda reply: self._onAddPrintJobToQueueFinished(stream, reply)) + + def _onAddPrintJobToQueueFinished(self, stream, reply: QNetworkReply) -> None: + s = json.loads(bytes(reply.readAll()).decode("utf-8")) + + self.put() + + # try: + # r = requests.put(self._job.output_url, data=data) + # if r.status_code == 200: + # Logger.log("d", "Finished writing %s to remote URL %s", "", self._job.output_url) + # self.onWriteSuccess.emit(r.text) + # else: + # Logger.log("d", "Error writing %s to remote URL %s", "", self._job.output_url) + # self.onWriteFailed.emit("Failed to export G-code to remote URL: {}".format(r.text)) + # except requests.ConnectionError as e: + # Logger.log("e", "There was a connection error when uploading the G-code to a remote URL: %s", e) + # self.onWriteFailed.emit("Failed to export G-code to remote URL: {}".format(e)) + # except requests.HTTPError as e: + # Logger.log("e", "There was an HTTP error when uploading the G-code to a remote URL: %s", e) + # self.onWriteFailed.emit("Failed to export G-code to remote URL: {}".format(e)) + + pass \ No newline at end of file diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models.py b/plugins/UM3NetworkPrinting/src/Cloud/Models.py index 7d6db9c8c0..86a48fb1f2 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models.py @@ -41,15 +41,15 @@ class CloudClusterPrinterConfiguration(BaseModel): ## Class representing a cluster printer class CloudClusterPrinter(BaseModel): def __init__(self, **kwargs): - self.configuration = None # type: CloudClusterPrinterConfiguration - self.enabled = None # type: str - self.firmware_version = None # type: str - self.friendly_name = None # type: str - self.ip_address = None # type: str - self.machine_variant = None # type: str - self.status = None # type: str - self.unique_name = None # type: str - self.uuid = None # type: str + self.configuration = None # type: CloudClusterPrinterConfiguration + self.enabled = None # type: str + self.firmware_version = None # type: str + self.friendly_name = None # type: str + self.ip_address = None # type: str + self.machine_variant = None # type: str + self.status = None # type: str + self.unique_name = None # type: str + self.uuid = None # type: str super().__init__(**kwargs) @@ -62,20 +62,38 @@ class CloudClusterPrintJobConstraint(BaseModel): ## Class representing a print job class CloudClusterPrintJob(BaseModel): def __init__(self, **kwargs): - self.assigned_to = None # type: str - self.configuration = None # type: str - self.constraints = None # type: str - self.created_at = None # type: str - self.force = None # type: str - self.last_seen = None # type: str - self.machine_variant = None # type: str - self.name = None # type: str - self.network_error_count = None # type: str - self.owner = None # type: str - self.printer_uuid = None # type: str - self.started = None # type: str - self.status = None # type: str - self.time_elapsed = None # type: str - self.time_total = None # type: str - self.uuid = None # type: str + self.assigned_to = None # type: str + self.configuration = None # type: str + self.constraints = None # type: str + self.created_at = None # type: str + self.force = None # type: str + self.last_seen = None # type: str + self.machine_variant = None # type: str + self.name = None # type: str + self.network_error_count = None # type: str + self.owner = None # type: str + self.printer_uuid = None # type: str + self.started = None # type: str + self.status = None # type: str + self.time_elapsed = None # type: str + self.time_total = None # type: str + self.uuid = None # type: str + super().__init__(**kwargs) + + +class JobUploadRequest(BaseModel): + def __init__(self, **kwargs): + self.file_size = None # type: int + self.job_name = None # type: str + super().__init__(**kwargs) + + +class JobUploadResponse(BaseModel): + def __init__(self, **kwargs): + self.download_url = None # type: str + self.job_id = None # type: str + self.job_name = None # type: str + self.slicing_details = None # type: str + self.status = None # type: str + self.upload_url = None # type: str super().__init__(**kwargs) From 36a86adc0f216e9bd03378db7017a7d8822ad765 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 30 Nov 2018 16:08:19 +0100 Subject: [PATCH 0573/1292] Remove spammy log --- plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py index daea696cd1..b96c508d70 100644 --- a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py +++ b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py @@ -341,7 +341,6 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): # Request more data if info is not complete if not info.address: - Logger.log("d", "Trying to get address of %s", name) info = zero_conf.get_service_info(service_type, name) if info: From 82d4897ba4e24ba9e1ed52a9d79dff0fc88e0096 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 30 Nov 2018 16:18:46 +0100 Subject: [PATCH 0574/1292] Use MouseArea to catch click instead of onClicked This is necessary because when you click it, the 'checked' property no longer depends on the active extruder. So prevent it from being clicked at all and handle the click separately in this MouseArea. Contributes to issue CURA-5876. --- .../Menus/ConfigurationMenu/CustomConfiguration.qml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index 605d0444e6..08ba042948 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -136,9 +136,19 @@ Item OldControls.CheckBox { checked: Cura.MachineManager.activeStack != null ? Cura.MachineManager.activeStack.isEnabled : false - onClicked: Cura.MachineManager.setExtruderEnabled(selectors.model.index, checked) height: UM.Theme.getSize("setting_control").height style: UM.Theme.styles.checkbox + + /* Use a MouseArea to process the click on this checkbox. + This is necessary because actually clicking the checkbox + causes the "checked" property to be overwritten. After + it's been overwritten, the original link that made it + depend on the active extruder stack is broken. */ + MouseArea + { + anchors.fill: parent + onClicked: Cura.MachineManager.setExtruderEnabled(Cura.ExtruderManager.activeExtruderIndex, !parent.checked) + } } } From d5d49fcec8ea3888ff53b47285322c56407e555a Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 30 Nov 2018 16:43:48 +0100 Subject: [PATCH 0575/1292] Disable extruder enabled checkbox if it's the last one You can't disable the last extruder. Contributes to issue CURA-5876. --- .../qml/Menus/ConfigurationMenu/CustomConfiguration.qml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index 08ba042948..6a3ab82ce2 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -10,6 +10,12 @@ import UM 1.3 as UM Item { + UM.I18nCatalog + { + id: catalog + name: "cura" + } + width: parent.width height: visible ? childrenRect.height : 0 @@ -136,6 +142,7 @@ Item OldControls.CheckBox { checked: Cura.MachineManager.activeStack != null ? Cura.MachineManager.activeStack.isEnabled : false + enabled: !checked || Cura.MachineManager.numberExtrudersEnabled > 1 //Disable if it's the last enabled extruder. height: UM.Theme.getSize("setting_control").height style: UM.Theme.styles.checkbox @@ -148,6 +155,7 @@ Item { anchors.fill: parent onClicked: Cura.MachineManager.setExtruderEnabled(Cura.ExtruderManager.activeExtruderIndex, !parent.checked) + enabled: parent.enabled } } } From 6ab2ce76900777ca64597cf81125351492b8f0aa Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 30 Nov 2018 16:44:55 +0100 Subject: [PATCH 0576/1292] Decrease padding between time & material specification headers --- resources/qml/ActionPanel/PrintJobInformation.qml | 2 -- 1 file changed, 2 deletions(-) diff --git a/resources/qml/ActionPanel/PrintJobInformation.qml b/resources/qml/ActionPanel/PrintJobInformation.qml index e53a92a994..156111af4d 100644 --- a/resources/qml/ActionPanel/PrintJobInformation.qml +++ b/resources/qml/ActionPanel/PrintJobInformation.qml @@ -21,7 +21,6 @@ Column Column { id: timeSpecification - spacing: UM.Theme.getSize("thin_margin").width width: parent.width topPadding: UM.Theme.getSize("default_margin").height leftPadding: UM.Theme.getSize("default_margin").width @@ -71,7 +70,6 @@ Column Column { id: materialSpecification - spacing: UM.Theme.getSize("thin_margin").width width: parent.width bottomPadding: UM.Theme.getSize("default_margin").height leftPadding: UM.Theme.getSize("default_margin").width From f4950cf92b2ba797d62ff85a6c936762c68bb81f Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 30 Nov 2018 17:04:50 +0100 Subject: [PATCH 0577/1292] Give checkboxes a style if they're disabled Contributes to issue CURA-5876. --- resources/themes/cura-light/styles.qml | 2 +- resources/themes/cura-light/theme.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index f00aab44c0..97eae65d27 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -646,7 +646,7 @@ QtObject implicitWidth: Theme.getSize("checkbox").width implicitHeight: Theme.getSize("checkbox").height - color: (control.hovered || control._hovered) ? Theme.getColor("checkbox_hover") : Theme.getColor("checkbox") + color: (control.hovered || control._hovered) ? Theme.getColor("checkbox_hover") : (control.enabled ? Theme.getColor("checkbox") : Theme.getColor("checkbox_disabled")) Behavior on color { ColorAnimation { duration: 50; } } radius: control.exclusiveGroup ? Math.round(Theme.getSize("checkbox").width / 2) : 0 diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index bd7c632eb1..0d77ecf802 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -235,6 +235,7 @@ "checkbox_border": [64, 69, 72, 255], "checkbox_border_hover": [50, 130, 255, 255], "checkbox_mark": [119, 122, 124, 255], + "checkbox_disabled": [223, 223, 223, 255], "checkbox_text": [27, 27, 27, 255], "tooltip": [68, 192, 255, 255], From 0a6e420710ae3c76a9f707c69b0afaec5307ae8f Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 30 Nov 2018 17:05:25 +0100 Subject: [PATCH 0578/1292] Make active tab white Contributes to issue CURA-5876. --- resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index 6a3ab82ce2..b269b95df2 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -89,7 +89,7 @@ Item radius: UM.Theme.getSize("default_radius").width border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") - color: UM.Theme.getColor("secondary") + color: UM.Theme.getColor("main_background") //Remove rounding and lining at the top. Rectangle From 29b7f42e0e2cb15df004fcbf5df023fbf17b9b0c Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Fri, 30 Nov 2018 18:33:53 +0100 Subject: [PATCH 0579/1292] Chaged settings visibility icon CURA-5941 --- resources/qml/Settings/SettingView.qml | 30 ++++++++++++++++++-------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 0a7102ff45..28a64f3346 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -1,4 +1,4 @@ -// Copyright (c) 2017 Ultimaker B.V. +// Copyright (c) 2018 Ultimaker B.V. // Uranium is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 @@ -25,13 +25,15 @@ Item { id: settingVisibilityMenu + property var toolButtonIconColor: UM.Theme.getColor("setting_category_text") + width: height height: UM.Theme.getSize("setting_control").height anchors { topMargin: UM.Theme.getSize("thick_margin").height - right: parent.right - rightMargin: UM.Theme.getSize("thick_margin").width + left: filterContainer.right + leftMargin: UM.Theme.getSize("default_margin").width } style: ButtonStyle { @@ -39,12 +41,12 @@ Item UM.RecolorImage { anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter - width: UM.Theme.getSize("standard_arrow").width - height: UM.Theme.getSize("standard_arrow").height + width: Math.round(parent.width * 0.6) + height: Math.round(parent.height * 0.6) sourceSize.width: width sourceSize.height: width - color: control.enabled ? UM.Theme.getColor("setting_category_text") : UM.Theme.getColor("setting_category_disabled_text") - source: UM.Theme.getIcon("menu") + color: settingVisibilityMenu.toolButtonIconColor + source: UM.Theme.getIcon("settings") } } label: Label{} @@ -57,6 +59,15 @@ Item filter.updateDefinitionModel(); } } + + MouseArea + { + anchors.fill: parent + hoverEnabled: true + acceptedButtons: Qt.RightButton + onEntered: settingVisibilityMenu.toolButtonIconColor = UM.Theme.getColor("setting_control_button_hover") + onExited: settingVisibilityMenu.toolButtonIconColor = UM.Theme.getColor("setting_category_text") + } } Rectangle @@ -84,8 +95,8 @@ Item topMargin: UM.Theme.getSize("thick_margin").height left: parent.left leftMargin: UM.Theme.getSize("default_margin").width - right: settingVisibilityMenu.left - rightMargin: Math.floor(UM.Theme.getSize("default_margin").width / 2) + right: scrollView.right + rightMargin: Math.floor(UM.Theme.getSize("wide_margin").width * 2) } height: UM.Theme.getSize("setting_control").height Timer @@ -196,6 +207,7 @@ Item ScrollView { + id: scrollView anchors.top: filterContainer.bottom; anchors.bottom: parent.bottom; anchors.right: parent.right; From 1238aa7304c24e3c7a706fdcceae09c14791409c Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Sun, 2 Dec 2018 12:03:58 +0100 Subject: [PATCH 0580/1292] Format the slider for the infill in the recommended mode Contributes to CURA-5941 --- .../PrintSetupSelectorContents.qml | 2 +- .../RecommendedInfillDensitySelector.qml | 488 +++++++++--------- .../Recommended/RecommendedPrintSetup.qml | 45 +- .../RecommendedQualityProfileSelector.qml | 28 +- 4 files changed, 268 insertions(+), 295 deletions(-) diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml index 5f22e4c337..0210ece977 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml @@ -25,7 +25,7 @@ Item { id: header height: UM.Theme.getSize("print_setup_widget_header").height - color: "transparent" //UM.Theme.getColor("action_button_hovered") // TODO: It's not clear the color that we need to use here + color: UM.Theme.getColor("action_button_hovered") // TODO: It's not clear the color that we need to use here anchors { diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml index 34cb8f2f20..8b0b87d997 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml @@ -15,57 +15,37 @@ import Cura 1.0 as Cura Item { id: infillRow + height: childrenRect.height + property real labelColumnWidth: Math.round(width / 3) + + // Here are the elements that are shown in the left column Cura.IconWithText { id: infillRowTitle source: UM.Theme.getIcon("category_infill") text: catalog.i18nc("@label", "Infill") + " (%)" - anchors.bottom: parent.bottom width: labelColumnWidth } Item { - id: infillCellRight + id: infillSliderContainer + height: childrenRect.height - height: infillSlider.height + UM.Theme.getSize("thick_margin").height + enableGradualInfillCheckBox.visible * (enableGradualInfillCheckBox.height + UM.Theme.getSize("thick_margin").height) - - anchors.left: infillRowTitle.right - anchors.right: parent.right - - Label + anchors { - id: selectedInfillRateText - - anchors.left: infillSlider.left - anchors.right: parent.right - - text: parseInt(infillDensity.properties.value) + "%" - horizontalAlignment: Text.AlignLeft - - color: infillSlider.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") - } - - // We use a binding to make sure that after manually setting infillSlider.value it is still bound to the property provider - Binding - { - target: infillSlider - property: "value" - value: parseInt(infillDensity.properties.value) + left: infillRowTitle.right + right: parent.right + verticalCenter: infillRowTitle.verticalCenter } Slider { id: infillSlider - anchors.top: selectedInfillRateText.bottom - anchors.left: parent.left - anchors.right: infillIcon.left - anchors.rightMargin: UM.Theme.getSize("thick_margin").width - - height: UM.Theme.getSize("thick_margin").height - width: parseInt(infillCellRight.width - UM.Theme.getSize("thick_margin").width - style.handleWidth) + width: parent.width + height: UM.Theme.getSize("print_setup_slider_handle").height // The handle is the widest element of the slider minimumValue: 0 maximumValue: 100 @@ -78,9 +58,62 @@ Item // set initial value from stack value: parseInt(infillDensity.properties.value) + style: SliderStyle + { + //Draw line + groove: Item + { + Rectangle + { + height: UM.Theme.getSize("print_setup_slider_groove").height + width: control.width - UM.Theme.getSize("print_setup_slider_handle").width + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") + } + } + + handle: Rectangle + { + id: handleButton + color: control.enabled ? UM.Theme.getColor("primary") : UM.Theme.getColor("quality_slider_unavailable") + implicitWidth: UM.Theme.getSize("print_setup_slider_handle").width + implicitHeight: implicitWidth + radius: Math.round(implicitWidth / 2) + opacity: 0.5 + } + + tickmarks: Repeater + { + id: repeater + model: control.maximumValue / control.stepSize + 1 + + Rectangle + { + color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") + implicitWidth: UM.Theme.getSize("print_setup_slider_tickmarks").width + implicitHeight: UM.Theme.getSize("print_setup_slider_tickmarks").height + anchors.verticalCenter: parent.verticalCenter + + // Do not use Math.round otherwise the tickmarks won't be aligned + x: ((styleData.handleWidth / 2) - (implicitWidth / 2) + (index * ((repeater.width - styleData.handleWidth) / (repeater.count-1)))) + radius: Math.round(implicitWidth / 2) + visible: (index % 10) == 0 // Only show steps of 10% + + Label + { + text: index + visible: (index % 20) == 0 // Only show steps of 20% + anchors.horizontalCenter: parent.horizontalCenter + y: UM.Theme.getSize("thin_margin").height + renderType: Text.NativeRendering + } + } + } + } + onValueChanged: { - // Don't round the value if it's already the same if (parseInt(infillDensity.properties.value) == infillSlider.value) { @@ -104,228 +137,177 @@ Item Cura.MachineManager.resetSettingForAllExtruders("infill_line_distance") } } - - style: SliderStyle - { - groove: Rectangle - { - id: groove - implicitWidth: 200 * screenScaleFactor - implicitHeight: 2 * screenScaleFactor - color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") - radius: 1 - } - - handle: Item - { - Rectangle - { - id: handleButton - anchors.centerIn: parent - color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") - implicitWidth: 10 * screenScaleFactor - implicitHeight: 10 * screenScaleFactor - radius: 10 * screenScaleFactor - } - } - - tickmarks: Repeater - { - id: repeater - model: control.maximumValue / control.stepSize + 1 - - // check if a tick should be shown based on it's index and wether the infill density is a multiple of 10 (slider step size) - function shouldShowTick (index) - { - if (index % 10 == 0) - { - return true - } - return false - } - - Rectangle - { - anchors.verticalCenter: parent.verticalCenter - color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") - width: 1 * screenScaleFactor - height: 6 * screenScaleFactor - x: Math.round(styleData.handleWidth / 2 + index * ((repeater.width - styleData.handleWidth) / (repeater.count-1))) - visible: shouldShowTick(index) - } - } - } } - Rectangle - { - id: infillIcon - - width: Math.round((parent.width / 5) - (UM.Theme.getSize("thick_margin").width)) - height: width - - anchors.right: parent.right - anchors.top: parent.top - anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height / 2) - - // we loop over all density icons and only show the one that has the current density and steps - Repeater - { - id: infillIconList - model: infillModel - anchors.fill: parent - - function activeIndex () - { - for (var i = 0; i < infillModel.count; i++) - { - var density = Math.round(infillDensity.properties.value) - var steps = Math.round(infillSteps.properties.value) - var infillModelItem = infillModel.get(i) - - if (infillModelItem != "undefined" - && density >= infillModelItem.percentageMin - && density <= infillModelItem.percentageMax - && steps >= infillModelItem.stepsMin - && steps <= infillModelItem.stepsMax) - { - return i - } - } - return -1 - } - - Rectangle - { - anchors.fill: parent - visible: infillIconList.activeIndex() == index - - border.width: UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("quality_slider_unavailable") - - UM.RecolorImage - { - anchors.fill: parent - anchors.margins: 2 * screenScaleFactor - sourceSize.width: width - sourceSize.height: width - source: UM.Theme.getIcon(model.icon) - color: UM.Theme.getColor("quality_slider_unavailable") - } - } - } - } - - // Gradual Support Infill Checkbox - CheckBox - { - id: enableGradualInfillCheckBox - property alias _hovered: enableGradualInfillMouseArea.containsMouse - - anchors.top: infillSlider.bottom - anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height / 2) // closer to slider since it belongs to the same category - anchors.left: infillCellRight.left - - style: UM.Theme.styles.checkbox - enabled: base.settingsEnabled - visible: infillSteps.properties.enabled == "True" - checked: parseInt(infillSteps.properties.value) > 0 - - MouseArea - { - id: enableGradualInfillMouseArea - - anchors.fill: parent - hoverEnabled: true - enabled: true - - property var previousInfillDensity: parseInt(infillDensity.properties.value) - - onClicked: - { - // Set to 90% only when enabling gradual infill - var newInfillDensity; - if (parseInt(infillSteps.properties.value) == 0) - { - previousInfillDensity = parseInt(infillDensity.properties.value) - newInfillDensity = 90 - } else { - newInfillDensity = previousInfillDensity - } - Cura.MachineManager.setSettingForAllExtruders("infill_sparse_density", "value", String(newInfillDensity)) - - var infill_steps_value = 0 - if (parseInt(infillSteps.properties.value) == 0) - { - infill_steps_value = 5 - } - - Cura.MachineManager.setSettingForAllExtruders("gradual_infill_steps", "value", infill_steps_value) - } - - onEntered: base.showTooltip(enableGradualInfillCheckBox, Qt.point(-infillCellRight.x, 0), - catalog.i18nc("@label", "Gradual infill will gradually increase the amount of infill towards the top.")) - - onExited: base.hideTooltip() - - } - - Label - { - id: gradualInfillLabel - height: parent.height - anchors.left: enableGradualInfillCheckBox.right - anchors.leftMargin: Math.round(UM.Theme.getSize("thick_margin").width / 2) - verticalAlignment: Text.AlignVCenter; - text: catalog.i18nc("@label", "Enable gradual") - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - } - } - - // Infill list model for mapping icon - ListModel - { - id: infillModel - Component.onCompleted: - { - infillModel.append({ - percentageMin: -1, - percentageMax: 0, - stepsMin: -1, - stepsMax: 0, - icon: "hollow" - }) - infillModel.append({ - percentageMin: 0, - percentageMax: 40, - stepsMin: -1, - stepsMax: 0, - icon: "sparse" - }) - infillModel.append({ - percentageMin: 40, - percentageMax: 89, - stepsMin: -1, - stepsMax: 0, - icon: "dense" - }) - infillModel.append({ - percentageMin: 90, - percentageMax: 9999999999, - stepsMin: -1, - stepsMax: 0, - icon: "solid" - }) - infillModel.append({ - percentageMin: 0, - percentageMax: 9999999999, - stepsMin: 1, - stepsMax: 9999999999, - icon: "gradual" - }) - } - } +// Rectangle +// { +// id: infillIcon +// +// width: Math.round((parent.width / 5) - (UM.Theme.getSize("thick_margin").width)) +// height: width +// +// anchors.right: parent.right +// anchors.top: parent.top +// anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height / 2) +// +// // we loop over all density icons and only show the one that has the current density and steps +// Repeater +// { +// id: infillIconList +// model: infillModel +// anchors.fill: parent +// +// function activeIndex () +// { +// for (var i = 0; i < infillModel.count; i++) +// { +// var density = Math.round(infillDensity.properties.value) +// var steps = Math.round(infillSteps.properties.value) +// var infillModelItem = infillModel.get(i) +// +// if (infillModelItem != "undefined" +// && density >= infillModelItem.percentageMin +// && density <= infillModelItem.percentageMax +// && steps >= infillModelItem.stepsMin +// && steps <= infillModelItem.stepsMax) +// { +// return i +// } +// } +// return -1 +// } +// +// Rectangle +// { +// anchors.fill: parent +// visible: infillIconList.activeIndex() == index +// +// border.width: UM.Theme.getSize("default_lining").width +// border.color: UM.Theme.getColor("quality_slider_unavailable") +// +// UM.RecolorImage +// { +// anchors.fill: parent +// anchors.margins: 2 * screenScaleFactor +// sourceSize.width: width +// sourceSize.height: width +// source: UM.Theme.getIcon(model.icon) +// color: UM.Theme.getColor("quality_slider_unavailable") +// } +// } +// } +// } +// +// // Gradual Support Infill Checkbox +// CheckBox +// { +// id: enableGradualInfillCheckBox +// property alias _hovered: enableGradualInfillMouseArea.containsMouse +// +// anchors.top: infillSlider.bottom +// anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height / 2) // closer to slider since it belongs to the same category +// anchors.left: infillSliderContainer.left +// +// style: UM.Theme.styles.checkbox +// enabled: base.settingsEnabled +// visible: infillSteps.properties.enabled == "True" +// checked: parseInt(infillSteps.properties.value) > 0 +// +// MouseArea +// { +// id: enableGradualInfillMouseArea +// +// anchors.fill: parent +// hoverEnabled: true +// enabled: true +// +// property var previousInfillDensity: parseInt(infillDensity.properties.value) +// +// onClicked: +// { +// // Set to 90% only when enabling gradual infill +// var newInfillDensity; +// if (parseInt(infillSteps.properties.value) == 0) +// { +// previousInfillDensity = parseInt(infillDensity.properties.value) +// newInfillDensity = 90 +// } else { +// newInfillDensity = previousInfillDensity +// } +// Cura.MachineManager.setSettingForAllExtruders("infill_sparse_density", "value", String(newInfillDensity)) +// +// var infill_steps_value = 0 +// if (parseInt(infillSteps.properties.value) == 0) +// { +// infill_steps_value = 5 +// } +// +// Cura.MachineManager.setSettingForAllExtruders("gradual_infill_steps", "value", infill_steps_value) +// } +// +// onEntered: base.showTooltip(enableGradualInfillCheckBox, Qt.point(-infillSliderContainer.x, 0), +// catalog.i18nc("@label", "Gradual infill will gradually increase the amount of infill towards the top.")) +// +// onExited: base.hideTooltip() +// +// } +// +// Label +// { +// id: gradualInfillLabel +// height: parent.height +// anchors.left: enableGradualInfillCheckBox.right +// anchors.leftMargin: Math.round(UM.Theme.getSize("thick_margin").width / 2) +// verticalAlignment: Text.AlignVCenter; +// text: catalog.i18nc("@label", "Enable gradual") +// font: UM.Theme.getFont("default") +// color: UM.Theme.getColor("text") +// } +// } +// +// // Infill list model for mapping icon +// ListModel +// { +// id: infillModel +// Component.onCompleted: +// { +// infillModel.append({ +// percentageMin: -1, +// percentageMax: 0, +// stepsMin: -1, +// stepsMax: 0, +// icon: "hollow" +// }) +// infillModel.append({ +// percentageMin: 0, +// percentageMax: 40, +// stepsMin: -1, +// stepsMax: 0, +// icon: "sparse" +// }) +// infillModel.append({ +// percentageMin: 40, +// percentageMax: 89, +// stepsMin: -1, +// stepsMax: 0, +// icon: "dense" +// }) +// infillModel.append({ +// percentageMin: 90, +// percentageMax: 9999999999, +// stepsMin: -1, +// stepsMax: 0, +// icon: "solid" +// }) +// infillModel.append({ +// percentageMin: 0, +// percentageMax: 9999999999, +// stepsMin: 1, +// stepsMax: 9999999999, +// icon: "gradual" +// }) +// } +// } } UM.SettingPropertyProvider diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml index 40a1910c69..0dabc3ea1e 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml @@ -12,10 +12,10 @@ Item { id: base + height: childrenRect.height + 2 * padding + signal showTooltip(Item item, point location, string text) signal hideTooltip() -// width: parent.width - height: childrenRect.height + 2 * padding property Action configureSettings @@ -28,24 +28,11 @@ Item name: "cura" } -// Rectangle -// { -// width: parent.width - 2 * parent.padding -// anchors -// { -// left: parent.left -// right: parent.right -// top: parent.top -// margins: parent.padding -// } -// color: "blue" -// height: 50 -// } - Column { width: parent.width - 2 * parent.padding - spacing: UM.Theme.getSize("default_margin").height + spacing: UM.Theme.getSize("wide_margin").height + anchors { left: parent.left @@ -55,33 +42,27 @@ Item } // TODO - property real labelColumnWidth: Math.round(width / 3) - property real settingsColumnWidth: width - labelColumnWidth + property real firstColumnWidth: Math.round(width / 3) RecommendedQualityProfileSelector { width: parent.width // TODO Create a reusable component with these properties to not define them separately for each component - property real labelColumnWidth: parent.labelColumnWidth - property real settingsColumnWidth: parent.settingsColumnWidth + labelColumnWidth: parent.firstColumnWidth } -// RecommendedInfillDensitySelector -// { -// width: parent.width -// height: childrenRect.height -// // TODO Create a reusable component with these properties to not define them separately for each component -// property real labelColumnWidth: parent.labelColumnWidth -// property real settingsColumnWidth: parent.settingsColumnWidth -// } + RecommendedInfillDensitySelector + { + width: parent.width + // TODO Create a reusable component with these properties to not define them separately for each component + labelColumnWidth: parent.firstColumnWidth + } // // RecommendedSupportSelector // { // width: parent.width -// height: childrenRect.height // // TODO Create a reusable component with these properties to not define them separately for each component -// property real labelColumnWidth: parent.labelColumnWidth -// property real settingsColumnWidth: parent.settingsColumnWidth +// property real firstColumnWidth: parent.labelColumnWidth // } diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml index f7e1d870c9..cddf01a4dc 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml @@ -17,6 +17,9 @@ Item id: qualityRow height: childrenRect.height + property real labelColumnWidth: Math.round(width / 3) + property real settingsColumnWidth: width - labelColumnWidth + Timer { id: qualitySliderChangeTimer @@ -158,6 +161,7 @@ Item } } + // Here are the elements that are shown in the left column Item { id: titleRow @@ -210,6 +214,7 @@ Item { anchors.left: speedSlider.left anchors.top: speedSlider.bottom + height: childrenRect.height Repeater { @@ -219,6 +224,8 @@ Item { anchors.verticalCenter: parent.verticalCenter anchors.top: parent.top + // The height has to be set manually, otherwise it's not automatically calculated in the repeater + height: UM.Theme.getSize("default_margin").height color: (Cura.MachineManager.activeMachine != null && Cura.QualityProfilesDropDownMenuModel.getItem(index).available) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") text: { @@ -268,7 +275,7 @@ Item } } - //Print speed slider + // Print speed slider // Two sliders are created, one at the bottom with the unavailable qualities // and the other at the top with the available quality profiles and so the handle to select them. Item @@ -287,6 +294,8 @@ Item Slider { id: unavailableSlider + + width: parent.width height: qualitySlider.height // Same height as the slider that is on top updateValueWhileDragging : false tickmarksEnabled: true @@ -297,8 +306,6 @@ Item maximumValue: qualityModel.totalTicks stepSize: 1 - width: parent.width - style: SliderStyle { //Draw Unvailable line @@ -329,7 +336,7 @@ Item anchors.verticalCenter: parent.verticalCenter // Do not use Math.round otherwise the tickmarks won't be aligned - x: ((UM.Theme.getSize("print_setup_slider_handle").width / 2) - (UM.Theme.getSize("print_setup_slider_tickmarks").width / 2) + (qualityModel.qualitySliderStepWidth * index)) + x: ((UM.Theme.getSize("print_setup_slider_handle").width / 2) - (implicitWidth / 2) + (qualityModel.qualitySliderStepWidth * index)) radius: Math.round(implicitWidth / 2) } } @@ -354,11 +361,19 @@ Item Slider { id: qualitySlider + + width: qualityModel.qualitySliderStepWidth * (qualityModel.availableTotalTicks - 1) + UM.Theme.getSize("print_setup_slider_handle").width height: UM.Theme.getSize("print_setup_slider_handle").height // The handle is the widest element of the slider enabled: qualityModel.totalTicks > 0 && !Cura.SimpleModeSettingsManager.isProfileCustomized visible: qualityModel.availableTotalTicks > 0 updateValueWhileDragging : false + anchors + { + right: parent.right + rightMargin: qualityModel.qualitySliderMarginRight + } + minimumValue: qualityModel.qualitySliderAvailableMin >= 0 ? qualityModel.qualitySliderAvailableMin : 0 // maximumValue must be greater than minimumValue to be able to see the handle. While the value is strictly // speaking not always correct, it seems to have the correct behavior (switching from 0 available to 1 available) @@ -367,11 +382,6 @@ Item value: qualityModel.qualitySliderActiveIndex - width: qualityModel.qualitySliderStepWidth * (qualityModel.availableTotalTicks - 1) + UM.Theme.getSize("print_setup_slider_handle").width - - anchors.right: parent.right - anchors.rightMargin: qualityModel.qualitySliderMarginRight - style: SliderStyle { // Draw Available line From 4154ec2fe82a79334a2d1b10d2de745a1aa38b19 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Sun, 2 Dec 2018 12:39:52 +0100 Subject: [PATCH 0581/1292] Add enable gradual checkbox to the infill panel Contributes to CURA-5941. --- .../RecommendedInfillDensitySelector.qml | 146 +++++++++--------- 1 file changed, 77 insertions(+), 69 deletions(-) diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml index 8b0b87d997..4226acb790 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml @@ -23,11 +23,20 @@ Item Cura.IconWithText { id: infillRowTitle + anchors.top: parent.top + anchors.left: parent.left source: UM.Theme.getIcon("category_infill") text: catalog.i18nc("@label", "Infill") + " (%)" width: labelColumnWidth } + Rectangle + { + anchors.fill: infillSliderContainer + color: "red" + opacity: 0.5 + } + Item { id: infillSliderContainer @@ -80,7 +89,6 @@ Item implicitWidth: UM.Theme.getSize("print_setup_slider_handle").width implicitHeight: implicitWidth radius: Math.round(implicitWidth / 2) - opacity: 0.5 } tickmarks: Repeater @@ -138,6 +146,74 @@ Item } } } + } + + // Gradual Support Infill Checkbox + CheckBox + { + id: enableGradualInfillCheckBox + property alias _hovered: enableGradualInfillMouseArea.containsMouse + + anchors.top: infillSliderContainer.bottom + anchors.topMargin: UM.Theme.getSize("wide_margin").height + anchors.left: infillSliderContainer.left + + style: UM.Theme.styles.checkbox + enabled: base.settingsEnabled + visible: infillSteps.properties.enabled == "True" + checked: parseInt(infillSteps.properties.value) > 0 + + MouseArea + { + id: enableGradualInfillMouseArea + + anchors.fill: parent + hoverEnabled: true + enabled: true + + property var previousInfillDensity: parseInt(infillDensity.properties.value) + + onClicked: + { + // Set to 90% only when enabling gradual infill + var newInfillDensity; + if (parseInt(infillSteps.properties.value) == 0) + { + previousInfillDensity = parseInt(infillDensity.properties.value) + newInfillDensity = 90 + } else { + newInfillDensity = previousInfillDensity + } + Cura.MachineManager.setSettingForAllExtruders("infill_sparse_density", "value", String(newInfillDensity)) + + var infill_steps_value = 0 + if (parseInt(infillSteps.properties.value) == 0) + { + infill_steps_value = 5 + } + + Cura.MachineManager.setSettingForAllExtruders("gradual_infill_steps", "value", infill_steps_value) + } + + onEntered: base.showTooltip(enableGradualInfillCheckBox, Qt.point(-infillSliderContainer.x - UM.Theme.getSize("thick_margin").width, 0), + catalog.i18nc("@label", "Gradual infill will gradually increase the amount of infill towards the top.")) + + onExited: base.hideTooltip() + } + + Label + { + id: gradualInfillLabel + height: parent.height + anchors.left: enableGradualInfillCheckBox.right + anchors.leftMargin: UM.Theme.getSize("default_margin").width + verticalAlignment: Text.AlignVCenter + text: catalog.i18nc("@label", "Enable gradual") + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + renderType: Text.NativeRendering + } + } // Rectangle // { @@ -198,73 +274,6 @@ Item // } // } // -// // Gradual Support Infill Checkbox -// CheckBox -// { -// id: enableGradualInfillCheckBox -// property alias _hovered: enableGradualInfillMouseArea.containsMouse -// -// anchors.top: infillSlider.bottom -// anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height / 2) // closer to slider since it belongs to the same category -// anchors.left: infillSliderContainer.left -// -// style: UM.Theme.styles.checkbox -// enabled: base.settingsEnabled -// visible: infillSteps.properties.enabled == "True" -// checked: parseInt(infillSteps.properties.value) > 0 -// -// MouseArea -// { -// id: enableGradualInfillMouseArea -// -// anchors.fill: parent -// hoverEnabled: true -// enabled: true -// -// property var previousInfillDensity: parseInt(infillDensity.properties.value) -// -// onClicked: -// { -// // Set to 90% only when enabling gradual infill -// var newInfillDensity; -// if (parseInt(infillSteps.properties.value) == 0) -// { -// previousInfillDensity = parseInt(infillDensity.properties.value) -// newInfillDensity = 90 -// } else { -// newInfillDensity = previousInfillDensity -// } -// Cura.MachineManager.setSettingForAllExtruders("infill_sparse_density", "value", String(newInfillDensity)) -// -// var infill_steps_value = 0 -// if (parseInt(infillSteps.properties.value) == 0) -// { -// infill_steps_value = 5 -// } -// -// Cura.MachineManager.setSettingForAllExtruders("gradual_infill_steps", "value", infill_steps_value) -// } -// -// onEntered: base.showTooltip(enableGradualInfillCheckBox, Qt.point(-infillSliderContainer.x, 0), -// catalog.i18nc("@label", "Gradual infill will gradually increase the amount of infill towards the top.")) -// -// onExited: base.hideTooltip() -// -// } -// -// Label -// { -// id: gradualInfillLabel -// height: parent.height -// anchors.left: enableGradualInfillCheckBox.right -// anchors.leftMargin: Math.round(UM.Theme.getSize("thick_margin").width / 2) -// verticalAlignment: Text.AlignVCenter; -// text: catalog.i18nc("@label", "Enable gradual") -// font: UM.Theme.getFont("default") -// color: UM.Theme.getColor("text") -// } -// } -// // // Infill list model for mapping icon // ListModel // { @@ -308,7 +317,6 @@ Item // }) // } // } - } UM.SettingPropertyProvider { From 1caccfb57705ed75dc49d0d257a71204d9210827 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Sun, 2 Dec 2018 13:40:41 +0100 Subject: [PATCH 0582/1292] Add a binding to react when the infill density changes in the custom panel Also make the icon dinamic, that will change when the infill density changes. Contributes to CURA-5941. --- .../RecommendedInfillDensitySelector.qml | 160 ++++-------------- resources/themes/cura-light/styles.qml | 3 +- resources/themes/cura-light/theme.json | 9 +- 3 files changed, 44 insertions(+), 128 deletions(-) diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml index 4226acb790..0dd594176c 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml @@ -19,6 +19,42 @@ Item property real labelColumnWidth: Math.round(width / 3) + // Create a binding to update the icon when the infill density changes + Binding + { + target: infillRowTitle + property: "source" + value: + { + var density = parseInt(infillDensity.properties.value) + if (parseInt(infillSteps.properties.value) != 0) + { + return UM.Theme.getIcon("gradual") + } + if (density <= 0) + { + return UM.Theme.getIcon("hollow") + } + if (density < 40) + { + return UM.Theme.getIcon("sparse") + } + if (density < 90) + { + return UM.Theme.getIcon("dense") + } + return UM.Theme.getIcon("solid") + } + } + + // We use a binding to make sure that after manually setting infillSlider.value it is still bound to the property provider + Binding + { + target: infillSlider + property: "value" + value: parseInt(infillDensity.properties.value) + } + // Here are the elements that are shown in the left column Cura.IconWithText { @@ -30,13 +66,6 @@ Item width: labelColumnWidth } - Rectangle - { - anchors.fill: infillSliderContainer - color: "red" - opacity: 0.5 - } - Item { id: infillSliderContainer @@ -158,6 +187,7 @@ Item anchors.topMargin: UM.Theme.getSize("wide_margin").height anchors.left: infillSliderContainer.left + text: catalog.i18nc("@label", "Gradual infill") style: UM.Theme.styles.checkbox enabled: base.settingsEnabled visible: infillSteps.properties.enabled == "True" @@ -200,124 +230,8 @@ Item onExited: base.hideTooltip() } - - Label - { - id: gradualInfillLabel - height: parent.height - anchors.left: enableGradualInfillCheckBox.right - anchors.leftMargin: UM.Theme.getSize("default_margin").width - verticalAlignment: Text.AlignVCenter - text: catalog.i18nc("@label", "Enable gradual") - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - renderType: Text.NativeRendering - } } -// Rectangle -// { -// id: infillIcon -// -// width: Math.round((parent.width / 5) - (UM.Theme.getSize("thick_margin").width)) -// height: width -// -// anchors.right: parent.right -// anchors.top: parent.top -// anchors.topMargin: Math.round(UM.Theme.getSize("thick_margin").height / 2) -// -// // we loop over all density icons and only show the one that has the current density and steps -// Repeater -// { -// id: infillIconList -// model: infillModel -// anchors.fill: parent -// -// function activeIndex () -// { -// for (var i = 0; i < infillModel.count; i++) -// { -// var density = Math.round(infillDensity.properties.value) -// var steps = Math.round(infillSteps.properties.value) -// var infillModelItem = infillModel.get(i) -// -// if (infillModelItem != "undefined" -// && density >= infillModelItem.percentageMin -// && density <= infillModelItem.percentageMax -// && steps >= infillModelItem.stepsMin -// && steps <= infillModelItem.stepsMax) -// { -// return i -// } -// } -// return -1 -// } -// -// Rectangle -// { -// anchors.fill: parent -// visible: infillIconList.activeIndex() == index -// -// border.width: UM.Theme.getSize("default_lining").width -// border.color: UM.Theme.getColor("quality_slider_unavailable") -// -// UM.RecolorImage -// { -// anchors.fill: parent -// anchors.margins: 2 * screenScaleFactor -// sourceSize.width: width -// sourceSize.height: width -// source: UM.Theme.getIcon(model.icon) -// color: UM.Theme.getColor("quality_slider_unavailable") -// } -// } -// } -// } -// -// // Infill list model for mapping icon -// ListModel -// { -// id: infillModel -// Component.onCompleted: -// { -// infillModel.append({ -// percentageMin: -1, -// percentageMax: 0, -// stepsMin: -1, -// stepsMax: 0, -// icon: "hollow" -// }) -// infillModel.append({ -// percentageMin: 0, -// percentageMax: 40, -// stepsMin: -1, -// stepsMax: 0, -// icon: "sparse" -// }) -// infillModel.append({ -// percentageMin: 40, -// percentageMax: 89, -// stepsMin: -1, -// stepsMax: 0, -// icon: "dense" -// }) -// infillModel.append({ -// percentageMin: 90, -// percentageMax: 9999999999, -// stepsMin: -1, -// stepsMax: 0, -// icon: "solid" -// }) -// infillModel.append({ -// percentageMin: 0, -// percentageMax: 9999999999, -// stepsMin: 1, -// stepsMax: 9999999999, -// icon: "gradual" -// }) -// } -// } - UM.SettingPropertyProvider { id: infillDensity diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index e040d91df9..96bf334c43 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -532,7 +532,7 @@ QtObject color: (control.hovered || control._hovered) ? Theme.getColor("checkbox_hover") : Theme.getColor("checkbox") Behavior on color { ColorAnimation { duration: 50; } } - radius: control.exclusiveGroup ? Math.round(Theme.getSize("checkbox").width / 2) : 0 + radius: control.exclusiveGroup ? Math.round(Theme.getSize("checkbox").width / 2) : UM.Theme.getSize("checkbox_radius").width border.width: Theme.getSize("default_lining").width border.color: (control.hovered || control._hovered) ? Theme.getColor("checkbox_border_hover") : Theme.getColor("checkbox_border") @@ -557,6 +557,7 @@ QtObject color: Theme.getColor("checkbox_text") font: Theme.getFont("default") elide: Text.ElideRight + renderType: Text.NativeRendering } } } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 7cfd7b93e1..392b09303d 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -239,10 +239,10 @@ "checkbox": [255, 255, 255, 255], "checkbox_hover": [255, 255, 255, 255], - "checkbox_border": [64, 69, 72, 255], + "checkbox_border": [199, 199, 199, 255], "checkbox_border_hover": [50, 130, 255, 255], - "checkbox_mark": [119, 122, 124, 255], - "checkbox_text": [27, 27, 27, 255], + "checkbox_mark": [50, 130, 255, 255], + "checkbox_text": [35, 35, 35, 255], "tooltip": [68, 192, 255, 255], "tooltip_text": [255, 255, 255, 255], @@ -459,7 +459,8 @@ "layerview_row": [11.0, 1.5], "layerview_row_spacing": [0.0, 0.5], - "checkbox": [2.0, 2.0], + "checkbox": [1.5, 1.5], + "checkbox_radius": [0.08, 0.08], "tooltip": [20.0, 10.0], "tooltip_margins": [1.0, 1.0], From 1cea36b08a5f6f1a8899667a39ec87285abab9c6 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Sun, 2 Dec 2018 19:01:54 +0100 Subject: [PATCH 0583/1292] Add the row for the support selection in the recommended mode Contributes to CURA-5941. --- .../Recommended/RecommendedPrintSetup.qml | 15 +- .../RecommendedSupportSelector.qml | 189 +++++++++++------- resources/themes/cura-light/styles.qml | 15 +- resources/themes/cura-light/theme.json | 10 +- 4 files changed, 134 insertions(+), 95 deletions(-) diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml index 0dabc3ea1e..d246be560e 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml @@ -57,13 +57,13 @@ Item // TODO Create a reusable component with these properties to not define them separately for each component labelColumnWidth: parent.firstColumnWidth } -// -// RecommendedSupportSelector -// { -// width: parent.width -// // TODO Create a reusable component with these properties to not define them separately for each component -// property real firstColumnWidth: parent.labelColumnWidth -// } + + RecommendedSupportSelector + { + width: parent.width + // TODO Create a reusable component with these properties to not define them separately for each component + labelColumnWidth: parent.firstColumnWidth + } // @@ -128,7 +128,6 @@ Item // } } - UM.SettingPropertyProvider { id: platformAdhesionType diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml index 9c4e5ed576..2407b746b2 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml @@ -8,114 +8,142 @@ import QtQuick.Controls.Styles 1.4 import UM 1.2 as UM import Cura 1.0 as Cura + // // Enable support // -Row +Item { + id: enableSupportRow + height: childrenRect.height + + property real labelColumnWidth: Math.round(width / 3) Cura.IconWithText { - id: enableSupportLabel + id: enableSupportRowTitle + anchors.top: parent.top + anchors.left: parent.left visible: enableSupportCheckBox.visible source: UM.Theme.getIcon("category_support") text: catalog.i18nc("@label", "Support") width: labelColumnWidth } - CheckBox + Item { - id: enableSupportCheckBox - property alias _hovered: enableSupportMouseArea.containsMouse + id: enableSupportContainer + height: childrenRect.height - style: UM.Theme.styles.checkbox - enabled: base.settingsEnabled - - visible: supportEnabled.properties.enabled == "True" - checked: supportEnabled.properties.value == "True" - - MouseArea + anchors { - id: enableSupportMouseArea - anchors.fill: parent - hoverEnabled: true - onClicked: supportEnabled.setPropertyValue("value", supportEnabled.properties.value != "True") - - onEntered: base.showTooltip(enableSupportCheckBox, Qt.point(-enableSupportCheckBox.x, 0), - catalog.i18nc("@label", "Generate structures to support parts of the model which have overhangs. Without these structures, such parts would collapse during printing.")) - - onExited: base.hideTooltip() - - } - } - - ComboBox - { - id: supportExtruderCombobox - visible: enableSupportCheckBox.visible && (supportEnabled.properties.value == "True") && (extrudersEnabledCount.properties.value > 1) - model: extruderModel - - property string color_override: "" // for manually setting values - property string color: // is evaluated automatically, but the first time is before extruderModel being filled - { - var current_extruder = extruderModel.get(currentIndex); - color_override = ""; - if (current_extruder === undefined) return "" - return (current_extruder.color) ? current_extruder.color : ""; + left: enableSupportRowTitle.right + right: parent.right + verticalCenter: enableSupportRowTitle.verticalCenter } - textRole: "text" // this solves that the combobox isn't populated in the first time Cura is started - - width: Math.round(UM.Theme.getSize("print_setup_widget").width * .55) - Math.round(UM.Theme.getSize("thick_margin").width / 2) - enableSupportCheckBox.width - height: ((supportEnabled.properties.value == "True") && (machineExtruderCount.properties.value > 1)) ? UM.Theme.getSize("setting_control").height : 0 - - Behavior on height { NumberAnimation { duration: 100 } } - - style: UM.Theme.styles.combobox_color - enabled: base.settingsEnabled - property alias _hovered: supportExtruderMouseArea.containsMouse - - currentIndex: + CheckBox { - if (supportExtruderNr.properties == null) + id: enableSupportCheckBox + anchors.verticalCenter: parent.verticalCenter + + property alias _hovered: enableSupportMouseArea.containsMouse + + style: UM.Theme.styles.checkbox + enabled: base.settingsEnabled + + visible: supportEnabled.properties.enabled == "True" + checked: supportEnabled.properties.value == "True" + + MouseArea { - return Cura.MachineManager.defaultExtruderPosition + id: enableSupportMouseArea + anchors.fill: parent + hoverEnabled: true + onClicked: supportEnabled.setPropertyValue("value", supportEnabled.properties.value != "True") + + onEntered: + { + base.showTooltip(enableSupportCheckBox, Qt.point(-enableSupportContainer.x - UM.Theme.getSize("thick_margin").width, 0), + catalog.i18nc("@label", "Generate structures to support parts of the model which have overhangs. Without these structures, such parts would collapse during printing.")) + } + onExited: base.hideTooltip() } - else + } + + ComboBox + { + id: supportExtruderCombobox + + height: UM.Theme.getSize("print_setup_support_extruder_selector").height + anchors { - var extruder = parseInt(supportExtruderNr.properties.value) - if ( extruder === -1) + left: enableSupportCheckBox.right + right: parent.right + leftMargin: UM.Theme.getSize("thick_margin").width + rightMargin: UM.Theme.getSize("thick_margin").width + verticalCenter: parent.verticalCenter + } + + style: UM.Theme.styles.combobox_color + enabled: base.settingsEnabled + visible: enableSupportCheckBox.visible && (supportEnabled.properties.value == "True") && (extrudersEnabledCount.properties.value > 1) + textRole: "text" // this solves that the combobox isn't populated in the first time Cura is started + + model: extruderModel + + property alias _hovered: supportExtruderMouseArea.containsMouse + property string color_override: "" // for manually setting values + property string color: // is evaluated automatically, but the first time is before extruderModel being filled + { + var current_extruder = extruderModel.get(currentIndex); + color_override = ""; + if (current_extruder === undefined) return "" + return (current_extruder.color) ? current_extruder.color : ""; + } + + currentIndex: + { + if (supportExtruderNr.properties == null) { return Cura.MachineManager.defaultExtruderPosition } - return extruder; + else + { + var extruder = parseInt(supportExtruderNr.properties.value) + if ( extruder === -1) + { + return Cura.MachineManager.defaultExtruderPosition + } + return extruder; + } } - } - onActivated: supportExtruderNr.setPropertyValue("value", String(index)) + onActivated: supportExtruderNr.setPropertyValue("value", String(index)) - MouseArea - { - id: supportExtruderMouseArea - anchors.fill: parent - hoverEnabled: true - enabled: base.settingsEnabled - acceptedButtons: Qt.NoButton - onEntered: + MouseArea { - base.showTooltip(supportExtruderCombobox, Qt.point(-supportExtruderCombobox.x, 0), - catalog.i18nc("@label", "Select which extruder to use for support. This will build up supporting structures below the model to prevent the model from sagging or printing in mid air.")); + id: supportExtruderMouseArea + anchors.fill: parent + hoverEnabled: true + enabled: base.settingsEnabled + acceptedButtons: Qt.NoButton + onEntered: + { + base.showTooltip(supportExtruderCombobox, Qt.point(-enableSupportContainer.x - supportExtruderCombobox.x - UM.Theme.getSize("thick_margin").width, 0), + catalog.i18nc("@label", "Select which extruder to use for support. This will build up supporting structures below the model to prevent the model from sagging or printing in mid air.")); + } + onExited: base.hideTooltip() + } - onExited: base.hideTooltip() - } - - function updateCurrentColor() - { - var current_extruder = extruderModel.get(currentIndex) - if (current_extruder !== undefined) + function updateCurrentColor() { - supportExtruderCombobox.color_override = current_extruder.color + var current_extruder = extruderModel.get(currentIndex) + if (current_extruder !== undefined) + { + supportExtruderCombobox.color_override = current_extruder.color + } } } } @@ -160,6 +188,15 @@ Row storeIndex: 0 } + UM.SettingPropertyProvider + { + id: machineExtruderCount + containerStack: Cura.MachineManager.activeMachine + key: "machine_extruder_count" + watchedProperties: ["value"] + storeIndex: 0 + } + function populateExtruderModel() { extruderModel.clear() diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index 96bf334c43..5203cb0b0b 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -413,11 +413,11 @@ QtObject border.width: Theme.getSize("default_lining").width; border.color: control.hovered ? Theme.getColor("setting_control_border_highlight") : Theme.getColor("setting_control_border"); + radius: UM.Theme.getSize("setting_control_radius").width } label: Item { - Label { anchors.left: parent.left @@ -465,11 +465,11 @@ QtObject color: !enabled ? UM.Theme.getColor("setting_control_disabled") : control._hovered ? UM.Theme.getColor("setting_control_highlight") : UM.Theme.getColor("setting_control") border.width: UM.Theme.getSize("default_lining").width border.color: !enabled ? UM.Theme.getColor("setting_control_disabled_border") : control._hovered ? UM.Theme.getColor("setting_control_border_highlight") : UM.Theme.getColor("setting_control_border") + radius: UM.Theme.getSize("setting_control_radius").width } label: Item { - Label { anchors.left: parent.left @@ -486,7 +486,7 @@ QtObject verticalAlignment: Text.AlignVCenter } - Rectangle + UM.RecolorImage { id: swatch height: Math.round(UM.Theme.getSize("setting_control").height / 2) @@ -494,9 +494,9 @@ QtObject anchors.right: downArrow.left anchors.verticalCenter: parent.verticalCenter anchors.margins: Math.round(UM.Theme.getSize("default_margin").width / 4) - radius: Math.round(width / 2) - border.width: UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("lining") + sourceSize.width: width + sourceSize.height: height + source: UM.Theme.getIcon("extruder_button") color: (control.color_override !== "") ? control.color_override : control.color } @@ -575,7 +575,7 @@ QtObject color: (control.hovered || control._hovered) ? Theme.getColor("checkbox_hover") : Theme.getColor("checkbox"); Behavior on color { ColorAnimation { duration: 50; } } - radius: control.exclusiveGroup ? Math.round(Theme.getSize("checkbox").width / 2) : 0 + radius: control.exclusiveGroup ? Math.round(Theme.getSize("checkbox").width / 2) : UM.Theme.getSize("checkbox_radius").width border.width: Theme.getSize("default_lining").width; border.color: (control.hovered || control._hovered) ? Theme.getColor("checkbox_border_hover") : Theme.getColor("checkbox_border"); @@ -628,6 +628,7 @@ QtObject border.width: Theme.getSize("default_lining").width; border.color: control.hovered ? Theme.getColor("setting_control_border_highlight") : Theme.getColor("setting_control_border"); + radius: UM.Theme.getSize("setting_control_radius").width color: Theme.getColor("setting_validation_ok"); diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 392b09303d..afe40007f4 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -206,11 +206,11 @@ "setting_control": [255, 255, 255, 255], "setting_control_selected": [31, 36, 39, 255], "setting_control_highlight": [255, 255, 255, 255], - "setting_control_border": [127, 127, 127, 255], + "setting_control_border": [199, 199, 199, 255], "setting_control_border_highlight": [50, 130, 255, 255], - "setting_control_text": [27, 27, 27, 255], - "setting_control_depth_line": [127, 127, 127, 255], - "setting_control_button": [127, 127, 127, 255], + "setting_control_text": [35, 35, 35, 255], + "setting_control_depth_line": [199, 199, 199, 255], + "setting_control_button": [199, 199, 199, 255], "setting_control_button_hover": [70, 84, 113, 255], "setting_control_disabled": [245, 245, 245, 255], "setting_control_disabled_text": [127, 127, 127, 255], @@ -377,6 +377,7 @@ "print_setup_slider_groove": [0.16, 0.16], "print_setup_slider_handle": [1.0, 1.0], "print_setup_slider_tickmarks": [0.32, 0.32], + "print_setup_support_extruder_selector": [18.2, 2.5], "configuration_selector_mode_tabs": [0.0, 3.0], @@ -415,6 +416,7 @@ "setting": [25.0, 1.8], "setting_control": [10.0, 2.0], + "setting_control_radius": [0.15, 0.15], "setting_control_depth_margin": [1.4, 0.0], "setting_preferences_button_margin": [4, 0.0], "setting_control_margin": [0.0, 0.0], From adabb833e0b6dbc978bfb96f8b42004f03e28a84 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Sun, 2 Dec 2018 19:14:34 +0100 Subject: [PATCH 0584/1292] Add row for the adhesion setting in the recommended mode Contributes to CURA-5941. --- .../RecommendedAdhesionSelector.qml | 99 +++++++++++++++++++ .../Recommended/RecommendedPrintSetup.qml | 77 ++------------- .../RecommendedSupportSelector.qml | 2 +- 3 files changed, 106 insertions(+), 72 deletions(-) create mode 100644 resources/qml/PrintSetupSelector/Recommended/RecommendedAdhesionSelector.qml diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedAdhesionSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedAdhesionSelector.qml new file mode 100644 index 0000000000..a7e8b3ea75 --- /dev/null +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedAdhesionSelector.qml @@ -0,0 +1,99 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 + +import UM 1.2 as UM +import Cura 1.0 as Cura + + +// +// Adhesion +// +Item +{ + id: enableAdhesionRow + height: childrenRect.height + + property real labelColumnWidth: Math.round(width / 3) + + Cura.IconWithText + { + id: enableAdhesionRowTitle + anchors.top: parent.top + anchors.left: parent.left + source: UM.Theme.getIcon("category_adhesion") + text: catalog.i18nc("@label", "Adhesion") + width: labelColumnWidth + } + + Item + { + id: enableAdhesionContainer + height: childrenRect.height + + anchors + { + left: enableAdhesionRowTitle.right + right: parent.right + verticalCenter: enableAdhesionRowTitle.verticalCenter + } + + CheckBox + { + id: enableAdhesionCheckBox + anchors.verticalCenter: parent.verticalCenter + + //: Setting enable printing build-plate adhesion helper checkbox + style: UM.Theme.styles.checkbox + enabled: base.settingsEnabled + + visible: platformAdhesionType.properties.enabled == "True" + checked: platformAdhesionType.properties.value != "skirt" && platformAdhesionType.properties.value != "none" + + MouseArea + { + id: adhesionMouseArea + anchors.fill: parent + hoverEnabled: true + enabled: base.settingsEnabled + + onClicked: + { + var adhesionType = "skirt" + if (!parent.checked) + { + // Remove the "user" setting to see if the rest of the stack prescribes a brim or a raft + platformAdhesionType.removeFromContainer(0) + adhesionType = platformAdhesionType.properties.value + if(adhesionType == "skirt" || adhesionType == "none") + { + // If the rest of the stack doesn't prescribe an adhesion-type, default to a brim + adhesionType = "brim" + } + } + platformAdhesionType.setPropertyValue("value", adhesionType) + } + + onEntered: + { + base.showTooltip(enableAdhesionCheckBox, Qt.point(-enableAdhesionContainer.x - UM.Theme.getSize("thick_margin").width, 0), + catalog.i18nc("@label", "Enable printing a brim or raft. This will add a flat area around or under your object which is easy to cut off afterwards.")); + } + onExited: base.hideTooltip() + } + } + } + + UM.SettingPropertyProvider + { + id: platformAdhesionType + containerStack: Cura.MachineManager.activeMachine + removeUnusedValue: false //Doesn't work with settings that are resolved. + key: "adhesion_type" + watchedProperties: [ "value", "enabled" ] + storeIndex: 0 + } +} \ No newline at end of file diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml index d246be560e..a8fca47d6c 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml @@ -65,76 +65,11 @@ Item labelColumnWidth: parent.firstColumnWidth } - -// -// // Adhesion -// Row -// { -// anchors.left: parent.left -// anchors.right: parent.right -// height: childrenRect.height -// -// Cura.IconWithText -// { -// id: adhesionHelperLabel -// visible: adhesionCheckBox.visible -// source: UM.Theme.getIcon("category_adhesion") -// text: catalog.i18nc("@label", "Adhesion") -// width: labelColumnWidth -// } -// -// CheckBox -// { -// id: adhesionCheckBox -// property alias _hovered: adhesionMouseArea.containsMouse -// -// //: Setting enable printing build-plate adhesion helper checkbox -// style: UM.Theme.styles.checkbox -// enabled: base.settingsEnabled -// -// visible: platformAdhesionType.properties.enabled == "True" -// checked: platformAdhesionType.properties.value != "skirt" && platformAdhesionType.properties.value != "none" -// -// MouseArea -// { -// id: adhesionMouseArea -// anchors.fill: parent -// hoverEnabled: true -// enabled: base.settingsEnabled -// onClicked: -// { -// var adhesionType = "skirt" -// if(!parent.checked) -// { -// // Remove the "user" setting to see if the rest of the stack prescribes a brim or a raft -// platformAdhesionType.removeFromContainer(0) -// adhesionType = platformAdhesionType.properties.value -// if(adhesionType == "skirt" || adhesionType == "none") -// { -// // If the rest of the stack doesn't prescribe an adhesion-type, default to a brim -// adhesionType = "brim" -// } -// } -// platformAdhesionType.setPropertyValue("value", adhesionType) -// } -// onEntered: -// { -// base.showTooltip(adhesionCheckBox, Qt.point(-adhesionCheckBox.x, 0), -// catalog.i18nc("@label", "Enable printing a brim or raft. This will add a flat area around or under your object which is easy to cut off afterwards.")); -// } -// onExited: base.hideTooltip() -// } -// } -// } - } - - UM.SettingPropertyProvider - { - id: platformAdhesionType - containerStack: Cura.MachineManager.activeMachine - removeUnusedValue: false //Doesn't work with settings that are resolved. - key: "adhesion_type" - watchedProperties: [ "value", "enabled" ] - storeIndex: 0 + RecommendedAdhesionSelector + { + width: parent.width + // TODO Create a reusable component with these properties to not define them separately for each component + labelColumnWidth: parent.firstColumnWidth + } } } diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml index 2407b746b2..4e63242f05 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml @@ -33,7 +33,7 @@ Item Item { id: enableSupportContainer - height: childrenRect.height + height: enableSupportCheckBox.height anchors { From 7dc3320b0648142719b59c7a73dcf66da373335c Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Sun, 2 Dec 2018 20:32:55 +0100 Subject: [PATCH 0585/1292] Remove all the signal propagation for the tooltip and allow only Cura.qml to handle them Contributes to CURA-5941. --- plugins/PrepareStage/PrepareMenu.qml | 4 ---- plugins/PreviewStage/PreviewMenu.qml | 3 --- resources/qml/Cura.qml | 9 --------- .../Custom/CustomPrintSetup.qml | 13 ++++++++++++- .../PrintSetupSelector/PrintSetupSelector.qml | 17 +---------------- .../PrintSetupSelectorContents.qml | 9 +++------ .../Recommended/RecommendedAdhesionSelector.qml | 7 ++++--- .../RecommendedInfillDensitySelector.qml | 2 +- .../Recommended/RecommendedPrintSetup.qml | 5 +---- .../Recommended/RecommendedSupportSelector.qml | 7 ++++--- resources/qml/Settings/SettingView.qml | 6 ++---- 11 files changed, 28 insertions(+), 54 deletions(-) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index 7c01b1f8b0..0191396e7b 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -13,10 +13,6 @@ import QtGraphicalEffects 1.0 // For the dropshadow Item { id: prepareMenu - // This widget doesn't show tooltips by itself. Instead it emits signals so others can do something with it. - signal showTooltip(Item item, point location, string text) - signal hideTooltip() - UM.I18nCatalog { diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index a1f59cd4ca..1543536160 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -10,9 +10,6 @@ import Cura 1.1 as Cura Item { id: previewMenu - // This widget doesn't show tooltips by itself. Instead it emits signals so others can do something with it. - signal showTooltip(Item item, point location, string text) - signal hideTooltip() property real itemHeight: height - 2 * UM.Theme.getSize("default_lining").width diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 36f5758fa3..4effea5ba7 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -181,13 +181,6 @@ UM.MainWindow } } - Connections - { - target: stageMenu.item - onShowTooltip: base.showTooltip(item, location, text) - onHideTooltip: base.hideTooltip() - } - JobSpecs { id: jobSpecs @@ -280,8 +273,6 @@ UM.MainWindow // Every time the stage is changed. property var printSetupSelector: Cura.PrintSetupSelector { - onShowTooltip: base.showTooltip(item, location, text) - onHideTooltip: base.hideTooltip() width: UM.Theme.getSize("print_setup_widget").width height: UM.Theme.getSize("stage_menu").height headerCornerSide: RoundedRectangle.Direction.Right diff --git a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml index 51cd8eff0d..ea56a4471e 100644 --- a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml +++ b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml @@ -6,5 +6,16 @@ import QtQuick.Controls 2.0 import Cura 1.0 as Cura -Cura.SettingView { + +Item +{ + id: customPrintSetup + + // TODO: Hardcoded now but UX has to decide about the height of this item + height: 500 + + Cura.SettingView + { + anchors.fill: parent + } } diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector/PrintSetupSelector.qml index 1794a54cdf..5518ac6b60 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelector.qml @@ -9,17 +9,13 @@ import Cura 1.0 as Cura Cura.ExpandableComponent { - id: base + id: printSetupSelector property bool hideSettings: PrintInformation.preSliced property string enabledText: catalog.i18nc("@label:Should be short", "On") property string disabledText: catalog.i18nc("@label:Should be short", "Off") - // This widget doesn't show tooltips by itself. Instead it emits signals so others can do something with it. - signal showTooltip(Item item, point location, string text) - signal hideTooltip() - iconSource: UM.Theme.getIcon("pencil") popupPadding: UM.Theme.getSize("default_lining").width popupSpacingY: UM.Theme.getSize("narrow_margin").width @@ -32,17 +28,6 @@ Cura.ExpandableComponent name: "cura" } - Timer - { - id: tooltipDelayTimer - interval: 500 - repeat: false - property var item - property string text - - onTriggered: base.showTooltip(base, {x: 0, y: item.y}, text) - } - headerItem: PrintSetupSelectorHeader { anchors.fill: parent diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml index 0210ece977..77d1b59f4c 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml @@ -93,7 +93,7 @@ Item Item { id: contents - height: childrenRect.height + height: currentModeIndex == 0 ? recommendedPrintSetup.height : customPrintSetup.height anchors { @@ -104,28 +104,25 @@ Item RecommendedPrintSetup { + id: recommendedPrintSetup anchors { left: parent.left right: parent.right top: parent.top } - onShowTooltip: base.showTooltip(item, location, text) - onHideTooltip: base.hideTooltip() visible: currentModeIndex == 0 } CustomPrintSetup { + id: customPrintSetup anchors { left: parent.left right: parent.right top: parent.top } - height: 500 - onShowTooltip: base.showTooltip(item, location, text) - onHideTooltip: base.hideTooltip() visible: currentModeIndex == 1 } } diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedAdhesionSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedAdhesionSelector.qml index a7e8b3ea75..3092644d4e 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedAdhesionSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedAdhesionSelector.qml @@ -32,7 +32,7 @@ Item Item { id: enableAdhesionContainer - height: childrenRect.height + height: enableAdhesionCheckBox.height anchors { @@ -46,9 +46,11 @@ Item id: enableAdhesionCheckBox anchors.verticalCenter: parent.verticalCenter + property alias _hovered: adhesionMouseArea.containsMouse + //: Setting enable printing build-plate adhesion helper checkbox style: UM.Theme.styles.checkbox - enabled: base.settingsEnabled + enabled: recommendedPrintSettup.settingsEnabled visible: platformAdhesionType.properties.enabled == "True" checked: platformAdhesionType.properties.value != "skirt" && platformAdhesionType.properties.value != "none" @@ -58,7 +60,6 @@ Item id: adhesionMouseArea anchors.fill: parent hoverEnabled: true - enabled: base.settingsEnabled onClicked: { diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml index 0dd594176c..7c026ac9de 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml @@ -189,7 +189,7 @@ Item text: catalog.i18nc("@label", "Gradual infill") style: UM.Theme.styles.checkbox - enabled: base.settingsEnabled + enabled: recommendedPrintSettup.settingsEnabled visible: infillSteps.properties.enabled == "True" checked: parseInt(infillSteps.properties.value) > 0 diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml index a8fca47d6c..194747271e 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml @@ -10,13 +10,10 @@ import Cura 1.0 as Cura Item { - id: base + id: recommendedPrintSettup height: childrenRect.height + 2 * padding - signal showTooltip(Item item, point location, string text) - signal hideTooltip() - property Action configureSettings property bool settingsEnabled: Cura.ExtruderManager.activeExtruderStackId || extrudersEnabledCount.properties.value == 1 diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml index 4e63242f05..25a5574a39 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml @@ -50,7 +50,7 @@ Item property alias _hovered: enableSupportMouseArea.containsMouse style: UM.Theme.styles.checkbox - enabled: base.settingsEnabled + enabled: recommendedPrintSettup.settingsEnabled visible: supportEnabled.properties.enabled == "True" checked: supportEnabled.properties.value == "True" @@ -60,6 +60,7 @@ Item id: enableSupportMouseArea anchors.fill: parent hoverEnabled: true + onClicked: supportEnabled.setPropertyValue("value", supportEnabled.properties.value != "True") onEntered: @@ -86,7 +87,7 @@ Item } style: UM.Theme.styles.combobox_color - enabled: base.settingsEnabled + enabled: recommendedPrintSettup.settingsEnabled visible: enableSupportCheckBox.visible && (supportEnabled.properties.value == "True") && (extrudersEnabledCount.properties.value > 1) textRole: "text" // this solves that the combobox isn't populated in the first time Cura is started @@ -126,7 +127,7 @@ Item id: supportExtruderMouseArea anchors.fill: parent hoverEnabled: true - enabled: base.settingsEnabled + enabled: recommendedPrintSettup.settingsEnabled acceptedButtons: Qt.NoButton onEntered: { diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 0a7102ff45..270f04e70f 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -13,13 +13,11 @@ import "../Menus" Item { - id: base; + id: settingsView property QtObject settingVisibilityPresetsModel: CuraApplication.getSettingVisibilityPresetsModel() property Action configureSettings property bool findingSettings - signal showTooltip(Item item, point location, string text) - signal hideTooltip() ToolButton { @@ -359,7 +357,7 @@ Item contextMenu.provider = provider contextMenu.popup(); } - onShowTooltip: base.showTooltip(delegate, { x: -UM.Theme.getSize("default_arrow").width, y: Math.round(delegate.height / 2) }, text) + onShowTooltip: base.showTooltip(delegate, Qt.point(- UM.Theme.getSize("default_arrow").width, 0), text) onHideTooltip: base.hideTooltip() onShowAllHiddenInheritedSettings: { From 82e66eeaa1957184e8cf9b4ce1359ec47690f946 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 3 Dec 2018 09:02:41 +0100 Subject: [PATCH 0586/1292] Remove tabs and lining with single-extruder printers There's no sense in showing tabs if the user can't use them. Contributes to issue CURA-5876. --- .../qml/Menus/ConfigurationMenu/CustomConfiguration.qml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index b269b95df2..957cd16b3e 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -40,6 +40,7 @@ Item id: tabBar anchors.top: header.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height + visible: Cura.MachineManager.numberExtrudersEnabled > 1 currentIndex: Math.max(Cura.ExtruderManager.activeExtruderIndex, 0) @@ -86,8 +87,8 @@ Item height: childrenRect.height anchors.top: tabBar.bottom - radius: UM.Theme.getSize("default_radius").width - border.width: UM.Theme.getSize("default_lining").width + radius: tabBar.visible ? UM.Theme.getSize("default_radius").width : 0 + border.width: tabBar.visible ? UM.Theme.getSize("default_lining").width : 0 border.color: UM.Theme.getColor("lining") color: UM.Theme.getColor("main_background") @@ -98,6 +99,7 @@ Item height: parent.radius anchors.top: parent.top color: UM.Theme.getColor("lining") + visible: tabBar.visible Rectangle { anchors From db05d7853a3567da6bb328f676c3f89dfb74bfcc Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 3 Dec 2018 09:04:35 +0100 Subject: [PATCH 0587/1292] Remove background colour from tab window The colour is the same as what is behind it anyway. Contributes to issue CURA-5876. --- resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index 957cd16b3e..eae160b48a 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -90,7 +90,6 @@ Item radius: tabBar.visible ? UM.Theme.getSize("default_radius").width : 0 border.width: tabBar.visible ? UM.Theme.getSize("default_lining").width : 0 border.color: UM.Theme.getColor("lining") - color: UM.Theme.getColor("main_background") //Remove rounding and lining at the top. Rectangle From 90281c455b74a56fc49c45724fee3e4b3aa88f85 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 3 Dec 2018 09:45:49 +0100 Subject: [PATCH 0588/1292] Add global profile selector to the custom print setup panel Also modify some styles to adjust to the designs. Contributes to CURA-5941. --- .../Custom/CustomPrintSetup.qml | 29 +++++++++- .../Custom/GlobalProfileSelector.qml} | 53 +++++++++++-------- .../PrintSetupSelector/PrintSetupSelector.qml | 2 - .../RecommendedQualityProfileSelector.qml | 4 +- .../RecommendedSupportSelector.qml | 2 +- resources/qml/qmldir | 3 +- resources/themes/cura-light/styles.qml | 6 ++- resources/themes/cura-light/theme.json | 3 +- 8 files changed, 71 insertions(+), 31 deletions(-) rename resources/qml/{GlobalProfileButton.qml => PrintSetupSelector/Custom/GlobalProfileSelector.qml} (67%) diff --git a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml index ea56a4471e..e0f0827b17 100644 --- a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml +++ b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml @@ -4,6 +4,7 @@ import QtQuick 2.7 import QtQuick.Controls 2.0 +import UM 1.3 as UM import Cura 1.0 as Cura @@ -14,8 +15,34 @@ Item // TODO: Hardcoded now but UX has to decide about the height of this item height: 500 + property real padding: UM.Theme.getSize("default_margin").width + + // Profile selector row + GlobalProfileSelector + { + id: globalProfileRow + anchors + { + top: parent.top + topMargin: parent.padding + left: parent.left + leftMargin: parent.padding + right: parent.right + rightMargin: parent.padding + } + } + Cura.SettingView { - anchors.fill: parent + anchors + { + top: globalProfileRow.bottom + topMargin: UM.Theme.getSize("default_margin").height + left: parent.left + leftMargin: parent.padding + right: parent.right + rightMargin: parent.padding + bottom: parent.bottom + } } } diff --git a/resources/qml/GlobalProfileButton.qml b/resources/qml/PrintSetupSelector/Custom/GlobalProfileSelector.qml similarity index 67% rename from resources/qml/GlobalProfileButton.qml rename to resources/qml/PrintSetupSelector/Custom/GlobalProfileSelector.qml index bac2732037..91525d0f9e 100644 --- a/resources/qml/GlobalProfileButton.qml +++ b/resources/qml/PrintSetupSelector/Custom/GlobalProfileSelector.qml @@ -9,24 +9,25 @@ import QtQuick.Layouts 1.2 import UM 1.2 as UM import Cura 1.0 as Cura -import "Menus" - Item { id: globalProfileRow - height: UM.Theme.getSize("print_setup_item").height + height: childrenRect.height Label { id: globalProfileLabel - text: catalog.i18nc("@label","Profile:") - textFormat: Text.PlainText - width: Math.round(parent.width * 0.45 - UM.Theme.getSize("thick_margin").width - 2) + anchors + { + top: parent.top + bottom: parent.bottom + left: parent.left + right: globalProfileSelection.left + } + text: catalog.i18nc("@label", "Profile") font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") verticalAlignment: Text.AlignVCenter - anchors.top: parent.top - anchors.bottom: parent.bottom } ToolButton @@ -34,20 +35,30 @@ Item id: globalProfileSelection text: generateActiveQualityText() - width: Math.round(parent.width * 0.55) - height: UM.Theme.getSize("setting_control").height - anchors.left: globalProfileLabel.right - anchors.right: parent.right + width: UM.Theme.getSize("print_setup_big_dropdown").width + height: UM.Theme.getSize("print_setup_big_dropdown").height + anchors + { + top: parent.top + right: parent.right + } tooltip: Cura.MachineManager.activeQualityOrQualityChangesName style: UM.Theme.styles.sidebar_header_button activeFocusOnPress: true - menu: ProfileMenu { } + menu: Cura.ProfileMenu { } - function generateActiveQualityText () { - var result = Cura.MachineManager.activeQualityOrQualityChangesName; + function generateActiveQualityText() + { + var result = Cura.MachineManager.activeQualityOrQualityChangesName + if (Cura.MachineManager.isActiveQualityExperimental) + { + result += " (Experimental)" + } - if (Cura.MachineManager.isActiveQualitySupported) { - if (Cura.MachineManager.activeQualityLayerHeight > 0) { + if (Cura.MachineManager.isActiveQualitySupported) + { + if (Cura.MachineManager.activeQualityLayerHeight > 0) + { result += " " result += " - " result += Cura.MachineManager.activeQualityLayerHeight + "mm" @@ -63,15 +74,15 @@ Item id: customisedSettings visible: Cura.MachineManager.hasUserSettings - height: Math.round(parent.height * 0.6) - width: Math.round(parent.height * 0.6) + width: UM.Theme.getSize("print_setup_icon").width + height: UM.Theme.getSize("print_setup_icon").height anchors.verticalCenter: parent.verticalCenter anchors.right: parent.right anchors.rightMargin: Math.round(UM.Theme.getSize("setting_preferences_button_margin").width - UM.Theme.getSize("thick_margin").width) color: hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button"); - iconSource: UM.Theme.getIcon("star"); + iconSource: UM.Theme.getIcon("star") onClicked: { @@ -81,7 +92,7 @@ Item onEntered: { var content = catalog.i18nc("@tooltip","Some setting/override values are different from the values stored in the profile.\n\nClick to open the profile manager.") - base.showTooltip(globalProfileRow, Qt.point(-UM.Theme.getSize("thick_margin").width, 0), content) + base.showTooltip(globalProfileRow, Qt.point(-UM.Theme.getSize("default_margin").width, 0), content) } onExited: base.hideTooltip() } diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector/PrintSetupSelector.qml index 5518ac6b60..f1b424f7f2 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelector.qml @@ -11,8 +11,6 @@ Cura.ExpandableComponent { id: printSetupSelector - property bool hideSettings: PrintInformation.preSliced - property string enabledText: catalog.i18nc("@label:Should be short", "On") property string disabledText: catalog.i18nc("@label:Should be short", "Off") diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml index cddf01a4dc..4963f10792 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml @@ -182,7 +182,7 @@ Item id: customisedSettings visible: Cura.SimpleModeSettingsManager.isProfileCustomized || Cura.SimpleModeSettingsManager.isProfileUserCreated - height: visible ? Math.round(0.8 * qualityRowTitle.height) : 0 + height: visible ? UM.Theme.getSize("print_setup_icon").height : 0 width: height anchors { @@ -203,7 +203,7 @@ Item onEntered: { var tooltipContent = catalog.i18nc("@tooltip","You have modified some profile settings. If you want to change these go to custom mode.") - base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), tooltipContent) + base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, 0), tooltipContent) } onExited: base.hideTooltip() } diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml index 25a5574a39..d367510ef6 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml @@ -76,7 +76,7 @@ Item { id: supportExtruderCombobox - height: UM.Theme.getSize("print_setup_support_extruder_selector").height + height: UM.Theme.getSize("print_setup_big_dropdown").height anchors { left: enableSupportCheckBox.right diff --git a/resources/qml/qmldir b/resources/qml/qmldir index c0a8bac0ae..4dc9a34894 100644 --- a/resources/qml/qmldir +++ b/resources/qml/qmldir @@ -15,4 +15,5 @@ ExpandableComponent 1.0 ExpandableComponent.qml PrinterTypeLabel 1.0 PrinterTypeLabel.qml ViewsSelector 1.0 ViewsSelector.qml ToolbarButton 1.0 ToolbarButton.qml -SettingView 1.0 SettingView.qml \ No newline at end of file +SettingView 1.0 SettingView.qml +ProfileMenu 1.0 ProfileMenu.qml \ No newline at end of file diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index 5203cb0b0b..e6144bb6ec 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -38,6 +38,7 @@ QtObject } } + radius: UM.Theme.getSize("setting_control_radius").width border.width: Theme.getSize("default_lining").width border.color: { @@ -489,11 +490,12 @@ QtObject UM.RecolorImage { id: swatch - height: Math.round(UM.Theme.getSize("setting_control").height / 2) + height: Math.round(control.height / 2) width: height anchors.right: downArrow.left anchors.verticalCenter: parent.verticalCenter - anchors.margins: Math.round(UM.Theme.getSize("default_margin").width / 4) + anchors.rightMargin: UM.Theme.getSize("default_margin").width +// anchors.margins: Math.round(UM.Theme.getSize("default_margin").width / 4) sourceSize.width: width sourceSize.height: height source: UM.Theme.getIcon("extruder_button") diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index afe40007f4..2c5c7a360a 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -377,7 +377,8 @@ "print_setup_slider_groove": [0.16, 0.16], "print_setup_slider_handle": [1.0, 1.0], "print_setup_slider_tickmarks": [0.32, 0.32], - "print_setup_support_extruder_selector": [18.2, 2.5], + "print_setup_big_dropdown": [28, 2.5], + "print_setup_icon": [1.2, 1.2], "configuration_selector_mode_tabs": [0.0, 3.0], From 8066074a2fbb71b3d124ad8966a3327298872ccb Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 3 Dec 2018 11:02:49 +0100 Subject: [PATCH 0589/1292] STAR-332: Fixing warnings --- .../NetworkedPrinterOutputDevice.py | 6 +- .../src/Cloud/CloudOutputDevice.py | 263 +++++++++--------- .../src/Cloud/CloudOutputDeviceManager.py | 2 +- .../UM3NetworkPrinting/src/Cloud/Models.py | 6 +- 4 files changed, 146 insertions(+), 131 deletions(-) diff --git a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py index 35d2ce014a..7125de4002 100644 --- a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py +++ b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py @@ -41,7 +41,8 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): self._api_prefix = "" self._address = address self._properties = properties - self._user_agent = "%s/%s " % (CuraApplication.getInstance().getApplicationName(), CuraApplication.getInstance().getVersion()) + self._user_agent = "%s/%s " % (CuraApplication.getInstance().getApplicationName(), + CuraApplication.getInstance().getVersion()) self._onFinishedCallbacks = {} # type: Dict[str, Callable[[QNetworkReply], None]] self._authentication_state = AuthState.NotAuthenticated @@ -55,7 +56,8 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): self._gcode = [] # type: List[str] self._connection_state_before_timeout = None # type: Optional[ConnectionState] - def requestWrite(self, nodes: List[SceneNode], file_name: Optional[str] = None, limit_mimetypes: bool = False, file_handler: Optional[FileHandler] = None, **kwargs: str) -> None: + def requestWrite(self, nodes: List[SceneNode], file_name: Optional[str] = None, limit_mimetypes: bool = False, + file_handler: Optional[FileHandler] = None, **kwargs: str) -> None: raise NotImplementedError("requestWrite needs to be implemented") def setAuthenticationState(self, authentication_state: AuthState) -> None: diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 5d2d140704..008633e198 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -3,20 +3,20 @@ import io import json import os -from typing import List, Optional, Dict, cast +from typing import List, Optional, Dict, cast, Union from PyQt5.QtCore import QObject, pyqtSignal, QUrl, pyqtProperty from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest from UM import i18nCatalog -from UM.FileHandler import FileWriter +from UM.FileHandler.FileWriter import FileWriter from UM.FileHandler.FileHandler import FileHandler from UM.Logger import Logger from UM.OutputDevice import OutputDeviceError from UM.Scene.SceneNode import SceneNode from UM.Version import Version from cura.CuraApplication import CuraApplication -from cura.PrinterOutput import PrinterOutputController, PrintJobOutputModel +from cura.PrinterOutput.PrinterOutputController import PrinterOutputController from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice, AuthState from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel @@ -38,7 +38,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # The cloud URL to use for this remote cluster. # TODO: Make sure that this url goes to the live api before release - ROOT_PATH= "https://api-staging.ultimaker.com" + ROOT_PATH = "https://api-staging.ultimaker.com" CLUSTER_API_ROOT = "{}/connect/v1/".format(ROOT_PATH) CURA_API_ROOT = "{}/cura/v1/".format(ROOT_PATH) CURA_DRIVE_API_ROOT = "{}/cura-drive/v1/".format(ROOT_PATH) @@ -66,10 +66,26 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self._printers = {} # type: Dict[str, PrinterOutputModel] self._print_jobs = {} # type: Dict[str, PrintJobOutputModel] self._number_of_extruders = 2 # All networked printers are dual-extrusion Ultimaker machines. - + + @staticmethod + def _parseReply(reply: QNetworkReply) -> Tuple[int, Union[None, str, bytes]]: + """ + Parses a reply from the stardust server. + :param reply: The reply received from the server. + :return: The status code and the response dict. + """ + status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) + response = None + try: + response = bytes(reply.readAll()).decode("utf-8") + response = json.loads(response) + except JSONDecodeError: + Logger.logException("w", "Unable to decode JSON from reply.") + return status_code, response + ## We need to override _createEmptyRequest to work for the cloud. def _createEmptyRequest(self, path: str, content_type: Optional[str] = "application/json") -> QNetworkRequest: - #url = QUrl(self.CLUSTER_API_ROOT_PATH_FORMAT.format(cluster_id = self._device_id) + path) + # noinspection PyArgumentList url = QUrl(path) request = QNetworkRequest(url) request.setHeader(QNetworkRequest.ContentTypeHeader, content_type) @@ -98,8 +114,9 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def requestWrite(self, nodes: List[SceneNode], file_name: Optional[str] = None, limit_mime_types: bool = False, file_handler: Optional[FileHandler] = None, **kwargs: str) -> None: self.writeStarted.emit(self) + file_format = self._determineFileFormat(file_handler) - writer = self._determineWriter(file_format) + writer = self._determineWriter(file_handler, file_format) # This function pauses with the yield, waiting on instructions on which printer it needs to print with. if not writer: @@ -123,7 +140,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self._addPrintJobToQueue(stream, request) # TODO: This is yanked right out of ClusterUM3OoutputDevice, great candidate for a utility or base class - def _determineFileFormat(self, file_handler) -> None: + def _determineFileFormat(self, file_handler) -> Optional[Dict[str, Union[str, int]]]: # Formats supported by this application (file types that we can actually write). if file_handler: file_formats = file_handler.getSupportedFileTypesWrite() @@ -143,21 +160,28 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): machine_file_formats = ["application/x-ufp"] + machine_file_formats # Take the intersection between file_formats and machine_file_formats. - format_by_mimetype = {format["mime_type"]: format for format in file_formats} - file_formats = [format_by_mimetype[mimetype] for mimetype in machine_file_formats] #Keep them ordered according to the preference in machine_file_formats. + format_by_mimetype = {f["mime_type"]: f for f in file_formats} + + # Keep them ordered according to the preference in machine_file_formats. + file_formats = [format_by_mimetype[mimetype] for mimetype in machine_file_formats] if len(file_formats) == 0: Logger.log("e", "There are no file formats available to write with!") - raise OutputDeviceError.WriteRequestFailedError(self.I18N_CATALOG.i18nc("@info:status", "There are no file formats available to write with!")) + raise OutputDeviceError.WriteRequestFailedError( + self.I18N_CATALOG.i18nc("@info:status", "There are no file formats available to write with!") + ) return file_formats[0] # TODO: This is yanked right out of ClusterUM3OoutputDevice, great candidate for a utility or base class - def _determineWriter(self, file_handler, file_format): + @staticmethod + def _determineWriter(file_handler, file_format) -> Optional[FileWriter]: # Just take the first file format available. if file_handler is not None: writer = file_handler.getWriterByMimeType(cast(str, file_format["mime_type"])) else: - writer = CuraApplication.getInstance().getMeshFileHandler().getWriterByMimeType(cast(str, file_format["mime_type"])) + writer = CuraApplication.getInstance().getMeshFileHandler().getWriterByMimeType( + cast(str, file_format["mime_type"]) + ) if not writer: Logger.log("e", "Unexpected error when trying to get the FileWriter") @@ -173,7 +197,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## Get remote print jobs. @pyqtProperty("QVariantList", notify = printJobsChanged) def queuedPrintJobs(self) -> List[UM3PrintJobOutputModel]: - return [print_job for print_job in self._print_jobs if print_job.state == "queued" or print_job.state == "error"] + return [print_job for print_job in self._print_jobs.values() + if print_job.state == "queued" or print_job.state == "error"] ## Called when the connection to the cluster changes. def connect(self) -> None: @@ -182,20 +207,19 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## Called when the network data should be updated. def _update(self) -> None: super()._update() - self.get("{root}/cluster/{cluster_id}/status".format(self.CLUSTER_API_ROOT, self._device_id), + self.get("{root}/cluster/{cluster_id}/status".format(root=self.CLUSTER_API_ROOT, cluster_id=self._device_id), on_finished = self._onStatusCallFinished) - ## Method called when HTTP request to status endpoint is finished. # Contains both printers and print jobs statuses in a single response. def _onStatusCallFinished(self, reply: QNetworkReply) -> None: - status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) - if status_code != 200: + status_code, response = self._parseReply(reply) + if status_code > 204: Logger.log("w", "Got unexpected response while trying to get cloud cluster data: {}, {}" - .format(status_code, reply.readAll())) + .format(status_code, status, response)) return - - printers, print_jobs = self._parseStatusResponse(reply) + + printers, print_jobs = self._parseStatusResponse(response) if not printers and not print_jobs: return @@ -204,79 +228,69 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self._updatePrintJobs(print_jobs) @staticmethod - def _parseStatusResponse(reply: QNetworkReply): # Optional[(CloudClusterPrinter, CloudClusterPrintJob)] doesn't work - + def _parseStatusResponse(response: dict) -> Optional[Tuple[CloudClusterPrinter, CloudClusterPrintJob]]: printers = [] print_jobs = [] - s = '' - try: - s = json.loads(bytes(reply.readAll()).decode("utf-8")) - for p in s["printers"]: - printer = CloudClusterPrinter(**p) - configuration = printer.configuration - printer.configuration = [] - for c in configuration: - extruder = CloudClusterPrinterConfiguration(**c) - extruder.material = CloudClusterPrinterConfigurationMaterial(extruder.material) - printer.configuration.append(extruder) + data = response["data"] + for p in data["printers"]: + printer = CloudClusterPrinter(**p) + configuration = printer.configuration + printer.configuration = [] + for c in configuration: + extruder = CloudClusterPrinterConfiguration(**c) + extruder.material = CloudClusterPrinterConfigurationMaterial(material=extruder.material) + printer.configuration.append(extruder) - printers.append(printer) + printers.append(printer) - for j in s["print_jobs"]: - job = CloudClusterPrintJob(**j) - constraints = job.constraints - job.constraints = [] - for c in constraints: - job.constraints.append(CloudClusterPrintJobConstraint(**c)) + for j in data["print_jobs"]: + job = CloudClusterPrintJob(**j) + constraints = job.constraints + job.constraints = [] + for c in constraints: + job.constraints.append(CloudClusterPrintJobConstraint(**c)) - configuration = job.configuration - job.configuration = [] - for c in configuration: - configuration = CloudClusterPrinterConfiguration(**c) - configuration.material = CloudClusterPrinterConfigurationMaterial(configuration.material) - job.configuration.append(configuration) + configuration = job.configuration + job.configuration = [] + for c in configuration: + configuration = CloudClusterPrinterConfiguration(**c) + configuration.material = CloudClusterPrinterConfigurationMaterial(material=configuration.material) + job.configuration.append(configuration) - print_jobs.append(job) - - except json.decoder.JSONDecodeError: - Logger.logException("w", "Unable to decode JSON from reply.") - return None + print_jobs.append(job) return printers, print_jobs def _updatePrinters(self, printers: List[CloudClusterPrinter]) -> None: - remote_printers = {p.uuid: p for p in printers} + remote_printers = {p.uuid: p for p in printers} # type: Dict[str, CloudClusterPrinter] - removed_printers = set(self._printers.keys()).difference(set(remote_printers.keys())) - new_printers = set(remote_printers.keys()).difference(set(self._printers.keys())) - updated_printers = set(self._printers.keys()).intersection(set(remote_printers.keys())) + removed_printer_ids = set(self._printers).difference(remote_printers) + new_printer_ids = set(remote_printers).difference(self._printers) + updated_printer_ids = set(self._printers).intersection(remote_printers) - for p in removed_printers: - self._removePrinter(p) + for printer_guid in removed_printer_ids: + self._removePrinter(printer_guid) - for p in new_printers: - self._addPrinter(printers[p]) - self._updatePrinter(printers[p]) + for printer_guid in new_printer_ids: + self._addPrinter(remote_printers[printer_guid]) + self._updatePrinter(remote_printers[printer_guid]) - for p in updated_printers: - self._updatePrinter(printers[p]) + for printer_guid in updated_printer_ids: + self._updatePrinter(remote_printers[printer_guid]) # TODO: properly handle removed and updated printers self.printersChanged.emit() - - def _addPrinter(self, printer): - self._printers[printer.uuid] = self._createPrinterOutputModel(self, printer) + def _addPrinter(self, printer: CloudClusterPrinter) -> None: + self._printers[printer.uuid] = self._createPrinterOutputModel(printer) def _createPrinterOutputModel(self, printer: CloudClusterPrinter) -> PrinterOutputModel: return PrinterOutputModel(PrinterOutputController(self), len(printer.configuration), firmware_version=printer.firmware_version) - def _updatePrinter(self, guid : str, printer : CloudClusterPrinter): - self._printers[guid] = self._updatePrinterOutputModel(self, printer) - - def _updatePrinterOutputModel(self, printer: CloudClusterPrinter, model : PrinterOutputModel) -> PrinterOutputModel: + def _updatePrinter(self, printer: CloudClusterPrinter) -> None: + model = self._printers[printer.uuid] model.updateKey(printer.uuid) model.updateName(printer.friendly_name) model.updateType(printer.machine_variant) @@ -291,43 +305,42 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): extruder.updateHotendID(extruder_data.print_core_id) - material_data = extruder_data.material - if extruder.activeMaterial is None or extruder.activeMaterial.guid != material.guid: - material = self._createMaterialOutputModel(material_data) + if extruder.activeMaterial is None or extruder.activeMaterial.guid != extruder_data.material.guid: + material = self._createMaterialOutputModel(extruder_data.material) extruder.updateActiveMaterial(material) - def _createMaterialOutputModel(self, material: CloudClusterPrinterConfigurationMaterial) -> MaterialOutputModel: - material_manager = CuraApplication.getInstance().getMaterialManager() - material_group_list = material_manager.getMaterialGroupListByGUID(material.guid) or [] + @staticmethod + def _createMaterialOutputModel(material: CloudClusterPrinterConfigurationMaterial) -> MaterialOutputModel: + material_manager = CuraApplication.getInstance().getMaterialManager() + material_group_list = material_manager.getMaterialGroupListByGUID(material.guid) or [] - # Sort the material groups by "is_read_only = True" first, and then the name alphabetically. - read_only_material_group_list = list(filter(lambda x: x.is_read_only, material_group_list)) - non_read_only_material_group_list = list(filter(lambda x: not x.is_read_only, material_group_list)) - material_group = None - if read_only_material_group_list: - read_only_material_group_list = sorted(read_only_material_group_list, key=lambda x: x.name) - material_group = read_only_material_group_list[0] - elif non_read_only_material_group_list: - non_read_only_material_group_list = sorted(non_read_only_material_group_list, key=lambda x: x.name) - material_group = non_read_only_material_group_list[0] + # Sort the material groups by "is_read_only = True" first, and then the name alphabetically. + read_only_material_group_list = list(filter(lambda x: x.is_read_only, material_group_list)) + non_read_only_material_group_list = list(filter(lambda x: not x.is_read_only, material_group_list)) + material_group = None + if read_only_material_group_list: + read_only_material_group_list = sorted(read_only_material_group_list, key=lambda x: x.name) + material_group = read_only_material_group_list[0] + elif non_read_only_material_group_list: + non_read_only_material_group_list = sorted(non_read_only_material_group_list, key=lambda x: x.name) + material_group = non_read_only_material_group_list[0] - if material_group: - container = material_group.root_material_node.getContainer() - color = container.getMetaDataEntry("color_code") - brand = container.getMetaDataEntry("brand") - material_type = container.getMetaDataEntry("material") - name = container.getName() - else: - Logger.log("w", - "Unable to find material with guid {guid}. Using data as provided by cluster".format( - guid=material.guid)) - color = material.color - brand = material.brand - material_type = material.material - name = "Empty" if material.material == "empty" else "Unknown" - - return MaterialOutputModel(guid=material.guid, type=material_type, brand=brand, color=color, name=name) + if material_group: + container = material_group.root_material_node.getContainer() + color = container.getMetaDataEntry("color_code") + brand = container.getMetaDataEntry("brand") + material_type = container.getMetaDataEntry("material") + name = container.getName() + else: + Logger.log("w", + "Unable to find material with guid {guid}. Using data as provided by cluster".format( + guid=material.guid)) + color = material.color + brand = material.brand + material_type = material.material + name = "Empty" if material.material == "empty" else "Unknown" + return MaterialOutputModel(guid=material.guid, type=material_type, brand=brand, color=color, name=name) def _removePrinter(self, guid): del self._printers[guid] @@ -346,53 +359,51 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self._addPrintJob(jobs[j]) for j in updated_jobs: - self._updatePrintJob(jobs[j]) + self._updatePrintJob(remote_jobs[j]) # TODO: properly handle removed and updated printers self.printJobsChanged() - def _addPrintJob(self, job: CloudClusterPrintJob): + def _addPrintJob(self, job: CloudClusterPrintJob) -> None: self._print_jobs[job.uuid] = self._createPrintJobOutputModel(job) - def _createPrintJobOutputModel(self, job:CloudClusterPrintJob) -> PrintJobOutputModel: + def _createPrintJobOutputModel(self, job: CloudClusterPrintJob) -> PrintJobOutputModel: controller = self._printers[job.printer_uuid]._controller # TODO: Can we access this property? model = PrintJobOutputModel(controller, job.uuid, job.name) assigned_printer = self._printes[job.printer_uuid] # TODO: Or do we have to use the assigned_to field? model.updateAssignedPrinter(assigned_printer) + return model - def _updatePrintJobOutputModel(self, guid: str, job:CloudClusterPrintJob): - model =self._print_jobs[guid] + def _updatePrintJobOutputModel(self, guid: str, job: CloudClusterPrintJob) -> None: + model = self._print_jobs[guid] model.updateTimeTotal(job.time_total) model.updateTimeElapsed(job.time_elapsed) model.updateOwner(job.owner) model.updateState(job.status) - def _removePrintJob(self, guid:str): + def _removePrintJob(self, guid: str): del self._print_jobs[guid] - def _addPrintJobToQueue(self, stream, request:JobUploadRequest): + def _addPrintJobToQueue(self, stream, request: JobUploadRequest): self.put("{}/jobs/upload".format(self.CURA_API_ROOT), data = json.dumps(request.__dict__), on_finished = lambda reply: self._onAddPrintJobToQueueFinished(stream, reply)) def _onAddPrintJobToQueueFinished(self, stream, reply: QNetworkReply) -> None: - s = json.loads(bytes(reply.readAll()).decode("utf-8")) + status_code, response = self._parseReply(reply) # type: Tuple[int, dict] + if status_code > 204 or not isinstance(dict, response) or "data" not in response: + Logger.error() + return - self.put() + job_response = JobUploadResponse(**response.get("data")) + self.put(job_response.upload_url, data=stream.getvalue(), on_finished=self._onPrintJobUploaded) - # try: - # r = requests.put(self._job.output_url, data=data) - # if r.status_code == 200: - # Logger.log("d", "Finished writing %s to remote URL %s", "", self._job.output_url) - # self.onWriteSuccess.emit(r.text) - # else: - # Logger.log("d", "Error writing %s to remote URL %s", "", self._job.output_url) - # self.onWriteFailed.emit("Failed to export G-code to remote URL: {}".format(r.text)) - # except requests.ConnectionError as e: - # Logger.log("e", "There was a connection error when uploading the G-code to a remote URL: %s", e) - # self.onWriteFailed.emit("Failed to export G-code to remote URL: {}".format(e)) - # except requests.HTTPError as e: - # Logger.log("e", "There was an HTTP error when uploading the G-code to a remote URL: %s", e) - # self.onWriteFailed.emit("Failed to export G-code to remote URL: {}".format(e)) + def _onPrintJobUploaded(self, reply: QNetworkReply) -> None: + status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) + if status_code > 204: + self.onWriteFailed.emit("Failed to export G-code to remote URL: {}".format(r.text)) + Logger.logException("w", "Received unexpected response from the job upload: %s, %s.", status_code, + bytes(reply.readAll()).decode()) + return - pass \ No newline at end of file + self.onWriteSuccess.emit(r.text) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index f6542e3c76..421f24bc25 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -3,7 +3,7 @@ import json from time import sleep from threading import Thread -from typing import Dict, Optional, List +from typing import Dict, Optional from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models.py b/plugins/UM3NetworkPrinting/src/Cloud/Models.py index 86a48fb1f2..5363f49c00 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models.py @@ -1,5 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +from typing import List + from ..Models import BaseModel @@ -41,7 +43,7 @@ class CloudClusterPrinterConfiguration(BaseModel): ## Class representing a cluster printer class CloudClusterPrinter(BaseModel): def __init__(self, **kwargs): - self.configuration = None # type: CloudClusterPrinterConfiguration + self.configuration = None # type: List[CloudClusterPrinterConfiguration] self.enabled = None # type: str self.firmware_version = None # type: str self.friendly_name = None # type: str @@ -56,7 +58,7 @@ class CloudClusterPrinter(BaseModel): ## Class representing a cloud cluster print job constraint class CloudClusterPrintJobConstraint(BaseModel): def __init__(self, **kwargs): - self.require_printer_name: None # type: str + self.require_printer_name = None # type: str super().__init__(**kwargs) ## Class representing a print job From f3af5a72ad7b29f3e27197cff85c43bcff0519fd Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 3 Dec 2018 11:13:26 +0100 Subject: [PATCH 0590/1292] Use ListModel.count instead of rowCount The .count property properly updates when the model is changed. Contributes to issue CURA-5876. --- cura/Settings/ExtrudersModel.py | 2 +- cura/Settings/MachineManager.py | 2 +- .../MachineSettingsAction.qml | 4 ++-- resources/qml/Dialogs/AddMachineDialog.qml | 2 +- .../ConfigurationMenu/ConfigurationMenu.qml | 2 +- resources/qml/Menus/ProfileMenu.qml | 8 +++---- resources/qml/Preferences/MachinesPage.qml | 8 ++++--- .../Preferences/Materials/MaterialsList.qml | 8 +++---- resources/qml/Preferences/ProfilesPage.qml | 24 ++++++++++++------- .../qml/Preferences/SettingVisibilityPage.qml | 2 +- .../qml/Settings/SettingOptionalExtruder.qml | 13 ++++++---- resources/qml/SidebarSimple.qml | 6 ++--- resources/qml/Toolbar.qml | 2 +- resources/qml/ViewsSelector.qml | 2 +- 14 files changed, 49 insertions(+), 36 deletions(-) diff --git a/cura/Settings/ExtrudersModel.py b/cura/Settings/ExtrudersModel.py index 955bd9dbb2..5f10ac99d4 100644 --- a/cura/Settings/ExtrudersModel.py +++ b/cura/Settings/ExtrudersModel.py @@ -165,7 +165,7 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): def __updateExtruders(self): extruders_changed = False - if self.rowCount() != 0: + if self.count != 0: extruders_changed = True items = [] diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index be4a4e2b4e..7e1a06f45c 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1540,7 +1540,7 @@ class MachineManager(QObject): elif word.isdigit(): abbr_machine += word else: - stripped_word = ''.join(char for char in unicodedata.normalize('NFD', word.upper()) if unicodedata.category(char) != 'Mn') + stripped_word = "".join(char for char in unicodedata.normalize("NFD", word.upper()) if unicodedata.category(char) != "Mn") # - use only the first character if the word is too long (> 3 characters) # - use the whole word if it's not too long (<= 3 characters) if len(stripped_word) > 3: diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index 004b4e3cfc..c88a721a84 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -1,4 +1,4 @@ -// Copyright (c) 2016 Ultimaker B.V. +// Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 @@ -23,7 +23,7 @@ Cura.MachineAction target: base.extrudersModel onModelChanged: { - var extruderCount = base.extrudersModel.rowCount(); + var extruderCount = base.extrudersModel.count; base.extruderTabsCount = extruderCount; } } diff --git a/resources/qml/Dialogs/AddMachineDialog.qml b/resources/qml/Dialogs/AddMachineDialog.qml index 8b2b9d1868..bcf5807949 100644 --- a/resources/qml/Dialogs/AddMachineDialog.qml +++ b/resources/qml/Dialogs/AddMachineDialog.qml @@ -170,7 +170,7 @@ UM.Dialog if (machineList.model.getItem(machineList.currentIndex).section != section) { // Find the first machine from this section - for(var i = 0; i < machineList.model.rowCount(); i++) + for(var i = 0; i < machineList.model.count; i++) { var item = machineList.model.getItem(i); if (item.section == section) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index 202bc22ce0..9927ad1498 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -44,7 +44,7 @@ Cura.ExpandableComponent delegate: Item { height: parent.height - width: Math.round(ListView.view.width / extrudersModel.rowCount()) + width: Math.round(ListView.view.width / extrudersModel.count) // Extruder icon. Shows extruder index and has the same color as the active material. Cura.ExtruderIcon diff --git a/resources/qml/Menus/ProfileMenu.qml b/resources/qml/Menus/ProfileMenu.qml index ffd3c556b6..e09b7930a8 100644 --- a/resources/qml/Menus/ProfileMenu.qml +++ b/resources/qml/Menus/ProfileMenu.qml @@ -34,7 +34,7 @@ Menu MenuSeparator { id: customSeparator - visible: Cura.CustomQualityProfilesDropDownMenuModel.rowCount > 0 + visible: Cura.CustomQualityProfilesDropDownMenuModel.count > 0 } Instantiator @@ -45,7 +45,7 @@ Menu Connections { target: Cura.CustomQualityProfilesDropDownMenuModel - onModelReset: customSeparator.visible = Cura.CustomQualityProfilesDropDownMenuModel.rowCount() > 0 + onModelReset: customSeparator.visible = Cura.CustomQualityProfilesDropDownMenuModel.count > 0 } MenuItem @@ -59,12 +59,12 @@ Menu onObjectAdded: { - customSeparator.visible = model.rowCount() > 0; + customSeparator.visible = model.count > 0; menu.insertItem(index, object); } onObjectRemoved: { - customSeparator.visible = model.rowCount() > 0; + customSeparator.visible = model.count > 0; menu.removeItem(object); } } diff --git a/resources/qml/Preferences/MachinesPage.qml b/resources/qml/Preferences/MachinesPage.qml index 4dc5465dc6..bc75b9bc72 100644 --- a/resources/qml/Preferences/MachinesPage.qml +++ b/resources/qml/Preferences/MachinesPage.qml @@ -21,8 +21,10 @@ UM.ManagementPage function activeMachineIndex() { - for(var i = 0; i < model.rowCount(); i++) { - if (model.getItem(i).id == Cura.MachineManager.activeMachineId) { + for(var i = 0; i < model.count; i++) + { + if (model.getItem(i).id == Cura.MachineManager.activeMachineId) + { return i; } } @@ -47,7 +49,7 @@ UM.ManagementPage { text: catalog.i18nc("@action:button", "Remove"); iconName: "list-remove"; - enabled: base.currentItem != null && model.rowCount() > 1 + enabled: base.currentItem != null && model.count > 1 onClicked: confirmDialog.open(); }, Button diff --git a/resources/qml/Preferences/Materials/MaterialsList.qml b/resources/qml/Preferences/Materials/MaterialsList.qml index 00bead9650..61f92db84c 100644 --- a/resources/qml/Preferences/Materials/MaterialsList.qml +++ b/resources/qml/Preferences/Materials/MaterialsList.qml @@ -57,7 +57,7 @@ Item var currentItemId = base.currentItem == null ? "" : base.currentItem.root_material_id search_root_id = currentItemId } - for (var material_idx = 0; material_idx < genericMaterialsModel.rowCount(); material_idx++) + for (var material_idx = 0; material_idx < genericMaterialsModel.count; material_idx++) { var material = genericMaterialsModel.getItem(material_idx) if (material.root_material_id == search_root_id) @@ -72,15 +72,15 @@ Item return true } } - for (var brand_idx = 0; brand_idx < materialsModel.rowCount(); brand_idx++) + for (var brand_idx = 0; brand_idx < materialsModel.count; brand_idx++) { var brand = materialsModel.getItem(brand_idx) var types_model = brand.material_types - for (var type_idx = 0; type_idx < types_model.rowCount(); type_idx++) + for (var type_idx = 0; type_idx < types_model.count; type_idx++) { var type = types_model.getItem(type_idx) var colors_model = type.colors - for (var material_idx = 0; material_idx < colors_model.rowCount(); material_idx++) + for (var material_idx = 0; material_idx < colors_model.count; material_idx++) { var material = colors_model.getItem(material_idx) if (material.root_material_id == search_root_id) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index ba0c2848a5..d7ffbb3152 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -188,21 +188,27 @@ Item Connections { target: qualitiesModel - onItemsChanged: { + onItemsChanged: + { var toSelectItemName = base.currentItem == null ? "" : base.currentItem.name; - if (newQualityNameToSelect != "") { + if (newQualityNameToSelect != "") + { toSelectItemName = newQualityNameToSelect; } var newIdx = -1; // Default to nothing if nothing can be found - if (toSelectItemName != "") { + if (toSelectItemName != "") + { // Select the required quality name if given - for (var idx = 0; idx < qualitiesModel.rowCount(); ++idx) { + for (var idx = 0; idx < qualitiesModel.count; ++idx) + { var item = qualitiesModel.getItem(idx); - if (item.name == toSelectItemName) { + if (item.name == toSelectItemName) + { // Switch to the newly created profile if needed newIdx = idx; - if (base.toActivateNewQuality) { + if (base.toActivateNewQuality) + { // Activate this custom quality if required Cura.MachineManager.setQualityChangesGroup(item.quality_changes_group); } @@ -382,9 +388,11 @@ Item var selectedItemName = Cura.MachineManager.activeQualityOrQualityChangesName; // Select the required quality name if given - for (var idx = 0; idx < qualitiesModel.rowCount(); idx++) { + for (var idx = 0; idx < qualitiesModel.count; idx++) + { var item = qualitiesModel.getItem(idx); - if (item.name == selectedItemName) { + if (item.name == selectedItemName) + { currentIndex = idx; break; } diff --git a/resources/qml/Preferences/SettingVisibilityPage.qml b/resources/qml/Preferences/SettingVisibilityPage.qml index 8896d0611e..bb47301b69 100644 --- a/resources/qml/Preferences/SettingVisibilityPage.qml +++ b/resources/qml/Preferences/SettingVisibilityPage.qml @@ -54,7 +54,7 @@ UM.PreferencesPage { return Qt.Unchecked } - else if(definitionsModel.visibleCount == definitionsModel.rowCount(null)) + else if(definitionsModel.visibleCount == definitionsModel.count) { return Qt.Checked } diff --git a/resources/qml/Settings/SettingOptionalExtruder.qml b/resources/qml/Settings/SettingOptionalExtruder.qml index a3c1422b30..5f0d8327f8 100644 --- a/resources/qml/Settings/SettingOptionalExtruder.qml +++ b/resources/qml/Settings/SettingOptionalExtruder.qml @@ -1,5 +1,5 @@ -// Copyright (c) 2016 Ultimaker B.V. -// Uranium is released under the terms of the LGPLv3 or higher. +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 import QtQuick.Controls 2.0 @@ -31,12 +31,15 @@ SettingItem { forceActiveFocus(); propertyProvider.setPropertyValue("value", model.getItem(index).index); - } else + } + else { if (propertyProvider.properties.value == -1) { - control.currentIndex = model.rowCount() - 1; // we know the last item is "Not overriden" - } else { + control.currentIndex = model.count - 1; // we know the last item is "Not overriden" + } + else + { control.currentIndex = propertyProvider.properties.value; // revert to the old value } } diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index 5e723a3d70..e07810691e 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -106,7 +106,7 @@ Item var availableMin = -1 var availableMax = -1 - for (var i = 0; i < Cura.QualityProfilesDropDownMenuModel.rowCount(); i++) + for (var i = 0; i < Cura.QualityProfilesDropDownMenuModel.count; i++) { var qualityItem = Cura.QualityProfilesDropDownMenuModel.getItem(i) @@ -183,7 +183,7 @@ Item qualityModel.existingQualityProfile = 0 // check, the ticks count cannot be less than zero - qualityModel.totalTicks = Math.max(0, Cura.QualityProfilesDropDownMenuModel.rowCount() - 1) + qualityModel.totalTicks = Math.max(0, Cura.QualityProfilesDropDownMenuModel.count - 1) } } @@ -1156,7 +1156,7 @@ Item function populateExtruderModel() { extruderModel.clear(); - for(var extruderNumber = 0; extruderNumber < extruders.rowCount() ; extruderNumber++) + for(var extruderNumber = 0; extruderNumber < extruders.count; extruderNumber++) { extruderModel.append({ text: extruders.getItem(extruderNumber).name, diff --git a/resources/qml/Toolbar.qml b/resources/qml/Toolbar.qml index 0240aaab26..4e00bd7248 100644 --- a/resources/qml/Toolbar.qml +++ b/resources/qml/Toolbar.qml @@ -65,7 +65,7 @@ Item style: UM.Theme.styles.toolbar_button property bool isFirstElement: toolsModel.getItem(0).id == model.id - property bool isLastElement: toolsModel.getItem(toolsModel.rowCount() - 1).id == model.id + property bool isLastElement: toolsModel.getItem(toolsModel.count - 1).id == model.id onCheckedChanged: { diff --git a/resources/qml/ViewsSelector.qml b/resources/qml/ViewsSelector.qml index e9fdd57177..e239ea82a0 100644 --- a/resources/qml/ViewsSelector.qml +++ b/resources/qml/ViewsSelector.qml @@ -19,7 +19,7 @@ Cura.ExpandableComponent property var activeView: { - for (var i = 0; i < viewModel.rowCount(); i++) + for (var i = 0; i < viewModel.count; i++) { if (viewModel.items[i].active) { From 6012ea0b9edf78369bec7abc463869f226e26b23 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 3 Dec 2018 11:15:11 +0100 Subject: [PATCH 0591/1292] Don't use QtQuick imports from Qt 5.11 Our build system uses 5.10. Contributes to issue CURA-5876. --- resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml | 2 +- resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index c40eb5b9e9..32be97f74e 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -2,7 +2,7 @@ // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 -import QtQuick.Controls 2.4 +import QtQuick.Controls 2.3 import UM 1.2 as UM import Cura 1.0 as Cura diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index 9927ad1498..816ac27470 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -4,7 +4,6 @@ import QtQuick 2.7 import QtQuick.Controls 2.0 import QtQuick.Controls.Styles 1.4 -import QtQuick.Layouts 1.11 import UM 1.2 as UM import Cura 1.0 as Cura From af747ae09c254327dd5d85e90a2cea86cc5d5562 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 3 Dec 2018 11:19:25 +0100 Subject: [PATCH 0592/1292] Don't hide tab bar when disabling all but one extruder And make sure the checkbox for enabling also disappears. We don't want to make this dependent on the number of enabled extruders, but on the total number of extruders. This way you can actually re-enable an extruder again because the tab bar shouldn't disappear. Contributes to issue CURA-5876. --- resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index eae160b48a..7ff47ea16f 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -40,7 +40,7 @@ Item id: tabBar anchors.top: header.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height - visible: Cura.MachineManager.numberExtrudersEnabled > 1 + visible: extrudersModel.count > 1 currentIndex: Math.max(Cura.ExtruderManager.activeExtruderIndex, 0) @@ -138,6 +138,7 @@ Item color: UM.Theme.getColor("text") height: parent.height width: selectors.textWidth + visible: extrudersModel.count > 1 } OldControls.CheckBox @@ -146,6 +147,7 @@ Item enabled: !checked || Cura.MachineManager.numberExtrudersEnabled > 1 //Disable if it's the last enabled extruder. height: UM.Theme.getSize("setting_control").height style: UM.Theme.styles.checkbox + visible: extrudersModel.count > 1 /* Use a MouseArea to process the click on this checkbox. This is necessary because actually clicking the checkbox From 39411222da20db6a39f1341e6d42c9610c88c85a Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 3 Dec 2018 11:37:22 +0100 Subject: [PATCH 0593/1292] Use normal font size for Auto slicing... message It should've been the normal font size anyway. This is not small! Contributes to issue CURA-5876. --- resources/qml/ActionPanel/SliceProcessWidget.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index cae598fea6..dee099bc88 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -48,7 +48,7 @@ Column text: catalog.i18nc("@label:PrintjobStatus", "Auto slicing...") color: UM.Theme.getColor("text") - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") renderType: Text.NativeRendering } From c8cb3a094a216eac21b139ba6577541ea53046d1 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 3 Dec 2018 11:52:10 +0100 Subject: [PATCH 0594/1292] Re-use SecondaryButton instead of setting colours ourselves It has a pre-defined theme. Contributes to issue CURA-5876. --- .../Menus/ConfigurationMenu/ConfigurationMenu.qml | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index 816ac27470..fc8b31f125 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -147,7 +147,7 @@ Cura.ExpandableComponent width: parent.width height: childrenRect.height - Cura.ActionButton + Cura.SecondaryButton { id: goToCustom visible: popupItem.configuration_method === "auto" @@ -159,18 +159,13 @@ Cura.ExpandableComponent top: parent.top } - color: UM.Theme.getColor("secondary") - hoverColor: UM.Theme.getColor("secondary") - textColor: UM.Theme.getColor("primary") - textHoverColor: UM.Theme.getColor("text") - iconSource: UM.Theme.getIcon("arrow_right") iconOnRightSide: true onClicked: popupItem.configuration_method = "custom" } - Cura.ActionButton + Cura.SecondaryButton { id: goToAuto visible: popupItem.configuration_method === "custom" @@ -182,11 +177,6 @@ Cura.ExpandableComponent top: parent.top } - color: UM.Theme.getColor("secondary") - hoverColor: UM.Theme.getColor("secondary") - textColor: UM.Theme.getColor("primary") - textHoverColor: UM.Theme.getColor("text") - iconSource: UM.Theme.getIcon("arrow_left") onClicked: popupItem.configuration_method = "auto" From 65d3aa44802c740d06c19ebbc58a2e9f2732ee80 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 3 Dec 2018 11:59:03 +0100 Subject: [PATCH 0595/1292] Fix broken sizes due to merged theme entry Merge conflict went wrong, I think. Contributes to issue CURA-5876. --- resources/qml/ActionPanel/OutputProcessWidget.qml | 2 +- resources/qml/ActionPanel/SliceProcessWidget.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/ActionPanel/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml index 3a85a13810..8ce5d13f17 100644 --- a/resources/qml/ActionPanel/OutputProcessWidget.qml +++ b/resources/qml/ActionPanel/OutputProcessWidget.qml @@ -111,7 +111,7 @@ Column { id: previewStageShortcut - height: UM.Theme.getSize("action_panel_button").height + height: UM.Theme.getSize("action_button").height text: catalog.i18nc("@button", "Preview") onClicked: UM.Controller.setActiveStage("PreviewStage") diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index dee099bc88..1143bb4c1a 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -101,7 +101,7 @@ Column // Disable the slice process when width: parent.width - height: UM.Theme.getSize("action_panel_button").height + height: UM.Theme.getSize("action_button").height visible: !autoSlice Cura.PrimaryButton { From 665e2d3060be1392695a89652e19015cd01c036a Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 3 Dec 2018 12:15:25 +0100 Subject: [PATCH 0596/1292] Move isActive and timeRemaining logic from QML to Python Contributes to CL-1153 --- cura/PrinterOutput/PrintJobOutputModel.py | 24 +++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/cura/PrinterOutput/PrintJobOutputModel.py b/cura/PrinterOutput/PrintJobOutputModel.py index 25b168e6fd..c3e6b7d267 100644 --- a/cura/PrinterOutput/PrintJobOutputModel.py +++ b/cura/PrinterOutput/PrintJobOutputModel.py @@ -125,10 +125,34 @@ class PrintJobOutputModel(QObject): def timeElapsed(self): return self._time_elapsed + @pyqtProperty(int, notify = timeElapsedChanged) + def timeRemaining(self) -> int: + # Never get a negative time remaining + return max(self.timeTotal - self.timeElapsed, 0) + + @pyqtProperty(float, notify = timeElapsedChanged) + def progress(self) -> float: + result = self.timeElapsed / self.timeTotal + if result > 1.0: + result = 1.0 + return result + @pyqtProperty(str, notify=stateChanged) def state(self): return self._state + @pyqtProperty(bool, notify=stateChanged) + def isActive(self) -> bool: + inactiveStates = [ + "pausing", + "paused", + "resuming", + "wait_cleanup" + ] + if self.state in inactiveStates and self.timeRemaining > 0: + return False + return True + def updateTimeTotal(self, new_time_total): if self._time_total != new_time_total: self._time_total = new_time_total From 3d80e281743a34681fbb643239253dbab852d598 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 3 Dec 2018 12:15:38 +0100 Subject: [PATCH 0597/1292] Add some typings Contributes to CL-1153 --- cura/PrinterOutput/PrintJobOutputModel.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cura/PrinterOutput/PrintJobOutputModel.py b/cura/PrinterOutput/PrintJobOutputModel.py index c3e6b7d267..604fd8e0b8 100644 --- a/cura/PrinterOutput/PrintJobOutputModel.py +++ b/cura/PrinterOutput/PrintJobOutputModel.py @@ -118,11 +118,11 @@ class PrintJobOutputModel(QObject): self.nameChanged.emit() @pyqtProperty(int, notify = timeTotalChanged) - def timeTotal(self): + def timeTotal(self) -> int: return self._time_total @pyqtProperty(int, notify = timeElapsedChanged) - def timeElapsed(self): + def timeElapsed(self) -> int: return self._time_elapsed @pyqtProperty(int, notify = timeElapsedChanged) @@ -138,7 +138,7 @@ class PrintJobOutputModel(QObject): return result @pyqtProperty(str, notify=stateChanged) - def state(self): + def state(self) -> str: return self._state @pyqtProperty(bool, notify=stateChanged) From a28cae0a43ff5e6e3c8e4a5912f0935e7978b2de Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 3 Dec 2018 12:18:33 +0100 Subject: [PATCH 0598/1292] Improve date rendering - Use "Mon Dec 3 at 12:39" if 7 days or more away. - Use "Mon at 12:39" if within 7 days but more than one away. - Use "tomorrow at 12:39" if one day away. - Use "today at 12:39" if today. Contributes to CL-1153 --- .../src/ClusterUM3OutputDevice.py | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index 3b124faf66..292011929d 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -386,8 +386,24 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): @pyqtSlot(int, result = str) def getDateCompleted(self, time_remaining: int) -> str: current_time = time() - datetime_completed = datetime.fromtimestamp(current_time + time_remaining) - return (datetime_completed.strftime("%a %b ") + "{day}".format(day=datetime_completed.day)).upper() + completed = datetime.fromtimestamp(current_time + time_remaining) + today = datetime.fromtimestamp(current_time) + + # If finishing date is more than 7 days out, using "Mon Dec 3 at HH:MM" format + if completed.toordinal() > today.toordinal() + 7: + return completed.strftime("%a %b ") + "{day}".format(day=completed.day) + + # If finishing date is within the next week, use "Monday at HH:MM" format + elif completed.toordinal() > today.toordinal() + 1: + return completed.strftime("%a") + + # If finishing tomorrow, use "tomorrow at HH:MM" format + elif completed.toordinal() > today.toordinal(): + return "tomorrow" + + # If finishing today, use "today at HH:MM" format + else: + return "today" @pyqtSlot(str) def sendJobToTop(self, print_job_uuid: str) -> None: From 4c468831f06fcc33de6b657985aed22907c2796c Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 3 Dec 2018 13:58:13 +0100 Subject: [PATCH 0599/1292] Add tabs for select the extruder in the custom print setup. Align some elements beneath the tabs. Contributes to CURA-5941. --- .../Custom/CustomPrintSetup.qml | 63 +++++- .../Custom/GlobalProfileSelector.qml | 4 +- .../Recommended/RecommendedPrintSetup.qml | 9 + .../RecommendedSupportSelector.qml | 11 +- resources/qml/Settings/SettingView.qml | 186 +++++++++--------- resources/themes/cura-light/styles.qml | 2 +- resources/themes/cura-light/theme.json | 4 +- 7 files changed, 164 insertions(+), 115 deletions(-) diff --git a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml index e0f0827b17..ae31976a34 100644 --- a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml +++ b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml @@ -13,9 +13,15 @@ Item id: customPrintSetup // TODO: Hardcoded now but UX has to decide about the height of this item - height: 500 + height: 480 property real padding: UM.Theme.getSize("default_margin").width + property bool multipleExtruders: extrudersModel.count > 1 + + Cura.ExtrudersModel + { + id: extrudersModel + } // Profile selector row GlobalProfileSelector @@ -32,11 +38,64 @@ Item } } + UM.TabRow + { + id: tabBar + + visible: multipleExtruders // The tab row is only visible when there are more than 1 extruder + + anchors + { + top: globalProfileRow.bottom + topMargin: UM.Theme.getSize("default_margin").height + left: parent.left + leftMargin: parent.padding + right: parent.right + rightMargin: parent.padding + } + + currentIndex: Math.max(Cura.ExtruderManager.activeExtruderIndex, 0) + + Repeater + { + id: repeater + model: extrudersModel + delegate: UM.TabRowButton + { + contentItem: Item + { + Cura.ExtruderIcon + { + anchors.horizontalCenter: parent.horizontalCenter + materialColor: model.color + extruderEnabled: model.enabled + } + } + onClicked: + { + Cura.ExtruderManager.setActiveExtruderIndex(tabBar.currentIndex) + } + } + } + + // When the model of the extruders is rebuilt, the list of extruders is briefly emptied and rebuilt. + // This causes the currentIndex of the tab to be in an invalid position which resets it to 0. + // Therefore we need to change it back to what it was: The active extruder index. + Connections + { + target: repeater.model + onModelChanged: + { + tabBar.currentIndex = Math.max(Cura.ExtruderManager.activeExtruderIndex, 0) + } + } + } + Cura.SettingView { anchors { - top: globalProfileRow.bottom + top: tabBar.visible ? tabBar.bottom : globalProfileRow.bottom topMargin: UM.Theme.getSize("default_margin").height left: parent.left leftMargin: parent.padding diff --git a/resources/qml/PrintSetupSelector/Custom/GlobalProfileSelector.qml b/resources/qml/PrintSetupSelector/Custom/GlobalProfileSelector.qml index 91525d0f9e..11b2d3608b 100644 --- a/resources/qml/PrintSetupSelector/Custom/GlobalProfileSelector.qml +++ b/resources/qml/PrintSetupSelector/Custom/GlobalProfileSelector.qml @@ -35,8 +35,8 @@ Item id: globalProfileSelection text: generateActiveQualityText() - width: UM.Theme.getSize("print_setup_big_dropdown").width - height: UM.Theme.getSize("print_setup_big_dropdown").height + width: UM.Theme.getSize("print_setup_big_item").width + height: UM.Theme.getSize("print_setup_big_item").height anchors { top: parent.top diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml index 194747271e..618c519d31 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml @@ -69,4 +69,13 @@ Item labelColumnWidth: parent.firstColumnWidth } } + + UM.SettingPropertyProvider + { + id: extrudersEnabledCount + containerStack: Cura.MachineManager.activeMachine + key: "extruders_enabled_count" + watchedProperties: [ "value" ] + storeIndex: 0 + } } diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml index d367510ef6..ce4aa6c195 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml @@ -76,7 +76,7 @@ Item { id: supportExtruderCombobox - height: UM.Theme.getSize("print_setup_big_dropdown").height + height: UM.Theme.getSize("print_setup_big_item").height anchors { left: enableSupportCheckBox.right @@ -171,15 +171,6 @@ Item storeIndex: 0 } - UM.SettingPropertyProvider - { - id: extrudersEnabledCount - containerStack: Cura.MachineManager.activeMachine - key: "extruders_enabled_count" - watchedProperties: [ "value" ] - storeIndex: 0 - } - UM.SettingPropertyProvider { id: supportExtruderNr diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 2c42d222ce..3250e847a3 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -19,70 +19,22 @@ Item property Action configureSettings property bool findingSettings - ToolButton - { - id: settingVisibilityMenu - - property var toolButtonIconColor: UM.Theme.getColor("setting_category_text") - - width: height - height: UM.Theme.getSize("setting_control").height - anchors - { - topMargin: UM.Theme.getSize("thick_margin").height - left: filterContainer.right - leftMargin: UM.Theme.getSize("default_margin").width - } - style: ButtonStyle - { - background: Item { - UM.RecolorImage { - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.horizontalCenter - width: Math.round(parent.width * 0.6) - height: Math.round(parent.height * 0.6) - sourceSize.width: width - sourceSize.height: width - color: settingVisibilityMenu.toolButtonIconColor - source: UM.Theme.getIcon("settings") - } - } - label: Label{} - } - menu: SettingVisibilityPresetsMenu - { - onShowAllSettings: - { - definitionsModel.setAllVisible(true); - filter.updateDefinitionModel(); - } - } - - MouseArea - { - anchors.fill: parent - hoverEnabled: true - acceptedButtons: Qt.RightButton - onEntered: settingVisibilityMenu.toolButtonIconColor = UM.Theme.getColor("setting_control_button_hover") - onExited: settingVisibilityMenu.toolButtonIconColor = UM.Theme.getColor("setting_category_text") - } - } - Rectangle { id: filterContainer visible: true + radius: UM.Theme.getSize("setting_control_radius").width border.width: Math.round(UM.Theme.getSize("default_lining").width) border.color: { - if(hoverMouseArea.containsMouse || clearFilterButton.containsMouse) + if (hoverMouseArea.containsMouse || clearFilterButton.containsMouse) { - return UM.Theme.getColor("setting_control_border_highlight"); + return UM.Theme.getColor("setting_control_border_highlight") } else { - return UM.Theme.getColor("setting_control_border"); + return UM.Theme.getColor("setting_control_border") } } @@ -90,13 +42,12 @@ Item anchors { - topMargin: UM.Theme.getSize("thick_margin").height + top: parent.top left: parent.left - leftMargin: UM.Theme.getSize("default_margin").width - right: scrollView.right - rightMargin: Math.floor(UM.Theme.getSize("wide_margin").width * 2) + right: settingVisibilityMenu.left + rightMargin: UM.Theme.getSize("default_margin").width } - height: UM.Theme.getSize("setting_control").height + height: UM.Theme.getSize("print_setup_big_item").height Timer { id: settingsSearchTimer @@ -108,7 +59,7 @@ Item TextField { - id: filter; + id: filter height: parent.height anchors.left: parent.left anchors.right: clearFilterButton.left @@ -118,9 +69,9 @@ Item style: TextFieldStyle { - textColor: UM.Theme.getColor("setting_control_text"); + textColor: UM.Theme.getColor("setting_control_text") placeholderTextColor: UM.Theme.getColor("setting_filter_field") - font: UM.Theme.getFont("default"); + font: UM.Theme.getFont("default_italic") background: Item {} } @@ -134,38 +85,38 @@ Item onEditingFinished: { - definitionsModel.filter = {"i18n_label": "*" + text}; - findingSettings = (text.length > 0); - if(findingSettings != lastFindingSettings) + definitionsModel.filter = {"i18n_label": "*" + text} + findingSettings = (text.length > 0) + if (findingSettings != lastFindingSettings) { - updateDefinitionModel(); - lastFindingSettings = findingSettings; + updateDefinitionModel() + lastFindingSettings = findingSettings } } Keys.onEscapePressed: { - filter.text = ""; + filter.text = "" } function updateDefinitionModel() { - if(findingSettings) + if (findingSettings) { - expandedCategories = definitionsModel.expanded.slice(); - definitionsModel.expanded = [""]; // keep categories closed while to prevent render while making settings visible one by one - definitionsModel.showAncestors = true; - definitionsModel.showAll = true; - definitionsModel.expanded = ["*"]; + expandedCategories = definitionsModel.expanded.slice() + definitionsModel.expanded = [""] // keep categories closed while to prevent render while making settings visible one by one + definitionsModel.showAncestors = true + definitionsModel.showAll = true + definitionsModel.expanded = ["*"] } else { - if(expandedCategories) + if (expandedCategories) { - definitionsModel.expanded = expandedCategories; + definitionsModel.expanded = expandedCategories } - definitionsModel.showAncestors = false; - definitionsModel.showAll = false; + definitionsModel.showAncestors = false + definitionsModel.showAll = false } } } @@ -197,8 +148,45 @@ Item onClicked: { - filter.text = ""; - filter.forceActiveFocus(); + filter.text = "" + filter.forceActiveFocus() + } + } + } + + ToolButton + { + id: settingVisibilityMenu + + anchors + { + top: filterContainer.top + bottom: filterContainer.bottom + right: parent.right + } + + style: ButtonStyle + { + background: Item { + UM.RecolorImage { + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + width: UM.Theme.getSize("standard_arrow").width + height: UM.Theme.getSize("standard_arrow").height + sourceSize.width: width + sourceSize.height: height + color: control.enabled ? UM.Theme.getColor("setting_category_text") : UM.Theme.getColor("setting_category_disabled_text") + source: UM.Theme.getIcon("menu") + } + } + label: Label{} + } + menu: SettingVisibilityPresetsMenu + { + onShowAllSettings: + { + definitionsModel.setAllVisible(true) + filter.updateDefinitionModel() } } } @@ -206,33 +194,35 @@ Item ScrollView { id: scrollView - anchors.top: filterContainer.bottom; - anchors.bottom: parent.bottom; - anchors.right: parent.right; - anchors.left: parent.left; - anchors.topMargin: UM.Theme.getSize("thick_margin").height - anchors.rightMargin: UM.Theme.getSize("narrow_margin").height / 3 + anchors + { + top: filterContainer.bottom + topMargin: UM.Theme.getSize("default_margin").height + bottom: parent.bottom + right: parent.right + left: parent.left + } - style: UM.Theme.styles.scrollview; - flickableItem.flickableDirection: Flickable.VerticalFlick; - __wheelAreaScrollSpeed: 75; // Scroll three lines in one scroll event + style: UM.Theme.styles.scrollview + flickableItem.flickableDirection: Flickable.VerticalFlick + __wheelAreaScrollSpeed: 75 // Scroll three lines in one scroll event ListView { id: contents - spacing: Math.round(UM.Theme.getSize("default_lining").height); - cacheBuffer: 1000000; // Set a large cache to effectively just cache every list item. + spacing: Math.round(UM.Theme.getSize("default_lining").height) + cacheBuffer: 1000000 // Set a large cache to effectively just cache every list item. model: UM.SettingDefinitionsModel { - id: definitionsModel; + id: definitionsModel containerId: Cura.MachineManager.activeDefinitionId visibilityHandler: UM.SettingPreferenceVisibilityHandler { } exclude: ["machine_settings", "command_line_settings", "infill_mesh", "infill_mesh_order", "cutting_mesh", "support_mesh", "anti_overhang_mesh"] // TODO: infill_mesh settigns are excluded hardcoded, but should be based on the fact that settable_globally, settable_per_meshgroup and settable_per_extruder are false. expanded: CuraApplication.expandedCategories onExpandedChanged: { - if(!findingSettings) + if (!findingSettings) { // Do not change expandedCategories preference while filtering settings // because all categories are expanded while filtering @@ -248,7 +238,7 @@ Item { id: delegate - width: Math.round(UM.Theme.getSize("print_setup_widget").width); + width: scrollView.width height: provider.properties.enabled == "True" ? UM.Theme.getSize("section").height : - contents.spacing Behavior on height { NumberAnimation { duration: 100 } } opacity: provider.properties.enabled == "True" ? 1 : 0 @@ -318,17 +308,17 @@ Item // machine gets changed. var activeMachineId = Cura.MachineManager.activeMachineId; - if(!model.settable_per_extruder) + if (!model.settable_per_extruder) { //Not settable per extruder or there only is global, so we must pick global. return activeMachineId; } - if(inheritStackProvider.properties.limit_to_extruder != null && inheritStackProvider.properties.limit_to_extruder >= 0) + if (inheritStackProvider.properties.limit_to_extruder != null && inheritStackProvider.properties.limit_to_extruder >= 0) { //We have limit_to_extruder, so pick that stack. return Cura.ExtruderManager.extruderIds[String(inheritStackProvider.properties.limit_to_extruder)]; } - if(Cura.ExtruderManager.activeExtruderStackId) + if (Cura.ExtruderManager.activeExtruderStackId) { //We're on an extruder tab. Pick the current extruder. return Cura.ExtruderManager.activeExtruderStackId; @@ -390,14 +380,14 @@ Item } onSetActiveFocusToNextSetting: { - if(forward == undefined || forward) + if (forward == undefined || forward) { contents.currentIndex = contents.indexWithFocus + 1; while(contents.currentItem && contents.currentItem.height <= 0) { contents.currentIndex++; } - if(contents.currentItem) + if (contents.currentItem) { contents.currentItem.item.focusItem.forceActiveFocus(); } @@ -409,7 +399,7 @@ Item { contents.currentIndex--; } - if(contents.currentItem) + if (contents.currentItem) { contents.currentItem.item.focusItem.forceActiveFocus(); } diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index e6144bb6ec..ca95b6d373 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -495,7 +495,7 @@ QtObject anchors.right: downArrow.left anchors.verticalCenter: parent.verticalCenter anchors.rightMargin: UM.Theme.getSize("default_margin").width -// anchors.margins: Math.round(UM.Theme.getSize("default_margin").width / 4) + sourceSize.width: width sourceSize.height: height source: UM.Theme.getIcon("extruder_button") diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 2c5c7a360a..5af77d59c3 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -377,7 +377,7 @@ "print_setup_slider_groove": [0.16, 0.16], "print_setup_slider_handle": [1.0, 1.0], "print_setup_slider_tickmarks": [0.32, 0.32], - "print_setup_big_dropdown": [28, 2.5], + "print_setup_big_item": [28, 2.5], "print_setup_icon": [1.2, 1.2], "configuration_selector_mode_tabs": [0.0, 3.0], @@ -425,7 +425,7 @@ "setting_text_maxwidth": [40.0, 0.0], "standard_list_lineheight": [1.5, 1.5], - "standard_arrow": [0.8, 0.8], + "standard_arrow": [1.0, 1.0], "button": [4, 4], "button_icon": [2.5, 2.5], From c9ed044205ed92236dc344a6c2683b2e262f1826 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 3 Dec 2018 14:41:22 +0100 Subject: [PATCH 0600/1292] Improve printer status and progress bar Contributes to CL-1153 --- .../resources/qml/MonitorPrintJobPreview.qml | 38 ++++- .../qml/MonitorPrintJobProgressBar.qml | 136 ++++++++---------- .../resources/qml/MonitorPrinterCard.qml | 11 +- 3 files changed, 99 insertions(+), 86 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml index 1a69d2dc12..7ac2a1d8de 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml @@ -21,7 +21,18 @@ Item { id: previewImage anchors.fill: parent - opacity: printJob && printJob.state == "error" ? 0.5 : 1.0 + opacity: + { + if (!printJob) + { + return 0 + } + if (printJob.state == "error" || !printJob.isActive) + { + return 0.5 + } + return 1.0 + } source: printJob ? printJob.previewImageUrl : "" visible: printJob } @@ -47,11 +58,32 @@ Item UM.RecolorImage { - id: statusImage + id: overlayIcon anchors.centerIn: printJobPreview color: UM.Theme.getColor("monitor_image_overlay") height: 0.5 * printJobPreview.height - source: printJob && printJob.state == "error" ? "../svg/aborted-icon.svg" : "" + source: + { + switch(printJob.state) + { + case "error": + return "../svg/aborted-icon.svg" + case "wait_cleanup": + if (printJob.state == "wait_cleanup" && printJob.timeTotal > printJob.timeElapsed) + { + return "../svg/aborted-icon.svg" + } + break; + case "pausing": + return "../svg/paused-icon.svg" + case "paused": + return "../svg/paused-icon.svg" + case "resuming": + return "../svg/paused-icon.svg" + default: + return "" + } + } sourceSize { height: height diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml index f70e1175a1..a7055f4c52 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml @@ -15,63 +15,10 @@ import UM 1.3 as UM Item { id: base + + // The print job which all other information is dervied from property var printJob: null - property var progress: - { - if (!printJob) - { - return 0 - } - var result = printJob.timeElapsed / printJob.timeTotal - if (result > 1.0) - { - result = 1.0 - } - return result - } - property var remainingTime: - { - if (!printJob) { - return 0 - } - /* Sometimes total minus elapsed is less than 0. Use Math.max() to prevent remaining - time from ever being less than 0. Negative durations cause strange behavior such - as displaying "-1h -1m". */ - return Math.max(printer.activePrintJob.timeTotal - printer.activePrintJob.timeElapsed, 0) - } - property var progressText: - { - if (!printJob) - { - return ""; - } - switch (printJob.state) - { - case "wait_cleanup": - if (printJob.timeTotal > printJob.timeElapsed) - { - return catalog.i18nc("@label:status", "Aborted") - } - return catalog.i18nc("@label:status", "Finished") - case "pre_print": - case "sent_to_printer": - return catalog.i18nc("@label:status", "Preparing") - case "aborted": - return catalog.i18nc("@label:status", "Aborted") - case "wait_user_action": - return catalog.i18nc("@label:status", "Aborted") - case "pausing": - return catalog.i18nc("@label:status", "Pausing") - case "paused": - return OutputDevice.formatDuration( remainingTime ) - case "resuming": - return catalog.i18nc("@label:status", "Resuming") - case "queued": - return catalog.i18nc("@label:status", "Action required") - default: - return OutputDevice.formatDuration( remainingTime ) - } - } + width: childrenRect.width height: 18 * screenScaleFactor // TODO: Theme! @@ -82,12 +29,12 @@ Item { verticalCenter: parent.verticalCenter } - value: progress; + value: printJob ? printJob.progress : 0 style: ProgressBarStyle { background: Rectangle { - color: "#e4e4f2" // TODO: Theme! + color: printJob && printJob.isActive ? "#e4e4f2" : "#f3f3f9" // TODO: Theme! implicitHeight: visible ? 8 * screenScaleFactor : 0 // TODO: Theme! implicitWidth: 180 * screenScaleFactor // TODO: Theme! radius: 4 * screenScaleFactor // TODO: Theme! @@ -95,41 +42,72 @@ Item progress: Rectangle { id: progressItem; - color: - { - if (printJob) - { - var state = printJob.state - var inactiveStates = [ - "pausing", - "paused", - "resuming", - "wait_cleanup" - ] - if (inactiveStates.indexOf(state) > -1 && remainingTime > 0) - { - return UM.Theme.getColor("monitor_progress_fill_inactive") - } - } - return "#0a0850" // TODO: Theme! - } + color: printJob && printJob.isActive ? "#0a0850" : "#9392b2" // TODO: Theme! radius: 4 * screenScaleFactor // TODO: Theme! } } } Label { - id: progressLabel + id: percentLabel anchors { left: progressBar.right leftMargin: 18 * screenScaleFactor // TODO: Theme! } - text: progressText - color: "#374355" // TODO: Theme! + text: Math.round(printJob.progress * 100) + "%" + color: printJob && printJob.isActive ? "#374355" : "#babac1" // TODO: Theme! width: contentWidth font: UM.Theme.getFont("medium") // 14pt, regular + // FIXED-LINE-HEIGHT: + height: 18 * screenScaleFactor // TODO: Theme! + verticalAlignment: Text.AlignVCenter + } + Label + { + id: statusLabel + anchors + { + left: percentLabel.right + leftMargin: 18 * screenScaleFactor // TODO: Theme! + } + color: "#374355" // TODO: Theme! + font: UM.Theme.getFont("medium") // 14pt, regular + text: + { + if (!printJob) + { + return ""; + } + switch (printJob.state) + { + case "wait_cleanup": + if (printJob.timeTotal > printJob.timeElapsed) + { + return catalog.i18nc("@label:status", "Aborted") + } + return catalog.i18nc("@label:status", "Finished") + case "sent_to_printer": + return catalog.i18nc("@label:status", "Preparing...") + case "aborting": + return catalog.i18nc("@label:status", "Aborting...") + case "aborted": + return catalog.i18nc("@label:status", "Aborted") + case "pausing": + return catalog.i18nc("@label:status", "Pausing...") + case "paused": + return catalog.i18nc("@label:status", "Paused") + case "resuming": + return catalog.i18nc("@label:status", "Resuming...") + case "queued": + return catalog.i18nc("@label:status", "Action required") + default: + return catalog.i18nc("@label:status", "Finishes ") + OutputDevice.getDateCompleted( printJob.timeRemaining ) + " at " + OutputDevice.getTimeCompleted( printJob.timeRemaining ) + } + } + width: contentWidth + // FIXED-LINE-HEIGHT: height: 18 * screenScaleFactor // TODO: Theme! verticalAlignment: Text.AlignVCenter diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml index 975fe12244..ee7212760b 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml @@ -183,6 +183,7 @@ Item printJob: base.printer.activePrintJob size: parent.height } + visible: printer.activePrintJob } Item @@ -193,14 +194,15 @@ Item } width: 216 * screenScaleFactor // TODO: Theme! height: printerNameLabel.height + printerFamilyPill.height + 6 * screenScaleFactor // TODO: Theme! + visible: printer.activePrintJob Label { id: printerJobNameLabel - text: base.printer.activePrintJob ? base.printer.activePrintJob.name : "Untitled" // TODO: I18N - color: "#414054" // TODO: Theme! + color: printer.activePrintJob && printer.activePrintJob.isActive ? "#414054" : "#babac1" // TODO: Theme! elide: Text.ElideRight font: UM.Theme.getFont("large") // 16pt, bold + text: base.printer.activePrintJob ? base.printer.activePrintJob.name : "Untitled" // TODO: I18N width: parent.width // FIXED-LINE-HEIGHT: @@ -217,10 +219,10 @@ Item topMargin: 6 * screenScaleFactor // TODO: Theme! left: printerJobNameLabel.left } - text: printer.activePrintJob ? printer.activePrintJob.owner : "Anonymous" // TODO: I18N - color: "#53657d" // TODO: Theme! + color: printer.activePrintJob && printer.activePrintJob.isActive ? "#53657d" : "#babac1" // TODO: Theme! elide: Text.ElideRight font: UM.Theme.getFont("very_small") // 12pt, regular + text: printer.activePrintJob ? printer.activePrintJob.owner : "Anonymous" // TODO: I18N width: parent.width // FIXED-LINE-HEIGHT: @@ -236,6 +238,7 @@ Item verticalCenter: parent.verticalCenter } printJob: printer.activePrintJob + visible: printer.activePrintJob } } } From fc26ccd6fa91f016f1eec7d6bd80c4da742b7496 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 3 Dec 2018 14:41:36 +0100 Subject: [PATCH 0601/1292] STAR-332: Some improvements to get the job in connect --- cura/API/Account.py | 6 +- .../NetworkedPrinterOutputDevice.py | 11 +- .../src/Cloud/CloudOutputDevice.py | 167 ++++++++++-------- .../src/Cloud/CloudOutputDeviceManager.py | 19 +- .../UM3NetworkPrinting/src/Cloud/Models.py | 10 +- 5 files changed, 121 insertions(+), 92 deletions(-) diff --git a/cura/API/Account.py b/cura/API/Account.py index 64d63c7025..d78c7e8826 100644 --- a/cura/API/Account.py +++ b/cura/API/Account.py @@ -37,14 +37,16 @@ class Account(QObject): self._logged_in = False self._callback_port = 32118 - self._oauth_root = "https://account.ultimaker.com" + self._oauth_root = "https://account-staging.ultimaker.com" self._oauth_settings = OAuth2Settings( OAUTH_SERVER_URL= self._oauth_root, CALLBACK_PORT=self._callback_port, CALLBACK_URL="http://localhost:{}/callback".format(self._callback_port), CLIENT_ID="um----------------------------ultimaker_cura", - CLIENT_SCOPES="account.user.read drive.backup.read drive.backup.write packages.download packages.rating.read packages.rating.write", + CLIENT_SCOPES="account.user.read drive.backup.read drive.backup.write packages.download " + "packages.rating.read packages.rating.write connect.cluster.read connect.cluster.write " + "cura.printjob.read cura.printjob.write cura.mesh.read cura.mesh.write", AUTH_DATA_PREFERENCE_KEY="general/ultimaker_auth_data", AUTH_SUCCESS_REDIRECT="{}/app/auth-success".format(self._oauth_root), AUTH_FAILED_REDIRECT="{}/app/auth-error".format(self._oauth_root) diff --git a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py index 7125de4002..0a799d4cd3 100644 --- a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py +++ b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py @@ -11,7 +11,7 @@ from cura.PrinterOutputDevice import PrinterOutputDevice, ConnectionState from PyQt5.QtNetwork import QHttpMultiPart, QHttpPart, QNetworkRequest, QNetworkAccessManager, QNetworkReply, QAuthenticator from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QUrl, QCoreApplication from time import time -from typing import Any, Callable, Dict, List, Optional +from typing import Callable, Dict, List, Optional, Union from enum import IntEnum import os # To get the username @@ -180,12 +180,12 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): self._createNetworkManager() assert (self._manager is not None) - def put(self, target: str, data: str, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: + def put(self, target: str, data: Union[str, bytes], on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: self._validateManager() request = self._createEmptyRequest(target) self._last_request_time = time() if self._manager is not None: - reply = self._manager.put(request, data.encode()) + reply = self._manager.put(request, data if isinstance(data, bytes) else data.encode()) self._registerOnFinishedCallback(reply, on_finished) else: Logger.log("e", "Could not find manager.") @@ -210,12 +210,13 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): else: Logger.log("e", "Could not find manager.") - def post(self, target: str, data: str, on_finished: Optional[Callable[[QNetworkReply], None]], on_progress: Callable = None) -> None: + def post(self, target: str, data: Union[str, bytes], on_finished: Optional[Callable[[QNetworkReply], None]], + on_progress: Callable = None) -> None: self._validateManager() request = self._createEmptyRequest(target) self._last_request_time = time() if self._manager is not None: - reply = self._manager.post(request, data.encode()) + reply = self._manager.post(request, data if isinstance(data, bytes) else data.encode()) if on_progress is not None: reply.uploadProgress.connect(on_progress) self._registerOnFinishedCallback(reply, on_finished) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 008633e198..caffa64a95 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -3,7 +3,8 @@ import io import json import os -from typing import List, Optional, Dict, cast, Union +from json import JSONDecodeError +from typing import List, Optional, Dict, cast, Union, Tuple from PyQt5.QtCore import QObject, pyqtSignal, QUrl, pyqtProperty from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest @@ -20,9 +21,9 @@ from cura.PrinterOutput.PrinterOutputController import PrinterOutputController from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice, AuthState from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel +from plugins.UM3NetworkPrinting.src.UM3PrintJobOutputModel import UM3PrintJobOutputModel from .Models import CloudClusterPrinter, CloudClusterPrinterConfiguration, CloudClusterPrinterConfigurationMaterial, \ - CloudClusterPrintJob, CloudClusterPrintJobConstraint, JobUploadRequest -from ..UM3PrintJobOutputModel import UM3PrintJobOutputModel + CloudClusterPrintJob, CloudClusterPrintJobConstraint, JobUploadRequest, JobUploadResponse, PrintResponse ## The cloud output device is a network output device that works remotely but has limited functionality. @@ -37,11 +38,10 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): I18N_CATALOG = i18nCatalog("cura") # The cloud URL to use for this remote cluster. - # TODO: Make sure that this url goes to the live api before release + # TODO: Make sure that this URL goes to the live api before release ROOT_PATH = "https://api-staging.ultimaker.com" CLUSTER_API_ROOT = "{}/connect/v1/".format(ROOT_PATH) CURA_API_ROOT = "{}/cura/v1/".format(ROOT_PATH) - CURA_DRIVE_API_ROOT = "{}/cura-drive/v1/".format(ROOT_PATH) # Signal triggered when the printers in the remote cluster were changed. printersChanged = pyqtSignal() @@ -56,6 +56,9 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self._device_id = device_id self._account = CuraApplication.getInstance().getCuraAPI().account + # Cluster does not have authentication, so default to authenticated + self._authentication_state = AuthState.Authenticated + # We re-use the Cura Connect monitor tab to get the most functionality right away. self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../resources/qml/ClusterMonitorItem.qml") @@ -63,8 +66,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): "../../resources/qml/ClusterControlItem.qml") # Properties to populate later on with received cloud data. - self._printers = {} # type: Dict[str, PrinterOutputModel] - self._print_jobs = {} # type: Dict[str, PrintJobOutputModel] + self._print_jobs = [] # type: List[UM3PrintJobOutputModel] self._number_of_extruders = 2 # All networked printers are dual-extrusion Ultimaker machines. @staticmethod @@ -123,23 +125,11 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): Logger.log("e", "Missing file or mesh writer!") return - stream = io.BytesIO() # type: Union[io.BytesIO, io.StringIO]# Binary mode. - if file_format["mode"] == FileWriter.OutputMode.TextMode: - stream = io.StringIO() - + stream = io.StringIO() if file_format["mode"] == FileWriter.OutputMode.TextMode else io.BytesIO() writer.write(stream, nodes) + self._sendPrintJob(file_name + "." + file_format["extension"], stream) - stream.seek(0, io.SEEK_END) - size = stream.tell() - stream.seek(0, io.SEEK_SET) - - request = JobUploadRequest() - request.job_name = file_name - request.file_size = size - - self._addPrintJobToQueue(stream, request) - - # TODO: This is yanked right out of ClusterUM3OoutputDevice, great candidate for a utility or base class + # TODO: This is yanked right out of ClusterUM3OutputDevice, great candidate for a utility or base class def _determineFileFormat(self, file_handler) -> Optional[Dict[str, Union[str, int]]]: # Formats supported by this application (file types that we can actually write). if file_handler: @@ -172,7 +162,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ) return file_formats[0] - # TODO: This is yanked right out of ClusterUM3OoutputDevice, great candidate for a utility or base class + # TODO: This is yanked right out of ClusterUM3OutputDevice, great candidate for a utility or base class @staticmethod def _determineWriter(file_handler, file_format) -> Optional[FileWriter]: # Just take the first file format available. @@ -194,10 +184,14 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def printers(self): return self._printers + @pyqtProperty("QVariantList", notify = printJobsChanged) + def printJobs(self)-> List[UM3PrintJobOutputModel]: + return self._print_jobs + ## Get remote print jobs. @pyqtProperty("QVariantList", notify = printJobsChanged) def queuedPrintJobs(self) -> List[UM3PrintJobOutputModel]: - return [print_job for print_job in self._print_jobs.values() + return [print_job for print_job in self._print_jobs if print_job.state == "queued" or print_job.state == "error"] ## Called when the connection to the cluster changes. @@ -207,6 +201,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## Called when the network data should be updated. def _update(self) -> None: super()._update() + Logger.log("i", "Calling the cloud cluster") self.get("{root}/cluster/{cluster_id}/status".format(root=self.CLUSTER_API_ROOT, cluster_id=self._device_id), on_finished = self._onStatusCallFinished) @@ -214,11 +209,12 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # Contains both printers and print jobs statuses in a single response. def _onStatusCallFinished(self, reply: QNetworkReply) -> None: status_code, response = self._parseReply(reply) - if status_code > 204: - Logger.log("w", "Got unexpected response while trying to get cloud cluster data: {}, {}" - .format(status_code, status, response)) + if status_code > 204 or not isinstance(response, dict): + Logger.log("w", "Got unexpected response while trying to get cloud cluster data: %s, %s", + status_code, response) return + Logger.log("d", "Got response form the cloud cluster %s, %s", status_code, response) printers, print_jobs = self._parseStatusResponse(response) if not printers and not print_jobs: return @@ -228,7 +224,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self._updatePrintJobs(print_jobs) @staticmethod - def _parseStatusResponse(response: dict) -> Optional[Tuple[CloudClusterPrinter, CloudClusterPrintJob]]: + def _parseStatusResponse(response: dict) -> Tuple[List[CloudClusterPrinter], List[CloudClusterPrintJob]]: printers = [] print_jobs = [] @@ -264,33 +260,31 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def _updatePrinters(self, printers: List[CloudClusterPrinter]) -> None: remote_printers = {p.uuid: p for p in printers} # type: Dict[str, CloudClusterPrinter] + current_printers = {p.key: p for p in self._printers} - removed_printer_ids = set(self._printers).difference(remote_printers) - new_printer_ids = set(remote_printers).difference(self._printers) - updated_printer_ids = set(self._printers).intersection(remote_printers) + removed_printer_ids = set(current_printers).difference(remote_printers) + new_printer_ids = set(remote_printers).difference(current_printers) + updated_printer_ids = set(current_printers).intersection(remote_printers) for printer_guid in removed_printer_ids: - self._removePrinter(printer_guid) + self._printers.remove(current_printers[printer_guid]) for printer_guid in new_printer_ids: self._addPrinter(remote_printers[printer_guid]) - self._updatePrinter(remote_printers[printer_guid]) for printer_guid in updated_printer_ids: - self._updatePrinter(remote_printers[printer_guid]) + self._updatePrinter(current_printers[printer_guid], remote_printers[printer_guid]) - # TODO: properly handle removed and updated printers self.printersChanged.emit() def _addPrinter(self, printer: CloudClusterPrinter) -> None: - self._printers[printer.uuid] = self._createPrinterOutputModel(printer) + model = PrinterOutputModel( + PrinterOutputController(self), len(printer.configuration), firmware_version=printer.firmware_version + ) + self._printers.append(model) + self._updatePrinter(model, printer) - def _createPrinterOutputModel(self, printer: CloudClusterPrinter) -> PrinterOutputModel: - return PrinterOutputModel(PrinterOutputController(self), len(printer.configuration), - firmware_version=printer.firmware_version) - - def _updatePrinter(self, printer: CloudClusterPrinter) -> None: - model = self._printers[printer.uuid] + def _updatePrinter(self, model: PrinterOutputModel, printer: CloudClusterPrinter) -> None: model.updateKey(printer.uuid) model.updateName(printer.friendly_name) model.updateType(printer.machine_variant) @@ -342,68 +336,85 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): return MaterialOutputModel(guid=material.guid, type=material_type, brand=brand, color=color, name=name) - def _removePrinter(self, guid): - del self._printers[guid] - def _updatePrintJobs(self, jobs: List[CloudClusterPrintJob]) -> None: remote_jobs = {j.uuid: j for j in jobs} + current_jobs = {j.key: j for j in self._print_jobs} - removed_jobs = set(self._print_jobs.keys()).difference(set(remote_jobs.keys())) - new_jobs = set(remote_jobs.keys()).difference(set(self._print_jobs.keys())) - updated_jobs = set(self._print_jobs.keys()).intersection(set(remote_jobs.keys())) + removed_job_ids = set(current_jobs).difference(set(remote_jobs)) + new_job_ids = set(remote_jobs.keys()).difference(set(current_jobs)) + updated_job_ids = set(current_jobs).intersection(set(remote_jobs)) - for j in removed_jobs: - self._removePrintJob(j) + for job_id in removed_job_ids: + self._print_jobs.remove(current_jobs[job_id]) - for j in new_jobs: - self._addPrintJob(jobs[j]) + for job_id in new_job_ids: + self._addPrintJob(remote_jobs[job_id]) - for j in updated_jobs: - self._updatePrintJob(remote_jobs[j]) + for job_id in updated_job_ids: + self._updateUM3PrintJobOutputModel(current_jobs[job_id], remote_jobs[job_id]) # TODO: properly handle removed and updated printers - self.printJobsChanged() + self.printJobsChanged.emit() def _addPrintJob(self, job: CloudClusterPrintJob) -> None: - self._print_jobs[job.uuid] = self._createPrintJobOutputModel(job) + try: + printer = next(p for p in self._printers if job.printer_uuid == p.key) + except StopIteration: + return Logger.log("w", "Missing printer %s for job %s in %s", job.printer_uuid, job.uuid, + [p.key for p in self._printers]) - def _createPrintJobOutputModel(self, job: CloudClusterPrintJob) -> PrintJobOutputModel: - controller = self._printers[job.printer_uuid]._controller # TODO: Can we access this property? - model = PrintJobOutputModel(controller, job.uuid, job.name) - assigned_printer = self._printes[job.printer_uuid] # TODO: Or do we have to use the assigned_to field? - model.updateAssignedPrinter(assigned_printer) - return model - - def _updatePrintJobOutputModel(self, guid: str, job: CloudClusterPrintJob) -> None: - model = self._print_jobs[guid] + model = UM3PrintJobOutputModel(printer.getController(), job.uuid, job.name) + model.updateAssignedPrinter(printer) + self._print_jobs.append(model) + @staticmethod + def _updateUM3PrintJobOutputModel(model: PrinterOutputModel, job: CloudClusterPrintJob) -> None: model.updateTimeTotal(job.time_total) model.updateTimeElapsed(job.time_elapsed) model.updateOwner(job.owner) model.updateState(job.status) - def _removePrintJob(self, guid: str): - del self._print_jobs[guid] + def _sendPrintJob(self, file_name: str, stream: Union[io.StringIO, io.BytesIO]) -> None: + mesh = stream.getvalue() - def _addPrintJobToQueue(self, stream, request: JobUploadRequest): - self.put("{}/jobs/upload".format(self.CURA_API_ROOT), data = json.dumps(request.__dict__), - on_finished = lambda reply: self._onAddPrintJobToQueueFinished(stream, reply)) + request = JobUploadRequest() + request.job_name = file_name + request.file_size = len(mesh) - def _onAddPrintJobToQueueFinished(self, stream, reply: QNetworkReply) -> None: - status_code, response = self._parseReply(reply) # type: Tuple[int, dict] - if status_code > 204 or not isinstance(dict, response) or "data" not in response: - Logger.error() + Logger.log("i", "Creating new cloud print job: %s", request.__dict__) + self.put("{}/jobs/upload".format(self.CURA_API_ROOT), data = json.dumps({"data": request.__dict__}), + on_finished = lambda reply: self._onPrintJobCreated(mesh, reply)) + + def _onPrintJobCreated(self, mesh: bytes, reply: QNetworkReply) -> None: + status_code, response = self._parseReply(reply) + if status_code > 204 or not isinstance(response, dict) or "data" not in response: + Logger.log("w", "Got unexpected response while trying to add print job to cluster: {}, {}" + .format(status_code, response)) return + # TODO: Multipart upload job_response = JobUploadResponse(**response.get("data")) - self.put(job_response.upload_url, data=stream.getvalue(), on_finished=self._onPrintJobUploaded) + Logger.log("i", "Print job created successfully: %s", job_response.__dict__) + self.put(job_response.upload_url, data=mesh, + on_finished=lambda r: self._onPrintJobUploaded(job_response.job_id, r)) - def _onPrintJobUploaded(self, reply: QNetworkReply) -> None: + def _onPrintJobUploaded(self, job_id: str, reply: QNetworkReply) -> None: status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) if status_code > 204: - self.onWriteFailed.emit("Failed to export G-code to remote URL: {}".format(r.text)) Logger.logException("w", "Received unexpected response from the job upload: %s, %s.", status_code, bytes(reply.readAll()).decode()) return - self.onWriteSuccess.emit(r.text) + Logger.log("i", "Print job uploaded successfully: %s", reply.readAll()) + url = "{}/cluster/{}/print/{}".format(self.CLUSTER_API_ROOT, self._device_id, job_id) + self.post(url, data="", on_finished=self._onPrintJobRequested) + + def _onPrintJobRequested(self, reply: QNetworkReply) -> None: + status_code, response = self._parseReply(reply) + if status_code > 204 or not isinstance(response, dict): + Logger.log("w", "Got unexpected response while trying to request printing: %s, %s", + status_code, response) + return + + print_response = PrintResponse(**response.get("data")) + Logger.log("i", "Print job requested successfully: %s", print_response.__dict__) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 421f24bc25..7c10cb4e50 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -25,9 +25,9 @@ from .Models import CloudCluster class CloudOutputDeviceManager(NetworkClient): # The cloud URL to use for remote clusters. - API_ROOT_PATH = "https://api.ultimaker.com/connect/v1" + API_ROOT_PATH = "https://api-staging.ultimaker.com/connect/v1" - # The interval with wich the remote clusters are checked + # The interval with which the remote clusters are checked CHECK_CLUSTER_INTERVAL = 5 # seconds def __init__(self): @@ -39,13 +39,14 @@ class CloudOutputDeviceManager(NetworkClient): application = CuraApplication.getInstance() self._output_device_manager = application.getOutputDeviceManager() self._account = application.getCuraAPI().account + self._account.loginStateChanged.connect(self._getRemoteClusters) # When switching machines we check if we have to activate a remote cluster. application.globalContainerStackChanged.connect(self._activeMachineChanged) # Periodically check all remote clusters for the authenticated user. - self._update_clusters_thread = Thread(target=self._updateClusters, daemon=True) - self._update_clusters_thread.start() + # self._update_clusters_thread = Thread(target=self._updateClusters, daemon=True) + # self._update_clusters_thread.start() ## Override _createEmptyRequest to add the needed authentication header for talking to the Ultimaker Cloud API. def _createEmptyRequest(self, path: str, content_type: Optional[str] = "application/json") -> QNetworkRequest: @@ -64,18 +65,22 @@ class CloudOutputDeviceManager(NetworkClient): ## Gets all remote clusters from the API. def _getRemoteClusters(self) -> None: + Logger.log("i", "Retrieving remote clusters") self.get("/clusters", on_finished = self._onGetRemoteClustersFinished) ## Callback for when the request for getting the clusters. is finished. def _onGetRemoteClustersFinished(self, reply: QNetworkReply) -> None: + Logger.log("i", "Received remote clusters") + status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) - if status_code != 200: + if status_code > 204: Logger.log("w", "Got unexpected response while trying to get cloud cluster data: {}, {}" .format(status_code, reply.readAll())) return # Parse the response (returns the "data" field from the body). found_clusters = self._parseStatusResponse(reply) + Logger.log("i", "Parsed remote clusters to %s", found_clusters) if not found_clusters: return @@ -96,7 +101,8 @@ class CloudOutputDeviceManager(NetworkClient): @staticmethod def _parseStatusResponse(reply: QNetworkReply) -> Dict[str, CloudCluster]: try: - return {c["cluster_id"]: CloudCluster(**c) for c in json.loads(reply.readAll().data().decode("utf-8"))} + response = bytes(reply.readAll()).decode() + return {c["cluster_id"]: CloudCluster(**c) for c in json.loads(response)["data"]} except UnicodeDecodeError: Logger.log("w", "Unable to read server response") except json.decoder.JSONDecodeError: @@ -110,6 +116,7 @@ class CloudOutputDeviceManager(NetworkClient): device = CloudOutputDevice(cluster.cluster_id) self._output_device_manager.addOutputDevice(device) self._remote_clusters[cluster.cluster_id] = device + device.connect() # TODO: Only connect the current device ## Remove a CloudOutputDevice def _removeCloudOutputDevice(self, cluster: CloudCluster): diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models.py b/plugins/UM3NetworkPrinting/src/Cloud/Models.py index 5363f49c00..435f265300 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models.py @@ -36,7 +36,7 @@ class CloudClusterPrinterConfiguration(BaseModel): self.extruder_index = None # type: str self.material = None # type: CloudClusterPrinterConfigurationMaterial self.nozzle_diameter = None # type: str - self.printer_core_id = None # type: str + self.print_core_id = None # type: str super().__init__(**kwargs) @@ -99,3 +99,11 @@ class JobUploadResponse(BaseModel): self.status = None # type: str self.upload_url = None # type: str super().__init__(**kwargs) + + +class PrintResponse(BaseModel): + def __init__(self, **kwargs): + self.cluster_job_id: str = None + self.job_id: str = None + self.status: str = None + super().__init__(**kwargs) From cced42a55bce1fbecdde3f8ce383daeec6185d92 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 3 Dec 2018 14:41:45 +0100 Subject: [PATCH 0602/1292] Handle idle, unavailable, and unreachable states Contributes to CL-1153 --- .../resources/qml/MonitorPrinterCard.qml | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml index ee7212760b..8659037cb8 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml @@ -169,6 +169,30 @@ Item height: childrenRect.height spacing: 18 * screenScaleFactor // TODO: Theme! + Label + { + id: printerStatus + anchors + { + verticalCenter: parent.verticalCenter + } + color: "#414054" // TODO: Theme! + font: UM.Theme.getFont("large") // 16pt, bold + text: { + if (printer && printer.state == "disabled"){ + return catalog.i18nc("@label:status", "Unavailable") + } + if (printer && printer.state == "unreachable"){ + return catalog.i18nc("@label:status", "Unavailable") + } + if (printer && !printer.activePrintJob) + { + return catalog.i18nc("@label:status", "Idle") + } + return "" + } + } + Item { anchors From ce6a0676dd029a8e4b6ce7d5e2640c8114505fa5 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 3 Dec 2018 14:43:35 +0100 Subject: [PATCH 0603/1292] Add a rectangle surrounding the settings listview Contributes to CURA-5941. --- .../Custom/CustomPrintSetup.qml | 23 +++++++++++++++++-- resources/qml/Settings/SettingCategory.qml | 20 ++++++++-------- resources/qml/Settings/SettingItem.qml | 11 +++++---- resources/qml/Settings/SettingView.qml | 3 ++- resources/themes/cura-light/styles.qml | 4 ++-- resources/themes/cura-light/theme.json | 2 +- 6 files changed, 43 insertions(+), 20 deletions(-) diff --git a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml index ae31976a34..b524bb5926 100644 --- a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml +++ b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml @@ -91,17 +91,36 @@ Item } } - Cura.SettingView + Rectangle { anchors { top: tabBar.visible ? tabBar.bottom : globalProfileRow.bottom - topMargin: UM.Theme.getSize("default_margin").height left: parent.left leftMargin: parent.padding right: parent.right rightMargin: parent.padding bottom: parent.bottom + topMargin: -UM.Theme.getSize("default_lining").width + bottomMargin: -UM.Theme.getSize("default_lining").width + } + z: tabBar.z - 1 + // Don't show the border when only one extruder + border.color: tabBar.visible ? UM.Theme.getColor("lining") : "transparent" + border.width: UM.Theme.getSize("default_lining").width + + Cura.SettingView + { + anchors + { + fill: parent + topMargin: UM.Theme.getSize("default_margin").height + leftMargin: UM.Theme.getSize("default_margin").width + // Small space for the scrollbar + rightMargin: UM.Theme.getSize("narrow_margin").width + // Compensate for the negative margin in the parent + bottomMargin: UM.Theme.getSize("default_lining").width + } } } } diff --git a/resources/qml/Settings/SettingCategory.qml b/resources/qml/Settings/SettingCategory.qml index 4ec6294d61..9a061304d4 100644 --- a/resources/qml/Settings/SettingCategory.qml +++ b/resources/qml/Settings/SettingCategory.qml @@ -12,8 +12,8 @@ Button id: base anchors.left: parent.left anchors.right: parent.right - anchors.leftMargin: UM.Theme.getSize("default_margin").width - anchors.rightMargin: UM.Theme.getSize("default_margin").width * 3 + // To avoid overlaping with the scrollBars + anchors.rightMargin: 2 * UM.Theme.getSize("thin_margin").width hoverEnabled: true background: Rectangle @@ -25,22 +25,24 @@ Button if (base.color) { return base.color - } else if (!base.enabled) + } + else if (!base.enabled) { return UM.Theme.getColor("setting_category_disabled") - } else if (base.hovered && base.checkable && base.checked) + } + else if (base.hovered && base.checkable && base.checked) { return UM.Theme.getColor("setting_category_active_hover") - } else if (base.pressed || (base.checkable && base.checked)) + } + else if (base.pressed || (base.checkable && base.checked)) { return UM.Theme.getColor("setting_category_active") - } else if (base.hovered) + } + else if (base.hovered) { return UM.Theme.getColor("setting_category_hover") - } else - { - return UM.Theme.getColor("setting_category") } + return UM.Theme.getColor("setting_category") } Behavior on color { ColorAnimation { duration: 50; } } Rectangle diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index 036dcfeba4..df90cffdf3 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -10,8 +10,9 @@ import Cura 1.0 as Cura import "." -Item { - id: base; +Item +{ + id: base height: UM.Theme.getSize("section").height @@ -105,11 +106,11 @@ Item { Label { - id: label; + id: label - anchors.left: parent.left; + anchors.left: parent.left anchors.leftMargin: doDepthIndentation ? Math.round((UM.Theme.getSize("section_icon_column").width / 1.2) + ((definition.depth - 1) * UM.Theme.getSize("setting_control_depth_margin").width)) : 0 - anchors.right: settingControls.left; + anchors.right: settingControls.left anchors.verticalCenter: parent.verticalCenter text: definition.label diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 3250e847a3..ff94c9168f 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -163,6 +163,7 @@ Item top: filterContainer.top bottom: filterContainer.bottom right: parent.right + rightMargin: UM.Theme.getSize("wide_margin").width } style: ButtonStyle @@ -210,7 +211,7 @@ Item ListView { id: contents - spacing: Math.round(UM.Theme.getSize("default_lining").height) + spacing: UM.Theme.getSize("default_lining").height cacheBuffer: 1000000 // Set a large cache to effectively just cache every list item. model: UM.SettingDefinitionsModel diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index ca95b6d373..eed5393a0b 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -384,13 +384,13 @@ QtObject { implicitWidth: Theme.getSize("scrollbar").width radius: Math.round(implicitWidth / 2) - color: Theme.getColor("scrollbar_background"); + color: Theme.getColor("scrollbar_background") } handle: Rectangle { id: scrollViewHandle - implicitWidth: Theme.getSize("scrollbar").width; + implicitWidth: Theme.getSize("scrollbar").width radius: Math.round(implicitWidth / 2) color: styleData.pressed ? Theme.getColor("scrollbar_handle_down") : styleData.hovered ? Theme.getColor("scrollbar_handle_hover") : Theme.getColor("scrollbar_handle"); diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 5af77d59c3..dbe5e7196e 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -411,7 +411,7 @@ "extruder_icon": [2.33, 2.33], - "section": [0.0, 2.2], + "section": [0.0, 2], "section_icon": [1.6, 1.6], "section_icon_column": [2.8, 0.0], From 95400282b907abf0a6d7ec707e209da50d0c1b36 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 3 Dec 2018 14:44:15 +0100 Subject: [PATCH 0604/1292] Simplify logic slightly Contributes to CL-1153 --- .../resources/qml/MonitorPrintJobPreview.qml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml index 7ac2a1d8de..b6b666cbf3 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml @@ -23,11 +23,7 @@ Item anchors.fill: parent opacity: { - if (!printJob) - { - return 0 - } - if (printJob.state == "error" || !printJob.isActive) + if (printJob && (printJob.state == "error" || !printJob.isActive)) { return 0.5 } From f8f6670cae4afc5069a8eeb8034d0c0074c2903b Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 3 Dec 2018 15:06:01 +0100 Subject: [PATCH 0605/1292] STAR-322: Letting models convert sub-models --- .../src/Cloud/CloudOutputDevice.py | 67 +++------- .../UM3NetworkPrinting/src/Cloud/Models.py | 115 +++++++++++------- 2 files changed, 84 insertions(+), 98 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index caffa64a95..c478f15ade 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -22,8 +22,10 @@ from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice, AuthState from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from plugins.UM3NetworkPrinting.src.UM3PrintJobOutputModel import UM3PrintJobOutputModel -from .Models import CloudClusterPrinter, CloudClusterPrinterConfiguration, CloudClusterPrinterConfigurationMaterial, \ - CloudClusterPrintJob, CloudClusterPrintJobConstraint, JobUploadRequest, JobUploadResponse, PrintResponse +from .Models import ( + CloudClusterPrinter, CloudClusterPrintJob, JobUploadRequest, JobUploadResponse, PrintResponse, CloudClusterStatus, + CloudClusterPrinterConfigurationMaterial +) ## The cloud output device is a network output device that works remotely but has limited functionality. @@ -209,58 +211,21 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # Contains both printers and print jobs statuses in a single response. def _onStatusCallFinished(self, reply: QNetworkReply) -> None: status_code, response = self._parseReply(reply) - if status_code > 204 or not isinstance(response, dict): + if status_code > 204 or not isinstance(response, dict) or "data" not in response: Logger.log("w", "Got unexpected response while trying to get cloud cluster data: %s, %s", status_code, response) return Logger.log("d", "Got response form the cloud cluster %s, %s", status_code, response) - printers, print_jobs = self._parseStatusResponse(response) - if not printers and not print_jobs: - return - + status = CloudClusterStatus(**response["data"]) + # Update all data from the cluster. - self._updatePrinters(printers) - self._updatePrintJobs(print_jobs) - - @staticmethod - def _parseStatusResponse(response: dict) -> Tuple[List[CloudClusterPrinter], List[CloudClusterPrintJob]]: - printers = [] - print_jobs = [] - - data = response["data"] - for p in data["printers"]: - printer = CloudClusterPrinter(**p) - configuration = printer.configuration - printer.configuration = [] - for c in configuration: - extruder = CloudClusterPrinterConfiguration(**c) - extruder.material = CloudClusterPrinterConfigurationMaterial(material=extruder.material) - printer.configuration.append(extruder) - - printers.append(printer) - - for j in data["print_jobs"]: - job = CloudClusterPrintJob(**j) - constraints = job.constraints - job.constraints = [] - for c in constraints: - job.constraints.append(CloudClusterPrintJobConstraint(**c)) - - configuration = job.configuration - job.configuration = [] - for c in configuration: - configuration = CloudClusterPrinterConfiguration(**c) - configuration.material = CloudClusterPrinterConfigurationMaterial(material=configuration.material) - job.configuration.append(configuration) - - print_jobs.append(job) - - return printers, print_jobs + self._updatePrinters(status.printers) + self._updatePrintJobs(status.print_jobs) def _updatePrinters(self, printers: List[CloudClusterPrinter]) -> None: - remote_printers = {p.uuid: p for p in printers} # type: Dict[str, CloudClusterPrinter] - current_printers = {p.key: p for p in self._printers} + remote_printers: Dict[str, CloudClusterPrinter] = {p.uuid: p for p in printers} + current_printers: Dict[str, PrinterOutputModel] = {p.key: p for p in self._printers} removed_printer_ids = set(current_printers).difference(remote_printers) new_printer_ids = set(remote_printers).difference(current_printers) @@ -337,8 +302,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): return MaterialOutputModel(guid=material.guid, type=material_type, brand=brand, color=color, name=name) def _updatePrintJobs(self, jobs: List[CloudClusterPrintJob]) -> None: - remote_jobs = {j.uuid: j for j in jobs} - current_jobs = {j.key: j for j in self._print_jobs} + remote_jobs: Dict[str, CloudClusterPrintJob] = {j.uuid: j for j in jobs} + current_jobs: Dict[str, UM3PrintJobOutputModel] = {j.key: j for j in self._print_jobs} removed_job_ids = set(current_jobs).difference(set(remote_jobs)) new_job_ids = set(remote_jobs.keys()).difference(set(current_jobs)) @@ -368,7 +333,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self._print_jobs.append(model) @staticmethod - def _updateUM3PrintJobOutputModel(model: PrinterOutputModel, job: CloudClusterPrintJob) -> None: + def _updateUM3PrintJobOutputModel(model: UM3PrintJobOutputModel, job: CloudClusterPrintJob) -> None: model.updateTimeTotal(job.time_total) model.updateTimeElapsed(job.time_elapsed) model.updateOwner(job.owner) @@ -411,10 +376,10 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def _onPrintJobRequested(self, reply: QNetworkReply) -> None: status_code, response = self._parseReply(reply) - if status_code > 204 or not isinstance(response, dict): + if status_code > 204 or not isinstance(response, dict) or "data" not in response: Logger.log("w", "Got unexpected response while trying to request printing: %s, %s", status_code, response) return - print_response = PrintResponse(**response.get("data")) + print_response = PrintResponse(**response["data"]) Logger.log("i", "Print job requested successfully: %s", print_response.__dict__) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models.py b/plugins/UM3NetworkPrinting/src/Cloud/Models.py index 435f265300..780fa06172 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models.py @@ -8,11 +8,11 @@ from ..Models import BaseModel ## Class representing a cloud connected cluster. class CloudCluster(BaseModel): def __init__(self, **kwargs): - self.cluster_id = None # type: str - self.host_guid = None # type: str - self.host_name = None # type: str - self.host_version = None # type: str - self.status = None # type: str + self.cluster_id: str = None + self.host_guid: str = None + self.host_name: str = None + self.host_version: str = None + self.status: str = None super().__init__(**kwargs) def validate(self): @@ -23,81 +23,102 @@ class CloudCluster(BaseModel): ## Class representing a cloud cluster printer configuration class CloudClusterPrinterConfigurationMaterial(BaseModel): def __init__(self, **kwargs): - self.guid = None # type: str - self.brand = None # type: str - self.color = None # type: str - self.material = None # type: str + self.guid: str = None + self.brand: str = None + self.color: str = None + self.material: str = None super().__init__(**kwargs) ## Class representing a cloud cluster printer configuration class CloudClusterPrinterConfiguration(BaseModel): def __init__(self, **kwargs): - self.extruder_index = None # type: str - self.material = None # type: CloudClusterPrinterConfigurationMaterial - self.nozzle_diameter = None # type: str - self.print_core_id = None # type: str + self.extruder_index: str = None + self.material: CloudClusterPrinterConfigurationMaterial = None + self.nozzle_diameter: str = None + self.print_core_id: str = None super().__init__(**kwargs) + if isinstance(self.material, dict): + self.material = CloudClusterPrinterConfigurationMaterial(**self.material) + ## Class representing a cluster printer class CloudClusterPrinter(BaseModel): def __init__(self, **kwargs): - self.configuration = None # type: List[CloudClusterPrinterConfiguration] - self.enabled = None # type: str - self.firmware_version = None # type: str - self.friendly_name = None # type: str - self.ip_address = None # type: str - self.machine_variant = None # type: str - self.status = None # type: str - self.unique_name = None # type: str - self.uuid = None # type: str + self.configuration: List[CloudClusterPrinterConfiguration] = [] + self.enabled: str = None + self.firmware_version: str = None + self.friendly_name: str = None + self.ip_address: str = None + self.machine_variant: str = None + self.status: str = None + self.unique_name: str = None + self.uuid: str = None super().__init__(**kwargs) + self.configuration = [CloudClusterPrinterConfiguration(**c) + if isinstance(c, dict) else c for c in self.configuration] + ## Class representing a cloud cluster print job constraint class CloudClusterPrintJobConstraint(BaseModel): def __init__(self, **kwargs): - self.require_printer_name = None # type: str + self.require_printer_name: str = None super().__init__(**kwargs) + ## Class representing a print job class CloudClusterPrintJob(BaseModel): def __init__(self, **kwargs): - self.assigned_to = None # type: str - self.configuration = None # type: str - self.constraints = None # type: str - self.created_at = None # type: str - self.force = None # type: str - self.last_seen = None # type: str - self.machine_variant = None # type: str - self.name = None # type: str - self.network_error_count = None # type: str - self.owner = None # type: str - self.printer_uuid = None # type: str - self.started = None # type: str - self.status = None # type: str - self.time_elapsed = None # type: str - self.time_total = None # type: str - self.uuid = None # type: str + self.assigned_to: str = None + self.configuration: List[CloudClusterPrinterConfiguration] = [] + self.constraints: List[CloudClusterPrintJobConstraint] = [] + self.created_at: str = None + self.force: str = None + self.last_seen: str = None + self.machine_variant: str = None + self.name: str = None + self.network_error_count: int = None + self.owner: str = None + self.printer_uuid: str = None + self.started: str = None + self.status: str = None + self.time_elapsed: str = None + self.time_total: str = None + self.uuid: str = None super().__init__(**kwargs) + self.printers = [CloudClusterPrinterConfiguration(**c) if isinstance(c, dict) else c + for c in self.configuration] + self.printers = [CloudClusterPrintJobConstraint(**p) if isinstance(p, dict) else p + for p in self.constraints] + + +class CloudClusterStatus(BaseModel): + def __init__(self, **kwargs): + self.printers: List[CloudClusterPrinter] = [] + self.print_jobs: List[CloudClusterPrintJob] = [] + super().__init__(**kwargs) + + self.printers = [CloudClusterPrinter(**p) if isinstance(p, dict) else p for p in self.printers] + self.print_jobs = [CloudClusterPrintJob(**j) if isinstance(j, dict) else j for j in self.print_jobs] class JobUploadRequest(BaseModel): def __init__(self, **kwargs): - self.file_size = None # type: int - self.job_name = None # type: str + self.file_size: int = None + self.job_name: str = None super().__init__(**kwargs) class JobUploadResponse(BaseModel): def __init__(self, **kwargs): - self.download_url = None # type: str - self.job_id = None # type: str - self.job_name = None # type: str - self.slicing_details = None # type: str - self.status = None # type: str - self.upload_url = None # type: str + self.download_url: str = None + self.job_id: str = None + self.job_name: str = None + self.slicing_details: str = None + self.status: str = None + self.upload_url: str = None super().__init__(**kwargs) From 4e9c595bdd3dec5ac4f3688a4a25554fcf6f980d Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 3 Dec 2018 15:34:33 +0100 Subject: [PATCH 0606/1292] Restyle the settings list Be sure that the alignments and the margins are corrects according to the designs. Contributes to CURA-5941. --- resources/qml/Settings/SettingCategory.qml | 34 ++--- resources/qml/Settings/SettingItem.qml | 149 ++++++++++++--------- resources/themes/cura-light/theme.json | 2 +- 3 files changed, 104 insertions(+), 81 deletions(-) diff --git a/resources/qml/Settings/SettingCategory.qml b/resources/qml/Settings/SettingCategory.qml index 9a061304d4..9b78683e14 100644 --- a/resources/qml/Settings/SettingCategory.qml +++ b/resources/qml/Settings/SettingCategory.qml @@ -138,19 +138,20 @@ Button if (!base.enabled) { return UM.Theme.getColor("setting_category_disabled_text") - } else if ((base.hovered || base.activeFocus) && base.checkable && base.checked) + } + else if ((base.hovered || base.activeFocus) && base.checkable && base.checked) { return UM.Theme.getColor("setting_category_active_hover_text") - } else if (base.pressed || (base.checkable && base.checked)) + } + else if (base.pressed || (base.checkable && base.checked)) { return UM.Theme.getColor("setting_category_active_text") - } else if (base.hovered || base.activeFocus) + } + else if (base.hovered || base.activeFocus) { return UM.Theme.getColor("setting_category_hover_text") - } else - { - return UM.Theme.getColor("setting_category_text") } + return UM.Theme.getColor("setting_category_text") } source: base.checked ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") } @@ -161,25 +162,26 @@ Button id: icon anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("default_margin").width + anchors.leftMargin: UM.Theme.getSize("thin_margin").width color: { if (!base.enabled) { return UM.Theme.getColor("setting_category_disabled_text") - } else if((base.hovered || base.activeFocus) && base.checkable && base.checked) + } + else if((base.hovered || base.activeFocus) && base.checkable && base.checked) { return UM.Theme.getColor("setting_category_active_hover_text") - } else if(base.pressed || (base.checkable && base.checked)) + } + else if(base.pressed || (base.checkable && base.checked)) { return UM.Theme.getColor("setting_category_active_text") - } else if(base.hovered || base.activeFocus) + } + else if(base.hovered || base.activeFocus) { return UM.Theme.getColor("setting_category_hover_text") - } else - { - return UM.Theme.getColor("setting_category_text") } + return UM.Theme.getColor("setting_category_text") } source: UM.Theme.getIcon(definition.icon) width: UM.Theme.getSize("section_icon").width @@ -196,7 +198,9 @@ Button if (definition.expanded) { settingDefinitionsModel.collapse(definition.key) - } else { + } + else + { settingDefinitionsModel.expandRecursive(definition.key) } //Set focus so that tab navigation continues from this point on. @@ -205,7 +209,7 @@ Button } onActiveFocusChanged: { - if(activeFocus) + if (activeFocus) { base.focusReceived() } diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index df90cffdf3..4dd53f8663 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -15,6 +15,10 @@ Item id: base height: UM.Theme.getSize("section").height + anchors.left: parent.left + anchors.right: parent.right + // To avoid overlaping with the scrollBars + anchors.rightMargin: 2 * UM.Theme.getSize("thin_margin").width property alias contents: controlContainer.children property alias hovered: mouse.containsMouse @@ -44,25 +48,25 @@ Item var affected_by = settingDefinitionsModel.getRequires(definition.key, "value") var affected_by_list = "" - for(var i in affected_by) + for (var i in affected_by) { affected_by_list += "

    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%0A`jGbBzf40jzn#+ltV|2}r62J1oQa2y8OOvT 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

  • %1
  • \n".arg(affected_by[i].label) } var affects_list = "" - for(var i in affects) + for (var i in affects) { affects_list += "
  • %1
  • \n".arg(affects[i].label) } var tooltip = "%1\n

    %2

    ".arg(definition.label).arg(definition.description) - if(affects_list != "") + if (affects_list != "") { tooltip += "
    %1\n
      \n%2
    ".arg(catalog.i18nc("@label Header for list of settings.", "Affects")).arg(affects_list) } - if(affected_by_list != "") + if (affected_by_list != "") { tooltip += "
    %1\n
      \n%2
    ".arg(catalog.i18nc("@label Header for list of settings.", "Affected By")).arg(affected_by_list) } @@ -72,35 +76,39 @@ Item MouseArea { - id: mouse; + id: mouse - anchors.fill: parent; + anchors.fill: parent - acceptedButtons: Qt.RightButton; + acceptedButtons: Qt.RightButton hoverEnabled: true; - onClicked: base.contextMenuRequested(); + onClicked: base.contextMenuRequested() - onEntered: { - hoverTimer.start(); + onEntered: + { + hoverTimer.start() } - onExited: { - if(controlContainer.item && controlContainer.item.hovered) { - return; + onExited: + { + if (controlContainer.item && controlContainer.item.hovered) + { + return } - hoverTimer.stop(); - base.hideTooltip(); + hoverTimer.stop() + base.hideTooltip() } - Timer { - id: hoverTimer; - interval: 500; - repeat: false; + Timer + { + id: hoverTimer + interval: 500 + repeat: false onTriggered: { - base.showTooltip(base.tooltipText); + base.showTooltip(base.tooltipText) } } @@ -109,16 +117,16 @@ Item id: label anchors.left: parent.left - anchors.leftMargin: doDepthIndentation ? Math.round((UM.Theme.getSize("section_icon_column").width / 1.2) + ((definition.depth - 1) * UM.Theme.getSize("setting_control_depth_margin").width)) : 0 + anchors.leftMargin: doDepthIndentation ? Math.round(UM.Theme.getSize("thin_margin").width + ((definition.depth - 1) * UM.Theme.getSize("setting_control_depth_margin").width)) : 0 anchors.right: settingControls.left anchors.verticalCenter: parent.verticalCenter text: definition.label - elide: Text.ElideMiddle; + elide: Text.ElideMiddle renderType: Text.NativeRendering textFormat: Text.PlainText - color: UM.Theme.getColor("setting_control_text"); + color: UM.Theme.getColor("setting_control_text") opacity: (definition.visible) ? 1 : 0.5 // emphasize the setting if it has a value in the user or quality profile font: base.doQualityUserSettingEmphasis && base.stackLevel != undefined && base.stackLevel <= 1 ? UM.Theme.getFont("default_italic") : UM.Theme.getFont("default") @@ -131,7 +139,8 @@ Item height: Math.round(parent.height / 2) spacing: Math.round(UM.Theme.getSize("thick_margin").height / 2) - anchors { + anchors + { right: controlContainer.left rightMargin: Math.round(UM.Theme.getSize("thick_margin").width / 2) verticalCenter: parent.verticalCenter @@ -151,112 +160,123 @@ Item iconSource: UM.Theme.getIcon("link") - onEntered: { - hoverTimer.stop(); - var tooltipText = catalog.i18nc("@label", "This setting is always shared between all extruders. Changing it here will change the value for all extruders."); - if ((resolve != "None") && (stackLevel != 0)) { + onEntered: + { + hoverTimer.stop() + var tooltipText = catalog.i18nc("@label", "This setting is always shared between all extruders. Changing it here will change the value for all extruders.") + if ((resolve != "None") && (stackLevel != 0)) + { // We come here if a setting has a resolve and the setting is not manually edited. - tooltipText += " " + catalog.i18nc("@label", "The value is resolved from per-extruder values ") + "[" + Cura.ExtruderManager.getInstanceExtruderValues(definition.key) + "]."; + tooltipText += " " + catalog.i18nc("@label", "The value is resolved from per-extruder values ") + "[" + Cura.ExtruderManager.getInstanceExtruderValues(definition.key) + "]." } - base.showTooltip(tooltipText); + base.showTooltip(tooltipText) } - onExited: base.showTooltip(base.tooltipText); + onExited: base.showTooltip(base.tooltipText) } UM.SimpleButton { - id: revertButton; + id: revertButton visible: base.stackLevel == 0 && base.showRevertButton - height: parent.height; - width: height; + height: parent.height + width: height color: UM.Theme.getColor("setting_control_button") hoverColor: UM.Theme.getColor("setting_control_button_hover") iconSource: UM.Theme.getIcon("reset") - onClicked: { + onClicked: + { revertButton.focus = true - if (externalResetHandler) { + if (externalResetHandler) + { externalResetHandler(propertyProvider.key) - } else { + } + else + { Cura.MachineManager.clearUserSettingAllCurrentStacks(propertyProvider.key) } } - onEntered: { hoverTimer.stop(); base.showTooltip(catalog.i18nc("@label", "This setting has a value that is different from the profile.\n\nClick to restore the value of the profile.")) } - onExited: base.showTooltip(base.tooltipText); + onEntered: + { + hoverTimer.stop() + base.showTooltip(catalog.i18nc("@label", "This setting has a value that is different from the profile.\n\nClick to restore the value of the profile.")) + } + onExited: base.showTooltip(base.tooltipText) } UM.SimpleButton { // This button shows when the setting has an inherited function, but is overriden by profile. - id: inheritButton; + id: inheritButton // Inherit button needs to be visible if; // - User made changes that override any loaded settings // - This setting item uses inherit button at all // - The type of the value of any deeper container is an "object" (eg; is a function) visible: { - if(!base.showInheritButton) + if (!base.showInheritButton) { - return false; + return false } - if(!propertyProvider.properties.enabled) + if (!propertyProvider.properties.enabled) { // Note: This is not strictly necessary since a disabled setting is hidden anyway. // But this will cause the binding to be re-evaluated when the enabled property changes. - return false; + return false } // There are no settings with any warning. - if(Cura.SettingInheritanceManager.settingsWithInheritanceWarning.length == 0) + if (Cura.SettingInheritanceManager.settingsWithInheritanceWarning.length == 0) { - return false; + return false } // This setting has a resolve value, so an inheritance warning doesn't do anything. - if(resolve != "None") + if (resolve != "None") { return false } // If the setting does not have a limit_to_extruder property (or is -1), use the active stack. - if(globalPropertyProvider.properties.limit_to_extruder == null || String(globalPropertyProvider.properties.limit_to_extruder) == "-1") + if (globalPropertyProvider.properties.limit_to_extruder == null || String(globalPropertyProvider.properties.limit_to_extruder) == "-1") { - return Cura.SettingInheritanceManager.settingsWithInheritanceWarning.indexOf(definition.key) >= 0; + return Cura.SettingInheritanceManager.settingsWithInheritanceWarning.indexOf(definition.key) >= 0 } // Setting does have a limit_to_extruder property, so use that one instead. if (definition.key === undefined) { // Observed when loading workspace, probably when SettingItems are removed. - return false; + return false } - return Cura.SettingInheritanceManager.getOverridesForExtruder(definition.key, String(globalPropertyProvider.properties.limit_to_extruder)).indexOf(definition.key) >= 0; + return Cura.SettingInheritanceManager.getOverridesForExtruder(definition.key, String(globalPropertyProvider.properties.limit_to_extruder)).indexOf(definition.key) >= 0 } - height: parent.height; - width: height; + height: parent.height + width: height - onClicked: { - focus = true; + onClicked: + { + focus = true // Get the most shallow function value (eg not a number) that we can find. var last_entry = propertyProvider.stackLevels[propertyProvider.stackLevels.length - 1] for (var i = 1; i < base.stackLevels.length; i++) { - var has_setting_function = typeof(propertyProvider.getPropertyValue("value", base.stackLevels[i])) == "object"; + var has_setting_function = typeof(propertyProvider.getPropertyValue("value", base.stackLevels[i])) == "object" if(has_setting_function) { last_entry = propertyProvider.stackLevels[i] - break; + break } } - if((last_entry == 4 || last_entry == 11) && base.stackLevel == 0 && base.stackLevels.length == 2) + if ((last_entry == 4 || last_entry == 11) && base.stackLevel == 0 && base.stackLevels.length == 2) { // Special case of the inherit reset. If only the definition (4th or 11th) container) and the first // entry (user container) are set, we can simply remove the container. @@ -277,23 +297,22 @@ Item color: UM.Theme.getColor("setting_control_button") hoverColor: UM.Theme.getColor("setting_control_button_hover") - iconSource: UM.Theme.getIcon("formula"); + iconSource: UM.Theme.getIcon("formula") onEntered: { hoverTimer.stop(); base.showTooltip(catalog.i18nc("@label", "This setting is normally calculated, but it currently has an absolute value set.\n\nClick to restore the calculated value.")) } - onExited: base.showTooltip(base.tooltipText); + onExited: base.showTooltip(base.tooltipText) } } Item { - id: controlContainer; + id: controlContainer enabled: propertyProvider.isValueUsed - anchors.right: parent.right; - anchors.rightMargin: UM.Theme.getSize("default_margin").width * 3 - anchors.verticalCenter: parent.verticalCenter; - width: UM.Theme.getSize("setting_control").width; + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + width: UM.Theme.getSize("setting_control").width height: UM.Theme.getSize("setting_control").height } } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index dbe5e7196e..57532d91e5 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -416,7 +416,7 @@ "section_icon_column": [2.8, 0.0], "setting": [25.0, 1.8], - "setting_control": [10.0, 2.0], + "setting_control": [11.0, 2.0], "setting_control_radius": [0.15, 0.15], "setting_control_depth_margin": [1.4, 0.0], "setting_preferences_button_margin": [4, 0.0], From d3b5b2717d726ff99e22c372e1eaf2da48b2a73b Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 3 Dec 2018 15:56:21 +0100 Subject: [PATCH 0607/1292] Add rounded corners to the settings Contributes to CURA-5941 --- .../RecommendedSupportSelector.qml | 6 +-- resources/qml/Settings/SettingCheckBox.qml | 43 +++++++++++-------- resources/qml/Settings/SettingComboBox.qml | 1 + resources/qml/Settings/SettingExtruder.qml | 40 ++++++++--------- .../qml/Settings/SettingOptionalExtruder.qml | 29 ++++++------- resources/qml/Settings/SettingTextField.qml | 37 +++++++++------- 6 files changed, 81 insertions(+), 75 deletions(-) diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml index ce4aa6c195..da46f2a735 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml @@ -97,10 +97,10 @@ Item property string color_override: "" // for manually setting values property string color: // is evaluated automatically, but the first time is before extruderModel being filled { - var current_extruder = extruderModel.get(currentIndex); - color_override = ""; + var current_extruder = extruderModel.get(currentIndex) + color_override = "" if (current_extruder === undefined) return "" - return (current_extruder.color) ? current_extruder.color : ""; + return (current_extruder.color) ? current_extruder.color : "" } currentIndex: diff --git a/resources/qml/Settings/SettingCheckBox.qml b/resources/qml/Settings/SettingCheckBox.qml index d37754d27c..f53a696343 100644 --- a/resources/qml/Settings/SettingCheckBox.qml +++ b/resources/qml/Settings/SettingCheckBox.qml @@ -28,37 +28,40 @@ SettingItem // 3: material -> user changed material in materials page // 4: variant // 5: machine - var value; - if ((base.resolve != "None") && (stackLevel != 0) && (stackLevel != 1)) { + var value + if ((base.resolve != "None") && (stackLevel != 0) && (stackLevel != 1)) + { // We have a resolve function. Indicates that the setting is not settable per extruder and that // we have to choose between the resolved value (default) and the global value // (if user has explicitly set this). - value = base.resolve; - } else { - value = propertyProvider.properties.value; + value = base.resolve + } + else + { + value = propertyProvider.properties.value } switch(value) { case "True": - return true; + return true case "False": - return false; + return false default: - return value; + return value } } Keys.onSpacePressed: { - forceActiveFocus(); - propertyProvider.setPropertyValue("value", !checked); + forceActiveFocus() + propertyProvider.setPropertyValue("value", !checked) } onClicked: { - forceActiveFocus(); - propertyProvider.setPropertyValue("value", !checked); + forceActiveFocus() + propertyProvider.setPropertyValue("value", !checked) } Keys.onTabPressed: @@ -72,9 +75,9 @@ SettingItem onActiveFocusChanged: { - if(activeFocus) + if (activeFocus) { - base.focusReceived(); + base.focusReceived() } } @@ -90,32 +93,34 @@ SettingItem color: { - if(!enabled) + if (!enabled) { return UM.Theme.getColor("setting_control_disabled") } - if(control.containsMouse || control.activeFocus) + if (control.containsMouse || control.activeFocus) { return UM.Theme.getColor("setting_control_highlight") } return UM.Theme.getColor("setting_control") } + radius: UM.Theme.getSize("setting_control_radius").width border.width: UM.Theme.getSize("default_lining").width border.color: { - if(!enabled) + if (!enabled) { return UM.Theme.getColor("setting_control_disabled_border") } - if(control.containsMouse || control.activeFocus) + if (control.containsMouse || control.activeFocus) { return UM.Theme.getColor("setting_control_border_highlight") } return UM.Theme.getColor("setting_control_border") } - UM.RecolorImage { + UM.RecolorImage + { anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter width: Math.round(parent.width / 2.5) diff --git a/resources/qml/Settings/SettingComboBox.qml b/resources/qml/Settings/SettingComboBox.qml index 76d458e427..13d2a0eb8f 100644 --- a/resources/qml/Settings/SettingComboBox.qml +++ b/resources/qml/Settings/SettingComboBox.qml @@ -35,6 +35,7 @@ SettingItem return UM.Theme.getColor("setting_control") } + radius: UM.Theme.getSize("setting_control_radius").width border.width: UM.Theme.getSize("default_lining").width border.color: { diff --git a/resources/qml/Settings/SettingExtruder.qml b/resources/qml/Settings/SettingExtruder.qml index a9427f863a..e1fedd9274 100644 --- a/resources/qml/Settings/SettingExtruder.qml +++ b/resources/qml/Settings/SettingExtruder.qml @@ -19,8 +19,9 @@ SettingItem model: Cura.ExtrudersModel { - onModelChanged: { - control.color = getItem(control.currentIndex).color; + onModelChanged: + { + control.color = getItem(control.currentIndex).color } } @@ -113,14 +114,15 @@ SettingItem { if (!enabled) { - return UM.Theme.getColor("setting_control_disabled"); + return UM.Theme.getColor("setting_control_disabled") } if (control.hovered || base.activeFocus) { - return UM.Theme.getColor("setting_control_highlight"); + return UM.Theme.getColor("setting_control_highlight") } - return UM.Theme.getColor("setting_control"); + return UM.Theme.getColor("setting_control") } + radius: UM.Theme.getSize("setting_control_radius").width border.width: UM.Theme.getSize("default_lining").width border.color: { @@ -153,20 +155,18 @@ SettingItem elide: Text.ElideLeft verticalAlignment: Text.AlignVCenter - background: Rectangle + background: UM.RecolorImage { id: swatch - height: Math.round(UM.Theme.getSize("setting_control").height / 2) + height: Math.round(parent.height / 2) width: height - anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter - anchors.margins: Math.round(UM.Theme.getSize("default_margin").width / 4) - - border.width: UM.Theme.getSize("default_lining").width - border.color: enabled ? UM.Theme.getColor("setting_control_border") : UM.Theme.getColor("setting_control_disabled_border") - radius: Math.round(width / 2) + anchors.rightMargin: UM.Theme.getSize("thin_margin").width + sourceSize.width: width + sourceSize.height: height + source: UM.Theme.getIcon("extruder_button") color: control.color } } @@ -219,20 +219,18 @@ SettingItem verticalAlignment: Text.AlignVCenter rightPadding: swatch.width + UM.Theme.getSize("setting_unit_margin").width - background: Rectangle + background: UM.RecolorImage { id: swatch - height: Math.round(UM.Theme.getSize("setting_control").height / 2) + height: Math.round(parent.height / 2) width: height - anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter - anchors.margins: Math.round(UM.Theme.getSize("default_margin").width / 4) - - border.width: UM.Theme.getSize("default_lining").width - border.color: enabled ? UM.Theme.getColor("setting_control_border") : UM.Theme.getColor("setting_control_disabled_border") - radius: Math.round(width / 2) + anchors.rightMargin: UM.Theme.getSize("thin_margin").width + sourceSize.width: width + sourceSize.height: height + source: UM.Theme.getIcon("extruder_button") color: control.model.getItem(index).color } } diff --git a/resources/qml/Settings/SettingOptionalExtruder.qml b/resources/qml/Settings/SettingOptionalExtruder.qml index a3c1422b30..53044b0f82 100644 --- a/resources/qml/Settings/SettingOptionalExtruder.qml +++ b/resources/qml/Settings/SettingOptionalExtruder.qml @@ -116,6 +116,7 @@ SettingItem } return UM.Theme.getColor("setting_control"); } + radius: UM.Theme.getSize("setting_control_radius").width border.width: UM.Theme.getSize("default_lining").width border.color: { @@ -148,20 +149,18 @@ SettingItem elide: Text.ElideRight verticalAlignment: Text.AlignVCenter - background: Rectangle + background: UM.RecolorImage { id: swatch - height: Math.round(UM.Theme.getSize("setting_control").height / 2) + height: Math.round(parent.height / 2) width: height - anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter - anchors.margins: Math.round(UM.Theme.getSize("default_margin").width / 4) - - border.width: UM.Theme.getSize("default_lining").width - border.color: enabled ? UM.Theme.getColor("setting_control_border") : UM.Theme.getColor("setting_control_disabled_border") - radius: Math.round(width / 2) + anchors.rightMargin: UM.Theme.getSize("thin_margin").width + sourceSize.width: width + sourceSize.height: height + source: UM.Theme.getIcon("extruder_button") color: control.color } } @@ -215,20 +214,18 @@ SettingItem verticalAlignment: Text.AlignVCenter rightPadding: swatch.width + UM.Theme.getSize("setting_unit_margin").width - background: Rectangle + background: UM.RecolorImage { id: swatch - height: Math.round(UM.Theme.getSize("setting_control").height / 2) + height: Math.round(parent.height / 2) width: height - anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter - anchors.margins: Math.round(UM.Theme.getSize("default_margin").width / 4) - - border.width: UM.Theme.getSize("default_lining").width - border.color: enabled ? UM.Theme.getColor("setting_control_border") : UM.Theme.getColor("setting_control_disabled_border") - radius: Math.round(width / 2) + anchors.rightMargin: UM.Theme.getSize("thin_margin").width + sourceSize.width: width + sourceSize.height: height + source: UM.Theme.getIcon("extruder_button") color: control.model.getItem(index).color } } diff --git a/resources/qml/Settings/SettingTextField.qml b/resources/qml/Settings/SettingTextField.qml index 9ec9338316..770ef53900 100644 --- a/resources/qml/Settings/SettingTextField.qml +++ b/resources/qml/Settings/SettingTextField.qml @@ -32,6 +32,7 @@ SettingItem anchors.fill: parent + radius: UM.Theme.getSize("setting_control_radius").width border.width: Math.round(UM.Theme.getSize("default_lining").width) border.color: { @@ -81,10 +82,10 @@ SettingItem Rectangle { - anchors.fill: parent; - anchors.margins: Math.round(UM.Theme.getSize("default_lining").width); + anchors.fill: parent + anchors.margins: Math.round(UM.Theme.getSize("default_lining").width) color: UM.Theme.getColor("setting_control_highlight") - opacity: !control.hovered ? 0 : propertyProvider.properties.validationState == "ValidatorState.Valid" ? 1.0 : 0.35; + opacity: !control.hovered ? 0 : propertyProvider.properties.validationState == "ValidatorState.Valid" ? 1.0 : 0.35 } Label @@ -145,11 +146,11 @@ SettingItem } color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text") - font: UM.Theme.getFont("default"); + font: UM.Theme.getFont("default") - selectByMouse: true; + selectByMouse: true - maximumLength: (definition.type == "str" || definition.type == "[int]") ? -1 : 10; + maximumLength: (definition.type == "str" || definition.type == "[int]") ? -1 : 10 clip: true; //Hide any text that exceeds the width of the text box. validator: RegExpValidator { regExp: (definition.type == "[int]") ? /^\[?(\s*-?[0-9]{0,9}\s*,)*(\s*-?[0-9]{0,9})\s*\]?$/ : (definition.type == "int") ? /^-?[0-9]{0,10}$/ : (definition.type == "float") ? /^-?[0-9]{0,9}[.,]?[0-9]{0,3}$/ : /^.*$/ } // definition.type property from parent loader used to disallow fractional number entry @@ -158,7 +159,8 @@ SettingItem { target: input property: "text" - value: { + value: + { // Stacklevels // 0: user -> unsaved change // 1: quality changes -> saved change @@ -167,13 +169,15 @@ SettingItem // 4: variant // 5: machine_changes // 6: machine - if ((base.resolve != "None" && base.resolve) && (stackLevel != 0) && (stackLevel != 1)) { + if ((base.resolve != "None" && base.resolve) && (stackLevel != 0) && (stackLevel != 1)) + { // We have a resolve function. Indicates that the setting is not settable per extruder and that // we have to choose between the resolved value (default) and the global value // (if user has explicitly set this). - return base.resolve; - } else { - return propertyProvider.properties.value; + return base.resolve + } + else { + return propertyProvider.properties.value } } when: !input.activeFocus @@ -182,16 +186,17 @@ SettingItem MouseArea { id: mouseArea - anchors.fill: parent; + anchors.fill: parent cursorShape: Qt.IBeamCursor onPressed: { - if(!input.activeFocus) { - base.focusGainedByClick = true; - input.forceActiveFocus(); + if (!input.activeFocus) + { + base.focusGainedByClick = true + input.forceActiveFocus() } - mouse.accepted = false; + mouse.accepted = false } } } From ddf958d39ab3fe5c8a9712cfbe441d44dc853bd8 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 3 Dec 2018 16:23:44 +0100 Subject: [PATCH 0608/1292] Fix typing in CloudOutputDevice --- plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index c478f15ade..3d577d0991 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -224,8 +224,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self._updatePrintJobs(status.print_jobs) def _updatePrinters(self, printers: List[CloudClusterPrinter]) -> None: - remote_printers: Dict[str, CloudClusterPrinter] = {p.uuid: p for p in printers} - current_printers: Dict[str, PrinterOutputModel] = {p.key: p for p in self._printers} + remote_printers = {p.uuid: p for p in printers} # type: Dict[str, CloudClusterPrinter] + current_printers = {p.key: p for p in self._printers} # type: Dict[str, PrinterOutputModel] removed_printer_ids = set(current_printers).difference(remote_printers) new_printer_ids = set(remote_printers).difference(current_printers) @@ -302,8 +302,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): return MaterialOutputModel(guid=material.guid, type=material_type, brand=brand, color=color, name=name) def _updatePrintJobs(self, jobs: List[CloudClusterPrintJob]) -> None: - remote_jobs: Dict[str, CloudClusterPrintJob] = {j.uuid: j for j in jobs} - current_jobs: Dict[str, UM3PrintJobOutputModel] = {j.key: j for j in self._print_jobs} + remote_jobs = {j.uuid: j for j in jobs} # type: Dict[str, CloudClusterPrintJob] + current_jobs = {j.key: j for j in self._print_jobs} # type: Dict[str, UM3PrintJobOutputModel] removed_job_ids = set(current_jobs).difference(set(remote_jobs)) new_job_ids = set(remote_jobs.keys()).difference(set(current_jobs)) From 186c2cf3f5e7430fd50fbd7dc83a40f6d29be023 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 3 Dec 2018 16:35:51 +0100 Subject: [PATCH 0609/1292] START-322: Python 3.5 compatibility --- .../src/Cloud/CloudOutputDevice.py | 8 +- .../UM3NetworkPrinting/src/Cloud/Models.py | 104 +++++++++--------- 2 files changed, 56 insertions(+), 56 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index c478f15ade..3d577d0991 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -224,8 +224,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self._updatePrintJobs(status.print_jobs) def _updatePrinters(self, printers: List[CloudClusterPrinter]) -> None: - remote_printers: Dict[str, CloudClusterPrinter] = {p.uuid: p for p in printers} - current_printers: Dict[str, PrinterOutputModel] = {p.key: p for p in self._printers} + remote_printers = {p.uuid: p for p in printers} # type: Dict[str, CloudClusterPrinter] + current_printers = {p.key: p for p in self._printers} # type: Dict[str, PrinterOutputModel] removed_printer_ids = set(current_printers).difference(remote_printers) new_printer_ids = set(remote_printers).difference(current_printers) @@ -302,8 +302,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): return MaterialOutputModel(guid=material.guid, type=material_type, brand=brand, color=color, name=name) def _updatePrintJobs(self, jobs: List[CloudClusterPrintJob]) -> None: - remote_jobs: Dict[str, CloudClusterPrintJob] = {j.uuid: j for j in jobs} - current_jobs: Dict[str, UM3PrintJobOutputModel] = {j.key: j for j in self._print_jobs} + remote_jobs = {j.uuid: j for j in jobs} # type: Dict[str, CloudClusterPrintJob] + current_jobs = {j.key: j for j in self._print_jobs} # type: Dict[str, UM3PrintJobOutputModel] removed_job_ids = set(current_jobs).difference(set(remote_jobs)) new_job_ids = set(remote_jobs.keys()).difference(set(current_jobs)) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models.py b/plugins/UM3NetworkPrinting/src/Cloud/Models.py index 780fa06172..7b9ad460c5 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models.py @@ -8,11 +8,11 @@ from ..Models import BaseModel ## Class representing a cloud connected cluster. class CloudCluster(BaseModel): def __init__(self, **kwargs): - self.cluster_id: str = None - self.host_guid: str = None - self.host_name: str = None - self.host_version: str = None - self.status: str = None + self.cluster_id = None # type: str + self.host_guid = None # type: str + self.host_name = None # type: str + self.host_version = None # type: str + self.status = None # type: str super().__init__(**kwargs) def validate(self): @@ -23,20 +23,20 @@ class CloudCluster(BaseModel): ## Class representing a cloud cluster printer configuration class CloudClusterPrinterConfigurationMaterial(BaseModel): def __init__(self, **kwargs): - self.guid: str = None - self.brand: str = None - self.color: str = None - self.material: str = None + self.guid = None # type: str + self.brand = None # type: str + self.color = None # type: str + self.material = None # type: str super().__init__(**kwargs) ## Class representing a cloud cluster printer configuration class CloudClusterPrinterConfiguration(BaseModel): def __init__(self, **kwargs): - self.extruder_index: str = None - self.material: CloudClusterPrinterConfigurationMaterial = None - self.nozzle_diameter: str = None - self.print_core_id: str = None + self.extruder_index = None # type: str + self.material = None # type: CloudClusterPrinterConfigurationMaterial + self.nozzle_diameter = None # type: str + self.print_core_id = None # type: str super().__init__(**kwargs) if isinstance(self.material, dict): @@ -46,15 +46,15 @@ class CloudClusterPrinterConfiguration(BaseModel): ## Class representing a cluster printer class CloudClusterPrinter(BaseModel): def __init__(self, **kwargs): - self.configuration: List[CloudClusterPrinterConfiguration] = [] - self.enabled: str = None - self.firmware_version: str = None - self.friendly_name: str = None - self.ip_address: str = None - self.machine_variant: str = None - self.status: str = None - self.unique_name: str = None - self.uuid: str = None + self.configuration = [] # type: List[CloudClusterPrinterConfiguration] + self.enabled = None # type: str + self.firmware_version = None # type: str + self.friendly_name = None # type: str + self.ip_address = None # type: str + self.machine_variant = None # type: str + self.status = None # type: str + self.unique_name = None # type: str + self.uuid = None # type: str super().__init__(**kwargs) self.configuration = [CloudClusterPrinterConfiguration(**c) @@ -64,29 +64,29 @@ class CloudClusterPrinter(BaseModel): ## Class representing a cloud cluster print job constraint class CloudClusterPrintJobConstraint(BaseModel): def __init__(self, **kwargs): - self.require_printer_name: str = None + self.require_printer_name = None # type: str super().__init__(**kwargs) ## Class representing a print job class CloudClusterPrintJob(BaseModel): def __init__(self, **kwargs): - self.assigned_to: str = None - self.configuration: List[CloudClusterPrinterConfiguration] = [] - self.constraints: List[CloudClusterPrintJobConstraint] = [] - self.created_at: str = None - self.force: str = None - self.last_seen: str = None - self.machine_variant: str = None - self.name: str = None - self.network_error_count: int = None - self.owner: str = None - self.printer_uuid: str = None - self.started: str = None - self.status: str = None - self.time_elapsed: str = None - self.time_total: str = None - self.uuid: str = None + self.assigned_to = None # type: str + self.configuration = [] # type: List[CloudClusterPrinterConfiguration] + self.constraints = [] # type: List[CloudClusterPrintJobConstraint] + self.created_at = None # type: str + self.force = None # type: str + self.last_seen = None # type: str + self.machine_variant = None # type: str + self.name = None # type: str + self.network_error_count = None # type: int + self.owner = None # type: str + self.printer_uuid = None # type: str + self.started = None # type: str + self.status = None # type: str + self.time_elapsed = None # type: str + self.time_total = None # type: str + self.uuid = None # type: str super().__init__(**kwargs) self.printers = [CloudClusterPrinterConfiguration(**c) if isinstance(c, dict) else c for c in self.configuration] @@ -96,8 +96,8 @@ class CloudClusterPrintJob(BaseModel): class CloudClusterStatus(BaseModel): def __init__(self, **kwargs): - self.printers: List[CloudClusterPrinter] = [] - self.print_jobs: List[CloudClusterPrintJob] = [] + self.printers = [] # type: List[CloudClusterPrinter] + self.print_jobs = [] # type: List[CloudClusterPrintJob] super().__init__(**kwargs) self.printers = [CloudClusterPrinter(**p) if isinstance(p, dict) else p for p in self.printers] @@ -106,25 +106,25 @@ class CloudClusterStatus(BaseModel): class JobUploadRequest(BaseModel): def __init__(self, **kwargs): - self.file_size: int = None - self.job_name: str = None + self.file_size = None # type: int + self.job_name = None # type: str super().__init__(**kwargs) class JobUploadResponse(BaseModel): def __init__(self, **kwargs): - self.download_url: str = None - self.job_id: str = None - self.job_name: str = None - self.slicing_details: str = None - self.status: str = None - self.upload_url: str = None + self.download_url = None # type: str + self.job_id = None # type: str + self.job_name = None # type: str + self.slicing_details = None # type: str + self.status = None # type: str + self.upload_url = None # type: str super().__init__(**kwargs) class PrintResponse(BaseModel): def __init__(self, **kwargs): - self.cluster_job_id: str = None - self.job_id: str = None - self.status: str = None + self.cluster_job_id = None # type: str + self.job_id = None # type: str + self.status = None # type: str super().__init__(**kwargs) From 15415dc3b98e70a2dd299c4d2cdef1a2065c1185 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 3 Dec 2018 16:53:52 +0100 Subject: [PATCH 0610/1292] Fix position of the tooltips for the settings Contributes to CURA-5941 --- resources/qml/Settings/SettingView.qml | 2 +- resources/themes/cura-light/theme.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index ff94c9168f..867d662edc 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -360,7 +360,7 @@ Item contextMenu.provider = provider contextMenu.popup(); } - onShowTooltip: base.showTooltip(delegate, Qt.point(- UM.Theme.getSize("default_arrow").width, 0), text) + onShowTooltip: base.showTooltip(delegate, Qt.point(- settingsView.x - UM.Theme.getSize("default_margin").width, 0), text) onHideTooltip: base.hideTooltip() onShowAllHiddenInheritedSettings: { diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 57532d91e5..3d0169dac9 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -35,7 +35,7 @@ "family": "Noto Sans" }, "default_italic": { - "size": 1.15, + "size": 1.0, "weight": 50, "italic": true, "family": "Noto Sans" From 5db6bd9a9bd7334e2f8d27de892094a39df806d9 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 3 Dec 2018 17:09:04 +0100 Subject: [PATCH 0611/1292] Send content type to API when uploading print job --- .../UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py | 9 +++++++-- plugins/UM3NetworkPrinting/src/Cloud/Models.py | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 3d577d0991..dbb5ebf263 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -129,7 +129,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): stream = io.StringIO() if file_format["mode"] == FileWriter.OutputMode.TextMode else io.BytesIO() writer.write(stream, nodes) - self._sendPrintJob(file_name + "." + file_format["extension"], stream) + self._sendPrintJob(file_name + "." + file_format["extension"], file_format["mime_type"], stream) # TODO: This is yanked right out of ClusterUM3OutputDevice, great candidate for a utility or base class def _determineFileFormat(self, file_handler) -> Optional[Dict[str, Union[str, int]]]: @@ -339,12 +339,13 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): model.updateOwner(job.owner) model.updateState(job.status) - def _sendPrintJob(self, file_name: str, stream: Union[io.StringIO, io.BytesIO]) -> None: + def _sendPrintJob(self, file_name: str, content_type: str, stream: Union[io.StringIO, io.BytesIO]) -> None: mesh = stream.getvalue() request = JobUploadRequest() request.job_name = file_name request.file_size = len(mesh) + request.content_type = content_type Logger.log("i", "Creating new cloud print job: %s", request.__dict__) self.put("{}/jobs/upload".format(self.CURA_API_ROOT), data = json.dumps({"data": request.__dict__}), @@ -355,6 +356,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): if status_code > 204 or not isinstance(response, dict) or "data" not in response: Logger.log("w", "Got unexpected response while trying to add print job to cluster: {}, {}" .format(status_code, response)) + self.writeError.emit() return # TODO: Multipart upload @@ -368,6 +370,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): if status_code > 204: Logger.logException("w", "Received unexpected response from the job upload: %s, %s.", status_code, bytes(reply.readAll()).decode()) + self.writeError.emit() return Logger.log("i", "Print job uploaded successfully: %s", reply.readAll()) @@ -379,7 +382,9 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): if status_code > 204 or not isinstance(response, dict) or "data" not in response: Logger.log("w", "Got unexpected response while trying to request printing: %s, %s", status_code, response) + self.writeError.emit() return print_response = PrintResponse(**response["data"]) Logger.log("i", "Print job requested successfully: %s", print_response.__dict__) + self.writeFinished.emit() diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models.py b/plugins/UM3NetworkPrinting/src/Cloud/Models.py index 7b9ad460c5..22a733c70e 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models.py @@ -108,6 +108,7 @@ class JobUploadRequest(BaseModel): def __init__(self, **kwargs): self.file_size = None # type: int self.job_name = None # type: str + self.content_type = None # type: str super().__init__(**kwargs) From 90ec3f6cf95e2d1d545320845c642f5af3901605 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 3 Dec 2018 17:22:21 +0100 Subject: [PATCH 0612/1292] Add TODO for progress messages --- plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index dbb5ebf263..28b219469a 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -359,6 +359,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self.writeError.emit() return + # TODO: add progress messages so we have visual feedback when uploading to cloud # TODO: Multipart upload job_response = JobUploadResponse(**response.get("data")) Logger.log("i", "Print job created successfully: %s", job_response.__dict__) From f320000ce5e5019d8f96af20b29aa266b54856f6 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 3 Dec 2018 17:23:44 +0100 Subject: [PATCH 0613/1292] Change default profile of Aurora and Alfawise printers Instead of the default layer height, we should change the default quality profile. This is necessary because the 'normal' quality profile doesn't define a layer height, so that should inherit from the 0.1mm default layer height. But if the printer turned the default into a 0.15mm layer height then that is wrong. Maybe we should let the normal quality profile overwrite it to 0.1mm, always? Contributes to issue CURA-5902. --- resources/definitions/alfawise_u20.def.json | 5 +---- resources/definitions/jgaurora_a1.def.json | 5 +---- resources/definitions/jgaurora_a5.def.json | 5 +---- resources/definitions/jgaurora_z_603s.def.json | 5 +---- 4 files changed, 4 insertions(+), 16 deletions(-) diff --git a/resources/definitions/alfawise_u20.def.json b/resources/definitions/alfawise_u20.def.json index 87726fec3d..de8525fa4d 100644 --- a/resources/definitions/alfawise_u20.def.json +++ b/resources/definitions/alfawise_u20.def.json @@ -7,7 +7,7 @@ "author": "Samuel Pinches", "manufacturer": "Alfawise", "file_formats": "text/x-gcode", - "preferred_quality_type": "fine", + "preferred_quality_type": "fast", "machine_extruder_trains": { "0": "alfawise_u20_extruder_0" @@ -53,9 +53,6 @@ "material_bed_temperature": { "default_value": 50 }, - "layer_height": { - "default_value": 0.15 - }, "layer_height_0": { "default_value": 0.2 }, diff --git a/resources/definitions/jgaurora_a1.def.json b/resources/definitions/jgaurora_a1.def.json index 4fd2eb4994..b9a921c311 100644 --- a/resources/definitions/jgaurora_a1.def.json +++ b/resources/definitions/jgaurora_a1.def.json @@ -7,7 +7,7 @@ "author": "Samuel Pinches", "manufacturer": "JGAurora", "file_formats": "text/x-gcode", - "preferred_quality_type": "fine", + "preferred_quality_type": "fast", "machine_extruder_trains": { "0": "jgaurora_a1_extruder_0" @@ -53,9 +53,6 @@ "material_bed_temperature": { "default_value": 67 }, - "layer_height": { - "default_value": 0.15 - }, "layer_height_0": { "default_value": 0.12 }, diff --git a/resources/definitions/jgaurora_a5.def.json b/resources/definitions/jgaurora_a5.def.json index 02d9a9db4f..d84a8440e6 100644 --- a/resources/definitions/jgaurora_a5.def.json +++ b/resources/definitions/jgaurora_a5.def.json @@ -9,7 +9,7 @@ "file_formats": "text/x-gcode", "platform": "jgaurora_a5.stl", "platform_offset": [-242, -101, 273], - "preferred_quality_type": "fine", + "preferred_quality_type": "fast", "machine_extruder_trains": { "0": "jgaurora_a5_extruder_0" @@ -55,9 +55,6 @@ "material_bed_temperature": { "default_value": 67 }, - "layer_height": { - "default_value": 0.15 - }, "layer_height_0": { "default_value": 0.12 }, diff --git a/resources/definitions/jgaurora_z_603s.def.json b/resources/definitions/jgaurora_z_603s.def.json index 59e0ff129c..3a78585240 100644 --- a/resources/definitions/jgaurora_z_603s.def.json +++ b/resources/definitions/jgaurora_z_603s.def.json @@ -7,7 +7,7 @@ "author": "Samuel Pinches", "manufacturer": "JGAurora", "file_formats": "text/x-gcode", - "preferred_quality_type": "fine", + "preferred_quality_type": "fast", "machine_extruder_trains": { "0": "jgaurora_z_603s_extruder_0" @@ -53,9 +53,6 @@ "material_bed_temperature": { "default_value": 55 }, - "layer_height": { - "default_value": 0.15 - }, "layer_height_0": { "default_value": 0.2 }, From 004405e5f97337c5acfafda2da0c75bc4a9e7004 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 3 Dec 2018 17:25:07 +0100 Subject: [PATCH 0614/1292] Change the colors to match the designs. Contributes to CURA-5941. --- .../PrintSetupSelectorContents.qml | 6 +-- resources/qml/Settings/SettingCategory.qml | 26 ----------- resources/themes/cura-light/styles.qml | 2 +- resources/themes/cura-light/theme.json | 46 +++++++++---------- 4 files changed, 27 insertions(+), 53 deletions(-) diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml index 77d1b59f4c..358cba8ad0 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml @@ -25,7 +25,7 @@ Item { id: header height: UM.Theme.getSize("print_setup_widget_header").height - color: UM.Theme.getColor("action_button_hovered") // TODO: It's not clear the color that we need to use here + color: UM.Theme.getColor("secondary") anchors { @@ -46,9 +46,9 @@ Item anchors { - topMargin: UM.Theme.getSize("sidebar_margin").height + topMargin: UM.Theme.getSize("default_margin").height left: parent.left - leftMargin: UM.Theme.getSize("narrow_margin").height + leftMargin: UM.Theme.getSize("default_margin").height } } diff --git a/resources/qml/Settings/SettingCategory.qml b/resources/qml/Settings/SettingCategory.qml index 9b78683e14..be93f8ffab 100644 --- a/resources/qml/Settings/SettingCategory.qml +++ b/resources/qml/Settings/SettingCategory.qml @@ -45,32 +45,6 @@ Button return UM.Theme.getColor("setting_category") } Behavior on color { ColorAnimation { duration: 50; } } - Rectangle - { - id: backgroundLiningRectangle - height: UM.Theme.getSize("default_lining").height - width: parent.width - anchors.bottom: parent.bottom - color: - { - if (!base.enabled) - { - return UM.Theme.getColor("setting_category_disabled_border") - } else if ((base.hovered || base.activeFocus) && base.checkable && base.checked) - { - return UM.Theme.getColor("setting_category_active_hover_border") - } else if (base.pressed || (base.checkable && base.checked)) - { - return UM.Theme.getColor("setting_category_active_border") - } else if (base.hovered || base.activeFocus) - { - return UM.Theme.getColor("setting_category_hover_border") - } else - { - return UM.Theme.getColor("setting_category_border") - } - } - } } signal showTooltip(string text) diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index eed5393a0b..66c000af62 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -393,7 +393,7 @@ QtObject implicitWidth: Theme.getSize("scrollbar").width radius: Math.round(implicitWidth / 2) - color: styleData.pressed ? Theme.getColor("scrollbar_handle_down") : styleData.hovered ? Theme.getColor("scrollbar_handle_hover") : Theme.getColor("scrollbar_handle"); + color: styleData.pressed ? Theme.getColor("scrollbar_handle_down") : styleData.hovered ? Theme.getColor("scrollbar_handle_hover") : Theme.getColor("scrollbar_handle") Behavior on color { ColorAnimation { duration: 50; } } } } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 3d0169dac9..8e440757aa 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -86,7 +86,7 @@ "primary_hover": [48, 182, 231, 255], "primary_text": [255, 255, 255, 255], "border": [127, 127, 127, 255], - "secondary": [240, 240, 240, 255], + "secondary": [245, 245, 245, 255], "secondary_shadow": [216, 216, 216, 255], "primary_button": [38, 113, 231, 255], @@ -183,25 +183,25 @@ "action_button_disabled_shadow": [228, 228, 228, 255], "scrollbar_background": [255, 255, 255, 255], - "scrollbar_handle": [31, 36, 39, 255], - "scrollbar_handle_hover": [12, 159, 227, 255], - "scrollbar_handle_down": [12, 159, 227, 255], + "scrollbar_handle": [10, 8, 80, 255], + "scrollbar_handle_hover": [50, 130, 255, 255], + "scrollbar_handle_down": [50, 130, 255, 255], "setting_category": [245, 245, 245, 255], "setting_category_disabled": [255, 255, 255, 255], - "setting_category_hover": [245, 245, 245, 255], + "setting_category_hover": [232, 242, 252, 255], "setting_category_active": [245, 245, 245, 255], - "setting_category_active_hover": [245, 245, 245, 255], - "setting_category_text": [31, 36, 39, 255], + "setting_category_active_hover": [232, 242, 252, 255], + "setting_category_text": [35, 35, 35, 255], "setting_category_disabled_text": [24, 41, 77, 101], - "setting_category_hover_text": [31, 36, 39, 255], - "setting_category_active_text": [31, 36, 39, 255], - "setting_category_active_hover_text": [31, 36, 39, 255], + "setting_category_hover_text": [35, 35, 35, 255], + "setting_category_active_text": [35, 35, 35, 255], + "setting_category_active_hover_text": [35, 35, 35, 255], "setting_category_border": [245, 245, 245, 255], "setting_category_disabled_border": [245, 245, 245, 255], - "setting_category_hover_border": [12, 159, 227, 255], - "setting_category_active_border": [245, 245, 245, 255], - "setting_category_active_hover_border": [12, 159, 227, 255], + "setting_category_hover_border": [50, 130, 255, 255], + "setting_category_active_border": [50, 130, 255, 255], + "setting_category_active_hover_border": [50, 130, 255, 255], "setting_control": [255, 255, 255, 255], "setting_control_selected": [31, 36, 39, 255], @@ -298,16 +298,16 @@ "xray_error": [255, 0, 0, 255], "layerview_ghost": [32, 32, 32, 96], - "layerview_none": [255, 255, 255, 255], - "layerview_inset_0": [255, 0, 0, 255], - "layerview_inset_x": [0, 255, 0, 255], - "layerview_skin": [255, 255, 0, 255], - "layerview_support": [0, 255, 255, 255], - "layerview_skirt": [0, 255, 255, 255], - "layerview_infill": [255, 192, 0, 255], - "layerview_support_infill": [0, 255, 255, 255], - "layerview_move_combing": [0, 0, 255, 255], - "layerview_move_retraction": [128, 128, 255, 255], + "layerview_none": [255, 255, 255, 255], + "layerview_inset_0": [255, 0, 0, 255], + "layerview_inset_x": [0, 255, 0, 255], + "layerview_skin": [255, 255, 0, 255], + "layerview_support": [0, 255, 255, 255], + "layerview_skirt": [0, 255, 255, 255], + "layerview_infill": [255, 192, 0, 255], + "layerview_support_infill": [0, 255, 255, 255], + "layerview_move_combing": [0, 0, 255, 255], + "layerview_move_retraction": [128, 128, 255, 255], "layerview_support_interface": [64, 192, 255, 255], "layerview_nozzle": [181, 166, 66, 50], From 9b8b91b6a41eef06b504f47474d213f54335a308 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 3 Dec 2018 17:34:08 +0100 Subject: [PATCH 0615/1292] More specific variable type for is_connected Contributes to issue CURA-5876. Co-Authored-By: Ghostkeeper --- resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index fc8b31f125..79b7c9bf66 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -102,7 +102,7 @@ Cura.ExpandableComponent height: implicitHeight //Required because ExpandableComponent will try to use this to determine the size of the background of the pop-up. spacing: UM.Theme.getSize("default_margin").height - property var is_connected: false //If current machine is connected to a printer. Only evaluated upon making popup visible. + property bool is_connected: false //If current machine is connected to a printer. Only evaluated upon making popup visible. onVisibleChanged: { is_connected = Cura.MachineManager.activeMachineNetworkKey !== "" && Cura.MachineManager.printerConnected //Re-evaluate. From d91efc656a28b4d5b94e9f2bff987a3c1ccca493 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 3 Dec 2018 17:38:31 +0100 Subject: [PATCH 0616/1292] Add some more todo's for UI messages --- .../src/Cloud/CloudOutputDevice.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 28b219469a..2f59b6aeea 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -13,6 +13,7 @@ from UM import i18nCatalog from UM.FileHandler.FileWriter import FileWriter from UM.FileHandler.FileHandler import FileHandler from UM.Logger import Logger +from UM.Message import Message from UM.OutputDevice import OutputDeviceError from UM.Scene.SceneNode import SceneNode from UM.Version import Version @@ -389,3 +390,17 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): print_response = PrintResponse(**response["data"]) Logger.log("i", "Print job requested successfully: %s", print_response.__dict__) self.writeFinished.emit() + + def _showUploadErrorMessage(self): + message = Message(self.I18N_CATALOG.i18nc( + "@info:status", "Sending new jobs (temporarily) blocked, still sending the previous print job.")) + message.show() + + def _showOrUpdateUploadProgressMessage(self, new_progress = 0): + # TODO: implement this + # See ClusterUM3OutputDevice for inspiration + pass + + def _showUploadSuccessMessage(self): + # TODO: implement this + pass From 0852d2ebefe7a6732124ead1498910feafafe845 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 3 Dec 2018 17:42:39 +0100 Subject: [PATCH 0617/1292] add one more TODO --- .../UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 7c10cb4e50..2df07fca77 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -132,7 +132,7 @@ class CloudOutputDeviceManager(NetworkClient): local_device_id = active_machine.getMetaDataEntry("um_network_key") if local_device_id: active_output_device = self._output_device_manager.getActiveDevice() - # We must find a match for the active machine and a cloud device + # TODO: We must find a match for the active machine and a cloud device stored_cluster_id = active_machine.getMetaDataEntry("um_cloud_cluster_id") if stored_cluster_id not in self._remote_clusters.keys(): From 8d6f109092619b7ff91ae88f6dc7781cc31e5e6d Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 3 Dec 2018 20:11:53 +0100 Subject: [PATCH 0618/1292] Set priority to 2 --- plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 2f59b6aeea..ee84762cf8 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -108,7 +108,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## Set all the interface elements and texts for this output device. def _setInterfaceElements(self): - self.setPriority(3) + self.setPriority(2) # make sure we end up below the local networking and above 'save to file' self.setName(self._id) # TODO: how to name these? self.setShortDescription(self.I18N_CATALOG.i18nc("@action:button", "Print via Cloud")) From 08e1b4691b5791fe1ae19ccd56cbac226ae3813e Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 3 Dec 2018 20:19:16 +0100 Subject: [PATCH 0619/1292] Remove TODO --- plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index ee84762cf8..faca2472ad 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -110,7 +110,6 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def _setInterfaceElements(self): self.setPriority(2) # make sure we end up below the local networking and above 'save to file' self.setName(self._id) - # TODO: how to name these? self.setShortDescription(self.I18N_CATALOG.i18nc("@action:button", "Print via Cloud")) self.setDescription(self.I18N_CATALOG.i18nc("@properties:tooltip", "Print via Cloud")) self.setConnectionText(self.I18N_CATALOG.i18nc("@info:status", "Connected via Cloud")) From 5fdff1778261c2eb8a5267bca4711f50127a080e Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 3 Dec 2018 22:12:18 +0100 Subject: [PATCH 0620/1292] Add upload messages for UI feedback, needs some refactoring --- .../NetworkedPrinterOutputDevice.py | 5 +- .../src/Cloud/CloudOutputDevice.py | 98 ++++++++++++++----- .../UM3NetworkPrinting/src/Cloud/Models.py | 1 + 3 files changed, 76 insertions(+), 28 deletions(-) diff --git a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py index 0a799d4cd3..5677106782 100644 --- a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py +++ b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py @@ -180,13 +180,16 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): self._createNetworkManager() assert (self._manager is not None) - def put(self, target: str, data: Union[str, bytes], on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: + def put(self, target: str, data: Union[str, bytes], on_finished: Optional[Callable[[QNetworkReply], None]], + on_progress: Optional[Callable] = None) -> None: self._validateManager() request = self._createEmptyRequest(target) self._last_request_time = time() if self._manager is not None: reply = self._manager.put(request, data if isinstance(data, bytes) else data.encode()) self._registerOnFinishedCallback(reply, on_finished) + if on_progress is not None: + reply.uploadProgress.connect(on_progress) else: Logger.log("e", "Could not find manager.") diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index faca2472ad..db5ad21b06 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -71,6 +71,10 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # Properties to populate later on with received cloud data. self._print_jobs = [] # type: List[UM3PrintJobOutputModel] self._number_of_extruders = 2 # All networked printers are dual-extrusion Ultimaker machines. + + # We only allow a single upload at a time. + self._sending_job = False + self._progress_message = None # type: Optional[Message] @staticmethod def _parseReply(reply: QNetworkReply) -> Tuple[int, Union[None, str, bytes]]: @@ -117,14 +121,22 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## Called when Cura requests an output device to receive a (G-code) file. def requestWrite(self, nodes: List[SceneNode], file_name: Optional[str] = None, limit_mime_types: bool = False, file_handler: Optional[FileHandler] = None, **kwargs: str) -> None: + + # Show an error message if we're already sending a job. + if self._sending_job: + self._onUploadError(self.I18N_CATALOG.i18nc( + "@info:status", "Sending new jobs (temporarily) blocked, still sending the previous print job.")) + return + + # Indicate we have started sending a job. + self._sending_job = True self.writeStarted.emit(self) file_format = self._determineFileFormat(file_handler) writer = self._determineWriter(file_handler, file_format) - - # This function pauses with the yield, waiting on instructions on which printer it needs to print with. if not writer: Logger.log("e", "Missing file or mesh writer!") + self._onUploadError(self.I18N_CATALOG.i18nc("@info:status", "Could not export print job.")) return stream = io.StringIO() if file_format["mode"] == FileWriter.OutputMode.TextMode else io.BytesIO() @@ -186,11 +198,12 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def printers(self): return self._printers + ## Get remote print jobs. @pyqtProperty("QVariantList", notify = printJobsChanged) def printJobs(self)-> List[UM3PrintJobOutputModel]: return self._print_jobs - ## Get remote print jobs. + ## Get remote print jobs that are still in the print queue. @pyqtProperty("QVariantList", notify = printJobsChanged) def queuedPrintJobs(self) -> List[UM3PrintJobOutputModel]: return [print_job for print_job in self._print_jobs @@ -354,24 +367,27 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def _onPrintJobCreated(self, mesh: bytes, reply: QNetworkReply) -> None: status_code, response = self._parseReply(reply) if status_code > 204 or not isinstance(response, dict) or "data" not in response: - Logger.log("w", "Got unexpected response while trying to add print job to cluster: {}, {}" - .format(status_code, response)) - self.writeError.emit() + Logger.log("w", "Unexpected response while adding to queue: {}, {}".format(status_code, response)) + self._onUploadError(self.I18N_CATALOG.i18nc("@info:status", "Could not add print job to queue.")) return - # TODO: add progress messages so we have visual feedback when uploading to cloud # TODO: Multipart upload job_response = JobUploadResponse(**response.get("data")) Logger.log("i", "Print job created successfully: %s", job_response.__dict__) self.put(job_response.upload_url, data=mesh, - on_finished=lambda r: self._onPrintJobUploaded(job_response.job_id, r)) + on_finished=lambda r: self._onPrintJobUploaded(job_response.job_id, r), + on_progress = self._onUploadPrintJobProgress) + + def _onUploadPrintJobProgress(self, bytes_sent: int, bytes_total: int) -> None: + if bytes_total > 0: + self._updateUploadProgress(int((bytes_sent / bytes_total) * 100)) def _onPrintJobUploaded(self, job_id: str, reply: QNetworkReply) -> None: status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) if status_code > 204: - Logger.logException("w", "Received unexpected response from the job upload: %s, %s.", status_code, - bytes(reply.readAll()).decode()) - self.writeError.emit() + Logger.log("w", "Received unexpected response from the job upload: %s, %s.", status_code, + bytes(reply.readAll()).decode()) + self._onUploadError(self.I18N_CATALOG.i18nc("@info:status", "Could not add print job to queue.")) return Logger.log("i", "Print job uploaded successfully: %s", reply.readAll()) @@ -381,25 +397,53 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def _onPrintJobRequested(self, reply: QNetworkReply) -> None: status_code, response = self._parseReply(reply) if status_code > 204 or not isinstance(response, dict) or "data" not in response: - Logger.log("w", "Got unexpected response while trying to request printing: %s, %s", - status_code, response) - self.writeError.emit() + Logger.log("w", "Got unexpected response while trying to request printing: %s, %s", status_code, response) + self._onUploadError(self.I18N_CATALOG.i18nc("@info:status", "Could not add print job to queue.")) return print_response = PrintResponse(**response["data"]) Logger.log("i", "Print job requested successfully: %s", print_response.__dict__) - self.writeFinished.emit() + self._onUploadSuccess() - def _showUploadErrorMessage(self): - message = Message(self.I18N_CATALOG.i18nc( - "@info:status", "Sending new jobs (temporarily) blocked, still sending the previous print job.")) + def _updateUploadProgress(self, progress: int): + if not self._progress_message: + self._progress_message = Message( + text = self.I18N_CATALOG.i18nc("@info:status", "Sending data to remote cluster"), + title = self.I18N_CATALOG.i18nc("@info:title", "Sending Data..."), + progress = -1, + lifetime = 0, + dismissable = False, + use_inactivity_timer = False + ) + self._progress_message.setProgress(progress) + self._progress_message.show() + + def _resetUploadProgress(self): + if self._progress_message: + self._progress_message.hide() + self._progress_message = None + + def _onUploadError(self, message: str = None): + self._resetUploadProgress() + if message: + message = Message( + text = message, + title = self.I18N_CATALOG.i18nc("@info:title", "Error"), + lifetime = 10, + dismissable = True + ) + message.show() + self._sending_job = False # the upload has failed so we're not sending a job anymore + self.writeError.emit() + + def _onUploadSuccess(self): + self._resetUploadProgress() + message = Message( + text = self.I18N_CATALOG.i18nc("@info:status", "Print job was successfully sent to the printer."), + title = self.I18N_CATALOG.i18nc("@info:title", "Data Sent"), + lifetime = 5, + dismissable = True, + ) message.show() - - def _showOrUpdateUploadProgressMessage(self, new_progress = 0): - # TODO: implement this - # See ClusterUM3OutputDevice for inspiration - pass - - def _showUploadSuccessMessage(self): - # TODO: implement this - pass + self._sending_job = False # the upload has finished so we're not sending a job anymore + self.writeFinished.emit() diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models.py b/plugins/UM3NetworkPrinting/src/Cloud/Models.py index 22a733c70e..e1c25cc662 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models.py @@ -120,6 +120,7 @@ class JobUploadResponse(BaseModel): self.slicing_details = None # type: str self.status = None # type: str self.upload_url = None # type: str + self.content_type = None # type: str super().__init__(**kwargs) From c40d76f9ee6479b4c14c1b35bb061aaa282a1411 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 3 Dec 2018 23:13:24 +0100 Subject: [PATCH 0621/1292] Fix formatting according to Cura code style --- .../src/Cloud/CloudOutputDevice.py | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index db5ad21b06..e2957cacae 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -217,7 +217,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def _update(self) -> None: super()._update() Logger.log("i", "Calling the cloud cluster") - self.get("{root}/cluster/{cluster_id}/status".format(root=self.CLUSTER_API_ROOT, cluster_id=self._device_id), + self.get("{root}/cluster/{cluster_id}/status".format(root = self.CLUSTER_API_ROOT, + cluster_id = self._device_id), on_finished = self._onStatusCallFinished) ## Method called when HTTP request to status endpoint is finished. @@ -257,7 +258,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def _addPrinter(self, printer: CloudClusterPrinter) -> None: model = PrinterOutputModel( - PrinterOutputController(self), len(printer.configuration), firmware_version=printer.firmware_version + PrinterOutputController(self), len(printer.configuration), firmware_version = printer.firmware_version ) self._printers.append(model) self._updatePrinter(model, printer) @@ -291,10 +292,10 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): non_read_only_material_group_list = list(filter(lambda x: not x.is_read_only, material_group_list)) material_group = None if read_only_material_group_list: - read_only_material_group_list = sorted(read_only_material_group_list, key=lambda x: x.name) + read_only_material_group_list = sorted(read_only_material_group_list, key = lambda x: x.name) material_group = read_only_material_group_list[0] elif non_read_only_material_group_list: - non_read_only_material_group_list = sorted(non_read_only_material_group_list, key=lambda x: x.name) + non_read_only_material_group_list = sorted(non_read_only_material_group_list, key = lambda x: x.name) material_group = non_read_only_material_group_list[0] if material_group: @@ -304,15 +305,15 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): material_type = container.getMetaDataEntry("material") name = container.getName() else: - Logger.log("w", - "Unable to find material with guid {guid}. Using data as provided by cluster".format( - guid=material.guid)) + Logger.log("w", "Unable to find material with guid {guid}. Using data as provided by cluster" + .format(guid = material.guid)) color = material.color brand = material.brand material_type = material.material name = "Empty" if material.material == "empty" else "Unknown" - return MaterialOutputModel(guid=material.guid, type=material_type, brand=brand, color=color, name=name) + return MaterialOutputModel(guid = material.guid, type = material_type, brand = brand, color = color, + name = name) def _updatePrintJobs(self, jobs: List[CloudClusterPrintJob]) -> None: remote_jobs = {j.uuid: j for j in jobs} # type: Dict[str, CloudClusterPrintJob] @@ -374,8 +375,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # TODO: Multipart upload job_response = JobUploadResponse(**response.get("data")) Logger.log("i", "Print job created successfully: %s", job_response.__dict__) - self.put(job_response.upload_url, data=mesh, - on_finished=lambda r: self._onPrintJobUploaded(job_response.job_id, r), + self.put(job_response.upload_url, data = mesh, + on_finished = lambda r: self._onPrintJobUploaded(job_response.job_id, r), on_progress = self._onUploadPrintJobProgress) def _onUploadPrintJobProgress(self, bytes_sent: int, bytes_total: int) -> None: @@ -392,7 +393,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): Logger.log("i", "Print job uploaded successfully: %s", reply.readAll()) url = "{}/cluster/{}/print/{}".format(self.CLUSTER_API_ROOT, self._device_id, job_id) - self.post(url, data="", on_finished=self._onPrintJobRequested) + self.post(url, data = "", on_finished = self._onPrintJobRequested) def _onPrintJobRequested(self, reply: QNetworkReply) -> None: status_code, response = self._parseReply(reply) From b50e9427684d4bbc81eeca3cd7c7ef693749c7e1 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 3 Dec 2018 23:42:41 +0100 Subject: [PATCH 0622/1292] Describe TODO for association by hostname, only connect when online --- .../src/Cloud/CloudOutputDeviceManager.py | 39 +++++++++---------- .../UM3NetworkPrinting/src/Cloud/Models.py | 1 + 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 2df07fca77..6da6c4f4d7 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -20,8 +20,6 @@ from .Models import CloudCluster # # API spec is available on https://api.ultimaker.com/docs/connect/spec/. # -# TODO: figure out how to pair remote clusters, local networked clusters and local cura printer presets. -# TODO: for now we just have multiple output devices if the cluster is available both locally and remote. class CloudOutputDeviceManager(NetworkClient): # The cloud URL to use for remote clusters. @@ -42,8 +40,9 @@ class CloudOutputDeviceManager(NetworkClient): self._account.loginStateChanged.connect(self._getRemoteClusters) # When switching machines we check if we have to activate a remote cluster. - application.globalContainerStackChanged.connect(self._activeMachineChanged) - + application.globalContainerStackChanged.connect(self._connectToActiveMachine) + + # TODO: fix this # Periodically check all remote clusters for the authenticated user. # self._update_clusters_thread = Thread(target=self._updateClusters, daemon=True) # self._update_clusters_thread.start() @@ -89,15 +88,13 @@ class CloudOutputDeviceManager(NetworkClient): # Add an output device for each new remote cluster. for cluster_id in found_cluster_ids.difference(known_cluster_ids): - self._addCloudOutputDevice(found_clusters[cluster_id]) + if found_clusters[cluster_id].is_online: + self._addCloudOutputDevice(found_clusters[cluster_id]) # Remove output devices that are gone for cluster_id in known_cluster_ids.difference(found_cluster_ids): self._removeCloudOutputDevice(found_clusters[cluster_id]) - # For testing we add a dummy device: - # self._addCloudOutputDevice(CloudCluster(cluster_id = "LJ0tciiuZZjarrXAvFLEZ6ox4Cvx8FvtXUlQv4vIhV6w")) - @staticmethod def _parseStatusResponse(reply: QNetworkReply) -> Dict[str, CloudCluster]: try: @@ -116,7 +113,9 @@ class CloudOutputDeviceManager(NetworkClient): device = CloudOutputDevice(cluster.cluster_id) self._output_device_manager.addOutputDevice(device) self._remote_clusters[cluster.cluster_id] = device - device.connect() # TODO: Only connect the current device + if cluster.is_online: + # We found a new online cluster, we might need to connect to it. + self._connectToActiveMachine() ## Remove a CloudOutputDevice def _removeCloudOutputDevice(self, cluster: CloudCluster): @@ -124,20 +123,20 @@ class CloudOutputDeviceManager(NetworkClient): del self._remote_clusters[cluster.cluster_id] ## Callback for when the active machine was changed by the user. - def _activeMachineChanged(self): + def _connectToActiveMachine(self) -> None: active_machine = CuraApplication.getInstance().getGlobalContainerStack() if not active_machine: return - - local_device_id = active_machine.getMetaDataEntry("um_network_key") - if local_device_id: - active_output_device = self._output_device_manager.getActiveDevice() - # TODO: We must find a match for the active machine and a cloud device - + + # Check if the stored cluster_id for the active machine is in our list of remote clusters. stored_cluster_id = active_machine.getMetaDataEntry("um_cloud_cluster_id") - if stored_cluster_id not in self._remote_clusters.keys(): - # Currently authenticated user does not have access to stored cluster or no user is signed in. + if stored_cluster_id in self._remote_clusters.keys(): + self._remote_clusters.get(stored_cluster_id).connect() return - # We found the active machine as remote cluster so let's connect to it. - self._remote_clusters.get(stored_cluster_id).connect() + # TODO: See if this cloud cluster still has to be associated to the active machine. + # TODO: We have to get a common piece of data, like local network hostname, from the active machine and + # TODO: cloud cluster and then set the "um_cloud_cluster_id" meta data key on the active machine. + # TODO: If so, we can also immediate connect to it. + # active_machine.setMetaDataEntry("um_cloud_cluster_id", "") + # self._remote_clusters.get(stored_cluster_id).connect() diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models.py b/plugins/UM3NetworkPrinting/src/Cloud/Models.py index e1c25cc662..d7cb68e5d3 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models.py @@ -13,6 +13,7 @@ class CloudCluster(BaseModel): self.host_name = None # type: str self.host_version = None # type: str self.status = None # type: str + self.is_online = None # type: bool super().__init__(**kwargs) def validate(self): From 1bcabc6f42867fb8a352255fd572f67f66f84fbe Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 3 Dec 2018 23:44:52 +0100 Subject: [PATCH 0623/1292] Fix is_online logic --- .../UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 6da6c4f4d7..06beb8bce4 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -87,6 +87,7 @@ class CloudOutputDeviceManager(NetworkClient): found_cluster_ids = set(found_clusters.keys()) # Add an output device for each new remote cluster. + # We only add when is_online as we don't want the option in the drop down if the cluster is not online. for cluster_id in found_cluster_ids.difference(known_cluster_ids): if found_clusters[cluster_id].is_online: self._addCloudOutputDevice(found_clusters[cluster_id]) @@ -113,9 +114,7 @@ class CloudOutputDeviceManager(NetworkClient): device = CloudOutputDevice(cluster.cluster_id) self._output_device_manager.addOutputDevice(device) self._remote_clusters[cluster.cluster_id] = device - if cluster.is_online: - # We found a new online cluster, we might need to connect to it. - self._connectToActiveMachine() + self._connectToActiveMachine() ## Remove a CloudOutputDevice def _removeCloudOutputDevice(self, cluster: CloudCluster): From 6af1e72ea330c009feb3a3834233481a442db2c7 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 4 Dec 2018 07:45:34 +0100 Subject: [PATCH 0624/1292] Show progress bar while autoslice is preparing Previously it would say 'preparing to slice'. Now it just says 'auto slicing' but with an indeterminate progress bar. Only the indeterminate progress bar just appears empty right now... Contributes to issue CURA-5997. --- resources/qml/ActionPanel/SliceProcessWidget.qml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index 3329ac4b23..14e149dddb 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -44,7 +44,7 @@ Column { id: autoSlicingLabel width: parent.width - visible: prepareButtons.autoSlice && widget.backendState == UM.Backend.Processing + visible: prepareButtons.autoSlice && (widget.backendState == UM.Backend.Processing || widget.backendState == UM.Backend.NotStarted) text: catalog.i18nc("@label:PrintjobStatus", "Auto slicing...") color: UM.Theme.getColor("text") @@ -71,7 +71,8 @@ Column width: parent.width height: UM.Theme.getSize("progressbar").height value: progress - visible: widget.backendState == UM.Backend.Processing + indeterminate: widget.backendState == UM.Backend.NotStarted + visible: (widget.backendState == UM.Backend.Processing || (prepareButtons.autoSlice && widget.backendState == UM.Backend.NotStarted)) background: Rectangle { From 98ec6c66f2d486890b2d31c68bb8bd09e3bd911e Mon Sep 17 00:00:00 2001 From: THeijmans Date: Tue, 4 Dec 2018 08:25:05 +0100 Subject: [PATCH 0625/1292] CC06 profile fix removed line adding 10degrees to many profiles --- resources/variants/ultimaker_s5_cc06.inst.cfg | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/variants/ultimaker_s5_cc06.inst.cfg b/resources/variants/ultimaker_s5_cc06.inst.cfg index d41d08118a..7adf7ab7a0 100644 --- a/resources/variants/ultimaker_s5_cc06.inst.cfg +++ b/resources/variants/ultimaker_s5_cc06.inst.cfg @@ -13,7 +13,6 @@ brim_width = 7 machine_nozzle_cool_down_speed = 0.9 machine_nozzle_id = CC 0.6 machine_nozzle_size = 0.6 -material_print_temperature = =default_material_print_temperature + 10 raft_acceleration = =acceleration_print raft_airgap = 0.3 raft_base_thickness = =resolveOrValue('layer_height_0') * 1.2 From e9f8757fac1b5740f7daab3dea3288940f092400 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 4 Dec 2018 09:12:57 +0100 Subject: [PATCH 0626/1292] Change the info button in the action panel according to the designs Adjust the padding in the preview shortcut. --- .../qml/ActionPanel/OutputProcessWidget.qml | 2 + .../ActionPanel/PrintInformationWidget.qml | 3 -- resources/themes/cura-light/icons/info.svg | 48 ------------------- 3 files changed, 2 insertions(+), 51 deletions(-) delete mode 100644 resources/themes/cura-light/icons/info.svg diff --git a/resources/qml/ActionPanel/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml index 45cb1fdb41..6ab8dc6fbb 100644 --- a/resources/qml/ActionPanel/OutputProcessWidget.qml +++ b/resources/qml/ActionPanel/OutputProcessWidget.qml @@ -112,6 +112,8 @@ Column id: previewStageShortcut height: UM.Theme.getSize("action_panel_button").height + leftPadding: UM.Theme.getSize("default_margin").width + rightPadding: UM.Theme.getSize("default_margin").width text: catalog.i18nc("@button", "Preview") onClicked: UM.Controller.setActiveStage("PreviewStage") diff --git a/resources/qml/ActionPanel/PrintInformationWidget.qml b/resources/qml/ActionPanel/PrintInformationWidget.qml index 82707576e0..25e380dea8 100644 --- a/resources/qml/ActionPanel/PrintInformationWidget.qml +++ b/resources/qml/ActionPanel/PrintInformationWidget.qml @@ -11,9 +11,6 @@ UM.RecolorImage { id: widget - //implicitHeight: UM.Theme.getSize("section_icon").height - //implicitWidth: UM.Theme.getSize("section_icon").width - source: UM.Theme.getIcon("info") width: UM.Theme.getSize("section_icon").width height: UM.Theme.getSize("section_icon").height diff --git a/resources/themes/cura-light/icons/info.svg b/resources/themes/cura-light/icons/info.svg deleted file mode 100644 index 97e4fc4f35..0000000000 --- a/resources/themes/cura-light/icons/info.svg +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From c1f5c00a7e088fee409d7c7282607faf3976707f Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 4 Dec 2018 09:18:45 +0100 Subject: [PATCH 0627/1292] Forgot to add the icon --- resources/themes/cura-light/icons/info.svg | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 resources/themes/cura-light/icons/info.svg diff --git a/resources/themes/cura-light/icons/info.svg b/resources/themes/cura-light/icons/info.svg new file mode 100644 index 0000000000..9896b3dac8 --- /dev/null +++ b/resources/themes/cura-light/icons/info.svg @@ -0,0 +1,13 @@ + + + + Icon/ info + Created with Sketch. + + + + + + + + \ No newline at end of file From 57a852a15ae0ff9e292e3eff574c067399a29777 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 4 Dec 2018 09:19:08 +0100 Subject: [PATCH 0628/1292] Don't show the background if there are less than 2 extruders to show in the Toolbar It caused a very tiny rectangle if the printer has only 1 extruder. Contributes to CURA-5984. --- resources/qml/Toolbar.qml | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/resources/qml/Toolbar.qml b/resources/qml/Toolbar.qml index 07522dd535..5fbddea9ac 100644 --- a/resources/qml/Toolbar.qml +++ b/resources/qml/Toolbar.qml @@ -115,6 +115,7 @@ Item } radius: UM.Theme.getSize("default_radius").width color: UM.Theme.getColor("lining") + visible: extrudersModel.items.length > 1 } Column @@ -131,8 +132,7 @@ Item id: extruders width: childrenRect.width height: childrenRect.height - property var _model: Cura.ExtrudersModel { id: extrudersModel } - model: _model.items.length > 1 ? _model : 0 + model: extrudersModel.items.length > 1 ? extrudersModel : 0 delegate: ExtruderButton { @@ -144,13 +144,18 @@ Item } } + Cura.ExtrudersModel + { + id: extrudersModel + } + UM.PointingRectangle { - id: panelBorder; + id: panelBorder - anchors.left: parent.right; - anchors.leftMargin: UM.Theme.getSize("default_margin").width; - anchors.top: base.top; + anchors.left: parent.right + anchors.leftMargin: UM.Theme.getSize("default_margin").width + anchors.top: base.top anchors.topMargin: base.activeY z: buttons.z - 1 @@ -161,14 +166,14 @@ Item { if (panel.item && panel.width > 0) { - return Math.max(panel.width + 2 * UM.Theme.getSize("default_margin").width); + return Math.max(panel.width + 2 * UM.Theme.getSize("default_margin").width) } else { return 0; } } - height: panel.item ? panel.height + 2 * UM.Theme.getSize("default_margin").height : 0; + height: panel.item ? panel.height + 2 * UM.Theme.getSize("default_margin").height : 0 opacity: panel.item && panel.width > 0 ? 1 : 0 Behavior on opacity { NumberAnimation { duration: 100 } } @@ -186,11 +191,11 @@ Item { id: panel - x: UM.Theme.getSize("default_margin").width; - y: UM.Theme.getSize("default_margin").height; + x: UM.Theme.getSize("default_margin").width + y: UM.Theme.getSize("default_margin").height source: UM.ActiveTool.valid ? UM.ActiveTool.activeToolPanel : "" - enabled: UM.Controller.toolsEnabled; + enabled: UM.Controller.toolsEnabled } } From 12b3f0088d49c2fb064f775a6c6d26177a32f41d Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 4 Dec 2018 10:07:43 +0100 Subject: [PATCH 0629/1292] Add content type to file upload --- cura/PrinterOutput/NetworkedPrinterOutputDevice.py | 5 +++-- plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py index 5677106782..72b6319020 100644 --- a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py +++ b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py @@ -180,10 +180,11 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): self._createNetworkManager() assert (self._manager is not None) - def put(self, target: str, data: Union[str, bytes], on_finished: Optional[Callable[[QNetworkReply], None]], + def put(self, target: str, data: Union[str, bytes], content_type: str = None, + on_finished: Optional[Callable[[QNetworkReply], None]] = None, on_progress: Optional[Callable] = None) -> None: self._validateManager() - request = self._createEmptyRequest(target) + request = self._createEmptyRequest(target, content_type = content_type) self._last_request_time = time() if self._manager is not None: reply = self._manager.put(request, data if isinstance(data, bytes) else data.encode()) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index e2957cacae..63a109cf5c 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -375,7 +375,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # TODO: Multipart upload job_response = JobUploadResponse(**response.get("data")) Logger.log("i", "Print job created successfully: %s", job_response.__dict__) - self.put(job_response.upload_url, data = mesh, + self.put(job_response.upload_url, data = mesh, content_type = job_response.content_type, on_finished = lambda r: self._onPrintJobUploaded(job_response.job_id, r), on_progress = self._onUploadPrintJobProgress) From 0363c1257cf947aff14b2543a76edc7d4cd08b20 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 4 Dec 2018 10:18:09 +0100 Subject: [PATCH 0630/1292] Improve exposed progress prop Contributes to CL-1153 --- cura/PrinterOutput/PrintJobOutputModel.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cura/PrinterOutput/PrintJobOutputModel.py b/cura/PrinterOutput/PrintJobOutputModel.py index 604fd8e0b8..256c9dffe9 100644 --- a/cura/PrinterOutput/PrintJobOutputModel.py +++ b/cura/PrinterOutput/PrintJobOutputModel.py @@ -133,9 +133,8 @@ class PrintJobOutputModel(QObject): @pyqtProperty(float, notify = timeElapsedChanged) def progress(self) -> float: result = self.timeElapsed / self.timeTotal - if result > 1.0: - result = 1.0 - return result + # Never get a progress past 1.0 + return min(result, 1.0) @pyqtProperty(str, notify=stateChanged) def state(self) -> str: From ab245bbff6fe76d0647f9a8655bf0abbb3ee5595 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 4 Dec 2018 10:23:26 +0100 Subject: [PATCH 0631/1292] Make "finishes at" single translatable string Contributes to CL-1153 --- .../resources/qml/MonitorPrintJobProgressBar.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml index a7055f4c52..4ca3c24d87 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml @@ -103,7 +103,7 @@ Item case "queued": return catalog.i18nc("@label:status", "Action required") default: - return catalog.i18nc("@label:status", "Finishes ") + OutputDevice.getDateCompleted( printJob.timeRemaining ) + " at " + OutputDevice.getTimeCompleted( printJob.timeRemaining ) + return catalog.i18nc("@label:status", "Finishes %1 at %2".arg(OutputDevice.getDateCompleted( printJob.timeRemaining ), OutputDevice.getTimeCompleted( printJob.timeRemaining ))) } } width: contentWidth From 9ec7428620e4ea31b1b172aeda86a29db28fd7c8 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 4 Dec 2018 10:54:30 +0100 Subject: [PATCH 0632/1292] Fix setting visiblity current index CURA-5981 --- resources/qml/Preferences/SettingVisibilityPage.qml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/resources/qml/Preferences/SettingVisibilityPage.qml b/resources/qml/Preferences/SettingVisibilityPage.qml index e319069502..1b964cad0c 100644 --- a/resources/qml/Preferences/SettingVisibilityPage.qml +++ b/resources/qml/Preferences/SettingVisibilityPage.qml @@ -115,15 +115,16 @@ UM.PreferencesPage currentIndex: { + var idx = -1; for(var i = 0; i < settingVisibilityPresetsModel.items.length; ++i) { if(settingVisibilityPresetsModel.items[i].presetId == settingVisibilityPresetsModel.activePreset) { - currentIndex = i; - return; + idx = i; + break; } } - return -1 + return idx; } onActivated: From 249a90199bd2da38aac6974a03a1a07f624b0acf Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 4 Dec 2018 11:08:01 +0100 Subject: [PATCH 0633/1292] Improve printer status handling Contributes to CL-1153 --- .../resources/qml/MonitorPrintJobProgressBar.qml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml index 4ca3c24d87..0d159af21c 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml @@ -90,9 +90,11 @@ Item return catalog.i18nc("@label:status", "Finished") case "sent_to_printer": return catalog.i18nc("@label:status", "Preparing...") - case "aborting": + case "pre_print": + return catalog.i18nc("@label:status", "Preparing...") + case "aborting": // NOTE: Doesn't exist but maybe should someday return catalog.i18nc("@label:status", "Aborting...") - case "aborted": + case "aborted": // NOTE: Unused, see above return catalog.i18nc("@label:status", "Aborted") case "pausing": return catalog.i18nc("@label:status", "Pausing...") From 96b9c7f3ea045aaecf81fb3d79c72929f0ad8ce5 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 4 Dec 2018 11:40:56 +0100 Subject: [PATCH 0634/1292] Fix multi-argument i18n string Contributes to CL-1153 --- .../resources/qml/MonitorPrintJobProgressBar.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml index 0d159af21c..88418516ed 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml @@ -78,7 +78,7 @@ Item { if (!printJob) { - return ""; + return "" } switch (printJob.state) { @@ -105,7 +105,7 @@ Item case "queued": return catalog.i18nc("@label:status", "Action required") default: - return catalog.i18nc("@label:status", "Finishes %1 at %2".arg(OutputDevice.getDateCompleted( printJob.timeRemaining ), OutputDevice.getTimeCompleted( printJob.timeRemaining ))) + return catalog.i18nc("@label:status", "Finishes %1 at %2".arg(OutputDevice.getDateCompleted( printJob.timeRemaining )).arg(OutputDevice.getTimeCompleted( printJob.timeRemaining ))) } } width: contentWidth From 692686597cf9204748a25c38fc11392712e74ae4 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 4 Dec 2018 12:07:31 +0100 Subject: [PATCH 0635/1292] Fix an issues that didn't calculate the correct height of the popup when the custom mode was selected from previous runs. Contributes to CURA-5941. --- resources/qml/ExpandableComponent.qml | 42 ++++++++-------- .../PrintSetupSelectorContents.qml | 49 ++++++++++--------- 2 files changed, 48 insertions(+), 43 deletions(-) diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index 82747d1c5b..df7604015e 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -25,10 +25,7 @@ Item property alias headerItem: headerItemLoader.sourceComponent // The popupItem holds the QML item that is shown when the "open" button is pressed - property var popupItem - - // The popupItem holds the QML item that is shown when the "open" button is pressed - property var componentItem + property alias popupItem: popup.contentItem property color popupBackgroundColor: UM.Theme.getColor("action_button") @@ -87,23 +84,6 @@ Item } } - onPopupItemChanged: - { - // Since we want the size of the popup to be set by the size of the content, - // we need to do it like this. - popup.width = popupItem.width + 2 * popup.padding - popup.height = popupItem.height + 2 * popup.padding - popup.contentItem = popupItem - } - - Connections - { - // Since it could be that the popup is dynamically populated, we should also take these changes into account. - target: popupItem - onWidthChanged: popup.width = popupItem.width + 2 * popup.padding - onHeightChanged: popup.height = popupItem.height + 2 * popup.padding - } - implicitHeight: 100 * screenScaleFactor implicitWidth: 400 * screenScaleFactor @@ -202,5 +182,25 @@ Item border.color: UM.Theme.getColor("lining") radius: UM.Theme.getSize("default_radius").width } + + contentItem: Item { } + + onContentItemChanged: + { + // Since we want the size of the popup to be set by the size of the content, + // we need to do it like this. + popup.width = contentItem.width + 2 * popup.padding + popup.height = contentItem.height + 2 * popup.padding + } + } + + // DO NOT MOVE UP IN THE CODE: This connection has to be here, after the definition of the Popup item. + // Apparently the order in which these are handled matters and so the height is correctly updated if this is here. + Connections + { + // Since it could be that the popup is dynamically populated, we should also take these changes into account. + target: popup.contentItem + onWidthChanged: popup.width = popup.contentItem.width + 2 * popup.padding + onHeightChanged: popup.height = popup.contentItem.height + 2 * popup.padding } } diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml index 358cba8ad0..a2856e1fe5 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml @@ -17,9 +17,26 @@ Item width: UM.Theme.getSize("print_setup_widget").width - 2 * UM.Theme.getSize("default_margin").width height: childrenRect.height - property int currentModeIndex: -1 + enum Mode + { + Recommended = 0, + Custom = 1 + } + + // Set the current mode index to the value that is stored in the preferences or Recommended mode otherwise. + property int currentModeIndex: + { + var index = Math.round(UM.Preferences.getValue("cura/active_mode")) + + if(index != null && !isNaN(index)) + { + return index + } + return PrintSetupSelectorContents.Mode.Recommended + } onCurrentModeIndexChanged: UM.Preferences.setValue("cura/active_mode", currentModeIndex) + // Header of the popup Rectangle { @@ -93,7 +110,9 @@ Item Item { id: contents - height: currentModeIndex == 0 ? recommendedPrintSetup.height : customPrintSetup.height + // Use the visible property instead of checking the currentModeIndex. That creates a binding that + // evaluates the new height every time the visible property changes. + height: recommendedPrintSetup.visible ? recommendedPrintSetup.height : customPrintSetup.height anchors { @@ -111,7 +130,7 @@ Item right: parent.right top: parent.top } - visible: currentModeIndex == 0 + visible: currentModeIndex == PrintSetupSelectorContents.Mode.Recommended } CustomPrintSetup @@ -123,7 +142,7 @@ Item right: parent.right top: parent.top } - visible: currentModeIndex == 1 + visible: currentModeIndex == PrintSetupSelectorContents.Mode.Custom } } @@ -160,8 +179,8 @@ Item rightPadding: UM.Theme.getSize("default_margin").width text: catalog.i18nc("@button", "Recommended") iconSource: UM.Theme.getIcon("arrow_left") - visible: currentModeIndex == 1 - onClicked: currentModeIndex = 0 + visible: currentModeIndex == PrintSetupSelectorContents.Mode.Custom + onClicked: currentModeIndex = PrintSetupSelectorContents.Mode.Recommended } Cura.SecondaryButton @@ -174,22 +193,8 @@ Item text: catalog.i18nc("@button", "Custom") iconSource: UM.Theme.getIcon("arrow_right") iconOnRightSide: true - visible: currentModeIndex == 0 - onClicked: currentModeIndex = 1 - } - } - - Component.onCompleted: - { - var index = Math.round(UM.Preferences.getValue("cura/active_mode")) - - if(index != null && !isNaN(index)) - { - currentModeIndex = index - } - else - { - currentModeIndex = 0 + visible: currentModeIndex == PrintSetupSelectorContents.Mode.Recommended + onClicked: currentModeIndex = PrintSetupSelectorContents.Mode.Custom } } } \ No newline at end of file From 97607419cfaddaa0403e8c48775fcb2530dcf114 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 4 Dec 2018 12:14:21 +0100 Subject: [PATCH 0636/1292] Start with some fakes for monitor page --- .../src/Cloud/CloudOutputDevice.py | 31 ++++++++++++++++++- .../src/Cloud/CloudOutputDeviceManager.py | 1 + 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 63a109cf5c..747d911407 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -6,7 +6,7 @@ import os from json import JSONDecodeError from typing import List, Optional, Dict, cast, Union, Tuple -from PyQt5.QtCore import QObject, pyqtSignal, QUrl, pyqtProperty +from PyQt5.QtCore import QObject, pyqtSignal, QUrl, pyqtProperty, pyqtSlot from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest from UM import i18nCatalog @@ -209,6 +209,16 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): return [print_job for print_job in self._print_jobs if print_job.state == "queued" or print_job.state == "error"] + ## Get remote print jobs that are assigned to a printer. + @pyqtProperty("QVariantList", notify = printJobsChanged) + def activePrintJobs(self) -> List[UM3PrintJobOutputModel]: + return [print_job for print_job in self._print_jobs if + print_job.assignedPrinter is not None and print_job.state != "queued"] + + @pyqtProperty(bool, notify = printJobsChanged) + def receivedPrintJobs(self) -> bool: + return not self._sending_job + ## Called when the connection to the cluster changes. def connect(self) -> None: super().connect() @@ -448,3 +458,22 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): message.show() self._sending_job = False # the upload has finished so we're not sending a job anymore self.writeFinished.emit() + + ## TODO: The following methods are required by the monitor page QML, but are not actually available using cloud. + # TODO: We fake the methods here to not break the monitor page. + + @pyqtProperty(QObject, notify = printersChanged) + def activePrinter(self) -> Optional[PrinterOutputModel]: + return self._printers[0] or None + + @pyqtSlot(QObject) + def setActivePrinter(self, printer: Optional[PrinterOutputModel]) -> None: + pass + + @pyqtProperty(QUrl, notify = printersChanged) + def activeCameraUrl(self) -> "QUrl": + return QUrl() + + @pyqtSlot(QUrl) + def setActiveCameraUrl(self, camera_url: "QUrl") -> None: + pass diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 06beb8bce4..bc871ec7ac 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -114,6 +114,7 @@ class CloudOutputDeviceManager(NetworkClient): device = CloudOutputDevice(cluster.cluster_id) self._output_device_manager.addOutputDevice(device) self._remote_clusters[cluster.cluster_id] = device + device.connect() # TODO: remove this self._connectToActiveMachine() ## Remove a CloudOutputDevice From 894c69685a740641b62ab7431b338cd985e11009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Tue, 4 Dec 2018 13:06:27 +0100 Subject: [PATCH 0637/1292] Periodically update the remote clusters and printjobs --- .../src/Cloud/CloudOutputDeviceManager.py | 31 ++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 06beb8bce4..e50cd6540c 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -8,6 +8,7 @@ from typing import Dict, Optional from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply from UM.Logger import Logger +from UM.Signal import Signal from cura.CuraApplication import CuraApplication from cura.NetworkClient import NetworkClient @@ -42,10 +43,14 @@ class CloudOutputDeviceManager(NetworkClient): # When switching machines we check if we have to activate a remote cluster. application.globalContainerStackChanged.connect(self._connectToActiveMachine) - # TODO: fix this # Periodically check all remote clusters for the authenticated user. - # self._update_clusters_thread = Thread(target=self._updateClusters, daemon=True) - # self._update_clusters_thread.start() + # This is done by emitting to _on_cluster_received by _update_clusters_thread + # The thread is only started after the user is authenticated, otherwise the api call results in + # an authentication error + self._on_cluster_received = Signal() + self._on_cluster_received.connect(self._getRemoteClusters) + self._update_clusters_thread = Thread(target=self._updateClusters, daemon=True) + ## Override _createEmptyRequest to add the needed authentication header for talking to the Ultimaker Cloud API. def _createEmptyRequest(self, path: str, content_type: Optional[str] = "application/json") -> QNetworkRequest: @@ -59,13 +64,25 @@ class CloudOutputDeviceManager(NetworkClient): ## Update the clusters def _updateClusters(self) -> None: while True: - self._getRemoteClusters() - sleep(self.CHECK_CLUSTER_INTERVAL) - + + # Stop if the application is shutting down + if CuraApplication.getInstance().isShuttingDown(): + return + + self._on_cluster_received.emit() + sleep(5) + ## Gets all remote clusters from the API. def _getRemoteClusters(self) -> None: Logger.log("i", "Retrieving remote clusters") - self.get("/clusters", on_finished = self._onGetRemoteClustersFinished) + if self._account.isLoggedIn: + self.get("/clusters", on_finished = self._onGetRemoteClustersFinished) + + # Only start the polling thread after the user is authenticated + # The first call to _getRemoteClusters comes from self._account.loginStateChanged + if not self._update_clusters_thread.is_alive(): + self._update_clusters_thread.start() + ## Callback for when the request for getting the clusters. is finished. def _onGetRemoteClustersFinished(self, reply: QNetworkReply) -> None: From e159cbdb1a8124ceac8c897d39a96556ba35da5a Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 4 Dec 2018 13:14:12 +0100 Subject: [PATCH 0638/1292] Rename all the references from 'popup' to 'content' Contributes to CURA-5941. --- .../SimulationViewMenuComponent.qml | 2 +- resources/qml/ExpandableComponent.qml | 82 ++++++++++--------- .../QuickConfigurationSelector.qml | 2 +- .../PrintSetupSelector/PrintSetupSelector.qml | 8 +- .../qml/PrinterSelector/MachineSelector.qml | 6 +- resources/qml/ViewsSelector.qml | 6 +- 6 files changed, 57 insertions(+), 49 deletions(-) diff --git a/plugins/SimulationView/SimulationViewMenuComponent.qml b/plugins/SimulationView/SimulationViewMenuComponent.qml index 53b64afb47..a9eb157f48 100644 --- a/plugins/SimulationView/SimulationViewMenuComponent.qml +++ b/plugins/SimulationView/SimulationViewMenuComponent.qml @@ -45,7 +45,7 @@ Cura.ExpandableComponent verticalAlignment: Text.AlignVCenter } - popupItem: Column + contentItem: Column { id: viewSettings diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index df7604015e..0b4076c04a 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -6,40 +6,48 @@ import Cura 1.0 as Cura import QtGraphicalEffects 1.0 // For the dropshadow -// The expandable component has 3 major sub components: +// The expandable component has 2 major sub components: // * The headerItem; Always visible and should hold some info about what happens if the component is expanded -// * The popupItem; The content that needs to be shown if the component is expanded. -// * The icon; An icon that is displayed on the right of the drawer. +// * The contentItem; The content that needs to be shown if the component is expanded. Item { id: base - // Enumeration with the different possible alignments of the popup with respect of the headerItem - enum PopupAlignment + // Enumeration with the different possible alignments of the content with respect of the headerItem + enum ContentAlignment { AlignLeft, AlignRight } + enum ContentType + { + Floating, + Fixed + } + // The headerItem holds the QML item that is always displayed. property alias headerItem: headerItemLoader.sourceComponent - // The popupItem holds the QML item that is shown when the "open" button is pressed - property alias popupItem: popup.contentItem + // The contentItem holds the QML item that is shown when the "open" button is pressed + property alias contentItem: content.contentItem - property color popupBackgroundColor: UM.Theme.getColor("action_button") + // Defines the type of the contents + property int contentType: ExpandableComponent.ContentType.Floating + + property color contentBackgroundColor: UM.Theme.getColor("action_button") property color headerBackgroundColor: UM.Theme.getColor("action_button") property color headerHoverColor: UM.Theme.getColor("action_button_hovered") - // Defines the alignment of the popup with respect of the headerItem, by default to the right - property int popupAlignment: ExpandableComponent.PopupAlignment.AlignRight + // Defines the alignment of the content with respect of the headerItem, by default to the right + property int contentAlignment: ExpandableComponent.ContentAlignment.AlignRight - // How much spacing is needed around the popupItem - property alias popupPadding: popup.padding + // How much spacing is needed around the contentItem + property alias contentPadding: content.padding - // How much spacing is needed for the popupItem by Y coordinate - property var popupSpacingY: 0 + // How much spacing is needed for the contentItem by Y coordinate + property var contentSpacingY: 0 // How much padding is needed around the header & button property alias headerPadding: background.padding @@ -53,7 +61,7 @@ Item property alias iconSize: collapseButton.height // Is the "drawer" open? - readonly property alias expanded: popup.visible + readonly property alias expanded: content.visible property alias expandedHighlightColor: expandedHighlight.color @@ -63,8 +71,8 @@ Item // On what side should the header corners be shown? 1 is down, 2 is left, 3 is up and 4 is right. property alias headerCornerSide: background.cornerSide - // Change the popupItem close behaviour - property alias popupClosePolicy : popup.closePolicy + // Change the contentItem close behaviour + property alias contentClosePolicy : content.closePolicy property alias headerShadowColor: shadow.color @@ -72,15 +80,15 @@ Item property int shadowOffset: 2 - function togglePopup() + function toggleContent() { - if (popup.visible) + if (content.visible) { - popup.close() + content.close() } else { - popup.open() + content.open() } } @@ -108,7 +116,7 @@ Item } } - // A highlight that is shown when the popup is expanded + // A highlight that is shown when the content is expanded Rectangle { id: expandedHighlight @@ -140,7 +148,7 @@ Item { id: mouseArea anchors.fill: parent - onClicked: togglePopup() + onClicked: toggleContent() hoverEnabled: true onEntered: background.color = headerHoverColor onExited: background.color = headerBackgroundColor @@ -163,21 +171,21 @@ Item Popup { - id: popup + id: content - // Ensure that the popup is located directly below the headerItem - y: background.height + base.shadowOffset + popupSpacingY + // Ensure that the content is located directly below the headerItem + y: background.height + base.shadowOffset + base.contentSpacingY - // Make the popup aligned with the rest, using the property popupAlignment to decide whether is right or left. + // Make the content aligned with the rest, using the property contentAlignment to decide whether is right or left. // In case of right alignment, the 3x padding is due to left, right and padding between the button & text. - x: popupAlignment == ExpandableComponent.PopupAlignment.AlignRight ? -width + collapseButton.width + headerItemLoader.width + 3 * background.padding : 0 + x: contentAlignment == ExpandableComponent.ContentAlignment.AlignRight ? -width + collapseButton.width + headerItemLoader.width + 3 * background.padding : 0 padding: UM.Theme.getSize("default_margin").width closePolicy: Popup.CloseOnPressOutsideParent background: Cura.RoundedRectangle { cornerSide: Cura.RoundedRectangle.Direction.Down - color: popupBackgroundColor + color: contentBackgroundColor border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") radius: UM.Theme.getSize("default_radius").width @@ -187,20 +195,20 @@ Item onContentItemChanged: { - // Since we want the size of the popup to be set by the size of the content, + // Since we want the size of the content to be set by the size of the content, // we need to do it like this. - popup.width = contentItem.width + 2 * popup.padding - popup.height = contentItem.height + 2 * popup.padding + content.width = contentItem.width + 2 * content.padding + content.height = contentItem.height + 2 * content.padding } } - // DO NOT MOVE UP IN THE CODE: This connection has to be here, after the definition of the Popup item. + // DO NOT MOVE UP IN THE CODE: This connection has to be here, after the definition of the content item. // Apparently the order in which these are handled matters and so the height is correctly updated if this is here. Connections { - // Since it could be that the popup is dynamically populated, we should also take these changes into account. - target: popup.contentItem - onWidthChanged: popup.width = popup.contentItem.width + 2 * popup.padding - onHeightChanged: popup.height = popup.contentItem.height + 2 * popup.padding + // Since it could be that the content is dynamically populated, we should also take these changes into account. + target: content.contentItem + onWidthChanged: content.width = content.contentItem.width + 2 * content.padding + onHeightChanged: content.height = content.contentItem.height + 2 * content.padding } } diff --git a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml index eb6800cb36..de92161bbb 100644 --- a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml +++ b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml @@ -93,7 +93,7 @@ Cura.ExpandableComponent } } - popupItem: Item + contentItem: Item { width: base.width - 2 * UM.Theme.getSize("default_margin").width height: 200 diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector/PrintSetupSelector.qml index f1b424f7f2..78bdbde542 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelector.qml @@ -15,10 +15,10 @@ Cura.ExpandableComponent property string disabledText: catalog.i18nc("@label:Should be short", "Off") iconSource: UM.Theme.getIcon("pencil") - popupPadding: UM.Theme.getSize("default_lining").width - popupSpacingY: UM.Theme.getSize("narrow_margin").width + contentPadding: UM.Theme.getSize("default_lining").width + contentSpacingY: UM.Theme.getSize("narrow_margin").width - popupClosePolicy: Popup.CloseOnEscape + contentClosePolicy: Popup.CloseOnEscape UM.I18nCatalog { @@ -36,5 +36,5 @@ Cura.ExpandableComponent id: extrudersModel } - popupItem: PrintSetupSelectorContents {} + contentItem: PrintSetupSelectorContents {} } \ No newline at end of file diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index 15cd773c90..f742d0bef3 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -15,8 +15,8 @@ Cura.ExpandableComponent property bool isPrinterConnected: Cura.MachineManager.printerConnected property var outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null - popupPadding: UM.Theme.getSize("default_lining").width - popupAlignment: Cura.ExpandableComponent.PopupAlignment.AlignLeft + contentPadding: UM.Theme.getSize("default_lining").width + contentAlignment: Cura.ExpandableComponent.ContentAlignment.AlignLeft iconSource: expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") UM.I18nCatalog @@ -80,7 +80,7 @@ Cura.ExpandableComponent } } - popupItem: Item + contentItem: Item { id: popup width: UM.Theme.getSize("machine_selector_widget_content").width diff --git a/resources/qml/ViewsSelector.qml b/resources/qml/ViewsSelector.qml index e9fdd57177..97de60689b 100644 --- a/resources/qml/ViewsSelector.qml +++ b/resources/qml/ViewsSelector.qml @@ -11,8 +11,8 @@ Cura.ExpandableComponent { id: viewSelector - popupPadding: UM.Theme.getSize("default_lining").width - popupAlignment: Cura.ExpandableComponent.PopupAlignment.AlignLeft + contentPadding: UM.Theme.getSize("default_lining").width + contentAlignment: Cura.ExpandableComponent.ContentAlignment.AlignLeft iconSource: expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") property var viewModel: UM.ViewModel { } @@ -70,7 +70,7 @@ Cura.ExpandableComponent } } - popupItem: Column + contentItem: Column { id: viewSelectorPopup width: viewSelector.width - 2 * viewSelector.popupPadding From 02963eb9bfdeac576786889e5568203ee11ab764 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Tue, 4 Dec 2018 13:19:12 +0100 Subject: [PATCH 0639/1292] Use a timer for the periodic update of the remote clusters and printjobs --- .../src/Cloud/CloudOutputDeviceManager.py | 22 +++---------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 37198fd7c6..85e734f7a3 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -2,7 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. import json from time import sleep -from threading import Thread +from threading import Timer from typing import Dict, Optional from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply @@ -43,13 +43,8 @@ class CloudOutputDeviceManager(NetworkClient): # When switching machines we check if we have to activate a remote cluster. application.globalContainerStackChanged.connect(self._connectToActiveMachine) - # Periodically check all remote clusters for the authenticated user. - # This is done by emitting to _on_cluster_received by _update_clusters_thread - # The thread is only started after the user is authenticated, otherwise the api call results in - # an authentication error self._on_cluster_received = Signal() self._on_cluster_received.connect(self._getRemoteClusters) - self._update_clusters_thread = Thread(target=self._updateClusters, daemon=True) ## Override _createEmptyRequest to add the needed authentication header for talking to the Ultimaker Cloud API. @@ -61,17 +56,6 @@ class CloudOutputDeviceManager(NetworkClient): request.setRawHeader(b"Authorization", "Bearer {}".format(self._account.accessToken).encode()) return request - ## Update the clusters - def _updateClusters(self) -> None: - while True: - - # Stop if the application is shutting down - if CuraApplication.getInstance().isShuttingDown(): - return - - self._on_cluster_received.emit() - sleep(5) - ## Gets all remote clusters from the API. def _getRemoteClusters(self) -> None: Logger.log("i", "Retrieving remote clusters") @@ -80,8 +64,8 @@ class CloudOutputDeviceManager(NetworkClient): # Only start the polling thread after the user is authenticated # The first call to _getRemoteClusters comes from self._account.loginStateChanged - if not self._update_clusters_thread.is_alive(): - self._update_clusters_thread.start() + timer = Timer(5.0, self._on_cluster_received.emit) + timer.start() ## Callback for when the request for getting the clusters. is finished. From 4dcce7616bb8286c265a392ed21d62fabd10e6a7 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 4 Dec 2018 13:21:26 +0100 Subject: [PATCH 0640/1292] Fix some leftover renamings Contributes to CURA-5941 --- resources/qml/Account/AccountDetails.qml | 4 ++-- resources/qml/ExpandableComponent.qml | 4 ++-- .../qml/PrintSetupSelector/PrintSetupSelectorContents.qml | 2 +- resources/qml/PrinterSelector/MachineSelector.qml | 4 ++-- resources/qml/PrinterSelector/MachineSelectorButton.qml | 2 +- resources/qml/ViewsSelector.qml | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/resources/qml/Account/AccountDetails.qml b/resources/qml/Account/AccountDetails.qml index a288426e0c..bfb23930c6 100644 --- a/resources/qml/Account/AccountDetails.qml +++ b/resources/qml/Account/AccountDetails.qml @@ -13,8 +13,8 @@ Column property var loggedIn: false property var profileImage: "" - padding: 2 * UM.Theme.getSize("default_margin").height - spacing: 2 * UM.Theme.getSize("default_margin").height + padding: UM.Theme.getSize("wide_margin").height + spacing: UM.Theme.getSize("wide_margin").height AvatarImage { diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index 0b4076c04a..89f6cf9f25 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -139,8 +139,8 @@ Item sourceSize.width: width sourceSize.height: height visible: source != "" - width: height - height: Math.round(0.2 * base.height) + width: UM.Theme.getSize("standard_arrow").width + height: UM.Theme.getSize("standard_arrow").height color: UM.Theme.getColor("text") } diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml index a2856e1fe5..0524a6de9e 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml @@ -93,7 +93,7 @@ Item background: Item {} - onClicked: togglePopup() // Will hide the popup item + onClicked: toggleContent() // Will hide the popup item } } diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index f742d0bef3..49b4f87267 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -134,7 +134,7 @@ Cura.ExpandableComponent text: catalog.i18nc("@button", "Add printer") onClicked: { - togglePopup() + toggleContent() Cura.Actions.addMachine.trigger() } } @@ -146,7 +146,7 @@ Cura.ExpandableComponent text: catalog.i18nc("@button", "Manage printers") onClicked: { - togglePopup() + toggleContent() Cura.Actions.configureMachines.trigger() } } diff --git a/resources/qml/PrinterSelector/MachineSelectorButton.qml b/resources/qml/PrinterSelector/MachineSelectorButton.qml index 369e75cede..b88af35f82 100644 --- a/resources/qml/PrinterSelector/MachineSelectorButton.qml +++ b/resources/qml/PrinterSelector/MachineSelectorButton.qml @@ -83,7 +83,7 @@ Button onClicked: { - togglePopup() + toggleContent() Cura.MachineManager.setActiveMachine(model.id) } diff --git a/resources/qml/ViewsSelector.qml b/resources/qml/ViewsSelector.qml index 97de60689b..71a29e4949 100644 --- a/resources/qml/ViewsSelector.qml +++ b/resources/qml/ViewsSelector.qml @@ -120,7 +120,7 @@ Cura.ExpandableComponent onClicked: { - viewSelector.togglePopup() + toggleContent() UM.Controller.setActiveView(id) } } From 8e3e0c149e6963f01485ff411902ad5e932b764d Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 4 Dec 2018 13:23:31 +0100 Subject: [PATCH 0641/1292] fixes --- .../src/Cloud/CloudOutputDevice.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 747d911407..d17728f513 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -215,10 +215,6 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): return [print_job for print_job in self._print_jobs if print_job.assignedPrinter is not None and print_job.state != "queued"] - @pyqtProperty(bool, notify = printJobsChanged) - def receivedPrintJobs(self) -> bool: - return not self._sending_job - ## Called when the connection to the cluster changes. def connect(self) -> None: super().connect() @@ -464,7 +460,9 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): @pyqtProperty(QObject, notify = printersChanged) def activePrinter(self) -> Optional[PrinterOutputModel]: - return self._printers[0] or None + if not self._printers: + return None + return self._printers[0] @pyqtSlot(QObject) def setActivePrinter(self, printer: Optional[PrinterOutputModel]) -> None: @@ -477,3 +475,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): @pyqtSlot(QUrl) def setActiveCameraUrl(self, camera_url: "QUrl") -> None: pass + + @pyqtProperty(bool, notify = printJobsChanged) + def receivedPrintJobs(self) -> bool: + return True From 47ff95b1f3cfb793b2b4af6114aa1688e864d8a3 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 4 Dec 2018 13:53:11 +0100 Subject: [PATCH 0642/1292] Set contentType to the different expandable components. Also add a color for the active state when the contentType is 'Fixed'. Contributes to CURA-5941. --- .../SimulationViewMenuComponent.qml | 2 +- resources/qml/ExpandableComponent.qml | 28 +++++++++++-------- .../QuickConfigurationSelector.qml | 1 - .../PrintSetupSelector/PrintSetupSelector.qml | 2 +- .../qml/PrinterSelector/MachineSelector.qml | 1 - resources/qml/ViewsSelector.qml | 1 - 6 files changed, 18 insertions(+), 17 deletions(-) diff --git a/plugins/SimulationView/SimulationViewMenuComponent.qml b/plugins/SimulationView/SimulationViewMenuComponent.qml index a9eb157f48..9dc3b67658 100644 --- a/plugins/SimulationView/SimulationViewMenuComponent.qml +++ b/plugins/SimulationView/SimulationViewMenuComponent.qml @@ -16,7 +16,7 @@ Cura.ExpandableComponent id: base width: UM.Theme.getSize("layerview_menu_size").width - iconSource: UM.Theme.getIcon("pencil") + contentType: Cura.ExpandableComponent.ContentType.Fixed Connections { diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index 89f6cf9f25..f6e340c4ea 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -30,7 +30,7 @@ Item property alias headerItem: headerItemLoader.sourceComponent // The contentItem holds the QML item that is shown when the "open" button is pressed - property alias contentItem: content.contentItem + property var contentItem: content.contentItem // Defines the type of the contents property int contentType: ExpandableComponent.ContentType.Floating @@ -38,6 +38,7 @@ Item property color contentBackgroundColor: UM.Theme.getColor("action_button") property color headerBackgroundColor: UM.Theme.getColor("action_button") + property color headerActiveColor: UM.Theme.getColor("secondary") property color headerHoverColor: UM.Theme.getColor("action_button_hovered") // Defines the alignment of the content with respect of the headerItem, by default to the right @@ -123,7 +124,7 @@ Item width: parent.width height: UM.Theme.getSize("thick_lining").height color: UM.Theme.getColor("primary") - visible: expanded + visible: contentType == ExpandableComponent.ContentType.Floating && expanded anchors.bottom: parent.bottom } @@ -138,6 +139,9 @@ Item } sourceSize.width: width sourceSize.height: height + source: contentType == ExpandableComponent.ContentType.Floating ? + (expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left")) : + UM.Theme.getIcon("pencil") visible: source != "" width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height @@ -151,7 +155,8 @@ Item onClicked: toggleContent() hoverEnabled: true onEntered: background.color = headerHoverColor - onExited: background.color = headerBackgroundColor + onExited: background.color = (contentType == ExpandableComponent.ContentType.Fixed && expanded) ? + headerActiveColor : headerBackgroundColor } } @@ -190,16 +195,15 @@ Item border.color: UM.Theme.getColor("lining") radius: UM.Theme.getSize("default_radius").width } + } - contentItem: Item { } - - onContentItemChanged: - { - // Since we want the size of the content to be set by the size of the content, - // we need to do it like this. - content.width = contentItem.width + 2 * content.padding - content.height = contentItem.height + 2 * content.padding - } + onContentItemChanged: + { + // Since we want the size of the content to be set by the size of the content, + // we need to do it like this. + content.width = contentItem.width + 2 * content.padding + content.height = contentItem.height + 2 * content.padding + content.contentItem = contentItem } // DO NOT MOVE UP IN THE CODE: This connection has to be here, after the definition of the content item. diff --git a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml index de92161bbb..ea82f4fe13 100644 --- a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml +++ b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml @@ -27,7 +27,6 @@ Cura.ExpandableComponent name: "cura" } - iconSource: expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") headerItem: Item { // Horizontal list that shows the extruders diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector/PrintSetupSelector.qml index 78bdbde542..0eea697950 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelector.qml @@ -14,7 +14,7 @@ Cura.ExpandableComponent property string enabledText: catalog.i18nc("@label:Should be short", "On") property string disabledText: catalog.i18nc("@label:Should be short", "Off") - iconSource: UM.Theme.getIcon("pencil") + contentType: Cura.ExpandableComponent.ContentType.Fixed contentPadding: UM.Theme.getSize("default_lining").width contentSpacingY: UM.Theme.getSize("narrow_margin").width diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index 49b4f87267..69a1ac899c 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -17,7 +17,6 @@ Cura.ExpandableComponent contentPadding: UM.Theme.getSize("default_lining").width contentAlignment: Cura.ExpandableComponent.ContentAlignment.AlignLeft - iconSource: expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") UM.I18nCatalog { diff --git a/resources/qml/ViewsSelector.qml b/resources/qml/ViewsSelector.qml index 71a29e4949..d469202606 100644 --- a/resources/qml/ViewsSelector.qml +++ b/resources/qml/ViewsSelector.qml @@ -13,7 +13,6 @@ Cura.ExpandableComponent contentPadding: UM.Theme.getSize("default_lining").width contentAlignment: Cura.ExpandableComponent.ContentAlignment.AlignLeft - iconSource: expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") property var viewModel: UM.ViewModel { } From 5d77209cfbadbf5f43571bf6cf350273ed874c79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Tue, 4 Dec 2018 13:57:41 +0100 Subject: [PATCH 0643/1292] Be more efficient in updating the print jobs --- plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py | 6 ++++-- .../src/Cloud/CloudOutputDeviceManager.py | 1 - 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index d17728f513..0f3a92f9d8 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -338,8 +338,10 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): for job_id in updated_job_ids: self._updateUM3PrintJobOutputModel(current_jobs[job_id], remote_jobs[job_id]) - # TODO: properly handle removed and updated printers - self.printJobsChanged.emit() + # We only have to update when jobs are added or removed + # updated jobs push their changes via their outputmodel + if len(removed_job_ids) > 0 or len(new_job_ids) > 0: + self.printJobsChanged.emit() def _addPrintJob(self, job: CloudClusterPrintJob) -> None: try: diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 85e734f7a3..c6134d9a63 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -1,7 +1,6 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import json -from time import sleep from threading import Timer from typing import Dict, Optional From 82d8410d184d0727612158bf50e45a8b13ae31a9 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 4 Dec 2018 13:58:54 +0100 Subject: [PATCH 0644/1292] Don't emit enabledChanged signal if it didn't change Contributes to issue CURA-5876. --- cura/Settings/ExtruderStack.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cura/Settings/ExtruderStack.py b/cura/Settings/ExtruderStack.py index ed758db183..d626ef06da 100644 --- a/cura/Settings/ExtruderStack.py +++ b/cura/Settings/ExtruderStack.py @@ -52,6 +52,8 @@ class ExtruderStack(CuraContainerStack): return super().getNextStack() def setEnabled(self, enabled: bool) -> None: + if self.getMetaDataEntry("enabled", True) == enabled: #No change. + return #Don't emit a signal then. self.setMetaDataEntry("enabled", str(enabled)) self.enabledChanged.emit() From a1f579a5288a43dd48480f565ed8c2dd514f9b47 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 4 Dec 2018 14:01:49 +0100 Subject: [PATCH 0645/1292] Improve wording of iconOnRightSide documentation Contributes to issue CURA-5876. --- resources/qml/ActionButton.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index cd0a264766..116253ab7a 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -43,7 +43,7 @@ Button contentItem: Row { - //Icon if displayed on the left side. + //Left side icon. Only displayed if !iconOnRightSide. UM.RecolorImage { id: buttonIconLeft @@ -71,7 +71,7 @@ Button elide: Text.ElideRight } - //Icon if displayed on the right side. + //Right side icon. Only displayed if iconOnRightSide. UM.RecolorImage { id: buttonIconRight From 801701623eedd41681c4caf31251b2cd4bf33f84 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 4 Dec 2018 14:04:07 +0100 Subject: [PATCH 0646/1292] Remove unnecessary top anchor in first subitem of item It already gets aligned to the top anyway. Contributes to issue CURA-5876. --- resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml index 8e86549e17..58b6bac089 100644 --- a/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml @@ -22,7 +22,6 @@ Item anchors { - top: parent.top left: parent.left right: parent.right } From e98f3bff384c384eaab419c6997de52e55a7bb25 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 4 Dec 2018 14:09:20 +0100 Subject: [PATCH 0647/1292] Implement test version of showing cloud connected printers in list --- cura/Settings/MachineManager.py | 6 +++ .../src/Cloud/CloudOutputDeviceManager.py | 9 +++- resources/qml/Menus/CloudPrinterMenu.qml | 26 +++++++++++ resources/qml/Menus/PrinterMenu.qml | 17 +++++++ .../PrinterSelector/MachineSelectorList.qml | 44 ++++++++++++++++++- 5 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 resources/qml/Menus/CloudPrinterMenu.qml diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 53390ca88d..15e2c67c33 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -527,6 +527,12 @@ class MachineManager(QObject): return self._global_container_stack.getMetaDataEntry("um_network_key", "") return "" + @pyqtProperty(str, notify=printerConnectedStatusChanged) + def activeMachineCloudKey(self) -> str: + if self._global_container_stack: + return self._global_container_stack.getMetaDataEntry("um_cloud_cluster_id", "") + return "" + @pyqtProperty(str, notify = printerConnectedStatusChanged) def activeMachineNetworkGroupName(self) -> str: if self._global_container_stack: diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 85e734f7a3..6c5d681a39 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -116,7 +116,7 @@ class CloudOutputDeviceManager(NetworkClient): self._output_device_manager.addOutputDevice(device) self._remote_clusters[cluster.cluster_id] = device device.connect() # TODO: remove this - self._connectToActiveMachine() + self._connectToActiveMachine(cluster.cluster_id, cluster.host_name) ## Remove a CloudOutputDevice def _removeCloudOutputDevice(self, cluster: CloudCluster): @@ -124,10 +124,15 @@ class CloudOutputDeviceManager(NetworkClient): del self._remote_clusters[cluster.cluster_id] ## Callback for when the active machine was changed by the user. - def _connectToActiveMachine(self) -> None: + def _connectToActiveMachine(self, cluster_id: Optional[str] = None, host_name: Optional[str] = None) -> None: active_machine = CuraApplication.getInstance().getGlobalContainerStack() if not active_machine: return + + # TODO: Remove this once correct pairing has been added (see below). + if cluster_id: + active_machine.setMetaDataEntry("um_cloud_cluster_id", cluster_id) + active_machine.setMetaDataEntry("connect_group_name", host_name) # Check if the stored cluster_id for the active machine is in our list of remote clusters. stored_cluster_id = active_machine.getMetaDataEntry("um_cloud_cluster_id") diff --git a/resources/qml/Menus/CloudPrinterMenu.qml b/resources/qml/Menus/CloudPrinterMenu.qml new file mode 100644 index 0000000000..4ceebbfdfc --- /dev/null +++ b/resources/qml/Menus/CloudPrinterMenu.qml @@ -0,0 +1,26 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. +import QtQuick 2.2 +import QtQuick.Controls 1.4 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +Instantiator { + + model: UM.ContainerStacksModel { + filter: {"type": "machine", "um_cloud_cluster_id": "*", "hidden": "False"} + } + + MenuItem { + // iconSource: UM.Theme.getIcon("printer_single") TODO: use cloud icon here + text: model.name + checkable: true + checked: true // cloud printers are only listed if they are actually online + exclusiveGroup: group; + onTriggered: Cura.MachineManager.setActiveMachine(model.id); + } + + onObjectAdded: menu.insertItem(index, object) + onObjectRemoved: menu.removeItem(object) +} diff --git a/resources/qml/Menus/PrinterMenu.qml b/resources/qml/Menus/PrinterMenu.qml index 741d927c13..a924b0e589 100644 --- a/resources/qml/Menus/PrinterMenu.qml +++ b/resources/qml/Menus/PrinterMenu.qml @@ -37,6 +37,23 @@ Menu visible: networkPrinterMenu.count > 0 } + MenuItem + { + text: catalog.i18nc("@label:category menu label", "Cloud enabled printers") + enabled: false + visible: cloudPrinterMenu.count > 0 + } + + CloudPrinterMenu + { + id: cloudPrinterMenu + } + + MenuSeparator + { + visible: cloudPrinterMenu.count > 0 + } + MenuItem { text: catalog.i18nc("@label:category menu label", "Local printers") diff --git a/resources/qml/PrinterSelector/MachineSelectorList.qml b/resources/qml/PrinterSelector/MachineSelectorList.qml index 5ef04b7351..26c703fddd 100644 --- a/resources/qml/PrinterSelector/MachineSelectorList.qml +++ b/resources/qml/PrinterSelector/MachineSelectorList.qml @@ -50,6 +50,46 @@ Column } } + Label + { + text: catalog.i18nc("@label", "Cloud connected printers") + visible: cloudPrintersModel.items.length > 0 + leftPadding: UM.Theme.getSize("default_margin").width + height: visible ? contentHeight + 2 * UM.Theme.getSize("default_margin").height : 0 + renderType: Text.NativeRendering + font: UM.Theme.getFont("medium") + color: UM.Theme.getColor("text_medium") + verticalAlignment: Text.AlignVCenter + } + + Repeater + { + id: cloudPrinters + + model: UM.ContainerStacksModel + { + id: cloudPrintersModel + filter: + { + "type": "machine", + "um_cloud_cluster_id": "*" + } + } + + delegate: MachineSelectorButton + { + text: model.metadata["connect_group_name"] + checked: Cura.MachineManager.activeMachineNetworkGroupName == model.metadata["connect_group_name"] + outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null + + Connections + { + target: Cura.MachineManager + onActiveMachineNetworkGroupNameChanged: checked = Cura.MachineManager.activeMachineNetworkGroupName == model.metadata["connect_group_name"] + } + } + } + Label { text: catalog.i18nc("@label", "Preset printers") @@ -71,7 +111,9 @@ Column id: virtualPrintersModel filter: { - "type": "machine", "um_network_key": null + "type": "machine", + "um_network_key": null, + "um_cloud_cluster_id": null } } From 7de947f5fab60e8cc9d38c17d5f0c62653cd13f0 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 4 Dec 2018 14:15:19 +0100 Subject: [PATCH 0648/1292] use correct label text --- resources/qml/Menus/CloudPrinterMenu.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Menus/CloudPrinterMenu.qml b/resources/qml/Menus/CloudPrinterMenu.qml index 4ceebbfdfc..bd03890642 100644 --- a/resources/qml/Menus/CloudPrinterMenu.qml +++ b/resources/qml/Menus/CloudPrinterMenu.qml @@ -9,12 +9,12 @@ import Cura 1.0 as Cura Instantiator { model: UM.ContainerStacksModel { - filter: {"type": "machine", "um_cloud_cluster_id": "*", "hidden": "False"} + filter: {"type": "machine", "um_cloud_cluster_id": "*"} } MenuItem { // iconSource: UM.Theme.getIcon("printer_single") TODO: use cloud icon here - text: model.name + text: model.metadata["connect_group_name"] checkable: true checked: true // cloud printers are only listed if they are actually online exclusiveGroup: group; From 759b5b58476c3d2be6c0faf5118fc052f1d6bec8 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 4 Dec 2018 14:23:41 +0100 Subject: [PATCH 0649/1292] Use anchors rather than a calculation with padding It's supposed to be slightly more efficient. Contributes to issue CURA-5876. --- .../ConfigurationMenu/ConfigurationItem.qml | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 3ea220c91e..7ba7202819 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -34,7 +34,13 @@ Button { id: extruderRow - width: parent.width - 2 * parent.padding + anchors + { + left: parent.left + leftMargin: parent.padding + right: parent.right + rightMargin: parent.padding + } height: childrenRect.height spacing: UM.Theme.getSize("default_margin").width @@ -58,7 +64,13 @@ Button id: separator visible: buildplateInformation.visible - width: parent.width - 2 * parent.padding + anchors + { + left: parent.left + leftMargin: parent.padding + right: parent.right + rightMargin: parent.padding + } height: visible ? Math.round(UM.Theme.getSize("thick_lining").height / 2) : 0 color: UM.Theme.getColor("text") } @@ -66,7 +78,14 @@ Button Item { id: buildplateInformation - width: parent.width - 2 * parent.padding + + anchors + { + left: parent.left + leftMargin: parent.padding + right: parent.right + rightMargin: parent.padding + } height: childrenRect.height visible: configuration.buildplateConfiguration != "" From 7cc1f021c1333fe962a2875167f6b1750bc238fb Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 4 Dec 2018 14:25:58 +0100 Subject: [PATCH 0650/1292] Fix right-alignment of configuration items in list The scrollbar will go on top of it now, but it looks nicer if you don't scroll. Maybe we have to make it adaptable? Contributes to issue CURA-5876. --- .../qml/Menus/ConfigurationMenu/ConfigurationListView.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index 32be97f74e..5a9f72260c 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -27,7 +27,7 @@ Column ScrollView { id: container - width: parent.width - parent.padding + width: parent.width height: Math.min(configurationList.contentHeight, 350 * screenScaleFactor) ButtonGroup @@ -58,7 +58,7 @@ Column delegate: ConfigurationItem { - width: parent.width - UM.Theme.getSize("default_margin").width + width: parent.width configuration: modelData } } From 347240410ad1885d3dc237dc7f0db1f9e249671b Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 4 Dec 2018 14:35:28 +0100 Subject: [PATCH 0651/1292] Use enumeration to check and switch state of configuration menu Instead of a string. This is a bit more restrictive. Contributes to issue CURA-5876. --- .../ConfigurationMenu/ConfigurationMenu.qml | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index 79b7c9bf66..1b7dfe30e4 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -28,6 +28,12 @@ Cura.ExpandableComponent name: "cura" } + enum ConfigurationMethod + { + AUTO, + CUSTOM + } + iconSource: expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") headerItem: Item { @@ -108,7 +114,7 @@ Cura.ExpandableComponent is_connected = Cura.MachineManager.activeMachineNetworkKey !== "" && Cura.MachineManager.printerConnected //Re-evaluate. } - property var configuration_method: is_connected ? "auto" : "custom" //Auto if connected to a printer at start-up, or Custom if not. + property int configuration_method: is_connected ? ConfigurationMenu.ConfigurationMethod.AUTO : ConfigurationMenu.ConfigurationMethod.CUSTOM //Auto if connected to a printer at start-up, or Custom if not. Item { @@ -117,13 +123,13 @@ Cura.ExpandableComponent AutoConfiguration { id: autoConfiguration - visible: popupItem.configuration_method === "auto" + visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.AUTO } CustomConfiguration { id: customConfiguration - visible: popupItem.configuration_method === "custom" + visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.CUSTOM } } @@ -150,7 +156,7 @@ Cura.ExpandableComponent Cura.SecondaryButton { id: goToCustom - visible: popupItem.configuration_method === "auto" + visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.AUTO text: catalog.i18nc("@label", "Custom") anchors @@ -162,13 +168,13 @@ Cura.ExpandableComponent iconSource: UM.Theme.getIcon("arrow_right") iconOnRightSide: true - onClicked: popupItem.configuration_method = "custom" + onClicked: popupItem.configuration_method = ConfigurationMenu.ConfigurationMethod.CUSTOM } Cura.SecondaryButton { id: goToAuto - visible: popupItem.configuration_method === "custom" + visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.CUSTOM text: catalog.i18nc("@label", "Configurations") anchors @@ -179,7 +185,7 @@ Cura.ExpandableComponent iconSource: UM.Theme.getIcon("arrow_left") - onClicked: popupItem.configuration_method = "auto" + onClicked: popupItem.configuration_method = ConfigurationMenu.ConfigurationMethod.AUTO } } } From 2dde2438b2a984e2dabf19edcb5164934e456050 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 4 Dec 2018 14:38:13 +0100 Subject: [PATCH 0652/1292] Remove unnecessary anchors Contributes to issue CURA-5876. --- .../Menus/ConfigurationMenu/ConfigurationMenu.qml | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index 1b7dfe30e4..a49fe5574f 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -159,11 +159,7 @@ Cura.ExpandableComponent visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.AUTO text: catalog.i18nc("@label", "Custom") - anchors - { - right: parent.right - top: parent.top - } + anchors.right: parent.right iconSource: UM.Theme.getIcon("arrow_right") iconOnRightSide: true @@ -177,12 +173,6 @@ Cura.ExpandableComponent visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.CUSTOM text: catalog.i18nc("@label", "Configurations") - anchors - { - left: parent.left - top: parent.top - } - iconSource: UM.Theme.getIcon("arrow_left") onClicked: popupItem.configuration_method = ConfigurationMenu.ConfigurationMethod.AUTO From 023100f4c3690e564d26ddf4bd6ffece955d4c38 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 4 Dec 2018 14:39:08 +0100 Subject: [PATCH 0653/1292] Changed valueError property to bool instead of var A bit more specific. Contributes to issue CURA-5876. Co-Authored-By: Ghostkeeper --- resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index 7ff47ea16f..e28478e9e2 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -181,7 +181,7 @@ Item { id: materialSelection - property var valueError: Cura.MachineManager.activeStack != null ? Cura.ContainerManager.getContainerMetaDataEntry(Cura.MachineManager.activeStack.material.id, "compatible", "") != "True" : true + property bool valueError: Cura.MachineManager.activeStack != null ? Cura.ContainerManager.getContainerMetaDataEntry(Cura.MachineManager.activeStack.material.id, "compatible", "") != "True" : true property var valueWarning: !Cura.MachineManager.isActiveQualitySupported text: Cura.MachineManager.activeStack != null ? Cura.MachineManager.activeStack.material.name : "" @@ -232,4 +232,4 @@ Item } } } -} \ No newline at end of file +} From 8a257f018486a2d4cc22ae980ea4e8dd8e5ffc57 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 4 Dec 2018 14:39:39 +0100 Subject: [PATCH 0654/1292] Change valueWarning property to bool instead of var A bit more specific. Contributes to issue CURA-5876. Co-Authored-By: Ghostkeeper --- resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index e28478e9e2..72b640e94a 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -182,7 +182,7 @@ Item id: materialSelection property bool valueError: Cura.MachineManager.activeStack != null ? Cura.ContainerManager.getContainerMetaDataEntry(Cura.MachineManager.activeStack.material.id, "compatible", "") != "True" : true - property var valueWarning: !Cura.MachineManager.isActiveQualitySupported + property bool valueWarning: !Cura.MachineManager.isActiveQualitySupported text: Cura.MachineManager.activeStack != null ? Cura.MachineManager.activeStack.material.name : "" tooltip: text From ef29fb0cfaaf22ccd582ad238cbc3259894fb137 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 4 Dec 2018 14:44:12 +0100 Subject: [PATCH 0655/1292] Remove unnecessary item wrapper Contributes to issue CURA-5876. --- .../ConfigurationMenu/PrintCoreConfiguration.qml | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml index 8d2f0c0f7c..4064a961d5 100644 --- a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml @@ -16,16 +16,11 @@ Row spacing: UM.Theme.getSize("default_margin").width //Extruder icon. - Item + Cura.ExtruderIcon { - width: childrenRect.width - height: information.height - Cura.ExtruderIcon - { - materialColor: printCoreConfiguration.material.color - anchors.verticalCenter: parent.verticalCenter - extruderEnabled: printCoreConfiguration.material.name !== "" && printCoreConfiguration.hotendID !== "" - } + materialColor: printCoreConfiguration.material.color + anchors.verticalCenter: parent.verticalCenter + extruderEnabled: printCoreConfiguration.material.name !== "" && printCoreConfiguration.hotendID !== "" } Column From 2fdfdaa00b4cc7cea04e754a25ad58f056d3d684 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 4 Dec 2018 14:47:34 +0100 Subject: [PATCH 0656/1292] Rename iconOnRightSide to isIconOnRightSide More accurately represents the type of value that's in this property. Contributes to issue CURA-5876. --- resources/qml/ActionButton.qml | 10 +++++----- .../qml/Menus/ConfigurationMenu/ConfigurationMenu.qml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index 116253ab7a..2107264dff 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -12,7 +12,7 @@ Button { id: button property alias iconSource: buttonIconLeft.source - property var iconOnRightSide: false + property bool isIconOnRightSide: false property alias textFont: buttonText.font property alias cornerRadius: backgroundRect.radius property alias tooltip: tooltip.text @@ -43,7 +43,7 @@ Button contentItem: Row { - //Left side icon. Only displayed if !iconOnRightSide. + //Left side icon. Only displayed if !isIconOnRightSide. UM.RecolorImage { id: buttonIconLeft @@ -53,7 +53,7 @@ Button sourceSize.width: width sourceSize.height: height color: button.hovered ? button.textHoverColor : button.textColor - visible: source != "" && !button.iconOnRightSide + visible: source != "" && !button.isIconOnRightSide anchors.verticalCenter: parent.verticalCenter } @@ -71,7 +71,7 @@ Button elide: Text.ElideRight } - //Right side icon. Only displayed if iconOnRightSide. + //Right side icon. Only displayed if isIconOnRightSide. UM.RecolorImage { id: buttonIconRight @@ -81,7 +81,7 @@ Button sourceSize.width: width sourceSize.height: height color: buttonIconLeft.color - visible: source != "" && button.iconOnRightSide + visible: source != "" && button.isIconOnRightSide anchors.verticalCenter: buttonIconLeft.verticalCenter } } diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index a49fe5574f..f81176ab1a 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -162,7 +162,7 @@ Cura.ExpandableComponent anchors.right: parent.right iconSource: UM.Theme.getIcon("arrow_right") - iconOnRightSide: true + isIconOnRightSide: true onClicked: popupItem.configuration_method = ConfigurationMenu.ConfigurationMethod.CUSTOM } From 5b4fad3c08fe089bf216f91ac2ce889c4cc16e83 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 4 Dec 2018 14:54:15 +0100 Subject: [PATCH 0657/1292] When toggling auto-slice, force a re-slice CURA-5997 --- resources/qml/ActionPanel/SliceProcessWidget.qml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index 14e149dddb..03d91db530 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -137,6 +137,10 @@ Column { var autoSlice = UM.Preferences.getValue("general/auto_slice") prepareButtons.autoSlice = autoSlice + if(autoSlice) + { + CuraApplication.backend.forceSlice() + } } } From 02e7f904734c3d0cae1a33f0a978d3c3aa088912 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 4 Dec 2018 15:02:24 +0100 Subject: [PATCH 0658/1292] Fix module importing in USBPrinting CURA-5943 --- plugins/USBPrinting/AutoDetectBaudJob.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/USBPrinting/AutoDetectBaudJob.py b/plugins/USBPrinting/AutoDetectBaudJob.py index 6f1af6727a..78de864e57 100644 --- a/plugins/USBPrinting/AutoDetectBaudJob.py +++ b/plugins/USBPrinting/AutoDetectBaudJob.py @@ -3,8 +3,8 @@ from UM.Job import Job from UM.Logger import Logger -from plugins.USBPrinting.avr_isp import ispBase +from .avr_isp import ispBase from .avr_isp.stk500v2 import Stk500v2 from time import time, sleep From 43096c1bafc0790bf265709d46eb1b88eb7445dc Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 4 Dec 2018 15:03:43 +0100 Subject: [PATCH 0659/1292] Update USBPrinting version to 1.0.1 CURA-5943 --- plugins/USBPrinting/plugin.json | 2 +- resources/bundled_packages/cura.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/USBPrinting/plugin.json b/plugins/USBPrinting/plugin.json index 3484c8a48a..5d3cba8415 100644 --- a/plugins/USBPrinting/plugin.json +++ b/plugins/USBPrinting/plugin.json @@ -1,7 +1,7 @@ { "name": "USB printing", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "api": 5, "description": "Accepts G-Code and sends them to a printer. Plugin can also update firmware.", "i18n-catalog": "cura" diff --git a/resources/bundled_packages/cura.json b/resources/bundled_packages/cura.json index ee82b17a75..d8a7df2478 100644 --- a/resources/bundled_packages/cura.json +++ b/resources/bundled_packages/cura.json @@ -515,7 +515,7 @@ "package_type": "plugin", "display_name": "USB Printing", "description": "Accepts G-Code and sends them to a printer. Plugin can also update firmware.", - "package_version": "1.0.0", + "package_version": "1.0.1", "sdk_version": 5, "website": "https://ultimaker.com", "author": { From 4d87c464237c4c92c2aa5dfd0c4909a94f49bf92 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 4 Dec 2018 15:04:51 +0100 Subject: [PATCH 0660/1292] Remove sourceSize.width: width from all RecolorImages It is now the default in Uranium. Contributes to issue CURA-5876. --- plugins/ModelChecker/ModelChecker.qml | 1 - .../PerObjectSettingsPanel.qml | 1 - .../PostProcessingPlugin/PostProcessingPlugin.qml | 4 ---- plugins/PrepareStage/PrepareMenu.qml | 1 - .../resources/qml/ToolboxDownloadsGridTile.qml | 1 - .../resources/qml/ToolboxDownloadsShowcaseTile.qml | 2 -- resources/qml/ActionButton.qml | 4 ---- .../qml/ActionPanel/PrintInformationWidget.qml | 3 --- resources/qml/Dialogs/AboutDialog.qml | 2 -- resources/qml/Dialogs/AddMachineDialog.qml | 3 +-- resources/qml/ExpandableComponent.qml | 2 -- resources/qml/ExtruderIcon.qml | 3 --- resources/qml/IconLabel.qml | 3 --- resources/qml/IconWithText.qml | 2 -- resources/qml/JobSpecs.qml | 1 - resources/qml/MainWindow/MainWindowHeader.qml | 3 --- .../Menus/ConfigurationMenu/ConfigurationItem.qml | 2 -- resources/qml/ObjectsList.qml | 3 +-- .../Preferences/Materials/MaterialsBrandSection.qml | 5 ++--- .../qml/Preferences/Materials/MaterialsSlot.qml | 2 -- .../Preferences/Materials/MaterialsTypeSection.qml | 2 -- resources/qml/PrinterSelector/MachineSelector.qml | 3 --- resources/qml/Settings/SettingCategory.qml | 13 ++++++++----- resources/qml/Settings/SettingCheckBox.qml | 4 ++-- resources/qml/Settings/SettingView.qml | 11 ++++++----- resources/qml/SidebarSimple.qml | 1 - resources/themes/cura-light/styles.qml | 5 ----- 27 files changed, 20 insertions(+), 67 deletions(-) diff --git a/plugins/ModelChecker/ModelChecker.qml b/plugins/ModelChecker/ModelChecker.qml index 5e41591d6b..437df29516 100644 --- a/plugins/ModelChecker/ModelChecker.qml +++ b/plugins/ModelChecker/ModelChecker.qml @@ -33,7 +33,6 @@ Button { width: UM.Theme.getSize("save_button_specs_icons").width; height: UM.Theme.getSize("save_button_specs_icons").height; - sourceSize.width: width; sourceSize.height: width; color: control.hovered ? UM.Theme.getColor("text_scene_hover") : UM.Theme.getColor("text_scene"); source: "model_checker.svg" diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index 5d4e17a102..0e2bd88619 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -265,7 +265,6 @@ Item { anchors.verticalCenter: parent.verticalCenter width: parent.width height: width - sourceSize.width: width sourceSize.height: width color: control.hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button") source: UM.Theme.getIcon("minus") diff --git a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml index bd4d361d35..3fa10c23b9 100644 --- a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml +++ b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml @@ -141,7 +141,6 @@ UM.Dialog anchors.horizontalCenter: parent.horizontalCenter width: Math.round(control.width / 2.7) height: Math.round(control.height / 2.7) - sourceSize.width: width sourceSize.height: width color: palette.text source: UM.Theme.getIcon("cross1") @@ -176,7 +175,6 @@ UM.Dialog anchors.horizontalCenter: parent.horizontalCenter width: Math.round(control.width / 2.5) height: Math.round(control.height / 2.5) - sourceSize.width: width sourceSize.height: width color: control.enabled ? palette.text : disabledPalette.text source: UM.Theme.getIcon("arrow_bottom") @@ -211,7 +209,6 @@ UM.Dialog anchors.horizontalCenter: parent.horizontalCenter width: Math.round(control.width / 2.5) height: Math.round(control.height / 2.5) - sourceSize.width: width sourceSize.height: width color: control.enabled ? palette.text : disabledPalette.text source: UM.Theme.getIcon("arrow_top") @@ -498,7 +495,6 @@ UM.Dialog anchors.horizontalCenter: parent.horizontalCenter width: Math.round(parent.width / 2) height: Math.round(parent.height / 2) - sourceSize.width: width sourceSize.height: height color: !control.enabled ? UM.Theme.getColor("action_button_disabled_text") : control.pressed ? UM.Theme.getColor("action_button_active_text") : diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index abfe3080c2..fa94bc88b2 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -107,7 +107,6 @@ Item height: UM.Theme.getSize("button_icon").height color: UM.Theme.getColor("toolbar_button_text") - sourceSize.width: width sourceSize.height: height } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index be44c0f374..61374f9d99 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -52,7 +52,6 @@ Item bottom: parent.bottom right: parent.right } - sourceSize.width: width sourceSize.height: height visible: installedPackages != 0 color: (installedPackages == packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border") diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml index 4fb70541d2..8a2fdc8bc8 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml @@ -48,8 +48,6 @@ Rectangle right: parent.right bottomMargin: UM.Theme.getSize("default_lining").width } - sourceSize.width: width - sourceSize.height: height visible: installedPackages != 0 color: (installedPackages == packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border") source: "../images/installed_check.svg" diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index 2107264dff..54d77f7d59 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -50,8 +50,6 @@ Button source: "" height: buttonText.height width: visible ? height : 0 - sourceSize.width: width - sourceSize.height: height color: button.hovered ? button.textHoverColor : button.textColor visible: source != "" && !button.isIconOnRightSide anchors.verticalCenter: parent.verticalCenter @@ -78,8 +76,6 @@ Button source: buttonIconLeft.source height: buttonText.height width: visible ? height : 0 - sourceSize.width: width - sourceSize.height: height color: buttonIconLeft.color visible: source != "" && button.isIconOnRightSide anchors.verticalCenter: buttonIconLeft.verticalCenter diff --git a/resources/qml/ActionPanel/PrintInformationWidget.qml b/resources/qml/ActionPanel/PrintInformationWidget.qml index 82707576e0..436649c4e1 100644 --- a/resources/qml/ActionPanel/PrintInformationWidget.qml +++ b/resources/qml/ActionPanel/PrintInformationWidget.qml @@ -18,9 +18,6 @@ UM.RecolorImage width: UM.Theme.getSize("section_icon").width height: UM.Theme.getSize("section_icon").height - sourceSize.width: width - sourceSize.height: height - color: popup.opened ? UM.Theme.getColor("primary") : UM.Theme.getColor("text_medium") MouseArea diff --git a/resources/qml/Dialogs/AboutDialog.qml b/resources/qml/Dialogs/AboutDialog.qml index 25c9bbf74b..94eca4e7c0 100644 --- a/resources/qml/Dialogs/AboutDialog.qml +++ b/resources/qml/Dialogs/AboutDialog.qml @@ -39,8 +39,6 @@ UM.Dialog source: UM.Theme.getImage("logo") - sourceSize.width: width - sourceSize.height: height anchors.top: parent.top anchors.topMargin: ((base.minimumWidth - width) / 2) | 0 anchors.horizontalCenter: parent.horizontalCenter diff --git a/resources/qml/Dialogs/AddMachineDialog.qml b/resources/qml/Dialogs/AddMachineDialog.qml index 918c717b94..f00359869c 100644 --- a/resources/qml/Dialogs/AddMachineDialog.qml +++ b/resources/qml/Dialogs/AddMachineDialog.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.2 @@ -156,7 +156,6 @@ UM.Dialog anchors.rightMargin: UM.Theme.getSize("default_margin").width width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height - sourceSize.width: width sourceSize.height: width color: palette.windowText source: base.activeCategory == section ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_right") diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index b438f0398c..9bedaa940c 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -139,8 +139,6 @@ Item verticalCenter: parent.verticalCenter margins: background.padding } - sourceSize.width: width - sourceSize.height: height visible: source != "" width: height height: Math.round(0.2 * base.height) diff --git a/resources/qml/ExtruderIcon.qml b/resources/qml/ExtruderIcon.qml index 742c2a9dfe..49ad73a32e 100644 --- a/resources/qml/ExtruderIcon.qml +++ b/resources/qml/ExtruderIcon.qml @@ -22,8 +22,6 @@ Item id: mainIcon anchors.fill: parent - sourceSize.width: parent.width - sourceSize.height: parent.height source: UM.Theme.getIcon("extruder_button") color: extruderEnabled ? materialColor: "gray" } @@ -64,7 +62,6 @@ Item id: disabledIcon anchors.fill: parent anchors.margins: UM.Theme.getSize("thick_lining").width - sourceSize.width: width sourceSize.height: width source: UM.Theme.getIcon("cross1") visible: !extruderEnabled diff --git a/resources/qml/IconLabel.qml b/resources/qml/IconLabel.qml index 386ed0ae01..f925b6eab5 100644 --- a/resources/qml/IconLabel.qml +++ b/resources/qml/IconLabel.qml @@ -31,9 +31,6 @@ Item width: UM.Theme.getSize("section_icon").width height: width - sourceSize.width: width - sourceSize.height: height - color: label.color visible: source != "" } diff --git a/resources/qml/IconWithText.qml b/resources/qml/IconWithText.qml index dcb3ef7851..22599b3aed 100644 --- a/resources/qml/IconWithText.qml +++ b/resources/qml/IconWithText.qml @@ -37,8 +37,6 @@ Item width: UM.Theme.getSize("section_icon").width height: UM.Theme.getSize("section_icon").height - sourceSize.width: width - sourceSize.height: height color: "black" anchors diff --git a/resources/qml/JobSpecs.qml b/resources/qml/JobSpecs.qml index 717d6e925b..935cb723de 100644 --- a/resources/qml/JobSpecs.qml +++ b/resources/qml/JobSpecs.qml @@ -60,7 +60,6 @@ Item { { width: UM.Theme.getSize("save_button_specs_icons").width; height: UM.Theme.getSize("save_button_specs_icons").height; - sourceSize.width: width; sourceSize.height: width; color: control.hovered ? UM.Theme.getColor("text_scene_hover") : UM.Theme.getColor("text_scene"); source: UM.Theme.getIcon("pencil"); diff --git a/resources/qml/MainWindow/MainWindowHeader.qml b/resources/qml/MainWindow/MainWindowHeader.qml index 34936e9b5a..fa0594e2ae 100644 --- a/resources/qml/MainWindow/MainWindowHeader.qml +++ b/resources/qml/MainWindow/MainWindowHeader.qml @@ -54,9 +54,6 @@ Rectangle source: UM.Theme.getImage("logo") width: UM.Theme.getSize("logo").width height: UM.Theme.getSize("logo").height - - sourceSize.width: width - sourceSize.height: height } Row diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 7ba7202819..4a17e8eed8 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -95,8 +95,6 @@ Button anchors.left: parent.left width: UM.Theme.getSize("main_window_header_button_icon").width height: UM.Theme.getSize("main_window_header_button_icon").height - sourceSize.width: width - sourceSize.height: height source: UM.Theme.getIcon("buildplate") color: UM.Theme.getColor("text") } diff --git a/resources/qml/ObjectsList.qml b/resources/qml/ObjectsList.qml index 8c8eaa16ae..8f45b3744f 100644 --- a/resources/qml/ObjectsList.qml +++ b/resources/qml/ObjectsList.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.2 @@ -55,7 +55,6 @@ Rectangle { width: control.width height: control.height - sourceSize.width: width sourceSize.height: width color: UM.Theme.getColor("setting_control_text") source: collapsed ? UM.Theme.getIcon("arrow_left") : UM.Theme.getIcon("arrow_bottom") diff --git a/resources/qml/Preferences/Materials/MaterialsBrandSection.qml b/resources/qml/Preferences/Materials/MaterialsBrandSection.qml index c8f391dfb0..a3a0e4708f 100644 --- a/resources/qml/Preferences/Materials/MaterialsBrandSection.qml +++ b/resources/qml/Preferences/Materials/MaterialsBrandSection.qml @@ -55,7 +55,8 @@ Rectangle text: "" implicitWidth: UM.Theme.getSize("favorites_button").width implicitHeight: UM.Theme.getSize("favorites_button").height - UM.RecolorImage { + UM.RecolorImage + { anchors { verticalCenter: parent.verticalCenter @@ -63,8 +64,6 @@ Rectangle } width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height - sourceSize.width: width - sourceSize.height: height color: "black" source: brand_section.expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") } diff --git a/resources/qml/Preferences/Materials/MaterialsSlot.qml b/resources/qml/Preferences/Materials/MaterialsSlot.qml index a5af17f47a..a706aaf2b9 100644 --- a/resources/qml/Preferences/Materials/MaterialsSlot.qml +++ b/resources/qml/Preferences/Materials/MaterialsSlot.qml @@ -95,8 +95,6 @@ Rectangle } width: UM.Theme.getSize("favorites_button_icon").width height: UM.Theme.getSize("favorites_button_icon").height - sourceSize.width: width - sourceSize.height: height color: { if (favorite_button.hovered) diff --git a/resources/qml/Preferences/Materials/MaterialsTypeSection.qml b/resources/qml/Preferences/Materials/MaterialsTypeSection.qml index f62fc4ee16..f98c19e0b3 100644 --- a/resources/qml/Preferences/Materials/MaterialsTypeSection.qml +++ b/resources/qml/Preferences/Materials/MaterialsTypeSection.qml @@ -74,8 +74,6 @@ Rectangle } width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height - sourceSize.width: width - sourceSize.height: height color: "black" source: material_type_section.expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") } diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index 15cd773c90..91b5591cd8 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -59,9 +59,6 @@ Cura.ExpandableComponent width: UM.Theme.getSize("printer_status_icon").width height: UM.Theme.getSize("printer_status_icon").height - sourceSize.width: width - sourceSize.height: height - color: UM.Theme.getColor("primary") visible: isNetworkPrinter && isPrinterConnected diff --git a/resources/qml/Settings/SettingCategory.qml b/resources/qml/Settings/SettingCategory.qml index aafe36c546..196b2d6b97 100644 --- a/resources/qml/Settings/SettingCategory.qml +++ b/resources/qml/Settings/SettingCategory.qml @@ -129,23 +129,26 @@ Button anchors.rightMargin: UM.Theme.getSize("default_margin").width width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height - sourceSize.width: width sourceSize.height: width color: { if (!base.enabled) { return UM.Theme.getColor("setting_category_disabled_text") - } else if ((base.hovered || base.activeFocus) && base.checkable && base.checked) + } + else if ((base.hovered || base.activeFocus) && base.checkable && base.checked) { return UM.Theme.getColor("setting_category_active_hover_text") - } else if (base.pressed || (base.checkable && base.checked)) + } + else if (base.pressed || (base.checkable && base.checked)) { return UM.Theme.getColor("setting_category_active_text") - } else if (base.hovered || base.activeFocus) + } + else if (base.hovered || base.activeFocus) { return UM.Theme.getColor("setting_category_hover_text") - } else + } + else { return UM.Theme.getColor("setting_category_text") } diff --git a/resources/qml/Settings/SettingCheckBox.qml b/resources/qml/Settings/SettingCheckBox.qml index d37754d27c..fb2d5a2f4d 100644 --- a/resources/qml/Settings/SettingCheckBox.qml +++ b/resources/qml/Settings/SettingCheckBox.qml @@ -115,12 +115,12 @@ SettingItem return UM.Theme.getColor("setting_control_border") } - UM.RecolorImage { + UM.RecolorImage + { anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter width: Math.round(parent.width / 2.5) height: Math.round(parent.height / 2.5) - sourceSize.width: width sourceSize.height: width color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text"); source: UM.Theme.getIcon("check") diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index ef1f123953..bb624bcbde 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -1,5 +1,5 @@ -// Copyright (c) 2017 Ultimaker B.V. -// Uranium is released under the terms of the LGPLv3 or higher. +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 import QtQuick.Controls 1.1 @@ -129,13 +129,14 @@ Item } style: ButtonStyle { - background: Item { - UM.RecolorImage { + background: Item + { + UM.RecolorImage + { anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height - sourceSize.width: width sourceSize.height: width color: control.enabled ? UM.Theme.getColor("setting_category_text") : UM.Theme.getColor("setting_category_disabled_text") source: UM.Theme.getIcon("menu") diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index e07810691e..fb4d52979d 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -731,7 +731,6 @@ Item { anchors.fill: parent anchors.margins: 2 * screenScaleFactor - sourceSize.width: width sourceSize.height: width source: UM.Theme.getIcon(model.icon) color: UM.Theme.getColor("quality_slider_unavailable") diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index 90344d4644..aaa8ec18f1 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -73,7 +73,6 @@ QtObject anchors.rightMargin: Theme.getSize("default_margin").width width: Theme.getSize("standard_arrow").width height: Theme.getSize("standard_arrow").height - sourceSize.width: width sourceSize.height: width color: control.enabled ? Theme.getColor("setting_category_text") : Theme.getColor("setting_category_disabled_text") source: Theme.getIcon("arrow_bottom") @@ -257,7 +256,6 @@ QtObject anchors.bottomMargin: Theme.getSize("button").height - Math.round(Theme.getSize("button_icon").height / 4) width: Theme.getSize("standard_arrow").width height: Theme.getSize("standard_arrow").height - sourceSize.width: width sourceSize.height: width visible: control.menu != null; color: @@ -543,7 +541,6 @@ QtObject anchors.horizontalCenter: parent.horizontalCenter width: Math.round(parent.width / 2.5) height: Math.round(parent.height / 2.5) - sourceSize.width: width sourceSize.height: width color: Theme.getColor("checkbox_mark") source: control.exclusiveGroup ? Theme.getIcon("dot") : Theme.getIcon("check") @@ -585,7 +582,6 @@ QtObject anchors.horizontalCenter: parent.horizontalCenter width: Math.round(parent.width / 2.5) height: Math.round(parent.height / 2.5) - sourceSize.width: width sourceSize.height: width color: Theme.getColor("checkbox_mark") source: @@ -836,7 +832,6 @@ QtObject anchors.horizontalCenter: parent.horizontalCenter width: Math.floor(control.width / 2) height: Math.floor(control.height / 2) - sourceSize.width: width sourceSize.height: width color: { From ebb31409b80fe94db4d5638ef9244bdb6599fe1f Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 4 Dec 2018 15:10:31 +0100 Subject: [PATCH 0661/1292] Always return a string for preview icon Contributes to CL-1153 --- .../UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml index b6b666cbf3..2043837ff6 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml @@ -69,7 +69,7 @@ Item { return "../svg/aborted-icon.svg" } - break; + return ""; case "pausing": return "../svg/paused-icon.svg" case "paused": From 1494daf6712cc9d028799d3fa115ec9e8f4f4b8c Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 4 Dec 2018 15:11:31 +0100 Subject: [PATCH 0662/1292] Simplify preview icon logic Contributes to CL-1153 --- .../resources/qml/MonitorPrintJobPreview.qml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml index 2043837ff6..84d325aa32 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml @@ -65,11 +65,7 @@ Item case "error": return "../svg/aborted-icon.svg" case "wait_cleanup": - if (printJob.state == "wait_cleanup" && printJob.timeTotal > printJob.timeElapsed) - { - return "../svg/aborted-icon.svg" - } - return ""; + return printJob.timeTotal > printJob.timeElapsed ? "../svg/aborted-icon.svg" : ""; case "pausing": return "../svg/paused-icon.svg" case "paused": From 014a138fda4fbd4776c0751b21ce2549cf5da1c8 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 4 Dec 2018 15:12:00 +0100 Subject: [PATCH 0663/1292] Remove semi-colon Contributes to CL-1153 --- .../UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml index 84d325aa32..ec26bbe568 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml @@ -65,7 +65,7 @@ Item case "error": return "../svg/aborted-icon.svg" case "wait_cleanup": - return printJob.timeTotal > printJob.timeElapsed ? "../svg/aborted-icon.svg" : ""; + return printJob.timeTotal > printJob.timeElapsed ? "../svg/aborted-icon.svg" : "" case "pausing": return "../svg/paused-icon.svg" case "paused": From a9273ec2b5563f57781eab7d096f7a8793b1a4d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Tue, 4 Dec 2018 15:20:24 +0100 Subject: [PATCH 0664/1292] Use QTimer instead of threading.Timer --- .../src/Cloud/CloudOutputDeviceManager.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 6f3f1fb9d7..f5f3555145 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -1,9 +1,9 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import json -from threading import Timer from typing import Dict, Optional +from PyQt5.QtCore import QTimer from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply from UM.Logger import Logger @@ -45,6 +45,11 @@ class CloudOutputDeviceManager(NetworkClient): self._on_cluster_received = Signal() self._on_cluster_received.connect(self._getRemoteClusters) + self.update_timer = QTimer(CuraApplication.getInstance()) + self.update_timer.setInterval(self.CHECK_CLUSTER_INTERVAL * 1000) + self.update_timer.setSingleShot(False) + self.update_timer.timeout.connect(self._on_cluster_received.emit) + ## Override _createEmptyRequest to add the needed authentication header for talking to the Ultimaker Cloud API. def _createEmptyRequest(self, path: str, content_type: Optional[str] = "application/json") -> QNetworkRequest: @@ -61,10 +66,9 @@ class CloudOutputDeviceManager(NetworkClient): if self._account.isLoggedIn: self.get("/clusters", on_finished = self._onGetRemoteClustersFinished) - # Only start the polling thread after the user is authenticated + # Only start the polling timer after the user is authenticated # The first call to _getRemoteClusters comes from self._account.loginStateChanged - timer = Timer(5.0, self._on_cluster_received.emit) - timer.start() + self.update_timer.start() ## Callback for when the request for getting the clusters. is finished. From b2238420fb2ee25d979bba5ef7015462298d340b Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 4 Dec 2018 15:46:13 +0100 Subject: [PATCH 0665/1292] Ensure that reset always correctly gets set to basic The old code that simply resetted the preferences was still active, but this could cause a race condition in some situations. In those cases it would first set it to basic and then clear the preferences (thus resulting in no settings being visible) CURA-5981 --- resources/qml/Preferences/SettingVisibilityPage.qml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/resources/qml/Preferences/SettingVisibilityPage.qml b/resources/qml/Preferences/SettingVisibilityPage.qml index 1b964cad0c..2edbeee960 100644 --- a/resources/qml/Preferences/SettingVisibilityPage.qml +++ b/resources/qml/Preferences/SettingVisibilityPage.qml @@ -25,11 +25,7 @@ UM.PreferencesPage function reset() { - UM.Preferences.resetPreference("general/visible_settings") - - // After calling this function update Setting visibility preset combobox. - // Reset should set default setting preset ("Basic") - visibilityPreset.currentIndex = 1 + settingVisibilityPresetsModel.setActivePreset("basic") } resetEnabled: true; From 9046b39b436ffaf067de668eabb3bbdf0bf56e29 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Tue, 4 Dec 2018 16:14:08 +0100 Subject: [PATCH 0666/1292] STAR-322: Creating a Cloud API client to handle the interaction --- cura/API/Account.py | 5 + cura/NetworkClient.py | 87 ++++++---- .../NetworkedPrinterOutputDevice.py | 111 ++++++++----- .../src/Cloud/CloudApiClient.py | 155 ++++++++++++++++++ .../src/Cloud/CloudOutputDevice.py | 138 ++++------------ .../src/Cloud/CloudOutputDeviceManager.py | 78 ++++----- .../UM3NetworkPrinting/src/Cloud/Models.py | 28 +++- 7 files changed, 367 insertions(+), 235 deletions(-) create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py diff --git a/cura/API/Account.py b/cura/API/Account.py index d78c7e8826..70881000a3 100644 --- a/cura/API/Account.py +++ b/cura/API/Account.py @@ -61,6 +61,11 @@ class Account(QObject): self._authorization_service.onAuthenticationError.connect(self._onLoginStateChanged) self._authorization_service.loadAuthDataFromPreferences() + ## Returns a boolean indicating whether the given authentication is applied against staging or not. + @property + def is_staging(self) -> bool: + return "staging" in self._oauth_root + @pyqtProperty(bool, notify=loginStateChanged) def isLoggedIn(self) -> bool: return self._logged_in diff --git a/cura/NetworkClient.py b/cura/NetworkClient.py index fbe0c63c36..8a321b6af4 100644 --- a/cura/NetworkClient.py +++ b/cura/NetworkClient.py @@ -1,7 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. from time import time -from typing import Optional, Dict, Callable, List +from typing import Optional, Dict, Callable, List, Union from PyQt5.QtCore import QUrl from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkReply, QHttpMultiPart, QNetworkRequest, QHttpPart, \ @@ -49,6 +49,8 @@ class NetworkClient: ## Create a new empty network request. # Automatically adds the required HTTP headers. + # \param url: The URL to request + # \param content_type: The type of the body contents. def _createEmptyRequest(self, url: str, content_type: Optional[str] = "application/json") -> QNetworkRequest: request = QNetworkRequest(QUrl(url)) if content_type: @@ -120,67 +122,82 @@ class NetworkClient: def createFormPart(self, content_header: str, data: bytes, content_type: Optional[str] = None) -> QHttpPart: return self._createFormPart(content_header, data, content_type) - ## Does a PUT request to the given URL. - def put(self, url: str, data: str, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: + ## Sends a put request to the given path. + # url: The path after the API prefix. + # data: The data to be sent in the body + # content_type: The content type of the body data. + # on_finished: The function to call when the response is received. + # on_progress: The function to call when the progress changes. Parameters are bytes_sent / bytes_total. + def put(self, url: str, data: Union[str, bytes], content_type: Optional[str] = None, + on_finished: Optional[Callable[[QNetworkReply], None]] = None, + on_progress: Optional[Callable[[int, int], None]] = None) -> None: self._validateManager() - - request = self._createEmptyRequest(url) - self._last_request_time = time() - - if not self._manager: - Logger.log("e", "No network manager was created to execute the PUT call with.") - return - reply = self._manager.put(request, data.encode()) + request = self._createEmptyRequest(url, content_type = content_type) + self._last_request_time = time() + + if not self._manager: + return Logger.log("e", "No network manager was created to execute the PUT call with.") + + body = data if isinstance(data, bytes) else data.encode() # type: bytes + reply = self._manager.put(request, body) self._registerOnFinishedCallback(reply, on_finished) - ## Does a DELETE request to the given URL. + if on_progress is not None: + reply.uploadProgress.connect(on_progress) + + ## Sends a delete request to the given path. + # url: The path after the API prefix. + # on_finished: The function to be call when the response is received. def delete(self, url: str, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: self._validateManager() - + request = self._createEmptyRequest(url) self._last_request_time = time() - + if not self._manager: - Logger.log("e", "No network manager was created to execute the DELETE call with.") - return - + return Logger.log("e", "No network manager was created to execute the DELETE call with.") + reply = self._manager.deleteResource(request) self._registerOnFinishedCallback(reply, on_finished) - ## Does a GET request to the given URL. + ## Sends a get request to the given path. + # \param url: The path after the API prefix. + # \param on_finished: The function to be call when the response is received. def get(self, url: str, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: self._validateManager() - + request = self._createEmptyRequest(url) self._last_request_time = time() - + if not self._manager: - Logger.log("e", "No network manager was created to execute the GET call with.") - return - + return Logger.log("e", "No network manager was created to execute the GET call with.") + reply = self._manager.get(request) self._registerOnFinishedCallback(reply, on_finished) - ## Does a POST request to the given URL. - def post(self, url: str, data: str, on_finished: Optional[Callable[[QNetworkReply], None]], - on_progress: Callable = None) -> None: + ## Sends a post request to the given path. + # \param url: The path after the API prefix. + # \param data: The data to be sent in the body + # \param on_finished: The function to call when the response is received. + # \param on_progress: The function to call when the progress changes. Parameters are bytes_sent / bytes_total. + def post(self, url: str, data: Union[str, bytes], + on_finished: Optional[Callable[[QNetworkReply], None]], + on_progress: Optional[Callable[[int, int], None]] = None) -> None: self._validateManager() - + request = self._createEmptyRequest(url) self._last_request_time = time() - + if not self._manager: - Logger.log("e", "No network manager was created to execute the GET call with.") - return - - reply = self._manager.post(request, data.encode()) - + return Logger.log("e", "Could not find manager.") + + body = data if isinstance(data, bytes) else data.encode() # type: bytes + reply = self._manager.post(request, body) if on_progress is not None: reply.uploadProgress.connect(on_progress) - self._registerOnFinishedCallback(reply, on_finished) - + ## Does a POST request with form data to the given URL. def postForm(self, url: str, header_data: str, body_data: bytes, on_finished: Optional[Callable[[QNetworkReply], None]], diff --git a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py index 72b6319020..300ed5194d 100644 --- a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py +++ b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py @@ -145,7 +145,7 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): url = QUrl("http://" + self._address + self._api_prefix + target) request = QNetworkRequest(url) if content_type is not None: - request.setHeader(QNetworkRequest.ContentTypeHeader, "application/json") + request.setHeader(QNetworkRequest.ContentTypeHeader, content_type) request.setHeader(QNetworkRequest.UserAgentHeader, self._user_agent) return request @@ -180,54 +180,85 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): self._createNetworkManager() assert (self._manager is not None) - def put(self, target: str, data: Union[str, bytes], content_type: str = None, + ## Sends a put request to the given path. + # url: The path after the API prefix. + # data: The data to be sent in the body + # content_type: The content type of the body data. + # on_finished: The function to call when the response is received. + # on_progress: The function to call when the progress changes. Parameters are bytes_sent / bytes_total. + def put(self, url: str, data: Union[str, bytes], content_type: Optional[str] = None, on_finished: Optional[Callable[[QNetworkReply], None]] = None, - on_progress: Optional[Callable] = None) -> None: + on_progress: Optional[Callable[[int, int], None]] = None) -> None: self._validateManager() - request = self._createEmptyRequest(target, content_type = content_type) - self._last_request_time = time() - if self._manager is not None: - reply = self._manager.put(request, data if isinstance(data, bytes) else data.encode()) - self._registerOnFinishedCallback(reply, on_finished) - if on_progress is not None: - reply.uploadProgress.connect(on_progress) - else: - Logger.log("e", "Could not find manager.") - def delete(self, target: str, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: + request = self._createEmptyRequest(url, content_type = content_type) + self._last_request_time = time() + + if not self._manager: + return Logger.log("e", "No network manager was created to execute the PUT call with.") + + body = data if isinstance(data, bytes) else data.encode() # type: bytes + reply = self._manager.put(request, body) + self._registerOnFinishedCallback(reply, on_finished) + + if on_progress is not None: + reply.uploadProgress.connect(on_progress) + + ## Sends a delete request to the given path. + # url: The path after the API prefix. + # on_finished: The function to be call when the response is received. + def delete(self, url: str, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: self._validateManager() - request = self._createEmptyRequest(target) - self._last_request_time = time() - if self._manager is not None: - reply = self._manager.deleteResource(request) - self._registerOnFinishedCallback(reply, on_finished) - else: - Logger.log("e", "Could not find manager.") - def get(self, target: str, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: + request = self._createEmptyRequest(url) + self._last_request_time = time() + + if not self._manager: + return Logger.log("e", "No network manager was created to execute the DELETE call with.") + + reply = self._manager.deleteResource(request) + self._registerOnFinishedCallback(reply, on_finished) + + ## Sends a get request to the given path. + # \param url: The path after the API prefix. + # \param on_finished: The function to be call when the response is received. + def get(self, url: str, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: self._validateManager() - request = self._createEmptyRequest(target) - self._last_request_time = time() - if self._manager is not None: - reply = self._manager.get(request) - self._registerOnFinishedCallback(reply, on_finished) - else: - Logger.log("e", "Could not find manager.") - def post(self, target: str, data: Union[str, bytes], on_finished: Optional[Callable[[QNetworkReply], None]], - on_progress: Callable = None) -> None: + request = self._createEmptyRequest(url) + self._last_request_time = time() + + if not self._manager: + return Logger.log("e", "No network manager was created to execute the GET call with.") + + reply = self._manager.get(request) + self._registerOnFinishedCallback(reply, on_finished) + + ## Sends a post request to the given path. + # \param url: The path after the API prefix. + # \param data: The data to be sent in the body + # \param on_finished: The function to call when the response is received. + # \param on_progress: The function to call when the progress changes. Parameters are bytes_sent / bytes_total. + def post(self, url: str, data: Union[str, bytes], + on_finished: Optional[Callable[[QNetworkReply], None]], + on_progress: Optional[Callable[[int, int], None]] = None) -> None: self._validateManager() - request = self._createEmptyRequest(target) - self._last_request_time = time() - if self._manager is not None: - reply = self._manager.post(request, data if isinstance(data, bytes) else data.encode()) - if on_progress is not None: - reply.uploadProgress.connect(on_progress) - self._registerOnFinishedCallback(reply, on_finished) - else: - Logger.log("e", "Could not find manager.") - def postFormWithParts(self, target: str, parts: List[QHttpPart], on_finished: Optional[Callable[[QNetworkReply], None]], on_progress: Callable = None) -> QNetworkReply: + request = self._createEmptyRequest(url) + self._last_request_time = time() + + if not self._manager: + return Logger.log("e", "Could not find manager.") + + body = data if isinstance(data, bytes) else data.encode() # type: bytes + reply = self._manager.post(request, body) + if on_progress is not None: + reply.uploadProgress.connect(on_progress) + self._registerOnFinishedCallback(reply, on_finished) + + def postFormWithParts(self, target: str, parts: List[QHttpPart], + on_finished: Optional[Callable[[QNetworkReply], None]], + on_progress: Callable = None) -> QNetworkReply: self._validateManager() request = self._createEmptyRequest(target, content_type=None) multi_post_part = QHttpMultiPart(QHttpMultiPart.FormDataType) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py new file mode 100644 index 0000000000..1d2de1d9bf --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py @@ -0,0 +1,155 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +import json +from json import JSONDecodeError +from typing import Callable, List, Type, TypeVar, Union, Optional, Tuple, Dict + +from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply + +from UM.Logger import Logger +from cura.API import Account +from cura.NetworkClient import NetworkClient +from plugins.UM3NetworkPrinting.src.Models import BaseModel +from plugins.UM3NetworkPrinting.src.Cloud.Models import ( + CloudCluster, CloudErrorObject, CloudClusterStatus, CloudJobUploadRequest, + CloudJobResponse, + CloudPrintResponse +) + + +## The cloud API client is responsible for handling the requests and responses from the cloud. +# Each method should only handle models instead of exposing any HTTP details. +class CloudApiClient(NetworkClient): + + # The cloud URL to use for this remote cluster. + # TODO: Make sure that this URL goes to the live api before release + ROOT_PATH = "https://api-staging.ultimaker.com" + CLUSTER_API_ROOT = "{}/connect/v1/".format(ROOT_PATH) + CURA_API_ROOT = "{}/cura/v1/".format(ROOT_PATH) + + ## Initializes a new cloud API client. + # \param account: The user's account object + # \param on_error: The callback to be called whenever we receive errors from the server. + def __init__(self, account: Account, on_error: Callable[[List[CloudErrorObject]], None]): + super().__init__() + self._account = account + self._on_error = on_error + + ## Retrieves all the clusters for the user that is currently logged in. + # \param on_finished: The function to be called after the result is parsed. + def getClusters(self, on_finished: Callable[[List[CloudCluster]], any]) -> None: + url = "/clusters" + self.get(url, on_finished=self._createCallback(on_finished, CloudCluster)) + + ## Retrieves the status of the given cluster. + # \param cluster_id: The ID of the cluster. + # \param on_finished: The function to be called after the result is parsed. + def getClusterStatus(self, cluster_id: str, on_finished: Callable[[CloudClusterStatus], any]) -> None: + url = "{}/cluster/{}/status".format(self.CLUSTER_API_ROOT, cluster_id) + self.get(url, on_finished=self._createCallback(on_finished, CloudClusterStatus)) + + ## Requests the cloud to register the upload of a print job mesh. + # \param request: The request object. + # \param on_finished: The function to be called after the result is parsed. + def requestUpload(self, request: CloudJobUploadRequest, on_finished: Callable[[CloudJobResponse], any]) -> None: + url = "{}/jobs/upload".format(self.CURA_API_ROOT) + body = json.dumps({"data": request.__dict__}) + self.put(url, body, on_finished=self._createCallback(on_finished, CloudJobResponse)) + + ## Requests the cloud to register the upload of a print job mesh. + # \param upload_response: The object received after requesting an upload with `self.requestUpload`. + # \param on_finished: The function to be called after the result is parsed. It receives the print job ID. + def uploadMesh(self, upload_response: CloudJobResponse, mesh: bytes, on_finished: Callable[[str], any], + on_progress: Callable[[int], any]): + + def progressCallback(bytes_sent: int, bytes_total: int) -> None: + if bytes_total: + on_progress(int((bytes_sent / bytes_total) * 100)) + + def finishedCallback(reply: QNetworkReply): + status_code, response = self._parseReply(reply) + if status_code < 300: + on_finished(upload_response.job_id) + else: + self._uploadMeshError(status_code, response) + + # TODO: Multipart upload + self.put(upload_response.upload_url, data = mesh, content_type = upload_response.content_type, + on_finished = finishedCallback, on_progress = progressCallback) + + # Requests a cluster to print the given print job. + # \param cluster_id: The ID of the cluster. + # \param job_id: The ID of the print job. + # \param on_finished: The function to be called after the result is parsed. + def requestPrint(self, cluster_id: str, job_id: str, on_finished: Callable[[], any]) -> None: + url = "{}/cluster/{}/print/{}".format(self.CLUSTER_API_ROOT, cluster_id, job_id) + self.post(url, data = "", on_finished=self._createCallback(on_finished, CloudPrintResponse)) + + ## We override _createEmptyRequest in order to add the user credentials. + # \param url: The URL to request + # \param content_type: The type of the body contents. + def _createEmptyRequest(self, path: str, content_type: Optional[str] = "application/json") -> QNetworkRequest: + request = super()._createEmptyRequest(path, content_type) + if self._account.isLoggedIn: + request.setRawHeader(b"Authorization", "Bearer {}".format(self._account.accessToken).encode()) + return request + + ## Parses the given JSON network reply into a status code and a dictionary, handling unexpected errors as well. + # \param reply: The reply from the server. + # \return A tuple with a status code and a dictionary. + @staticmethod + def _parseReply(reply: QNetworkReply) -> Tuple[int, Dict[str, any]]: + status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) + try: + response = bytes(reply.readAll()).decode() + Logger.log("i", "Received an HTTP %s from %s with %s", status_code, reply.url, response) + return status_code, json.loads(response) + except (UnicodeDecodeError, JSONDecodeError, ValueError) as err: + error = {"code": type(err).__name__, "title": str(err), "http_code": str(status_code)} + Logger.logException("e", "Could not parse the stardust response: %s", error) + return status_code, {"errors": [error]} + + ## Calls the error handler that is responsible for handling errors uploading meshes. + # \param http_status - The status of the HTTP request. + # \param response - The response received from the upload endpoint. This is not formatted according to the standard + # JSON-api response. + def _uploadMeshError(self, http_status: int, response: Dict[str, any]) -> None: + error = CloudErrorObject( + code = "uploadError", + http_status = str(http_status), + title = "Could not upload the mesh", + meta = response + ) + self._on_error([error]) + + ## The generic type variable used to document the methods below. + Model = TypeVar("Model", bound=BaseModel) + + ## Parses the given models and calls the correct callback depending on the result. + # \param response: The response from the server, after being converted to a dict. + # \param on_finished: The callback in case the response is successful. + # \param model: The type of the model to convert the response to. It may either be a single record or a list. + def _parseModels(self, response: Dict[str, any], + on_finished: Callable[[Union[Model, List[Model]]], any], + model: Type[Model]) -> None: + if "data" in response: + data = response["data"] + result = [model(**c) for c in data] if isinstance(data, list) else model(**data) + on_finished(result) + elif "error" in response: + self._on_error([CloudErrorObject(**error) for error in response["errors"]]) + else: + Logger.log("e", "Cannot find data or errors in the cloud response: %s", response) + + ## Creates a callback function that includes the parsing of the response into the correct model. + # \param on_finished: The callback in case the response is successful. + # \param model: The type of the model to convert the response to. It may either be a single record or a list. + # \return: A function that can be passed to the + def _createCallback(self, + on_finished: Callable[[Union[Model, List[Model]]], any], + model: Type[Model], + ) -> Callable[[QNetworkReply], None]: + def parse(reply: QNetworkReply) -> None: + status_code, response = self._parseReply(reply) + return self._parseModels(response, on_finished, model) + return parse diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index d17728f513..adc670ad1e 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -1,13 +1,10 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import io -import json import os -from json import JSONDecodeError -from typing import List, Optional, Dict, cast, Union, Tuple +from typing import List, Optional, Dict, cast, Union from PyQt5.QtCore import QObject, pyqtSignal, QUrl, pyqtProperty, pyqtSlot -from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest from UM import i18nCatalog from UM.FileHandler.FileWriter import FileWriter @@ -22,10 +19,11 @@ from cura.PrinterOutput.PrinterOutputController import PrinterOutputController from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice, AuthState from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel +from plugins.UM3NetworkPrinting.src.Cloud.CloudApiClient import CloudApiClient from plugins.UM3NetworkPrinting.src.UM3PrintJobOutputModel import UM3PrintJobOutputModel from .Models import ( - CloudClusterPrinter, CloudClusterPrintJob, JobUploadRequest, JobUploadResponse, PrintResponse, CloudClusterStatus, - CloudClusterPrinterConfigurationMaterial + CloudClusterPrinter, CloudClusterPrintJob, CloudJobUploadRequest, CloudJobResponse, CloudClusterStatus, + CloudClusterPrinterConfigurationMaterial, CloudErrorObject ) @@ -40,20 +38,16 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # The translation catalog for this device. I18N_CATALOG = i18nCatalog("cura") - # The cloud URL to use for this remote cluster. - # TODO: Make sure that this URL goes to the live api before release - ROOT_PATH = "https://api-staging.ultimaker.com" - CLUSTER_API_ROOT = "{}/connect/v1/".format(ROOT_PATH) - CURA_API_ROOT = "{}/cura/v1/".format(ROOT_PATH) - # Signal triggered when the printers in the remote cluster were changed. printersChanged = pyqtSignal() # Signal triggered when the print jobs in the queue were changed. printJobsChanged = pyqtSignal() - def __init__(self, device_id: str, parent: QObject = None): + def __init__(self, api_client: CloudApiClient, device_id: str, parent: QObject = None): super().__init__(device_id = device_id, address = "", properties = {}, parent = parent) + self._api = api_client + self._setInterfaceElements() self._device_id = device_id @@ -76,40 +70,6 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self._sending_job = False self._progress_message = None # type: Optional[Message] - @staticmethod - def _parseReply(reply: QNetworkReply) -> Tuple[int, Union[None, str, bytes]]: - """ - Parses a reply from the stardust server. - :param reply: The reply received from the server. - :return: The status code and the response dict. - """ - status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) - response = None - try: - response = bytes(reply.readAll()).decode("utf-8") - response = json.loads(response) - except JSONDecodeError: - Logger.logException("w", "Unable to decode JSON from reply.") - return status_code, response - - ## We need to override _createEmptyRequest to work for the cloud. - def _createEmptyRequest(self, path: str, content_type: Optional[str] = "application/json") -> QNetworkRequest: - # noinspection PyArgumentList - url = QUrl(path) - request = QNetworkRequest(url) - request.setHeader(QNetworkRequest.ContentTypeHeader, content_type) - request.setHeader(QNetworkRequest.UserAgentHeader, self._user_agent) - - if not self._account.isLoggedIn: - # TODO: show message to user to sign in - self.setAuthenticationState(AuthState.NotAuthenticated) - else: - # TODO: not execute call at all when not signed in? - self.setAuthenticationState(AuthState.Authenticated) - request.setRawHeader(b"Authorization", "Bearer {}".format(self._account.accessToken).encode()) - - return request - ## Set all the interface elements and texts for this output device. def _setInterfaceElements(self): self.setPriority(2) # make sure we end up below the local networking and above 'save to file' @@ -223,22 +183,16 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def _update(self) -> None: super()._update() Logger.log("i", "Calling the cloud cluster") - self.get("{root}/cluster/{cluster_id}/status".format(root = self.CLUSTER_API_ROOT, - cluster_id = self._device_id), - on_finished = self._onStatusCallFinished) + if self._account.isLoggedIn: + self.setAuthenticationState(AuthState.Authenticated) + self._api.getClusterStatus(self._device_id, self._onStatusCallFinished) + else: + self.setAuthenticationState(AuthState.NotAuthenticated) ## Method called when HTTP request to status endpoint is finished. # Contains both printers and print jobs statuses in a single response. - def _onStatusCallFinished(self, reply: QNetworkReply) -> None: - status_code, response = self._parseReply(reply) - if status_code > 204 or not isinstance(response, dict) or "data" not in response: - Logger.log("w", "Got unexpected response while trying to get cloud cluster data: %s, %s", - status_code, response) - return - - Logger.log("d", "Got response form the cloud cluster %s, %s", status_code, response) - status = CloudClusterStatus(**response["data"]) - + def _onStatusCallFinished(self, status: CloudClusterStatus) -> None: + Logger.log("d", "Got response form the cloud cluster: %s", status.__dict__) # Update all data from the cluster. self._updatePrinters(status.printers) self._updatePrintJobs(status.print_jobs) @@ -325,18 +279,14 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): remote_jobs = {j.uuid: j for j in jobs} # type: Dict[str, CloudClusterPrintJob] current_jobs = {j.key: j for j in self._print_jobs} # type: Dict[str, UM3PrintJobOutputModel] - removed_job_ids = set(current_jobs).difference(set(remote_jobs)) - new_job_ids = set(remote_jobs.keys()).difference(set(current_jobs)) - updated_job_ids = set(current_jobs).intersection(set(remote_jobs)) + for removed_job_id in set(current_jobs).difference(remote_jobs): + self._print_jobs.remove(current_jobs[removed_job_id]) - for job_id in removed_job_ids: - self._print_jobs.remove(current_jobs[job_id]) + for new_job_id in set(remote_jobs.keys()).difference(current_jobs): + self._addPrintJob(remote_jobs[new_job_id]) - for job_id in new_job_ids: - self._addPrintJob(remote_jobs[job_id]) - - for job_id in updated_job_ids: - self._updateUM3PrintJobOutputModel(current_jobs[job_id], remote_jobs[job_id]) + for updated_job_id in set(current_jobs).intersection(remote_jobs): + self._updateUM3PrintJobOutputModel(current_jobs[updated_job_id], remote_jobs[updated_job_id]) # TODO: properly handle removed and updated printers self.printJobsChanged.emit() @@ -362,56 +312,25 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def _sendPrintJob(self, file_name: str, content_type: str, stream: Union[io.StringIO, io.BytesIO]) -> None: mesh = stream.getvalue() - request = JobUploadRequest() + request = CloudJobUploadRequest() request.job_name = file_name request.file_size = len(mesh) request.content_type = content_type Logger.log("i", "Creating new cloud print job: %s", request.__dict__) - self.put("{}/jobs/upload".format(self.CURA_API_ROOT), data = json.dumps({"data": request.__dict__}), - on_finished = lambda reply: self._onPrintJobCreated(mesh, reply)) + self._api.requestUpload(request, lambda response: self._onPrintJobCreated(mesh, response)) - def _onPrintJobCreated(self, mesh: bytes, reply: QNetworkReply) -> None: - status_code, response = self._parseReply(reply) - if status_code > 204 or not isinstance(response, dict) or "data" not in response: - Logger.log("w", "Unexpected response while adding to queue: {}, {}".format(status_code, response)) - self._onUploadError(self.I18N_CATALOG.i18nc("@info:status", "Could not add print job to queue.")) - return - - # TODO: Multipart upload - job_response = JobUploadResponse(**response.get("data")) + def _onPrintJobCreated(self, mesh: bytes, job_response: CloudJobResponse) -> None: Logger.log("i", "Print job created successfully: %s", job_response.__dict__) - self.put(job_response.upload_url, data = mesh, content_type = job_response.content_type, - on_finished = lambda r: self._onPrintJobUploaded(job_response.job_id, r), - on_progress = self._onUploadPrintJobProgress) + self._api.uploadMesh(job_response, mesh, self._onPrintJobUploaded, self._onUploadPrintJobProgress) + + def _onPrintJobUploaded(self, job_id: str) -> None: + self._api.requestPrint(self._device_id, job_id, self._onUploadSuccess) def _onUploadPrintJobProgress(self, bytes_sent: int, bytes_total: int) -> None: if bytes_total > 0: self._updateUploadProgress(int((bytes_sent / bytes_total) * 100)) - def _onPrintJobUploaded(self, job_id: str, reply: QNetworkReply) -> None: - status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) - if status_code > 204: - Logger.log("w", "Received unexpected response from the job upload: %s, %s.", status_code, - bytes(reply.readAll()).decode()) - self._onUploadError(self.I18N_CATALOG.i18nc("@info:status", "Could not add print job to queue.")) - return - - Logger.log("i", "Print job uploaded successfully: %s", reply.readAll()) - url = "{}/cluster/{}/print/{}".format(self.CLUSTER_API_ROOT, self._device_id, job_id) - self.post(url, data = "", on_finished = self._onPrintJobRequested) - - def _onPrintJobRequested(self, reply: QNetworkReply) -> None: - status_code, response = self._parseReply(reply) - if status_code > 204 or not isinstance(response, dict) or "data" not in response: - Logger.log("w", "Got unexpected response while trying to request printing: %s, %s", status_code, response) - self._onUploadError(self.I18N_CATALOG.i18nc("@info:status", "Could not add print job to queue.")) - return - - print_response = PrintResponse(**response["data"]) - Logger.log("i", "Print job requested successfully: %s", print_response.__dict__) - self._onUploadSuccess() - def _updateUploadProgress(self, progress: int): if not self._progress_message: self._progress_message = Message( @@ -479,3 +398,6 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): @pyqtProperty(bool, notify = printJobsChanged) def receivedPrintJobs(self) -> bool: return True + + def _onApiError(self, errors: List[CloudErrorObject]) -> None: + pass # TODO: Show errors... diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 85e734f7a3..22e2d57b05 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -1,19 +1,17 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -import json -from time import sleep from threading import Timer -from typing import Dict, Optional - -from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply +from typing import Dict, List +from UM import i18nCatalog from UM.Logger import Logger +from UM.Message import Message from UM.Signal import Signal from cura.CuraApplication import CuraApplication -from cura.NetworkClient import NetworkClient +from plugins.UM3NetworkPrinting.src.Cloud.CloudApiClient import CloudApiClient from .CloudOutputDevice import CloudOutputDevice -from .Models import CloudCluster +from .Models import CloudCluster, CloudErrorObject ## The cloud output device manager is responsible for using the Ultimaker Cloud APIs to manage remote clusters. @@ -21,14 +19,14 @@ from .Models import CloudCluster # # API spec is available on https://api.ultimaker.com/docs/connect/spec/. # -class CloudOutputDeviceManager(NetworkClient): - - # The cloud URL to use for remote clusters. - API_ROOT_PATH = "https://api-staging.ultimaker.com/connect/v1" +class CloudOutputDeviceManager: # The interval with which the remote clusters are checked CHECK_CLUSTER_INTERVAL = 5 # seconds - + + # The translation catalog for this device. + I18N_CATALOG = i18nCatalog("cura") + def __init__(self): super().__init__() @@ -37,8 +35,10 @@ class CloudOutputDeviceManager(NetworkClient): application = CuraApplication.getInstance() self._output_device_manager = application.getOutputDeviceManager() + self._account = application.getCuraAPI().account self._account.loginStateChanged.connect(self._getRemoteClusters) + self._api = CloudApiClient(self._account, self._onApiError) # When switching machines we check if we have to activate a remote cluster. application.globalContainerStackChanged.connect(self._connectToActiveMachine) @@ -46,40 +46,21 @@ class CloudOutputDeviceManager(NetworkClient): self._on_cluster_received = Signal() self._on_cluster_received.connect(self._getRemoteClusters) - - ## Override _createEmptyRequest to add the needed authentication header for talking to the Ultimaker Cloud API. - def _createEmptyRequest(self, path: str, content_type: Optional[str] = "application/json") -> QNetworkRequest: - request = super()._createEmptyRequest(self.API_ROOT_PATH + path, content_type = content_type) - if self._account.isLoggedIn: - # TODO: add correct scopes to OAuth2 client to use remote connect API. - # TODO: don't create the client when not signed in? - request.setRawHeader(b"Authorization", "Bearer {}".format(self._account.accessToken).encode()) - return request - ## Gets all remote clusters from the API. def _getRemoteClusters(self) -> None: Logger.log("i", "Retrieving remote clusters") if self._account.isLoggedIn: - self.get("/clusters", on_finished = self._onGetRemoteClustersFinished) + self._api.getClusters(self._onGetRemoteClustersFinished) # Only start the polling thread after the user is authenticated # The first call to _getRemoteClusters comes from self._account.loginStateChanged timer = Timer(5.0, self._on_cluster_received.emit) timer.start() - ## Callback for when the request for getting the clusters. is finished. - def _onGetRemoteClustersFinished(self, reply: QNetworkReply) -> None: - Logger.log("i", "Received remote clusters") + def _onGetRemoteClustersFinished(self, clusters: List[CloudCluster]) -> None: + found_clusters = {c.cluster_id: c for c in clusters} - status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) - if status_code > 204: - Logger.log("w", "Got unexpected response while trying to get cloud cluster data: {}, {}" - .format(status_code, reply.readAll())) - return - - # Parse the response (returns the "data" field from the body). - found_clusters = self._parseStatusResponse(reply) Logger.log("i", "Parsed remote clusters to %s", found_clusters) if not found_clusters: return @@ -97,28 +78,17 @@ class CloudOutputDeviceManager(NetworkClient): for cluster_id in known_cluster_ids.difference(found_cluster_ids): self._removeCloudOutputDevice(found_clusters[cluster_id]) - @staticmethod - def _parseStatusResponse(reply: QNetworkReply) -> Dict[str, CloudCluster]: - try: - response = bytes(reply.readAll()).decode() - return {c["cluster_id"]: CloudCluster(**c) for c in json.loads(response)["data"]} - except UnicodeDecodeError: - Logger.log("w", "Unable to read server response") - except json.decoder.JSONDecodeError: - Logger.logException("w", "Unable to decode JSON from reply.") - except ValueError: - Logger.logException("w", "Response was missing values.") - return {} - ## Adds a CloudOutputDevice for each entry in the remote cluster list from the API. + # \param cluster: The cluster that was added. def _addCloudOutputDevice(self, cluster: CloudCluster): - device = CloudOutputDevice(cluster.cluster_id) + device = CloudOutputDevice(self._api, cluster.cluster_id) self._output_device_manager.addOutputDevice(device) self._remote_clusters[cluster.cluster_id] = device device.connect() # TODO: remove this self._connectToActiveMachine() ## Remove a CloudOutputDevice + # \param cluster: The cluster that was removed def _removeCloudOutputDevice(self, cluster: CloudCluster): self._output_device_manager.removeOutputDevice(cluster.cluster_id) del self._remote_clusters[cluster.cluster_id] @@ -141,3 +111,15 @@ class CloudOutputDeviceManager(NetworkClient): # TODO: If so, we can also immediate connect to it. # active_machine.setMetaDataEntry("um_cloud_cluster_id", "") # self._remote_clusters.get(stored_cluster_id).connect() + + ## Handles an API error received from the cloud. + # \param errors: The errors received + def _onApiError(self, errors: List[CloudErrorObject]) -> None: + message = ". ".join(e.title for e in errors) # TODO: translate errors + message = Message( + text = message, + title = self.I18N_CATALOG.i18nc("@info:title", "Error"), + lifetime = 10, + dismissable = True + ) + message.show() diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models.py b/plugins/UM3NetworkPrinting/src/Cloud/Models.py index d7cb68e5d3..27ff7df604 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models.py @@ -1,10 +1,22 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import List +from typing import List, Dict from ..Models import BaseModel +## Class representing errors generated by the cloud servers, according to the json-api standard. +class CloudErrorObject(BaseModel): + def __init__(self, **kwargs): + self.id = None # type: str + self.code = None # type: str + self.http_status = None # type: str + self.title = None # type: str + self.detail = None # type: str + self.meta = None # type: Dict[str, any] + super().__init__(**kwargs) + + ## Class representing a cloud connected cluster. class CloudCluster(BaseModel): def __init__(self, **kwargs): @@ -95,17 +107,23 @@ class CloudClusterPrintJob(BaseModel): for p in self.constraints] +# Model that represents the status of the cluster for the cloud class CloudClusterStatus(BaseModel): def __init__(self, **kwargs): + # a list of the printers self.printers = [] # type: List[CloudClusterPrinter] + # a list of the print jobs self.print_jobs = [] # type: List[CloudClusterPrintJob] + super().__init__(**kwargs) + # converting any dictionaries into models self.printers = [CloudClusterPrinter(**p) if isinstance(p, dict) else p for p in self.printers] self.print_jobs = [CloudClusterPrintJob(**j) if isinstance(j, dict) else j for j in self.print_jobs] -class JobUploadRequest(BaseModel): +# Model that represents the request to upload a print job to the cloud +class CloudJobUploadRequest(BaseModel): def __init__(self, **kwargs): self.file_size = None # type: int self.job_name = None # type: str @@ -113,7 +131,8 @@ class JobUploadRequest(BaseModel): super().__init__(**kwargs) -class JobUploadResponse(BaseModel): +# Model that represents the response received from the cloud after requesting to upload a print job +class CloudJobResponse(BaseModel): def __init__(self, **kwargs): self.download_url = None # type: str self.job_id = None # type: str @@ -125,7 +144,8 @@ class JobUploadResponse(BaseModel): super().__init__(**kwargs) -class PrintResponse(BaseModel): +# Model that represents the responses received from the cloud after requesting a job to be printed. +class CloudPrintResponse(BaseModel): def __init__(self, **kwargs): self.cluster_job_id = None # type: str self.job_id = None # type: str From b32d6812db2abfba8973ab3b3466c02357b038ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Tue, 4 Dec 2018 16:20:27 +0100 Subject: [PATCH 0667/1292] We don't need a Signal with QTimer --- .../src/Cloud/CloudOutputDeviceManager.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 6ab72d8ee3..b7ad4e9f6a 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -7,7 +7,6 @@ from PyQt5.QtCore import QTimer from UM import i18nCatalog from UM.Logger import Logger from UM.Message import Message -from UM.Signal import Signal from cura.CuraApplication import CuraApplication from plugins.UM3NetworkPrinting.src.Cloud.CloudApiClient import CloudApiClient from .CloudOutputDevice import CloudOutputDevice @@ -43,13 +42,10 @@ class CloudOutputDeviceManager: # When switching machines we check if we have to activate a remote cluster. application.globalContainerStackChanged.connect(self._connectToActiveMachine) - self._on_cluster_received = Signal() - self._on_cluster_received.connect(self._getRemoteClusters) - self.update_timer = QTimer(CuraApplication.getInstance()) self.update_timer.setInterval(self.CHECK_CLUSTER_INTERVAL * 1000) self.update_timer.setSingleShot(False) - self.update_timer.timeout.connect(self._on_cluster_received.emit) + self.update_timer.timeout.connect(self._getRemoteClusters) ## Gets all remote clusters from the API. def _getRemoteClusters(self) -> None: @@ -59,7 +55,8 @@ class CloudOutputDeviceManager: # Only start the polling timer after the user is authenticated # The first call to _getRemoteClusters comes from self._account.loginStateChanged - self.update_timer.start() + if not self.update_timer.isActive(): + self.update_timer.start() ## Callback for when the request for getting the clusters. is finished. def _onGetRemoteClustersFinished(self, clusters: List[CloudCluster]) -> None: From 0887817f7dd0c157c758a8459bd54a46196cb766 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 4 Dec 2018 16:35:09 +0100 Subject: [PATCH 0668/1292] use special icon for cloud connected --- resources/qml/PrinterSelector/MachineSelector.qml | 5 +++-- resources/qml/PrinterSelector/MachineSelectorList.qml | 2 +- .../themes/cura-light/icons/printer_cloud_connected.svg | 0 3 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 resources/themes/cura-light/icons/printer_cloud_connected.svg diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index 15cd773c90..780b5baa74 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -12,6 +12,7 @@ Cura.ExpandableComponent id: machineSelector property bool isNetworkPrinter: Cura.MachineManager.activeMachineNetworkKey != "" + property bool isCloudConnected: Cura.MachineManager.activeMachineCloudKey != "" property bool isPrinterConnected: Cura.MachineManager.printerConnected property var outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null @@ -55,7 +56,7 @@ Cura.ExpandableComponent leftMargin: UM.Theme.getSize("thick_margin").width } - source: UM.Theme.getIcon("printer_connected") + source: isCloudConnected ? UM.Theme.getIcon("printer_cloud_connected") : UM.Theme.getIcon("printer_connected") width: UM.Theme.getSize("printer_status_icon").width height: UM.Theme.getSize("printer_status_icon").height @@ -63,7 +64,7 @@ Cura.ExpandableComponent sourceSize.height: height color: UM.Theme.getColor("primary") - visible: isNetworkPrinter && isPrinterConnected + visible: isNetworkPrinter && (isPrinterConnected || isCloudConnected) // Make a themable circle in the background so we can change it in other themes Rectangle diff --git a/resources/qml/PrinterSelector/MachineSelectorList.qml b/resources/qml/PrinterSelector/MachineSelectorList.qml index 26c703fddd..e605f23f73 100644 --- a/resources/qml/PrinterSelector/MachineSelectorList.qml +++ b/resources/qml/PrinterSelector/MachineSelectorList.qml @@ -79,7 +79,7 @@ Column delegate: MachineSelectorButton { text: model.metadata["connect_group_name"] - checked: Cura.MachineManager.activeMachineNetworkGroupName == model.metadata["connect_group_name"] + checked: true // cloud devices are always online if they are available outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null Connections diff --git a/resources/themes/cura-light/icons/printer_cloud_connected.svg b/resources/themes/cura-light/icons/printer_cloud_connected.svg new file mode 100644 index 0000000000..e69de29bb2 From 3a733bb0a3b11b02e4cae838b8809c593bee6120 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Tue, 4 Dec 2018 16:35:48 +0100 Subject: [PATCH 0669/1292] Check before removing a printer --- .../UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index b7ad4e9f6a..5440795e5d 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -92,7 +92,8 @@ class CloudOutputDeviceManager: # \param cluster: The cluster that was removed def _removeCloudOutputDevice(self, cluster: CloudCluster): self._output_device_manager.removeOutputDevice(cluster.cluster_id) - del self._remote_clusters[cluster.cluster_id] + if cluster.cluster_id in self._remote_clusters: + del self._remote_clusters[cluster.cluster_id] ## Callback for when the active machine was changed by the user. def _connectToActiveMachine(self, cluster_id: Optional[str] = None, host_name: Optional[str] = None) -> None: From 9df49a1232152f22133f627a16c2c935aa5b49c7 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 4 Dec 2018 16:39:46 +0100 Subject: [PATCH 0670/1292] Add the actual icon contents --- .../cura-light/icons/printer_cloud_connected.svg | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/resources/themes/cura-light/icons/printer_cloud_connected.svg b/resources/themes/cura-light/icons/printer_cloud_connected.svg index e69de29bb2..fff2bf7c44 100644 --- a/resources/themes/cura-light/icons/printer_cloud_connected.svg +++ b/resources/themes/cura-light/icons/printer_cloud_connected.svg @@ -0,0 +1,13 @@ + + + + noun_Cloud_377836 + Created with Sketch. + + + + + + + + \ No newline at end of file From de78c44461d89061a5110d30d3b93066dc07bfc1 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 4 Dec 2018 16:43:13 +0100 Subject: [PATCH 0671/1292] Fix configuration drop-down for dark theme This actually changes the secondary colour to be darker for the dark theme, to be more in line with the general theme then. Contributes to issue CURA-5876. --- resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml | 1 + resources/themes/cura-dark/theme.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index 72b640e94a..fe2bf34e35 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -90,6 +90,7 @@ Item radius: tabBar.visible ? UM.Theme.getSize("default_radius").width : 0 border.width: tabBar.visible ? UM.Theme.getSize("default_lining").width : 0 border.color: UM.Theme.getColor("lining") + color: UM.Theme.getColor("main_background") //Remove rounding and lining at the top. Rectangle diff --git a/resources/themes/cura-dark/theme.json b/resources/themes/cura-dark/theme.json index 078f04db1a..d9ef74ebb9 100644 --- a/resources/themes/cura-dark/theme.json +++ b/resources/themes/cura-dark/theme.json @@ -15,7 +15,7 @@ "primary_hover": [48, 182, 231, 255], "primary_text": [255, 255, 255, 204], "border": [127, 127, 127, 255], - "secondary": [241, 242, 242, 255], + "secondary": [95, 95, 95, 255], "main_window_header_button_text_inactive": [128, 128, 128, 255], "main_window_header_button_text_hovered": [255, 255, 255, 255], From 27dc17f9930958a3a4682d7ac3dcbc586e2311ca Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Tue, 4 Dec 2018 16:49:26 +0100 Subject: [PATCH 0672/1292] STAR-322: Extracting translations --- .../src/Cloud/CloudOutputDevice.py | 75 ++++++++++++------- 1 file changed, 50 insertions(+), 25 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index c91944fe4d..af9324c9b0 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -2,7 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. import io import os -from typing import List, Optional, Dict, cast, Union +from typing import List, Optional, Dict, cast, Union, Set from PyQt5.QtCore import QObject, pyqtSignal, QUrl, pyqtProperty, pyqtSlot @@ -27,6 +27,32 @@ from .Models import ( ) +## Private class that contains all the translations for this component. +class T: + # The translation catalog for this device. + + _I18N_CATALOG = i18nCatalog("cura") + + PRINT_VIA_CLOUD_BUTTON = _I18N_CATALOG.i18nc("@action:button", "Print via Cloud") + PRINT_VIA_CLOUD_TOOLTIP = _I18N_CATALOG.i18nc("@properties:tooltip", "Print via Cloud") + + CONNECTED_VIA_CLOUD = _I18N_CATALOG.i18nc("@info:status", "Connected via Cloud") + BLOCKED_UPLOADING = _I18N_CATALOG.i18nc("@info:status", "Sending new jobs (temporarily) blocked, still sending " + "the previous print job.") + + COULD_NOT_EXPORT = _I18N_CATALOG.i18nc("@info:status", "Could not export print job.") + WRITE_FAILED = _I18N_CATALOG.i18nc("@info:status", "There are no file formats available to write with!") + + SENDING_DATA_TEXT = _I18N_CATALOG.i18nc("@info:status", "Sending data to remote cluster") + SENDING_DATA_TITLE = _I18N_CATALOG.i18nc("@info:status", "Sending data to remote cluster") + + ERROR = _I18N_CATALOG.i18nc("@info:title", "Error") + UPLOAD_ERROR = _I18N_CATALOG.i18nc("@info:text", "Could not upload the data to the printer.") + + UPLOAD_SUCCESS_TITLE = _I18N_CATALOG.i18nc("@info:title", "Data Sent") + UPLOAD_SUCCESS_TEXT = _I18N_CATALOG.i18nc("@info:status", "Print job was successfully sent to the printer.") + + ## The cloud output device is a network output device that works remotely but has limited functionality. # Currently it only supports viewing the printer and print job status and adding a new job to the queue. # As such, those methods have been implemented here. @@ -34,9 +60,6 @@ from .Models import ( # # TODO: figure our how the QML interface for the cluster networking should operate with this limited functionality. class CloudOutputDevice(NetworkedPrinterOutputDevice): - - # The translation catalog for this device. - I18N_CATALOG = i18nCatalog("cura") # Signal triggered when the printers in the remote cluster were changed. printersChanged = pyqtSignal() @@ -74,9 +97,9 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def _setInterfaceElements(self): self.setPriority(2) # make sure we end up below the local networking and above 'save to file' self.setName(self._id) - self.setShortDescription(self.I18N_CATALOG.i18nc("@action:button", "Print via Cloud")) - self.setDescription(self.I18N_CATALOG.i18nc("@properties:tooltip", "Print via Cloud")) - self.setConnectionText(self.I18N_CATALOG.i18nc("@info:status", "Connected via Cloud")) + self.setShortDescription(T.PRINT_VIA_CLOUD_BUTTON) + self.setDescription(T.PRINT_VIA_CLOUD_TOOLTIP) + self.setConnectionText(T.CONNECTED_VIA_CLOUD) ## Called when Cura requests an output device to receive a (G-code) file. def requestWrite(self, nodes: List[SceneNode], file_name: Optional[str] = None, limit_mime_types: bool = False, @@ -84,8 +107,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # Show an error message if we're already sending a job. if self._sending_job: - self._onUploadError(self.I18N_CATALOG.i18nc( - "@info:status", "Sending new jobs (temporarily) blocked, still sending the previous print job.")) + self._onUploadError(T.BLOCKED_UPLOADING) return # Indicate we have started sending a job. @@ -96,7 +118,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): writer = self._determineWriter(file_handler, file_format) if not writer: Logger.log("e", "Missing file or mesh writer!") - self._onUploadError(self.I18N_CATALOG.i18nc("@info:status", "Could not export print job.")) + self._onUploadError(T.COULD_NOT_EXPORT) return stream = io.StringIO() if file_format["mode"] == FileWriter.OutputMode.TextMode else io.BytesIO() @@ -131,9 +153,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): if len(file_formats) == 0: Logger.log("e", "There are no file formats available to write with!") - raise OutputDeviceError.WriteRequestFailedError( - self.I18N_CATALOG.i18nc("@info:status", "There are no file formats available to write with!") - ) + raise OutputDeviceError.WriteRequestFailedError(T.WRITE_FAILED) return file_formats[0] # TODO: This is yanked right out of ClusterUM3OutputDevice, great candidate for a utility or base class @@ -279,18 +299,21 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): remote_jobs = {j.uuid: j for j in jobs} # type: Dict[str, CloudClusterPrintJob] current_jobs = {j.key: j for j in self._print_jobs} # type: Dict[str, UM3PrintJobOutputModel] - for removed_job_id in set(current_jobs).difference(remote_jobs): + remote_job_ids = set(remote_jobs) # type: Set[str] + current_job_ids = set(current_jobs) # type: Set[str] + + for removed_job_id in current_job_ids.difference(remote_job_ids): self._print_jobs.remove(current_jobs[removed_job_id]) - for new_job_id in set(remote_jobs.keys()).difference(current_jobs): + for new_job_id in remote_job_ids.difference(current_jobs): self._addPrintJob(remote_jobs[new_job_id]) - for updated_job_id in set(current_jobs).intersection(remote_jobs): + for updated_job_id in current_job_ids.intersection(remote_job_ids): self._updateUM3PrintJobOutputModel(current_jobs[updated_job_id], remote_jobs[updated_job_id]) # We only have to update when jobs are added or removed - # updated jobs push their changes via their outputmodel - if len(removed_job_ids) > 0 or len(new_job_ids) > 0: + # updated jobs push their changes via their output model + if remote_job_ids != current_job_ids: self.printJobsChanged.emit() def _addPrintJob(self, job: CloudClusterPrintJob) -> None: @@ -324,7 +347,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def _onPrintJobCreated(self, mesh: bytes, job_response: CloudJobResponse) -> None: Logger.log("i", "Print job created successfully: %s", job_response.__dict__) - self._api.uploadMesh(job_response, mesh, self._onPrintJobUploaded, self._onUploadPrintJobProgress) + self._api.uploadMesh(job_response, mesh, self._onPrintJobUploaded, self._onUploadPrintJobProgress, + lambda error: self._onUploadError(T.UPLOAD_ERROR)) def _onPrintJobUploaded(self, job_id: str) -> None: self._api.requestPrint(self._device_id, job_id, self._onUploadSuccess) @@ -336,8 +360,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def _updateUploadProgress(self, progress: int): if not self._progress_message: self._progress_message = Message( - text = self.I18N_CATALOG.i18nc("@info:status", "Sending data to remote cluster"), - title = self.I18N_CATALOG.i18nc("@info:title", "Sending Data..."), + text = T.SENDING_DATA_TEXT, + title = T.SENDING_DATA_TITLE, progress = -1, lifetime = 0, dismissable = False, @@ -356,19 +380,20 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): if message: message = Message( text = message, - title = self.I18N_CATALOG.i18nc("@info:title", "Error"), + title = T.ERROR, lifetime = 10, dismissable = True ) message.show() - self._sending_job = False # the upload has failed so we're not sending a job anymore + self._sending_job = False # the upload has finished so we're not sending a job anymore self.writeError.emit() + # Shows a message when the upload has succeeded def _onUploadSuccess(self): self._resetUploadProgress() message = Message( - text = self.I18N_CATALOG.i18nc("@info:status", "Print job was successfully sent to the printer."), - title = self.I18N_CATALOG.i18nc("@info:title", "Data Sent"), + text = T.UPLOAD_SUCCESS_TEXT, + title = T.UPLOAD_SUCCESS_TITLE, lifetime = 5, dismissable = True, ) From 02efc9e1a905d1345a493d17108f74ca68b82110 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 4 Dec 2018 16:54:36 +0100 Subject: [PATCH 0673/1292] Fix cloud status icon size --- resources/themes/cura-light/icons/printer_cloud_connected.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/themes/cura-light/icons/printer_cloud_connected.svg b/resources/themes/cura-light/icons/printer_cloud_connected.svg index fff2bf7c44..ef6f0f2910 100644 --- a/resources/themes/cura-light/icons/printer_cloud_connected.svg +++ b/resources/themes/cura-light/icons/printer_cloud_connected.svg @@ -1,5 +1,5 @@ - + noun_Cloud_377836 Created with Sketch. From 1544ab6cf0b5b5a746e2084dffce2da7a3172067 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 4 Dec 2018 17:07:59 +0100 Subject: [PATCH 0674/1292] Explicitly enable hover on ConfigurationItem Apparently the default for this depends on some system setting. In Nallath's computer that system setting makes it false by default for some reason. Contributes to issue CURA-5876. --- resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 4a17e8eed8..af2712be44 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -12,6 +12,7 @@ Button id: configurationItem property var configuration: null + hoverEnabled: true height: childrenRect.height From 780e5e16917192e8f639142e1058f399a5e291f5 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 4 Dec 2018 17:09:55 +0100 Subject: [PATCH 0675/1292] Fix binding loop in PrintCoreConfiguration Contributes to issue CURA-5876. --- .../qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml index 4064a961d5..885f02d740 100644 --- a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml @@ -12,7 +12,7 @@ Row id: extruderInfo property var printCoreConfiguration - height: childrenRect.height + height: information.height spacing: UM.Theme.getSize("default_margin").width //Extruder icon. From 4ff5e43a28f3fd7479cd60defa7935f74c2f5729 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 4 Dec 2018 17:24:48 +0100 Subject: [PATCH 0676/1292] Handle Empty and Unknown material cases CURA-5982 --- plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index 1e0f538d8d..e31229680c 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -608,14 +608,15 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): def _createMaterialOutputModel(self, material_data: Dict[str, Any]) -> "MaterialOutputModel": material_manager = CuraApplication.getInstance().getMaterialManager() material_group_list = material_manager.getMaterialGroupListByGUID(material_data["guid"]) - # This can happen if the connected machine has no material in one or more extruders, so we should return an - # "empty" material model. + # This can happen if the connected machine has no material in one or more extruders (if GUID is empty), or the + # material is unknown to Cura, so we should return an "empty" or "unknown" material model. if material_group_list is None: + material_name = "Empty" if len(material_data["guid"]) == 0 else "Unknown" return MaterialOutputModel(guid = material_data["guid"], type = material_data.get("type", ""), color = material_data.get("color", ""), brand = material_data.get("brand", ""), - name = material_data.get("name", "Empty") + name = material_data.get("name", material_name) ) # Sort the material groups by "is_read_only = True" first, and then the name alphabetically. From 8ea4edf67e576014c9ec321e5f847f3659d13e00 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Tue, 4 Dec 2018 17:37:58 +0100 Subject: [PATCH 0677/1292] STAR-322: Fixing job uploads --- cura/NetworkClient.py | 4 +- .../src/Cloud/CloudApiClient.py | 54 ++++++++----------- .../src/Cloud/CloudOutputDevice.py | 43 ++++++++------- .../src/Cloud/CloudOutputDeviceManager.py | 2 +- 4 files changed, 49 insertions(+), 54 deletions(-) diff --git a/cura/NetworkClient.py b/cura/NetworkClient.py index 8a321b6af4..5294813fb7 100644 --- a/cura/NetworkClient.py +++ b/cura/NetworkClient.py @@ -60,7 +60,7 @@ class NetworkClient: ## Executes the correct callback method when a network request finishes. def __handleOnFinished(self, reply: QNetworkReply) -> None: - + # Due to garbage collection, we need to cache certain bits of post operations. # As we don't want to keep them around forever, delete them if we get a reply. if reply.operation() == QNetworkAccessManager.PostOperation: @@ -79,6 +79,8 @@ class NetworkClient: callback_key = reply.url().toString() + str(reply.operation()) if callback_key in self._on_finished_callbacks: self._on_finished_callbacks[callback_key](reply) + else: + Logger.log("w", "Received reply to URL %s but no callbacks are registered", reply.url()) ## Removes all cached Multi-Part items. def _clearCachedMultiPart(self, reply: QNetworkReply) -> None: diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py index 1d2de1d9bf..d6c20d387b 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py @@ -11,9 +11,7 @@ from cura.API import Account from cura.NetworkClient import NetworkClient from plugins.UM3NetworkPrinting.src.Models import BaseModel from plugins.UM3NetworkPrinting.src.Cloud.Models import ( - CloudCluster, CloudErrorObject, CloudClusterStatus, CloudJobUploadRequest, - CloudJobResponse, - CloudPrintResponse + CloudCluster, CloudErrorObject, CloudClusterStatus, CloudJobUploadRequest, CloudPrintResponse, CloudJobResponse ) @@ -24,8 +22,8 @@ class CloudApiClient(NetworkClient): # The cloud URL to use for this remote cluster. # TODO: Make sure that this URL goes to the live api before release ROOT_PATH = "https://api-staging.ultimaker.com" - CLUSTER_API_ROOT = "{}/connect/v1/".format(ROOT_PATH) - CURA_API_ROOT = "{}/cura/v1/".format(ROOT_PATH) + CLUSTER_API_ROOT = "{}/connect/v1".format(ROOT_PATH) + CURA_API_ROOT = "{}/cura/v1".format(ROOT_PATH) ## Initializes a new cloud API client. # \param account: The user's account object @@ -38,15 +36,15 @@ class CloudApiClient(NetworkClient): ## Retrieves all the clusters for the user that is currently logged in. # \param on_finished: The function to be called after the result is parsed. def getClusters(self, on_finished: Callable[[List[CloudCluster]], any]) -> None: - url = "/clusters" - self.get(url, on_finished=self._createCallback(on_finished, CloudCluster)) + url = "{}/clusters".format(self.CLUSTER_API_ROOT) + self.get(url, on_finished=self._wrapCallback(on_finished, CloudCluster)) ## Retrieves the status of the given cluster. # \param cluster_id: The ID of the cluster. # \param on_finished: The function to be called after the result is parsed. def getClusterStatus(self, cluster_id: str, on_finished: Callable[[CloudClusterStatus], any]) -> None: url = "{}/cluster/{}/status".format(self.CLUSTER_API_ROOT, cluster_id) - self.get(url, on_finished=self._createCallback(on_finished, CloudClusterStatus)) + self.get(url, on_finished=self._wrapCallback(on_finished, CloudClusterStatus)) ## Requests the cloud to register the upload of a print job mesh. # \param request: The request object. @@ -54,13 +52,16 @@ class CloudApiClient(NetworkClient): def requestUpload(self, request: CloudJobUploadRequest, on_finished: Callable[[CloudJobResponse], any]) -> None: url = "{}/jobs/upload".format(self.CURA_API_ROOT) body = json.dumps({"data": request.__dict__}) - self.put(url, body, on_finished=self._createCallback(on_finished, CloudJobResponse)) + self.put(url, body, on_finished=self._wrapCallback(on_finished, CloudJobResponse)) ## Requests the cloud to register the upload of a print job mesh. # \param upload_response: The object received after requesting an upload with `self.requestUpload`. + # \param mesh: The mesh data to be uploaded. # \param on_finished: The function to be called after the result is parsed. It receives the print job ID. + # \param on_progress: A function to be called during upload progress. It receives a percentage (0-100). + # \param on_error: A function to be called if the upload fails. It receives a dict with the error. def uploadMesh(self, upload_response: CloudJobResponse, mesh: bytes, on_finished: Callable[[str], any], - on_progress: Callable[[int], any]): + on_progress: Callable[[int], any], on_error: Callable[[dict], any]): def progressCallback(bytes_sent: int, bytes_total: int) -> None: if bytes_total: @@ -71,7 +72,8 @@ class CloudApiClient(NetworkClient): if status_code < 300: on_finished(upload_response.job_id) else: - self._uploadMeshError(status_code, response) + Logger.log("e", "Received unexpected response %s uploading mesh: %s", status_code, response) + on_error(response) # TODO: Multipart upload self.put(upload_response.upload_url, data = mesh, content_type = upload_response.content_type, @@ -81,9 +83,9 @@ class CloudApiClient(NetworkClient): # \param cluster_id: The ID of the cluster. # \param job_id: The ID of the print job. # \param on_finished: The function to be called after the result is parsed. - def requestPrint(self, cluster_id: str, job_id: str, on_finished: Callable[[], any]) -> None: + def requestPrint(self, cluster_id: str, job_id: str, on_finished: Callable[[CloudPrintResponse], any]) -> None: url = "{}/cluster/{}/print/{}".format(self.CLUSTER_API_ROOT, cluster_id, job_id) - self.post(url, data = "", on_finished=self._createCallback(on_finished, CloudPrintResponse)) + self.post(url, data = "", on_finished=self._wrapCallback(on_finished, CloudPrintResponse)) ## We override _createEmptyRequest in order to add the user credentials. # \param url: The URL to request @@ -92,6 +94,7 @@ class CloudApiClient(NetworkClient): request = super()._createEmptyRequest(path, content_type) if self._account.isLoggedIn: request.setRawHeader(b"Authorization", "Bearer {}".format(self._account.accessToken).encode()) + Logger.log("i", "Created request for URL %s. Logged in = %s", path, self._account.isLoggedIn) return request ## Parses the given JSON network reply into a status code and a dictionary, handling unexpected errors as well. @@ -102,26 +105,13 @@ class CloudApiClient(NetworkClient): status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) try: response = bytes(reply.readAll()).decode() - Logger.log("i", "Received an HTTP %s from %s with %s", status_code, reply.url, response) + Logger.log("i", "Received a reply %s from %s with %s", status_code, reply.url().toString(), response) return status_code, json.loads(response) except (UnicodeDecodeError, JSONDecodeError, ValueError) as err: error = {"code": type(err).__name__, "title": str(err), "http_code": str(status_code)} Logger.logException("e", "Could not parse the stardust response: %s", error) return status_code, {"errors": [error]} - ## Calls the error handler that is responsible for handling errors uploading meshes. - # \param http_status - The status of the HTTP request. - # \param response - The response received from the upload endpoint. This is not formatted according to the standard - # JSON-api response. - def _uploadMeshError(self, http_status: int, response: Dict[str, any]) -> None: - error = CloudErrorObject( - code = "uploadError", - http_status = str(http_status), - title = "Could not upload the mesh", - meta = response - ) - self._on_error([error]) - ## The generic type variable used to document the methods below. Model = TypeVar("Model", bound=BaseModel) @@ -141,14 +131,14 @@ class CloudApiClient(NetworkClient): else: Logger.log("e", "Cannot find data or errors in the cloud response: %s", response) - ## Creates a callback function that includes the parsing of the response into the correct model. + ## Wraps a callback function so that it includes the parsing of the response into the correct model. # \param on_finished: The callback in case the response is successful. # \param model: The type of the model to convert the response to. It may either be a single record or a list. # \return: A function that can be passed to the - def _createCallback(self, - on_finished: Callable[[Union[Model, List[Model]]], any], - model: Type[Model], - ) -> Callable[[QNetworkReply], None]: + def _wrapCallback(self, + on_finished: Callable[[Union[Model, List[Model]]], any], + model: Type[Model], + ) -> Callable[[QNetworkReply], None]: def parse(reply: QNetworkReply) -> None: status_code, response = self._parseReply(reply) return self._parseModels(response, on_finished, model) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index af9324c9b0..27bf3a821e 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -2,6 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. import io import os +from time import time from typing import List, Optional, Dict, cast, Union, Set from PyQt5.QtCore import QObject, pyqtSignal, QUrl, pyqtProperty, pyqtSlot @@ -23,11 +24,12 @@ from plugins.UM3NetworkPrinting.src.Cloud.CloudApiClient import CloudApiClient from plugins.UM3NetworkPrinting.src.UM3PrintJobOutputModel import UM3PrintJobOutputModel from .Models import ( CloudClusterPrinter, CloudClusterPrintJob, CloudJobUploadRequest, CloudJobResponse, CloudClusterStatus, - CloudClusterPrinterConfigurationMaterial, CloudErrorObject + CloudClusterPrinterConfigurationMaterial, CloudErrorObject, + CloudPrintResponse ) -## Private class that contains all the translations for this component. +## Class that contains all the translations for this module. class T: # The translation catalog for this device. @@ -61,13 +63,20 @@ class T: # TODO: figure our how the QML interface for the cluster networking should operate with this limited functionality. class CloudOutputDevice(NetworkedPrinterOutputDevice): + # The interval with which the remote clusters are checked + CHECK_CLUSTER_INTERVAL = 2.0 # seconds + # Signal triggered when the printers in the remote cluster were changed. printersChanged = pyqtSignal() # Signal triggered when the print jobs in the queue were changed. printJobsChanged = pyqtSignal() - def __init__(self, api_client: CloudApiClient, device_id: str, parent: QObject = None): + ## Creates a new cloud output device + # \param api_client: The client that will run the API calls + # \param device_id: The ID of the device (i.e. the cluster_id for the cloud API) + # \param parent: The optional parent of this output device. + def __init__(self, api_client: CloudApiClient, device_id: str, parent: QObject = None) -> None: super().__init__(device_id = device_id, address = "", properties = {}, parent = parent) self._api = api_client @@ -76,10 +85,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self._device_id = device_id self._account = CuraApplication.getInstance().getCuraAPI().account - # Cluster does not have authentication, so default to authenticated - self._authentication_state = AuthState.Authenticated - - # We re-use the Cura Connect monitor tab to get the most functionality right away. + # We use the Cura Connect monitor tab to get most functionality right away. self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../resources/qml/ClusterMonitorItem.qml") self._control_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), @@ -118,11 +124,12 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): writer = self._determineWriter(file_handler, file_format) if not writer: Logger.log("e", "Missing file or mesh writer!") - self._onUploadError(T.COULD_NOT_EXPORT) - return + return self._onUploadError(T.COULD_NOT_EXPORT) stream = io.StringIO() if file_format["mode"] == FileWriter.OutputMode.TextMode else io.BytesIO() writer.write(stream, nodes) + + # TODO: Remove extension from the file name, since we are using content types now self._sendPrintJob(file_name + "." + file_format["extension"], file_format["mime_type"], stream) # TODO: This is yanked right out of ClusterUM3OutputDevice, great candidate for a utility or base class @@ -202,7 +209,9 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## Called when the network data should be updated. def _update(self) -> None: super()._update() - Logger.log("i", "Calling the cloud cluster") + if self._last_response_time and time() - self._last_response_time < self.CHECK_CLUSTER_INTERVAL: + return # avoid calling the cloud too often + if self._account.isLoggedIn: self.setAuthenticationState(AuthState.Authenticated) self._api.getClusterStatus(self._device_id, self._onStatusCallFinished) @@ -212,7 +221,6 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## Method called when HTTP request to status endpoint is finished. # Contains both printers and print jobs statuses in a single response. def _onStatusCallFinished(self, status: CloudClusterStatus) -> None: - Logger.log("d", "Got response form the cloud cluster: %s", status.__dict__) # Update all data from the cluster. self._updatePrinters(status.printers) self._updatePrintJobs(status.print_jobs) @@ -342,21 +350,15 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): request.file_size = len(mesh) request.content_type = content_type - Logger.log("i", "Creating new cloud print job: %s", request.__dict__) self._api.requestUpload(request, lambda response: self._onPrintJobCreated(mesh, response)) def _onPrintJobCreated(self, mesh: bytes, job_response: CloudJobResponse) -> None: - Logger.log("i", "Print job created successfully: %s", job_response.__dict__) - self._api.uploadMesh(job_response, mesh, self._onPrintJobUploaded, self._onUploadPrintJobProgress, - lambda error: self._onUploadError(T.UPLOAD_ERROR)) + self._api.uploadMesh(job_response, mesh, self._onPrintJobUploaded, self._updateUploadProgress, + lambda _: self._onUploadError(T.UPLOAD_ERROR)) def _onPrintJobUploaded(self, job_id: str) -> None: self._api.requestPrint(self._device_id, job_id, self._onUploadSuccess) - def _onUploadPrintJobProgress(self, bytes_sent: int, bytes_total: int) -> None: - if bytes_total > 0: - self._updateUploadProgress(int((bytes_sent / bytes_total) * 100)) - def _updateUploadProgress(self, progress: int): if not self._progress_message: self._progress_message = Message( @@ -389,7 +391,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self.writeError.emit() # Shows a message when the upload has succeeded - def _onUploadSuccess(self): + def _onUploadSuccess(self, response: CloudPrintResponse): + Logger.log("i", "The cluster will be printing this print job with the ID %s", response.cluster_job_id) self._resetUploadProgress() message = Message( text = T.UPLOAD_SUCCESS_TEXT, diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 5440795e5d..772d40edd4 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -21,7 +21,7 @@ from .Models import CloudCluster, CloudErrorObject class CloudOutputDeviceManager: # The interval with which the remote clusters are checked - CHECK_CLUSTER_INTERVAL = 5 # seconds + CHECK_CLUSTER_INTERVAL = 5.0 # seconds # The translation catalog for this device. I18N_CATALOG = i18nCatalog("cura") From d0513e40e15b831b41b5ec9821178e2b8634172b Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 4 Dec 2018 22:21:36 +0100 Subject: [PATCH 0678/1292] Remove crappy implementation --- cura/Settings/MachineManager.py | 6 --- .../src/Cloud/CloudOutputDeviceManager.py | 5 +- resources/qml/Menus/CloudPrinterMenu.qml | 26 ----------- resources/qml/Menus/PrinterMenu.qml | 17 ------- .../qml/PrinterSelector/MachineSelector.qml | 5 +- .../PrinterSelector/MachineSelectorList.qml | 46 ++----------------- .../icons/printer_cloud_connected.svg | 2 +- 7 files changed, 8 insertions(+), 99 deletions(-) delete mode 100644 resources/qml/Menus/CloudPrinterMenu.qml diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 15e2c67c33..53390ca88d 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -527,12 +527,6 @@ class MachineManager(QObject): return self._global_container_stack.getMetaDataEntry("um_network_key", "") return "" - @pyqtProperty(str, notify=printerConnectedStatusChanged) - def activeMachineCloudKey(self) -> str: - if self._global_container_stack: - return self._global_container_stack.getMetaDataEntry("um_cloud_cluster_id", "") - return "" - @pyqtProperty(str, notify = printerConnectedStatusChanged) def activeMachineNetworkGroupName(self) -> str: if self._global_container_stack: diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 772d40edd4..9f7e8fa74a 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -86,7 +86,7 @@ class CloudOutputDeviceManager: self._output_device_manager.addOutputDevice(device) self._remote_clusters[cluster.cluster_id] = device device.connect() # TODO: remove this - self._connectToActiveMachine(cluster.cluster_id, cluster.host_name) + self._connectToActiveMachine(cluster.cluster_id) ## Remove a CloudOutputDevice # \param cluster: The cluster that was removed @@ -96,7 +96,7 @@ class CloudOutputDeviceManager: del self._remote_clusters[cluster.cluster_id] ## Callback for when the active machine was changed by the user. - def _connectToActiveMachine(self, cluster_id: Optional[str] = None, host_name: Optional[str] = None) -> None: + def _connectToActiveMachine(self, cluster_id: Optional[str] = None) -> None: active_machine = CuraApplication.getInstance().getGlobalContainerStack() if not active_machine: return @@ -104,7 +104,6 @@ class CloudOutputDeviceManager: # TODO: Remove this once correct pairing has been added (see below). if cluster_id: active_machine.setMetaDataEntry("um_cloud_cluster_id", cluster_id) - active_machine.setMetaDataEntry("connect_group_name", host_name) # Check if the stored cluster_id for the active machine is in our list of remote clusters. stored_cluster_id = active_machine.getMetaDataEntry("um_cloud_cluster_id") diff --git a/resources/qml/Menus/CloudPrinterMenu.qml b/resources/qml/Menus/CloudPrinterMenu.qml deleted file mode 100644 index bd03890642..0000000000 --- a/resources/qml/Menus/CloudPrinterMenu.qml +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.2 -import QtQuick.Controls 1.4 - -import UM 1.2 as UM -import Cura 1.0 as Cura - -Instantiator { - - model: UM.ContainerStacksModel { - filter: {"type": "machine", "um_cloud_cluster_id": "*"} - } - - MenuItem { - // iconSource: UM.Theme.getIcon("printer_single") TODO: use cloud icon here - text: model.metadata["connect_group_name"] - checkable: true - checked: true // cloud printers are only listed if they are actually online - exclusiveGroup: group; - onTriggered: Cura.MachineManager.setActiveMachine(model.id); - } - - onObjectAdded: menu.insertItem(index, object) - onObjectRemoved: menu.removeItem(object) -} diff --git a/resources/qml/Menus/PrinterMenu.qml b/resources/qml/Menus/PrinterMenu.qml index a924b0e589..741d927c13 100644 --- a/resources/qml/Menus/PrinterMenu.qml +++ b/resources/qml/Menus/PrinterMenu.qml @@ -37,23 +37,6 @@ Menu visible: networkPrinterMenu.count > 0 } - MenuItem - { - text: catalog.i18nc("@label:category menu label", "Cloud enabled printers") - enabled: false - visible: cloudPrinterMenu.count > 0 - } - - CloudPrinterMenu - { - id: cloudPrinterMenu - } - - MenuSeparator - { - visible: cloudPrinterMenu.count > 0 - } - MenuItem { text: catalog.i18nc("@label:category menu label", "Local printers") diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index 780b5baa74..15cd773c90 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -12,7 +12,6 @@ Cura.ExpandableComponent id: machineSelector property bool isNetworkPrinter: Cura.MachineManager.activeMachineNetworkKey != "" - property bool isCloudConnected: Cura.MachineManager.activeMachineCloudKey != "" property bool isPrinterConnected: Cura.MachineManager.printerConnected property var outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null @@ -56,7 +55,7 @@ Cura.ExpandableComponent leftMargin: UM.Theme.getSize("thick_margin").width } - source: isCloudConnected ? UM.Theme.getIcon("printer_cloud_connected") : UM.Theme.getIcon("printer_connected") + source: UM.Theme.getIcon("printer_connected") width: UM.Theme.getSize("printer_status_icon").width height: UM.Theme.getSize("printer_status_icon").height @@ -64,7 +63,7 @@ Cura.ExpandableComponent sourceSize.height: height color: UM.Theme.getColor("primary") - visible: isNetworkPrinter && (isPrinterConnected || isCloudConnected) + visible: isNetworkPrinter && isPrinterConnected // Make a themable circle in the background so we can change it in other themes Rectangle diff --git a/resources/qml/PrinterSelector/MachineSelectorList.qml b/resources/qml/PrinterSelector/MachineSelectorList.qml index e605f23f73..445940ab50 100644 --- a/resources/qml/PrinterSelector/MachineSelectorList.qml +++ b/resources/qml/PrinterSelector/MachineSelectorList.qml @@ -32,7 +32,8 @@ Column id: networkedPrintersModel filter: { - "type": "machine", "um_network_key": "*", "hidden": "False" + "type": "machine", + "um_network_key": "*" } } @@ -50,46 +51,6 @@ Column } } - Label - { - text: catalog.i18nc("@label", "Cloud connected printers") - visible: cloudPrintersModel.items.length > 0 - leftPadding: UM.Theme.getSize("default_margin").width - height: visible ? contentHeight + 2 * UM.Theme.getSize("default_margin").height : 0 - renderType: Text.NativeRendering - font: UM.Theme.getFont("medium") - color: UM.Theme.getColor("text_medium") - verticalAlignment: Text.AlignVCenter - } - - Repeater - { - id: cloudPrinters - - model: UM.ContainerStacksModel - { - id: cloudPrintersModel - filter: - { - "type": "machine", - "um_cloud_cluster_id": "*" - } - } - - delegate: MachineSelectorButton - { - text: model.metadata["connect_group_name"] - checked: true // cloud devices are always online if they are available - outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null - - Connections - { - target: Cura.MachineManager - onActiveMachineNetworkGroupNameChanged: checked = Cura.MachineManager.activeMachineNetworkGroupName == model.metadata["connect_group_name"] - } - } - } - Label { text: catalog.i18nc("@label", "Preset printers") @@ -112,8 +73,7 @@ Column filter: { "type": "machine", - "um_network_key": null, - "um_cloud_cluster_id": null + "um_network_key": null } } diff --git a/resources/themes/cura-light/icons/printer_cloud_connected.svg b/resources/themes/cura-light/icons/printer_cloud_connected.svg index ef6f0f2910..59ca67e93e 100644 --- a/resources/themes/cura-light/icons/printer_cloud_connected.svg +++ b/resources/themes/cura-light/icons/printer_cloud_connected.svg @@ -1,5 +1,5 @@ - + noun_Cloud_377836 Created with Sketch. From b57f6c5c6a6f7b227963bbbfb06633e7e306c113 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 4 Dec 2018 22:58:50 +0100 Subject: [PATCH 0679/1292] Do no stop when no clusters are found, we still might need to remove some --- .../src/Cloud/CloudOutputDeviceManager.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 9f7e8fa74a..0fbeeb82b6 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -63,8 +63,6 @@ class CloudOutputDeviceManager: found_clusters = {c.cluster_id: c for c in clusters} Logger.log("i", "Parsed remote clusters to %s", found_clusters) - if not found_clusters: - return known_cluster_ids = set(self._remote_clusters.keys()) found_cluster_ids = set(found_clusters.keys()) @@ -85,7 +83,6 @@ class CloudOutputDeviceManager: device = CloudOutputDevice(self._api, cluster.cluster_id) self._output_device_manager.addOutputDevice(device) self._remote_clusters[cluster.cluster_id] = device - device.connect() # TODO: remove this self._connectToActiveMachine(cluster.cluster_id) ## Remove a CloudOutputDevice @@ -95,13 +92,14 @@ class CloudOutputDeviceManager: if cluster.cluster_id in self._remote_clusters: del self._remote_clusters[cluster.cluster_id] - ## Callback for when the active machine was changed by the user. + ## Callback for when the active machine was changed by the user or a new remote cluster was found. def _connectToActiveMachine(self, cluster_id: Optional[str] = None) -> None: active_machine = CuraApplication.getInstance().getGlobalContainerStack() if not active_machine: return # TODO: Remove this once correct pairing has been added (see below). + # TODO: This just adds any available cluster to the active device for testing. if cluster_id: active_machine.setMetaDataEntry("um_cloud_cluster_id", cluster_id) From a62da4e5239b2f29d66d261d5405aa3e35f3f6d0 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 5 Dec 2018 09:13:48 +0100 Subject: [PATCH 0680/1292] Use setCurrentIndex instead of direct assignment This should prevent the binding from breaking and hopefully the segfault CURA-5876 --- resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index fe2bf34e35..2667c837ba 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -76,7 +76,7 @@ Item target: repeater.model onModelChanged: { - tabBar.currentIndex = Math.max(Cura.ExtruderManager.activeExtruderIndex, 0) + tabBar.setCurrentIndex(Cura.ExtruderManager.activeExtruderIndex) } } } From cdb8020029bec6ee1c6c4224ff5cb02159dd810e Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 5 Dec 2018 09:39:04 +0100 Subject: [PATCH 0681/1292] Add another expandable component Use one of them if the drop-panel has to act as a Popup and the other if it has to act as a standard component. Contributes to CURA-5941. --- .../SimulationViewMenuComponent.qml | 1 - resources/qml/ExpandableComponent.qml | 66 ++---- resources/qml/ExpandablePopup.qml | 204 ++++++++++++++++++ .../QuickConfigurationSelector.qml | 2 +- .../PrintSetupSelector/PrintSetupSelector.qml | 4 - .../qml/PrinterSelector/MachineSelector.qml | 4 +- resources/qml/ViewsSelector.qml | 8 +- 7 files changed, 227 insertions(+), 62 deletions(-) create mode 100644 resources/qml/ExpandablePopup.qml diff --git a/plugins/SimulationView/SimulationViewMenuComponent.qml b/plugins/SimulationView/SimulationViewMenuComponent.qml index 9dc3b67658..76875a035d 100644 --- a/plugins/SimulationView/SimulationViewMenuComponent.qml +++ b/plugins/SimulationView/SimulationViewMenuComponent.qml @@ -16,7 +16,6 @@ Cura.ExpandableComponent id: base width: UM.Theme.getSize("layerview_menu_size").width - contentType: Cura.ExpandableComponent.ContentType.Fixed Connections { diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index f6e340c4ea..4f4848ea8b 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -20,20 +20,11 @@ Item AlignRight } - enum ContentType - { - Floating, - Fixed - } - // The headerItem holds the QML item that is always displayed. property alias headerItem: headerItemLoader.sourceComponent // The contentItem holds the QML item that is shown when the "open" button is pressed - property var contentItem: content.contentItem - - // Defines the type of the contents - property int contentType: ExpandableComponent.ContentType.Floating + property alias contentItem: content.contentItem property color contentBackgroundColor: UM.Theme.getColor("action_button") @@ -48,7 +39,7 @@ Item property alias contentPadding: content.padding // How much spacing is needed for the contentItem by Y coordinate - property var contentSpacingY: 0 + property var contentSpacingY: UM.Theme.getSize("narrow_margin").width // How much padding is needed around the header & button property alias headerPadding: background.padding @@ -64,17 +55,12 @@ Item // Is the "drawer" open? readonly property alias expanded: content.visible - property alias expandedHighlightColor: expandedHighlight.color - // What should the radius of the header be. This is also influenced by the headerCornerSide property alias headerRadius: background.radius // On what side should the header corners be shown? 1 is down, 2 is left, 3 is up and 4 is right. property alias headerCornerSide: background.cornerSide - // Change the contentItem close behaviour - property alias contentClosePolicy : content.closePolicy - property alias headerShadowColor: shadow.color property alias enableHeaderShadow: shadow.visible @@ -83,14 +69,7 @@ Item function toggleContent() { - if (content.visible) - { - content.close() - } - else - { - content.open() - } + content.visible = !content.visible } implicitHeight: 100 * screenScaleFactor @@ -117,17 +96,6 @@ Item } } - // A highlight that is shown when the content is expanded - Rectangle - { - id: expandedHighlight - width: parent.width - height: UM.Theme.getSize("thick_lining").height - color: UM.Theme.getColor("primary") - visible: contentType == ExpandableComponent.ContentType.Floating && expanded - anchors.bottom: parent.bottom - } - UM.RecolorImage { id: collapseButton @@ -139,9 +107,7 @@ Item } sourceSize.width: width sourceSize.height: height - source: contentType == ExpandableComponent.ContentType.Floating ? - (expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left")) : - UM.Theme.getIcon("pencil") + source: UM.Theme.getIcon("pencil") visible: source != "" width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height @@ -155,8 +121,7 @@ Item onClicked: toggleContent() hoverEnabled: true onEntered: background.color = headerHoverColor - onExited: background.color = (contentType == ExpandableComponent.ContentType.Fixed && expanded) ? - headerActiveColor : headerBackgroundColor + onExited: background.color = expanded ? headerActiveColor : headerBackgroundColor } } @@ -174,9 +139,10 @@ Item z: background.z - 1 } - Popup + Control { id: content + visible: false // Ensure that the content is located directly below the headerItem y: background.height + base.shadowOffset + base.contentSpacingY @@ -185,7 +151,6 @@ Item // In case of right alignment, the 3x padding is due to left, right and padding between the button & text. x: contentAlignment == ExpandableComponent.ContentAlignment.AlignRight ? -width + collapseButton.width + headerItemLoader.width + 3 * background.padding : 0 padding: UM.Theme.getSize("default_margin").width - closePolicy: Popup.CloseOnPressOutsideParent background: Cura.RoundedRectangle { @@ -195,15 +160,16 @@ Item border.color: UM.Theme.getColor("lining") radius: UM.Theme.getSize("default_radius").width } - } - onContentItemChanged: - { - // Since we want the size of the content to be set by the size of the content, - // we need to do it like this. - content.width = contentItem.width + 2 * content.padding - content.height = contentItem.height + 2 * content.padding - content.contentItem = contentItem + contentItem: Item {} + + onContentItemChanged: + { + // Since we want the size of the content to be set by the size of the content, + // we need to do it like this. + content.width = contentItem.width + 2 * content.padding + content.height = contentItem.height + 2 * content.padding + } } // DO NOT MOVE UP IN THE CODE: This connection has to be here, after the definition of the content item. diff --git a/resources/qml/ExpandablePopup.qml b/resources/qml/ExpandablePopup.qml new file mode 100644 index 0000000000..da79d9b77b --- /dev/null +++ b/resources/qml/ExpandablePopup.qml @@ -0,0 +1,204 @@ +import QtQuick 2.7 +import QtQuick.Controls 2.3 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +import QtGraphicalEffects 1.0 // For the dropshadow + +// The expandable component has 2 major sub components: +// * The headerItem; Always visible and should hold some info about what happens if the component is expanded +// * The contentItem; The content that needs to be shown if the component is expanded. +Item +{ + id: base + + // Enumeration with the different possible alignments of the content with respect of the headerItem + enum ContentAlignment + { + AlignLeft, + AlignRight + } + + // The headerItem holds the QML item that is always displayed. + property alias headerItem: headerItemLoader.sourceComponent + + // The contentItem holds the QML item that is shown when the "open" button is pressed + property alias contentItem: content.contentItem + + property color contentBackgroundColor: UM.Theme.getColor("action_button") + + property color headerBackgroundColor: UM.Theme.getColor("action_button") + property color headerActiveColor: UM.Theme.getColor("secondary") + property color headerHoverColor: UM.Theme.getColor("action_button_hovered") + + // Defines the alignment of the content with respect of the headerItem, by default to the right + property int contentAlignment: ExpandablePopup.ContentAlignment.AlignRight + + // How much spacing is needed around the contentItem + property alias contentPadding: content.padding + + // How much padding is needed around the header & button + property alias headerPadding: background.padding + + // What icon should be displayed on the right. + property alias iconSource: collapseButton.source + + property alias iconColor: collapseButton.color + + // The icon size (it's always drawn as a square) + property alias iconSize: collapseButton.height + + // Is the "drawer" open? + readonly property alias expanded: content.visible + + property alias expandedHighlightColor: expandedHighlight.color + + // What should the radius of the header be. This is also influenced by the headerCornerSide + property alias headerRadius: background.radius + + // On what side should the header corners be shown? 1 is down, 2 is left, 3 is up and 4 is right. + property alias headerCornerSide: background.cornerSide + + // Change the contentItem close behaviour + property alias contentClosePolicy : content.closePolicy + + property alias headerShadowColor: shadow.color + + property alias enableHeaderShadow: shadow.visible + + property int shadowOffset: 2 + + function toggleContent() + { + if (content.visible) + { + content.close() + } + else + { + content.open() + } + } + + implicitHeight: 100 * screenScaleFactor + implicitWidth: 400 * screenScaleFactor + + RoundedRectangle + { + id: background + property real padding: UM.Theme.getSize("default_margin").width + + color: headerBackgroundColor + anchors.fill: parent + + Loader + { + id: headerItemLoader + anchors + { + left: parent.left + right: collapseButton.visible ? collapseButton.left : parent.right + top: parent.top + bottom: parent.bottom + margins: background.padding + } + } + + // A highlight that is shown when the content is expanded + Rectangle + { + id: expandedHighlight + width: parent.width + height: UM.Theme.getSize("thick_lining").height + color: UM.Theme.getColor("primary") + visible: expanded + anchors.bottom: parent.bottom + } + + UM.RecolorImage + { + id: collapseButton + anchors + { + right: parent.right + verticalCenter: parent.verticalCenter + margins: background.padding + } + sourceSize.width: width + sourceSize.height: height + source: expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") + visible: source != "" + width: UM.Theme.getSize("standard_arrow").width + height: UM.Theme.getSize("standard_arrow").height + color: UM.Theme.getColor("text") + } + + MouseArea + { + id: mouseArea + anchors.fill: parent + onClicked: toggleContent() + hoverEnabled: true + onEntered: background.color = headerHoverColor + onExited: background.color = headerBackgroundColor + } + } + + DropShadow + { + id: shadow + // Don't blur the shadow + radius: 0 + anchors.fill: background + source: background + verticalOffset: base.shadowOffset + visible: true + color: UM.Theme.getColor("action_button_shadow") + // Should always be drawn behind the background. + z: background.z - 1 + } + + Popup + { + id: content + + // Ensure that the content is located directly below the headerItem + y: background.height + base.shadowOffset + + // Make the content aligned with the rest, using the property contentAlignment to decide whether is right or left. + // In case of right alignment, the 3x padding is due to left, right and padding between the button & text. + x: contentAlignment == ExpandablePopup.ContentAlignment.AlignRight ? -width + collapseButton.width + headerItemLoader.width + 3 * background.padding : 0 + padding: UM.Theme.getSize("default_margin").width + closePolicy: Popup.CloseOnPressOutsideParent + + background: Cura.RoundedRectangle + { + cornerSide: Cura.RoundedRectangle.Direction.Down + color: contentBackgroundColor + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("lining") + radius: UM.Theme.getSize("default_radius").width + } + + contentItem: Item {} + + onContentItemChanged: + { + // Since we want the size of the content to be set by the size of the content, + // we need to do it like this. + content.width = contentItem.width + 2 * content.padding + content.height = contentItem.height + 2 * content.padding + } + } + + // DO NOT MOVE UP IN THE CODE: This connection has to be here, after the definition of the content item. + // Apparently the order in which these are handled matters and so the height is correctly updated if this is here. + Connections + { + // Since it could be that the content is dynamically populated, we should also take these changes into account. + target: content.contentItem + onWidthChanged: content.width = content.contentItem.width + 2 * content.padding + onHeightChanged: content.height = content.contentItem.height + 2 * content.padding + } +} diff --git a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml index ea82f4fe13..138a1d6669 100644 --- a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml +++ b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml @@ -12,7 +12,7 @@ import UM 1.2 as UM import Cura 1.0 as Cura -Cura.ExpandableComponent +Cura.ExpandablePopup { id: base diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector/PrintSetupSelector.qml index 0eea697950..19c8067683 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelector.qml @@ -14,11 +14,7 @@ Cura.ExpandableComponent property string enabledText: catalog.i18nc("@label:Should be short", "On") property string disabledText: catalog.i18nc("@label:Should be short", "Off") - contentType: Cura.ExpandableComponent.ContentType.Fixed contentPadding: UM.Theme.getSize("default_lining").width - contentSpacingY: UM.Theme.getSize("narrow_margin").width - - contentClosePolicy: Popup.CloseOnEscape UM.I18nCatalog { diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index 69a1ac899c..ef766b6030 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -7,7 +7,7 @@ import QtQuick.Controls 2.3 import UM 1.2 as UM import Cura 1.0 as Cura -Cura.ExpandableComponent +Cura.ExpandablePopup { id: machineSelector @@ -16,7 +16,7 @@ Cura.ExpandableComponent property var outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null contentPadding: UM.Theme.getSize("default_lining").width - contentAlignment: Cura.ExpandableComponent.ContentAlignment.AlignLeft + contentAlignment: Cura.ExpandablePopup.ContentAlignment.AlignLeft UM.I18nCatalog { diff --git a/resources/qml/ViewsSelector.qml b/resources/qml/ViewsSelector.qml index d469202606..18d1f66759 100644 --- a/resources/qml/ViewsSelector.qml +++ b/resources/qml/ViewsSelector.qml @@ -7,12 +7,12 @@ import QtQuick.Controls 2.3 import UM 1.2 as UM import Cura 1.0 as Cura -Cura.ExpandableComponent +Cura.ExpandablePopup { id: viewSelector contentPadding: UM.Theme.getSize("default_lining").width - contentAlignment: Cura.ExpandableComponent.ContentAlignment.AlignLeft + contentAlignment: Cura.ExpandablePopup.ContentAlignment.AlignLeft property var viewModel: UM.ViewModel { } @@ -72,13 +72,13 @@ Cura.ExpandableComponent contentItem: Column { id: viewSelectorPopup - width: viewSelector.width - 2 * viewSelector.popupPadding + width: viewSelector.width - 2 * viewSelector.contentPadding // For some reason the height/width of the column gets set to 0 if this is not set... Component.onCompleted: { height = implicitHeight - width = viewSelector.width - 2 * viewSelector.popupPadding + width = viewSelector.width - 2 * viewSelector.contentPadding } Repeater From 5d95d1143762a72e7cfe9c384c9d5752f6b888c2 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 5 Dec 2018 09:52:43 +0100 Subject: [PATCH 0682/1292] Use setCurrentIndex to switch tabs at activeExtruderChanged This fixes a mysterious segfault. We still don't know why the segfault occurred though. All we know is that QML logs something about a binding loop on currentIndex, and Qt logs something about removing range [-1 through 0] from VisualItemModel. When the tab bar is then made visible, Cura crashes. It is a nondeterministic crash. After this change, we are not seeing it any more (but with any nondeterministic bug, it's hard to verify that it was actually fixed). Contributes to issue CURA-5876. --- .../ConfigurationMenu/CustomConfiguration.qml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index 2667c837ba..18c2dabb0f 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -42,8 +42,6 @@ Item anchors.topMargin: UM.Theme.getSize("default_margin").height visible: extrudersModel.count > 1 - currentIndex: Math.max(Cura.ExtruderManager.activeExtruderIndex, 0) - Repeater { id: repeater @@ -68,6 +66,18 @@ Item } } + //When active extruder changes for some other reason, switch tabs. + //Don't directly link currentIndex to Cura.ExtruderManager.activeExtruderIndex! + //This causes a segfault in Qt 5.11. Something with VisualItemModel removing index -1. We have to use setCurrentIndex instead. + Connections + { + target: Cura.ExtruderManager + onActiveExtruderChanged: + { + tabBar.setCurrentIndex(Cura.ExtruderManager.activeExtruderIndex); + } + } + //When the model of the extruders is rebuilt, the list of extruders is briefly emptied and rebuilt. //This causes the currentIndex of the tab to be in an invalid position which resets it to 0. //Therefore we need to change it back to what it was: The active extruder index. From 01e443049fb51943369d3f1eca376bfb03f82b5a Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 5 Dec 2018 10:37:58 +0100 Subject: [PATCH 0683/1292] STAR-322: Creating a subclass for connect devices --- .../src/BaseCuraConnectDevice.py | 8 ++++++++ .../src/Cloud/CloudOutputDevice.py | 6 ++++-- .../src/ClusterUM3OutputDevice.py | 19 +++++++++---------- .../src/UM3OutputDevicePlugin.py | 2 +- 4 files changed, 22 insertions(+), 13 deletions(-) create mode 100644 plugins/UM3NetworkPrinting/src/BaseCuraConnectDevice.py diff --git a/plugins/UM3NetworkPrinting/src/BaseCuraConnectDevice.py b/plugins/UM3NetworkPrinting/src/BaseCuraConnectDevice.py new file mode 100644 index 0000000000..dc3d577cd5 --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/BaseCuraConnectDevice.py @@ -0,0 +1,8 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice + + +## this is the base class for the UM3 output devices (via connect or cloud) +class BaseCuraConnectDevice(NetworkedPrinterOutputDevice): + pass diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 27bf3a821e..4fa8d3b376 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -2,6 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. import io import os +from datetime import datetime, timedelta from time import time from typing import List, Optional, Dict, cast, Union, Set @@ -18,8 +19,9 @@ from UM.Version import Version from cura.CuraApplication import CuraApplication from cura.PrinterOutput.PrinterOutputController import PrinterOutputController from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel -from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice, AuthState +from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel +from plugins.UM3NetworkPrinting.src.BaseCuraConnectDevice import BaseCuraConnectDevice from plugins.UM3NetworkPrinting.src.Cloud.CloudApiClient import CloudApiClient from plugins.UM3NetworkPrinting.src.UM3PrintJobOutputModel import UM3PrintJobOutputModel from .Models import ( @@ -61,7 +63,7 @@ class T: # Note that this device represents a single remote cluster, not a list of multiple clusters. # # TODO: figure our how the QML interface for the cluster networking should operate with this limited functionality. -class CloudOutputDevice(NetworkedPrinterOutputDevice): +class CloudOutputDevice(BaseCuraConnectDevice): # The interval with which the remote clusters are checked CHECK_CLUSTER_INTERVAL = 2.0 # seconds diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index 8881584416..7015f71be4 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -1,7 +1,13 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import Any, cast, Optional, Set, Tuple, Union +from typing import Any, cast, Tuple, Union, Optional, Dict, List +from time import time +from datetime import datetime + +import io # To create the correct buffers for sending data to the printer. +import json +import os from UM.FileHandler.FileHandler import FileHandler from UM.FileHandler.FileWriter import FileWriter # To choose based on the output file mode (text vs. binary). @@ -22,6 +28,7 @@ from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationM from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice, AuthState from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel +from plugins.UM3NetworkPrinting.src.BaseCuraConnectDevice import BaseCuraConnectDevice from .ClusterUM3PrinterOutputController import ClusterUM3PrinterOutputController from .SendMaterialJob import SendMaterialJob @@ -32,18 +39,10 @@ from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply from PyQt5.QtGui import QDesktopServices, QImage from PyQt5.QtCore import pyqtSlot, QUrl, pyqtSignal, pyqtProperty, QObject -from time import time -from datetime import datetime -from typing import Optional, Dict, List - -import io # To create the correct buffers for sending data to the printer. -import json -import os - i18n_catalog = i18nCatalog("cura") -class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): +class ClusterUM3OutputDevice(BaseCuraConnectDevice): printJobsChanged = pyqtSignal() activePrinterChanged = pyqtSignal() activeCameraUrlChanged = pyqtSignal() diff --git a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py index 91c9cb32b9..6a80ae046e 100644 --- a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py +++ b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py @@ -363,4 +363,4 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): Logger.log("d", "Bonjour service removed: %s" % name) self.removeDeviceSignal.emit(str(name)) - return True \ No newline at end of file + return True From 700ae4bebb2218610fbf0095f57e7aabb81e52ba Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 5 Dec 2018 10:48:06 +0100 Subject: [PATCH 0684/1292] Removed super spammy logging CURA-6006 --- plugins/Toolbox/src/Toolbox.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 562a964f01..2b78581deb 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -491,11 +491,8 @@ class Toolbox(QObject, Extension): def canUpdate(self, package_id: str) -> bool: local_package = self._package_manager.getInstalledPackageInfo(package_id) if local_package is None: - Logger.log("i", "Could not find package [%s] as installed in the package manager, fall back to check the old plugins", - package_id) local_package = self.getOldPluginPackageMetadata(package_id) if local_package is None: - Logger.log("i", "Could not find package [%s] in the old plugins", package_id) return False remote_package = self.getRemotePackage(package_id) From 978a01e4c89873b42909991ae5ecc49988beab33 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 5 Dec 2018 10:51:05 +0100 Subject: [PATCH 0685/1292] Fix typing & codestyle CURA-6006 --- plugins/Toolbox/src/Toolbox.py | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 2b78581deb..1fe7c961ba 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -31,8 +31,8 @@ i18n_catalog = i18nCatalog("cura") ## The Toolbox class is responsible of communicating with the server through the API class Toolbox(QObject, Extension): - DEFAULT_CLOUD_API_ROOT = "https://api.ultimaker.com" #type: str - DEFAULT_CLOUD_API_VERSION = 1 #type: int + DEFAULT_CLOUD_API_ROOT = "https://api.ultimaker.com" # type: str + DEFAULT_CLOUD_API_VERSION = 1 # type: int def __init__(self, application: CuraApplication) -> None: super().__init__() @@ -192,9 +192,9 @@ class Toolbox(QObject, Extension): return self.DEFAULT_CLOUD_API_ROOT if not hasattr(cura.CuraVersion, "CuraCloudAPIRoot"): # type: ignore return self.DEFAULT_CLOUD_API_ROOT - if not cura.CuraVersion.CuraCloudAPIRoot: # type: ignore + if not cura.CuraVersion.CuraCloudAPIRoot: # type: ignore return self.DEFAULT_CLOUD_API_ROOT - return cura.CuraVersion.CuraCloudAPIRoot # type: ignore + return cura.CuraVersion.CuraCloudAPIRoot # type: ignore # Get the cloud API version from CuraVersion def _getCloudAPIVersion(self) -> int: @@ -202,9 +202,9 @@ class Toolbox(QObject, Extension): return self.DEFAULT_CLOUD_API_VERSION if not hasattr(cura.CuraVersion, "CuraCloudAPIVersion"): # type: ignore return self.DEFAULT_CLOUD_API_VERSION - if not cura.CuraVersion.CuraCloudAPIVersion: # type: ignore + if not cura.CuraVersion.CuraCloudAPIVersion: # type: ignore return self.DEFAULT_CLOUD_API_VERSION - return cura.CuraVersion.CuraCloudAPIVersion # type: ignore + return cura.CuraVersion.CuraCloudAPIVersion # type: ignore # Get the packages version depending on Cura version settings. def _getSDKVersion(self) -> Union[int, str]: @@ -231,12 +231,6 @@ class Toolbox(QObject, Extension): # Make remote requests: self._makeRequestByType("packages") self._makeRequestByType("authors") - # TODO: Uncomment in the future when the tag-filtered api calls work in the cloud server - # self._makeRequestByType("plugins_showcase") - # self._makeRequestByType("plugins_available") - # self._makeRequestByType("materials_showcase") - # self._makeRequestByType("materials_available") - # self._makeRequestByType("materials_generic") # Gather installed packages: self._updateInstalledModels() @@ -281,7 +275,7 @@ class Toolbox(QObject, Extension): "description": plugin_data["plugin"]["description"] } return formatted - except: + except KeyError: Logger.log("w", "Unable to convert plugin meta data %s", str(plugin_data)) return None From d9135ac72fa9aa4aa155179fb44e57cda2d1ad96 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 5 Dec 2018 11:06:14 +0100 Subject: [PATCH 0686/1292] Fix more codestyle issues CURA-6006 --- plugins/Toolbox/src/Toolbox.py | 62 +++++++++++++++------------------- 1 file changed, 27 insertions(+), 35 deletions(-) diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 1fe7c961ba..b6cfafe40c 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -559,34 +559,30 @@ class Toolbox(QObject, Extension): # Check for plugins that were installed with the old plugin browser def isOldPlugin(self, plugin_id: str) -> bool: - if plugin_id in self._old_plugin_ids: - return True - return False + return plugin_id in self._old_plugin_ids def getOldPluginPackageMetadata(self, plugin_id: str) -> Optional[Dict[str, Any]]: return self._old_plugin_metadata.get(plugin_id) - def loadingComplete(self) -> bool: + def isLoadingComplete(self) -> bool: populated = 0 - for list in self._metadata.items(): - if len(list) > 0: + for metadata_list in self._metadata.items(): + if metadata_list: populated += 1 - if populated == len(self._metadata.items()): - return True - return False + return populated == len(self._metadata.items()) # Make API Calls # -------------------------------------------------------------------------- - def _makeRequestByType(self, type: str) -> None: - Logger.log("i", "Marketplace: Requesting %s metadata from server.", type) - request = QNetworkRequest(self._request_urls[type]) + def _makeRequestByType(self, request_type: str) -> None: + Logger.log("i", "Requesting %s metadata from server.", request_type) + request = QNetworkRequest(self._request_urls[request_type]) request.setRawHeader(*self._request_header) if self._network_manager: self._network_manager.get(request) @pyqtSlot(str) def startDownload(self, url: str) -> None: - Logger.log("i", "Marketplace: Attempting to download & install package from %s.", url) + Logger.log("i", "Attempting to download & install package from %s.", url) url = QUrl(url) self._download_request = QNetworkRequest(url) if hasattr(QNetworkRequest, "FollowRedirectsAttribute"): @@ -603,7 +599,7 @@ class Toolbox(QObject, Extension): @pyqtSlot() def cancelDownload(self) -> None: - Logger.log("i", "Marketplace: User cancelled the download of a package.") + Logger.log("i", "User cancelled the download of a package.") self.resetDownload() def resetDownload(self) -> None: @@ -647,10 +643,10 @@ class Toolbox(QObject, Extension): ] if reply.operation() == QNetworkAccessManager.GetOperation: - for type, url in self._request_urls.items(): + for response_type, url in self._request_urls.items(): # HACK: Do nothing because we'll handle these from the "packages" call - if type in do_not_handle: + if response_type in do_not_handle: continue if reply.url() == url: @@ -665,38 +661,35 @@ class Toolbox(QObject, Extension): return # Create model and apply metadata: - if not self._models[type]: - Logger.log("e", "Could not find the %s model.", type) + if not self._models[response_type]: + Logger.log("e", "Could not find the %s model.", response_type) break - self._metadata[type] = json_data["data"] - self._models[type].setMetadata(self._metadata[type]) + self._metadata[response_type] = json_data["data"] + self._models[response_type].setMetadata(self._metadata[response_type]) # Do some auto filtering # TODO: Make multiple API calls in the future to handle this - if type is "packages": - self._models[type].setFilter({"type": "plugin"}) + if response_type is "packages": + self._models[response_type].setFilter({"type": "plugin"}) self.buildMaterialsModels() self.buildPluginsModels() - if type is "authors": - self._models[type].setFilter({"package_types": "material"}) - if type is "materials_generic": - self._models[type].setFilter({"tags": "generic"}) + if response_type is "authors": + self._models[response_type].setFilter({"package_types": "material"}) + if response_type is "materials_generic": + self._models[response_type].setFilter({"tags": "generic"}) self.metadataChanged.emit() - if self.loadingComplete() is True: + if self.isLoadingComplete(): self.setViewPage("overview") - return except json.decoder.JSONDecodeError: - Logger.log("w", "Marketplace: Received invalid JSON for %s.", type) + Logger.log("w", "Received invalid JSON for %s.", response_type) break else: self.setViewPage("errored") self.resetDownload() - return - else: # Ignore any operation that is not a get operation pass @@ -717,10 +710,10 @@ class Toolbox(QObject, Extension): self._onDownloadComplete(file_path) def _onDownloadComplete(self, file_path: str) -> None: - Logger.log("i", "Marketplace: Download complete.") + Logger.log("i", "Download complete.") package_info = self._package_manager.getPackageInfo(file_path) if not package_info: - Logger.log("w", "Marketplace: Package file [%s] was not a valid CuraPackage.", file_path) + Logger.log("w", "Package file [%s] was not a valid CuraPackage.", file_path) return license_content = self._package_manager.getPackageLicense(file_path) @@ -729,7 +722,6 @@ class Toolbox(QObject, Extension): return self.install(file_path) - return # Getter & Setters for Properties: # -------------------------------------------------------------------------- @@ -847,7 +839,7 @@ class Toolbox(QObject, Extension): self._metadata["materials_available"] = [] self._metadata["materials_generic"] = [] - processed_authors = [] # type: List[str] + processed_authors = [] # type: List[str] for item in self._metadata["packages"]: if item["package_type"] == "material": From d99e2d15339b8638b6161fc4659e77f9eb618c19 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 5 Dec 2018 11:21:17 +0100 Subject: [PATCH 0687/1292] STAR-322: Extracting file handler methods --- .../src/BaseCuraConnectDevice.py | 68 ++++++++++++++++++- .../src/Cloud/CloudOutputDevice.py | 68 +++---------------- .../src/ClusterUM3OutputDevice.py | 53 +++------------ 3 files changed, 83 insertions(+), 106 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/BaseCuraConnectDevice.py b/plugins/UM3NetworkPrinting/src/BaseCuraConnectDevice.py index dc3d577cd5..0abf5955cf 100644 --- a/plugins/UM3NetworkPrinting/src/BaseCuraConnectDevice.py +++ b/plugins/UM3NetworkPrinting/src/BaseCuraConnectDevice.py @@ -1,8 +1,72 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +from typing import Optional, Dict, Union + +from UM.FileHandler.FileHandler import FileHandler +from UM.FileHandler.FileWriter import FileWriter +from UM.Logger import Logger +from UM.OutputDevice import OutputDeviceError # To show that something went wrong when writing. +from UM.Version import Version # To check against firmware versions for support. +from UM.i18n import i18nCatalog +from cura.CuraApplication import CuraApplication from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice -## this is the base class for the UM3 output devices (via connect or cloud) +## Class that contains all the translations for this module. +class T: + # The translation catalog for this device. + + _I18N_CATALOG = i18nCatalog("cura") + NO_FORMATS_AVAILABLE = _I18N_CATALOG.i18nc("@info:status", "There are no file formats available to write with!") + + +## This is the base class for the UM3 output devices (via connect or cloud) class BaseCuraConnectDevice(NetworkedPrinterOutputDevice): - pass + + ## Gets the default file handler + @property + def defaultFileHandler(self) -> FileHandler: + return CuraApplication.getInstance().getMeshFileHandler() + + ## Chooses the preferred file format for the given file handler. + # \param file_handler: The file handler. + # \return A dict with the file format details, with format: + # {id: str, extension: str, description: str, mime_type: str, mode: int, hide_in_file_dialog: bool} + def _getPreferredFormat(self, file_handler: Optional[FileHandler]) -> Optional[Dict[str, Union[str, int, bool]]]: + # Formats supported by this application (file types that we can actually write). + application = CuraApplication.getInstance() + + file_handler = file_handler or self.defaultFileHandler + file_formats = file_handler.getSupportedFileTypesWrite() + + global_stack = application.getGlobalContainerStack() + # Create a list from the supported file formats string. + if not global_stack: + Logger.log("e", "Missing global stack!") + return + + machine_file_formats = global_stack.getMetaDataEntry("file_formats").split(";") + machine_file_formats = [file_type.strip() for file_type in machine_file_formats] + # Exception for UM3 firmware version >=4.4: UFP is now supported and should be the preferred file format. + if "application/x-ufp" not in machine_file_formats and Version(self.firmwareVersion) >= Version("4.4"): + machine_file_formats = ["application/x-ufp"] + machine_file_formats + + # Take the intersection between file_formats and machine_file_formats. + format_by_mimetype = {f["mime_type"]: f for f in file_formats} + + # Keep them ordered according to the preference in machine_file_formats. + file_formats = [format_by_mimetype[mimetype] for mimetype in machine_file_formats] + + if len(file_formats) == 0: + Logger.log("e", "There are no file formats available to write with!") + raise OutputDeviceError.WriteRequestFailedError(T.NO_FORMATS_AVAILABLE) + return file_formats[0] + + ## Gets the file writer for the given file handler and mime type. + # \param file_handler: The file handler. + # \param mime_type: The mine type. + # \return A file writer. + def _getWriter(self, file_handler: Optional[FileHandler], mime_type: str) -> Optional[FileWriter]: + # Just take the first file format available. + file_handler = file_handler or self.defaultFileHandler + return file_handler.getWriterByMimeType(mime_type) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 4fa8d3b376..0c6d11c708 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -2,9 +2,8 @@ # Cura is released under the terms of the LGPLv3 or higher. import io import os -from datetime import datetime, timedelta from time import time -from typing import List, Optional, Dict, cast, Union, Set +from typing import List, Optional, Dict, Union, Set from PyQt5.QtCore import QObject, pyqtSignal, QUrl, pyqtProperty, pyqtSlot @@ -13,9 +12,7 @@ from UM.FileHandler.FileWriter import FileWriter from UM.FileHandler.FileHandler import FileHandler from UM.Logger import Logger from UM.Message import Message -from UM.OutputDevice import OutputDeviceError from UM.Scene.SceneNode import SceneNode -from UM.Version import Version from cura.CuraApplication import CuraApplication from cura.PrinterOutput.PrinterOutputController import PrinterOutputController from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel @@ -45,7 +42,6 @@ class T: "the previous print job.") COULD_NOT_EXPORT = _I18N_CATALOG.i18nc("@info:status", "Could not export print job.") - WRITE_FAILED = _I18N_CATALOG.i18nc("@info:status", "There are no file formats available to write with!") SENDING_DATA_TEXT = _I18N_CATALOG.i18nc("@info:status", "Sending data to remote cluster") SENDING_DATA_TITLE = _I18N_CATALOG.i18nc("@info:status", "Sending data to remote cluster") @@ -69,7 +65,7 @@ class CloudOutputDevice(BaseCuraConnectDevice): CHECK_CLUSTER_INTERVAL = 2.0 # seconds # Signal triggered when the printers in the remote cluster were changed. - printersChanged = pyqtSignal() + clusterPrintersChanged = pyqtSignal() # Signal triggered when the print jobs in the queue were changed. printJobsChanged = pyqtSignal() @@ -122,8 +118,8 @@ class CloudOutputDevice(BaseCuraConnectDevice): self._sending_job = True self.writeStarted.emit(self) - file_format = self._determineFileFormat(file_handler) - writer = self._determineWriter(file_handler, file_format) + file_format = self._getPreferredFormat(file_handler) + writer = self._getWriter(file_handler, file_format["mime_type"]) if not writer: Logger.log("e", "Missing file or mesh writer!") return self._onUploadError(T.COULD_NOT_EXPORT) @@ -134,56 +130,8 @@ class CloudOutputDevice(BaseCuraConnectDevice): # TODO: Remove extension from the file name, since we are using content types now self._sendPrintJob(file_name + "." + file_format["extension"], file_format["mime_type"], stream) - # TODO: This is yanked right out of ClusterUM3OutputDevice, great candidate for a utility or base class - def _determineFileFormat(self, file_handler) -> Optional[Dict[str, Union[str, int]]]: - # Formats supported by this application (file types that we can actually write). - if file_handler: - file_formats = file_handler.getSupportedFileTypesWrite() - else: - file_formats = CuraApplication.getInstance().getMeshFileHandler().getSupportedFileTypesWrite() - - global_stack = CuraApplication.getInstance().getGlobalContainerStack() - # Create a list from the supported file formats string. - if not global_stack: - Logger.log("e", "Missing global stack!") - return - - machine_file_formats = global_stack.getMetaDataEntry("file_formats").split(";") - machine_file_formats = [file_type.strip() for file_type in machine_file_formats] - # Exception for UM3 firmware version >=4.4: UFP is now supported and should be the preferred file format. - if "application/x-ufp" not in machine_file_formats and Version(self.firmwareVersion) >= Version("4.4"): - machine_file_formats = ["application/x-ufp"] + machine_file_formats - - # Take the intersection between file_formats and machine_file_formats. - format_by_mimetype = {f["mime_type"]: f for f in file_formats} - - # Keep them ordered according to the preference in machine_file_formats. - file_formats = [format_by_mimetype[mimetype] for mimetype in machine_file_formats] - - if len(file_formats) == 0: - Logger.log("e", "There are no file formats available to write with!") - raise OutputDeviceError.WriteRequestFailedError(T.WRITE_FAILED) - return file_formats[0] - - # TODO: This is yanked right out of ClusterUM3OutputDevice, great candidate for a utility or base class - @staticmethod - def _determineWriter(file_handler, file_format) -> Optional[FileWriter]: - # Just take the first file format available. - if file_handler is not None: - writer = file_handler.getWriterByMimeType(cast(str, file_format["mime_type"])) - else: - writer = CuraApplication.getInstance().getMeshFileHandler().getWriterByMimeType( - cast(str, file_format["mime_type"]) - ) - - if not writer: - Logger.log("e", "Unexpected error when trying to get the FileWriter") - return - - return writer - ## Get remote printers. - @pyqtProperty("QVariantList", notify = printersChanged) + @pyqtProperty("QVariantList", notify = clusterPrintersChanged) def printers(self): return self._printers @@ -244,7 +192,7 @@ class CloudOutputDevice(BaseCuraConnectDevice): for printer_guid in updated_printer_ids: self._updatePrinter(current_printers[printer_guid], remote_printers[printer_guid]) - self.printersChanged.emit() + self.clusterPrintersChanged.emit() def _addPrinter(self, printer: CloudClusterPrinter) -> None: model = PrinterOutputModel( @@ -409,7 +357,7 @@ class CloudOutputDevice(BaseCuraConnectDevice): ## TODO: The following methods are required by the monitor page QML, but are not actually available using cloud. # TODO: We fake the methods here to not break the monitor page. - @pyqtProperty(QObject, notify = printersChanged) + @pyqtProperty(QObject, notify = clusterPrintersChanged) def activePrinter(self) -> Optional[PrinterOutputModel]: if not self._printers: return None @@ -419,7 +367,7 @@ class CloudOutputDevice(BaseCuraConnectDevice): def setActivePrinter(self, printer: Optional[PrinterOutputModel]) -> None: pass - @pyqtProperty(QUrl, notify = printersChanged) + @pyqtProperty(QUrl, notify = clusterPrintersChanged) def activeCameraUrl(self) -> "QUrl": return QUrl() diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index a1530c128d..c77c4b93c2 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -18,14 +18,12 @@ from UM.i18n import i18nCatalog from UM.Message import Message from UM.Qt.Duration import Duration, DurationFormat -from UM.OutputDevice import OutputDeviceError # To show that something went wrong when writing. from UM.Scene.SceneNode import SceneNode # For typing. -from UM.Version import Version # To check against firmware versions for support. from cura.CuraApplication import CuraApplication from cura.PrinterOutput.ConfigurationModel import ConfigurationModel from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel -from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice, AuthState +from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel from plugins.UM3NetworkPrinting.src.BaseCuraConnectDevice import BaseCuraConnectDevice @@ -50,7 +48,7 @@ class ClusterUM3OutputDevice(BaseCuraConnectDevice): # This is a bit of a hack, as the notify can only use signals that are defined by the class that they are in. # Inheritance doesn't seem to work. Tying them together does work, but i'm open for better suggestions. - clusterPrintersChanged = pyqtSignal() + _clusterPrintersChanged = pyqtSignal() def __init__(self, device_id, address, properties, parent = None) -> None: super().__init__(device_id = device_id, address = address, properties=properties, parent = parent) @@ -66,7 +64,7 @@ class ClusterUM3OutputDevice(BaseCuraConnectDevice): self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../resources/qml/ClusterMonitorItem.qml") # See comments about this hack with the clusterPrintersChanged signal - self.printersChanged.connect(self.clusterPrintersChanged) + self.printersChanged.connect(self._clusterPrintersChanged) self._accepts_commands = True # type: bool @@ -99,47 +97,14 @@ class ClusterUM3OutputDevice(BaseCuraConnectDevice): self._active_camera_url = QUrl() # type: QUrl - def requestWrite(self, nodes: List[SceneNode], file_name: Optional[str] = None, limit_mimetypes: bool = False, file_handler: Optional[FileHandler] = None, **kwargs: str) -> None: + def requestWrite(self, nodes: List[SceneNode], file_name: Optional[str] = None, limit_mimetypes: bool = False, + file_handler: Optional[FileHandler] = None, **kwargs: str) -> None: self.writeStarted.emit(self) self.sendMaterialProfiles() - # Formats supported by this application (file types that we can actually write). - if file_handler: - file_formats = file_handler.getSupportedFileTypesWrite() - else: - file_formats = CuraApplication.getInstance().getMeshFileHandler().getSupportedFileTypesWrite() - - global_stack = CuraApplication.getInstance().getGlobalContainerStack() - # Create a list from the supported file formats string. - if not global_stack: - Logger.log("e", "Missing global stack!") - return - - machine_file_formats = global_stack.getMetaDataEntry("file_formats").split(";") - machine_file_formats = [file_type.strip() for file_type in machine_file_formats] - # Exception for UM3 firmware version >=4.4: UFP is now supported and should be the preferred file format. - if "application/x-ufp" not in machine_file_formats and Version(self.firmwareVersion) >= Version("4.4"): - machine_file_formats = ["application/x-ufp"] + machine_file_formats - - # Take the intersection between file_formats and machine_file_formats. - format_by_mimetype = {format["mime_type"]: format for format in file_formats} - file_formats = [format_by_mimetype[mimetype] for mimetype in machine_file_formats] #Keep them ordered according to the preference in machine_file_formats. - - if len(file_formats) == 0: - Logger.log("e", "There are no file formats available to write with!") - raise OutputDeviceError.WriteRequestFailedError(i18n_catalog.i18nc("@info:status", "There are no file formats available to write with!")) - preferred_format = file_formats[0] - - # Just take the first file format available. - if file_handler is not None: - writer = file_handler.getWriterByMimeType(cast(str, preferred_format["mime_type"])) - else: - writer = CuraApplication.getInstance().getMeshFileHandler().getWriterByMimeType(cast(str, preferred_format["mime_type"])) - - if not writer: - Logger.log("e", "Unexpected error when trying to get the FileWriter") - return + preferred_format = self._getPreferredFormat(file_handler) + writer = self._getWriter(file_handler, preferred_format["mime_type"]) # This function pauses with the yield, waiting on instructions on which printer it needs to print with. if not writer: @@ -355,7 +320,7 @@ class ClusterUM3OutputDevice(BaseCuraConnectDevice): def activePrintJobs(self) -> List[UM3PrintJobOutputModel]: return [print_job for print_job in self._print_jobs if print_job.assignedPrinter is not None and print_job.state != "queued"] - @pyqtProperty("QVariantList", notify = clusterPrintersChanged) + @pyqtProperty("QVariantList", notify = _clusterPrintersChanged) def connectedPrintersTypeCount(self) -> List[Dict[str, str]]: printer_count = {} # type: Dict[str, int] for printer in self._printers: @@ -368,7 +333,7 @@ class ClusterUM3OutputDevice(BaseCuraConnectDevice): result.append({"machine_type": machine_type, "count": str(printer_count[machine_type])}) return result - @pyqtProperty("QVariantList", notify=clusterPrintersChanged) + @pyqtProperty("QVariantList", notify=_clusterPrintersChanged) def printers(self): return self._printers From abcc621cc62120a0f9f1e5f32599f8356e607dc2 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 5 Dec 2018 11:29:44 +0100 Subject: [PATCH 0688/1292] Added missing typing --- plugins/Toolbox/src/AuthorsModel.py | 43 ++++++++++++++-------------- plugins/Toolbox/src/PackagesModel.py | 2 +- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/plugins/Toolbox/src/AuthorsModel.py b/plugins/Toolbox/src/AuthorsModel.py index bea3893504..6f4b5bd280 100644 --- a/plugins/Toolbox/src/AuthorsModel.py +++ b/plugins/Toolbox/src/AuthorsModel.py @@ -2,18 +2,19 @@ # Cura is released under the terms of the LGPLv3 or higher. import re -from typing import Dict +from typing import Dict, List, Optional, Union from PyQt5.QtCore import Qt, pyqtProperty, pyqtSignal from UM.Qt.ListModel import ListModel + ## Model that holds cura packages. By setting the filter property the instances held by this model can be changed. class AuthorsModel(ListModel): - def __init__(self, parent = None): + def __init__(self, parent = None) -> None: super().__init__(parent) - self._metadata = None + self._metadata = None # type: Optional[List[Dict[str, Union[str, List[str], int]]]] self.addRoleName(Qt.UserRole + 1, "id") self.addRoleName(Qt.UserRole + 2, "name") @@ -25,39 +26,39 @@ class AuthorsModel(ListModel): self.addRoleName(Qt.UserRole + 8, "description") # List of filters for queries. The result is the union of the each list of results. - self._filter = {} # type: Dict[str,str] + self._filter = {} # type: Dict[str, str] - def setMetadata(self, data): + def setMetadata(self, data: List[Dict[str, Union[str, List[str], int]]]): self._metadata = data self._update() - def _update(self): - items = [] + def _update(self) -> None: + items = [] # type: List[Dict[str, Union[str, List[str], int, None]]] if not self._metadata: - self.setItems([]) + self.setItems(items) return for author in self._metadata: items.append({ - "id": author["author_id"], - "name": author["display_name"], - "email": author["email"] if "email" in author else None, - "website": author["website"], - "package_count": author["package_count"] if "package_count" in author else 0, - "package_types": author["package_types"] if "package_types" in author else [], - "icon_url": author["icon_url"] if "icon_url" in author else None, - "description": "Material and quality profiles from {author_name}".format(author_name = author["display_name"]) + "id": author.get("author_id"), + "name": author.get("display_name"), + "email": author.get("email"), + "website": author.get("website"), + "package_count": author.get("package_count", 0), + "package_types": author.get("package_types", []), + "icon_url": author.get("icon_url"), + "description": "Material and quality profiles from {author_name}".format(author_name = author.get("display_name", "")) }) # Filter on all the key-word arguments. for key, value in self._filter.items(): if key is "package_types": - key_filter = lambda item, value = value: value in item["package_types"] + key_filter = lambda item, value = value: value in item["package_types"] # type: ignore elif "*" in value: - key_filter = lambda item, key = key, value = value: self._matchRegExp(item, key, value) + key_filter = lambda item, key = key, value = value: self._matchRegExp(item, key, value) # type: ignore else: - key_filter = lambda item, key = key, value = value: self._matchString(item, key, value) - items = filter(key_filter, items) + key_filter = lambda item, key = key, value = value: self._matchString(item, key, value) # type: ignore + items = filter(key_filter, items) # type: ignore # Execute all filters. filtered_items = list(items) @@ -72,7 +73,7 @@ class AuthorsModel(ListModel): self._filter = filter_dict self._update() - @pyqtProperty("QVariantMap", fset = setFilter, constant = True) + @pyqtProperty("QStringMap", fset = setFilter, constant = True) def filter(self) -> Dict[str, str]: return self._filter diff --git a/plugins/Toolbox/src/PackagesModel.py b/plugins/Toolbox/src/PackagesModel.py index a31facf75a..2849a29c99 100644 --- a/plugins/Toolbox/src/PackagesModel.py +++ b/plugins/Toolbox/src/PackagesModel.py @@ -33,7 +33,7 @@ class PackagesModel(ListModel): self.addRoleName(Qt.UserRole + 12, "last_updated") self.addRoleName(Qt.UserRole + 13, "is_bundled") self.addRoleName(Qt.UserRole + 14, "is_active") - self.addRoleName(Qt.UserRole + 15, "is_installed") # Scheduled pkgs are included in the model but should not be marked as actually installed + self.addRoleName(Qt.UserRole + 15, "is_installed") # Scheduled pkgs are included in the model but should not be marked as actually installed self.addRoleName(Qt.UserRole + 16, "has_configs") self.addRoleName(Qt.UserRole + 17, "supported_configs") self.addRoleName(Qt.UserRole + 18, "download_count") From 163226f9400651b45a088af884a0edad383dc8e7 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 5 Dec 2018 12:02:04 +0100 Subject: [PATCH 0689/1292] STAR-322: Using composition rather than inheritance --- cura/PrinterOutputDevice.py | 9 ++- .../src/Cloud/CloudOutputDevice.py | 35 ++++----- .../src/ClusterUM3OutputDevice.py | 45 ++++++----- ...aConnectDevice.py => MeshFormatHandler.py} | 74 ++++++++++++++----- 4 files changed, 97 insertions(+), 66 deletions(-) rename plugins/UM3NetworkPrinting/src/{BaseCuraConnectDevice.py => MeshFormatHandler.py} (50%) diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index 99c48189cc..8c00ea1aa6 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -131,7 +131,8 @@ class PrinterOutputDevice(QObject, OutputDevice): return None - def requestWrite(self, nodes: List["SceneNode"], file_name: Optional[str] = None, limit_mimetypes: bool = False, file_handler: Optional["FileHandler"] = None, **kwargs: str) -> None: + def requestWrite(self, nodes: List["SceneNode"], file_name: Optional[str] = None, limit_mimetypes: bool = False, + file_handler: Optional["FileHandler"] = None, **kwargs: str) -> None: raise NotImplementedError("requestWrite needs to be implemented") @pyqtProperty(QObject, notify = printersChanged) @@ -207,8 +208,10 @@ class PrinterOutputDevice(QObject, OutputDevice): return self._unique_configurations def _updateUniqueConfigurations(self) -> None: - self._unique_configurations = list(set([printer.printerConfiguration for printer in self._printers if printer.printerConfiguration is not None])) - self._unique_configurations.sort(key = lambda k: k.printerType) + self._unique_configurations = sorted( + {printer.printerConfiguration for printer in self._printers if printer.printerConfiguration is not None}, + key=lambda config: config.printerType, + ) self.uniqueConfigurationsChanged.emit() # Returns the unique configurations of the printers within this output device diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 0c6d11c708..91f5721aa6 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -1,14 +1,12 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -import io import os from time import time -from typing import List, Optional, Dict, Union, Set +from typing import List, Optional, Dict, Set from PyQt5.QtCore import QObject, pyqtSignal, QUrl, pyqtProperty, pyqtSlot from UM import i18nCatalog -from UM.FileHandler.FileWriter import FileWriter from UM.FileHandler.FileHandler import FileHandler from UM.Logger import Logger from UM.Message import Message @@ -16,10 +14,10 @@ from UM.Scene.SceneNode import SceneNode from cura.CuraApplication import CuraApplication from cura.PrinterOutput.PrinterOutputController import PrinterOutputController from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel -from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState +from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState, NetworkedPrinterOutputDevice from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel -from plugins.UM3NetworkPrinting.src.BaseCuraConnectDevice import BaseCuraConnectDevice from plugins.UM3NetworkPrinting.src.Cloud.CloudApiClient import CloudApiClient +from plugins.UM3NetworkPrinting.src.MeshFormatHandler import MeshFormatHandler from plugins.UM3NetworkPrinting.src.UM3PrintJobOutputModel import UM3PrintJobOutputModel from .Models import ( CloudClusterPrinter, CloudClusterPrintJob, CloudJobUploadRequest, CloudJobResponse, CloudClusterStatus, @@ -59,7 +57,7 @@ class T: # Note that this device represents a single remote cluster, not a list of multiple clusters. # # TODO: figure our how the QML interface for the cluster networking should operate with this limited functionality. -class CloudOutputDevice(BaseCuraConnectDevice): +class CloudOutputDevice(NetworkedPrinterOutputDevice): # The interval with which the remote clusters are checked CHECK_CLUSTER_INTERVAL = 2.0 # seconds @@ -118,17 +116,20 @@ class CloudOutputDevice(BaseCuraConnectDevice): self._sending_job = True self.writeStarted.emit(self) - file_format = self._getPreferredFormat(file_handler) - writer = self._getWriter(file_handler, file_format["mime_type"]) - if not writer: + mesh_format = MeshFormatHandler(file_handler, self.firmwareVersion) + if not mesh_format.is_valid: Logger.log("e", "Missing file or mesh writer!") return self._onUploadError(T.COULD_NOT_EXPORT) - stream = io.StringIO() if file_format["mode"] == FileWriter.OutputMode.TextMode else io.BytesIO() - writer.write(stream, nodes) + mesh_bytes = mesh_format.getBytes(nodes) # TODO: Remove extension from the file name, since we are using content types now - self._sendPrintJob(file_name + "." + file_format["extension"], file_format["mime_type"], stream) + request = CloudJobUploadRequest( + job_name = file_name + "." + mesh_format.file_extension, + file_size = len(mesh_bytes), + content_type = mesh_format.mime_type, + ) + self._api.requestUpload(request, lambda response: self._onPrintJobCreated(mesh_bytes, response)) ## Get remote printers. @pyqtProperty("QVariantList", notify = clusterPrintersChanged) @@ -292,16 +293,6 @@ class CloudOutputDevice(BaseCuraConnectDevice): model.updateOwner(job.owner) model.updateState(job.status) - def _sendPrintJob(self, file_name: str, content_type: str, stream: Union[io.StringIO, io.BytesIO]) -> None: - mesh = stream.getvalue() - - request = CloudJobUploadRequest() - request.job_name = file_name - request.file_size = len(mesh) - request.content_type = content_type - - self._api.requestUpload(request, lambda response: self._onPrintJobCreated(mesh, response)) - def _onPrintJobCreated(self, mesh: bytes, job_response: CloudJobResponse) -> None: self._api.uploadMesh(job_response, mesh, self._onPrintJobUploaded, self._updateUploadProgress, lambda _: self._onUploadError(T.UPLOAD_ERROR)) diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index c77c4b93c2..64ac613723 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -10,7 +10,6 @@ import json import os from UM.FileHandler.FileHandler import FileHandler -from UM.FileHandler.FileWriter import FileWriter # To choose based on the output file mode (text vs. binary). from UM.FileHandler.WriteFileJob import WriteFileJob # To call the file writer asynchronously. from UM.Logger import Logger from UM.Settings.ContainerRegistry import ContainerRegistry @@ -23,10 +22,10 @@ from UM.Scene.SceneNode import SceneNode # For typing. from cura.CuraApplication import CuraApplication from cura.PrinterOutput.ConfigurationModel import ConfigurationModel from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel -from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState +from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState, NetworkedPrinterOutputDevice from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel -from plugins.UM3NetworkPrinting.src.BaseCuraConnectDevice import BaseCuraConnectDevice +from plugins.UM3NetworkPrinting.src.MeshFormatHandler import MeshFormatHandler from .ClusterUM3PrinterOutputController import ClusterUM3PrinterOutputController from .SendMaterialJob import SendMaterialJob @@ -40,7 +39,7 @@ from PyQt5.QtCore import pyqtSlot, QUrl, pyqtSignal, pyqtProperty, QObject i18n_catalog = i18nCatalog("cura") -class ClusterUM3OutputDevice(BaseCuraConnectDevice): +class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): printJobsChanged = pyqtSignal() activePrinterChanged = pyqtSignal() activeCameraUrlChanged = pyqtSignal() @@ -103,14 +102,13 @@ class ClusterUM3OutputDevice(BaseCuraConnectDevice): self.sendMaterialProfiles() - preferred_format = self._getPreferredFormat(file_handler) - writer = self._getWriter(file_handler, preferred_format["mime_type"]) + mesh_format = MeshFormatHandler(file_handler, self.firmwareVersion) # This function pauses with the yield, waiting on instructions on which printer it needs to print with. - if not writer: + if not mesh_format.is_valid: Logger.log("e", "Missing file or mesh writer!") return - self._sending_job = self._sendPrintJob(writer, preferred_format, nodes) + self._sending_job = self._sendPrintJob(mesh_format, nodes) if self._sending_job is not None: self._sending_job.send(None) # Start the generator. @@ -150,11 +148,8 @@ class ClusterUM3OutputDevice(BaseCuraConnectDevice): # greenlet in order to optionally wait for selectPrinter() to select a # printer. # The greenlet yields exactly three times: First time None, - # \param writer The file writer to use to create the data. - # \param preferred_format A dictionary containing some information about - # what format to write to. This is necessary to create the correct buffer - # types and file extension and such. - def _sendPrintJob(self, writer: FileWriter, preferred_format: Dict, nodes: List[SceneNode]): + # \param mesh_format Object responsible for choosing the right kind of format to write with. + def _sendPrintJob(self, mesh_format: MeshFormatHandler, nodes: List[SceneNode]): Logger.log("i", "Sending print job to printer.") if self._sending_gcode: self._error_message = Message( @@ -172,17 +167,17 @@ class ClusterUM3OutputDevice(BaseCuraConnectDevice): # Using buffering greatly reduces the write time for many lines of gcode - stream = io.BytesIO() # type: Union[io.BytesIO, io.StringIO]# Binary mode. - if preferred_format["mode"] == FileWriter.OutputMode.TextMode: - stream = io.StringIO() + stream = mesh_format.createStream() - job = WriteFileJob(writer, stream, nodes, preferred_format["mode"]) + job = WriteFileJob(mesh_format.writer, stream, nodes, mesh_format.file_mode) - self._write_job_progress_message = Message(i18n_catalog.i18nc("@info:status", "Sending data to printer"), lifetime = 0, dismissable = False, progress = -1, - title = i18n_catalog.i18nc("@info:title", "Sending Data"), use_inactivity_timer = False) + self._write_job_progress_message = Message(i18n_catalog.i18nc("@info:status", "Sending data to printer"), + lifetime = 0, dismissable = False, progress = -1, + title = i18n_catalog.i18nc("@info:title", "Sending Data"), + use_inactivity_timer = False) self._write_job_progress_message.show() - self._dummy_lambdas = (target_printer, preferred_format, stream) + self._dummy_lambdas = (target_printer, mesh_format.preferred_format, stream) job.finished.connect(self._sendPrintJobWaitOnWriteJobFinished) job.start() @@ -194,9 +189,11 @@ class ClusterUM3OutputDevice(BaseCuraConnectDevice): if self._write_job_progress_message: self._write_job_progress_message.hide() - self._progress_message = Message(i18n_catalog.i18nc("@info:status", "Sending data to printer"), lifetime = 0, dismissable = False, progress = -1, + self._progress_message = Message(i18n_catalog.i18nc("@info:status", "Sending data to printer"), lifetime = 0, + dismissable = False, progress = -1, title = i18n_catalog.i18nc("@info:title", "Sending Data")) - self._progress_message.addAction("Abort", i18n_catalog.i18nc("@action:button", "Cancel"), icon = None, description = "") + self._progress_message.addAction("Abort", i18n_catalog.i18nc("@action:button", "Cancel"), icon = None, + description = "") self._progress_message.actionTriggered.connect(self._progressMessageActionTriggered) self._progress_message.show() parts = [] @@ -220,7 +217,9 @@ class ClusterUM3OutputDevice(BaseCuraConnectDevice): parts.append(self._createFormPart("name=\"file\"; filename=\"%s\"" % file_name, output)) - self._latest_reply_handler = self.postFormWithParts("print_jobs/", parts, on_finished = self._onPostPrintJobFinished, on_progress = self._onUploadPrintJobProgress) + self._latest_reply_handler = self.postFormWithParts("print_jobs/", parts, + on_finished = self._onPostPrintJobFinished, + on_progress = self._onUploadPrintJobProgress) @pyqtProperty(QObject, notify = activePrinterChanged) def activePrinter(self) -> Optional[PrinterOutputModel]: diff --git a/plugins/UM3NetworkPrinting/src/BaseCuraConnectDevice.py b/plugins/UM3NetworkPrinting/src/MeshFormatHandler.py similarity index 50% rename from plugins/UM3NetworkPrinting/src/BaseCuraConnectDevice.py rename to plugins/UM3NetworkPrinting/src/MeshFormatHandler.py index 0abf5955cf..c2bd997fbb 100644 --- a/plugins/UM3NetworkPrinting/src/BaseCuraConnectDevice.py +++ b/plugins/UM3NetworkPrinting/src/MeshFormatHandler.py @@ -1,15 +1,16 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import Optional, Dict, Union +import io +from typing import Optional, Dict, Union, List from UM.FileHandler.FileHandler import FileHandler from UM.FileHandler.FileWriter import FileWriter from UM.Logger import Logger from UM.OutputDevice import OutputDeviceError # To show that something went wrong when writing. +from UM.Scene.SceneNode import SceneNode from UM.Version import Version # To check against firmware versions for support. from UM.i18n import i18nCatalog from cura.CuraApplication import CuraApplication -from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice ## Class that contains all the translations for this module. @@ -20,24 +21,63 @@ class T: NO_FORMATS_AVAILABLE = _I18N_CATALOG.i18nc("@info:status", "There are no file formats available to write with!") -## This is the base class for the UM3 output devices (via connect or cloud) -class BaseCuraConnectDevice(NetworkedPrinterOutputDevice): +## This class is responsible for choosing the formats used by the connected clusters. +class MeshFormatHandler: + + def __init__(self, file_handler: Optional[FileHandler], firmware_version: str) -> None: + self._file_handler = file_handler or CuraApplication.getInstance().getMeshFileHandler() + self._preferred_format = self._getPreferredFormat(firmware_version) + self._writer = self._getWriter(self._preferred_format["mime_type"]) if self._preferred_format else None - ## Gets the default file handler @property - def defaultFileHandler(self) -> FileHandler: - return CuraApplication.getInstance().getMeshFileHandler() + def is_valid(self) -> bool: + return bool(self._writer) + + ## Chooses the preferred file format. + # \return A dict with the file format details, with the following keys: + # {id: str, extension: str, description: str, mime_type: str, mode: int, hide_in_file_dialog: bool} + @property + def preferred_format(self) -> Optional[Dict[str, Union[str, int, bool]]]: + return self._preferred_format + + ## Gets the file writer for the given file handler and mime type. + # \return A file writer. + @property + def writer(self) -> Optional[FileWriter]: + return self._writer + + @property + def mime_type(self) -> str: + return self._preferred_format["mime_type"] + + ## Gets the file mode (FileWriter.OutputMode.TextMode or FileWriter.OutputMode.BinaryMode) + @property + def file_mode(self) -> int: + return self._preferred_format["mode"] + + ## Gets the file extension + @property + def file_extension(self) -> str: + return self._preferred_format["extension"] + + ## Creates the right kind of stream based on the preferred format. + def createStream(self) -> Union[io.BytesIO, io.StringIO]: + return io.StringIO() if self.file_mode == FileWriter.OutputMode.TextMode else io.BytesIO() + + ## Writes the mesh and returns its value. + def getBytes(self, nodes: List[SceneNode]) -> bytes: + stream = self.createStream() + self.writer.write(stream, nodes) + return stream.getvalue() ## Chooses the preferred file format for the given file handler. - # \param file_handler: The file handler. - # \return A dict with the file format details, with format: - # {id: str, extension: str, description: str, mime_type: str, mode: int, hide_in_file_dialog: bool} - def _getPreferredFormat(self, file_handler: Optional[FileHandler]) -> Optional[Dict[str, Union[str, int, bool]]]: + # \param firmware_version: The version of the firmware. + # \return A dict with the file format details. + def _getPreferredFormat(self, firmware_version: str) -> Optional[Dict[str, Union[str, int, bool]]]: # Formats supported by this application (file types that we can actually write). application = CuraApplication.getInstance() - file_handler = file_handler or self.defaultFileHandler - file_formats = file_handler.getSupportedFileTypesWrite() + file_formats = self._file_handler.getSupportedFileTypesWrite() global_stack = application.getGlobalContainerStack() # Create a list from the supported file formats string. @@ -48,7 +88,7 @@ class BaseCuraConnectDevice(NetworkedPrinterOutputDevice): machine_file_formats = global_stack.getMetaDataEntry("file_formats").split(";") machine_file_formats = [file_type.strip() for file_type in machine_file_formats] # Exception for UM3 firmware version >=4.4: UFP is now supported and should be the preferred file format. - if "application/x-ufp" not in machine_file_formats and Version(self.firmwareVersion) >= Version("4.4"): + if "application/x-ufp" not in machine_file_formats and Version(firmware_version) >= Version("4.4"): machine_file_formats = ["application/x-ufp"] + machine_file_formats # Take the intersection between file_formats and machine_file_formats. @@ -63,10 +103,8 @@ class BaseCuraConnectDevice(NetworkedPrinterOutputDevice): return file_formats[0] ## Gets the file writer for the given file handler and mime type. - # \param file_handler: The file handler. # \param mime_type: The mine type. # \return A file writer. - def _getWriter(self, file_handler: Optional[FileHandler], mime_type: str) -> Optional[FileWriter]: + def _getWriter(self, mime_type: str) -> Optional[FileWriter]: # Just take the first file format available. - file_handler = file_handler or self.defaultFileHandler - return file_handler.getWriterByMimeType(mime_type) + return self._file_handler.getWriterByMimeType(mime_type) From e8a933331c0be8ce2086a26a982ee220282001d7 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Wed, 5 Dec 2018 12:14:18 +0100 Subject: [PATCH 0690/1292] Clean-up printer status label Contributes to CL-1153 --- .../resources/qml/MonitorPrinterCard.qml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml index 8659037cb8..567fff8489 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml @@ -179,13 +179,15 @@ Item color: "#414054" // TODO: Theme! font: UM.Theme.getFont("large") // 16pt, bold text: { - if (printer && printer.state == "disabled"){ + if (printer && printer.state == "disabled") + { return catalog.i18nc("@label:status", "Unavailable") } - if (printer && printer.state == "unreachable"){ - return catalog.i18nc("@label:status", "Unavailable") + if (printer && printer.state == "unreachable") + { + return catalog.i18nc("@label:status", "Unreachable") } - if (printer && !printer.activePrintJob) + if (printer && printer.state == "idle") { return catalog.i18nc("@label:status", "Idle") } From 034b1660f766211bd658127e28f0dd35809c2f6b Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 5 Dec 2018 13:05:22 +0100 Subject: [PATCH 0691/1292] Adjust sizes in the custom print setup mode Contributes to CURA-5941. --- .../qml/PrintSetupSelector/Custom/CustomPrintSetup.qml | 9 +++------ .../PrintSetupSelector/PrintSetupSelectorContents.qml | 8 ++++---- resources/themes/cura-light/theme.json | 2 +- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml index b524bb5926..8b0f3524d7 100644 --- a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml +++ b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml @@ -11,9 +11,7 @@ import Cura 1.0 as Cura Item { id: customPrintSetup - - // TODO: Hardcoded now but UX has to decide about the height of this item - height: 480 + height: childrenRect.height + padding property real padding: UM.Theme.getSize("default_margin").width property bool multipleExtruders: extrudersModel.count > 1 @@ -93,16 +91,15 @@ Item Rectangle { + height: UM.Theme.getSize("print_setup_widget").height anchors { - top: tabBar.visible ? tabBar.bottom : globalProfileRow.bottom + top: tabBar.bottom left: parent.left leftMargin: parent.padding right: parent.right rightMargin: parent.padding - bottom: parent.bottom topMargin: -UM.Theme.getSize("default_lining").width - bottomMargin: -UM.Theme.getSize("default_lining").width } z: tabBar.z - 1 // Don't show the border when only one extruder diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml index 0524a6de9e..522b038423 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml @@ -28,7 +28,7 @@ Item { var index = Math.round(UM.Preferences.getValue("cura/active_mode")) - if(index != null && !isNaN(index)) + if (index != null && !isNaN(index)) { return index } @@ -150,7 +150,8 @@ Item { id: buttonsSeparator - anchors.top: contents.bottom + // The buttonsSeparator is inside the contents. This is to avoid a double line in the bottom + anchors.bottom: contents.bottom width: parent.width height: UM.Theme.getSize("default_lining").height color: UM.Theme.getColor("lining") @@ -162,10 +163,9 @@ Item property real padding: UM.Theme.getSize("default_margin").width height: childrenRect.height + 2 * padding - // The buttonsSeparator is inside the buttonRow. This is to avoid some weird behaviours with the scroll bar. anchors { - top: buttonsSeparator.top + top: buttonsSeparator.bottom left: parent.left right: parent.right } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 8e440757aa..f383a570a2 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -369,7 +369,7 @@ "account_button": [12, 3], - "print_setup_widget": [38.0, 42.0], + "print_setup_widget": [38.0, 30.0], "print_setup_mode_toggle": [0.0, 2.0], "print_setup_item": [0.0, 2.0], "print_setup_extruder_box": [0.0, 6.0], From b1440737e641a708683c06ea12c7874dd3fb8ab7 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 5 Dec 2018 13:21:17 +0100 Subject: [PATCH 0692/1292] Remove a whole bunch of unused code CURA-6006 --- plugins/Toolbox/src/AuthorsModel.py | 2 +- plugins/Toolbox/src/Toolbox.py | 70 +++++++++-------------------- 2 files changed, 22 insertions(+), 50 deletions(-) diff --git a/plugins/Toolbox/src/AuthorsModel.py b/plugins/Toolbox/src/AuthorsModel.py index 6f4b5bd280..8fafda54ec 100644 --- a/plugins/Toolbox/src/AuthorsModel.py +++ b/plugins/Toolbox/src/AuthorsModel.py @@ -73,7 +73,7 @@ class AuthorsModel(ListModel): self._filter = filter_dict self._update() - @pyqtProperty("QStringMap", fset = setFilter, constant = True) + @pyqtProperty("QVariantMap", fset = setFilter, constant = True) def filter(self) -> Dict[str, str]: return self._filter diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index b6cfafe40c..5db3dd934f 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -70,13 +70,6 @@ class Toolbox(QObject, Extension): self._metadata = { "authors": [], "packages": [], - "plugins_showcase": [], - "plugins_available": [], - "plugins_installed": [], - "materials_showcase": [], - "materials_available": [], - "materials_installed": [], - "materials_generic": [] } # type: Dict[str, List[Any]] # Models: @@ -178,12 +171,7 @@ class Toolbox(QObject, Extension): ) self._request_urls = { "authors": QUrl("{base_url}/authors".format(base_url = self._api_url)), - "packages": QUrl("{base_url}/packages".format(base_url = self._api_url)), - "plugins_showcase": QUrl("{base_url}/showcase".format(base_url = self._api_url)), - "plugins_available": QUrl("{base_url}/packages?package_type=plugin".format(base_url = self._api_url)), - "materials_showcase": QUrl("{base_url}/showcase".format(base_url = self._api_url)), - "materials_available": QUrl("{base_url}/packages?package_type=material".format(base_url = self._api_url)), - "materials_generic": QUrl("{base_url}/packages?package_type=material&tags=generic".format(base_url = self._api_url)) + "packages": QUrl("{base_url}/packages".format(base_url = self._api_url)) } # Get the API root for the packages API depending on Cura version settings. @@ -606,8 +594,8 @@ class Toolbox(QObject, Extension): if self._download_reply: try: self._download_reply.downloadProgress.disconnect(self._onDownloadProgress) - except TypeError: #Raised when the method is not connected to the signal yet. - pass #Don't need to disconnect. + except TypeError: # Raised when the method is not connected to the signal yet. + pass # Don't need to disconnect. self._download_reply.abort() self._download_reply = None self._download_request = None @@ -633,22 +621,8 @@ class Toolbox(QObject, Extension): self.resetDownload() return - # HACK: These request are not handled independently at this moment, but together from the "packages" call - do_not_handle = [ - "materials_available", - "materials_showcase", - "materials_generic", - "plugins_available", - "plugins_showcase", - ] - if reply.operation() == QNetworkAccessManager.GetOperation: for response_type, url in self._request_urls.items(): - - # HACK: Do nothing because we'll handle these from the "packages" call - if response_type in do_not_handle: - continue - if reply.url() == url: if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) == 200: try: @@ -672,11 +646,10 @@ class Toolbox(QObject, Extension): # TODO: Make multiple API calls in the future to handle this if response_type is "packages": self._models[response_type].setFilter({"type": "plugin"}) - self.buildMaterialsModels() + self.reBuildMaterialsModels() self.buildPluginsModels() - if response_type is "authors": + elif response_type is "authors": self._models[response_type].setFilter({"package_types": "material"}) - if response_type is "materials_generic": self._models[response_type].setFilter({"tags": "generic"}) self.metadataChanged.emit() @@ -834,10 +807,10 @@ class Toolbox(QObject, Extension): # HACK(S): # -------------------------------------------------------------------------- - def buildMaterialsModels(self) -> None: - self._metadata["materials_showcase"] = [] - self._metadata["materials_available"] = [] - self._metadata["materials_generic"] = [] + def reBuildMaterialsModels(self) -> None: + materials_showcase_metadata = [] + materials_available_metadata = [] + materials_generic_metadata = [] processed_authors = [] # type: List[str] @@ -850,30 +823,29 @@ class Toolbox(QObject, Extension): # Generic materials to be in the same section if "generic" in item["tags"]: - self._metadata["materials_generic"].append(item) + materials_generic_metadata.append(item) else: if "showcase" in item["tags"]: - self._metadata["materials_showcase"].append(author) + materials_showcase_metadata.append(author) else: - self._metadata["materials_available"].append(author) + materials_available_metadata.append(author) processed_authors.append(author["author_id"]) - self._models["materials_showcase"].setMetadata(self._metadata["materials_showcase"]) - self._models["materials_available"].setMetadata(self._metadata["materials_available"]) - self._models["materials_generic"].setMetadata(self._metadata["materials_generic"]) + self._models["materials_showcase"].setMetadata(materials_showcase_metadata) + self._models["materials_available"].setMetadata(materials_available_metadata) + self._models["materials_generic"].setMetadata(materials_generic_metadata) def buildPluginsModels(self) -> None: - self._metadata["plugins_showcase"] = [] - self._metadata["plugins_available"] = [] + plugins_showcase_metadata = [] + plugins_available_metadata = [] for item in self._metadata["packages"]: if item["package_type"] == "plugin": - if "showcase" in item["tags"]: - self._metadata["plugins_showcase"].append(item) + plugins_showcase_metadata.append(item) else: - self._metadata["plugins_available"].append(item) + plugins_available_metadata.append(item) - self._models["plugins_showcase"].setMetadata(self._metadata["plugins_showcase"]) - self._models["plugins_available"].setMetadata(self._metadata["plugins_available"]) + self._models["plugins_showcase"].setMetadata(plugins_showcase_metadata) + self._models["plugins_available"].setMetadata(plugins_available_metadata) From 5b57e6bf307eb2060b6c386c054401ab0625a779 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 5 Dec 2018 13:24:34 +0100 Subject: [PATCH 0693/1292] Code style in JobSpecs --- resources/qml/JobSpecs.qml | 82 +++++++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 33 deletions(-) diff --git a/resources/qml/JobSpecs.qml b/resources/qml/JobSpecs.qml index 45111992c1..5f773f9b25 100644 --- a/resources/qml/JobSpecs.qml +++ b/resources/qml/JobSpecs.qml @@ -9,20 +9,27 @@ import QtQuick.Layouts 1.1 import UM 1.1 as UM import Cura 1.0 as Cura -Item { +Item +{ id: base property bool activity: CuraApplication.platformActivity property string fileBaseName: PrintInformation.baseName - UM.I18nCatalog { id: catalog; name: "cura"} + UM.I18nCatalog + { + id: catalog + name:"cura" + } height: childrenRect.height - onActivityChanged: { - if (activity == false) { + onActivityChanged: + { + if (!activity) + { //When there is no mesh in the buildplate; the printJobTextField is set to an empty string so it doesn't set an empty string as a jobName (which is later used for saving the file) - PrintInformation.baseName = '' + PrintInformation.baseName = "" } } @@ -49,21 +56,22 @@ Item { onClicked: { - printJobTextfield.selectAll(); - printJobTextfield.focus = true; + printJobTextfield.selectAll() + printJobTextfield.focus = true } + style: ButtonStyle { background: Item { UM.RecolorImage { - width: UM.Theme.getSize("save_button_specs_icons").width; - height: UM.Theme.getSize("save_button_specs_icons").height; - sourceSize.width: width; - sourceSize.height: width; - color: control.hovered ? UM.Theme.getColor("text_scene_hover") : UM.Theme.getColor("text_scene"); - source: UM.Theme.getIcon("pencil"); + width: UM.Theme.getSize("save_button_specs_icons").width + height: UM.Theme.getSize("save_button_specs_icons").height + sourceSize.width: width + sourceSize.height: width + color: control.hovered ? UM.Theme.getColor("text_scene_hover") : UM.Theme.getColor("text_scene") + source: UM.Theme.getIcon("pencil") } } } @@ -73,25 +81,31 @@ Item { { id: printJobTextfield anchors.right: printJobPencilIcon.left - anchors.rightMargin: Math.round(UM.Theme.getSize("default_margin").width / 2) + anchors.rightMargin: UM.Theme.getSize("narrow_margin").width height: UM.Theme.getSize("jobspecs_line").height width: Math.max(__contentWidth + UM.Theme.getSize("default_margin").width, 50) maximumLength: 120 property int unremovableSpacing: 5 text: PrintInformation.jobName horizontalAlignment: TextInput.AlignRight - onEditingFinished: { - var new_name = text == "" ? catalog.i18nc("@text Print job name", "Untitled") : text; - PrintInformation.setJobName(new_name, true); - printJobTextfield.focus = false; + + onEditingFinished: + { + var new_name = text == "" ? catalog.i18nc("@text Print job name", "Untitled") : text + PrintInformation.setJobName(new_name, true) + printJobTextfield.focus = false } + validator: RegExpValidator { regExp: /^[^\\\/\*\?\|\[\]]*$/ } - style: TextFieldStyle{ - textColor: UM.Theme.getColor("text_scene"); - font: UM.Theme.getFont("default_bold"); - background: Rectangle { + + style: TextFieldStyle + { + textColor: UM.Theme.getColor("text_scene") + font: UM.Theme.getFont("default_bold") + background: Rectangle + { opacity: 0 border.width: 0 } @@ -100,7 +114,8 @@ Item { } } - Row { + Row + { id: additionalComponentsRow anchors.top: jobNameRow.bottom anchors.right: parent.right @@ -117,10 +132,7 @@ Item { { return UM.Theme.getSize("default_margin").width } - else - { - return 0; - } + return 0 } height: UM.Theme.getSize("jobspecs_line").height verticalAlignment: Text.AlignVCenter @@ -129,21 +141,25 @@ Item { text: CuraApplication.getSceneBoundingBoxString } - Component.onCompleted: { + Component.onCompleted: + { base.addAdditionalComponents("jobSpecsButton") } - Connections { + Connections + { target: CuraApplication onAdditionalComponentsChanged: base.addAdditionalComponents("jobSpecsButton") } - function addAdditionalComponents (areaId) { - if(areaId == "jobSpecsButton") { - for (var component in CuraApplication.additionalComponents["jobSpecsButton"]) { + function addAdditionalComponents (areaId) + { + if (areaId == "jobSpecsButton") + { + for (var component in CuraApplication.additionalComponents["jobSpecsButton"]) + { CuraApplication.additionalComponents["jobSpecsButton"][component].parent = additionalComponentsRow } } } - } From 0e22f6b672a29c8b57309332a1f77355f151f870 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 5 Dec 2018 13:30:01 +0100 Subject: [PATCH 0694/1292] Fix an issue that caused a non-deterministic segfault Also add a topMargin only when there are tabs in the custom print setup. Contributes to CURA-5941. --- .../Custom/CustomPrintSetup.qml | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml index 8b0f3524d7..b28c9ceb46 100644 --- a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml +++ b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml @@ -52,8 +52,6 @@ Item rightMargin: parent.padding } - currentIndex: Math.max(Cura.ExtruderManager.activeExtruderIndex, 0) - Repeater { id: repeater @@ -76,15 +74,27 @@ Item } } - // When the model of the extruders is rebuilt, the list of extruders is briefly emptied and rebuilt. - // This causes the currentIndex of the tab to be in an invalid position which resets it to 0. - // Therefore we need to change it back to what it was: The active extruder index. + //When active extruder changes for some other reason, switch tabs. + //Don't directly link currentIndex to Cura.ExtruderManager.activeExtruderIndex! + //This causes a segfault in Qt 5.11. Something with VisualItemModel removing index -1. We have to use setCurrentIndex instead. + Connections + { + target: Cura.ExtruderManager + onActiveExtruderChanged: + { + tabBar.setCurrentIndex(Cura.ExtruderManager.activeExtruderIndex); + } + } + + //When the model of the extruders is rebuilt, the list of extruders is briefly emptied and rebuilt. + //This causes the currentIndex of the tab to be in an invalid position which resets it to 0. + //Therefore we need to change it back to what it was: The active extruder index. Connections { target: repeater.model onModelChanged: { - tabBar.currentIndex = Math.max(Cura.ExtruderManager.activeExtruderIndex, 0) + tabBar.setCurrentIndex(Cura.ExtruderManager.activeExtruderIndex) } } } @@ -94,7 +104,7 @@ Item height: UM.Theme.getSize("print_setup_widget").height anchors { - top: tabBar.bottom + top: tabBar.visible ? tabBar.bottom : globalProfileRow.bottom left: parent.left leftMargin: parent.padding right: parent.right From 07d210483c91d77c3198548a386247fdc993df2f Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 5 Dec 2018 13:42:13 +0100 Subject: [PATCH 0695/1292] Greatly decrease the bloat / complexity of the toolbox There was a lot of stuff going on that didn't need to happen, so I cut those parts out in order to improve the overview. --- plugins/Toolbox/src/AuthorsModel.py | 5 +-- plugins/Toolbox/src/PackagesModel.py | 5 +-- plugins/Toolbox/src/Toolbox.py | 54 ++++++++++++++-------------- 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/plugins/Toolbox/src/AuthorsModel.py b/plugins/Toolbox/src/AuthorsModel.py index 8fafda54ec..877f8256ee 100644 --- a/plugins/Toolbox/src/AuthorsModel.py +++ b/plugins/Toolbox/src/AuthorsModel.py @@ -29,8 +29,9 @@ class AuthorsModel(ListModel): self._filter = {} # type: Dict[str, str] def setMetadata(self, data: List[Dict[str, Union[str, List[str], int]]]): - self._metadata = data - self._update() + if self._metadata != data: + self._metadata = data + self._update() def _update(self) -> None: items = [] # type: List[Dict[str, Union[str, List[str], int, None]]] diff --git a/plugins/Toolbox/src/PackagesModel.py b/plugins/Toolbox/src/PackagesModel.py index 2849a29c99..f941804653 100644 --- a/plugins/Toolbox/src/PackagesModel.py +++ b/plugins/Toolbox/src/PackagesModel.py @@ -45,8 +45,9 @@ class PackagesModel(ListModel): self._filter = {} # type: Dict[str, str] def setMetadata(self, data): - self._metadata = data - self._update() + if self._metadata != data: + self._metadata = data + self._update() def _update(self): items = [] diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 5db3dd934f..7b1442ff3c 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -66,8 +66,8 @@ class Toolbox(QObject, Extension): self._old_plugin_ids = set() # type: Set[str] self._old_plugin_metadata = dict() # type: Dict[str, Dict[str, Any]] - # Data: - self._metadata = { + # The responses as given by the server parsed to a list. + self._server_response_data = { "authors": [], "packages": [], } # type: Dict[str, List[Any]] @@ -301,13 +301,13 @@ class Toolbox(QObject, Extension): if plugin_id not in all_plugin_package_ids) self._old_plugin_metadata = {k: v for k, v in self._old_plugin_metadata.items() if k in self._old_plugin_ids} - self._metadata["plugins_installed"] = all_packages["plugin"] + list(self._old_plugin_metadata.values()) - self._models["plugins_installed"].setMetadata(self._metadata["plugins_installed"]) + self._server_response_data["plugins_installed"] = all_packages["plugin"] + list(self._old_plugin_metadata.values()) + self._models["plugins_installed"].setMetadata(self._server_response_data["plugins_installed"]) self.metadataChanged.emit() if "material" in all_packages: - self._metadata["materials_installed"] = all_packages["material"] + self._server_response_data["materials_installed"] = all_packages["material"] # TODO: ADD MATERIALS HERE ONCE MATERIALS PORTION OF TOOLBOX IS LIVE - self._models["materials_installed"].setMetadata(self._metadata["materials_installed"]) + self._models["materials_installed"].setMetadata(self._server_response_data["materials_installed"]) self.metadataChanged.emit() @pyqtSlot(str) @@ -461,7 +461,7 @@ class Toolbox(QObject, Extension): def getRemotePackage(self, package_id: str) -> Optional[Dict]: # TODO: make the lookup in a dict, not a loop. canUpdate is called for every item. remote_package = None - for package in self._metadata["packages"]: + for package in self._server_response_data["packages"]: if package["package_id"] == package_id: remote_package = package break @@ -524,7 +524,7 @@ class Toolbox(QObject, Extension): @pyqtSlot(str, result = int) def getNumberOfInstalledPackagesByAuthor(self, author_id: str) -> int: count = 0 - for package in self._metadata["materials_installed"]: + for package in self._server_response_data["materials_installed"]: if package["author"]["author_id"] == author_id: count += 1 return count @@ -533,7 +533,7 @@ class Toolbox(QObject, Extension): @pyqtSlot(str, result = int) def getTotalNumberOfMaterialPackagesByAuthor(self, author_id: str) -> int: count = 0 - for package in self._metadata["packages"]: + for package in self._server_response_data["packages"]: if package["package_type"] == "material": if package["author"]["author_id"] == author_id: count += 1 @@ -554,10 +554,10 @@ class Toolbox(QObject, Extension): def isLoadingComplete(self) -> bool: populated = 0 - for metadata_list in self._metadata.items(): + for metadata_list in self._server_response_data.items(): if metadata_list: populated += 1 - return populated == len(self._metadata.items()) + return populated == len(self._server_response_data.items()) # Make API Calls # -------------------------------------------------------------------------- @@ -639,15 +639,13 @@ class Toolbox(QObject, Extension): Logger.log("e", "Could not find the %s model.", response_type) break - self._metadata[response_type] = json_data["data"] - self._models[response_type].setMetadata(self._metadata[response_type]) + self._server_response_data[response_type] = json_data["data"] + self._models[response_type].setMetadata(self._server_response_data[response_type]) - # Do some auto filtering - # TODO: Make multiple API calls in the future to handle this if response_type is "packages": self._models[response_type].setFilter({"type": "plugin"}) self.reBuildMaterialsModels() - self.buildPluginsModels() + self.reBuildPluginsModels() elif response_type is "authors": self._models[response_type].setFilter({"package_types": "material"}) self._models[response_type].setFilter({"tags": "generic"}) @@ -743,39 +741,39 @@ class Toolbox(QObject, Extension): # Exposed Models: # -------------------------------------------------------------------------- - @pyqtProperty(QObject, notify = metadataChanged) + @pyqtProperty(QObject, constant=True) def authorsModel(self) -> AuthorsModel: return cast(AuthorsModel, self._models["authors"]) - @pyqtProperty(QObject, notify = metadataChanged) + @pyqtProperty(QObject, constant=True) def packagesModel(self) -> PackagesModel: return cast(PackagesModel, self._models["packages"]) - @pyqtProperty(QObject, notify = metadataChanged) + @pyqtProperty(QObject, constant=True) def pluginsShowcaseModel(self) -> PackagesModel: return cast(PackagesModel, self._models["plugins_showcase"]) - @pyqtProperty(QObject, notify = metadataChanged) + @pyqtProperty(QObject, constant=True) def pluginsAvailableModel(self) -> PackagesModel: return cast(PackagesModel, self._models["plugins_available"]) - @pyqtProperty(QObject, notify = metadataChanged) + @pyqtProperty(QObject, constant=True) def pluginsInstalledModel(self) -> PackagesModel: return cast(PackagesModel, self._models["plugins_installed"]) - @pyqtProperty(QObject, notify = metadataChanged) + @pyqtProperty(QObject, constant=True) def materialsShowcaseModel(self) -> AuthorsModel: return cast(AuthorsModel, self._models["materials_showcase"]) - @pyqtProperty(QObject, notify = metadataChanged) + @pyqtProperty(QObject, constant=True) def materialsAvailableModel(self) -> AuthorsModel: return cast(AuthorsModel, self._models["materials_available"]) - @pyqtProperty(QObject, notify = metadataChanged) + @pyqtProperty(QObject, constant=True) def materialsInstalledModel(self) -> PackagesModel: return cast(PackagesModel, self._models["materials_installed"]) - @pyqtProperty(QObject, notify=metadataChanged) + @pyqtProperty(QObject, constant=True) def materialsGenericModel(self) -> PackagesModel: return cast(PackagesModel, self._models["materials_generic"]) @@ -814,7 +812,7 @@ class Toolbox(QObject, Extension): processed_authors = [] # type: List[str] - for item in self._metadata["packages"]: + for item in self._server_response_data["packages"]: if item["package_type"] == "material": author = item["author"] @@ -836,11 +834,11 @@ class Toolbox(QObject, Extension): self._models["materials_available"].setMetadata(materials_available_metadata) self._models["materials_generic"].setMetadata(materials_generic_metadata) - def buildPluginsModels(self) -> None: + def reBuildPluginsModels(self) -> None: plugins_showcase_metadata = [] plugins_available_metadata = [] - for item in self._metadata["packages"]: + for item in self._server_response_data["packages"]: if item["package_type"] == "plugin": if "showcase" in item["tags"]: plugins_showcase_metadata.append(item) From 7d7dd6bdde7738e3b8e56a879e07a535557eaad6 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Wed, 5 Dec 2018 14:02:53 +0100 Subject: [PATCH 0696/1292] First idea for pairing local and remote clusters --- .../src/Cloud/CloudOutputDeviceManager.py | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 0fbeeb82b6..9405ea8490 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -77,13 +77,15 @@ class CloudOutputDeviceManager: for cluster_id in known_cluster_ids.difference(found_cluster_ids): self._removeCloudOutputDevice(found_clusters[cluster_id]) + # TODO: not pass clusters that are not online? + self._connectToActiveMachine(clusters) + ## Adds a CloudOutputDevice for each entry in the remote cluster list from the API. # \param cluster: The cluster that was added. def _addCloudOutputDevice(self, cluster: CloudCluster): device = CloudOutputDevice(self._api, cluster.cluster_id) self._output_device_manager.addOutputDevice(device) self._remote_clusters[cluster.cluster_id] = device - self._connectToActiveMachine(cluster.cluster_id) ## Remove a CloudOutputDevice # \param cluster: The cluster that was removed @@ -93,28 +95,28 @@ class CloudOutputDeviceManager: del self._remote_clusters[cluster.cluster_id] ## Callback for when the active machine was changed by the user or a new remote cluster was found. - def _connectToActiveMachine(self, cluster_id: Optional[str] = None) -> None: + def _connectToActiveMachine(self, clusters: List[CloudCluster]) -> None: active_machine = CuraApplication.getInstance().getGlobalContainerStack() if not active_machine: return - # TODO: Remove this once correct pairing has been added (see below). - # TODO: This just adds any available cluster to the active device for testing. - if cluster_id: - active_machine.setMetaDataEntry("um_cloud_cluster_id", cluster_id) - # Check if the stored cluster_id for the active machine is in our list of remote clusters. stored_cluster_id = active_machine.getMetaDataEntry("um_cloud_cluster_id") if stored_cluster_id in self._remote_clusters.keys(): - self._remote_clusters.get(stored_cluster_id).connect() + return self._remote_clusters.get(stored_cluster_id).connect() + + # Check if the active printer has a local network connection and match this key to the remote cluster. + # The local network key is formatted as ultimakersystem-xxxxxxxxxxxx._ultimaker._tcp.local. + # The optional remote host_name is formatted as ultimakersystem-xxxxxxxxxxxx. + # This means we can match the two by checking if the host_name is in the network key string. + + local_network_key = active_machine.getMetaDataEntry("um_network_key") + if not local_network_key: return - # TODO: See if this cloud cluster still has to be associated to the active machine. - # TODO: We have to get a common piece of data, like local network hostname, from the active machine and - # TODO: cloud cluster and then set the "um_cloud_cluster_id" meta data key on the active machine. - # TODO: If so, we can also immediate connect to it. - # active_machine.setMetaDataEntry("um_cloud_cluster_id", "") - # self._remote_clusters.get(stored_cluster_id).connect() + cluster_id = next(local_network_key in cluster.host_name for cluster in clusters) + if cluster_id in self._remote_clusters.keys(): + return self._remote_clusters.get(cluster_id).connect() ## Handles an API error received from the cloud. # \param errors: The errors received From a52f866f818324994b1a1b34f06805ffd3ed24d0 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 5 Dec 2018 14:03:32 +0100 Subject: [PATCH 0697/1292] Move most models out of dictionary CURA-6006 --- plugins/Toolbox/src/Toolbox.py | 47 ++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 7b1442ff3c..ada81dbc07 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -70,21 +70,25 @@ class Toolbox(QObject, Extension): self._server_response_data = { "authors": [], "packages": [], + "plugins_installed": [], + "materials_installed": [] } # type: Dict[str, List[Any]] # Models: self._models = { "authors": AuthorsModel(self), "packages": PackagesModel(self), - "plugins_showcase": PackagesModel(self), - "plugins_available": PackagesModel(self), - "plugins_installed": PackagesModel(self), - "materials_showcase": AuthorsModel(self), - "materials_available": AuthorsModel(self), - "materials_installed": PackagesModel(self), - "materials_generic": PackagesModel(self) } # type: Dict[str, ListModel] + self._plugins_showcase_model = PackagesModel(self) + self._plugins_available_model = PackagesModel(self) + self._plugins_installed_model = PackagesModel(self) + + self._materials_showcase_model = AuthorsModel(self) + self._materials_available_model = AuthorsModel(self) + self._materials_installed_model = PackagesModel(self) + self._materials_generic_model = PackagesModel(self) + # These properties are for keeping track of the UI state: # ---------------------------------------------------------------------- # View category defines which filter to use, and therefore effectively @@ -302,12 +306,11 @@ class Toolbox(QObject, Extension): self._old_plugin_metadata = {k: v for k, v in self._old_plugin_metadata.items() if k in self._old_plugin_ids} self._server_response_data["plugins_installed"] = all_packages["plugin"] + list(self._old_plugin_metadata.values()) - self._models["plugins_installed"].setMetadata(self._server_response_data["plugins_installed"]) + self._plugins_installed_model.setMetadata(self._server_response_data["plugins_installed"]) self.metadataChanged.emit() if "material" in all_packages: self._server_response_data["materials_installed"] = all_packages["material"] - # TODO: ADD MATERIALS HERE ONCE MATERIALS PORTION OF TOOLBOX IS LIVE - self._models["materials_installed"].setMetadata(self._server_response_data["materials_installed"]) + self._materials_installed_model.setMetadata(all_packages["material"]) self.metadataChanged.emit() @pyqtSlot(str) @@ -751,31 +754,31 @@ class Toolbox(QObject, Extension): @pyqtProperty(QObject, constant=True) def pluginsShowcaseModel(self) -> PackagesModel: - return cast(PackagesModel, self._models["plugins_showcase"]) + return self._plugins_showcase_model @pyqtProperty(QObject, constant=True) def pluginsAvailableModel(self) -> PackagesModel: - return cast(PackagesModel, self._models["plugins_available"]) + return self._plugins_available_model @pyqtProperty(QObject, constant=True) def pluginsInstalledModel(self) -> PackagesModel: - return cast(PackagesModel, self._models["plugins_installed"]) + return self._plugins_installed_model @pyqtProperty(QObject, constant=True) def materialsShowcaseModel(self) -> AuthorsModel: - return cast(AuthorsModel, self._models["materials_showcase"]) + return self._materials_showcase_model @pyqtProperty(QObject, constant=True) def materialsAvailableModel(self) -> AuthorsModel: - return cast(AuthorsModel, self._models["materials_available"]) + return self._materials_available_model @pyqtProperty(QObject, constant=True) def materialsInstalledModel(self) -> PackagesModel: - return cast(PackagesModel, self._models["materials_installed"]) + return self._materials_installed_model @pyqtProperty(QObject, constant=True) def materialsGenericModel(self) -> PackagesModel: - return cast(PackagesModel, self._models["materials_generic"]) + return self._materials_generic_model # Filter Models: # -------------------------------------------------------------------------- @@ -830,9 +833,9 @@ class Toolbox(QObject, Extension): processed_authors.append(author["author_id"]) - self._models["materials_showcase"].setMetadata(materials_showcase_metadata) - self._models["materials_available"].setMetadata(materials_available_metadata) - self._models["materials_generic"].setMetadata(materials_generic_metadata) + self._materials_showcase_model.setMetadata(materials_showcase_metadata) + self._materials_available_model.setMetadata(materials_available_metadata) + self._materials_generic_model.setMetadata(materials_generic_metadata) def reBuildPluginsModels(self) -> None: plugins_showcase_metadata = [] @@ -845,5 +848,5 @@ class Toolbox(QObject, Extension): else: plugins_available_metadata.append(item) - self._models["plugins_showcase"].setMetadata(plugins_showcase_metadata) - self._models["plugins_available"].setMetadata(plugins_available_metadata) + self._plugins_showcase_model.setMetadata(plugins_showcase_metadata) + self._plugins_available_model.setMetadata(plugins_available_metadata) From b693b9d98fa592ddde05f5049845b803fb0a405d Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 5 Dec 2018 14:08:40 +0100 Subject: [PATCH 0698/1292] STAR-322: Extracting models to be able for converting themselves --- __init__.py | 0 .../src/Cloud/CloudApiClient.py | 11 +- .../src/Cloud/CloudOutputDevice.py | 119 ++++---------- .../src/Cloud/CloudOutputDeviceManager.py | 5 +- .../UM3NetworkPrinting/src/Cloud/Models.py | 153 ------------------ .../src/Cloud/Models/CloudCluster.py | 21 +++ .../src/Cloud/Models/CloudClusterPrintJob.py | 52 ++++++ .../Models/CloudClusterPrintJobConstraint.py | 10 ++ .../src/Cloud/Models/CloudClusterPrinter.py | 44 +++++ .../CloudClusterPrinterConfiguration.py | 27 ++++ ...loudClusterPrinterConfigurationMaterial.py | 46 ++++++ .../src/Cloud/Models/CloudClusterStatus.py | 22 +++ .../src/Cloud/Models/CloudErrorObject.py | 17 ++ .../src/Cloud/Models/CloudJobResponse.py | 16 ++ .../src/Cloud/Models/CloudJobUploadRequest.py | 12 ++ .../src/Cloud/Models/CloudPrintResponse.py | 12 ++ .../src/Cloud/Models/__init__.py | 2 + .../src/ClusterUM3OutputDevice.py | 4 +- plugins/UM3NetworkPrinting/src/Models.py | 3 + .../tests/TestSendMaterialJob.py | 2 +- 20 files changed, 324 insertions(+), 254 deletions(-) create mode 100644 __init__.py delete mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Models.py create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Models/CloudCluster.py create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobConstraint.py create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinter.py create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfigurationMaterial.py create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterStatus.py create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Models/CloudErrorObject.py create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobResponse.py create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobUploadRequest.py create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintResponse.py create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Models/__init__.py diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py index d6c20d387b..3ede206d45 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py @@ -9,10 +9,13 @@ from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply from UM.Logger import Logger from cura.API import Account from cura.NetworkClient import NetworkClient -from plugins.UM3NetworkPrinting.src.Models import BaseModel -from plugins.UM3NetworkPrinting.src.Cloud.Models import ( - CloudCluster, CloudErrorObject, CloudClusterStatus, CloudJobUploadRequest, CloudPrintResponse, CloudJobResponse -) +from ..Models import BaseModel +from .Models.CloudCluster import CloudCluster +from .Models.CloudErrorObject import CloudErrorObject +from .Models.CloudClusterStatus import CloudClusterStatus +from .Models.CloudJobUploadRequest import CloudJobUploadRequest +from .Models.CloudPrintResponse import CloudPrintResponse +from .Models.CloudJobResponse import CloudJobResponse ## The cloud API client is responsible for handling the requests and responses from the cloud. diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 91f5721aa6..c6397fc41f 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -2,9 +2,9 @@ # Cura is released under the terms of the LGPLv3 or higher. import os from time import time -from typing import List, Optional, Dict, Set +from typing import Dict, List, Optional, Set -from PyQt5.QtCore import QObject, pyqtSignal, QUrl, pyqtProperty, pyqtSlot +from PyQt5.QtCore import QObject, QUrl, pyqtProperty, pyqtSignal, pyqtSlot from UM import i18nCatalog from UM.FileHandler.FileHandler import FileHandler @@ -12,18 +12,19 @@ from UM.Logger import Logger from UM.Message import Message from UM.Scene.SceneNode import SceneNode from cura.CuraApplication import CuraApplication -from cura.PrinterOutput.PrinterOutputController import PrinterOutputController -from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState, NetworkedPrinterOutputDevice +from cura.PrinterOutput.PrinterOutputController import PrinterOutputController from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel -from plugins.UM3NetworkPrinting.src.Cloud.CloudApiClient import CloudApiClient -from plugins.UM3NetworkPrinting.src.MeshFormatHandler import MeshFormatHandler -from plugins.UM3NetworkPrinting.src.UM3PrintJobOutputModel import UM3PrintJobOutputModel -from .Models import ( - CloudClusterPrinter, CloudClusterPrintJob, CloudJobUploadRequest, CloudJobResponse, CloudClusterStatus, - CloudClusterPrinterConfigurationMaterial, CloudErrorObject, - CloudPrintResponse -) +from ..MeshFormatHandler import MeshFormatHandler +from ..UM3PrintJobOutputModel import UM3PrintJobOutputModel +from .CloudApiClient import CloudApiClient +from .Models.CloudErrorObject import CloudErrorObject +from .Models.CloudClusterStatus import CloudClusterStatus +from .Models.CloudJobUploadRequest import CloudJobUploadRequest +from .Models.CloudPrintResponse import CloudPrintResponse +from .Models.CloudJobResponse import CloudJobResponse +from .Models.CloudClusterPrinter import CloudClusterPrinter +from .Models.CloudClusterPrintJob import CloudClusterPrintJob ## Class that contains all the translations for this module. @@ -180,80 +181,23 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): remote_printers = {p.uuid: p for p in printers} # type: Dict[str, CloudClusterPrinter] current_printers = {p.key: p for p in self._printers} # type: Dict[str, PrinterOutputModel] - removed_printer_ids = set(current_printers).difference(remote_printers) - new_printer_ids = set(remote_printers).difference(current_printers) - updated_printer_ids = set(current_printers).intersection(remote_printers) + remote_printer_ids = set(remote_printers) # type: Set[str] + current_printer_ids = set(current_printers) # type: Set[str] - for printer_guid in removed_printer_ids: - self._printers.remove(current_printers[printer_guid]) + for removed_printer_id in current_printer_ids.difference(remote_printer_ids): + removed_printer = current_printers[removed_printer_id] + self._printers.remove(removed_printer) - for printer_guid in new_printer_ids: - self._addPrinter(remote_printers[printer_guid]) + for new_printer_id in remote_printer_ids.difference(current_printer_ids): + new_printer = remote_printers[new_printer_id] + controller = PrinterOutputController(self) + self._printers.append(new_printer.createOutputModel(controller)) - for printer_guid in updated_printer_ids: - self._updatePrinter(current_printers[printer_guid], remote_printers[printer_guid]) + for updated_printer_guid in current_printer_ids.intersection(remote_printer_ids): + remote_printers[updated_printer_guid].updateOutputModel(current_printers[updated_printer_guid]) self.clusterPrintersChanged.emit() - def _addPrinter(self, printer: CloudClusterPrinter) -> None: - model = PrinterOutputModel( - PrinterOutputController(self), len(printer.configuration), firmware_version = printer.firmware_version - ) - self._printers.append(model) - self._updatePrinter(model, printer) - - def _updatePrinter(self, model: PrinterOutputModel, printer: CloudClusterPrinter) -> None: - model.updateKey(printer.uuid) - model.updateName(printer.friendly_name) - model.updateType(printer.machine_variant) - model.updateState(printer.status if printer.enabled else "disabled") - - for index in range(0, len(printer.configuration)): - try: - extruder = model.extruders[index] - extruder_data = printer.configuration[index] - except IndexError: - break - - extruder.updateHotendID(extruder_data.print_core_id) - - if extruder.activeMaterial is None or extruder.activeMaterial.guid != extruder_data.material.guid: - material = self._createMaterialOutputModel(extruder_data.material) - extruder.updateActiveMaterial(material) - - @staticmethod - def _createMaterialOutputModel(material: CloudClusterPrinterConfigurationMaterial) -> MaterialOutputModel: - material_manager = CuraApplication.getInstance().getMaterialManager() - material_group_list = material_manager.getMaterialGroupListByGUID(material.guid) or [] - - # Sort the material groups by "is_read_only = True" first, and then the name alphabetically. - read_only_material_group_list = list(filter(lambda x: x.is_read_only, material_group_list)) - non_read_only_material_group_list = list(filter(lambda x: not x.is_read_only, material_group_list)) - material_group = None - if read_only_material_group_list: - read_only_material_group_list = sorted(read_only_material_group_list, key = lambda x: x.name) - material_group = read_only_material_group_list[0] - elif non_read_only_material_group_list: - non_read_only_material_group_list = sorted(non_read_only_material_group_list, key = lambda x: x.name) - material_group = non_read_only_material_group_list[0] - - if material_group: - container = material_group.root_material_node.getContainer() - color = container.getMetaDataEntry("color_code") - brand = container.getMetaDataEntry("brand") - material_type = container.getMetaDataEntry("material") - name = container.getName() - else: - Logger.log("w", "Unable to find material with guid {guid}. Using data as provided by cluster" - .format(guid = material.guid)) - color = material.color - brand = material.brand - material_type = material.material - name = "Empty" if material.material == "empty" else "Unknown" - - return MaterialOutputModel(guid = material.guid, type = material_type, brand = brand, color = color, - name = name) - def _updatePrintJobs(self, jobs: List[CloudClusterPrintJob]) -> None: remote_jobs = {j.uuid: j for j in jobs} # type: Dict[str, CloudClusterPrintJob] current_jobs = {j.key: j for j in self._print_jobs} # type: Dict[str, UM3PrintJobOutputModel] @@ -264,11 +208,11 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): for removed_job_id in current_job_ids.difference(remote_job_ids): self._print_jobs.remove(current_jobs[removed_job_id]) - for new_job_id in remote_job_ids.difference(current_jobs): + for new_job_id in remote_job_ids.difference(current_job_ids): self._addPrintJob(remote_jobs[new_job_id]) for updated_job_id in current_job_ids.intersection(remote_job_ids): - self._updateUM3PrintJobOutputModel(current_jobs[updated_job_id], remote_jobs[updated_job_id]) + remote_jobs[updated_job_id].updateOutputModel(current_jobs[updated_job_id]) # We only have to update when jobs are added or removed # updated jobs push their changes via their output model @@ -282,16 +226,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): return Logger.log("w", "Missing printer %s for job %s in %s", job.printer_uuid, job.uuid, [p.key for p in self._printers]) - model = UM3PrintJobOutputModel(printer.getController(), job.uuid, job.name) - model.updateAssignedPrinter(printer) - self._print_jobs.append(model) - - @staticmethod - def _updateUM3PrintJobOutputModel(model: UM3PrintJobOutputModel, job: CloudClusterPrintJob) -> None: - model.updateTimeTotal(job.time_total) - model.updateTimeElapsed(job.time_elapsed) - model.updateOwner(job.owner) - model.updateState(job.status) + self._print_jobs.append(job.createOutputModel(printer)) def _onPrintJobCreated(self, mesh: bytes, job_response: CloudJobResponse) -> None: self._api.uploadMesh(job_response, mesh, self._onPrintJobUploaded, self._updateUploadProgress, diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 0fbeeb82b6..51c7f49074 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -8,9 +8,10 @@ from UM import i18nCatalog from UM.Logger import Logger from UM.Message import Message from cura.CuraApplication import CuraApplication -from plugins.UM3NetworkPrinting.src.Cloud.CloudApiClient import CloudApiClient +from .CloudApiClient import CloudApiClient from .CloudOutputDevice import CloudOutputDevice -from .Models import CloudCluster, CloudErrorObject +from .Models.CloudCluster import CloudCluster +from .Models.CloudErrorObject import CloudErrorObject ## The cloud output device manager is responsible for using the Ultimaker Cloud APIs to manage remote clusters. diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models.py b/plugins/UM3NetworkPrinting/src/Cloud/Models.py deleted file mode 100644 index 27ff7df604..0000000000 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models.py +++ /dev/null @@ -1,153 +0,0 @@ -# Copyright (c) 2018 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. -from typing import List, Dict - -from ..Models import BaseModel - - -## Class representing errors generated by the cloud servers, according to the json-api standard. -class CloudErrorObject(BaseModel): - def __init__(self, **kwargs): - self.id = None # type: str - self.code = None # type: str - self.http_status = None # type: str - self.title = None # type: str - self.detail = None # type: str - self.meta = None # type: Dict[str, any] - super().__init__(**kwargs) - - -## Class representing a cloud connected cluster. -class CloudCluster(BaseModel): - def __init__(self, **kwargs): - self.cluster_id = None # type: str - self.host_guid = None # type: str - self.host_name = None # type: str - self.host_version = None # type: str - self.status = None # type: str - self.is_online = None # type: bool - super().__init__(**kwargs) - - def validate(self): - if not self.cluster_id: - raise ValueError("cluster_id is required on CloudCluster") - - -## Class representing a cloud cluster printer configuration -class CloudClusterPrinterConfigurationMaterial(BaseModel): - def __init__(self, **kwargs): - self.guid = None # type: str - self.brand = None # type: str - self.color = None # type: str - self.material = None # type: str - super().__init__(**kwargs) - - -## Class representing a cloud cluster printer configuration -class CloudClusterPrinterConfiguration(BaseModel): - def __init__(self, **kwargs): - self.extruder_index = None # type: str - self.material = None # type: CloudClusterPrinterConfigurationMaterial - self.nozzle_diameter = None # type: str - self.print_core_id = None # type: str - super().__init__(**kwargs) - - if isinstance(self.material, dict): - self.material = CloudClusterPrinterConfigurationMaterial(**self.material) - - -## Class representing a cluster printer -class CloudClusterPrinter(BaseModel): - def __init__(self, **kwargs): - self.configuration = [] # type: List[CloudClusterPrinterConfiguration] - self.enabled = None # type: str - self.firmware_version = None # type: str - self.friendly_name = None # type: str - self.ip_address = None # type: str - self.machine_variant = None # type: str - self.status = None # type: str - self.unique_name = None # type: str - self.uuid = None # type: str - super().__init__(**kwargs) - - self.configuration = [CloudClusterPrinterConfiguration(**c) - if isinstance(c, dict) else c for c in self.configuration] - - -## Class representing a cloud cluster print job constraint -class CloudClusterPrintJobConstraint(BaseModel): - def __init__(self, **kwargs): - self.require_printer_name = None # type: str - super().__init__(**kwargs) - - -## Class representing a print job -class CloudClusterPrintJob(BaseModel): - def __init__(self, **kwargs): - self.assigned_to = None # type: str - self.configuration = [] # type: List[CloudClusterPrinterConfiguration] - self.constraints = [] # type: List[CloudClusterPrintJobConstraint] - self.created_at = None # type: str - self.force = None # type: str - self.last_seen = None # type: str - self.machine_variant = None # type: str - self.name = None # type: str - self.network_error_count = None # type: int - self.owner = None # type: str - self.printer_uuid = None # type: str - self.started = None # type: str - self.status = None # type: str - self.time_elapsed = None # type: str - self.time_total = None # type: str - self.uuid = None # type: str - super().__init__(**kwargs) - self.printers = [CloudClusterPrinterConfiguration(**c) if isinstance(c, dict) else c - for c in self.configuration] - self.printers = [CloudClusterPrintJobConstraint(**p) if isinstance(p, dict) else p - for p in self.constraints] - - -# Model that represents the status of the cluster for the cloud -class CloudClusterStatus(BaseModel): - def __init__(self, **kwargs): - # a list of the printers - self.printers = [] # type: List[CloudClusterPrinter] - # a list of the print jobs - self.print_jobs = [] # type: List[CloudClusterPrintJob] - - super().__init__(**kwargs) - - # converting any dictionaries into models - self.printers = [CloudClusterPrinter(**p) if isinstance(p, dict) else p for p in self.printers] - self.print_jobs = [CloudClusterPrintJob(**j) if isinstance(j, dict) else j for j in self.print_jobs] - - -# Model that represents the request to upload a print job to the cloud -class CloudJobUploadRequest(BaseModel): - def __init__(self, **kwargs): - self.file_size = None # type: int - self.job_name = None # type: str - self.content_type = None # type: str - super().__init__(**kwargs) - - -# Model that represents the response received from the cloud after requesting to upload a print job -class CloudJobResponse(BaseModel): - def __init__(self, **kwargs): - self.download_url = None # type: str - self.job_id = None # type: str - self.job_name = None # type: str - self.slicing_details = None # type: str - self.status = None # type: str - self.upload_url = None # type: str - self.content_type = None # type: str - super().__init__(**kwargs) - - -# Model that represents the responses received from the cloud after requesting a job to be printed. -class CloudPrintResponse(BaseModel): - def __init__(self, **kwargs): - self.cluster_job_id = None # type: str - self.job_id = None # type: str - self.status = None # type: str - super().__init__(**kwargs) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudCluster.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudCluster.py new file mode 100644 index 0000000000..dd1e2e85bf --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudCluster.py @@ -0,0 +1,21 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +from ...Models import BaseModel + + +## Class representing a cloud connected cluster. +class CloudCluster(BaseModel): + def __init__(self, **kwargs): + self.cluster_id = None # type: str + self.host_guid = None # type: str + self.host_name = None # type: str + self.host_version = None # type: str + self.status = None # type: str + self.is_online = None # type: bool + super().__init__(**kwargs) + + # Validates the model, raising an exception if the model is invalid. + def validate(self) -> None: + super().validate() + if not self.cluster_id: + raise ValueError("cluster_id is required on CloudCluster") diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py new file mode 100644 index 0000000000..e2e3787435 --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py @@ -0,0 +1,52 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +from typing import List + +from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel +from .CloudClusterPrinterConfiguration import CloudClusterPrinterConfiguration +from .CloudClusterPrintJobConstraint import CloudClusterPrintJobConstraint +from ...Models import BaseModel + + +## Class representing a print job +from plugins.UM3NetworkPrinting.src.UM3PrintJobOutputModel import UM3PrintJobOutputModel + + +class CloudClusterPrintJob(BaseModel): + def __init__(self, **kwargs) -> None: + self.assigned_to = None # type: str + self.configuration = [] # type: List[CloudClusterPrinterConfiguration] + self.constraints = [] # type: List[CloudClusterPrintJobConstraint] + self.created_at = None # type: str + self.force = None # type: str + self.last_seen = None # type: str + self.machine_variant = None # type: str + self.name = None # type: str + self.network_error_count = None # type: int + self.owner = None # type: str + self.printer_uuid = None # type: str + self.started = None # type: str + self.status = None # type: str + self.time_elapsed = None # type: str + self.time_total = None # type: str + self.uuid = None # type: str + super().__init__(**kwargs) + self.printers = [CloudClusterPrinterConfiguration(**c) if isinstance(c, dict) else c + for c in self.configuration] + self.printers = [CloudClusterPrintJobConstraint(**p) if isinstance(p, dict) else p + for p in self.constraints] + + ## Creates an UM3 print job output model based on this cloud cluster print job. + # \param printer: The output model of the printer + def createOutputModel(self, printer: PrinterOutputModel) -> UM3PrintJobOutputModel: + model = UM3PrintJobOutputModel(printer.getController(), self.uuid, self.name) + model.updateAssignedPrinter(printer) + return model + + ## Updates an UM3 print job output model based on this cloud cluster print job. + # \param model: The model to update. + def updateOutputModel(self, model: UM3PrintJobOutputModel) -> None: + model.updateTimeTotal(self.time_total) + model.updateTimeElapsed(self.time_elapsed) + model.updateOwner(self.owner) + model.updateState(self.status) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobConstraint.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobConstraint.py new file mode 100644 index 0000000000..884ff8f0c2 --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobConstraint.py @@ -0,0 +1,10 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +from ...Models import BaseModel + + +## Class representing a cloud cluster print job constraint +class CloudClusterPrintJobConstraint(BaseModel): + def __init__(self, **kwargs) -> None: + self.require_printer_name = None # type: str + super().__init__(**kwargs) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinter.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinter.py new file mode 100644 index 0000000000..dd65dffa26 --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinter.py @@ -0,0 +1,44 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +from typing import List + +from cura.PrinterOutput.PrinterOutputController import PrinterOutputController +from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel +from .CloudClusterPrinterConfiguration import CloudClusterPrinterConfiguration +from ...Models import BaseModel + + +## Class representing a cluster printer +class CloudClusterPrinter(BaseModel): + def __init__(self, **kwargs) -> None: + self.configuration = [] # type: List[CloudClusterPrinterConfiguration] + self.enabled = None # type: str + self.firmware_version = None # type: str + self.friendly_name = None # type: str + self.ip_address = None # type: str + self.machine_variant = None # type: str + self.status = None # type: str + self.unique_name = None # type: str + self.uuid = None # type: str + super().__init__(**kwargs) + + self.configuration = [CloudClusterPrinterConfiguration(**c) + if isinstance(c, dict) else c for c in self.configuration] + + ## Creates a new output model. + # \param controller - The controller of the model. + def createOutputModel(self, controller: PrinterOutputController) -> PrinterOutputModel: + model = PrinterOutputModel(controller, len(self.configuration), firmware_version = self.firmware_version) + self.updateOutputModel(model) + return model + + ## Updates the given output model. + # \param model - The output model to update. + def updateOutputModel(self, model: PrinterOutputModel) -> None: + model.updateKey(self.uuid) + model.updateName(self.friendly_name) + model.updateType(self.machine_variant) + model.updateState(self.status if self.enabled else "disabled") + + for configuration, extruder in zip(self.configuration, model.extruders): + configuration.updateOutputModel(extruder) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py new file mode 100644 index 0000000000..be92549015 --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py @@ -0,0 +1,27 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +from cura.PrinterOutput.ExtruderOutputModel import ExtruderOutputModel +from .CloudClusterPrinterConfigurationMaterial import CloudClusterPrinterConfigurationMaterial +from ...Models import BaseModel + + +## Class representing a cloud cluster printer configuration +class CloudClusterPrinterConfiguration(BaseModel): + def __init__(self, **kwargs) -> None: + self.extruder_index = None # type: str + self.material = None # type: CloudClusterPrinterConfigurationMaterial + self.nozzle_diameter = None # type: str + self.print_core_id = None # type: str + super().__init__(**kwargs) + + if isinstance(self.material, dict): + self.material = CloudClusterPrinterConfigurationMaterial(**self.material) + + ## Updates the given output model. + # \param model - The output model to update. + def updateOutputModel(self, model: ExtruderOutputModel) -> None: + model.updateHotendID(self.print_core_id) + + if model.activeMaterial is None or model.activeMaterial.guid != self.material.guid: + material = self.material.createOutputModel() + model.updateActiveMaterial(material) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfigurationMaterial.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfigurationMaterial.py new file mode 100644 index 0000000000..8023784925 --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfigurationMaterial.py @@ -0,0 +1,46 @@ +from UM.Logger import Logger +from cura.CuraApplication import CuraApplication +from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel +from ...Models import BaseModel + + +## Class representing a cloud cluster printer configuration +class CloudClusterPrinterConfigurationMaterial(BaseModel): + def __init__(self, **kwargs) -> None: + self.guid = None # type: str + self.brand = None # type: str + self.color = None # type: str + self.material = None # type: str + super().__init__(**kwargs) + + ## Creates a material output model based on this cloud printer material. + def createOutputModel(self) -> MaterialOutputModel: + material_manager = CuraApplication.getInstance().getMaterialManager() + material_group_list = material_manager.getMaterialGroupListByGUID(self.guid) or [] + + # Sort the material groups by "is_read_only = True" first, and then the name alphabetically. + read_only_material_group_list = list(filter(lambda x: x.is_read_only, material_group_list)) + non_read_only_material_group_list = list(filter(lambda x: not x.is_read_only, material_group_list)) + material_group = None + if read_only_material_group_list: + read_only_material_group_list = sorted(read_only_material_group_list, key = lambda x: x.name) + material_group = read_only_material_group_list[0] + elif non_read_only_material_group_list: + non_read_only_material_group_list = sorted(non_read_only_material_group_list, key = lambda x: x.name) + material_group = non_read_only_material_group_list[0] + + if material_group: + container = material_group.root_material_node.getContainer() + color = container.getMetaDataEntry("color_code") + brand = container.getMetaDataEntry("brand") + material_type = container.getMetaDataEntry("material") + name = container.getName() + else: + Logger.log("w", "Unable to find material with guid {guid}. Using data as provided by cluster" + .format(guid = self.guid)) + color = self.color + brand = self.brand + material_type = self.material + name = "Empty" if self.material == "empty" else "Unknown" + + return MaterialOutputModel(guid = self.guid, type = material_type, brand = brand, color = color, name = name) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterStatus.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterStatus.py new file mode 100644 index 0000000000..a44b665973 --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterStatus.py @@ -0,0 +1,22 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +from typing import List + +from .CloudClusterPrinter import CloudClusterPrinter +from .CloudClusterPrintJob import CloudClusterPrintJob +from ...Models import BaseModel + + +# Model that represents the status of the cluster for the cloud +class CloudClusterStatus(BaseModel): + def __init__(self, **kwargs) -> None: + # a list of the printers + self.printers = [] # type: List[CloudClusterPrinter] + # a list of the print jobs + self.print_jobs = [] # type: List[CloudClusterPrintJob] + + super().__init__(**kwargs) + + # converting any dictionaries into models + self.printers = [CloudClusterPrinter(**p) if isinstance(p, dict) else p for p in self.printers] + self.print_jobs = [CloudClusterPrintJob(**j) if isinstance(j, dict) else j for j in self.print_jobs] diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudErrorObject.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudErrorObject.py new file mode 100644 index 0000000000..813ef957e4 --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudErrorObject.py @@ -0,0 +1,17 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +from typing import Dict + +from ...Models import BaseModel + + +## Class representing errors generated by the cloud servers, according to the json-api standard. +class CloudErrorObject(BaseModel): + def __init__(self, **kwargs) -> None: + self.id = None # type: str + self.code = None # type: str + self.http_status = None # type: str + self.title = None # type: str + self.detail = None # type: str + self.meta = None # type: Dict[str, any] + super().__init__(**kwargs) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobResponse.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobResponse.py new file mode 100644 index 0000000000..0b611dd2d3 --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobResponse.py @@ -0,0 +1,16 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +from ...Models import BaseModel + + +# Model that represents the response received from the cloud after requesting to upload a print job +class CloudJobResponse(BaseModel): + def __init__(self, **kwargs) -> None: + self.download_url = None # type: str + self.job_id = None # type: str + self.job_name = None # type: str + self.slicing_details = None # type: str + self.status = None # type: str + self.upload_url = None # type: str + self.content_type = None # type: str + super().__init__(**kwargs) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobUploadRequest.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobUploadRequest.py new file mode 100644 index 0000000000..3e038b343e --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobUploadRequest.py @@ -0,0 +1,12 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +from ...Models import BaseModel + + +# Model that represents the request to upload a print job to the cloud +class CloudJobUploadRequest(BaseModel): + def __init__(self, **kwargs) -> None: + self.file_size = None # type: int + self.job_name = None # type: str + self.content_type = None # type: str + super().__init__(**kwargs) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintResponse.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintResponse.py new file mode 100644 index 0000000000..ff05ad5b19 --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintResponse.py @@ -0,0 +1,12 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +from ...Models import BaseModel + + +# Model that represents the responses received from the cloud after requesting a job to be printed. +class CloudPrintResponse(BaseModel): + def __init__(self, **kwargs) -> None: + self.cluster_job_id = None # type: str + self.job_id = None # type: str + self.status = None # type: str + super().__init__(**kwargs) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/__init__.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/__init__.py new file mode 100644 index 0000000000..f3f6970c54 --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index 64ac613723..aa8be9ecd9 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -25,11 +25,11 @@ from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationM from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState, NetworkedPrinterOutputDevice from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel -from plugins.UM3NetworkPrinting.src.MeshFormatHandler import MeshFormatHandler from .ClusterUM3PrinterOutputController import ClusterUM3PrinterOutputController -from .SendMaterialJob import SendMaterialJob from .ConfigurationChangeModel import ConfigurationChangeModel +from .MeshFormatHandler import MeshFormatHandler +from .SendMaterialJob import SendMaterialJob from .UM3PrintJobOutputModel import UM3PrintJobOutputModel from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply diff --git a/plugins/UM3NetworkPrinting/src/Models.py b/plugins/UM3NetworkPrinting/src/Models.py index 2bcac70766..c5b9b16665 100644 --- a/plugins/UM3NetworkPrinting/src/Models.py +++ b/plugins/UM3NetworkPrinting/src/Models.py @@ -8,6 +8,7 @@ class BaseModel: self.__dict__.update(kwargs) self.validate() + # Validates the model, raising an exception if the model is invalid. def validate(self) -> None: pass @@ -34,7 +35,9 @@ class LocalMaterial(BaseModel): self.version = version # type: int super().__init__(**kwargs) + # def validate(self) -> None: + super().validate() if not self.GUID: raise ValueError("guid is required on LocalMaterial") if not self.version: diff --git a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py index b669eb192a..e3ec9faeaf 100644 --- a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py @@ -10,7 +10,7 @@ from PyQt5.QtCore import QByteArray from UM.MimeTypeDatabase import MimeType from UM.Application import Application -from plugins.UM3NetworkPrinting.src.SendMaterialJob import SendMaterialJob +from ..src.SendMaterialJob import SendMaterialJob @patch("builtins.open", lambda _, __: io.StringIO("")) From d6630b68815781ba92edae3510aaf62cf77b4d0d Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 5 Dec 2018 14:09:55 +0100 Subject: [PATCH 0699/1292] Removed some more cases where data was duplicated and re-used for different purposes CURA-6006 --- plugins/Toolbox/src/Toolbox.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index ada81dbc07..f70543d5d7 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -69,16 +69,14 @@ class Toolbox(QObject, Extension): # The responses as given by the server parsed to a list. self._server_response_data = { "authors": [], - "packages": [], - "plugins_installed": [], - "materials_installed": [] + "packages": [] } # type: Dict[str, List[Any]] # Models: self._models = { "authors": AuthorsModel(self), "packages": PackagesModel(self), - } # type: Dict[str, ListModel] + } # type: Dict[str, Union[AuthorsModel, PackagesModel]] self._plugins_showcase_model = PackagesModel(self) self._plugins_available_model = PackagesModel(self) @@ -305,11 +303,9 @@ class Toolbox(QObject, Extension): if plugin_id not in all_plugin_package_ids) self._old_plugin_metadata = {k: v for k, v in self._old_plugin_metadata.items() if k in self._old_plugin_ids} - self._server_response_data["plugins_installed"] = all_packages["plugin"] + list(self._old_plugin_metadata.values()) - self._plugins_installed_model.setMetadata(self._server_response_data["plugins_installed"]) + self._plugins_installed_model.setMetadata(all_packages["plugin"] + list(self._old_plugin_metadata.values())) self.metadataChanged.emit() if "material" in all_packages: - self._server_response_data["materials_installed"] = all_packages["material"] self._materials_installed_model.setMetadata(all_packages["material"]) self.metadataChanged.emit() @@ -527,8 +523,8 @@ class Toolbox(QObject, Extension): @pyqtSlot(str, result = int) def getNumberOfInstalledPackagesByAuthor(self, author_id: str) -> int: count = 0 - for package in self._server_response_data["materials_installed"]: - if package["author"]["author_id"] == author_id: + for package in self._materials_installed_model.items: + if package["author_id"] == author_id: count += 1 return count From 5ba8820f185673f0486393187eafca826c657537 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 5 Dec 2018 14:10:51 +0100 Subject: [PATCH 0700/1292] Remove unnecessary setting height to 0 when invisible Turns out that it doesn't count for the childrenRect.height anyway when the item is invisible. Contributes to issue CURA-5876. --- resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml | 2 +- resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml index 58b6bac089..a09d6d2ba4 100644 --- a/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml @@ -10,7 +10,7 @@ import Cura 1.0 as Cura Item { width: parent.width - height: visible ? childrenRect.height : 0 + height: childrenRect.height Label { diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index 18c2dabb0f..19b7158929 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -17,7 +17,7 @@ Item } width: parent.width - height: visible ? childrenRect.height : 0 + height: childrenRect.height Label { From 218fa3aded7ed4e4fb77bd092ca7e798ca948dae Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 5 Dec 2018 14:22:04 +0100 Subject: [PATCH 0701/1292] Align the print info to the left --- resources/qml/Cura.qml | 26 ++++---- resources/qml/JobSpecs.qml | 126 +++++++++++++++++-------------------- 2 files changed, 71 insertions(+), 81 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 3578888886..6559fafa12 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -189,16 +189,6 @@ UM.MainWindow onHideTooltip: base.hideTooltip() } - JobSpecs - { - id: jobSpecs - anchors - { - bottom: parent.bottom - bottomMargin: UM.Theme.getSize("default_margin").height - } - } - Toolbar { // The toolbar is the left bar that is populated by all the tools (which are dynamicly populated by @@ -228,6 +218,19 @@ UM.MainWindow } } + JobSpecs + { + id: jobSpecs + visible: CuraApplication.platformActivity + anchors + { + left: parent.left + bottom: viewOrientationControls.top + margins: UM.Theme.getSize("wide_margin").width + bottomMargin: UM.Theme.getSize("default_margin").width + } + } + ViewOrientationControls { id: viewOrientationControls @@ -235,9 +238,8 @@ UM.MainWindow anchors { left: parent.left - margins: UM.Theme.getSize("default_margin").width - bottom: parent.bottom + margins: UM.Theme.getSize("wide_margin").width } } diff --git a/resources/qml/JobSpecs.qml b/resources/qml/JobSpecs.qml index 19b5b3f2de..97e12e15a3 100644 --- a/resources/qml/JobSpecs.qml +++ b/resources/qml/JobSpecs.qml @@ -19,9 +19,10 @@ Item UM.I18nCatalog { id: catalog - name:"cura" + name: "cura" } + width: childrenRect.width height: childrenRect.height onActivityChanged: @@ -33,82 +34,75 @@ Item } } - Rectangle + Item { id: jobNameRow anchors.top: parent.top - anchors.right: parent.right + anchors.left: parent.left height: UM.Theme.getSize("jobspecs_line").height - visible: base.activity - Item + Button { - width: parent.width - height: parent.height + id: printJobPencilIcon + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + width: UM.Theme.getSize("save_button_specs_icons").width + height: UM.Theme.getSize("save_button_specs_icons").height - Button + onClicked: { - id: printJobPencilIcon - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - width: UM.Theme.getSize("save_button_specs_icons").width - height: UM.Theme.getSize("save_button_specs_icons").height + printJobTextfield.selectAll() + printJobTextfield.focus = true + } - onClicked: + style: ButtonStyle + { + background: Item { - printJobTextfield.selectAll() - printJobTextfield.focus = true - } - - style: ButtonStyle - { - background: Item + UM.RecolorImage { - UM.RecolorImage - { - width: UM.Theme.getSize("save_button_specs_icons").width - height: UM.Theme.getSize("save_button_specs_icons").height - sourceSize.width: width - sourceSize.height: width - color: control.hovered ? UM.Theme.getColor("text_scene_hover") : UM.Theme.getColor("text_scene") - source: UM.Theme.getIcon("pencil") - } + width: UM.Theme.getSize("save_button_specs_icons").width + height: UM.Theme.getSize("save_button_specs_icons").height + sourceSize.width: width + sourceSize.height: width + color: control.hovered ? UM.Theme.getColor("text_scene_hover") : UM.Theme.getColor("text_scene") + source: UM.Theme.getIcon("pencil") } } } + } - TextField + TextField + { + id: printJobTextfield + anchors.left: printJobPencilIcon.right + anchors.leftMargin: UM.Theme.getSize("narrow_margin").width + height: UM.Theme.getSize("jobspecs_line").height + width: Math.max(__contentWidth + UM.Theme.getSize("default_margin").width, 50) + maximumLength: 120 + property int unremovableSpacing: 5 + text: PrintInformation.jobName + horizontalAlignment: TextInput.AlignLeft + + onEditingFinished: { - id: printJobTextfield - anchors.right: printJobPencilIcon.left - anchors.rightMargin: UM.Theme.getSize("narrow_margin").width - height: UM.Theme.getSize("jobspecs_line").height - width: Math.max(__contentWidth + UM.Theme.getSize("default_margin").width, 50) - maximumLength: 120 - property int unremovableSpacing: 5 - text: PrintInformation.jobName - horizontalAlignment: TextInput.AlignRight + var new_name = text == "" ? catalog.i18nc("@text Print job name", "Untitled") : text + PrintInformation.setJobName(new_name, true) + printJobTextfield.focus = false + } - onEditingFinished: + validator: RegExpValidator { + regExp: /^[^\\\/\*\?\|\[\]]*$/ + } + + style: TextFieldStyle + { + textColor: UM.Theme.getColor("text_scene") + font: UM.Theme.getFont("default_bold") + background: Rectangle { - var new_name = text == "" ? catalog.i18nc("@text Print job name", "Untitled") : text - PrintInformation.setJobName(new_name, true) - printJobTextfield.focus = false - } - - validator: RegExpValidator { - regExp: /^[^\\\/\*\?\|\[\]]*$/ - } - - style: TextFieldStyle - { - textColor: UM.Theme.getColor("text_scene") - font: UM.Theme.getFont("default_bold") - background: Rectangle - { - opacity: 0 - border.width: 0 - } + opacity: 0 + border.width: 0 } } } @@ -118,22 +112,16 @@ Item { id: additionalComponentsRow anchors.top: jobNameRow.bottom - anchors.right: parent.right + anchors.left: parent.left } Label { id: boundingSpec anchors.top: jobNameRow.bottom - anchors.right: additionalComponentsRow.left - anchors.rightMargin: - { - if (additionalComponentsRow.width > 0) - { - return UM.Theme.getSize("default_margin").width - } - return 0 - } + anchors.left: additionalComponentsRow.right + anchors.leftMargin: additionalComponentsRow.width > 0 ? UM.Theme.getSize("default_margin").width : 0 + height: UM.Theme.getSize("jobspecs_line").height verticalAlignment: Text.AlignVCenter font: UM.Theme.getFont("default_bold") From 00e95e68eb974e19ac3f6960b86965dd9ada8fbf Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 5 Dec 2018 14:26:47 +0100 Subject: [PATCH 0702/1292] Removed unneeded Marketplace tag in logging The logger does that all by itself already. CURA-6006 --- plugins/Toolbox/src/Toolbox.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index f70543d5d7..cd20d26eca 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -781,7 +781,7 @@ class Toolbox(QObject, Extension): @pyqtSlot(str, str, str) def filterModelByProp(self, model_type: str, filter_type: str, parameter: str) -> None: if not self._models[model_type]: - Logger.log("w", "Marketplace: Couldn't filter %s model because it doesn't exist.", model_type) + Logger.log("w", "Couldn't filter %s model because it doesn't exist.", model_type) return self._models[model_type].setFilter({filter_type: parameter}) self.filterChanged.emit() @@ -789,7 +789,7 @@ class Toolbox(QObject, Extension): @pyqtSlot(str, "QVariantMap") def setFilters(self, model_type: str, filter_dict: dict) -> None: if not self._models[model_type]: - Logger.log("w", "Marketplace: Couldn't filter %s model because it doesn't exist.", model_type) + Logger.log("w", "Couldn't filter %s model because it doesn't exist.", model_type) return self._models[model_type].setFilter(filter_dict) self.filterChanged.emit() @@ -797,7 +797,7 @@ class Toolbox(QObject, Extension): @pyqtSlot(str) def removeFilters(self, model_type: str) -> None: if not self._models[model_type]: - Logger.log("w", "Marketplace: Couldn't remove filters on %s model because it doesn't exist.", model_type) + Logger.log("w", "Couldn't remove filters on %s model because it doesn't exist.", model_type) return self._models[model_type].setFilter({}) self.filterChanged.emit() From cd67100097fe092bfc8fc96e4b8941c0f90b3e7d Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Wed, 5 Dec 2018 14:19:57 +0100 Subject: [PATCH 0703/1292] Comment out some currently broken code --- .../src/Cloud/CloudOutputDeviceManager.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 936ef03ddc..3ddd865c5f 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -79,7 +79,7 @@ class CloudOutputDeviceManager: self._removeCloudOutputDevice(found_clusters[cluster_id]) # TODO: not pass clusters that are not online? - self._connectToActiveMachine(clusters) + self._connectToActiveMachine() ## Adds a CloudOutputDevice for each entry in the remote cluster list from the API. # \param cluster: The cluster that was added. @@ -96,7 +96,7 @@ class CloudOutputDeviceManager: del self._remote_clusters[cluster.cluster_id] ## Callback for when the active machine was changed by the user or a new remote cluster was found. - def _connectToActiveMachine(self, clusters: List[CloudCluster]) -> None: + def _connectToActiveMachine(self) -> None: active_machine = CuraApplication.getInstance().getGlobalContainerStack() if not active_machine: return @@ -115,9 +115,10 @@ class CloudOutputDeviceManager: if not local_network_key: return - cluster_id = next(local_network_key in cluster.host_name for cluster in clusters) - if cluster_id in self._remote_clusters.keys(): - return self._remote_clusters.get(cluster_id).connect() + # TODO: get host_name in the output device so we can iterate here + # cluster_id = next(local_network_key in cluster.host_name for cluster in self._remote_clusters.items()) + # if cluster_id in self._remote_clusters.keys(): + # return self._remote_clusters.get(cluster_id).connect() ## Handles an API error received from the cloud. # \param errors: The errors received From 7e769137368af1b6d19416289040e5b4c953ce4e Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 5 Dec 2018 16:02:38 +0100 Subject: [PATCH 0704/1292] STAR-322: Fixing printer matching by network key --- .../src/Cloud/CloudOutputDevice.py | 43 ++++++--- .../src/Cloud/CloudOutputDeviceManager.py | 91 +++++++++---------- .../src/Cloud/Models/CloudCluster.py | 2 +- plugins/UM3NetworkPrinting/src/Cloud/Utils.py | 19 ++++ .../src/ClusterUM3OutputDevice.py | 6 +- 5 files changed, 97 insertions(+), 64 deletions(-) create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Utils.py diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index c6397fc41f..e8f7687b03 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -18,7 +18,6 @@ from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from ..MeshFormatHandler import MeshFormatHandler from ..UM3PrintJobOutputModel import UM3PrintJobOutputModel from .CloudApiClient import CloudApiClient -from .Models.CloudErrorObject import CloudErrorObject from .Models.CloudClusterStatus import CloudClusterStatus from .Models.CloudJobUploadRequest import CloudJobUploadRequest from .Models.CloudPrintResponse import CloudPrintResponse @@ -63,19 +62,21 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # The interval with which the remote clusters are checked CHECK_CLUSTER_INTERVAL = 2.0 # seconds - # Signal triggered when the printers in the remote cluster were changed. - clusterPrintersChanged = pyqtSignal() - # Signal triggered when the print jobs in the queue were changed. printJobsChanged = pyqtSignal() + # Notify can only use signals that are defined by the class that they are in, not inherited ones. + # Therefore we create a private signal used to trigger the printersChanged signal. + _clusterPrintersChanged = pyqtSignal() + ## Creates a new cloud output device # \param api_client: The client that will run the API calls # \param device_id: The ID of the device (i.e. the cluster_id for the cloud API) # \param parent: The optional parent of this output device. - def __init__(self, api_client: CloudApiClient, device_id: str, parent: QObject = None) -> None: + def __init__(self, api_client: CloudApiClient, device_id: str, host_name: str, parent: QObject = None) -> None: super().__init__(device_id = device_id, address = "", properties = {}, parent = parent) self._api = api_client + self._host_name = host_name self._setInterfaceElements() @@ -87,7 +88,10 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): "../../resources/qml/ClusterMonitorItem.qml") self._control_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../resources/qml/ClusterControlItem.qml") - + + # trigger the printersChanged signal when the private signal is triggered + self.printersChanged.connect(self._clusterPrintersChanged) + # Properties to populate later on with received cloud data. self._print_jobs = [] # type: List[UM3PrintJobOutputModel] self._number_of_extruders = 2 # All networked printers are dual-extrusion Ultimaker machines. @@ -96,6 +100,22 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self._sending_job = False self._progress_message = None # type: Optional[Message] + ## Gets the host name of this device + @property + def host_name(self) -> str: + return self._host_name + + ## Updates the host name of the output device + @host_name.setter + def host_name(self, value: str) -> None: + self._host_name = value + + ## Checks whether the given network key is found in the cloud's host name + def matchesNetworkKey(self, network_key: str) -> bool: + # A network key looks like "ultimakersystem-aabbccdd0011._ultimaker._tcp.local." + # the host name should then be "ultimakersystem-aabbccdd0011" + return network_key.startswith(self._host_name) + ## Set all the interface elements and texts for this output device. def _setInterfaceElements(self): self.setPriority(2) # make sure we end up below the local networking and above 'save to file' @@ -133,7 +153,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self._api.requestUpload(request, lambda response: self._onPrintJobCreated(mesh_bytes, response)) ## Get remote printers. - @pyqtProperty("QVariantList", notify = clusterPrintersChanged) + @pyqtProperty("QVariantList", notify = _clusterPrintersChanged) def printers(self): return self._printers @@ -196,7 +216,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): for updated_printer_guid in current_printer_ids.intersection(remote_printer_ids): remote_printers[updated_printer_guid].updateOutputModel(current_printers[updated_printer_guid]) - self.clusterPrintersChanged.emit() + self._clusterPrintersChanged.emit() def _updatePrintJobs(self, jobs: List[CloudClusterPrintJob]) -> None: remote_jobs = {j.uuid: j for j in jobs} # type: Dict[str, CloudClusterPrintJob] @@ -283,7 +303,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## TODO: The following methods are required by the monitor page QML, but are not actually available using cloud. # TODO: We fake the methods here to not break the monitor page. - @pyqtProperty(QObject, notify = clusterPrintersChanged) + @pyqtProperty(QObject, notify = _clusterPrintersChanged) def activePrinter(self) -> Optional[PrinterOutputModel]: if not self._printers: return None @@ -293,7 +313,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def setActivePrinter(self, printer: Optional[PrinterOutputModel]) -> None: pass - @pyqtProperty(QUrl, notify = clusterPrintersChanged) + @pyqtProperty(QUrl, notify = _clusterPrintersChanged) def activeCameraUrl(self) -> "QUrl": return QUrl() @@ -304,6 +324,3 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): @pyqtProperty(bool, notify = printJobsChanged) def receivedPrintJobs(self) -> bool: return True - - def _onApiError(self, errors: List[CloudErrorObject]) -> None: - pass # TODO: Show errors... diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 3ddd865c5f..f11d41a7bd 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -1,6 +1,6 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import Dict, List, Optional +from typing import Dict, List from PyQt5.QtCore import QTimer @@ -8,10 +8,12 @@ from UM import i18nCatalog from UM.Logger import Logger from UM.Message import Message from cura.CuraApplication import CuraApplication +from cura.Settings.GlobalStack import GlobalStack from .CloudApiClient import CloudApiClient from .CloudOutputDevice import CloudOutputDevice from .Models.CloudCluster import CloudCluster from .Models.CloudErrorObject import CloudErrorObject +from .Utils import findChanges ## The cloud output device manager is responsible for using the Ultimaker Cloud APIs to manage remote clusters. @@ -19,7 +21,9 @@ from .Models.CloudErrorObject import CloudErrorObject # # API spec is available on https://api.ultimaker.com/docs/connect/spec/. # + class CloudOutputDeviceManager: + META_CLUSTER_ID = "um_cloud_cluster_id" # The interval with which the remote clusters are checked CHECK_CLUSTER_INTERVAL = 5.0 # seconds @@ -42,59 +46,48 @@ class CloudOutputDeviceManager: # When switching machines we check if we have to activate a remote cluster. application.globalContainerStackChanged.connect(self._connectToActiveMachine) - - self.update_timer = QTimer(CuraApplication.getInstance()) - self.update_timer.setInterval(self.CHECK_CLUSTER_INTERVAL * 1000) - self.update_timer.setSingleShot(False) - self.update_timer.timeout.connect(self._getRemoteClusters) + + # create a timer to update the remote cluster list + self._update_timer = QTimer(application) + self._update_timer.setInterval(self.CHECK_CLUSTER_INTERVAL * 1000) + self._update_timer.setSingleShot(False) + self._update_timer.timeout.connect(self._getRemoteClusters) ## Gets all remote clusters from the API. def _getRemoteClusters(self) -> None: Logger.log("i", "Retrieving remote clusters") if self._account.isLoggedIn: self._api.getClusters(self._onGetRemoteClustersFinished) - - # Only start the polling timer after the user is authenticated - # The first call to _getRemoteClusters comes from self._account.loginStateChanged - if not self.update_timer.isActive(): - self.update_timer.start() + # Only start the polling timer after the user is authenticated + # The first call to _getRemoteClusters comes from self._account.loginStateChanged + if not self._update_timer.isActive(): + self._update_timer.start() ## Callback for when the request for getting the clusters. is finished. def _onGetRemoteClustersFinished(self, clusters: List[CloudCluster]) -> None: - found_clusters = {c.cluster_id: c for c in clusters} + online_clusters = {c.cluster_id: c for c in clusters if c.is_online} # type: Dict[str, CloudCluster] - Logger.log("i", "Parsed remote clusters to %s", found_clusters) + removed_devices, added_clusters, updates = findChanges(self._remote_clusters, online_clusters) - known_cluster_ids = set(self._remote_clusters.keys()) - found_cluster_ids = set(found_clusters.keys()) + Logger.log("i", "Parsed remote clusters to %s", online_clusters) + + # Remove output devices that are gone + for removed_cluster in removed_devices: + self._output_device_manager.removeOutputDevice(removed_cluster.key) + del self._remote_clusters[removed_cluster.key] # Add an output device for each new remote cluster. # We only add when is_online as we don't want the option in the drop down if the cluster is not online. - for cluster_id in found_cluster_ids.difference(known_cluster_ids): - if found_clusters[cluster_id].is_online: - self._addCloudOutputDevice(found_clusters[cluster_id]) + for added_cluster in added_clusters: + device = CloudOutputDevice(self._api, added_cluster.cluster_id, added_cluster.host_name) + self._output_device_manager.addOutputDevice(device) + self._remote_clusters[added_cluster.cluster_id] = device - # Remove output devices that are gone - for cluster_id in known_cluster_ids.difference(found_cluster_ids): - self._removeCloudOutputDevice(found_clusters[cluster_id]) + for device, cluster in updates: + device.host_name = cluster.host_name - # TODO: not pass clusters that are not online? self._connectToActiveMachine() - ## Adds a CloudOutputDevice for each entry in the remote cluster list from the API. - # \param cluster: The cluster that was added. - def _addCloudOutputDevice(self, cluster: CloudCluster): - device = CloudOutputDevice(self._api, cluster.cluster_id) - self._output_device_manager.addOutputDevice(device) - self._remote_clusters[cluster.cluster_id] = device - - ## Remove a CloudOutputDevice - # \param cluster: The cluster that was removed - def _removeCloudOutputDevice(self, cluster: CloudCluster): - self._output_device_manager.removeOutputDevice(cluster.cluster_id) - if cluster.cluster_id in self._remote_clusters: - del self._remote_clusters[cluster.cluster_id] - ## Callback for when the active machine was changed by the user or a new remote cluster was found. def _connectToActiveMachine(self) -> None: active_machine = CuraApplication.getInstance().getGlobalContainerStack() @@ -102,23 +95,27 @@ class CloudOutputDeviceManager: return # Check if the stored cluster_id for the active machine is in our list of remote clusters. - stored_cluster_id = active_machine.getMetaDataEntry("um_cloud_cluster_id") - if stored_cluster_id in self._remote_clusters.keys(): - return self._remote_clusters.get(stored_cluster_id).connect() + stored_cluster_id = active_machine.getMetaDataEntry(self.META_CLUSTER_ID) + if stored_cluster_id in self._remote_clusters: + device = self._remote_clusters[stored_cluster_id] + if not device.isConnected(): + device.connect() + else: + self._connectByNetworkKey(active_machine) + ## Tries to match the + def _connectByNetworkKey(self, active_machine: GlobalStack) -> None: # Check if the active printer has a local network connection and match this key to the remote cluster. - # The local network key is formatted as ultimakersystem-xxxxxxxxxxxx._ultimaker._tcp.local. - # The optional remote host_name is formatted as ultimakersystem-xxxxxxxxxxxx. - # This means we can match the two by checking if the host_name is in the network key string. - local_network_key = active_machine.getMetaDataEntry("um_network_key") if not local_network_key: return - # TODO: get host_name in the output device so we can iterate here - # cluster_id = next(local_network_key in cluster.host_name for cluster in self._remote_clusters.items()) - # if cluster_id in self._remote_clusters.keys(): - # return self._remote_clusters.get(cluster_id).connect() + device = next((c for c in self._remote_clusters.values() if c.matchesNetworkKey(local_network_key)), None) + if not device: + return + + active_machine.setMetaDataEntry(self.META_CLUSTER_ID, device.key) + return device.connect() ## Handles an API error received from the cloud. # \param errors: The errors received diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudCluster.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudCluster.py index dd1e2e85bf..28e95a097a 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudCluster.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudCluster.py @@ -11,7 +11,7 @@ class CloudCluster(BaseModel): self.host_name = None # type: str self.host_version = None # type: str self.status = None # type: str - self.is_online = None # type: bool + self.is_online = False # type: bool super().__init__(**kwargs) # Validates the model, raising an exception if the model is invalid. diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Utils.py b/plugins/UM3NetworkPrinting/src/Cloud/Utils.py new file mode 100644 index 0000000000..9a2a160492 --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Cloud/Utils.py @@ -0,0 +1,19 @@ +from typing import TypeVar, Dict, Tuple, List + +T = TypeVar("T") +U = TypeVar("U") + + +def findChanges(previous: Dict[str, T], received: Dict[str, U]) -> Tuple[List[T], List[U], List[Tuple[T, U]]]: + previous_ids = set(previous) + received_ids = set(received) + + removed_ids = previous_ids.difference(received_ids) + new_ids = received_ids.difference(previous_ids) + updated_ids = received_ids.intersection(previous_ids) + + removed = [previous[removed_id] for removed_id in removed_ids] + added = [received[new_id] for new_id in new_ids] + updated = [(previous[updated_id], received[updated_id]) for updated_id in updated_ids] + + return removed, added, updated diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index aa8be9ecd9..70f4d2d0ee 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -45,8 +45,8 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): activeCameraUrlChanged = pyqtSignal() receivedPrintJobsChanged = pyqtSignal() - # This is a bit of a hack, as the notify can only use signals that are defined by the class that they are in. - # Inheritance doesn't seem to work. Tying them together does work, but i'm open for better suggestions. + # Notify can only use signals that are defined by the class that they are in, not inherited ones. + # Therefore we create a private signal used to trigger the printersChanged signal. _clusterPrintersChanged = pyqtSignal() def __init__(self, device_id, address, properties, parent = None) -> None: @@ -62,7 +62,7 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../resources/qml/ClusterMonitorItem.qml") - # See comments about this hack with the clusterPrintersChanged signal + # trigger the printersChanged signal when the private signal is triggered self.printersChanged.connect(self._clusterPrintersChanged) self._accepts_commands = True # type: bool From 657e76331870f502adc6ce4424b6de20c67127ec Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 5 Dec 2018 16:15:51 +0100 Subject: [PATCH 0705/1292] STAR-322: Using findChanges method to simplify code --- .../src/Cloud/CloudOutputDevice.py | 41 +++++++++---------- plugins/UM3NetworkPrinting/src/Cloud/Utils.py | 7 ++++ .../src/MeshFormatHandler.py | 3 +- 3 files changed, 27 insertions(+), 24 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index e8f7687b03..980b9efa9e 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -24,6 +24,7 @@ from .Models.CloudPrintResponse import CloudPrintResponse from .Models.CloudJobResponse import CloudJobResponse from .Models.CloudClusterPrinter import CloudClusterPrinter from .Models.CloudClusterPrintJob import CloudClusterPrintJob +from .Utils import findChanges ## Class that contains all the translations for this module. @@ -198,45 +199,41 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self._updatePrintJobs(status.print_jobs) def _updatePrinters(self, printers: List[CloudClusterPrinter]) -> None: - remote_printers = {p.uuid: p for p in printers} # type: Dict[str, CloudClusterPrinter] - current_printers = {p.key: p for p in self._printers} # type: Dict[str, PrinterOutputModel] + previous = {p.key: p for p in self._printers} # type: Dict[str, PrinterOutputModel] + received = {p.uuid: p for p in printers} # type: Dict[str, CloudClusterPrinter] - remote_printer_ids = set(remote_printers) # type: Set[str] - current_printer_ids = set(current_printers) # type: Set[str] + removed_printers, added_printers, updated_printers = findChanges(previous, received) - for removed_printer_id in current_printer_ids.difference(remote_printer_ids): - removed_printer = current_printers[removed_printer_id] + for removed_printer in removed_printers: self._printers.remove(removed_printer) - for new_printer_id in remote_printer_ids.difference(current_printer_ids): - new_printer = remote_printers[new_printer_id] + for added_printer in added_printers: controller = PrinterOutputController(self) - self._printers.append(new_printer.createOutputModel(controller)) + self._printers.append(added_printer.createOutputModel(controller)) - for updated_printer_guid in current_printer_ids.intersection(remote_printer_ids): - remote_printers[updated_printer_guid].updateOutputModel(current_printers[updated_printer_guid]) + for model, printer in updated_printers: + printer.updateOutputModel(model) self._clusterPrintersChanged.emit() def _updatePrintJobs(self, jobs: List[CloudClusterPrintJob]) -> None: - remote_jobs = {j.uuid: j for j in jobs} # type: Dict[str, CloudClusterPrintJob] - current_jobs = {j.key: j for j in self._print_jobs} # type: Dict[str, UM3PrintJobOutputModel] + received = {j.uuid: j for j in jobs} # type: Dict[str, CloudClusterPrintJob] + previous = {j.key: j for j in self._print_jobs} # type: Dict[str, UM3PrintJobOutputModel] - remote_job_ids = set(remote_jobs) # type: Set[str] - current_job_ids = set(current_jobs) # type: Set[str] + removed_jobs, added_jobs, updated_jobs = findChanges(previous, received) - for removed_job_id in current_job_ids.difference(remote_job_ids): - self._print_jobs.remove(current_jobs[removed_job_id]) + for removed_job in removed_jobs: + self._print_jobs.remove(removed_job) - for new_job_id in remote_job_ids.difference(current_job_ids): - self._addPrintJob(remote_jobs[new_job_id]) + for added_job in added_jobs: + self._addPrintJob(added_job) - for updated_job_id in current_job_ids.intersection(remote_job_ids): - remote_jobs[updated_job_id].updateOutputModel(current_jobs[updated_job_id]) + for model, job in updated_jobs: + job.updateOutputModel(model) # We only have to update when jobs are added or removed # updated jobs push their changes via their output model - if remote_job_ids != current_job_ids: + if added_jobs or removed_jobs: self.printJobsChanged.emit() def _addPrintJob(self, job: CloudClusterPrintJob) -> None: diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Utils.py b/plugins/UM3NetworkPrinting/src/Cloud/Utils.py index 9a2a160492..58eaf5edb9 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Utils.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Utils.py @@ -4,6 +4,13 @@ T = TypeVar("T") U = TypeVar("U") +## Splits the given dictionaries into three lists (in a tuple): +# - `removed`: Items that were in the first argument but removed in the second one. +# - `added`: Items that were not in the first argument but were included in the second one. +# - `updated`: Items that were in both dictionaries. Both values are given in a tuple. +# \param previous: The previous items +# \param received: The received items +# \return: The tuple (removed, added, updated) as explained above. def findChanges(previous: Dict[str, T], received: Dict[str, U]) -> Tuple[List[T], List[U], List[Tuple[T, U]]]: previous_ids = set(previous) received_ids = set(received) diff --git a/plugins/UM3NetworkPrinting/src/MeshFormatHandler.py b/plugins/UM3NetworkPrinting/src/MeshFormatHandler.py index c2bd997fbb..d64861ea91 100644 --- a/plugins/UM3NetworkPrinting/src/MeshFormatHandler.py +++ b/plugins/UM3NetworkPrinting/src/MeshFormatHandler.py @@ -15,8 +15,7 @@ from cura.CuraApplication import CuraApplication ## Class that contains all the translations for this module. class T: - # The translation catalog for this device. - + # The translation catalog for this module. _I18N_CATALOG = i18nCatalog("cura") NO_FORMATS_AVAILABLE = _I18N_CATALOG.i18nc("@info:status", "There are no file formats available to write with!") From 117cf10a2c60fa4687044ef473303b184634660d Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 5 Dec 2018 16:26:20 +0100 Subject: [PATCH 0706/1292] STAR-322: Removing devices when logging off --- plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py | 2 +- .../src/Cloud/CloudOutputDeviceManager.py | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py index 3ede206d45..b4c8774140 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py @@ -129,7 +129,7 @@ class CloudApiClient(NetworkClient): data = response["data"] result = [model(**c) for c in data] if isinstance(data, list) else model(**data) on_finished(result) - elif "error" in response: + elif "errors" in response: self._on_error([CloudErrorObject(**error) for error in response["errors"]]) else: Logger.log("e", "Cannot find data or errors in the cloud response: %s", response) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index f11d41a7bd..29514870ac 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -62,6 +62,10 @@ class CloudOutputDeviceManager: # The first call to _getRemoteClusters comes from self._account.loginStateChanged if not self._update_timer.isActive(): self._update_timer.start() + else: + self._onGetRemoteClustersFinished([]) + if self._update_timer.isActive(): + self._update_timer.stop() ## Callback for when the request for getting the clusters. is finished. def _onGetRemoteClustersFinished(self, clusters: List[CloudCluster]) -> None: @@ -73,6 +77,8 @@ class CloudOutputDeviceManager: # Remove output devices that are gone for removed_cluster in removed_devices: + if removed_cluster.isConnected(): + removed_cluster.disconnect() self._output_device_manager.removeOutputDevice(removed_cluster.key) del self._remote_clusters[removed_cluster.key] From 5e15858cae6f36596b806841e94390c2b1fd13fb Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Wed, 5 Dec 2018 17:05:21 +0100 Subject: [PATCH 0707/1292] more mocks for monitor page, fix showing current print job in monitor page, add todo --- .../src/Cloud/CloudOutputDevice.py | 20 ++++++++++++++++--- .../src/Cloud/Models/CloudClusterPrintJob.py | 7 ++++--- .../src/ClusterUM3OutputDevice.py | 5 +++-- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 980b9efa9e..ec7e7f4acf 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -155,9 +155,13 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## Get remote printers. @pyqtProperty("QVariantList", notify = _clusterPrintersChanged) - def printers(self): + def printers(self) -> List[PrinterOutputModel]: return self._printers + @pyqtProperty(int, notify = _clusterPrintersChanged) + def clusterSize(self) -> int: + return len(self._printers) + ## Get remote print jobs. @pyqtProperty("QVariantList", notify = printJobsChanged) def printJobs(self)-> List[UM3PrintJobOutputModel]: @@ -237,13 +241,15 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self.printJobsChanged.emit() def _addPrintJob(self, job: CloudClusterPrintJob) -> None: + # TODO: somehow we don't see the queued print jobs on the monitor page yet, we have to figure out why. try: - printer = next(p for p in self._printers if job.printer_uuid == p.key) + printer = next(p for p in self._printers if job.printer_uuid == p.key or job.assigned_to == p.key) except StopIteration: return Logger.log("w", "Missing printer %s for job %s in %s", job.printer_uuid, job.uuid, [p.key for p in self._printers]) - self._print_jobs.append(job.createOutputModel(printer)) + print_job = job.createOutputModel(printer) + self._print_jobs.append(print_job) def _onPrintJobCreated(self, mesh: bytes, job_response: CloudJobResponse) -> None: self._api.uploadMesh(job_response, mesh, self._onPrintJobUploaded, self._updateUploadProgress, @@ -321,3 +327,11 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): @pyqtProperty(bool, notify = printJobsChanged) def receivedPrintJobs(self) -> bool: return True + + @pyqtSlot() + def openPrintJobControlPanel(self) -> None: + pass + + @pyqtSlot() + def openPrinterControlPanel(self) -> None: + pass diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py index e2e3787435..36d878d46f 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py @@ -1,6 +1,6 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import List +from typing import List, Optional from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from .CloudClusterPrinterConfiguration import CloudClusterPrinterConfiguration @@ -33,14 +33,15 @@ class CloudClusterPrintJob(BaseModel): super().__init__(**kwargs) self.printers = [CloudClusterPrinterConfiguration(**c) if isinstance(c, dict) else c for c in self.configuration] - self.printers = [CloudClusterPrintJobConstraint(**p) if isinstance(p, dict) else p - for p in self.constraints] + self.print_jobs = [CloudClusterPrintJobConstraint(**p) if isinstance(p, dict) else p + for p in self.constraints] ## Creates an UM3 print job output model based on this cloud cluster print job. # \param printer: The output model of the printer def createOutputModel(self, printer: PrinterOutputModel) -> UM3PrintJobOutputModel: model = UM3PrintJobOutputModel(printer.getController(), self.uuid, self.name) model.updateAssignedPrinter(printer) + printer.updateActivePrintJob(model) return model ## Updates an UM3 print job output model based on this cloud cluster print job. diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index 70f4d2d0ee..965a698029 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -411,8 +411,9 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): ## Called when the connection to the cluster changes. def connect(self) -> None: - super().connect() - self.sendMaterialProfiles() + pass + # super().connect() + # self.sendMaterialProfiles() def _onGetPreviewImageFinished(self, reply: QNetworkReply) -> None: reply_url = reply.url().toString() From 66690dfef72e0e8466927d0d71d7fa84c86ff18e Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Wed, 5 Dec 2018 17:06:22 +0100 Subject: [PATCH 0708/1292] Add testing todo --- plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index 965a698029..cc5b128479 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -412,6 +412,7 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): ## Called when the connection to the cluster changes. def connect(self) -> None: pass + # TODO: uncomment this once cloud implementation works for testing # super().connect() # self.sendMaterialProfiles() From ce07e31bbf299f4ec86f24fd7acd66795ec14da3 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Wed, 5 Dec 2018 17:21:46 +0100 Subject: [PATCH 0709/1292] Implement active printer for cloud device to get monitor page functionality working --- .../src/Cloud/CloudOutputDevice.py | 86 ++++++++++++++++--- 1 file changed, 75 insertions(+), 11 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index ec7e7f4acf..9dab829825 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -1,6 +1,8 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import os +from datetime import datetime + from time import time from typing import Dict, List, Optional, Set @@ -10,6 +12,7 @@ from UM import i18nCatalog from UM.FileHandler.FileHandler import FileHandler from UM.Logger import Logger from UM.Message import Message +from UM.Qt.Duration import Duration, DurationFormat from UM.Scene.SceneNode import SceneNode from cura.CuraApplication import CuraApplication from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState, NetworkedPrinterOutputDevice @@ -66,6 +69,9 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # Signal triggered when the print jobs in the queue were changed. printJobsChanged = pyqtSignal() + # Signal triggered when the selected printer in the UI should be changed. + activePrinterChanged = pyqtSignal() + # Notify can only use signals that are defined by the class that they are in, not inherited ones. # Therefore we create a private signal used to trigger the printersChanged signal. _clusterPrintersChanged = pyqtSignal() @@ -90,9 +96,12 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self._control_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../resources/qml/ClusterControlItem.qml") - # trigger the printersChanged signal when the private signal is triggered + # Trigger the printersChanged signal when the private signal is triggered. self.printersChanged.connect(self._clusterPrintersChanged) + # We keep track of which printer is visible in the monitor page. + self._active_printer = None # type: Optional[PrinterOutputModel] + # Properties to populate later on with received cloud data. self._print_jobs = [] # type: List[UM3PrintJobOutputModel] self._number_of_extruders = 2 # All networked printers are dual-extrusion Ultimaker machines. @@ -158,6 +167,18 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def printers(self) -> List[PrinterOutputModel]: return self._printers + ## Get the active printer in the UI (monitor page). + @pyqtProperty(QObject, notify = activePrinterChanged) + def activePrinter(self) -> Optional[PrinterOutputModel]: + return self._active_printer + + ## Set the active printer in the UI (monitor page). + @pyqtSlot(QObject) + def setActivePrinter(self, printer: Optional[PrinterOutputModel] = None) -> None: + if printer != self._active_printer: + self._active_printer = printer + self.activePrinterChanged.emit() + @pyqtProperty(int, notify = _clusterPrintersChanged) def clusterSize(self) -> int: return len(self._printers) @@ -179,6 +200,37 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): return [print_job for print_job in self._print_jobs if print_job.assignedPrinter is not None and print_job.state != "queued"] + @pyqtSlot(int, result = str) + def formatDuration(self, seconds: int) -> str: + # TODO: this really shouldn't be in this class + return Duration(seconds).getDisplayString(DurationFormat.Format.Short) + + @pyqtSlot(int, result = str) + def getTimeCompleted(self, time_remaining: int) -> str: + # TODO: this really shouldn't be in this class + current_time = time() + datetime_completed = datetime.fromtimestamp(current_time + time_remaining) + return "{hour:02d}:{minute:02d}".format(hour = datetime_completed.hour, minute = datetime_completed.minute) + + @pyqtSlot(int, result = str) + def getDateCompleted(self, time_remaining: int) -> str: + # TODO: this really shouldn't be in this class + current_time = time() + completed = datetime.fromtimestamp(current_time + time_remaining) + today = datetime.fromtimestamp(current_time) + # If finishing date is more than 7 days out, using "Mon Dec 3 at HH:MM" format + if completed.toordinal() > today.toordinal() + 7: + return completed.strftime("%a %b ") + "{day}".format(day = completed.day) + # If finishing date is within the next week, use "Monday at HH:MM" format + elif completed.toordinal() > today.toordinal() + 1: + return completed.strftime("%a") + # If finishing tomorrow, use "tomorrow at HH:MM" format + elif completed.toordinal() > today.toordinal(): + return "tomorrow" + # If finishing today, use "today at HH:MM" format + else: + return "today" + ## Called when the connection to the cluster changes. def connect(self) -> None: super().connect() @@ -209,6 +261,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): removed_printers, added_printers, updated_printers = findChanges(previous, received) for removed_printer in removed_printers: + if self._active_printer == removed_printer: + self.setActivePrinter(None) self._printers.remove(removed_printer) for added_printer in added_printers: @@ -218,6 +272,10 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): for model, printer in updated_printers: printer.updateOutputModel(model) + # Always have an active printer + if not self._active_printer: + self.setActivePrinter(self._printers[0]) + self._clusterPrintersChanged.emit() def _updatePrintJobs(self, jobs: List[CloudClusterPrintJob]) -> None: @@ -306,16 +364,6 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## TODO: The following methods are required by the monitor page QML, but are not actually available using cloud. # TODO: We fake the methods here to not break the monitor page. - @pyqtProperty(QObject, notify = _clusterPrintersChanged) - def activePrinter(self) -> Optional[PrinterOutputModel]: - if not self._printers: - return None - return self._printers[0] - - @pyqtSlot(QObject) - def setActivePrinter(self, printer: Optional[PrinterOutputModel]) -> None: - pass - @pyqtProperty(QUrl, notify = _clusterPrintersChanged) def activeCameraUrl(self) -> "QUrl": return QUrl() @@ -335,3 +383,19 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): @pyqtSlot() def openPrinterControlPanel(self) -> None: pass + + @pyqtSlot(str) + def sendJobToTop(self, print_job_uuid: str) -> None: + pass + + @pyqtSlot(str) + def deleteJobFromQueue(self, print_job_uuid: str) -> None: + pass + + @pyqtSlot(str) + def forceSendJob(self, print_job_uuid: str) -> None: + pass + + @pyqtProperty("QVariantList", notify = _clusterPrintersChanged) + def connectedPrintersTypeCount(self) -> List[Dict[str, str]]: + return [] From 94f31378a68b8daa05cc3b7e3434107171fd2540 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Wed, 5 Dec 2018 17:24:47 +0100 Subject: [PATCH 0710/1292] Add a TODO --- .../UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py index 36d878d46f..f4d211f8f4 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py @@ -40,6 +40,7 @@ class CloudClusterPrintJob(BaseModel): # \param printer: The output model of the printer def createOutputModel(self, printer: PrinterOutputModel) -> UM3PrintJobOutputModel: model = UM3PrintJobOutputModel(printer.getController(), self.uuid, self.name) + # TODO: implement more data as shown in ClusterUM3OutputDevice._createPrintJobModel model.updateAssignedPrinter(printer) printer.updateActivePrintJob(model) return model From 57efca13769a9328c5e2ac31efc66201ef89c540 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Wed, 5 Dec 2018 19:31:58 +0100 Subject: [PATCH 0711/1292] Fix a possible division by zero error --- cura/PrinterOutput/PrintJobOutputModel.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cura/PrinterOutput/PrintJobOutputModel.py b/cura/PrinterOutput/PrintJobOutputModel.py index 256c9dffe9..a77ac81909 100644 --- a/cura/PrinterOutput/PrintJobOutputModel.py +++ b/cura/PrinterOutput/PrintJobOutputModel.py @@ -132,9 +132,9 @@ class PrintJobOutputModel(QObject): @pyqtProperty(float, notify = timeElapsedChanged) def progress(self) -> float: - result = self.timeElapsed / self.timeTotal - # Never get a progress past 1.0 - return min(result, 1.0) + time_elapsed = max(float(self.timeElapsed), 1.0) # Prevent a division by zero exception + result = time_elapsed / self.timeTotal + return min(result, 1.0) # Never get a progress past 1.0 @pyqtProperty(str, notify=stateChanged) def state(self) -> str: From c757bf128e9fae8895973956a671fc0bcc430b31 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 6 Dec 2018 09:12:43 +0100 Subject: [PATCH 0712/1292] Adjust colors and alignments in the print info panel --- resources/qml/Cura.qml | 6 +++--- resources/qml/ExpandableComponent.qml | 2 +- resources/themes/cura-light/theme.json | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 6559fafa12..ba1230f37d 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -226,8 +226,8 @@ UM.MainWindow { left: parent.left bottom: viewOrientationControls.top - margins: UM.Theme.getSize("wide_margin").width - bottomMargin: UM.Theme.getSize("default_margin").width + margins: UM.Theme.getSize("default_margin").width + bottomMargin: UM.Theme.getSize("thin_margin").width } } @@ -239,7 +239,7 @@ UM.MainWindow { left: parent.left bottom: parent.bottom - margins: UM.Theme.getSize("wide_margin").width + margins: UM.Theme.getSize("default_margin").width } } diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index 9bedaa940c..3991ed74ba 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -142,7 +142,7 @@ Item visible: source != "" width: height height: Math.round(0.2 * base.height) - color: UM.Theme.getColor("text") + color: UM.Theme.getColor("small_button_text") } MouseArea diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 767b6eaccd..3cea54ac77 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -123,8 +123,8 @@ "text_subtext": [0, 0, 0, 255], "text_medium": [128, 128, 128, 255], "text_emphasis": [255, 255, 255, 255], - "text_scene": [31, 36, 39, 255], - "text_scene_hover": [70, 84, 113, 255], + "text_scene": [102, 102, 102, 255], + "text_scene_hover": [123, 123, 113, 255], "error": [255, 140, 0, 255], "warning": [255, 190, 35, 255], @@ -144,10 +144,10 @@ "button_text_active_hover": [255, 255, 255, 255], "small_button": [0, 0, 0, 0], - "small_button_hover": [10, 8, 80, 255], + "small_button_hover": [102, 102, 102, 255], "small_button_active": [10, 8, 80, 255], "small_button_active_hover": [10, 8, 80, 255], - "small_button_text": [171, 171, 191, 255], + "small_button_text": [102, 102, 102, 255], "small_button_text_hover": [255, 255, 255, 255], "small_button_text_active": [255, 255, 255, 255], "small_button_text_active_hover": [255, 255, 255, 255], From b0c3a4e17a558154807a7807218367cb1b158a64 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 6 Dec 2018 09:25:31 +0100 Subject: [PATCH 0713/1292] Align the additional components to the right of the job specs The model checker now shows centered --- plugins/ModelChecker/ModelChecker.qml | 12 +++++++----- resources/qml/JobSpecs.qml | 21 +++++++++++---------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/plugins/ModelChecker/ModelChecker.qml b/plugins/ModelChecker/ModelChecker.qml index 437df29516..ddeed063b1 100644 --- a/plugins/ModelChecker/ModelChecker.qml +++ b/plugins/ModelChecker/ModelChecker.qml @@ -4,19 +4,19 @@ import QtQuick 2.2 import QtQuick.Controls 1.1 import QtQuick.Controls.Styles 1.1 -import QtQuick.Layouts 1.1 -import QtQuick.Dialogs 1.1 -import QtQuick.Window 2.2 import UM 1.2 as UM -import Cura 1.0 as Cura Button { id: modelCheckerButton - UM.I18nCatalog{id: catalog; name: "cura"} + UM.I18nCatalog + { + id: catalog + name: "cura" + } visible: manager.hasWarnings tooltip: catalog.i18nc("@info:tooltip", "Some things could be problematic in this print. Click to see tips for adjustment.") @@ -25,6 +25,8 @@ Button width: UM.Theme.getSize("save_button_specs_icons").width height: UM.Theme.getSize("save_button_specs_icons").height + anchors.verticalCenter: parent ? parent.verticalCenter : undefined + style: ButtonStyle { background: Item diff --git a/resources/qml/JobSpecs.qml b/resources/qml/JobSpecs.qml index 97e12e15a3..8b06ab06db 100644 --- a/resources/qml/JobSpecs.qml +++ b/resources/qml/JobSpecs.qml @@ -108,19 +108,11 @@ Item } } - Row - { - id: additionalComponentsRow - anchors.top: jobNameRow.bottom - anchors.left: parent.left - } - Label { id: boundingSpec anchors.top: jobNameRow.bottom - anchors.left: additionalComponentsRow.right - anchors.leftMargin: additionalComponentsRow.width > 0 ? UM.Theme.getSize("default_margin").width : 0 + anchors.left: parent.left height: UM.Theme.getSize("jobspecs_line").height verticalAlignment: Text.AlignVCenter @@ -129,6 +121,15 @@ Item text: CuraApplication.getSceneBoundingBoxString } + Row + { + id: additionalComponentsRow + anchors.top: boundingSpec.top + anchors.bottom: boundingSpec.bottom + anchors.left: boundingSpec.right + anchors.leftMargin: UM.Theme.getSize("default_margin").width + } + Component.onCompleted: { base.addAdditionalComponents("jobSpecsButton") @@ -140,7 +141,7 @@ Item onAdditionalComponentsChanged: base.addAdditionalComponents("jobSpecsButton") } - function addAdditionalComponents (areaId) + function addAdditionalComponents(areaId) { if (areaId == "jobSpecsButton") { From 838949dac74831e38e9f07fe7d628af7807320db Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 6 Dec 2018 09:45:27 +0100 Subject: [PATCH 0714/1292] Moved qml pages of toolbox to a loader This dramatically improves the loading of the toolbox dialog CURA-6006 --- plugins/Toolbox/resources/qml/Toolbox.qml | 54 ++++++++++----------- plugins/Toolbox/src/Toolbox.py | 59 +++++++++++------------ 2 files changed, 52 insertions(+), 61 deletions(-) diff --git a/plugins/Toolbox/resources/qml/Toolbox.qml b/plugins/Toolbox/resources/qml/Toolbox.qml index 853cec399d..d3d980b0b3 100644 --- a/plugins/Toolbox/resources/qml/Toolbox.qml +++ b/plugins/Toolbox/resources/qml/Toolbox.qml @@ -44,36 +44,31 @@ Window top: header.bottom bottom: footer.top } - // TODO: This could be improved using viewFilter instead of viewCategory - ToolboxLoadingPage + + Loader { - id: viewLoading - visible: toolbox.viewCategory != "installed" && toolbox.viewPage == "loading" - } - ToolboxErrorPage - { - id: viewErrored - visible: toolbox.viewCategory != "installed" && toolbox.viewPage == "errored" - } - ToolboxDownloadsPage - { - id: viewDownloads - visible: toolbox.viewCategory != "installed" && toolbox.viewPage == "overview" - } - ToolboxDetailPage - { - id: viewDetail - visible: toolbox.viewCategory != "installed" && toolbox.viewPage == "detail" - } - ToolboxAuthorPage - { - id: viewAuthor - visible: toolbox.viewCategory != "installed" && toolbox.viewPage == "author" - } - ToolboxInstalledPage - { - id: installedPluginList - visible: toolbox.viewCategory == "installed" + anchors.fill:parent + source: + { + if(toolbox.viewCategory == "installed") + { + return "ToolboxInstalledPage.qml" + } + + switch (toolbox.viewPage) + { + case "loading": + return "ToolboxLoadingPage.qml" + case "errored": + return "ToolboxErrorPage.qml" + case "overview": + return "ToolboxDownloadsPage.qml" + case "detail": + return "ToolboxDetailPage.qml" + case "author": + return "ToolboxAuthorPage.qml" + } + } } } @@ -95,6 +90,7 @@ Window licenseDialog.show(); } } + ToolboxLicenseDialog { id: licenseDialog diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index cd20d26eca..c8349827a9 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -622,44 +622,39 @@ class Toolbox(QObject, Extension): if reply.operation() == QNetworkAccessManager.GetOperation: for response_type, url in self._request_urls.items(): - if reply.url() == url: - if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) == 200: - try: - json_data = json.loads(bytes(reply.readAll()).decode("utf-8")) + if reply.url() != url: + continue - # Check for errors: - if "errors" in json_data: - for error in json_data["errors"]: - Logger.log("e", "%s", error["title"]) - return + if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) == 200: + try: + json_data = json.loads(bytes(reply.readAll()).decode("utf-8")) + except json.decoder.JSONDecodeError: + Logger.log("w", "Received invalid JSON for %s.", response_type) + break - # Create model and apply metadata: - if not self._models[response_type]: - Logger.log("e", "Could not find the %s model.", response_type) - break - - self._server_response_data[response_type] = json_data["data"] - self._models[response_type].setMetadata(self._server_response_data[response_type]) + # Check for errors: + if "errors" in json_data: + for error in json_data["errors"]: + Logger.log("e", "%s", error["title"]) + return - if response_type is "packages": - self._models[response_type].setFilter({"type": "plugin"}) - self.reBuildMaterialsModels() - self.reBuildPluginsModels() - elif response_type is "authors": - self._models[response_type].setFilter({"package_types": "material"}) - self._models[response_type].setFilter({"tags": "generic"}) + self._server_response_data[response_type] = json_data["data"] + self._models[response_type].setMetadata(json_data["data"]) - self.metadataChanged.emit() + if response_type is "packages": + self._models["packages"].setFilter({"type": "plugin"}) + self.reBuildMaterialsModels() + self.reBuildPluginsModels() + elif response_type is "authors": + self._models["authors"].setFilter({"tags": "generic"}) - if self.isLoadingComplete(): - self.setViewPage("overview") + self.metadataChanged.emit() - except json.decoder.JSONDecodeError: - Logger.log("w", "Received invalid JSON for %s.", response_type) - break - else: - self.setViewPage("errored") - self.resetDownload() + if self.isLoadingComplete(): + self.setViewPage("overview") + else: + self.setViewPage("errored") + self.resetDownload() else: # Ignore any operation that is not a get operation pass From 6a466c99b241035a6dc6d9cbbf174f39d51aad3d Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 6 Dec 2018 09:54:32 +0100 Subject: [PATCH 0715/1292] Make the progressButton use signals instead of functions Although the naming is still a bit off, it's much cleaner to use signals instead of functions. It's also more in line with how default QML components handle these kind of situations CURA-6006 --- plugins/Toolbox/resources/qml/Toolbox.qml | 2 +- .../qml/ToolboxDetailTileActions.qml | 23 ++++++++----------- .../qml/ToolboxInstalledTileActions.qml | 8 +++---- .../resources/qml/ToolboxProgressButton.qml | 12 +++++----- 4 files changed, 19 insertions(+), 26 deletions(-) diff --git a/plugins/Toolbox/resources/qml/Toolbox.qml b/plugins/Toolbox/resources/qml/Toolbox.qml index d3d980b0b3..b2bab4355a 100644 --- a/plugins/Toolbox/resources/qml/Toolbox.qml +++ b/plugins/Toolbox/resources/qml/Toolbox.qml @@ -90,7 +90,7 @@ Window licenseDialog.show(); } } - + ToolboxLicenseDialog { id: licenseDialog diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml b/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml index cd1e4cdbda..72a9d14dcd 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml @@ -18,19 +18,15 @@ Column id: installButton active: toolbox.isDownloading && toolbox.activePackage == model complete: installed - readyAction: function() + onReadyAction: { toolbox.activePackage = model toolbox.startDownload(model.download_url) } - activeAction: function() - { - toolbox.cancelDownload() - } - completeAction: function() - { - toolbox.viewCategory = "installed" - } + onActiveAction: toolbox.cancelDownload() + + onCompleteAction: toolbox.viewCategory = "installed" + // Don't allow installing while another download is running enabled: installed || !(toolbox.isDownloading && toolbox.activePackage != model) opacity: enabled ? 1.0 : 0.5 @@ -44,20 +40,19 @@ Column readyLabel: catalog.i18nc("@action:button", "Update") activeLabel: catalog.i18nc("@action:button", "Updating") completeLabel: catalog.i18nc("@action:button", "Updated") - readyAction: function() + + onReadyAction: { toolbox.activePackage = model toolbox.update(model.id) } - activeAction: function() - { - toolbox.cancelDownload() - } + onActiveAction: toolbox.cancelDownload() // Don't allow installing while another download is running enabled: !(toolbox.isDownloading && toolbox.activePackage != model) opacity: enabled ? 1.0 : 0.5 visible: canUpdate } + Connections { target: toolbox diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml index 8fd88b1cfd..621ecd96ea 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml @@ -30,15 +30,13 @@ Column readyLabel: catalog.i18nc("@action:button", "Update") activeLabel: catalog.i18nc("@action:button", "Updating") completeLabel: catalog.i18nc("@action:button", "Updated") - readyAction: function() + onReadyAction: { toolbox.activePackage = model toolbox.update(model.id) } - activeAction: function() - { - toolbox.cancelDownload() - } + onActiveAction: toolbox.cancelDownload() + // Don't allow installing while another download is running enabled: !(toolbox.isDownloading && toolbox.activePackage != model) opacity: enabled ? 1.0 : 0.5 diff --git a/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml b/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml index 2744e40ec9..00b0b985f5 100644 --- a/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml +++ b/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml @@ -18,9 +18,9 @@ Item property var activeLabel: catalog.i18nc("@action:button", "Cancel") property var completeLabel: catalog.i18nc("@action:button", "Installed") - property var readyAction: null // Action when button is ready and clicked (likely install) - property var activeAction: null // Action when button is active and clicked (likely cancel) - property var completeAction: null // Action when button is complete and clicked (likely go to installed) + signal readyAction() // Action when button is ready and clicked (likely install) + signal activeAction() // Action when button is active and clicked (likely cancel) + signal completeAction() // Action when button is complete and clicked (likely go to installed) width: UM.Theme.getSize("toolbox_action_button").width height: UM.Theme.getSize("toolbox_action_button").height @@ -47,15 +47,15 @@ Item { if (complete) { - return completeAction() + completeAction() } else if (active) { - return activeAction() + activeAction() } else { - return readyAction() + readyAction() } } style: ButtonStyle From eb3777ed9fb48ed6f0385c230d9f12fc5aa338f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Thu, 6 Dec 2018 10:40:06 +0100 Subject: [PATCH 0716/1292] Cleaner login and update cluster flow, start update cluster timer at startup when the user is already logged in --- .../src/Cloud/CloudOutputDeviceManager.py | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 29514870ac..5d55d30548 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -41,7 +41,7 @@ class CloudOutputDeviceManager: self._output_device_manager = application.getOutputDeviceManager() self._account = application.getCuraAPI().account - self._account.loginStateChanged.connect(self._getRemoteClusters) + self._account.loginStateChanged.connect(self._onLoginStateChanged) self._api = CloudApiClient(self._account, self._onApiError) # When switching machines we check if we have to activate a remote cluster. @@ -49,23 +49,26 @@ class CloudOutputDeviceManager: # create a timer to update the remote cluster list self._update_timer = QTimer(application) - self._update_timer.setInterval(self.CHECK_CLUSTER_INTERVAL * 1000) + self._update_timer.setInterval(int(self.CHECK_CLUSTER_INTERVAL * 1000)) self._update_timer.setSingleShot(False) self._update_timer.timeout.connect(self._getRemoteClusters) + # Make sure the timer is started in case we missed the loginChanged signal + self._onLoginStateChanged() + + # Called when the uses logs in or out + def _onLoginStateChanged(self) -> None: + if self._account.isLoggedIn and not self._update_timer.isActive(): + self._update_timer.start() + else: + self._update_timer.stop() + # Notify that all clusters have disappeared + self._onGetRemoteClustersFinished([]) + ## Gets all remote clusters from the API. def _getRemoteClusters(self) -> None: Logger.log("i", "Retrieving remote clusters") - if self._account.isLoggedIn: - self._api.getClusters(self._onGetRemoteClustersFinished) - # Only start the polling timer after the user is authenticated - # The first call to _getRemoteClusters comes from self._account.loginStateChanged - if not self._update_timer.isActive(): - self._update_timer.start() - else: - self._onGetRemoteClustersFinished([]) - if self._update_timer.isActive(): - self._update_timer.stop() + self._api.getClusters(self._onGetRemoteClustersFinished) ## Callback for when the request for getting the clusters. is finished. def _onGetRemoteClustersFinished(self, clusters: List[CloudCluster]) -> None: From 2602d5bf02287745831d3d264bbc8e3dcda37541 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 6 Dec 2018 10:46:19 +0100 Subject: [PATCH 0717/1292] Add changed checks to prevent unneeded signals from being fired CURA-6006 --- plugins/Toolbox/src/Toolbox.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index c8349827a9..68919cf987 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -546,7 +546,7 @@ class Toolbox(QObject, Extension): # Check for plugins that were installed with the old plugin browser def isOldPlugin(self, plugin_id: str) -> bool: - return plugin_id in self._old_plugin_ids + return plugin_id in self._old_plugin_ids def getOldPluginPackageMetadata(self, plugin_id: str) -> Optional[Dict[str, Any]]: return self._old_plugin_metadata.get(plugin_id) @@ -709,8 +709,9 @@ class Toolbox(QObject, Extension): return self._is_downloading def setActivePackage(self, package: Dict[str, Any]) -> None: - self._active_package = package - self.activePackageChanged.emit() + if self._active_package != package: + self._active_package = package + self.activePackageChanged.emit() ## The active package is the package that is currently being downloaded @pyqtProperty(QObject, fset = setActivePackage, notify = activePackageChanged) @@ -718,16 +719,18 @@ class Toolbox(QObject, Extension): return self._active_package def setViewCategory(self, category: str = "plugin") -> None: - self._view_category = category - self.viewChanged.emit() + if self._view_category != category: + self._view_category = category + self.viewChanged.emit() @pyqtProperty(str, fset = setViewCategory, notify = viewChanged) def viewCategory(self) -> str: return self._view_category def setViewPage(self, page: str = "overview") -> None: - self._view_page = page - self.viewChanged.emit() + if self._view_page != page: + self._view_page = page + self.viewChanged.emit() @pyqtProperty(str, fset = setViewPage, notify = viewChanged) def viewPage(self) -> str: From f7f3c96f81d82cead247c3ecd0d3925d79047a48 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 6 Dec 2018 10:53:40 +0100 Subject: [PATCH 0718/1292] Fix typo CURA-5941 --- .../Recommended/RecommendedAdhesionSelector.qml | 2 +- .../Recommended/RecommendedInfillDensitySelector.qml | 2 +- .../Recommended/RecommendedPrintSetup.qml | 2 +- .../Recommended/RecommendedSupportSelector.qml | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedAdhesionSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedAdhesionSelector.qml index 3092644d4e..a5f35f333b 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedAdhesionSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedAdhesionSelector.qml @@ -50,7 +50,7 @@ Item //: Setting enable printing build-plate adhesion helper checkbox style: UM.Theme.styles.checkbox - enabled: recommendedPrintSettup.settingsEnabled + enabled: recommendedPrintSetup.settingsEnabled visible: platformAdhesionType.properties.enabled == "True" checked: platformAdhesionType.properties.value != "skirt" && platformAdhesionType.properties.value != "none" diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml index 7c026ac9de..2971415948 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml @@ -189,7 +189,7 @@ Item text: catalog.i18nc("@label", "Gradual infill") style: UM.Theme.styles.checkbox - enabled: recommendedPrintSettup.settingsEnabled + enabled: recommendedPrintSetup.settingsEnabled visible: infillSteps.properties.enabled == "True" checked: parseInt(infillSteps.properties.value) > 0 diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml index 618c519d31..6885f8c041 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml @@ -10,7 +10,7 @@ import Cura 1.0 as Cura Item { - id: recommendedPrintSettup + id: recommendedPrintSetup height: childrenRect.height + 2 * padding diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml index da46f2a735..57e0c8ce6b 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml @@ -50,7 +50,7 @@ Item property alias _hovered: enableSupportMouseArea.containsMouse style: UM.Theme.styles.checkbox - enabled: recommendedPrintSettup.settingsEnabled + enabled: recommendedPrintSetup.settingsEnabled visible: supportEnabled.properties.enabled == "True" checked: supportEnabled.properties.value == "True" @@ -87,7 +87,7 @@ Item } style: UM.Theme.styles.combobox_color - enabled: recommendedPrintSettup.settingsEnabled + enabled: recommendedPrintSetup.settingsEnabled visible: enableSupportCheckBox.visible && (supportEnabled.properties.value == "True") && (extrudersEnabledCount.properties.value > 1) textRole: "text" // this solves that the combobox isn't populated in the first time Cura is started @@ -127,7 +127,7 @@ Item id: supportExtruderMouseArea anchors.fill: parent hoverEnabled: true - enabled: recommendedPrintSettup.settingsEnabled + enabled: recommendedPrintSetup.settingsEnabled acceptedButtons: Qt.NoButton onEntered: { From 48e15daf6410e19fd8eb658061a925c4e714ee1b Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 6 Dec 2018 11:16:42 +0100 Subject: [PATCH 0719/1292] Fix height of scroll view and make scrollable Contributes to issue CURA-5876. --- resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml | 2 +- .../qml/Menus/ConfigurationMenu/ConfigurationListView.qml | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index af2712be44..6ac1e6a2ad 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -14,7 +14,7 @@ Button property var configuration: null hoverEnabled: true - height: childrenRect.height + height: background.height background: Rectangle { diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index 5a9f72260c..d07337f9c5 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -28,7 +28,9 @@ Column { id: container width: parent.width - height: Math.min(configurationList.contentHeight, 350 * screenScaleFactor) + height: Math.round(Math.min(configurationList.height, 350 * screenScaleFactor)) + contentHeight: configurationList.height + clip: true ButtonGroup { @@ -41,6 +43,7 @@ Column spacing: Math.round(UM.Theme.getSize("default_margin").height / 2) width: container.width contentHeight: childrenRect.height + height: childrenRect.height section.property: "modelData.printerType" section.criteria: ViewSection.FullString From f655e6c43ee115cdad81b7683cab1902cf930258 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 6 Dec 2018 11:30:59 +0100 Subject: [PATCH 0720/1292] Add a pattern in the background of the header. Adjust some main colors to the ones in the designs. --- resources/qml/Cura.qml | 65 +- resources/qml/MainWindow/MainWindowHeader.qml | 27 +- .../cura-light/images/header_pattern.svg | 1903 ++++++++++++++++- resources/themes/cura-light/theme.json | 22 +- 4 files changed, 1940 insertions(+), 77 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 3578888886..f16ae9a19b 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -88,6 +88,30 @@ UM.MainWindow window: base } + Rectangle + { + id: headerBackground + anchors + { + top: parent.top + left: parent.left + right: parent.right + } + height: stageMenu.source != "" ? Math.round(mainWindowHeader.height + stageMenu.height / 2) : mainWindowHeader.height + color: UM.Theme.getColor("main_window_header_background") + + // This is the new fancy pattern + Image + { + id: backgourndPattern + anchors.fill: parent + fillMode: Image.Tile + source: UM.Theme.getImage("header_pattern") + horizontalAlignment: Image.AlignLeft + verticalAlignment: Image.AlignTop + } + } + MainWindowHeader { id: mainWindowHeader @@ -144,44 +168,6 @@ UM.MainWindow } } - Rectangle - { - id: stageMenuBackground - anchors - { - left: parent.left - right: parent.right - top: parent.top - } - visible: stageMenu.source != "" - height: visible ? Math.round(UM.Theme.getSize("stage_menu").height / 2) : 0 - - LinearGradient - { - anchors.fill: parent - start: Qt.point(0, 0) - end: Qt.point(parent.width, 0) - gradient: Gradient - { - GradientStop - { - position: 0.0 - color: UM.Theme.getColor("main_window_header_background") - } - GradientStop - { - position: 0.5 - color: UM.Theme.getColor("main_window_header_background_gradient") - } - GradientStop - { - position: 1.0 - color: UM.Theme.getColor("main_window_header_background") - } - } - } - } - Connections { target: stageMenu.item @@ -257,7 +243,8 @@ UM.MainWindow anchors { - top: stageMenuBackground.bottom + // Align to the top of the stageMenu since the stageMenu may not exist + top: parent.top left: parent.left right: parent.right bottom: parent.bottom diff --git a/resources/qml/MainWindow/MainWindowHeader.qml b/resources/qml/MainWindow/MainWindowHeader.qml index fa0594e2ae..ae1c13d9c3 100644 --- a/resources/qml/MainWindow/MainWindowHeader.qml +++ b/resources/qml/MainWindow/MainWindowHeader.qml @@ -12,38 +12,13 @@ import QtGraphicalEffects 1.0 import "../Account" -Rectangle +Item { id: base implicitHeight: UM.Theme.getSize("main_window_header").height implicitWidth: UM.Theme.getSize("main_window_header").width - LinearGradient - { - anchors.fill: parent - start: Qt.point(0, 0) - end: Qt.point(parent.width, 0) - gradient: Gradient - { - GradientStop - { - position: 0.0 - color: UM.Theme.getColor("main_window_header_background") - } - GradientStop - { - position: 0.5 - color: UM.Theme.getColor("main_window_header_background_gradient") - } - GradientStop - { - position: 1.0 - color: UM.Theme.getColor("main_window_header_background") - } - } - } - Image { id: logo diff --git a/resources/themes/cura-light/images/header_pattern.svg b/resources/themes/cura-light/images/header_pattern.svg index 2a9de2f3e9..14ea9dc917 100644 --- a/resources/themes/cura-light/images/header_pattern.svg +++ b/resources/themes/cura-light/images/header_pattern.svg @@ -1 +1,1902 @@ -Pattern \ No newline at end of file + + + + Pattern_Cura_1 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 767b6eaccd..a4ed45fb24 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -93,14 +93,14 @@ "secondary_button_hover": [228, 228, 228, 255], "secondary_button_text": [30, 102, 215, 255], - "main_window_header_background": [10, 8, 80, 255], + "main_window_header_background": [8, 7, 63, 255], "main_window_header_background_gradient": [25, 23, 91, 255], - "main_window_header_button_text_active": [10, 8, 80, 255], + "main_window_header_button_text_active": [8, 7, 63, 255], "main_window_header_button_text_inactive": [255, 255, 255, 255], "main_window_header_button_text_hovered": [255, 255, 255, 255], "main_window_header_button_background_active": [255, 255, 255, 255], "main_window_header_button_background_inactive": [255, 255, 255, 0], - "main_window_header_button_background_hovered": [255, 255, 255, 102], + "main_window_header_button_background_hovered": [117, 114, 159, 255], "account_widget_outline_active": [70, 66, 126, 255], @@ -113,7 +113,7 @@ "toolbar_background": [255, 255, 255, 255], - "printer_type_label_background": [171, 171, 191, 255], + "printer_type_label_background": [228, 228, 242, 255], "text": [0, 0, 0, 255], "text_detail": [174, 174, 174, 128], @@ -127,9 +127,9 @@ "text_scene_hover": [70, 84, 113, 255], "error": [255, 140, 0, 255], - "warning": [255, 190, 35, 255], + "warning": [245, 166, 35, 255], - "toolbar_button_text": [10, 8, 80, 255], + "toolbar_button_text": [8, 7, 63, 255], "toolbar_button_hover": [232, 242, 252, 255], "toolbar_button_active": [232, 242, 252, 255], "toolbar_button_active_hover": [232, 242, 252, 255], @@ -144,9 +144,9 @@ "button_text_active_hover": [255, 255, 255, 255], "small_button": [0, 0, 0, 0], - "small_button_hover": [10, 8, 80, 255], - "small_button_active": [10, 8, 80, 255], - "small_button_active_hover": [10, 8, 80, 255], + "small_button_hover": [8, 7, 63, 255], + "small_button_active": [8, 7, 63, 255], + "small_button_active_hover": [8, 7, 63, 255], "small_button_text": [171, 171, 191, 255], "small_button_text_hover": [255, 255, 255, 255], "small_button_text_active": [255, 255, 255, 255], @@ -222,8 +222,8 @@ "progressbar_control": [50, 130, 255, 255], "slider_groove": [223, 223, 223, 255], - "slider_groove_fill": [10, 8, 80, 255], - "slider_handle": [10, 8, 80, 255], + "slider_groove_fill": [8, 7, 63, 255], + "slider_handle": [8, 7, 63, 255], "slider_handle_active": [50, 130, 255, 255], "slider_text_background": [255, 255, 255, 255], From aab61ce8dac70c8a24ded4db31641ff67f0fb8c7 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 6 Dec 2018 11:35:33 +0100 Subject: [PATCH 0721/1292] Modify the header pattern to be have an empty space in the left and bottom, so when repeating the pattern it doesn't overlap. --- .../cura-light/images/header_pattern.svg | 3789 ++++++++--------- 1 file changed, 1894 insertions(+), 1895 deletions(-) diff --git a/resources/themes/cura-light/images/header_pattern.svg b/resources/themes/cura-light/images/header_pattern.svg index 14ea9dc917..eff5f01cfa 100644 --- a/resources/themes/cura-light/images/header_pattern.svg +++ b/resources/themes/cura-light/images/header_pattern.svg @@ -1,1902 +1,1901 @@ - + - Pattern_Cura_1 + Desktop HD Created with Sketch. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 26a41c37265822414c3b79e58acce3fc2765a51a Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 6 Dec 2018 11:45:14 +0100 Subject: [PATCH 0722/1292] Adjust the color of the printer in the printer selector For that I needed to get rid of the IconLabel component, since in this case the color of the icon and the text is the same (and it makes sense) --- .../qml/PrinterSelector/MachineSelector.qml | 57 +++++++++++++------ resources/themes/cura-light/theme.json | 1 + 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index 91b5591cd8..95abfd6644 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -25,29 +25,52 @@ Cura.ExpandableComponent name: "cura" } - headerItem: Cura.IconLabel + headerItem: Item { - text: isNetworkPrinter ? Cura.MachineManager.activeMachineNetworkGroupName : Cura.MachineManager.activeMachineName - source: - { - if (isNetworkPrinter) - { - if (machineSelector.outputDevice != null && machineSelector.outputDevice.clusterSize > 1) - { - return UM.Theme.getIcon("printer_group") - } - return UM.Theme.getIcon("printer_single") - } - return "" - } - font: UM.Theme.getFont("medium") - color: UM.Theme.getColor("text") - iconSize: UM.Theme.getSize("machine_selector_icon").width + implicitHeight: icon.height UM.RecolorImage { id: icon + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + + source: + { + if (isNetworkPrinter) + { + if (machineSelector.outputDevice != null && machineSelector.outputDevice.clusterSize > 1) + { + return UM.Theme.getIcon("printer_group") + } + return UM.Theme.getIcon("printer_single") + } + return "" + } + width: UM.Theme.getSize("machine_selector_icon").width + height: width + + color: UM.Theme.getColor("machine_selector_printer_icon") + visible: source != "" + } + + Label + { + id: label + anchors.left: icon.visible ? icon.right : parent.left + anchors.right: parent.right + anchors.leftMargin: UM.Theme.getSize("thin_margin").width + anchors.verticalCenter: icon.verticalCenter + text: isNetworkPrinter ? Cura.MachineManager.activeMachineNetworkGroupName : Cura.MachineManager.activeMachineName + elide: Text.ElideRight + color: UM.Theme.getColor("text") + font: UM.Theme.getFont("medium") + renderType: Text.NativeRendering + } + + UM.RecolorImage + { anchors { bottom: parent.bottom diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index a4ed45fb24..2d7e92be4d 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -108,6 +108,7 @@ "machine_selector_active": [68, 72, 75, 255], "machine_selector_hover": [68, 72, 75, 255], "machine_selector_text_active": [255, 255, 255, 255], + "machine_selector_printer_icon": [8, 7, 63, 255], "action_panel_secondary": [27, 95, 202, 255], From 47626f603341dc8d71688e1722f2a498763707f6 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 6 Dec 2018 11:57:55 +0100 Subject: [PATCH 0723/1292] Fix the color and proportions of the cura logo in the about panel --- resources/qml/Dialogs/AboutDialog.qml | 4 +- .../themes/cura-light/images/logo_about.svg | 172 ++++++++++++++++++ 2 files changed, 174 insertions(+), 2 deletions(-) create mode 100644 resources/themes/cura-light/images/logo_about.svg diff --git a/resources/qml/Dialogs/AboutDialog.qml b/resources/qml/Dialogs/AboutDialog.qml index 94eca4e7c0..add84614e0 100644 --- a/resources/qml/Dialogs/AboutDialog.qml +++ b/resources/qml/Dialogs/AboutDialog.qml @@ -35,9 +35,9 @@ UM.Dialog { id: logo width: (base.minimumWidth * 0.85) | 0 - height: (width * (1/4.25)) | 0 + height: (width * (UM.Theme.getSize("logo").height / UM.Theme.getSize("logo").width)) | 0 - source: UM.Theme.getImage("logo") + source: UM.Theme.getImage("logo_about") anchors.top: parent.top anchors.topMargin: ((base.minimumWidth - width) / 2) | 0 diff --git a/resources/themes/cura-light/images/logo_about.svg b/resources/themes/cura-light/images/logo_about.svg new file mode 100644 index 0000000000..34301fd6c9 --- /dev/null +++ b/resources/themes/cura-light/images/logo_about.svg @@ -0,0 +1,172 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 84c85439ff4db4db77eecc1657fcd78634eca16e Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Thu, 6 Dec 2018 12:00:26 +0100 Subject: [PATCH 0724/1292] The trigger_early_crash did not trigger early crash for testing purposes CURA-5939 --- cura/CuraApplication.py | 6 ++++-- cura_app.py | 6 ------ 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 47cc94f972..dfdb50515f 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -181,7 +181,6 @@ class CuraApplication(QtApplication): # Variables set from CLI self._files_to_open = [] self._use_single_instance = False - self._trigger_early_crash = False # For debug only self._single_instance = None @@ -292,7 +291,10 @@ class CuraApplication(QtApplication): sys.exit(0) self._use_single_instance = self._cli_args.single_instance - self._trigger_early_crash = self._cli_args.trigger_early_crash + # FOR TESTING ONLY + if self._cli_args.trigger_early_crash: + assert not "This crash is triggered by the trigger_early_crash command line argument." + for filename in self._cli_args.file: self._files_to_open.append(os.path.abspath(filename)) diff --git a/cura_app.py b/cura_app.py index 164e32e738..8df12d771a 100755 --- a/cura_app.py +++ b/cura_app.py @@ -17,12 +17,6 @@ parser.add_argument("--debug", default = False, help = "Turn on the debug mode by setting this option." ) -parser.add_argument("--trigger-early-crash", - dest = "trigger_early_crash", - action = "store_true", - default = False, - help = "FOR TESTING ONLY. Trigger an early crash to show the crash dialog." - ) known_args = vars(parser.parse_known_args()[0]) if not known_args["debug"]: From f1fec2f28082661e58b6fb0824521d69409bb4fb Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 6 Dec 2018 12:07:03 +0100 Subject: [PATCH 0725/1292] Theme the scroll bar We need to make this a reusable component at some point, I think. This is the first time we're using the QtQuick2 version of ScrollView. Contributes to issue CURA-5876. --- .../ConfigurationListView.qml | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index d07337f9c5..e7936b69d2 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -28,10 +28,25 @@ Column { id: container width: parent.width - height: Math.round(Math.min(configurationList.height, 350 * screenScaleFactor)) + readonly property int maximumHeight: 350 * screenScaleFactor + height: Math.round(Math.min(configurationList.height, maximumHeight)) contentHeight: configurationList.height clip: true + ScrollBar.vertical.policy: (configurationList.height > maximumHeight) ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff //The AsNeeded policy also hides it when the cursor is away, and we don't want that. + ScrollBar.vertical.background: Rectangle + { + implicitWidth: UM.Theme.getSize("scrollbar").width + radius: width / 2 + color: UM.Theme.getColor("scrollbar_background") + } + ScrollBar.vertical.contentItem: Rectangle + { + implicitWidth: UM.Theme.getSize("scrollbar").width + radius: width / 2 + color: UM.Theme.getColor(parent.pressed ? "scrollbar_handle_down" : parent.hovered ? "scrollbar_handle_hover" : "scrollbar_handle") + } + ButtonGroup { buttons: configurationList.children @@ -41,7 +56,7 @@ Column { id: configurationList spacing: Math.round(UM.Theme.getSize("default_margin").height / 2) - width: container.width + width: container.width - ((height > container.maximumHeight) ? container.ScrollBar.vertical.background.width : 0) //Make room for scroll bar if there is any. contentHeight: childrenRect.height height: childrenRect.height From e8cf9e034db4bf232f29171908e144d6455f0936 Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Thu, 6 Dec 2018 13:41:50 +0100 Subject: [PATCH 0726/1292] Catch All Exception except: SystemExit, KeyboardInterrupt, GeneratorException CURA-5939 --- cura/CrashHandler.py | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/cura/CrashHandler.py b/cura/CrashHandler.py index 46544ca0ef..d43743bc37 100644 --- a/cura/CrashHandler.py +++ b/cura/CrashHandler.py @@ -36,18 +36,14 @@ else: except ImportError: CuraDebugMode = False # [CodeStyle: Reflecting imported value] -# List of exceptions that should be considered "fatal" and abort the program. -# These are primarily some exception types that we simply cannot really recover from -# (MemoryError and SystemError) and exceptions that indicate grave errors in the -# code that cause the Python interpreter to fail (SyntaxError, ImportError). -fatal_exception_types = [ - MemoryError, - SyntaxError, - ImportError, - SystemError, +# List of exceptions that should not be considered "fatal" and abort the program. +# These are primarily some exception types that we simply skip +skip_exception_types = [ + SystemExit, + KeyboardInterrupt, + GeneratorExit ] - class CrashHandler: crash_url = "https://stats.ultimaker.com/api/cura" @@ -70,7 +66,7 @@ class CrashHandler: # If Cura has fully started, we only show fatal errors. # If Cura has not fully started yet, we always show the early crash dialog. Otherwise, Cura will just crash # without any information. - if has_started and exception_type not in fatal_exception_types: + if has_started and exception_type in skip_exception_types: return if not has_started: @@ -387,7 +383,7 @@ class CrashHandler: Application.getInstance().callLater(self._show) def _show(self): - # When the exception is not in the fatal_exception_types list, the dialog is not created, so we don't need to show it + # When the exception is in the skip_exception_types list, the dialog is not created, so we don't need to show it if self.dialog: self.dialog.exec_() os._exit(1) From 4b79770d58e4f3f608a1aa6b079f07b522262564 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 6 Dec 2018 13:42:29 +0100 Subject: [PATCH 0727/1292] Align the buttons in the output process widget The menu in the output device selector has now a rounded corner. --- resources/qml/ActionButton.qml | 5 ++++- .../ActionPanel/OutputDevicesActionButton.qml | 2 ++ .../qml/ActionPanel/OutputProcessWidget.qml | 17 ++++++++++++++--- resources/themes/cura-light/styles.qml | 2 +- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index 54d77f7d59..fc4a1c05f4 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -7,6 +7,7 @@ import QtQuick.Controls 2.1 import QtGraphicalEffects 1.0 // For the dropshadow import UM 1.1 as UM +import Cura 1.0 as Cura Button { @@ -16,6 +17,7 @@ Button property alias textFont: buttonText.font property alias cornerRadius: backgroundRect.radius property alias tooltip: tooltip.text + property alias cornerSide: backgroundRect.cornerSide property color color: UM.Theme.getColor("primary") property color hoverColor: UM.Theme.getColor("primary_hover") @@ -82,9 +84,10 @@ Button } } - background: Rectangle + background: Cura.RoundedRectangle { id: backgroundRect + cornerSide: Cura.RoundedRectangle.Direction.All color: button.enabled ? (button.hovered ? button.hoverColor : button.color) : button.disabledColor radius: UM.Theme.getSize("action_button_radius").width border.width: UM.Theme.getSize("default_lining").width diff --git a/resources/qml/ActionPanel/OutputDevicesActionButton.qml b/resources/qml/ActionPanel/OutputDevicesActionButton.qml index 12e4ac42fd..95750e6d11 100644 --- a/resources/qml/ActionPanel/OutputDevicesActionButton.qml +++ b/resources/qml/ActionPanel/OutputDevicesActionButton.qml @@ -17,6 +17,7 @@ Item id: saveToButton height: parent.height fixedWidthMode: true + cornerSide: deviceSelectionMenu.visible ? Cura.RoundedRectangle.Direction.Left : Cura.RoundedRectangle.Direction.All anchors { @@ -44,6 +45,7 @@ Item shadowEnabled: true shadowColor: UM.Theme.getColor("primary_shadow") + cornerSide: Cura.RoundedRectangle.Direction.Right anchors { diff --git a/resources/qml/ActionPanel/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml index d1790b3791..1d1a1e44e1 100644 --- a/resources/qml/ActionPanel/OutputProcessWidget.qml +++ b/resources/qml/ActionPanel/OutputProcessWidget.qml @@ -101,16 +101,24 @@ Column } } - Row + Item { id: buttonRow - spacing: UM.Theme.getSize("default_margin").width - width: parent.width + anchors.right: parent.right + anchors.left: parent.left + height: UM.Theme.getSize("action_button").height Cura.SecondaryButton { id: previewStageShortcut + anchors + { + left: parent.left + right: outputDevicesButton.left + rightMargin: UM.Theme.getSize("default_margin").width + } + height: UM.Theme.getSize("action_button").height leftPadding: UM.Theme.getSize("default_margin").width rightPadding: UM.Theme.getSize("default_margin").width @@ -125,6 +133,9 @@ Column Cura.OutputDevicesActionButton { + id: outputDevicesButton + + anchors.right: parent.right width: previewStageShortcut.visible ? UM.Theme.getSize("action_button").width : parent.width height: UM.Theme.getSize("action_button").height } diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index aaa8ec18f1..30cf42859a 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -145,7 +145,7 @@ QtObject text: control.text anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter - font: UM.Theme.getFont("medium_bold") + font: UM.Theme.getFont("medium") color: { if (control.checked) From 76acb13f5962d9c185dd29aa8618f13db95c588a Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 6 Dec 2018 13:50:58 +0100 Subject: [PATCH 0728/1292] Change the play/pause button colors --- plugins/SimulationView/SimulationViewMainComponent.qml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/plugins/SimulationView/SimulationViewMainComponent.qml b/plugins/SimulationView/SimulationViewMainComponent.qml index 16b9aeaae6..16b049c921 100644 --- a/plugins/SimulationView/SimulationViewMainComponent.qml +++ b/plugins/SimulationView/SimulationViewMainComponent.qml @@ -61,10 +61,9 @@ Item iconSource: !is_simulation_playing ? "./resources/simulation_resume.svg": "./resources/simulation_pause.svg" width: UM.Theme.getSize("small_button").width height: UM.Theme.getSize("small_button").height - hoverBackgroundColor: UM.Theme.getColor("small_button_hover") - hoverColor: UM.Theme.getColor("small_button_text_hover") - color: UM.Theme.getColor("small_button_text") - iconMargin: 0.5 * UM.Theme.getSize("wide_lining").width + hoverColor: UM.Theme.getColor("slider_handle_active") + color: UM.Theme.getColor("slider_handle") + iconMargin: UM.Theme.getSize("thick_lining").width visible: !UM.SimulationView.compatibilityMode Connections From 1e699604642f69dda88185a382cae0f657580d93 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 6 Dec 2018 13:52:57 +0100 Subject: [PATCH 0729/1292] Make it possible to disable ExpandableComponent It won't show the drop-down icon then, won't do hovers and won't allow you to click on it. This will not remove the contents of the ExpandableComponent menu bar item though, so that has to be done in ConfigurationMenu.qml. Contributes to issue CURA-5876. --- resources/qml/ExpandableComponent.qml | 4 +++- resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index 9bedaa940c..e42aa7e4a1 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -32,6 +32,8 @@ Item property color headerBackgroundColor: UM.Theme.getColor("action_button") property color headerHoverColor: UM.Theme.getColor("action_button_hovered") + property alias enabled: mouseArea.enabled + // Defines the alignment of the popup with respect of the headerItem, by default to the right property int popupAlignment: ExpandableComponent.PopupAlignment.AlignRight @@ -139,7 +141,7 @@ Item verticalCenter: parent.verticalCenter margins: background.padding } - visible: source != "" + visible: source != "" && base.enabled width: height height: Math.round(0.2 * base.height) color: UM.Theme.getColor("text") diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index f81176ab1a..c4671d3a3a 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -45,6 +45,7 @@ Cura.ExpandableComponent orientation: ListView.Horizontal anchors.fill: parent model: extrudersModel + visible: base.enabled delegate: Item { From 298c68c93b6a5d98f7a3847849045003f001a154 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 6 Dec 2018 13:56:06 +0100 Subject: [PATCH 0730/1292] Disable configuration menu if there are no configurations This then prevents you from dropping down into an empty menu. Contributes to issue CURA-5876. --- .../ConfigurationMenu/ConfigurationMenu.qml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index c4671d3a3a..edb74d0251 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -102,6 +102,23 @@ Cura.ExpandableComponent } } + //Disable the menu if there are no materials, variants or build plates to change. + function updateEnabled() + { + var active_definition_id = Cura.MachineManager.activeMachine.definition.id; + var has_materials = Cura.ContainerManager.getContainerMetaDataEntry(active_definition_id, "has_materials"); + var has_variants = Cura.ContainerManager.getContainerMetaDataEntry(active_definition_id, "has_variants"); + var has_buildplates = Cura.ContainerManager.getContainerMetaDataEntry(active_definition_id, "has_variant_buildplates"); + base.enabled = has_materials || has_variants || has_buildplates; //Only let it drop down if there is any configuration that you could change. + } + + Connections + { + target: Cura.MachineManager + onGlobalContainerChanged: base.updateEnabled(); + } + Component.onCompleted: updateEnabled(); + popupItem: Column { id: popupItem From 05ca0b372af64bdc198ed5cf3c64d605c7981f71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Thu, 6 Dec 2018 14:04:12 +0100 Subject: [PATCH 0731/1292] Updated TODO, printjobs are not displayed in the monitor page because data returned from cura connect api contains None's instead of printer uuid's --- plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 9dab829825..eb6fb3a789 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -299,7 +299,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self.printJobsChanged.emit() def _addPrintJob(self, job: CloudClusterPrintJob) -> None: - # TODO: somehow we don't see the queued print jobs on the monitor page yet, we have to figure out why. + # TODO: we don't see the queued print jobs on the monitor page yet because job.printer_uuid and job.assigned_to + # are always None try: printer = next(p for p in self._printers if job.printer_uuid == p.key or job.assigned_to == p.key) except StopIteration: From 85f2a7e8f692e5202f4821e25ea9a9a7d79d7501 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 6 Dec 2018 14:04:21 +0100 Subject: [PATCH 0732/1292] Move visible to Rows for extruder configs CURA-5941 So the whole row, such as "material", will be shown/hiden based on whether the machine has materials. --- .../Menus/ConfigurationMenu/CustomConfiguration.qml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index 19b7158929..ac40958a29 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -140,6 +140,7 @@ Item Row { height: UM.Theme.getSize("print_setup_item").height + visible: extrudersModel.count > 1 // If there is only one extruder, there is no point to enable/disable that. Label { @@ -149,7 +150,6 @@ Item color: UM.Theme.getColor("text") height: parent.height width: selectors.textWidth - visible: extrudersModel.count > 1 } OldControls.CheckBox @@ -158,7 +158,6 @@ Item enabled: !checked || Cura.MachineManager.numberExtrudersEnabled > 1 //Disable if it's the last enabled extruder. height: UM.Theme.getSize("setting_control").height style: UM.Theme.styles.checkbox - visible: extrudersModel.count > 1 /* Use a MouseArea to process the click on this checkbox. This is necessary because actually clicking the checkbox @@ -177,6 +176,8 @@ Item Row { height: UM.Theme.getSize("print_setup_item").height + visible: Cura.MachineManager.hasMaterials + Label { text: catalog.i18nc("@label", "Material") @@ -185,7 +186,6 @@ Item color: UM.Theme.getColor("text") height: parent.height width: selectors.textWidth - visible: materialSelection.visible } OldControls.ToolButton @@ -197,7 +197,6 @@ Item text: Cura.MachineManager.activeStack != null ? Cura.MachineManager.activeStack.material.name : "" tooltip: text - visible: Cura.MachineManager.hasMaterials height: UM.Theme.getSize("setting_control").height width: selectors.controlWidth @@ -214,6 +213,7 @@ Item Row { height: UM.Theme.getSize("print_setup_item").height + visible: Cura.MachineManager.hasVariants Label { @@ -223,15 +223,13 @@ Item color: UM.Theme.getColor("text") height: parent.height width: selectors.textWidth - visible: variantSelection.visible } OldControls.ToolButton { id: variantSelection text: Cura.MachineManager.activeVariantName - tooltip: Cura.MachineManager.activeVariantName; - visible: Cura.MachineManager.hasVariants + tooltip: Cura.MachineManager.activeVariantName height: UM.Theme.getSize("setting_control").height width: selectors.controlWidth From 54def4edee6d743eaf43988a8b2568bebc8fee53 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 6 Dec 2018 14:12:35 +0100 Subject: [PATCH 0733/1292] Revert "Moved qml pages of toolbox to a loader" This reverts commit 838949dac74831e38e9f07fe7d628af7807320db. --- plugins/Toolbox/resources/qml/Toolbox.qml | 55 +++++++++++---------- plugins/Toolbox/src/Toolbox.py | 59 ++++++++++++----------- 2 files changed, 62 insertions(+), 52 deletions(-) diff --git a/plugins/Toolbox/resources/qml/Toolbox.qml b/plugins/Toolbox/resources/qml/Toolbox.qml index b2bab4355a..7cc5a730f2 100644 --- a/plugins/Toolbox/resources/qml/Toolbox.qml +++ b/plugins/Toolbox/resources/qml/Toolbox.qml @@ -44,31 +44,36 @@ Window top: header.bottom bottom: footer.top } - - Loader + // TODO: This could be improved using viewFilter instead of viewCategory + ToolboxLoadingPage { - anchors.fill:parent - source: - { - if(toolbox.viewCategory == "installed") - { - return "ToolboxInstalledPage.qml" - } - - switch (toolbox.viewPage) - { - case "loading": - return "ToolboxLoadingPage.qml" - case "errored": - return "ToolboxErrorPage.qml" - case "overview": - return "ToolboxDownloadsPage.qml" - case "detail": - return "ToolboxDetailPage.qml" - case "author": - return "ToolboxAuthorPage.qml" - } - } + id: viewLoading + visible: toolbox.viewCategory != "installed" && toolbox.viewPage == "loading" + } + ToolboxErrorPage + { + id: viewErrored + visible: toolbox.viewCategory != "installed" && toolbox.viewPage == "errored" + } + ToolboxDownloadsPage + { + id: viewDownloads + visible: toolbox.viewCategory != "installed" && toolbox.viewPage == "overview" + } + ToolboxDetailPage + { + id: viewDetail + visible: toolbox.viewCategory != "installed" && toolbox.viewPage == "detail" + } + ToolboxAuthorPage + { + id: viewAuthor + visible: toolbox.viewCategory != "installed" && toolbox.viewPage == "author" + } + ToolboxInstalledPage + { + id: installedPluginList + visible: toolbox.viewCategory == "installed" } } @@ -90,7 +95,7 @@ Window licenseDialog.show(); } } - + ToolboxLicenseDialog { id: licenseDialog diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 68919cf987..ef67dc3c86 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -622,39 +622,44 @@ class Toolbox(QObject, Extension): if reply.operation() == QNetworkAccessManager.GetOperation: for response_type, url in self._request_urls.items(): - if reply.url() != url: - continue + if reply.url() == url: + if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) == 200: + try: + json_data = json.loads(bytes(reply.readAll()).decode("utf-8")) - if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) == 200: - try: - json_data = json.loads(bytes(reply.readAll()).decode("utf-8")) - except json.decoder.JSONDecodeError: - Logger.log("w", "Received invalid JSON for %s.", response_type) - break + # Check for errors: + if "errors" in json_data: + for error in json_data["errors"]: + Logger.log("e", "%s", error["title"]) + return - # Check for errors: - if "errors" in json_data: - for error in json_data["errors"]: - Logger.log("e", "%s", error["title"]) - return + # Create model and apply metadata: + if not self._models[response_type]: + Logger.log("e", "Could not find the %s model.", response_type) + break + + self._server_response_data[response_type] = json_data["data"] + self._models[response_type].setMetadata(self._server_response_data[response_type]) - self._server_response_data[response_type] = json_data["data"] - self._models[response_type].setMetadata(json_data["data"]) + if response_type is "packages": + self._models[response_type].setFilter({"type": "plugin"}) + self.reBuildMaterialsModels() + self.reBuildPluginsModels() + elif response_type is "authors": + self._models[response_type].setFilter({"package_types": "material"}) + self._models[response_type].setFilter({"tags": "generic"}) - if response_type is "packages": - self._models["packages"].setFilter({"type": "plugin"}) - self.reBuildMaterialsModels() - self.reBuildPluginsModels() - elif response_type is "authors": - self._models["authors"].setFilter({"tags": "generic"}) + self.metadataChanged.emit() - self.metadataChanged.emit() + if self.isLoadingComplete(): + self.setViewPage("overview") - if self.isLoadingComplete(): - self.setViewPage("overview") - else: - self.setViewPage("errored") - self.resetDownload() + except json.decoder.JSONDecodeError: + Logger.log("w", "Received invalid JSON for %s.", response_type) + break + else: + self.setViewPage("errored") + self.resetDownload() else: # Ignore any operation that is not a get operation pass From 05075c44ee31902bec6c9f9167acb7d00025c030 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 6 Dec 2018 14:19:34 +0100 Subject: [PATCH 0734/1292] Add renderType to some labels in the Configuration panel Contributes to CURA-5876. --- resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml | 1 + resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml | 5 ++++- .../qml/Menus/ConfigurationMenu/CustomConfiguration.qml | 4 ++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml index a09d6d2ba4..68c56c7c4b 100644 --- a/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml @@ -19,6 +19,7 @@ Item font: UM.Theme.getFont("large") color: UM.Theme.getColor("text") height: contentHeight + renderType: Text.NativeRendering anchors { diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index edb74d0251..1d086acc67 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -71,6 +71,7 @@ Cura.ExpandableComponent elide: Text.ElideRight font: UM.Theme.getFont("default") color: UM.Theme.getColor("text_inactive") + renderType: Text.NativeRendering anchors { @@ -88,6 +89,7 @@ Cura.ExpandableComponent elide: Text.ElideRight font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") + renderType: Text.NativeRendering anchors { @@ -155,8 +157,9 @@ Cura.ExpandableComponent { id: separator visible: buttonBar.visible + x: -popupPadding - width: parent.width + width: base.width height: UM.Theme.getSize("default_lining").height color: UM.Theme.getColor("lining") diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index 19b7158929..8d8f84155a 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -26,6 +26,7 @@ Item font: UM.Theme.getFont("large") color: UM.Theme.getColor("text") height: contentHeight + renderType: Text.NativeRendering anchors { @@ -150,6 +151,7 @@ Item height: parent.height width: selectors.textWidth visible: extrudersModel.count > 1 + renderType: Text.NativeRendering } OldControls.CheckBox @@ -186,6 +188,7 @@ Item height: parent.height width: selectors.textWidth visible: materialSelection.visible + renderType: Text.NativeRendering } OldControls.ToolButton @@ -224,6 +227,7 @@ Item height: parent.height width: selectors.textWidth visible: variantSelection.visible + renderType: Text.NativeRendering } OldControls.ToolButton From 3c517d3fcce96c4f57f75bbbcf53a086d49f4055 Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Thu, 6 Dec 2018 14:25:18 +0100 Subject: [PATCH 0735/1292] The top bar background overlaps settings bar --- resources/qml/Cura.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index f16ae9a19b..a75ab44b99 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -93,7 +93,7 @@ UM.MainWindow id: headerBackground anchors { - top: parent.top + top: applicationMenu.bottom left: parent.left right: parent.right } From 3ca749cdcbbc9526586d979acfa9e8ab9489bedc Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 6 Dec 2018 14:31:52 +0100 Subject: [PATCH 0736/1292] Add a bunch of renderTypes to labels in the DiscoverUM3Action. --- .../resources/qml/DiscoverUM3Action.qml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml b/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml index 967adfc029..bb710127fc 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml @@ -64,6 +64,7 @@ Cura.MachineAction width: parent.width text: catalog.i18nc("@title:window", "Connect to Networked Printer") wrapMode: Text.WordWrap + renderType: Text.NativeRendering font.pointSize: 18 } @@ -72,6 +73,7 @@ Cura.MachineAction id: pageDescription width: parent.width wrapMode: Text.WordWrap + renderType: Text.NativeRendering text: catalog.i18nc("@label", "To print directly to your printer over the network, please make sure your printer is connected to the network using a network cable or by connecting your printer to your WIFI network. If you don't connect Cura with your printer, you can still use a USB drive to transfer g-code files to your printer.\n\nSelect your printer from the list below:") } @@ -182,6 +184,7 @@ Cura.MachineAction text: listview.model[index].name color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text elide: Text.ElideRight + renderType: Text.NativeRendering } MouseArea @@ -204,6 +207,7 @@ Cura.MachineAction anchors.left: parent.left anchors.right: parent.right wrapMode: Text.WordWrap + renderType: Text.NativeRendering text: catalog.i18nc("@label", "If your printer is not listed, read the network printing troubleshooting guide").arg("https://ultimaker.com/en/troubleshooting"); onLinkActivated: Qt.openUrlExternally(link) } @@ -221,6 +225,7 @@ Cura.MachineAction text: base.selectedDevice ? base.selectedDevice.name : "" font: UM.Theme.getFont("large") elide: Text.ElideRight + renderType: Text.NativeRendering } Grid { @@ -231,12 +236,14 @@ Cura.MachineAction { width: Math.round(parent.width * 0.5) wrapMode: Text.WordWrap + renderType: Text.NativeRendering text: catalog.i18nc("@label", "Type") } Label { width: Math.round(parent.width * 0.5) wrapMode: Text.WordWrap + renderType: Text.NativeRendering text: { if(base.selectedDevice) @@ -268,24 +275,28 @@ Cura.MachineAction { width: Math.round(parent.width * 0.5) wrapMode: Text.WordWrap + renderType: Text.NativeRendering text: catalog.i18nc("@label", "Firmware version") } Label { width: Math.round(parent.width * 0.5) wrapMode: Text.WordWrap + renderType: Text.NativeRendering text: base.selectedDevice ? base.selectedDevice.firmwareVersion : "" } Label { width: Math.round(parent.width * 0.5) wrapMode: Text.WordWrap + renderType: Text.NativeRendering text: catalog.i18nc("@label", "Address") } Label { width: Math.round(parent.width * 0.5) wrapMode: Text.WordWrap + renderType: Text.NativeRendering text: base.selectedDevice ? base.selectedDevice.ipAddress : "" } } @@ -294,6 +305,7 @@ Cura.MachineAction { width: parent.width wrapMode: Text.WordWrap + renderType: Text.NativeRendering text:{ // The property cluster size does not exist for older UM3 devices. if(!base.selectedDevice || base.selectedDevice.clusterSize == null || base.selectedDevice.clusterSize == 1) @@ -315,6 +327,7 @@ Cura.MachineAction { width: parent.width wrapMode: Text.WordWrap + renderType: Text.NativeRendering visible: base.selectedDevice != null && !base.completeProperties text: catalog.i18nc("@label", "The printer at this address has not yet responded." ) } @@ -358,9 +371,10 @@ Cura.MachineAction Label { - text: catalog.i18nc("@alabel","Enter the IP address or hostname of your printer on the network.") + text: catalog.i18nc("@alabel", "Enter the IP address or hostname of your printer on the network.") width: parent.width wrapMode: Text.WordWrap + renderType: Text.NativeRendering } TextField From a77ad329993ae46799376689c4908de06292c801 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 6 Dec 2018 14:35:07 +0100 Subject: [PATCH 0737/1292] Move all the seperate tiles into loaders instead of the entire page Otherwise the details selection didn't work anymore and I didn't want to add more hacks. CURA-6006 --- .../resources/qml/ToolboxDetailList.qml | 7 ++++++- .../resources/qml/ToolboxDownloadsGrid.qml | 10 ++++++---- .../qml/ToolboxDownloadsShowcase.qml | 19 +++++++++++-------- .../resources/qml/ToolboxInstalledPage.qml | 12 ++++++++++-- 4 files changed, 33 insertions(+), 15 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailList.qml b/plugins/Toolbox/resources/qml/ToolboxDetailList.qml index 2e5eae098c..1700a58ebe 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailList.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailList.qml @@ -26,10 +26,15 @@ Item } height: childrenRect.height + 2 * UM.Theme.getSize("wide_margin").height spacing: UM.Theme.getSize("default_margin").height + Repeater { model: toolbox.packagesModel - delegate: ToolboxDetailTile {} + delegate: Loader + { + asynchronous: true + source: "ToolboxDetailTile.qml" + } } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml index c586828969..3e2643938b 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml @@ -24,7 +24,7 @@ Column color: UM.Theme.getColor("text_medium") font: UM.Theme.getFont("medium") } - GridLayout + Grid { id: grid width: parent.width - 2 * parent.padding @@ -34,10 +34,12 @@ Column Repeater { model: gridArea.model - delegate: ToolboxDownloadsGridTile + delegate: Loader { - Layout.preferredWidth: (grid.width - (grid.columns - 1) * grid.columnSpacing) / grid.columns - Layout.preferredHeight: UM.Theme.getSize("toolbox_thumbnail_small").height + asynchronous: true + width: (grid.width - (grid.columns - 1) * grid.columnSpacing) / grid.columns + height: UM.Theme.getSize("toolbox_thumbnail_small").height + source: "ToolboxDownloadsGridTile.qml" } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml index 46f5debfdd..9851128076 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml @@ -30,23 +30,26 @@ Rectangle height: childrenRect.height spacing: UM.Theme.getSize("wide_margin").width columns: 3 - anchors - { - horizontalCenter: parent.horizontalCenter - } + anchors.horizontalCenter: parent.horizontalCenter + Repeater { - model: { - if ( toolbox.viewCategory == "plugin" ) + model: + { + if (toolbox.viewCategory == "plugin") { return toolbox.pluginsShowcaseModel } - if ( toolbox.viewCategory == "material" ) + if (toolbox.viewCategory == "material") { return toolbox.materialsShowcaseModel } } - delegate: ToolboxDownloadsShowcaseTile {} + delegate: Loader + { + asynchronous: true + source: "ToolboxDownloadsShowcaseTile.qml" + } } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml index e683f89823..145e544b19 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml @@ -64,7 +64,11 @@ ScrollView { id: materialList model: toolbox.pluginsInstalledModel - delegate: ToolboxInstalledTile {} + delegate: Loader + { + asynchronous: true + source: "ToolboxInstalledTile.qml" + } } } } @@ -101,7 +105,11 @@ ScrollView { id: pluginList model: toolbox.materialsInstalledModel - delegate: ToolboxInstalledTile {} + delegate: Loader + { + asynchronous: true + source: "ToolboxInstalledTile.qml" + } } } } From 46c209a9936c1b2e52a83f743f1a3b8c58aeb2d7 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 6 Dec 2018 14:45:24 +0100 Subject: [PATCH 0738/1292] Add one pixel margin to the view selector. --- resources/qml/PrinterSelector/MachineSelectorList.qml | 2 +- resources/qml/ViewsSelector.qml | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/resources/qml/PrinterSelector/MachineSelectorList.qml b/resources/qml/PrinterSelector/MachineSelectorList.qml index 5ef04b7351..54d766a6e0 100644 --- a/resources/qml/PrinterSelector/MachineSelectorList.qml +++ b/resources/qml/PrinterSelector/MachineSelectorList.qml @@ -13,7 +13,7 @@ Column Label { - text: catalog.i18nc("@label", "Network connected printers") + text: catalog.i18nc("@label", "Connected printers") visible: networkedPrintersModel.items.length > 0 leftPadding: UM.Theme.getSize("default_margin").width height: visible ? contentHeight + 2 * UM.Theme.getSize("default_margin").height : 0 diff --git a/resources/qml/ViewsSelector.qml b/resources/qml/ViewsSelector.qml index e239ea82a0..1e42a0b3ba 100644 --- a/resources/qml/ViewsSelector.qml +++ b/resources/qml/ViewsSelector.qml @@ -74,6 +74,8 @@ Cura.ExpandableComponent { id: viewSelectorPopup width: viewSelector.width - 2 * viewSelector.popupPadding + leftPadding: UM.Theme.getSize("default_lining").width + rightPadding: UM.Theme.getSize("default_lining").width // For some reason the height/width of the column gets set to 0 if this is not set... Component.onCompleted: @@ -91,7 +93,7 @@ Cura.ExpandableComponent { id: viewsSelectorButton text: model.name - width: parent.width + width: parent.width - viewSelectorPopup.leftPadding - viewSelectorPopup.rightPadding height: UM.Theme.getSize("action_button").height leftPadding: UM.Theme.getSize("default_margin").width rightPadding: UM.Theme.getSize("default_margin").width From 62c53989335d4d955be4bcb1ac07df234bbb2896 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 6 Dec 2018 14:58:28 +0100 Subject: [PATCH 0739/1292] Change buttons to use either secondary or primary CURA-6006 --- .../resources/qml/ToolboxInstalledPage.qml | 12 +-- .../qml/ToolboxInstalledTileActions.qml | 42 ++------- .../resources/qml/ToolboxProgressButton.qml | 93 +------------------ 3 files changed, 16 insertions(+), 131 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml index 145e544b19..e683f89823 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml @@ -64,11 +64,7 @@ ScrollView { id: materialList model: toolbox.pluginsInstalledModel - delegate: Loader - { - asynchronous: true - source: "ToolboxInstalledTile.qml" - } + delegate: ToolboxInstalledTile {} } } } @@ -105,11 +101,7 @@ ScrollView { id: pluginList model: toolbox.materialsInstalledModel - delegate: Loader - { - asynchronous: true - source: "ToolboxInstalledTile.qml" - } + delegate: ToolboxInstalledTile {} } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml index 621ecd96ea..eb3a93f274 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml @@ -6,6 +6,8 @@ import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM +import Cura 1.0 as Cura + Column { property bool canUpdate: false @@ -43,44 +45,18 @@ Column visible: canUpdate } - Button + Cura.SecondaryButton { id: removeButton text: canDowngrade ? catalog.i18nc("@action:button", "Downgrade") : catalog.i18nc("@action:button", "Uninstall") visible: !model.is_bundled && model.is_installed enabled: !toolbox.isDownloading - style: ButtonStyle - { - background: Rectangle - { - implicitWidth: UM.Theme.getSize("toolbox_action_button").width - implicitHeight: UM.Theme.getSize("toolbox_action_button").height - color: "transparent" - border - { - width: UM.Theme.getSize("default_lining").width - color: - { - if (control.hovered) - { - return UM.Theme.getColor("primary_hover") - } - else - { - return UM.Theme.getColor("lining") - } - } - } - } - label: Label - { - text: control.text - color: UM.Theme.getColor("text") - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - font: UM.Theme.getFont("default") - } - } + + width: UM.Theme.getSize("toolbox_action_button").width + height: UM.Theme.getSize("toolbox_action_button").height + + fixedWidthMode: true + onClicked: toolbox.checkPackageUsageAndUninstall(model.id) Connections { diff --git a/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml b/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml index 00b0b985f5..0b574e8653 100644 --- a/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml +++ b/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml @@ -5,7 +5,7 @@ import QtQuick 2.2 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM - +import Cura 1.0 as Cura Item { @@ -25,9 +25,12 @@ Item width: UM.Theme.getSize("toolbox_action_button").width height: UM.Theme.getSize("toolbox_action_button").height - Button + Cura.PrimaryButton { id: button + width: UM.Theme.getSize("toolbox_action_button").width + height: UM.Theme.getSize("toolbox_action_button").height + fixedWidthMode: true text: { if (complete) @@ -58,92 +61,6 @@ Item readyAction() } } - style: ButtonStyle - { - background: Rectangle - { - implicitWidth: UM.Theme.getSize("toolbox_action_button").width - implicitHeight: UM.Theme.getSize("toolbox_action_button").height - color: - { - if (base.complete) - { - return "transparent" - } - else - { - if (control.hovered) - { - return UM.Theme.getColor("primary_hover") - } - else - { - return UM.Theme.getColor("primary") - } - } - } - border - { - width: - { - if (base.complete) - { - UM.Theme.getSize("default_lining").width - } - else - { - return 0 - } - } - color: - { - if (control.hovered) - { - return UM.Theme.getColor("primary_hover") - } - else - { - return UM.Theme.getColor("lining") - } - } - } - } - label: Label - { - text: control.text - color: - { - if (base.complete) - { - return UM.Theme.getColor("text") - } - else - { - if (control.hovered) - { - return UM.Theme.getColor("button_text_hover") - } - else - { - return UM.Theme.getColor("button_text") - } - } - } - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - font: - { - if (base.complete) - { - return UM.Theme.getFont("default") - } - else - { - return UM.Theme.getFont("default_bold") - } - } - } - } } AnimatedImage From b55ead8c89a331a2ce3902d2c7288587a1e675a7 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 6 Dec 2018 15:18:32 +0100 Subject: [PATCH 0740/1292] Fix typo Contributes to CURA-6010. --- resources/qml/Cura.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index f16ae9a19b..6a8493ff06 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -103,7 +103,7 @@ UM.MainWindow // This is the new fancy pattern Image { - id: backgourndPattern + id: backgroundPattern anchors.fill: parent fillMode: Image.Tile source: UM.Theme.getImage("header_pattern") From 4b9e6e7708b862eb30c5ddad91de6421b75f80c2 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 6 Dec 2018 16:06:22 +0100 Subject: [PATCH 0741/1292] Add the linear gradient back, that I removed in a previous commit Contributes to CURA-6010. --- resources/qml/Cura.qml | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 6a8493ff06..93d8bddf1e 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -98,7 +98,31 @@ UM.MainWindow right: parent.right } height: stageMenu.source != "" ? Math.round(mainWindowHeader.height + stageMenu.height / 2) : mainWindowHeader.height - color: UM.Theme.getColor("main_window_header_background") + + LinearGradient + { + anchors.fill: parent + start: Qt.point(0, 0) + end: Qt.point(parent.width, 0) + gradient: Gradient + { + GradientStop + { + position: 0.0 + color: UM.Theme.getColor("main_window_header_background") + } + GradientStop + { + position: 0.5 + color: UM.Theme.getColor("main_window_header_background_gradient") + } + GradientStop + { + position: 1.0 + color: UM.Theme.getColor("main_window_header_background") + } + } + } // This is the new fancy pattern Image From c39674cd0cbbc3cb8e71bd9ece5a72d0c4eefcd0 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 6 Dec 2018 16:22:26 +0100 Subject: [PATCH 0742/1292] Use upper camel case for enum options Contributes to issue CURA-5876. --- .../ConfigurationMenu/ConfigurationMenu.qml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index 1d086acc67..9bef2ca0be 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -30,8 +30,8 @@ Cura.ExpandableComponent enum ConfigurationMethod { - AUTO, - CUSTOM + Auto, + Custom } iconSource: expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") @@ -134,7 +134,7 @@ Cura.ExpandableComponent is_connected = Cura.MachineManager.activeMachineNetworkKey !== "" && Cura.MachineManager.printerConnected //Re-evaluate. } - property int configuration_method: is_connected ? ConfigurationMenu.ConfigurationMethod.AUTO : ConfigurationMenu.ConfigurationMethod.CUSTOM //Auto if connected to a printer at start-up, or Custom if not. + property int configuration_method: is_connected ? ConfigurationMenu.ConfigurationMethod.Auto : ConfigurationMenu.ConfigurationMethod.Custom //Auto if connected to a printer at start-up, or Custom if not. Item { @@ -143,13 +143,13 @@ Cura.ExpandableComponent AutoConfiguration { id: autoConfiguration - visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.AUTO + visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.Auto } CustomConfiguration { id: customConfiguration - visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.CUSTOM + visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.Custom } } @@ -177,7 +177,7 @@ Cura.ExpandableComponent Cura.SecondaryButton { id: goToCustom - visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.AUTO + visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.Auto text: catalog.i18nc("@label", "Custom") anchors.right: parent.right @@ -185,18 +185,18 @@ Cura.ExpandableComponent iconSource: UM.Theme.getIcon("arrow_right") isIconOnRightSide: true - onClicked: popupItem.configuration_method = ConfigurationMenu.ConfigurationMethod.CUSTOM + onClicked: popupItem.configuration_method = ConfigurationMenu.ConfigurationMethod.Custom } Cura.SecondaryButton { id: goToAuto - visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.CUSTOM + visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.Custom text: catalog.i18nc("@label", "Configurations") iconSource: UM.Theme.getIcon("arrow_left") - onClicked: popupItem.configuration_method = ConfigurationMenu.ConfigurationMethod.AUTO + onClicked: popupItem.configuration_method = ConfigurationMenu.ConfigurationMethod.Auto } } } From 4e2ab163ed5dffec65a7328820e494434def97e5 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 6 Dec 2018 16:24:12 +0100 Subject: [PATCH 0743/1292] Add login fequired link to packages that have the login-required tag CURA-6006 --- .../qml/ToolboxDetailTileActions.qml | 22 ++++++++++++++++++- plugins/Toolbox/src/PackagesModel.py | 2 ++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml b/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml index 72a9d14dcd..8a11b402d2 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml @@ -5,11 +5,14 @@ import QtQuick 2.7 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM +import Cura 1.1 as Cura Column { property bool installed: toolbox.isInstalled(model.id) property bool canUpdate: toolbox.canUpdate(model.id) + property bool loginRequired: model.login_required && !Cura.API.account.isLoggedIn + width: UM.Theme.getSize("toolbox_action_button").width spacing: UM.Theme.getSize("narrow_margin").height @@ -28,11 +31,28 @@ Column onCompleteAction: toolbox.viewCategory = "installed" // Don't allow installing while another download is running - enabled: installed || !(toolbox.isDownloading && toolbox.activePackage != model) + enabled: installed || (!(toolbox.isDownloading && toolbox.activePackage != model) && !loginRequired) opacity: enabled ? 1.0 : 0.5 visible: !updateButton.visible // Don't show when the update button is visible } + + Label + { + wrapMode: Text.WordWrap + text:"Log in is required to install" + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + linkColor: UM.Theme.getColor("text_link") + visible: loginRequired + width: installButton.width + MouseArea + { + anchors.fill: parent + onClicked:Cura.API.account.login() + } + } + ToolboxProgressButton { id: updateButton diff --git a/plugins/Toolbox/src/PackagesModel.py b/plugins/Toolbox/src/PackagesModel.py index f941804653..bcc02955a2 100644 --- a/plugins/Toolbox/src/PackagesModel.py +++ b/plugins/Toolbox/src/PackagesModel.py @@ -40,6 +40,7 @@ class PackagesModel(ListModel): self.addRoleName(Qt.UserRole + 19, "tags") self.addRoleName(Qt.UserRole + 20, "links") self.addRoleName(Qt.UserRole + 21, "website") + self.addRoleName(Qt.UserRole + 22, "login_required") # List of filters for queries. The result is the union of the each list of results. self._filter = {} # type: Dict[str, str] @@ -100,6 +101,7 @@ class PackagesModel(ListModel): "tags": package["tags"] if "tags" in package else [], "links": links_dict, "website": package["website"] if "website" in package else None, + "login_required": "login-required" in package.get("tags", []) }) # Filter on all the key-word arguments. From 373c953dbf565abcda33919f226af6e101e7ca19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Thu, 6 Dec 2018 16:25:04 +0100 Subject: [PATCH 0744/1292] Showing print queue, works with multiple printers in cluster, Add TODO --- .../src/Cloud/CloudOutputDevice.py | 36 ++++++++++++------- .../src/Cloud/Models/CloudClusterPrintJob.py | 8 ++--- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index eb6fb3a789..fd21d32256 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -18,6 +18,7 @@ from cura.CuraApplication import CuraApplication from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState, NetworkedPrinterOutputDevice from cura.PrinterOutput.PrinterOutputController import PrinterOutputController from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel +from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputController import CloudOutputController from ..MeshFormatHandler import MeshFormatHandler from ..UM3PrintJobOutputModel import UM3PrintJobOutputModel from .CloudApiClient import CloudApiClient @@ -266,8 +267,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self._printers.remove(removed_printer) for added_printer in added_printers: - controller = PrinterOutputController(self) - self._printers.append(added_printer.createOutputModel(controller)) + self._printers.append(added_printer.createOutputModel(CloudOutputController(self))) for model, printer in updated_printers: printer.updateOutputModel(model) @@ -276,7 +276,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): if not self._active_printer: self.setActivePrinter(self._printers[0]) - self._clusterPrintersChanged.emit() + if removed_printers or added_printers or updated_printers: + self._clusterPrintersChanged.emit() def _updatePrintJobs(self, jobs: List[CloudClusterPrintJob]) -> None: received = {j.uuid: j for j in jobs} # type: Dict[str, CloudClusterPrintJob] @@ -284,6 +285,9 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): removed_jobs, added_jobs, updated_jobs = findChanges(previous, received) + # TODO: we see that not all data in the UI is correctly updated when the queue and active jobs change. + # TODO: we need to fix this here somehow by updating the correct output models. + for removed_job in removed_jobs: self._print_jobs.remove(removed_job) @@ -292,24 +296,30 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): for model, job in updated_jobs: job.updateOutputModel(model) + self._updatePrintJobDetails(model) # We only have to update when jobs are added or removed # updated jobs push their changes via their output model - if added_jobs or removed_jobs: + if added_jobs or removed_jobs or updated_jobs: self.printJobsChanged.emit() def _addPrintJob(self, job: CloudClusterPrintJob) -> None: - # TODO: we don't see the queued print jobs on the monitor page yet because job.printer_uuid and job.assigned_to - # are always None - try: - printer = next(p for p in self._printers if job.printer_uuid == p.key or job.assigned_to == p.key) - except StopIteration: - return Logger.log("w", "Missing printer %s for job %s in %s", job.printer_uuid, job.uuid, - [p.key for p in self._printers]) - - print_job = job.createOutputModel(printer) + print_job = job.createOutputModel(CloudOutputController(self)) + self._updatePrintJobDetails(print_job) self._print_jobs.append(print_job) + def _updatePrintJobDetails(self, print_job: UM3PrintJobOutputModel): + printer = None + try: + printer = next(p for p in self._printers if print_job.assignedPrinter == p.key) + except StopIteration: + Logger.log("w", "Missing printer %s for job %s in %s", print_job.assignedPrinter, print_job.key, + [p.key for p in self._printers]) + + if printer: + printer.updateActivePrintJob(print_job) + print_job.updateAssignedPrinter(printer) + def _onPrintJobCreated(self, mesh: bytes, job_response: CloudJobResponse) -> None: self._api.uploadMesh(job_response, mesh, self._onPrintJobUploaded, self._updateUploadProgress, lambda _: self._onUploadError(T.UPLOAD_ERROR)) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py index f4d211f8f4..cf3e28aef7 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py @@ -2,7 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. from typing import List, Optional -from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel +from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputController import CloudOutputController from .CloudClusterPrinterConfiguration import CloudClusterPrinterConfiguration from .CloudClusterPrintJobConstraint import CloudClusterPrintJobConstraint from ...Models import BaseModel @@ -38,11 +38,9 @@ class CloudClusterPrintJob(BaseModel): ## Creates an UM3 print job output model based on this cloud cluster print job. # \param printer: The output model of the printer - def createOutputModel(self, printer: PrinterOutputModel) -> UM3PrintJobOutputModel: - model = UM3PrintJobOutputModel(printer.getController(), self.uuid, self.name) + def createOutputModel(self, controller: CloudOutputController) -> UM3PrintJobOutputModel: + model = UM3PrintJobOutputModel(controller, self.uuid, self.name) # TODO: implement more data as shown in ClusterUM3OutputDevice._createPrintJobModel - model.updateAssignedPrinter(printer) - printer.updateActivePrintJob(model) return model ## Updates an UM3 print job output model based on this cloud cluster print job. From 05b32548f38b279da211279d753016ac19ef74dd Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 6 Dec 2018 16:27:56 +0100 Subject: [PATCH 0745/1292] Code style: Start comments with a space Contributes to issue CURA-5876. --- cura/Settings/ExtruderStack.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/Settings/ExtruderStack.py b/cura/Settings/ExtruderStack.py index d626ef06da..edb0e7d41f 100644 --- a/cura/Settings/ExtruderStack.py +++ b/cura/Settings/ExtruderStack.py @@ -52,8 +52,8 @@ class ExtruderStack(CuraContainerStack): return super().getNextStack() def setEnabled(self, enabled: bool) -> None: - if self.getMetaDataEntry("enabled", True) == enabled: #No change. - return #Don't emit a signal then. + if self.getMetaDataEntry("enabled", True) == enabled: # No change. + return # Don't emit a signal then. self.setMetaDataEntry("enabled", str(enabled)) self.enabledChanged.emit() From 2af33738d17f95c87dcb8c826b0940576e4359c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Thu, 6 Dec 2018 16:32:00 +0100 Subject: [PATCH 0746/1292] Don't look at the timer --- .../src/Cloud/CloudOutputDeviceManager.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 5d55d30548..bc410a4a1d 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -58,10 +58,13 @@ class CloudOutputDeviceManager: # Called when the uses logs in or out def _onLoginStateChanged(self) -> None: - if self._account.isLoggedIn and not self._update_timer.isActive(): - self._update_timer.start() + if self._account.isLoggedIn: + if not self._update_timer.isActive(): + self._update_timer.start() else: - self._update_timer.stop() + if self._update_timer.isActive(): + self._update_timer.stop() + # Notify that all clusters have disappeared self._onGetRemoteClustersFinished([]) From 4b8e3c32cbd46ef2f4ff63ca6a53654d2c22b0ec Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 6 Dec 2018 16:37:47 +0100 Subject: [PATCH 0747/1292] Also show the login required if an update is needed CURA-6006 --- plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml b/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml index 8a11b402d2..37d9bce4c5 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml @@ -40,7 +40,7 @@ Column Label { wrapMode: Text.WordWrap - text:"Log in is required to install" + text: catalog.i18nc("@label:The string between and is the highlighted link", "Log in is required to install or update") font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") linkColor: UM.Theme.getColor("text_link") @@ -49,7 +49,7 @@ Column MouseArea { anchors.fill: parent - onClicked:Cura.API.account.login() + onClicked: Cura.API.account.login() } } @@ -68,7 +68,7 @@ Column } onActiveAction: toolbox.cancelDownload() // Don't allow installing while another download is running - enabled: !(toolbox.isDownloading && toolbox.activePackage != model) + enabled: !(toolbox.isDownloading && toolbox.activePackage != model) && !loginRequired opacity: enabled ? 1.0 : 0.5 visible: canUpdate } From 717fb260c15b2364e28d2de6ab4200d2c148a697 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 6 Dec 2018 16:58:01 +0100 Subject: [PATCH 0748/1292] Change toolbox tabs to controls2 CURA-6006 --- .../resources/qml/ToolboxTabButton.qml | 75 +++++++++---------- 1 file changed, 37 insertions(+), 38 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxTabButton.qml b/plugins/Toolbox/resources/qml/ToolboxTabButton.qml index b671d779f8..fa4f75d6fe 100644 --- a/plugins/Toolbox/resources/qml/ToolboxTabButton.qml +++ b/plugins/Toolbox/resources/qml/ToolboxTabButton.qml @@ -2,50 +2,49 @@ // Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 +import QtQuick.Controls 2.0 import UM 1.1 as UM Button { + id: control property bool active: false - style: ButtonStyle + hoverEnabled: true + + background: Item { - background: Rectangle + implicitWidth: UM.Theme.getSize("toolbox_header_tab").width + implicitHeight: UM.Theme.getSize("toolbox_header_tab").height + Rectangle { - color: "transparent" - implicitWidth: UM.Theme.getSize("toolbox_header_tab").width - implicitHeight: UM.Theme.getSize("toolbox_header_tab").height - Rectangle - { - visible: control.active - color: UM.Theme.getColor("toolbox_header_highlight_hover") - anchors.bottom: parent.bottom - width: parent.width - height: UM.Theme.getSize("toolbox_header_highlight").height - } - } - label: Label - { - text: control.text - color: - { - if(control.hovered) - { - return UM.Theme.getColor("toolbox_header_button_text_hovered"); - } - if(control.active) - { - return UM.Theme.getColor("toolbox_header_button_text_active"); - } - else - { - return UM.Theme.getColor("toolbox_header_button_text_inactive"); - } - } - font: control.enabled ? (control.active ? UM.Theme.getFont("medium_bold") : UM.Theme.getFont("medium")) : UM.Theme.getFont("default_italic") - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter + visible: control.active + color: UM.Theme.getColor("primary") + anchors.bottom: parent.bottom + width: parent.width + height: UM.Theme.getSize("toolbox_header_highlight").height } } -} + contentItem: Label + { + id: label + text: control.text + color: + { + if(control.hovered) + { + return UM.Theme.getColor("toolbox_header_button_text_hovered"); + } + if(control.active) + { + return UM.Theme.getColor("toolbox_header_button_text_active"); + } + else + { + return UM.Theme.getColor("toolbox_header_button_text_inactive"); + } + } + font: control.enabled ? (control.active ? UM.Theme.getFont("medium_bold") : UM.Theme.getFont("medium")) : UM.Theme.getFont("default_italic") + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + } +} \ No newline at end of file From 3ebefa4f8a232b87a5885937aeaf5818f0573271 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Thu, 6 Dec 2018 16:59:09 +0100 Subject: [PATCH 0749/1292] Add more TODO comments to clarify --- plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py | 2 ++ .../UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index fd21d32256..9f5857dff6 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -287,6 +287,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # TODO: we see that not all data in the UI is correctly updated when the queue and active jobs change. # TODO: we need to fix this here somehow by updating the correct output models. + # TODO: also the configuration drop down in the slice window is not populated because we are missing some data. + # TODO: to fix this we need to implement more data as shown in ClusterUM3OutputDevice._createPrintJobModel for removed_job in removed_jobs: self._print_jobs.remove(removed_job) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py index cf3e28aef7..c9255b8da8 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py @@ -40,7 +40,6 @@ class CloudClusterPrintJob(BaseModel): # \param printer: The output model of the printer def createOutputModel(self, controller: CloudOutputController) -> UM3PrintJobOutputModel: model = UM3PrintJobOutputModel(controller, self.uuid, self.name) - # TODO: implement more data as shown in ClusterUM3OutputDevice._createPrintJobModel return model ## Updates an UM3 print job output model based on this cloud cluster print job. From 2c9c9d8c962607311488a9a14526fb286de543a9 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 6 Dec 2018 17:23:02 +0100 Subject: [PATCH 0750/1292] Handle non-happy path for downloading CURA-6006 --- plugins/Toolbox/src/Toolbox.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index ef67dc3c86..ab975548ce 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -671,6 +671,11 @@ class Toolbox(QObject, Extension): if bytes_sent == bytes_total: self.setIsDownloading(False) cast(QNetworkReply, self._download_reply).downloadProgress.disconnect(self._onDownloadProgress) + + # Check if the download was sucessfull + if self._download_reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) != 200: + Logger.log("w", "Failed to download package. The following error was returned: %s", json.loads(bytes(self._download_reply.readAll()).decode("utf-8"))) + return # Must not delete the temporary file on Windows self._temp_plugin_file = tempfile.NamedTemporaryFile(mode = "w+b", suffix = ".curapackage", delete = False) file_path = self._temp_plugin_file.name From d4a255c9e5779c8131ebb9743a5adf472530f99f Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 6 Dec 2018 17:35:58 +0100 Subject: [PATCH 0751/1292] Also add the login required label at the installed plugin list CURA-6006 --- .../qml/ToolboxDetailTileActions.qml | 1 - .../qml/ToolboxInstalledTileActions.qml | 21 +++++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml b/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml index 37d9bce4c5..cc32ff032d 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml @@ -36,7 +36,6 @@ Column visible: !updateButton.visible // Don't show when the update button is visible } - Label { wrapMode: Text.WordWrap diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml index eb3a93f274..39528f6437 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml @@ -6,12 +6,13 @@ import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM -import Cura 1.0 as Cura +import Cura 1.1 as Cura Column { property bool canUpdate: false property bool canDowngrade: false + property bool loginRequired: model.login_required && !Cura.API.account.isLoggedIn width: UM.Theme.getSize("toolbox_action_button").width spacing: UM.Theme.getSize("narrow_margin").height @@ -40,11 +41,27 @@ Column onActiveAction: toolbox.cancelDownload() // Don't allow installing while another download is running - enabled: !(toolbox.isDownloading && toolbox.activePackage != model) + enabled: !(toolbox.isDownloading && toolbox.activePackage != model) && !loginRequired opacity: enabled ? 1.0 : 0.5 visible: canUpdate } + Label + { + wrapMode: Text.WordWrap + text: catalog.i18nc("@label:The string between and is the highlighted link", "Log in is required to update") + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + linkColor: UM.Theme.getColor("text_link") + visible: loginRequired + width: updateButton.width + MouseArea + { + anchors.fill: parent + onClicked: Cura.API.account.login() + } + } + Cura.SecondaryButton { id: removeButton From eddf4e7f3d96296576e8124fcfd3a86e01adf7e3 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 6 Dec 2018 19:38:12 +0100 Subject: [PATCH 0752/1292] Simplify QML --- .../resources/qml/ToolboxInstalledPage.qml | 33 +++++++------------ 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml index e683f89823..738cdde323 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml @@ -21,44 +21,39 @@ ScrollView Column { spacing: UM.Theme.getSize("default_margin").height + visible: toolbox.pluginsInstalledModel.items.length > 0 + height: childrenRect.height + 4 * UM.Theme.getSize("default_margin").height + anchors { right: parent.right left: parent.left - leftMargin: UM.Theme.getSize("wide_margin").width - topMargin: UM.Theme.getSize("wide_margin").height - bottomMargin: UM.Theme.getSize("wide_margin").height + margins: UM.Theme.getSize("default_margin").width top: parent.top } - height: childrenRect.height + 4 * UM.Theme.getSize("default_margin").height + Label { - visible: toolbox.pluginsInstalledModel.items.length > 0 - width: parent.width + width: page.width text: catalog.i18nc("@title:tab", "Plugins") color: UM.Theme.getColor("text_medium") font: UM.Theme.getFont("medium") } Rectangle { - visible: toolbox.pluginsInstalledModel.items.length > 0 color: "transparent" width: parent.width - height: childrenRect.height + 1 * UM.Theme.getSize("default_lining").width + height: childrenRect.height + UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") border.width: UM.Theme.getSize("default_lining").width Column { - height: childrenRect.height anchors { top: parent.top right: parent.right left: parent.left - leftMargin: UM.Theme.getSize("default_margin").width - rightMargin: UM.Theme.getSize("default_margin").width - topMargin: UM.Theme.getSize("default_lining").width - bottomMargin: UM.Theme.getSize("default_lining").width + margins: UM.Theme.getSize("default_margin").width } Repeater { @@ -70,32 +65,26 @@ ScrollView } Label { - visible: toolbox.materialsInstalledModel.items.length > 0 - width: page.width text: catalog.i18nc("@title:tab", "Materials") color: UM.Theme.getColor("text_medium") font: UM.Theme.getFont("medium") } + Rectangle { - visible: toolbox.materialsInstalledModel.items.length > 0 color: "transparent" width: parent.width - height: childrenRect.height + 1 * UM.Theme.getSize("default_lining").width + height: childrenRect.height + UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") border.width: UM.Theme.getSize("default_lining").width Column { - height: Math.max( UM.Theme.getSize("wide_margin").height, childrenRect.height) anchors { top: parent.top right: parent.right left: parent.left - leftMargin: UM.Theme.getSize("default_margin").width - rightMargin: UM.Theme.getSize("default_margin").width - topMargin: UM.Theme.getSize("default_lining").width - bottomMargin: UM.Theme.getSize("default_lining").width + margins: UM.Theme.getSize("default_margin").width } Repeater { From b33ce7a50f891165fe71e964815804e2a9427f6a Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 7 Dec 2018 09:35:08 +0100 Subject: [PATCH 0753/1292] Fix alignment of download grid tile CURA-6006 --- plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index 887140bbfa..d6eedbcde5 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -63,6 +63,8 @@ Item { width: parent.width - thumbnail.width - parent.spacing spacing: Math.floor(UM.Theme.getSize("narrow_margin").width) + anchors.top: parent.top + anchors.topMargin: UM.Theme.getSize("default_margin").height Label { id: name From 2a0954f24683066f28698b03b261721fc02847b0 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 7 Dec 2018 09:35:53 +0100 Subject: [PATCH 0754/1292] Gracefully handle the conectionError when logging in --- cura/OAuth2/AuthorizationHelpers.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/cura/OAuth2/AuthorizationHelpers.py b/cura/OAuth2/AuthorizationHelpers.py index f75ad9c9f9..762d0db069 100644 --- a/cura/OAuth2/AuthorizationHelpers.py +++ b/cura/OAuth2/AuthorizationHelpers.py @@ -81,9 +81,14 @@ class AuthorizationHelpers: # \param access_token: The encoded JWT token. # \return: Dict containing some profile data. def parseJWT(self, access_token: str) -> Optional["UserProfile"]: - token_request = requests.get("{}/check-token".format(self._settings.OAUTH_SERVER_URL), headers = { - "Authorization": "Bearer {}".format(access_token) - }) + try: + token_request = requests.get("{}/check-token".format(self._settings.OAUTH_SERVER_URL), headers = { + "Authorization": "Bearer {}".format(access_token) + }) + except ConnectionError: + # Connection was suddenly dropped. Nothing we can do about that. + Logger.logException("e", "Something failed while attempting to parse the JWT token") + return None if token_request.status_code not in (200, 201): Logger.log("w", "Could not retrieve token data from auth server: %s", token_request.text) return None From 9eb09132d66d989120d7002b212bbcd4f5816fa3 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 7 Dec 2018 09:38:02 +0100 Subject: [PATCH 0755/1292] Fix minor layout issue installed page CURA-6006 --- plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml index 738cdde323..3d5cd1c8d4 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml @@ -43,7 +43,7 @@ ScrollView { color: "transparent" width: parent.width - height: childrenRect.height + UM.Theme.getSize("default_lining").width + height: childrenRect.height + UM.Theme.getSize("default_margin").width border.color: UM.Theme.getColor("lining") border.width: UM.Theme.getSize("default_lining").width Column @@ -74,7 +74,7 @@ ScrollView { color: "transparent" width: parent.width - height: childrenRect.height + UM.Theme.getSize("default_lining").width + height: childrenRect.height + UM.Theme.getSize("default_margin").width border.color: UM.Theme.getColor("lining") border.width: UM.Theme.getSize("default_lining").width Column From eaf413997d0c5ca4b317a0d65b5aef5c44131627 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 7 Dec 2018 09:44:09 +0100 Subject: [PATCH 0756/1292] Changed the installed button to be a secondary button CURA-6006 --- .../qml/ToolboxDetailTileActions.qml | 40 ++++++++++++------- .../resources/qml/ToolboxProgressButton.qml | 1 + 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml b/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml index cc32ff032d..848acfbf4f 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml @@ -16,24 +16,36 @@ Column width: UM.Theme.getSize("toolbox_action_button").width spacing: UM.Theme.getSize("narrow_margin").height - ToolboxProgressButton + Item { - id: installButton - active: toolbox.isDownloading && toolbox.activePackage == model - complete: installed - onReadyAction: + width: installButton.width + height: installButton.height + ToolboxProgressButton { - toolbox.activePackage = model - toolbox.startDownload(model.download_url) + id: installButton + active: toolbox.isDownloading && toolbox.activePackage == model + onReadyAction: + { + toolbox.activePackage = model + toolbox.startDownload(model.download_url) + } + onActiveAction: toolbox.cancelDownload() + + // Don't allow installing while another download is running + enabled: installed || (!(toolbox.isDownloading && toolbox.activePackage != model) && !loginRequired) + opacity: enabled ? 1.0 : 0.5 + visible: !updateButton.visible && !installed// Don't show when the update button is visible } - onActiveAction: toolbox.cancelDownload() - onCompleteAction: toolbox.viewCategory = "installed" - - // Don't allow installing while another download is running - enabled: installed || (!(toolbox.isDownloading && toolbox.activePackage != model) && !loginRequired) - opacity: enabled ? 1.0 : 0.5 - visible: !updateButton.visible // Don't show when the update button is visible + Cura.SecondaryButton + { + visible: installed + onClicked: toolbox.viewCategory = "installed" + text: catalog.i18nc("@action:button", "Installed") + fixedWidthMode: true + width: installButton.width + height: installButton.height + } } Label diff --git a/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml b/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml index 0b574e8653..3ca18a52ed 100644 --- a/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml +++ b/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml @@ -7,6 +7,7 @@ import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM import Cura 1.0 as Cura +// TODO; This is in quite some need for refactoring. Item { id: base From 4bffa6d90f2e6e9784c7e5508b61e00a92ecb74f Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 7 Dec 2018 10:22:32 +0100 Subject: [PATCH 0757/1292] Revert "fix merge conflict" This reverts commit ec03b012a77a766e45a43a224bbb76cd32d0915a, reversing changes made to 2af33738d17f95c87dcb8c826b0940576e4359c3. --- cura/Settings/ExtruderManager.py | 4 +- cura/Settings/ExtruderStack.py | 4 +- cura/Settings/ExtrudersModel.py | 6 +- cura/Settings/MachineManager.py | 4 +- .../ProcessSlicedLayersJob.py | 2 +- .../MachineSettingsAction.qml | 4 +- plugins/ModelChecker/ModelChecker.qml | 1 + .../PerObjectSettingsPanel.qml | 1 + .../PostProcessingPlugin.qml | 4 + plugins/PrepareStage/PrepareMenu.qml | 3 +- .../SimulationViewMainComponent.qml | 7 +- .../resources/qml/ToolboxAuthorPage.qml | 8 +- .../qml/ToolboxCompatibilityChart.qml | 2 +- .../resources/qml/ToolboxDetailPage.qml | 16 +- .../qml/ToolboxDownloadsGridTile.qml | 3 +- .../qml/ToolboxDownloadsShowcaseTile.qml | 2 + .../resources/qml/DiscoverUM3Action.qml | 16 +- .../qml/MonitorBuildplateConfiguration.qml | 2 +- .../qml/MonitorExtruderConfiguration.qml | 4 +- .../resources/qml/MonitorPrinterCard.qml | 10 +- .../src/ClusterUM3OutputDevice.py | 12 +- resources/qml/ActionButton.qml | 35 +- .../ActionPanel/OutputDevicesActionButton.qml | 4 - .../qml/ActionPanel/OutputProcessWidget.qml | 27 +- .../ActionPanel/PrintInformationWidget.qml | 3 + .../qml/ActionPanel/PrintJobInformation.qml | 8 +- .../qml/ActionPanel/SliceProcessWidget.qml | 7 +- resources/qml/Cura.qml | 89 +- resources/qml/CustomConfigurationSelector.qml | 357 ++++ resources/qml/Dialogs/AboutDialog.qml | 6 +- resources/qml/Dialogs/AddMachineDialog.qml | 5 +- resources/qml/ExpandableComponent.qml | 6 +- resources/qml/ExtruderIcon.qml | 7 +- resources/qml/IconLabel.qml | 5 +- resources/qml/IconWithText.qml | 2 + resources/qml/JobSpecs.qml | 3 +- resources/qml/MainWindow/MainWindowHeader.qml | 30 +- .../ConfigurationMenu/AutoConfiguration.qml | 39 - .../ConfigurationMenu/ConfigurationItem.qml | 212 +- .../ConfigurationListView.qml | 77 +- .../ConfigurationMenu/ConfigurationMenu.qml | 203 -- .../ConfigurationMenu/CustomConfiguration.qml | 250 --- .../PrintCoreConfiguration.qml | 107 +- .../QuickConfigurationSelector.qml | 243 +++ .../Menus/ConfigurationMenu/SyncButton.qml | 102 + resources/qml/Menus/ProfileMenu.qml | 8 +- resources/qml/ObjectsList.qml | 3 +- resources/qml/Preferences/MachinesPage.qml | 8 +- .../Materials/MaterialsBrandSection.qml | 5 +- .../Preferences/Materials/MaterialsList.qml | 8 +- .../Preferences/Materials/MaterialsSlot.qml | 2 + .../Materials/MaterialsTypeSection.qml | 2 + resources/qml/Preferences/ProfilesPage.qml | 24 +- .../qml/Preferences/SettingVisibilityPage.qml | 2 +- resources/qml/PrinterOutput/ExtruderBox.qml | 2 +- resources/qml/PrinterOutput/HeatedBedBox.qml | 2 +- .../qml/PrinterOutput/OutputDeviceHeader.qml | 4 +- .../qml/PrinterSelector/MachineSelector.qml | 60 +- .../PrinterSelector/MachineSelectorList.qml | 2 +- .../PrinterTypeLabel.qml | 2 +- resources/qml/Settings/SettingCategory.qml | 13 +- resources/qml/Settings/SettingCheckBox.qml | 4 +- .../qml/Settings/SettingOptionalExtruder.qml | 13 +- resources/qml/Settings/SettingView.qml | 11 +- resources/qml/SidebarSimple.qml | 7 +- resources/qml/Toolbar.qml | 2 +- resources/qml/ViewsSelector.qml | 6 +- resources/qml/qmldir | 1 + resources/themes/cura-dark/theme.json | 10 +- .../cura-light/images/header_pattern.svg | 1902 +---------------- .../themes/cura-light/images/logo_about.svg | 172 -- resources/themes/cura-light/styles.qml | 9 +- resources/themes/cura-light/theme.json | 51 +- 73 files changed, 1223 insertions(+), 3054 deletions(-) create mode 100644 resources/qml/CustomConfigurationSelector.qml delete mode 100644 resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml delete mode 100644 resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml delete mode 100644 resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml create mode 100644 resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml create mode 100644 resources/qml/Menus/ConfigurationMenu/SyncButton.qml rename resources/qml/{ => PrinterSelector}/PrinterTypeLabel.qml (95%) delete mode 100644 resources/themes/cura-light/images/logo_about.svg diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index b0bcf3b100..9089ba96e9 100755 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -63,7 +63,7 @@ class ExtruderManager(QObject): if not self._application.getGlobalContainerStack(): return None # No active machine, so no active extruder. try: - return self._extruder_trains[self._application.getGlobalContainerStack().getId()][str(self.activeExtruderIndex)].getId() + return self._extruder_trains[self._application.getGlobalContainerStack().getId()][str(self._active_extruder_index)].getId() except KeyError: # Extruder index could be -1 if the global tab is selected, or the entry doesn't exist if the machine definition is wrong. return None @@ -144,7 +144,7 @@ class ExtruderManager(QObject): @pyqtSlot(result = QObject) def getActiveExtruderStack(self) -> Optional["ExtruderStack"]: - return self.getExtruderStack(self.activeExtruderIndex) + return self.getExtruderStack(self._active_extruder_index) ## Get an extruder stack by index def getExtruderStack(self, index) -> Optional["ExtruderStack"]: diff --git a/cura/Settings/ExtruderStack.py b/cura/Settings/ExtruderStack.py index d626ef06da..d7faedb71c 100644 --- a/cura/Settings/ExtruderStack.py +++ b/cura/Settings/ExtruderStack.py @@ -52,8 +52,8 @@ class ExtruderStack(CuraContainerStack): return super().getNextStack() def setEnabled(self, enabled: bool) -> None: - if self.getMetaDataEntry("enabled", True) == enabled: #No change. - return #Don't emit a signal then. + if "enabled" not in self._metadata: + self.setMetaDataEntry("enabled", "True") self.setMetaDataEntry("enabled", str(enabled)) self.enabledChanged.emit() diff --git a/cura/Settings/ExtrudersModel.py b/cura/Settings/ExtrudersModel.py index 5f10ac99d4..14a8dadc69 100644 --- a/cura/Settings/ExtrudersModel.py +++ b/cura/Settings/ExtrudersModel.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018 Ultimaker B.V. +# Copyright (c) 2017 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot, pyqtProperty, QTimer @@ -165,7 +165,7 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): def __updateExtruders(self): extruders_changed = False - if self.count != 0: + if self.rowCount() != 0: extruders_changed = True items = [] @@ -177,7 +177,7 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): machine_extruder_count = global_container_stack.getProperty("machine_extruder_count", "value") for extruder in Application.getInstance().getExtruderManager().getActiveExtruderStacks(): - position = extruder.getMetaDataEntry("position", default = "0") + position = extruder.getMetaDataEntry("position", default = "0") # Get the position try: position = int(position) except ValueError: diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index a472cc7f09..53390ca88d 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -874,7 +874,7 @@ class MachineManager(QObject): caution_message = Message(catalog.i18nc( "@info:generic", "Settings have been changed to match the current availability of extruders: [%s]" % ", ".join(add_user_changes)), - lifetime = 0, + lifetime=0, title = catalog.i18nc("@info:title", "Settings updated")) caution_message.show() @@ -1553,7 +1553,7 @@ class MachineManager(QObject): elif word.isdigit(): abbr_machine += word else: - stripped_word = "".join(char for char in unicodedata.normalize("NFD", word.upper()) if unicodedata.category(char) != "Mn") + stripped_word = ''.join(char for char in unicodedata.normalize('NFD', word.upper()) if unicodedata.category(char) != 'Mn') # - use only the first character if the word is too long (> 3 characters) # - use the whole word if it's not too long (<= 3 characters) if len(stripped_word) > 3: diff --git a/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py b/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py index 71c96880e8..594bf3a43e 100644 --- a/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py +++ b/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py @@ -195,7 +195,7 @@ class ProcessSlicedLayersJob(Job): if extruders: material_color_map = numpy.zeros((len(extruders), 4), dtype=numpy.float32) for extruder in extruders: - position = int(extruder.getMetaDataEntry("position", default = "0")) + position = int(extruder.getMetaDataEntry("position", default="0")) # Get the position try: default_color = ExtrudersModel.defaultColors[position] except IndexError: diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index c88a721a84..004b4e3cfc 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -1,4 +1,4 @@ -// Copyright (c) 2018 Ultimaker B.V. +// Copyright (c) 2016 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 @@ -23,7 +23,7 @@ Cura.MachineAction target: base.extrudersModel onModelChanged: { - var extruderCount = base.extrudersModel.count; + var extruderCount = base.extrudersModel.rowCount(); base.extruderTabsCount = extruderCount; } } diff --git a/plugins/ModelChecker/ModelChecker.qml b/plugins/ModelChecker/ModelChecker.qml index 437df29516..5e41591d6b 100644 --- a/plugins/ModelChecker/ModelChecker.qml +++ b/plugins/ModelChecker/ModelChecker.qml @@ -33,6 +33,7 @@ Button { width: UM.Theme.getSize("save_button_specs_icons").width; height: UM.Theme.getSize("save_button_specs_icons").height; + sourceSize.width: width; sourceSize.height: width; color: control.hovered ? UM.Theme.getColor("text_scene_hover") : UM.Theme.getColor("text_scene"); source: "model_checker.svg" diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index 0e2bd88619..5d4e17a102 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -265,6 +265,7 @@ Item { anchors.verticalCenter: parent.verticalCenter width: parent.width height: width + sourceSize.width: width sourceSize.height: width color: control.hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button") source: UM.Theme.getIcon("minus") diff --git a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml index 3fa10c23b9..bd4d361d35 100644 --- a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml +++ b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml @@ -141,6 +141,7 @@ UM.Dialog anchors.horizontalCenter: parent.horizontalCenter width: Math.round(control.width / 2.7) height: Math.round(control.height / 2.7) + sourceSize.width: width sourceSize.height: width color: palette.text source: UM.Theme.getIcon("cross1") @@ -175,6 +176,7 @@ UM.Dialog anchors.horizontalCenter: parent.horizontalCenter width: Math.round(control.width / 2.5) height: Math.round(control.height / 2.5) + sourceSize.width: width sourceSize.height: width color: control.enabled ? palette.text : disabledPalette.text source: UM.Theme.getIcon("arrow_bottom") @@ -209,6 +211,7 @@ UM.Dialog anchors.horizontalCenter: parent.horizontalCenter width: Math.round(control.width / 2.5) height: Math.round(control.height / 2.5) + sourceSize.width: width sourceSize.height: width color: control.enabled ? palette.text : disabledPalette.text source: UM.Theme.getIcon("arrow_top") @@ -495,6 +498,7 @@ UM.Dialog anchors.horizontalCenter: parent.horizontalCenter width: Math.round(parent.width / 2) height: Math.round(parent.height / 2) + sourceSize.width: width sourceSize.height: height color: !control.enabled ? UM.Theme.getColor("action_button_disabled_text") : control.pressed ? UM.Theme.getColor("action_button_active_text") : diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index fa94bc88b2..10b4262f01 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -61,7 +61,7 @@ Item color: UM.Theme.getColor("lining") } - Cura.ConfigurationMenu + Cura.QuickConfigurationSelector { Layout.fillHeight: true Layout.fillWidth: true @@ -107,6 +107,7 @@ Item height: UM.Theme.getSize("button_icon").height color: UM.Theme.getColor("toolbar_button_text") + sourceSize.width: width sourceSize.height: height } } diff --git a/plugins/SimulationView/SimulationViewMainComponent.qml b/plugins/SimulationView/SimulationViewMainComponent.qml index 16b049c921..16b9aeaae6 100644 --- a/plugins/SimulationView/SimulationViewMainComponent.qml +++ b/plugins/SimulationView/SimulationViewMainComponent.qml @@ -61,9 +61,10 @@ Item iconSource: !is_simulation_playing ? "./resources/simulation_resume.svg": "./resources/simulation_pause.svg" width: UM.Theme.getSize("small_button").width height: UM.Theme.getSize("small_button").height - hoverColor: UM.Theme.getColor("slider_handle_active") - color: UM.Theme.getColor("slider_handle") - iconMargin: UM.Theme.getSize("thick_lining").width + hoverBackgroundColor: UM.Theme.getColor("small_button_hover") + hoverColor: UM.Theme.getColor("small_button_text_hover") + color: UM.Theme.getColor("small_button_text") + iconMargin: 0.5 * UM.Theme.getSize("wide_lining").width visible: !UM.SimulationView.compatibilityMode Connections diff --git a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml index 9c1df0c49e..4aaea20813 100644 --- a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml @@ -86,13 +86,13 @@ Item Label { text: catalog.i18nc("@label", "Website") + ":" - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("very_small") color: UM.Theme.getColor("text_medium") } Label { text: catalog.i18nc("@label", "Email") + ":" - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("very_small") color: UM.Theme.getColor("text_medium") } } @@ -118,7 +118,7 @@ Item } return "" } - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("very_small") color: UM.Theme.getColor("text") linkColor: UM.Theme.getColor("text_link") onLinkActivated: Qt.openUrlExternally(link) @@ -134,7 +134,7 @@ Item } return "" } - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("very_small") color: UM.Theme.getColor("text") linkColor: UM.Theme.getColor("text_link") onLinkActivated: Qt.openUrlExternally(link) diff --git a/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml b/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml index d4c0ae14eb..4a6268df42 100644 --- a/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml +++ b/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml @@ -228,7 +228,7 @@ Item return result } - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("very_small") color: UM.Theme.getColor("text") linkColor: UM.Theme.getColor("text_link") onLinkActivated: Qt.openUrlExternally(link) diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 9e2e178b71..c5e9bb0a49 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -82,25 +82,25 @@ Item Label { text: catalog.i18nc("@label", "Version") + ":" - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("very_small") color: UM.Theme.getColor("text_medium") } Label { text: catalog.i18nc("@label", "Last updated") + ":" - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("very_small") color: UM.Theme.getColor("text_medium") } Label { text: catalog.i18nc("@label", "Author") + ":" - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("very_small") color: UM.Theme.getColor("text_medium") } Label { text: catalog.i18nc("@label", "Downloads") + ":" - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("very_small") color: UM.Theme.getColor("text_medium") } } @@ -119,7 +119,7 @@ Item Label { text: details === null ? "" : (details.version || catalog.i18nc("@label", "Unknown")) - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("very_small") color: UM.Theme.getColor("text") } Label @@ -133,7 +133,7 @@ Item var date = new Date(details.last_updated) return date.toLocaleString(UM.Preferences.getValue("general/language")) } - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("very_small") color: UM.Theme.getColor("text") } Label @@ -149,7 +149,7 @@ Item return "" + details.author_name + "" } } - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("very_small") color: UM.Theme.getColor("text") linkColor: UM.Theme.getColor("text_link") onLinkActivated: Qt.openUrlExternally(link) @@ -157,7 +157,7 @@ Item Label { text: details === null ? "" : (details.download_count || catalog.i18nc("@label", "Unknown")) - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("very_small") color: UM.Theme.getColor("text") } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index 61374f9d99..887140bbfa 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -52,6 +52,7 @@ Item bottom: parent.bottom right: parent.right } + sourceSize.width: width sourceSize.height: height visible: installedPackages != 0 color: (installedPackages == packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border") @@ -80,7 +81,7 @@ Item width: parent.width wrapMode: Text.WordWrap color: UM.Theme.getColor("text_medium") - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("very_small") } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml index 8a2fdc8bc8..4fb70541d2 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml @@ -48,6 +48,8 @@ Rectangle right: parent.right bottomMargin: UM.Theme.getSize("default_lining").width } + sourceSize.width: width + sourceSize.height: height visible: installedPackages != 0 color: (installedPackages == packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border") source: "../images/installed_check.svg" diff --git a/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml b/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml index bb710127fc..967adfc029 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml @@ -64,7 +64,6 @@ Cura.MachineAction width: parent.width text: catalog.i18nc("@title:window", "Connect to Networked Printer") wrapMode: Text.WordWrap - renderType: Text.NativeRendering font.pointSize: 18 } @@ -73,7 +72,6 @@ Cura.MachineAction id: pageDescription width: parent.width wrapMode: Text.WordWrap - renderType: Text.NativeRendering text: catalog.i18nc("@label", "To print directly to your printer over the network, please make sure your printer is connected to the network using a network cable or by connecting your printer to your WIFI network. If you don't connect Cura with your printer, you can still use a USB drive to transfer g-code files to your printer.\n\nSelect your printer from the list below:") } @@ -184,7 +182,6 @@ Cura.MachineAction text: listview.model[index].name color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text elide: Text.ElideRight - renderType: Text.NativeRendering } MouseArea @@ -207,7 +204,6 @@ Cura.MachineAction anchors.left: parent.left anchors.right: parent.right wrapMode: Text.WordWrap - renderType: Text.NativeRendering text: catalog.i18nc("@label", "If your printer is not listed, read the network printing troubleshooting guide").arg("https://ultimaker.com/en/troubleshooting"); onLinkActivated: Qt.openUrlExternally(link) } @@ -225,7 +221,6 @@ Cura.MachineAction text: base.selectedDevice ? base.selectedDevice.name : "" font: UM.Theme.getFont("large") elide: Text.ElideRight - renderType: Text.NativeRendering } Grid { @@ -236,14 +231,12 @@ Cura.MachineAction { width: Math.round(parent.width * 0.5) wrapMode: Text.WordWrap - renderType: Text.NativeRendering text: catalog.i18nc("@label", "Type") } Label { width: Math.round(parent.width * 0.5) wrapMode: Text.WordWrap - renderType: Text.NativeRendering text: { if(base.selectedDevice) @@ -275,28 +268,24 @@ Cura.MachineAction { width: Math.round(parent.width * 0.5) wrapMode: Text.WordWrap - renderType: Text.NativeRendering text: catalog.i18nc("@label", "Firmware version") } Label { width: Math.round(parent.width * 0.5) wrapMode: Text.WordWrap - renderType: Text.NativeRendering text: base.selectedDevice ? base.selectedDevice.firmwareVersion : "" } Label { width: Math.round(parent.width * 0.5) wrapMode: Text.WordWrap - renderType: Text.NativeRendering text: catalog.i18nc("@label", "Address") } Label { width: Math.round(parent.width * 0.5) wrapMode: Text.WordWrap - renderType: Text.NativeRendering text: base.selectedDevice ? base.selectedDevice.ipAddress : "" } } @@ -305,7 +294,6 @@ Cura.MachineAction { width: parent.width wrapMode: Text.WordWrap - renderType: Text.NativeRendering text:{ // The property cluster size does not exist for older UM3 devices. if(!base.selectedDevice || base.selectedDevice.clusterSize == null || base.selectedDevice.clusterSize == 1) @@ -327,7 +315,6 @@ Cura.MachineAction { width: parent.width wrapMode: Text.WordWrap - renderType: Text.NativeRendering visible: base.selectedDevice != null && !base.completeProperties text: catalog.i18nc("@label", "The printer at this address has not yet responded." ) } @@ -371,10 +358,9 @@ Cura.MachineAction Label { - text: catalog.i18nc("@alabel", "Enter the IP address or hostname of your printer on the network.") + text: catalog.i18nc("@alabel","Enter the IP address or hostname of your printer on the network.") width: parent.width wrapMode: Text.WordWrap - renderType: Text.NativeRendering } TextField diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml index 7edeb81a96..9ffb1eabb4 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml @@ -52,7 +52,7 @@ Item id: buildplateLabel color: "#191919" // TODO: Theme! elide: Text.ElideRight - font: UM.Theme.getFont("default") // 12pt, regular + font: UM.Theme.getFont("very_small") // 12pt, regular text: "" // FIXED-LINE-HEIGHT: diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorExtruderConfiguration.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorExtruderConfiguration.qml index 1e53191d8c..afbd4c3641 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorExtruderConfiguration.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorExtruderConfiguration.qml @@ -49,7 +49,7 @@ Item } color: "#191919" // TODO: Theme! elide: Text.ElideRight - font: UM.Theme.getFont("default") // 12pt, regular + font: UM.Theme.getFont("very_small") // 12pt, regular text: "" // FIXED-LINE-HEIGHT: @@ -66,7 +66,7 @@ Item } color: "#191919" // TODO: Theme! elide: Text.ElideRight - font: UM.Theme.getFont("default_bold") // 12pt, bold + font: UM.Theme.getFont("small") // 12pt, bold text: "" // FIXED-LINE-HEIGHT: diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml index 567fff8489..8659037cb8 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml @@ -179,15 +179,13 @@ Item color: "#414054" // TODO: Theme! font: UM.Theme.getFont("large") // 16pt, bold text: { - if (printer && printer.state == "disabled") - { + if (printer && printer.state == "disabled"){ return catalog.i18nc("@label:status", "Unavailable") } - if (printer && printer.state == "unreachable") - { - return catalog.i18nc("@label:status", "Unreachable") + if (printer && printer.state == "unreachable"){ + return catalog.i18nc("@label:status", "Unavailable") } - if (printer && printer.state == "idle") + if (printer && !printer.activePrintJob) { return catalog.i18nc("@label:status", "Idle") } diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index a5ee3bc650..cc5b128479 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -572,17 +572,7 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): def _createMaterialOutputModel(self, material_data: Dict[str, Any]) -> "MaterialOutputModel": material_manager = CuraApplication.getInstance().getMaterialManager() - material_group_list = material_manager.getMaterialGroupListByGUID(material_data["guid"]) - # This can happen if the connected machine has no material in one or more extruders (if GUID is empty), or the - # material is unknown to Cura, so we should return an "empty" or "unknown" material model. - if material_group_list is None: - material_name = "Empty" if len(material_data["guid"]) == 0 else "Unknown" - return MaterialOutputModel(guid = material_data["guid"], - type = material_data.get("type", ""), - color = material_data.get("color", ""), - brand = material_data.get("brand", ""), - name = material_data.get("name", material_name) - ) + material_group_list = material_manager.getMaterialGroupListByGUID(material_data["guid"]) or [] # Sort the material groups by "is_read_only = True" first, and then the name alphabetically. read_only_material_group_list = list(filter(lambda x: x.is_read_only, material_group_list)) diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index fc4a1c05f4..b9a04f3b46 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -7,17 +7,14 @@ import QtQuick.Controls 2.1 import QtGraphicalEffects 1.0 // For the dropshadow import UM 1.1 as UM -import Cura 1.0 as Cura Button { id: button - property alias iconSource: buttonIconLeft.source - property bool isIconOnRightSide: false + property alias iconSource: buttonIcon.source property alias textFont: buttonText.font property alias cornerRadius: backgroundRect.radius property alias tooltip: tooltip.text - property alias cornerSide: backgroundRect.cornerSide property color color: UM.Theme.getColor("primary") property color hoverColor: UM.Theme.getColor("primary_hover") @@ -39,21 +36,18 @@ Button // we elide the text to the right so the text will be cut off with the three dots at the end. property var fixedWidthMode: false - leftPadding: UM.Theme.getSize("default_margin").width - rightPadding: UM.Theme.getSize("default_margin").width - height: UM.Theme.getSize("action_button").height - contentItem: Row { - //Left side icon. Only displayed if !isIconOnRightSide. UM.RecolorImage { - id: buttonIconLeft + id: buttonIcon source: "" - height: buttonText.height - width: visible ? height : 0 + height: Math.round(0.6 * parent.height) + width: height + sourceSize.width: width + sourceSize.height: height color: button.hovered ? button.textHoverColor : button.textColor - visible: source != "" && !button.isIconOnRightSide + visible: source != "" anchors.verticalCenter: parent.verticalCenter } @@ -70,24 +64,11 @@ Button horizontalAlignment: Text.AlignHCenter elide: Text.ElideRight } - - //Right side icon. Only displayed if isIconOnRightSide. - UM.RecolorImage - { - id: buttonIconRight - source: buttonIconLeft.source - height: buttonText.height - width: visible ? height : 0 - color: buttonIconLeft.color - visible: source != "" && button.isIconOnRightSide - anchors.verticalCenter: buttonIconLeft.verticalCenter - } } - background: Cura.RoundedRectangle + background: Rectangle { id: backgroundRect - cornerSide: Cura.RoundedRectangle.Direction.All color: button.enabled ? (button.hovered ? button.hoverColor : button.color) : button.disabledColor radius: UM.Theme.getSize("action_button_radius").width border.width: UM.Theme.getSize("default_lining").width diff --git a/resources/qml/ActionPanel/OutputDevicesActionButton.qml b/resources/qml/ActionPanel/OutputDevicesActionButton.qml index 95750e6d11..2111038cfc 100644 --- a/resources/qml/ActionPanel/OutputDevicesActionButton.qml +++ b/resources/qml/ActionPanel/OutputDevicesActionButton.qml @@ -17,7 +17,6 @@ Item id: saveToButton height: parent.height fixedWidthMode: true - cornerSide: deviceSelectionMenu.visible ? Cura.RoundedRectangle.Direction.Left : Cura.RoundedRectangle.Direction.All anchors { @@ -45,7 +44,6 @@ Item shadowEnabled: true shadowColor: UM.Theme.getColor("primary_shadow") - cornerSide: Cura.RoundedRectangle.Direction.Right anchors { @@ -53,8 +51,6 @@ Item right: parent.right } - leftPadding: UM.Theme.getSize("narrow_margin").width //Need more space than usual here for wide text. - rightPadding: UM.Theme.getSize("narrow_margin").width tooltip: catalog.i18nc("@info:tooltip", "Select the active output device") iconSource: popup.opened ? UM.Theme.getIcon("arrow_top") : UM.Theme.getIcon("arrow_bottom") color: UM.Theme.getColor("action_panel_secondary") diff --git a/resources/qml/ActionPanel/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml index 1d1a1e44e1..6ab8dc6fbb 100644 --- a/resources/qml/ActionPanel/OutputProcessWidget.qml +++ b/resources/qml/ActionPanel/OutputProcessWidget.qml @@ -51,7 +51,7 @@ Column text: preSlicedData ? catalog.i18nc("@label", "No time estimation available") : PrintInformation.currentPrintTime.getDisplayString(UM.DurationFormat.Long) source: UM.Theme.getIcon("clock") - font: UM.Theme.getFont("default_bold") + font: UM.Theme.getFont("small") } Cura.IconLabel @@ -84,7 +84,7 @@ Column return totalWeights + "g · " + totalLengths.toFixed(2) + "m" } source: UM.Theme.getIcon("spool") - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("very_small") } } @@ -101,25 +101,17 @@ Column } } - Item + Row { id: buttonRow - anchors.right: parent.right - anchors.left: parent.left - height: UM.Theme.getSize("action_button").height + spacing: UM.Theme.getSize("default_margin").width + width: parent.width Cura.SecondaryButton { id: previewStageShortcut - anchors - { - left: parent.left - right: outputDevicesButton.left - rightMargin: UM.Theme.getSize("default_margin").width - } - - height: UM.Theme.getSize("action_button").height + height: UM.Theme.getSize("action_panel_button").height leftPadding: UM.Theme.getSize("default_margin").width rightPadding: UM.Theme.getSize("default_margin").width text: catalog.i18nc("@button", "Preview") @@ -133,11 +125,8 @@ Column Cura.OutputDevicesActionButton { - id: outputDevicesButton - - anchors.right: parent.right - width: previewStageShortcut.visible ? UM.Theme.getSize("action_button").width : parent.width - height: UM.Theme.getSize("action_button").height + width: previewStageShortcut.visible ? UM.Theme.getSize("action_panel_button").width : parent.width + height: UM.Theme.getSize("action_panel_button").height } } } \ No newline at end of file diff --git a/resources/qml/ActionPanel/PrintInformationWidget.qml b/resources/qml/ActionPanel/PrintInformationWidget.qml index 554273a818..25e380dea8 100644 --- a/resources/qml/ActionPanel/PrintInformationWidget.qml +++ b/resources/qml/ActionPanel/PrintInformationWidget.qml @@ -15,6 +15,9 @@ UM.RecolorImage width: UM.Theme.getSize("section_icon").width height: UM.Theme.getSize("section_icon").height + sourceSize.width: width + sourceSize.height: height + color: popup.opened ? UM.Theme.getColor("primary") : UM.Theme.getColor("text_medium") MouseArea diff --git a/resources/qml/ActionPanel/PrintJobInformation.qml b/resources/qml/ActionPanel/PrintJobInformation.qml index 8bd5d5a0d3..156111af4d 100644 --- a/resources/qml/ActionPanel/PrintJobInformation.qml +++ b/resources/qml/ActionPanel/PrintJobInformation.qml @@ -30,7 +30,7 @@ Column { text: catalog.i18nc("@label", "Time specification").toUpperCase() color: UM.Theme.getColor("primary") - font: UM.Theme.getFont("default_bold") + font: UM.Theme.getFont("small") renderType: Text.NativeRendering } @@ -61,7 +61,7 @@ Column } width: parent.width - 2 * UM.Theme.getSize("default_margin").width color: UM.Theme.getColor("text") - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("very_small") renderType: Text.NativeRendering textFormat: Text.RichText } @@ -79,7 +79,7 @@ Column { text: catalog.i18nc("@label", "Material specification").toUpperCase() color: UM.Theme.getColor("primary") - font: UM.Theme.getFont("default_bold") + font: UM.Theme.getFont("small") renderType: Text.NativeRendering } @@ -151,7 +151,7 @@ Column } width: parent.width - 2 * UM.Theme.getSize("default_margin").width color: UM.Theme.getColor("text") - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("very_small") renderType: Text.NativeRendering textFormat: Text.RichText } diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index 8f6608e15c..03d91db530 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -48,7 +48,7 @@ Column text: catalog.i18nc("@label:PrintjobStatus", "Auto slicing...") color: UM.Theme.getColor("text") - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("very_small") renderType: Text.NativeRendering } @@ -61,7 +61,7 @@ Column text: catalog.i18nc("@label:PrintjobStatus", "Unable to Slice") source: UM.Theme.getIcon("warning") color: UM.Theme.getColor("warning") - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("very_small") } // Progress bar, only visible when the backend is in the process of slice the printjob @@ -94,6 +94,7 @@ Column } } + Item { id: prepareButtons @@ -102,7 +103,7 @@ Column // Disable the slice process when width: parent.width - height: UM.Theme.getSize("action_button").height + height: UM.Theme.getSize("action_panel_button").height visible: !autoSlice Cura.PrimaryButton { diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 4e8e9ce788..3578888886 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -88,54 +88,6 @@ UM.MainWindow window: base } - Rectangle - { - id: headerBackground - anchors - { - top: applicationMenu.bottom - left: parent.left - right: parent.right - } - height: stageMenu.source != "" ? Math.round(mainWindowHeader.height + stageMenu.height / 2) : mainWindowHeader.height - - LinearGradient - { - anchors.fill: parent - start: Qt.point(0, 0) - end: Qt.point(parent.width, 0) - gradient: Gradient - { - GradientStop - { - position: 0.0 - color: UM.Theme.getColor("main_window_header_background") - } - GradientStop - { - position: 0.5 - color: UM.Theme.getColor("main_window_header_background_gradient") - } - GradientStop - { - position: 1.0 - color: UM.Theme.getColor("main_window_header_background") - } - } - } - - // This is the new fancy pattern - Image - { - id: backgroundPattern - anchors.fill: parent - fillMode: Image.Tile - source: UM.Theme.getImage("header_pattern") - horizontalAlignment: Image.AlignLeft - verticalAlignment: Image.AlignTop - } - } - MainWindowHeader { id: mainWindowHeader @@ -192,6 +144,44 @@ UM.MainWindow } } + Rectangle + { + id: stageMenuBackground + anchors + { + left: parent.left + right: parent.right + top: parent.top + } + visible: stageMenu.source != "" + height: visible ? Math.round(UM.Theme.getSize("stage_menu").height / 2) : 0 + + LinearGradient + { + anchors.fill: parent + start: Qt.point(0, 0) + end: Qt.point(parent.width, 0) + gradient: Gradient + { + GradientStop + { + position: 0.0 + color: UM.Theme.getColor("main_window_header_background") + } + GradientStop + { + position: 0.5 + color: UM.Theme.getColor("main_window_header_background_gradient") + } + GradientStop + { + position: 1.0 + color: UM.Theme.getColor("main_window_header_background") + } + } + } + } + Connections { target: stageMenu.item @@ -267,8 +257,7 @@ UM.MainWindow anchors { - // Align to the top of the stageMenu since the stageMenu may not exist - top: parent.top + top: stageMenuBackground.bottom left: parent.left right: parent.right bottom: parent.bottom diff --git a/resources/qml/CustomConfigurationSelector.qml b/resources/qml/CustomConfigurationSelector.qml new file mode 100644 index 0000000000..c78ca700da --- /dev/null +++ b/resources/qml/CustomConfigurationSelector.qml @@ -0,0 +1,357 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +Rectangle +{ + implicitWidth: parent.width + implicitHeight: parent.height + + id: base + color: UM.Theme.getColor("main_background") + + // Height has an extra 2x margin for the top & bottom margin. + height: childrenRect.height + 2 * UM.Theme.getSize("default_margin").width + + Cura.ExtrudersModel { id: extrudersModel } + + ListView + { + // Horizontal list that shows the extruders + id: extrudersList + visible: extrudersModel.items.length > 1 + property var index: 0 + + height: UM.Theme.getSize("configuration_selector_mode_tabs").height + boundsBehavior: Flickable.StopAtBounds + + anchors + { + left: parent.left + right: parent.right + top: parent.top + margins: UM.Theme.getSize("thick_margin").width + } + + ExclusiveGroup { id: extruderMenuGroup } + + orientation: ListView.Horizontal + + model: extrudersModel + + Connections + { + target: Cura.MachineManager + onGlobalContainerChanged: forceActiveFocus() // Changing focus applies the currently-being-typed values so it can change the displayed setting values. + } + + delegate: Button + { + height: parent.height + width: Math.round(ListView.view.width / extrudersModel.rowCount()) + + text: model.name + tooltip: model.name + exclusiveGroup: extruderMenuGroup + checked: Cura.ExtruderManager.activeExtruderIndex == index + + property bool extruder_enabled: true + + MouseArea // TODO; This really should be fixed. It makes absolutely no sense to have a button AND a mouse area. + { + anchors.fill: parent + acceptedButtons: Qt.LeftButton | Qt.RightButton + onClicked: + { + switch (mouse.button) + { + case Qt.LeftButton: + extruder_enabled = Cura.MachineManager.getExtruder(model.index).isEnabled + if (extruder_enabled) + { + forceActiveFocus() // Changing focus applies the currently-being-typed values so it can change the displayed setting values. + Cura.ExtruderManager.setActiveExtruderIndex(index) + } + break + case Qt.RightButton: + extruder_enabled = Cura.MachineManager.getExtruder(model.index).isEnabled + extruderMenu.popup() + break + } + } + } + + Menu + { + id: extruderMenu + + MenuItem + { + text: catalog.i18nc("@action:inmenu", "Enable Extruder") + onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, true) + visible: !extruder_enabled // using an intermediate variable prevents an empty popup that occured now and then + } + + MenuItem + { + text: catalog.i18nc("@action:inmenu", "Disable Extruder") + onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, false) + visible: extruder_enabled + enabled: Cura.MachineManager.numberExtrudersEnabled > 1 + } + } + + style: ButtonStyle + { + background: Rectangle + { + anchors.fill: parent + border.width: control.checked ? UM.Theme.getSize("default_lining").width * 2 : UM.Theme.getSize("default_lining").width + border.color: + { + if (Cura.MachineManager.getExtruder(index).isEnabled) + { + if(control.checked || control.pressed) + { + return UM.Theme.getColor("action_button_active_border") + } + else if (control.hovered) + { + return UM.Theme.getColor("action_button_hovered_border") + } + return UM.Theme.getColor("action_button_border") + } + return UM.Theme.getColor("action_button_disabled_border") + } + color: + { + if (Cura.MachineManager.getExtruder(index).isEnabled) + { + if(control.checked || control.pressed) + { + return UM.Theme.getColor("action_button_active"); + } + else if (control.hovered) + { + return UM.Theme.getColor("action_button_hovered") + } + return UM.Theme.getColor("action_button") + } + return UM.Theme.getColor("action_button_disabled") + } + Behavior on color { ColorAnimation { duration: 50; } } + + Item + { + id: extruderButtonFace + anchors.centerIn: parent + width: childrenRect.width + + Label + { + // Static text that holds the "Extruder" label + id: extruderStaticText + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + + color: + { + if (Cura.MachineManager.getExtruder(index).isEnabled) + { + if(control.checked || control.pressed) + { + return UM.Theme.getColor("action_button_active_text"); + } + else if (control.hovered) + { + return UM.Theme.getColor("action_button_hovered_text") + } + return UM.Theme.getColor("action_button_text") + } + return UM.Theme.getColor("action_button_disabled_text") + } + + font: UM.Theme.getFont("large_nonbold") + text: catalog.i18nc("@label", "Extruder") + visible: width < (control.width - extruderIcon.width - UM.Theme.getSize("default_margin").width) + elide: Text.ElideRight + } + + ExtruderIcon + { + // Round icon with the extruder number and material color indicator. + id: extruderIcon + + anchors.verticalCenter: parent.verticalCenter + anchors.left: extruderStaticText.right + anchors.leftMargin: UM.Theme.getSize("default_margin").width + width: control.height - Math.round(UM.Theme.getSize("default_margin").width / 2) + height: width + + checked: control.checked + materialColor: model.color + textColor: extruderStaticText.color + } + } + } + + label: Item {} + } + } + } + + Item + { + id: materialRow + height: UM.Theme.getSize("print_setup_item").height + visible: Cura.MachineManager.hasMaterials + + anchors + { + left: parent.left + right: parent.right + top: extrudersList.bottom + margins: UM.Theme.getSize("thick_margin").width + } + + Label + { + id: materialLabel + text: catalog.i18nc("@label", "Material"); + width: Math.round(parent.width * 0.45 - UM.Theme.getSize("default_margin").width) + height: parent.height + verticalAlignment: Text.AlignVCenter + font: UM.Theme.getFont("default"); + color: UM.Theme.getColor("text"); + } + + ToolButton + { + id: materialSelection + + property var activeExtruder: Cura.MachineManager.activeStack + property var hasActiveExtruder: activeExtruder != null + property var currentRootMaterialName: hasActiveExtruder ? activeExtruder.material.name : "" + + text: currentRootMaterialName + tooltip: currentRootMaterialName + visible: Cura.MachineManager.hasMaterials + + enabled: !extrudersList.visible || Cura.ExtruderManager.activeExtruderIndex > -1 + + height: UM.Theme.getSize("setting_control").height + width: Math.round(parent.width * 0.7) + UM.Theme.getSize("thick_margin").width + anchors.right: parent.right + style: UM.Theme.styles.sidebar_header_button + activeFocusOnPress: true; + menu: Cura.MaterialMenu + { + extruderIndex: Cura.ExtruderManager.activeExtruderIndex + } + + property var valueError: hasActiveExtruder ? Cura.ContainerManager.getContainerMetaDataEntry(activeExtruder.material.id, "compatible", "") != "True" : true + property var valueWarning: ! Cura.MachineManager.isActiveQualitySupported + } + } + + Item + { + id: variantRow + height: UM.Theme.getSize("print_setup_item").height + visible: Cura.MachineManager.hasVariants + + anchors + { + left: parent.left + right: parent.right + top: materialRow.bottom + margins: UM.Theme.getSize("thick_margin").width + } + + Label + { + id: variantLabel + text: Cura.MachineManager.activeDefinitionVariantsName; + width: Math.round(parent.width * 0.45 - UM.Theme.getSize("default_margin").width) + height: parent.height + verticalAlignment: Text.AlignVCenter + font: UM.Theme.getFont("default"); + color: UM.Theme.getColor("text"); + } + + ToolButton + { + id: variantSelection + text: Cura.MachineManager.activeVariantName + tooltip: Cura.MachineManager.activeVariantName; + visible: Cura.MachineManager.hasVariants + + height: UM.Theme.getSize("setting_control").height + width: Math.round(parent.width * 0.7 + UM.Theme.getSize("thick_margin").width) + anchors.right: parent.right + style: UM.Theme.styles.sidebar_header_button + activeFocusOnPress: true; + + menu: Cura.NozzleMenu { extruderIndex: Cura.ExtruderManager.activeExtruderIndex } + } + } + + Item + { + id: materialCompatibilityLink + height: UM.Theme.getSize("print_setup_item").height + + anchors.right: parent.right + anchors.top: variantRow.bottom + anchors.margins: UM.Theme.getSize("thick_margin").width + UM.RecolorImage + { + id: warningImage + + anchors.right: materialInfoLabel.left + anchors.rightMargin: UM.Theme.getSize("default_margin").width + + source: UM.Theme.getIcon("warning") + width: UM.Theme.getSize("section_icon").width + height: UM.Theme.getSize("section_icon").height + + sourceSize.width: width + sourceSize.height: height + + color: UM.Theme.getColor("material_compatibility_warning") + + visible: !Cura.MachineManager.isCurrentSetupSupported + } + + Label + { + id: materialInfoLabel + wrapMode: Text.WordWrap + text: "" + catalog.i18nc("@label", "Check compatibility") + "" + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + linkColor: UM.Theme.getColor("text_link") + + verticalAlignment: Text.AlignTop + + anchors.right: parent.right + + MouseArea + { + anchors.fill: parent + + onClicked: + { + // open the material URL with web browser + Qt.openUrlExternally("https://ultimaker.com/incoming-links/cura/material-compatibilty"); + } + } + } + } +} diff --git a/resources/qml/Dialogs/AboutDialog.qml b/resources/qml/Dialogs/AboutDialog.qml index add84614e0..25c9bbf74b 100644 --- a/resources/qml/Dialogs/AboutDialog.qml +++ b/resources/qml/Dialogs/AboutDialog.qml @@ -35,10 +35,12 @@ UM.Dialog { id: logo width: (base.minimumWidth * 0.85) | 0 - height: (width * (UM.Theme.getSize("logo").height / UM.Theme.getSize("logo").width)) | 0 + height: (width * (1/4.25)) | 0 - source: UM.Theme.getImage("logo_about") + source: UM.Theme.getImage("logo") + sourceSize.width: width + sourceSize.height: height anchors.top: parent.top anchors.topMargin: ((base.minimumWidth - width) / 2) | 0 anchors.horizontalCenter: parent.horizontalCenter diff --git a/resources/qml/Dialogs/AddMachineDialog.qml b/resources/qml/Dialogs/AddMachineDialog.qml index f00359869c..8e966c3df7 100644 --- a/resources/qml/Dialogs/AddMachineDialog.qml +++ b/resources/qml/Dialogs/AddMachineDialog.qml @@ -1,4 +1,4 @@ -// Copyright (c) 2018 Ultimaker B.V. +// Copyright (c) 2017 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 @@ -156,6 +156,7 @@ UM.Dialog anchors.rightMargin: UM.Theme.getSize("default_margin").width width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height + sourceSize.width: width sourceSize.height: width color: palette.windowText source: base.activeCategory == section ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_right") @@ -169,7 +170,7 @@ UM.Dialog if (machineList.model.getItem(machineList.currentIndex).section != section) { // Find the first machine from this section - for(var i = 0; i < machineList.model.count; i++) + for(var i = 0; i < machineList.model.rowCount(); i++) { var item = machineList.model.getItem(i); if (item.section == section) diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index e42aa7e4a1..b438f0398c 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -32,8 +32,6 @@ Item property color headerBackgroundColor: UM.Theme.getColor("action_button") property color headerHoverColor: UM.Theme.getColor("action_button_hovered") - property alias enabled: mouseArea.enabled - // Defines the alignment of the popup with respect of the headerItem, by default to the right property int popupAlignment: ExpandableComponent.PopupAlignment.AlignRight @@ -141,7 +139,9 @@ Item verticalCenter: parent.verticalCenter margins: background.padding } - visible: source != "" && base.enabled + sourceSize.width: width + sourceSize.height: height + visible: source != "" width: height height: Math.round(0.2 * base.height) color: UM.Theme.getColor("text") diff --git a/resources/qml/ExtruderIcon.qml b/resources/qml/ExtruderIcon.qml index 49ad73a32e..c1a202050b 100644 --- a/resources/qml/ExtruderIcon.qml +++ b/resources/qml/ExtruderIcon.qml @@ -22,6 +22,8 @@ Item id: mainIcon anchors.fill: parent + sourceSize.width: parent.width + sourceSize.height: parent.height source: UM.Theme.getIcon("extruder_button") color: extruderEnabled ? materialColor: "gray" } @@ -48,9 +50,7 @@ Item id: extruderNumberText anchors.centerIn: parent text: index + 1 - font: UM.Theme.getFont("very_small") - width: contentWidth - height: contentHeight + font: UM.Theme.getFont("extruder_icon") visible: extruderEnabled renderType: Text.NativeRendering horizontalAlignment: Text.AlignHCenter @@ -62,6 +62,7 @@ Item id: disabledIcon anchors.fill: parent anchors.margins: UM.Theme.getSize("thick_lining").width + sourceSize.width: width sourceSize.height: width source: UM.Theme.getIcon("cross1") visible: !extruderEnabled diff --git a/resources/qml/IconLabel.qml b/resources/qml/IconLabel.qml index f925b6eab5..0941254e7b 100644 --- a/resources/qml/IconLabel.qml +++ b/resources/qml/IconLabel.qml @@ -31,6 +31,9 @@ Item width: UM.Theme.getSize("section_icon").width height: width + sourceSize.width: width + sourceSize.height: height + color: label.color visible: source != "" } @@ -45,7 +48,7 @@ Item text: "Empty label" elide: Text.ElideRight color: UM.Theme.getColor("text") - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("very_small") renderType: Text.NativeRendering } } \ No newline at end of file diff --git a/resources/qml/IconWithText.qml b/resources/qml/IconWithText.qml index 22599b3aed..dcb3ef7851 100644 --- a/resources/qml/IconWithText.qml +++ b/resources/qml/IconWithText.qml @@ -37,6 +37,8 @@ Item width: UM.Theme.getSize("section_icon").width height: UM.Theme.getSize("section_icon").height + sourceSize.width: width + sourceSize.height: height color: "black" anchors diff --git a/resources/qml/JobSpecs.qml b/resources/qml/JobSpecs.qml index 935cb723de..45111992c1 100644 --- a/resources/qml/JobSpecs.qml +++ b/resources/qml/JobSpecs.qml @@ -60,6 +60,7 @@ Item { { width: UM.Theme.getSize("save_button_specs_icons").width; height: UM.Theme.getSize("save_button_specs_icons").height; + sourceSize.width: width; sourceSize.height: width; color: control.hovered ? UM.Theme.getColor("text_scene_hover") : UM.Theme.getColor("text_scene"); source: UM.Theme.getIcon("pencil"); @@ -123,7 +124,7 @@ Item { } height: UM.Theme.getSize("jobspecs_line").height verticalAlignment: Text.AlignVCenter - font: UM.Theme.getFont("default_bold") + font: UM.Theme.getFont("small") color: UM.Theme.getColor("text_scene") text: CuraApplication.getSceneBoundingBoxString } diff --git a/resources/qml/MainWindow/MainWindowHeader.qml b/resources/qml/MainWindow/MainWindowHeader.qml index ae1c13d9c3..34936e9b5a 100644 --- a/resources/qml/MainWindow/MainWindowHeader.qml +++ b/resources/qml/MainWindow/MainWindowHeader.qml @@ -12,13 +12,38 @@ import QtGraphicalEffects 1.0 import "../Account" -Item +Rectangle { id: base implicitHeight: UM.Theme.getSize("main_window_header").height implicitWidth: UM.Theme.getSize("main_window_header").width + LinearGradient + { + anchors.fill: parent + start: Qt.point(0, 0) + end: Qt.point(parent.width, 0) + gradient: Gradient + { + GradientStop + { + position: 0.0 + color: UM.Theme.getColor("main_window_header_background") + } + GradientStop + { + position: 0.5 + color: UM.Theme.getColor("main_window_header_background_gradient") + } + GradientStop + { + position: 1.0 + color: UM.Theme.getColor("main_window_header_background") + } + } + } + Image { id: logo @@ -29,6 +54,9 @@ Item source: UM.Theme.getImage("logo") width: UM.Theme.getSize("logo").width height: UM.Theme.getSize("logo").height + + sourceSize.width: width + sourceSize.height: height } Row diff --git a/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml deleted file mode 100644 index 68c56c7c4b..0000000000 --- a/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.7 -import QtQuick.Controls 2.0 - -import UM 1.3 as UM -import Cura 1.0 as Cura - -Item -{ - width: parent.width - height: childrenRect.height - - Label - { - id: header - text: catalog.i18nc("@header", "Configurations") - font: UM.Theme.getFont("large") - color: UM.Theme.getColor("text") - height: contentHeight - renderType: Text.NativeRendering - - anchors - { - left: parent.left - right: parent.right - } - } - - ConfigurationListView - { - anchors.top: header.bottom - anchors.topMargin: UM.Theme.getSize("default_margin").width - width: parent.width - - outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null - } -} \ No newline at end of file diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 6ac1e6a2ad..7427b5ddff 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -7,129 +7,143 @@ import QtQuick.Controls 2.0 import UM 1.2 as UM import Cura 1.0 as Cura -Button +Rectangle { id: configurationItem property var configuration: null - hoverEnabled: true + property var selected: false + signal activateConfiguration() - height: background.height + height: childrenRect.height + border.width: UM.Theme.getSize("default_lining").width + border.color: updateBorderColor() + color: selected ? UM.Theme.getColor("configuration_item_active") : UM.Theme.getColor("configuration_item") + property var textColor: selected ? UM.Theme.getColor("configuration_item_text_active") : UM.Theme.getColor("configuration_item_text") - background: Rectangle + function updateBorderColor() { - height: childrenRect.height - color: parent.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") - border.color: (parent.checked || parent.hovered) ? UM.Theme.getColor("primary") : UM.Theme.getColor("lining") - border.width: parent.checked ? UM.Theme.getSize("thick_lining").width : UM.Theme.getSize("default_lining").width - radius: UM.Theme.getSize("default_radius").width + border.color = selected ? UM.Theme.getColor("configuration_item_border_active") : UM.Theme.getColor("configuration_item_border") + } - Column + Column + { + id: contentColumn + width: parent.width + padding: UM.Theme.getSize("default_margin").width + spacing: Math.round(UM.Theme.getSize("default_margin").height / 2) + + Row { - id: contentColumn - width: parent.width - padding: UM.Theme.getSize("wide_margin").width - spacing: Math.round(UM.Theme.getSize("default_margin").height / 2) + id: extruderRow - Row + width: parent.width - 2 * parent.padding + height: childrenRect.height + + spacing: UM.Theme.getSize("default_margin").width + + Repeater { - id: extruderRow - - anchors - { - left: parent.left - leftMargin: parent.padding - right: parent.right - rightMargin: parent.padding - } + id: repeater height: childrenRect.height - - spacing: UM.Theme.getSize("default_margin").width - - Repeater + model: configuration.extruderConfigurations + delegate: PrintCoreConfiguration { - id: repeater - height: childrenRect.height - model: configuration.extruderConfigurations - delegate: PrintCoreConfiguration - { - width: Math.round(parent.width / 2) - printCoreConfiguration: modelData - } - } - } - - //Buildplate row separator - Rectangle - { - id: separator - - visible: buildplateInformation.visible - anchors - { - left: parent.left - leftMargin: parent.padding - right: parent.right - rightMargin: parent.padding - } - height: visible ? Math.round(UM.Theme.getSize("thick_lining").height / 2) : 0 - color: UM.Theme.getColor("text") - } - - Item - { - id: buildplateInformation - - anchors - { - left: parent.left - leftMargin: parent.padding - right: parent.right - rightMargin: parent.padding - } - height: childrenRect.height - visible: configuration.buildplateConfiguration != "" - - UM.RecolorImage - { - id: buildplateIcon - anchors.left: parent.left - width: UM.Theme.getSize("main_window_header_button_icon").width - height: UM.Theme.getSize("main_window_header_button_icon").height - source: UM.Theme.getIcon("buildplate") - color: UM.Theme.getColor("text") - } - - Label - { - id: buildplateLabel - anchors.left: buildplateIcon.right - anchors.verticalCenter: buildplateIcon.verticalCenter - anchors.leftMargin: Math.round(UM.Theme.getSize("default_margin").height / 2) - text: configuration.buildplateConfiguration - renderType: Text.NativeRendering - color: UM.Theme.getColor("text") + width: Math.round(parent.width / 2) + printCoreConfiguration: modelData + mainColor: textColor } } } - Connections + //Buildplate row separator + Rectangle { - target: Cura.MachineManager - onCurrentConfigurationChanged: - { - configurationItem.checked = Cura.MachineManager.matchesConfiguration(configuration) - } + id: separator + + visible: buildplateInformation.visible + width: parent.width - 2 * parent.padding + height: visible ? Math.round(UM.Theme.getSize("thick_lining").height / 2) : 0 + color: textColor } - Component.onCompleted: + Item { - configurationItem.checked = Cura.MachineManager.matchesConfiguration(configuration) + id: buildplateInformation + width: parent.width - 2 * parent.padding + height: childrenRect.height + visible: configuration.buildplateConfiguration != "" + + UM.RecolorImage { + id: buildplateIcon + anchors.left: parent.left + width: UM.Theme.getSize("main_window_header_button_icon").width + height: UM.Theme.getSize("main_window_header_button_icon").height + sourceSize.width: width + sourceSize.height: height + source: UM.Theme.getIcon("buildplate") + color: textColor + } + + Label + { + id: buildplateLabel + anchors.left: buildplateIcon.right + anchors.verticalCenter: buildplateIcon.verticalCenter + anchors.leftMargin: Math.round(UM.Theme.getSize("default_margin").height / 2) + text: configuration.buildplateConfiguration + renderType: Text.NativeRendering + color: textColor + } } } - onClicked: + MouseArea { - Cura.MachineManager.applyRemoteConfiguration(configuration) + id: mouse + anchors.fill: parent + onClicked: activateConfiguration() + cursorShape: Qt.PointingHandCursor + hoverEnabled: true + onEntered: + { + parent.border.color = UM.Theme.getColor("configuration_item_border_hover") + if (configurationItem.selected == false) + { + configurationItem.color = UM.Theme.getColor("wide_lining") + } + } + onExited: + { + updateBorderColor() + if (configurationItem.selected == false) + { + configurationItem.color = UM.Theme.getColor("configuration_item") + } + } + } + + Connections + { + target: Cura.MachineManager + onCurrentConfigurationChanged: { + configurationItem.selected = Cura.MachineManager.matchesConfiguration(configuration) + updateBorderColor() + } + } + + Component.onCompleted: + { + configurationItem.selected = Cura.MachineManager.matchesConfiguration(configuration) + updateBorderColor() + } + + onVisibleChanged: + { + if(visible) + { + // I cannot trigger function updateBorderColor() after visibility change + color = selected ? UM.Theme.getColor("configuration_item_active") : UM.Theme.getColor("configuration_item") + } } } \ No newline at end of file diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index e7936b69d2..210ff6057f 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -2,7 +2,8 @@ // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 -import QtQuick.Controls 2.3 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 import UM 1.2 as UM import Cura 1.0 as Cura @@ -11,7 +12,9 @@ Column { id: base property var outputDevice: null + property var computedHeight: container.height + configurationListHeading.height + 3 * padding height: childrenRect.height + 2 * padding + padding: UM.Theme.getSize("default_margin").width spacing: Math.round(UM.Theme.getSize("default_margin").height / 2) function forceModelUpdate() @@ -24,60 +27,60 @@ Column } } + Label + { + id: configurationListHeading + text: catalog.i18nc("@label:header configurations", "Available configurations") + font: UM.Theme.getFont("large") + width: parent.width - 2 * parent.padding + color: UM.Theme.getColor("configuration_item_text") + } + + Component + { + id: sectionHeading + Rectangle + { + height: childrenRect.height + UM.Theme.getSize("default_margin").height + Label + { + text: section + font: UM.Theme.getFont("default_bold") + color: UM.Theme.getColor("configuration_item_text") + } + } + } + ScrollView { id: container - width: parent.width - readonly property int maximumHeight: 350 * screenScaleFactor - height: Math.round(Math.min(configurationList.height, maximumHeight)) - contentHeight: configurationList.height - clip: true + width: parent.width - parent.padding + height: Math.min(configurationList.contentHeight, 350 * screenScaleFactor) - ScrollBar.vertical.policy: (configurationList.height > maximumHeight) ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff //The AsNeeded policy also hides it when the cursor is away, and we don't want that. - ScrollBar.vertical.background: Rectangle - { - implicitWidth: UM.Theme.getSize("scrollbar").width - radius: width / 2 - color: UM.Theme.getColor("scrollbar_background") - } - ScrollBar.vertical.contentItem: Rectangle - { - implicitWidth: UM.Theme.getSize("scrollbar").width - radius: width / 2 - color: UM.Theme.getColor(parent.pressed ? "scrollbar_handle_down" : parent.hovered ? "scrollbar_handle_hover" : "scrollbar_handle") - } - - ButtonGroup - { - buttons: configurationList.children - } + style: UM.Theme.styles.scrollview + __wheelAreaScrollSpeed: 75 // Scroll three lines in one scroll event ListView { id: configurationList spacing: Math.round(UM.Theme.getSize("default_margin").height / 2) - width: container.width - ((height > container.maximumHeight) ? container.ScrollBar.vertical.background.width : 0) //Make room for scroll bar if there is any. + width: container.width contentHeight: childrenRect.height - height: childrenRect.height section.property: "modelData.printerType" section.criteria: ViewSection.FullString - section.delegate: Item - { - height: printerTypeLabel.height + UM.Theme.getSize("default_margin").height - Cura.PrinterTypeLabel - { - id: printerTypeLabel - text: Cura.MachineManager.getAbbreviatedMachineName(section) - } - } + section.delegate: sectionHeading model: (outputDevice != null) ? outputDevice.uniqueConfigurations : [] - delegate: ConfigurationItem { - width: parent.width + width: parent.width - UM.Theme.getSize("default_margin").width configuration: modelData + onActivateConfiguration: + { + switchPopupState() + Cura.MachineManager.applyRemoteConfiguration(configuration) + } } } } diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml deleted file mode 100644 index 1d086acc67..0000000000 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ /dev/null @@ -1,203 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.7 -import QtQuick.Controls 2.0 -import QtQuick.Controls.Styles 1.4 - -import UM 1.2 as UM -import Cura 1.0 as Cura - - -/** - * Menu that allows you to select the configuration of the current printer, such - * as the nozzle sizes and materials in each extruder. - */ -Cura.ExpandableComponent -{ - id: base - - Cura.ExtrudersModel - { - id: extrudersModel - } - - UM.I18nCatalog - { - id: catalog - name: "cura" - } - - enum ConfigurationMethod - { - AUTO, - CUSTOM - } - - iconSource: expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") - headerItem: Item - { - // Horizontal list that shows the extruders - ListView - { - id: extrudersList - - orientation: ListView.Horizontal - anchors.fill: parent - model: extrudersModel - visible: base.enabled - - delegate: Item - { - height: parent.height - width: Math.round(ListView.view.width / extrudersModel.count) - - // Extruder icon. Shows extruder index and has the same color as the active material. - Cura.ExtruderIcon - { - id: extruderIcon - materialColor: model.color - extruderEnabled: model.enabled - height: parent.height - width: height - } - - // Label for the brand of the material - Label - { - id: brandNameLabel - - text: model.material_brand - elide: Text.ElideRight - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text_inactive") - renderType: Text.NativeRendering - - anchors - { - left: extruderIcon.right - leftMargin: UM.Theme.getSize("default_margin").width - right: parent.right - rightMargin: UM.Theme.getSize("default_margin").width - } - } - - // Label that shows the name of the material - Label - { - text: model.material - elide: Text.ElideRight - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - renderType: Text.NativeRendering - - anchors - { - left: extruderIcon.right - leftMargin: UM.Theme.getSize("default_margin").width - right: parent.right - rightMargin: UM.Theme.getSize("default_margin").width - top: brandNameLabel.bottom - } - } - } - } - } - - //Disable the menu if there are no materials, variants or build plates to change. - function updateEnabled() - { - var active_definition_id = Cura.MachineManager.activeMachine.definition.id; - var has_materials = Cura.ContainerManager.getContainerMetaDataEntry(active_definition_id, "has_materials"); - var has_variants = Cura.ContainerManager.getContainerMetaDataEntry(active_definition_id, "has_variants"); - var has_buildplates = Cura.ContainerManager.getContainerMetaDataEntry(active_definition_id, "has_variant_buildplates"); - base.enabled = has_materials || has_variants || has_buildplates; //Only let it drop down if there is any configuration that you could change. - } - - Connections - { - target: Cura.MachineManager - onGlobalContainerChanged: base.updateEnabled(); - } - Component.onCompleted: updateEnabled(); - - popupItem: Column - { - id: popupItem - width: base.width - 2 * UM.Theme.getSize("default_margin").width - height: implicitHeight //Required because ExpandableComponent will try to use this to determine the size of the background of the pop-up. - spacing: UM.Theme.getSize("default_margin").height - - property bool is_connected: false //If current machine is connected to a printer. Only evaluated upon making popup visible. - onVisibleChanged: - { - is_connected = Cura.MachineManager.activeMachineNetworkKey !== "" && Cura.MachineManager.printerConnected //Re-evaluate. - } - - property int configuration_method: is_connected ? ConfigurationMenu.ConfigurationMethod.AUTO : ConfigurationMenu.ConfigurationMethod.CUSTOM //Auto if connected to a printer at start-up, or Custom if not. - - Item - { - width: parent.width - height: childrenRect.height - AutoConfiguration - { - id: autoConfiguration - visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.AUTO - } - - CustomConfiguration - { - id: customConfiguration - visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.CUSTOM - } - } - - Rectangle - { - id: separator - visible: buttonBar.visible - x: -popupPadding - - width: base.width - height: UM.Theme.getSize("default_lining").height - - color: UM.Theme.getColor("lining") - } - - //Allow switching between custom and auto. - Item - { - id: buttonBar - visible: popupItem.is_connected //Switching only makes sense if the "auto" part is possible. - - width: parent.width - height: childrenRect.height - - Cura.SecondaryButton - { - id: goToCustom - visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.AUTO - text: catalog.i18nc("@label", "Custom") - - anchors.right: parent.right - - iconSource: UM.Theme.getIcon("arrow_right") - isIconOnRightSide: true - - onClicked: popupItem.configuration_method = ConfigurationMenu.ConfigurationMethod.CUSTOM - } - - Cura.SecondaryButton - { - id: goToAuto - visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.CUSTOM - text: catalog.i18nc("@label", "Configurations") - - iconSource: UM.Theme.getIcon("arrow_left") - - onClicked: popupItem.configuration_method = ConfigurationMenu.ConfigurationMethod.AUTO - } - } - } -} diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml deleted file mode 100644 index 8d8f84155a..0000000000 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ /dev/null @@ -1,250 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.6 -import QtQuick.Controls 2.0 -import QtQuick.Controls 1.1 as OldControls - -import Cura 1.0 as Cura -import UM 1.3 as UM - -Item -{ - UM.I18nCatalog - { - id: catalog - name: "cura" - } - - width: parent.width - height: childrenRect.height - - Label - { - id: header - text: catalog.i18nc("@header", "Custom") - font: UM.Theme.getFont("large") - color: UM.Theme.getColor("text") - height: contentHeight - renderType: Text.NativeRendering - - anchors - { - top: parent.top - left: parent.left - right: parent.right - } - } - - UM.TabRow - { - id: tabBar - anchors.top: header.bottom - anchors.topMargin: UM.Theme.getSize("default_margin").height - visible: extrudersModel.count > 1 - - Repeater - { - id: repeater - model: extrudersModel - delegate: UM.TabRowButton - { - contentItem: Item - { - Cura.ExtruderIcon - { - anchors.horizontalCenter: parent.horizontalCenter - materialColor: model.color - extruderEnabled: model.enabled - width: parent.height - height: parent.height - } - } - onClicked: - { - Cura.ExtruderManager.setActiveExtruderIndex(tabBar.currentIndex) - } - } - } - - //When active extruder changes for some other reason, switch tabs. - //Don't directly link currentIndex to Cura.ExtruderManager.activeExtruderIndex! - //This causes a segfault in Qt 5.11. Something with VisualItemModel removing index -1. We have to use setCurrentIndex instead. - Connections - { - target: Cura.ExtruderManager - onActiveExtruderChanged: - { - tabBar.setCurrentIndex(Cura.ExtruderManager.activeExtruderIndex); - } - } - - //When the model of the extruders is rebuilt, the list of extruders is briefly emptied and rebuilt. - //This causes the currentIndex of the tab to be in an invalid position which resets it to 0. - //Therefore we need to change it back to what it was: The active extruder index. - Connections - { - target: repeater.model - onModelChanged: - { - tabBar.setCurrentIndex(Cura.ExtruderManager.activeExtruderIndex) - } - } - } - - Rectangle - { - width: parent.width - height: childrenRect.height - anchors.top: tabBar.bottom - - radius: tabBar.visible ? UM.Theme.getSize("default_radius").width : 0 - border.width: tabBar.visible ? UM.Theme.getSize("default_lining").width : 0 - border.color: UM.Theme.getColor("lining") - color: UM.Theme.getColor("main_background") - - //Remove rounding and lining at the top. - Rectangle - { - width: parent.width - height: parent.radius - anchors.top: parent.top - color: UM.Theme.getColor("lining") - visible: tabBar.visible - Rectangle - { - anchors - { - left: parent.left - leftMargin: parent.parent.border.width - right: parent.right - rightMargin: parent.parent.border.width - top: parent.top - } - height: parent.parent.radius - color: parent.parent.color - } - } - - Column - { - id: selectors - padding: UM.Theme.getSize("default_margin").width - spacing: UM.Theme.getSize("default_margin").height - - property var model: extrudersModel.items[tabBar.currentIndex] - - readonly property real paddedWidth: parent.width - padding * 2 - property real textWidth: Math.round(paddedWidth * 0.3) - property real controlWidth: paddedWidth - textWidth - - Row - { - height: UM.Theme.getSize("print_setup_item").height - - Label - { - text: catalog.i18nc("@label", "Enabled") - verticalAlignment: Text.AlignVCenter - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - height: parent.height - width: selectors.textWidth - visible: extrudersModel.count > 1 - renderType: Text.NativeRendering - } - - OldControls.CheckBox - { - checked: Cura.MachineManager.activeStack != null ? Cura.MachineManager.activeStack.isEnabled : false - enabled: !checked || Cura.MachineManager.numberExtrudersEnabled > 1 //Disable if it's the last enabled extruder. - height: UM.Theme.getSize("setting_control").height - style: UM.Theme.styles.checkbox - visible: extrudersModel.count > 1 - - /* Use a MouseArea to process the click on this checkbox. - This is necessary because actually clicking the checkbox - causes the "checked" property to be overwritten. After - it's been overwritten, the original link that made it - depend on the active extruder stack is broken. */ - MouseArea - { - anchors.fill: parent - onClicked: Cura.MachineManager.setExtruderEnabled(Cura.ExtruderManager.activeExtruderIndex, !parent.checked) - enabled: parent.enabled - } - } - } - - Row - { - height: UM.Theme.getSize("print_setup_item").height - Label - { - text: catalog.i18nc("@label", "Material") - verticalAlignment: Text.AlignVCenter - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - height: parent.height - width: selectors.textWidth - visible: materialSelection.visible - renderType: Text.NativeRendering - } - - OldControls.ToolButton - { - id: materialSelection - - property bool valueError: Cura.MachineManager.activeStack != null ? Cura.ContainerManager.getContainerMetaDataEntry(Cura.MachineManager.activeStack.material.id, "compatible", "") != "True" : true - property bool valueWarning: !Cura.MachineManager.isActiveQualitySupported - - text: Cura.MachineManager.activeStack != null ? Cura.MachineManager.activeStack.material.name : "" - tooltip: text - visible: Cura.MachineManager.hasMaterials - - height: UM.Theme.getSize("setting_control").height - width: selectors.controlWidth - - style: UM.Theme.styles.sidebar_header_button - activeFocusOnPress: true - menu: Cura.MaterialMenu - { - extruderIndex: Cura.ExtruderManager.activeExtruderIndex - } - } - } - - Row - { - height: UM.Theme.getSize("print_setup_item").height - - Label - { - text: Cura.MachineManager.activeDefinitionVariantsName - verticalAlignment: Text.AlignVCenter - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - height: parent.height - width: selectors.textWidth - visible: variantSelection.visible - renderType: Text.NativeRendering - } - - OldControls.ToolButton - { - id: variantSelection - text: Cura.MachineManager.activeVariantName - tooltip: Cura.MachineManager.activeVariantName; - visible: Cura.MachineManager.hasVariants - - height: UM.Theme.getSize("setting_control").height - width: selectors.controlWidth - style: UM.Theme.styles.sidebar_header_button - activeFocusOnPress: true; - - menu: Cura.NozzleMenu { extruderIndex: Cura.ExtruderManager.activeExtruderIndex } - } - } - } - } -} diff --git a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml index 885f02d740..73fc342d66 100644 --- a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml @@ -5,50 +5,87 @@ import QtQuick 2.7 import QtQuick.Controls 2.0 import UM 1.2 as UM -import Cura 1.0 as Cura -Row + +Column { id: extruderInfo property var printCoreConfiguration + property var mainColor: "black" + spacing: Math.round(UM.Theme.getSize("default_margin").height / 2) - height: information.height - spacing: UM.Theme.getSize("default_margin").width + height: childrenRect.height - //Extruder icon. - Cura.ExtruderIcon + Item { - materialColor: printCoreConfiguration.material.color - anchors.verticalCenter: parent.verticalCenter - extruderEnabled: printCoreConfiguration.material.name !== "" && printCoreConfiguration.hotendID !== "" + id: extruder + width: parent.width + height: childrenRect.height + + Label + { + id: extruderLabel + text: catalog.i18nc("@label:extruder label", "Extruder") + renderType: Text.NativeRendering + elide: Text.ElideRight + anchors.left: parent.left + font: UM.Theme.getFont("default") + color: mainColor + } + + // Rounded item to show the extruder number + Item + { + id: extruderIconItem + anchors.verticalCenter: extruderLabel.verticalCenter + anchors.left: extruderLabel.right + anchors.leftMargin: Math.round(UM.Theme.getSize("default_margin").width / 2) + + width: UM.Theme.getSize("section_icon").width + height: UM.Theme.getSize("section_icon").height + + UM.RecolorImage { + id: mainCircle + anchors.fill: parent + + anchors.centerIn: parent + sourceSize.width: parent.width + sourceSize.height: parent.height + source: UM.Theme.getIcon("extruder_button") + color: mainColor + } + + Label + { + id: extruderNumberText + anchors.centerIn: parent + text: printCoreConfiguration.position + 1 + renderType: Text.NativeRendering + font: UM.Theme.getFont("default") + color: mainColor + } + } } - Column + Label { - id: information - Label - { - text: printCoreConfiguration.material.brand ? printCoreConfiguration.material.brand : " " //Use space so that the height is still correct. - renderType: Text.NativeRendering - elide: Text.ElideRight - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text_inactive") - } - Label - { - text: printCoreConfiguration.material.name ? printCoreConfiguration.material.name : " " //Use space so that the height is still correct. - renderType: Text.NativeRendering - elide: Text.ElideRight - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - } - Label - { - text: printCoreConfiguration.hotendID ? printCoreConfiguration.hotendID : " " //Use space so that the height is still correct. - renderType: Text.NativeRendering - elide: Text.ElideRight - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text_inactive") - } + id: materialLabel + text: printCoreConfiguration.material == null ? "" : printCoreConfiguration.material.name + renderType: Text.NativeRendering + elide: Text.ElideRight + width: parent.width + font: UM.Theme.getFont("default_bold") + color: mainColor + } + + Label + { + id: printCoreTypeLabel + text: printCoreConfiguration.hotendID + renderType: Text.NativeRendering + elide: Text.ElideRight + width: parent.width + font: UM.Theme.getFont("default") + color: mainColor } } diff --git a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml new file mode 100644 index 0000000000..eb6800cb36 --- /dev/null +++ b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml @@ -0,0 +1,243 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.0 +import QtQuick.Controls.Styles 1.4 +import QtQuick.Layouts 1.3 + +import QtQuick.Controls 1.1 as OldControls + +import UM 1.2 as UM +import Cura 1.0 as Cura + + +Cura.ExpandableComponent +{ + id: base + + Cura.ExtrudersModel + { + id: extrudersModel + } + + UM.I18nCatalog + { + id: catalog + name: "cura" + } + + iconSource: expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") + headerItem: Item + { + // Horizontal list that shows the extruders + ListView + { + id: extrudersList + + orientation: ListView.Horizontal + anchors.fill: parent + model: extrudersModel + + delegate: Item + { + height: parent.height + width: Math.round(ListView.view.width / extrudersModel.rowCount()) + + // Extruder icon. Shows extruder index and has the same color as the active material. + Cura.ExtruderIcon + { + id: extruderIcon + materialColor: model.color + extruderEnabled: model.enabled + anchors.verticalCenter: parent.verticalCenter + } + + // Label for the brand of the material + Label + { + id: brandNameLabel + + text: model.material_brand + elide: Text.ElideRight + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + + anchors + { + left: extruderIcon.right + leftMargin: UM.Theme.getSize("default_margin").width + right: parent.right + rightMargin: UM.Theme.getSize("default_margin").width + } + } + + // Label that shows the name of the material + Label + { + text: model.material + elide: Text.ElideRight + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + + anchors + { + left: extruderIcon.right + leftMargin: UM.Theme.getSize("default_margin").width + right: parent.right + rightMargin: UM.Theme.getSize("default_margin").width + top: brandNameLabel.bottom + } + } + } + } + } + + popupItem: Item + { + width: base.width - 2 * UM.Theme.getSize("default_margin").width + height: 200 + + TabBar + { + id: tabBar + onCurrentIndexChanged: Cura.ExtruderManager.setActiveExtruderIndex(currentIndex) + width: parent.width + height: 50 + Repeater + { + model: extrudersModel + + delegate: TabButton + { + width: ListView.view != null ? Math.round(ListView.view.width / extrudersModel.rowCount()): 0 + height: parent.height + contentItem: Item + { + Cura.ExtruderIcon + { + anchors.horizontalCenter: parent.horizontalCenter + materialColor: model.color + extruderEnabled: model.enabled + width: parent.height + height: parent.height + } + } + } + } + } + + Item + { + id: tabControl + width: parent.width + anchors.top: tabBar.bottom + anchors.bottom: parent.bottom + property var model: extrudersModel.items[tabBar.currentIndex] + property real textWidth: Math.round(width * 0.3) + property real controlWidth: width - textWidth + Column + { + spacing: UM.Theme.getSize("default_margin").height + Row + { + height: UM.Theme.getSize("print_setup_item").height + + Label + { + text: catalog.i18nc("@label", "Enabled") + verticalAlignment: Text.AlignVCenter + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + height: parent.height + width: tabControl.textWidth + renderType: Text.NativeRendering + } + + OldControls.CheckBox + { + checked: tabControl.model != null ? Cura.MachineManager.getExtruder(tabControl.model.index).isEnabled: false + onClicked: Cura.MachineManager.setExtruderEnabled(tabControl.model.index, checked) + height: UM.Theme.getSize("setting_control").height + style: UM.Theme.styles.checkbox + } + } + + Row + { + height: UM.Theme.getSize("print_setup_item").height + Label + { + text: catalog.i18nc("@label", "Material") + verticalAlignment: Text.AlignVCenter + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + height: parent.height + width: tabControl.textWidth + renderType: Text.NativeRendering + } + + OldControls.ToolButton + { + id: materialSelection + + property var activeExtruder: Cura.MachineManager.activeStack + property var hasActiveExtruder: activeExtruder != null + property var currentRootMaterialName: hasActiveExtruder ? activeExtruder.material.name : "" + property var valueError: hasActiveExtruder ? Cura.ContainerManager.getContainerMetaDataEntry(activeExtruder.material.id, "compatible", "") != "True" : true + property var valueWarning: ! Cura.MachineManager.isActiveQualitySupported + + text: currentRootMaterialName + tooltip: currentRootMaterialName + visible: Cura.MachineManager.hasMaterials + + enabled: Cura.ExtruderManager.activeExtruderIndex > -1 + + height: UM.Theme.getSize("setting_control").height + width: tabControl.controlWidth + + style: UM.Theme.styles.sidebar_header_button + activeFocusOnPress: true + menu: Cura.MaterialMenu + { + extruderIndex: Cura.ExtruderManager.activeExtruderIndex + } + + } + } + + Row + { + height: UM.Theme.getSize("print_setup_item").height + + Label + { + text: Cura.MachineManager.activeDefinitionVariantsName + verticalAlignment: Text.AlignVCenter + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + height: parent.height + width: tabControl.textWidth + renderType: Text.NativeRendering + } + + OldControls.ToolButton + { + id: variantSelection + text: Cura.MachineManager.activeVariantName + tooltip: Cura.MachineManager.activeVariantName; + visible: Cura.MachineManager.hasVariants + + height: UM.Theme.getSize("setting_control").height + width: tabControl.controlWidth + style: UM.Theme.styles.sidebar_header_button + activeFocusOnPress: true; + + menu: Cura.NozzleMenu { extruderIndex: Cura.ExtruderManager.activeExtruderIndex } + } + } + } + + } + } +} diff --git a/resources/qml/Menus/ConfigurationMenu/SyncButton.qml b/resources/qml/Menus/ConfigurationMenu/SyncButton.qml new file mode 100644 index 0000000000..558ae1e477 --- /dev/null +++ b/resources/qml/Menus/ConfigurationMenu/SyncButton.qml @@ -0,0 +1,102 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +Button +{ + id: base + property var outputDevice: null + property var matched: updateOnSync() + text: matched == true ? catalog.i18nc("@label:extruder label", "Yes") : catalog.i18nc("@label:extruder label", "No") + width: parent.width + height: parent.height + + function updateOnSync() + { + if (outputDevice != undefined) + { + for (var index in outputDevice.uniqueConfigurations) + { + var configuration = outputDevice.uniqueConfigurations[index] + if (Cura.MachineManager.matchesConfiguration(configuration)) + { + base.matched = true; + return; + } + } + } + base.matched = false; + } + + style: ButtonStyle + { + background: Rectangle + { + color: + { + if(control.pressed) + { + return UM.Theme.getColor("machine_selector_active"); + } + else if(control.hovered) + { + return UM.Theme.getColor("machine_selector_hover"); + } + else + { + return UM.Theme.getColor("machine_selector_bar"); + } + } + Behavior on color { ColorAnimation { duration: 50; } } + + UM.RecolorImage + { + id: downArrow + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: UM.Theme.getSize("default_margin").width + width: UM.Theme.getSize("standard_arrow").width + height: UM.Theme.getSize("standard_arrow").height + sourceSize.width: width + sourceSize.height: height + color: UM.Theme.getColor("text_emphasis") + source: UM.Theme.getIcon("arrow_bottom") + } + UM.RecolorImage + { + id: sidebarComboBoxLabel + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("default_margin").width + anchors.verticalCenter: parent.verticalCenter; + + width: UM.Theme.getSize("printer_sync_icon").width + height: UM.Theme.getSize("printer_sync_icon").height + + color: control.matched ? UM.Theme.getColor("printer_config_matched") : UM.Theme.getColor("printer_config_mismatch") + source: UM.Theme.getIcon("tab_status_connected") + sourceSize.width: width + sourceSize.height: height + } + } + label: Label {} + } + + Connections + { + target: outputDevice + onUniqueConfigurationsChanged: updateOnSync() + } + + Connections + { + target: Cura.MachineManager + onCurrentConfigurationChanged: updateOnSync() + onOutputDevicesChanged: updateOnSync() + } +} \ No newline at end of file diff --git a/resources/qml/Menus/ProfileMenu.qml b/resources/qml/Menus/ProfileMenu.qml index bf950aa409..fd46d2ef72 100644 --- a/resources/qml/Menus/ProfileMenu.qml +++ b/resources/qml/Menus/ProfileMenu.qml @@ -37,7 +37,7 @@ Menu MenuSeparator { id: customSeparator - visible: Cura.CustomQualityProfilesDropDownMenuModel.count > 0 + visible: Cura.CustomQualityProfilesDropDownMenuModel.rowCount > 0 } Instantiator @@ -48,7 +48,7 @@ Menu Connections { target: Cura.CustomQualityProfilesDropDownMenuModel - onModelReset: customSeparator.visible = Cura.CustomQualityProfilesDropDownMenuModel.count > 0 + onModelReset: customSeparator.visible = Cura.CustomQualityProfilesDropDownMenuModel.rowCount() > 0 } MenuItem @@ -62,12 +62,12 @@ Menu onObjectAdded: { - customSeparator.visible = model.count > 0; + customSeparator.visible = model.rowCount() > 0; menu.insertItem(index, object); } onObjectRemoved: { - customSeparator.visible = model.count > 0; + customSeparator.visible = model.rowCount() > 0; menu.removeItem(object); } } diff --git a/resources/qml/ObjectsList.qml b/resources/qml/ObjectsList.qml index 8f45b3744f..8c8eaa16ae 100644 --- a/resources/qml/ObjectsList.qml +++ b/resources/qml/ObjectsList.qml @@ -1,4 +1,4 @@ -// Copyright (c) 2018 Ultimaker B.V. +// Copyright (c) 2017 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 @@ -55,6 +55,7 @@ Rectangle { width: control.width height: control.height + sourceSize.width: width sourceSize.height: width color: UM.Theme.getColor("setting_control_text") source: collapsed ? UM.Theme.getIcon("arrow_left") : UM.Theme.getIcon("arrow_bottom") diff --git a/resources/qml/Preferences/MachinesPage.qml b/resources/qml/Preferences/MachinesPage.qml index bc75b9bc72..4dc5465dc6 100644 --- a/resources/qml/Preferences/MachinesPage.qml +++ b/resources/qml/Preferences/MachinesPage.qml @@ -21,10 +21,8 @@ UM.ManagementPage function activeMachineIndex() { - for(var i = 0; i < model.count; i++) - { - if (model.getItem(i).id == Cura.MachineManager.activeMachineId) - { + for(var i = 0; i < model.rowCount(); i++) { + if (model.getItem(i).id == Cura.MachineManager.activeMachineId) { return i; } } @@ -49,7 +47,7 @@ UM.ManagementPage { text: catalog.i18nc("@action:button", "Remove"); iconName: "list-remove"; - enabled: base.currentItem != null && model.count > 1 + enabled: base.currentItem != null && model.rowCount() > 1 onClicked: confirmDialog.open(); }, Button diff --git a/resources/qml/Preferences/Materials/MaterialsBrandSection.qml b/resources/qml/Preferences/Materials/MaterialsBrandSection.qml index a3a0e4708f..c8f391dfb0 100644 --- a/resources/qml/Preferences/Materials/MaterialsBrandSection.qml +++ b/resources/qml/Preferences/Materials/MaterialsBrandSection.qml @@ -55,8 +55,7 @@ Rectangle text: "" implicitWidth: UM.Theme.getSize("favorites_button").width implicitHeight: UM.Theme.getSize("favorites_button").height - UM.RecolorImage - { + UM.RecolorImage { anchors { verticalCenter: parent.verticalCenter @@ -64,6 +63,8 @@ Rectangle } width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height + sourceSize.width: width + sourceSize.height: height color: "black" source: brand_section.expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") } diff --git a/resources/qml/Preferences/Materials/MaterialsList.qml b/resources/qml/Preferences/Materials/MaterialsList.qml index 61f92db84c..00bead9650 100644 --- a/resources/qml/Preferences/Materials/MaterialsList.qml +++ b/resources/qml/Preferences/Materials/MaterialsList.qml @@ -57,7 +57,7 @@ Item var currentItemId = base.currentItem == null ? "" : base.currentItem.root_material_id search_root_id = currentItemId } - for (var material_idx = 0; material_idx < genericMaterialsModel.count; material_idx++) + for (var material_idx = 0; material_idx < genericMaterialsModel.rowCount(); material_idx++) { var material = genericMaterialsModel.getItem(material_idx) if (material.root_material_id == search_root_id) @@ -72,15 +72,15 @@ Item return true } } - for (var brand_idx = 0; brand_idx < materialsModel.count; brand_idx++) + for (var brand_idx = 0; brand_idx < materialsModel.rowCount(); brand_idx++) { var brand = materialsModel.getItem(brand_idx) var types_model = brand.material_types - for (var type_idx = 0; type_idx < types_model.count; type_idx++) + for (var type_idx = 0; type_idx < types_model.rowCount(); type_idx++) { var type = types_model.getItem(type_idx) var colors_model = type.colors - for (var material_idx = 0; material_idx < colors_model.count; material_idx++) + for (var material_idx = 0; material_idx < colors_model.rowCount(); material_idx++) { var material = colors_model.getItem(material_idx) if (material.root_material_id == search_root_id) diff --git a/resources/qml/Preferences/Materials/MaterialsSlot.qml b/resources/qml/Preferences/Materials/MaterialsSlot.qml index a706aaf2b9..a5af17f47a 100644 --- a/resources/qml/Preferences/Materials/MaterialsSlot.qml +++ b/resources/qml/Preferences/Materials/MaterialsSlot.qml @@ -95,6 +95,8 @@ Rectangle } width: UM.Theme.getSize("favorites_button_icon").width height: UM.Theme.getSize("favorites_button_icon").height + sourceSize.width: width + sourceSize.height: height color: { if (favorite_button.hovered) diff --git a/resources/qml/Preferences/Materials/MaterialsTypeSection.qml b/resources/qml/Preferences/Materials/MaterialsTypeSection.qml index f98c19e0b3..f62fc4ee16 100644 --- a/resources/qml/Preferences/Materials/MaterialsTypeSection.qml +++ b/resources/qml/Preferences/Materials/MaterialsTypeSection.qml @@ -74,6 +74,8 @@ Rectangle } width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height + sourceSize.width: width + sourceSize.height: height color: "black" source: material_type_section.expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") } diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index d7ffbb3152..ba0c2848a5 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -188,27 +188,21 @@ Item Connections { target: qualitiesModel - onItemsChanged: - { + onItemsChanged: { var toSelectItemName = base.currentItem == null ? "" : base.currentItem.name; - if (newQualityNameToSelect != "") - { + if (newQualityNameToSelect != "") { toSelectItemName = newQualityNameToSelect; } var newIdx = -1; // Default to nothing if nothing can be found - if (toSelectItemName != "") - { + if (toSelectItemName != "") { // Select the required quality name if given - for (var idx = 0; idx < qualitiesModel.count; ++idx) - { + for (var idx = 0; idx < qualitiesModel.rowCount(); ++idx) { var item = qualitiesModel.getItem(idx); - if (item.name == toSelectItemName) - { + if (item.name == toSelectItemName) { // Switch to the newly created profile if needed newIdx = idx; - if (base.toActivateNewQuality) - { + if (base.toActivateNewQuality) { // Activate this custom quality if required Cura.MachineManager.setQualityChangesGroup(item.quality_changes_group); } @@ -388,11 +382,9 @@ Item var selectedItemName = Cura.MachineManager.activeQualityOrQualityChangesName; // Select the required quality name if given - for (var idx = 0; idx < qualitiesModel.count; idx++) - { + for (var idx = 0; idx < qualitiesModel.rowCount(); idx++) { var item = qualitiesModel.getItem(idx); - if (item.name == selectedItemName) - { + if (item.name == selectedItemName) { currentIndex = idx; break; } diff --git a/resources/qml/Preferences/SettingVisibilityPage.qml b/resources/qml/Preferences/SettingVisibilityPage.qml index 3f7571a170..2edbeee960 100644 --- a/resources/qml/Preferences/SettingVisibilityPage.qml +++ b/resources/qml/Preferences/SettingVisibilityPage.qml @@ -50,7 +50,7 @@ UM.PreferencesPage { return Qt.Unchecked } - else if(definitionsModel.visibleCount == definitionsModel.count) + else if(definitionsModel.visibleCount == definitionsModel.rowCount(null)) { return Qt.Checked } diff --git a/resources/qml/PrinterOutput/ExtruderBox.qml b/resources/qml/PrinterOutput/ExtruderBox.qml index 247bb3a27d..f5a1bd75c4 100644 --- a/resources/qml/PrinterOutput/ExtruderBox.qml +++ b/resources/qml/PrinterOutput/ExtruderBox.qml @@ -47,7 +47,7 @@ Item { id: extruderTargetTemperature text: Math.round(extruderModel.targetHotendTemperature) + "°C" - font: UM.Theme.getFont("default_bold") + font: UM.Theme.getFont("small") color: UM.Theme.getColor("text_inactive") anchors.right: parent.right anchors.rightMargin: UM.Theme.getSize("default_margin").width diff --git a/resources/qml/PrinterOutput/HeatedBedBox.qml b/resources/qml/PrinterOutput/HeatedBedBox.qml index 33cf5cd1e2..8c99814e02 100644 --- a/resources/qml/PrinterOutput/HeatedBedBox.qml +++ b/resources/qml/PrinterOutput/HeatedBedBox.qml @@ -35,7 +35,7 @@ Item { id: bedTargetTemperature text: printerModel != null ? printerModel.targetBedTemperature + "°C" : "" - font: UM.Theme.getFont("default_bold") + font: UM.Theme.getFont("small") color: UM.Theme.getColor("text_inactive") anchors.right: parent.right anchors.rightMargin: UM.Theme.getSize("default_margin").width diff --git a/resources/qml/PrinterOutput/OutputDeviceHeader.qml b/resources/qml/PrinterOutput/OutputDeviceHeader.qml index 16280eab5f..e6328546ef 100644 --- a/resources/qml/PrinterOutput/OutputDeviceHeader.qml +++ b/resources/qml/PrinterOutput/OutputDeviceHeader.qml @@ -43,7 +43,7 @@ Item { id: outputDeviceAddressLabel text: (outputDevice != null && outputDevice.address != null) ? outputDevice.address : "" - font: UM.Theme.getFont("default_bold") + font: UM.Theme.getFont("small") color: UM.Theme.getColor("text_inactive") anchors.top: outputDeviceNameLabel.bottom anchors.left: parent.left @@ -54,7 +54,7 @@ Item { text: outputDevice != null ? "" : catalog.i18nc("@info:status", "The printer is not connected.") color: outputDevice != null && outputDevice.acceptsCommands ? UM.Theme.getColor("setting_control_text") : UM.Theme.getColor("setting_control_disabled_text") - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("very_small") wrapMode: Text.WordWrap anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("default_margin").width diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index 95abfd6644..15cd773c90 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -25,52 +25,29 @@ Cura.ExpandableComponent name: "cura" } - headerItem: Item + headerItem: Cura.IconLabel { - implicitHeight: icon.height + text: isNetworkPrinter ? Cura.MachineManager.activeMachineNetworkGroupName : Cura.MachineManager.activeMachineName + source: + { + if (isNetworkPrinter) + { + if (machineSelector.outputDevice != null && machineSelector.outputDevice.clusterSize > 1) + { + return UM.Theme.getIcon("printer_group") + } + return UM.Theme.getIcon("printer_single") + } + return "" + } + font: UM.Theme.getFont("medium") + color: UM.Theme.getColor("text") + iconSize: UM.Theme.getSize("machine_selector_icon").width UM.RecolorImage { id: icon - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - - source: - { - if (isNetworkPrinter) - { - if (machineSelector.outputDevice != null && machineSelector.outputDevice.clusterSize > 1) - { - return UM.Theme.getIcon("printer_group") - } - return UM.Theme.getIcon("printer_single") - } - return "" - } - width: UM.Theme.getSize("machine_selector_icon").width - height: width - - color: UM.Theme.getColor("machine_selector_printer_icon") - visible: source != "" - } - - Label - { - id: label - anchors.left: icon.visible ? icon.right : parent.left - anchors.right: parent.right - anchors.leftMargin: UM.Theme.getSize("thin_margin").width - anchors.verticalCenter: icon.verticalCenter - text: isNetworkPrinter ? Cura.MachineManager.activeMachineNetworkGroupName : Cura.MachineManager.activeMachineName - elide: Text.ElideRight - color: UM.Theme.getColor("text") - font: UM.Theme.getFont("medium") - renderType: Text.NativeRendering - } - - UM.RecolorImage - { anchors { bottom: parent.bottom @@ -82,6 +59,9 @@ Cura.ExpandableComponent width: UM.Theme.getSize("printer_status_icon").width height: UM.Theme.getSize("printer_status_icon").height + sourceSize.width: width + sourceSize.height: height + color: UM.Theme.getColor("primary") visible: isNetworkPrinter && isPrinterConnected diff --git a/resources/qml/PrinterSelector/MachineSelectorList.qml b/resources/qml/PrinterSelector/MachineSelectorList.qml index d831f4eb5c..445940ab50 100644 --- a/resources/qml/PrinterSelector/MachineSelectorList.qml +++ b/resources/qml/PrinterSelector/MachineSelectorList.qml @@ -13,7 +13,7 @@ Column Label { - text: catalog.i18nc("@label", "Connected printers") + text: catalog.i18nc("@label", "Network connected printers") visible: networkedPrintersModel.items.length > 0 leftPadding: UM.Theme.getSize("default_margin").width height: visible ? contentHeight + 2 * UM.Theme.getSize("default_margin").height : 0 diff --git a/resources/qml/PrinterTypeLabel.qml b/resources/qml/PrinterSelector/PrinterTypeLabel.qml similarity index 95% rename from resources/qml/PrinterTypeLabel.qml rename to resources/qml/PrinterSelector/PrinterTypeLabel.qml index 7feae32e16..cd9f3b9743 100644 --- a/resources/qml/PrinterTypeLabel.qml +++ b/resources/qml/PrinterSelector/PrinterTypeLabel.qml @@ -28,7 +28,7 @@ Item anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter renderType: Text.NativeRendering - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("very_small") color: UM.Theme.getColor("text") } } \ No newline at end of file diff --git a/resources/qml/Settings/SettingCategory.qml b/resources/qml/Settings/SettingCategory.qml index 196b2d6b97..aafe36c546 100644 --- a/resources/qml/Settings/SettingCategory.qml +++ b/resources/qml/Settings/SettingCategory.qml @@ -129,26 +129,23 @@ Button anchors.rightMargin: UM.Theme.getSize("default_margin").width width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height + sourceSize.width: width sourceSize.height: width color: { if (!base.enabled) { return UM.Theme.getColor("setting_category_disabled_text") - } - else if ((base.hovered || base.activeFocus) && base.checkable && base.checked) + } else if ((base.hovered || base.activeFocus) && base.checkable && base.checked) { return UM.Theme.getColor("setting_category_active_hover_text") - } - else if (base.pressed || (base.checkable && base.checked)) + } else if (base.pressed || (base.checkable && base.checked)) { return UM.Theme.getColor("setting_category_active_text") - } - else if (base.hovered || base.activeFocus) + } else if (base.hovered || base.activeFocus) { return UM.Theme.getColor("setting_category_hover_text") - } - else + } else { return UM.Theme.getColor("setting_category_text") } diff --git a/resources/qml/Settings/SettingCheckBox.qml b/resources/qml/Settings/SettingCheckBox.qml index fb2d5a2f4d..d37754d27c 100644 --- a/resources/qml/Settings/SettingCheckBox.qml +++ b/resources/qml/Settings/SettingCheckBox.qml @@ -115,12 +115,12 @@ SettingItem return UM.Theme.getColor("setting_control_border") } - UM.RecolorImage - { + UM.RecolorImage { anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter width: Math.round(parent.width / 2.5) height: Math.round(parent.height / 2.5) + sourceSize.width: width sourceSize.height: width color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text"); source: UM.Theme.getIcon("check") diff --git a/resources/qml/Settings/SettingOptionalExtruder.qml b/resources/qml/Settings/SettingOptionalExtruder.qml index 5f0d8327f8..a3c1422b30 100644 --- a/resources/qml/Settings/SettingOptionalExtruder.qml +++ b/resources/qml/Settings/SettingOptionalExtruder.qml @@ -1,5 +1,5 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. +// Copyright (c) 2016 Ultimaker B.V. +// Uranium is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 import QtQuick.Controls 2.0 @@ -31,15 +31,12 @@ SettingItem { forceActiveFocus(); propertyProvider.setPropertyValue("value", model.getItem(index).index); - } - else + } else { if (propertyProvider.properties.value == -1) { - control.currentIndex = model.count - 1; // we know the last item is "Not overriden" - } - else - { + control.currentIndex = model.rowCount() - 1; // we know the last item is "Not overriden" + } else { control.currentIndex = propertyProvider.properties.value; // revert to the old value } } diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index bb624bcbde..ef1f123953 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -1,5 +1,5 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. +// Copyright (c) 2017 Ultimaker B.V. +// Uranium is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 import QtQuick.Controls 1.1 @@ -129,14 +129,13 @@ Item } style: ButtonStyle { - background: Item - { - UM.RecolorImage - { + background: Item { + UM.RecolorImage { anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height + sourceSize.width: width sourceSize.height: width color: control.enabled ? UM.Theme.getColor("setting_category_text") : UM.Theme.getColor("setting_category_disabled_text") source: UM.Theme.getIcon("menu") diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index fb4d52979d..5e723a3d70 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -106,7 +106,7 @@ Item var availableMin = -1 var availableMax = -1 - for (var i = 0; i < Cura.QualityProfilesDropDownMenuModel.count; i++) + for (var i = 0; i < Cura.QualityProfilesDropDownMenuModel.rowCount(); i++) { var qualityItem = Cura.QualityProfilesDropDownMenuModel.getItem(i) @@ -183,7 +183,7 @@ Item qualityModel.existingQualityProfile = 0 // check, the ticks count cannot be less than zero - qualityModel.totalTicks = Math.max(0, Cura.QualityProfilesDropDownMenuModel.count - 1) + qualityModel.totalTicks = Math.max(0, Cura.QualityProfilesDropDownMenuModel.rowCount() - 1) } } @@ -731,6 +731,7 @@ Item { anchors.fill: parent anchors.margins: 2 * screenScaleFactor + sourceSize.width: width sourceSize.height: width source: UM.Theme.getIcon(model.icon) color: UM.Theme.getColor("quality_slider_unavailable") @@ -1155,7 +1156,7 @@ Item function populateExtruderModel() { extruderModel.clear(); - for(var extruderNumber = 0; extruderNumber < extruders.count; extruderNumber++) + for(var extruderNumber = 0; extruderNumber < extruders.rowCount() ; extruderNumber++) { extruderModel.append({ text: extruders.getItem(extruderNumber).name, diff --git a/resources/qml/Toolbar.qml b/resources/qml/Toolbar.qml index 1e335472d4..5fbddea9ac 100644 --- a/resources/qml/Toolbar.qml +++ b/resources/qml/Toolbar.qml @@ -62,7 +62,7 @@ Item enabled: model.enabled && UM.Selection.hasSelection && UM.Controller.toolsEnabled isTopElement: toolsModel.getItem(0).id == model.id - isBottomElement: toolsModel.getItem(toolsModel.count - 1).id == model.id + isBottomElement: toolsModel.getItem(toolsModel.rowCount() - 1).id == model.id toolItem: UM.RecolorImage { diff --git a/resources/qml/ViewsSelector.qml b/resources/qml/ViewsSelector.qml index 1e42a0b3ba..e9fdd57177 100644 --- a/resources/qml/ViewsSelector.qml +++ b/resources/qml/ViewsSelector.qml @@ -19,7 +19,7 @@ Cura.ExpandableComponent property var activeView: { - for (var i = 0; i < viewModel.count; i++) + for (var i = 0; i < viewModel.rowCount(); i++) { if (viewModel.items[i].active) { @@ -74,8 +74,6 @@ Cura.ExpandableComponent { id: viewSelectorPopup width: viewSelector.width - 2 * viewSelector.popupPadding - leftPadding: UM.Theme.getSize("default_lining").width - rightPadding: UM.Theme.getSize("default_lining").width // For some reason the height/width of the column gets set to 0 if this is not set... Component.onCompleted: @@ -93,7 +91,7 @@ Cura.ExpandableComponent { id: viewsSelectorButton text: model.name - width: parent.width - viewSelectorPopup.leftPadding - viewSelectorPopup.rightPadding + width: parent.width height: UM.Theme.getSize("action_button").height leftPadding: UM.Theme.getSize("default_margin").width rightPadding: UM.Theme.getSize("default_margin").width diff --git a/resources/qml/qmldir b/resources/qml/qmldir index 7e57119bc6..2475f398f8 100644 --- a/resources/qml/qmldir +++ b/resources/qml/qmldir @@ -1,6 +1,7 @@ module Cura MachineSelector 1.0 MachineSelector.qml +QuickConfigurationSelector 1.0 QuickConfigurationSelector.qml CustomConfigurationSelector 1.0 CustomConfigurationSelector.qml PrintSetupSelector 1.0 PrintSetupSelector.qml ActionButton 1.0 ActionButton.qml diff --git a/resources/themes/cura-dark/theme.json b/resources/themes/cura-dark/theme.json index d9ef74ebb9..34b944b25b 100644 --- a/resources/themes/cura-dark/theme.json +++ b/resources/themes/cura-dark/theme.json @@ -15,7 +15,7 @@ "primary_hover": [48, 182, 231, 255], "primary_text": [255, 255, 255, 204], "border": [127, 127, 127, 255], - "secondary": [95, 95, 95, 255], + "secondary": [241, 242, 242, 255], "main_window_header_button_text_inactive": [128, 128, 128, 255], "main_window_header_button_text_hovered": [255, 255, 255, 255], @@ -196,6 +196,14 @@ "layerview_support_interface": [64, 192, 255, 255], "layerview_nozzle": [181, 166, 66, 120], + "configuration_item": [0, 0, 0, 0], + "configuration_item_active": [12, 169, 227, 179], + "configuration_item_text": [255, 255, 255, 255], + "configuration_item_text_active": [255, 255, 255, 255], + "configuration_item_border": [255, 255, 255, 255], + "configuration_item_border_active": [12, 169, 227, 179], + "configuration_item_border_hover": [12, 169, 227, 179], + "material_compatibility_warning": [255, 255, 255, 255], "quality_slider_unavailable": [179, 179, 179, 255], diff --git a/resources/themes/cura-light/images/header_pattern.svg b/resources/themes/cura-light/images/header_pattern.svg index eff5f01cfa..2a9de2f3e9 100644 --- a/resources/themes/cura-light/images/header_pattern.svg +++ b/resources/themes/cura-light/images/header_pattern.svg @@ -1,1901 +1 @@ - - - - Desktop HD - Created with Sketch. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file +Pattern \ No newline at end of file diff --git a/resources/themes/cura-light/images/logo_about.svg b/resources/themes/cura-light/images/logo_about.svg deleted file mode 100644 index 34301fd6c9..0000000000 --- a/resources/themes/cura-light/images/logo_about.svg +++ /dev/null @@ -1,172 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index 30cf42859a..f2ad2b6f4a 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -73,6 +73,7 @@ QtObject anchors.rightMargin: Theme.getSize("default_margin").width width: Theme.getSize("standard_arrow").width height: Theme.getSize("standard_arrow").height + sourceSize.width: width sourceSize.height: width color: control.enabled ? Theme.getColor("setting_category_text") : Theme.getColor("setting_category_disabled_text") source: Theme.getIcon("arrow_bottom") @@ -145,7 +146,7 @@ QtObject text: control.text anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter - font: UM.Theme.getFont("medium") + font: UM.Theme.getFont("medium_bold") color: { if (control.checked) @@ -256,6 +257,7 @@ QtObject anchors.bottomMargin: Theme.getSize("button").height - Math.round(Theme.getSize("button_icon").height / 4) width: Theme.getSize("standard_arrow").width height: Theme.getSize("standard_arrow").height + sourceSize.width: width sourceSize.height: width visible: control.menu != null; color: @@ -527,7 +529,7 @@ QtObject implicitWidth: Theme.getSize("checkbox").width implicitHeight: Theme.getSize("checkbox").height - color: (control.hovered || control._hovered) ? Theme.getColor("checkbox_hover") : (control.enabled ? Theme.getColor("checkbox") : Theme.getColor("checkbox_disabled")) + color: (control.hovered || control._hovered) ? Theme.getColor("checkbox_hover") : Theme.getColor("checkbox") Behavior on color { ColorAnimation { duration: 50; } } radius: control.exclusiveGroup ? Math.round(Theme.getSize("checkbox").width / 2) : 0 @@ -541,6 +543,7 @@ QtObject anchors.horizontalCenter: parent.horizontalCenter width: Math.round(parent.width / 2.5) height: Math.round(parent.height / 2.5) + sourceSize.width: width sourceSize.height: width color: Theme.getColor("checkbox_mark") source: control.exclusiveGroup ? Theme.getIcon("dot") : Theme.getIcon("check") @@ -582,6 +585,7 @@ QtObject anchors.horizontalCenter: parent.horizontalCenter width: Math.round(parent.width / 2.5) height: Math.round(parent.height / 2.5) + sourceSize.width: width sourceSize.height: width color: Theme.getColor("checkbox_mark") source: @@ -832,6 +836,7 @@ QtObject anchors.horizontalCenter: parent.horizontalCenter width: Math.floor(control.width / 2) height: Math.floor(control.height / 2) + sourceSize.width: width sourceSize.height: width color: { diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 2d7e92be4d..dfad5cfd17 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -41,12 +41,12 @@ "family": "Noto Sans" }, "small": { - "size": 0.85, - "weight": 50, + "size": 1.0, + "weight": 63, "family": "Noto Sans" }, "very_small": { - "size": 0.7, + "size": 1.0, "weight": 50, "family": "Noto Sans" }, @@ -64,6 +64,12 @@ "size": 1.15, "weight": 50, "family": "Noto Sans" + }, + "extruder_icon": + { + "size": 0.7, + "weight": 50, + "family": "Noto Sans" } }, @@ -93,14 +99,14 @@ "secondary_button_hover": [228, 228, 228, 255], "secondary_button_text": [30, 102, 215, 255], - "main_window_header_background": [8, 7, 63, 255], + "main_window_header_background": [10, 8, 80, 255], "main_window_header_background_gradient": [25, 23, 91, 255], - "main_window_header_button_text_active": [8, 7, 63, 255], + "main_window_header_button_text_active": [10, 8, 80, 255], "main_window_header_button_text_inactive": [255, 255, 255, 255], "main_window_header_button_text_hovered": [255, 255, 255, 255], "main_window_header_button_background_active": [255, 255, 255, 255], "main_window_header_button_background_inactive": [255, 255, 255, 0], - "main_window_header_button_background_hovered": [117, 114, 159, 255], + "main_window_header_button_background_hovered": [255, 255, 255, 102], "account_widget_outline_active": [70, 66, 126, 255], @@ -108,13 +114,12 @@ "machine_selector_active": [68, 72, 75, 255], "machine_selector_hover": [68, 72, 75, 255], "machine_selector_text_active": [255, 255, 255, 255], - "machine_selector_printer_icon": [8, 7, 63, 255], "action_panel_secondary": [27, 95, 202, 255], "toolbar_background": [255, 255, 255, 255], - "printer_type_label_background": [228, 228, 242, 255], + "printer_type_label_background": [171, 171, 191, 255], "text": [0, 0, 0, 255], "text_detail": [174, 174, 174, 128], @@ -128,9 +133,9 @@ "text_scene_hover": [70, 84, 113, 255], "error": [255, 140, 0, 255], - "warning": [245, 166, 35, 255], + "warning": [255, 190, 35, 255], - "toolbar_button_text": [8, 7, 63, 255], + "toolbar_button_text": [10, 8, 80, 255], "toolbar_button_hover": [232, 242, 252, 255], "toolbar_button_active": [232, 242, 252, 255], "toolbar_button_active_hover": [232, 242, 252, 255], @@ -145,9 +150,9 @@ "button_text_active_hover": [255, 255, 255, 255], "small_button": [0, 0, 0, 0], - "small_button_hover": [8, 7, 63, 255], - "small_button_active": [8, 7, 63, 255], - "small_button_active_hover": [8, 7, 63, 255], + "small_button_hover": [10, 8, 80, 255], + "small_button_active": [10, 8, 80, 255], + "small_button_active_hover": [10, 8, 80, 255], "small_button_text": [171, 171, 191, 255], "small_button_text_hover": [255, 255, 255, 255], "small_button_text_active": [255, 255, 255, 255], @@ -223,8 +228,8 @@ "progressbar_control": [50, 130, 255, 255], "slider_groove": [223, 223, 223, 255], - "slider_groove_fill": [8, 7, 63, 255], - "slider_handle": [8, 7, 63, 255], + "slider_groove_fill": [10, 8, 80, 255], + "slider_handle": [10, 8, 80, 255], "slider_handle_active": [50, 130, 255, 255], "slider_text_background": [255, 255, 255, 255], @@ -236,7 +241,6 @@ "checkbox_border": [64, 69, 72, 255], "checkbox_border_hover": [50, 130, 255, 255], "checkbox_mark": [119, 122, 124, 255], - "checkbox_disabled": [223, 223, 223, 255], "checkbox_text": [27, 27, 27, 255], "tooltip": [68, 192, 255, 255], @@ -306,6 +310,14 @@ "layerview_support_interface": [64, 192, 255, 255], "layerview_nozzle": [181, 166, 66, 50], + "configuration_item": [255, 255, 255, 0], + "configuration_item_active": [12, 169, 227, 32], + "configuration_item_text": [0, 0, 0, 255], + "configuration_item_text_active": [0, 0, 0, 255], + "configuration_item_border": [127, 127, 127, 255], + "configuration_item_border_active": [12, 169, 227, 32], + "configuration_item_border_hover": [50, 130, 255, 255], + "tab_status_connected": [50, 130, 255, 255], "tab_status_disconnected": [200, 200, 200, 255], @@ -365,6 +377,7 @@ "action_panel_widget": [25.0, 0.0], "action_panel_information_widget": [20.0, 0.0], + "action_panel_button": [15.0, 3.0], "machine_selector_widget": [20.0, 4.0], "machine_selector_widget_content": [25.0, 32.0], @@ -410,9 +423,6 @@ "button_icon": [2.5, 2.5], "button_lining": [0, 0], - "action_button": [15.0, 3.0], - "action_button_radius": [0.15, 0.15], - "small_button": [2, 2], "small_button_icon": [1.5, 1.5], @@ -501,6 +511,9 @@ "avatar_image": [6.8, 6.8], + "action_button": [15.0, 3.0], + "action_button_radius": [0.15, 0.15], + "monitor_config_override_box": [1.0, 14.0], "monitor_extruder_circle": [2.75, 2.75], "monitor_text_line": [1.16, 1.16], From a1c252d3a20de28ae5c3f81b660b260e28b9065f Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 7 Dec 2018 10:25:46 +0100 Subject: [PATCH 0758/1292] Revert "Revert "fix merge conflict"" This reverts commit 4bffa6d90f2e6e9784c7e5508b61e00a92ecb74f. --- cura/Settings/ExtruderManager.py | 4 +- cura/Settings/ExtruderStack.py | 4 +- cura/Settings/ExtrudersModel.py | 6 +- cura/Settings/MachineManager.py | 4 +- .../ProcessSlicedLayersJob.py | 2 +- .../MachineSettingsAction.qml | 4 +- plugins/ModelChecker/ModelChecker.qml | 1 - .../PerObjectSettingsPanel.qml | 1 - .../PostProcessingPlugin.qml | 4 - plugins/PrepareStage/PrepareMenu.qml | 3 +- .../SimulationViewMainComponent.qml | 7 +- .../resources/qml/ToolboxAuthorPage.qml | 8 +- .../qml/ToolboxCompatibilityChart.qml | 2 +- .../resources/qml/ToolboxDetailPage.qml | 16 +- .../qml/ToolboxDownloadsGridTile.qml | 3 +- .../qml/ToolboxDownloadsShowcaseTile.qml | 2 - .../resources/qml/DiscoverUM3Action.qml | 16 +- .../qml/MonitorBuildplateConfiguration.qml | 2 +- .../qml/MonitorExtruderConfiguration.qml | 4 +- .../resources/qml/MonitorPrinterCard.qml | 10 +- .../src/ClusterUM3OutputDevice.py | 12 +- resources/qml/ActionButton.qml | 35 +- .../ActionPanel/OutputDevicesActionButton.qml | 4 + .../qml/ActionPanel/OutputProcessWidget.qml | 27 +- .../ActionPanel/PrintInformationWidget.qml | 3 - .../qml/ActionPanel/PrintJobInformation.qml | 8 +- .../qml/ActionPanel/SliceProcessWidget.qml | 7 +- resources/qml/Cura.qml | 89 +- resources/qml/CustomConfigurationSelector.qml | 357 ---- resources/qml/Dialogs/AboutDialog.qml | 6 +- resources/qml/Dialogs/AddMachineDialog.qml | 5 +- resources/qml/ExpandableComponent.qml | 6 +- resources/qml/ExtruderIcon.qml | 7 +- resources/qml/IconLabel.qml | 5 +- resources/qml/IconWithText.qml | 2 - resources/qml/JobSpecs.qml | 3 +- resources/qml/MainWindow/MainWindowHeader.qml | 30 +- .../ConfigurationMenu/AutoConfiguration.qml | 39 + .../ConfigurationMenu/ConfigurationItem.qml | 210 +- .../ConfigurationListView.qml | 77 +- .../ConfigurationMenu/ConfigurationMenu.qml | 203 ++ .../ConfigurationMenu/CustomConfiguration.qml | 250 +++ .../PrintCoreConfiguration.qml | 95 +- .../QuickConfigurationSelector.qml | 243 --- .../Menus/ConfigurationMenu/SyncButton.qml | 102 - resources/qml/Menus/ProfileMenu.qml | 8 +- resources/qml/ObjectsList.qml | 3 +- resources/qml/Preferences/MachinesPage.qml | 8 +- .../Materials/MaterialsBrandSection.qml | 5 +- .../Preferences/Materials/MaterialsList.qml | 8 +- .../Preferences/Materials/MaterialsSlot.qml | 2 - .../Materials/MaterialsTypeSection.qml | 2 - resources/qml/Preferences/ProfilesPage.qml | 24 +- .../qml/Preferences/SettingVisibilityPage.qml | 2 +- resources/qml/PrinterOutput/ExtruderBox.qml | 2 +- resources/qml/PrinterOutput/HeatedBedBox.qml | 2 +- .../qml/PrinterOutput/OutputDeviceHeader.qml | 4 +- .../qml/PrinterSelector/MachineSelector.qml | 60 +- .../PrinterSelector/MachineSelectorList.qml | 2 +- .../PrinterTypeLabel.qml | 2 +- resources/qml/Settings/SettingCategory.qml | 13 +- resources/qml/Settings/SettingCheckBox.qml | 4 +- .../qml/Settings/SettingOptionalExtruder.qml | 13 +- resources/qml/Settings/SettingView.qml | 11 +- resources/qml/SidebarSimple.qml | 7 +- resources/qml/Toolbar.qml | 2 +- resources/qml/ViewsSelector.qml | 6 +- resources/qml/qmldir | 1 - resources/themes/cura-dark/theme.json | 10 +- .../cura-light/images/header_pattern.svg | 1902 ++++++++++++++++- .../themes/cura-light/images/logo_about.svg | 172 ++ resources/themes/cura-light/styles.qml | 9 +- resources/themes/cura-light/theme.json | 51 +- 73 files changed, 3047 insertions(+), 1216 deletions(-) delete mode 100644 resources/qml/CustomConfigurationSelector.qml create mode 100644 resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml create mode 100644 resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml create mode 100644 resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml delete mode 100644 resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml delete mode 100644 resources/qml/Menus/ConfigurationMenu/SyncButton.qml rename resources/qml/{PrinterSelector => }/PrinterTypeLabel.qml (95%) create mode 100644 resources/themes/cura-light/images/logo_about.svg diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index 9089ba96e9..b0bcf3b100 100755 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -63,7 +63,7 @@ class ExtruderManager(QObject): if not self._application.getGlobalContainerStack(): return None # No active machine, so no active extruder. try: - return self._extruder_trains[self._application.getGlobalContainerStack().getId()][str(self._active_extruder_index)].getId() + return self._extruder_trains[self._application.getGlobalContainerStack().getId()][str(self.activeExtruderIndex)].getId() except KeyError: # Extruder index could be -1 if the global tab is selected, or the entry doesn't exist if the machine definition is wrong. return None @@ -144,7 +144,7 @@ class ExtruderManager(QObject): @pyqtSlot(result = QObject) def getActiveExtruderStack(self) -> Optional["ExtruderStack"]: - return self.getExtruderStack(self._active_extruder_index) + return self.getExtruderStack(self.activeExtruderIndex) ## Get an extruder stack by index def getExtruderStack(self, index) -> Optional["ExtruderStack"]: diff --git a/cura/Settings/ExtruderStack.py b/cura/Settings/ExtruderStack.py index d7faedb71c..d626ef06da 100644 --- a/cura/Settings/ExtruderStack.py +++ b/cura/Settings/ExtruderStack.py @@ -52,8 +52,8 @@ class ExtruderStack(CuraContainerStack): return super().getNextStack() def setEnabled(self, enabled: bool) -> None: - if "enabled" not in self._metadata: - self.setMetaDataEntry("enabled", "True") + if self.getMetaDataEntry("enabled", True) == enabled: #No change. + return #Don't emit a signal then. self.setMetaDataEntry("enabled", str(enabled)) self.enabledChanged.emit() diff --git a/cura/Settings/ExtrudersModel.py b/cura/Settings/ExtrudersModel.py index 14a8dadc69..5f10ac99d4 100644 --- a/cura/Settings/ExtrudersModel.py +++ b/cura/Settings/ExtrudersModel.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. from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot, pyqtProperty, QTimer @@ -165,7 +165,7 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): def __updateExtruders(self): extruders_changed = False - if self.rowCount() != 0: + if self.count != 0: extruders_changed = True items = [] @@ -177,7 +177,7 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): machine_extruder_count = global_container_stack.getProperty("machine_extruder_count", "value") for extruder in Application.getInstance().getExtruderManager().getActiveExtruderStacks(): - position = extruder.getMetaDataEntry("position", default = "0") # Get the position + position = extruder.getMetaDataEntry("position", default = "0") try: position = int(position) except ValueError: diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 53390ca88d..a472cc7f09 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -874,7 +874,7 @@ class MachineManager(QObject): caution_message = Message(catalog.i18nc( "@info:generic", "Settings have been changed to match the current availability of extruders: [%s]" % ", ".join(add_user_changes)), - lifetime=0, + lifetime = 0, title = catalog.i18nc("@info:title", "Settings updated")) caution_message.show() @@ -1553,7 +1553,7 @@ class MachineManager(QObject): elif word.isdigit(): abbr_machine += word else: - stripped_word = ''.join(char for char in unicodedata.normalize('NFD', word.upper()) if unicodedata.category(char) != 'Mn') + stripped_word = "".join(char for char in unicodedata.normalize("NFD", word.upper()) if unicodedata.category(char) != "Mn") # - use only the first character if the word is too long (> 3 characters) # - use the whole word if it's not too long (<= 3 characters) if len(stripped_word) > 3: diff --git a/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py b/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py index 594bf3a43e..71c96880e8 100644 --- a/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py +++ b/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py @@ -195,7 +195,7 @@ class ProcessSlicedLayersJob(Job): if extruders: material_color_map = numpy.zeros((len(extruders), 4), dtype=numpy.float32) for extruder in extruders: - position = int(extruder.getMetaDataEntry("position", default="0")) # Get the position + position = int(extruder.getMetaDataEntry("position", default = "0")) try: default_color = ExtrudersModel.defaultColors[position] except IndexError: diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index 004b4e3cfc..c88a721a84 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -1,4 +1,4 @@ -// Copyright (c) 2016 Ultimaker B.V. +// Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 @@ -23,7 +23,7 @@ Cura.MachineAction target: base.extrudersModel onModelChanged: { - var extruderCount = base.extrudersModel.rowCount(); + var extruderCount = base.extrudersModel.count; base.extruderTabsCount = extruderCount; } } diff --git a/plugins/ModelChecker/ModelChecker.qml b/plugins/ModelChecker/ModelChecker.qml index 5e41591d6b..437df29516 100644 --- a/plugins/ModelChecker/ModelChecker.qml +++ b/plugins/ModelChecker/ModelChecker.qml @@ -33,7 +33,6 @@ Button { width: UM.Theme.getSize("save_button_specs_icons").width; height: UM.Theme.getSize("save_button_specs_icons").height; - sourceSize.width: width; sourceSize.height: width; color: control.hovered ? UM.Theme.getColor("text_scene_hover") : UM.Theme.getColor("text_scene"); source: "model_checker.svg" diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index 5d4e17a102..0e2bd88619 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -265,7 +265,6 @@ Item { anchors.verticalCenter: parent.verticalCenter width: parent.width height: width - sourceSize.width: width sourceSize.height: width color: control.hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button") source: UM.Theme.getIcon("minus") diff --git a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml index bd4d361d35..3fa10c23b9 100644 --- a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml +++ b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml @@ -141,7 +141,6 @@ UM.Dialog anchors.horizontalCenter: parent.horizontalCenter width: Math.round(control.width / 2.7) height: Math.round(control.height / 2.7) - sourceSize.width: width sourceSize.height: width color: palette.text source: UM.Theme.getIcon("cross1") @@ -176,7 +175,6 @@ UM.Dialog anchors.horizontalCenter: parent.horizontalCenter width: Math.round(control.width / 2.5) height: Math.round(control.height / 2.5) - sourceSize.width: width sourceSize.height: width color: control.enabled ? palette.text : disabledPalette.text source: UM.Theme.getIcon("arrow_bottom") @@ -211,7 +209,6 @@ UM.Dialog anchors.horizontalCenter: parent.horizontalCenter width: Math.round(control.width / 2.5) height: Math.round(control.height / 2.5) - sourceSize.width: width sourceSize.height: width color: control.enabled ? palette.text : disabledPalette.text source: UM.Theme.getIcon("arrow_top") @@ -498,7 +495,6 @@ UM.Dialog anchors.horizontalCenter: parent.horizontalCenter width: Math.round(parent.width / 2) height: Math.round(parent.height / 2) - sourceSize.width: width sourceSize.height: height color: !control.enabled ? UM.Theme.getColor("action_button_disabled_text") : control.pressed ? UM.Theme.getColor("action_button_active_text") : diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index 10b4262f01..fa94bc88b2 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -61,7 +61,7 @@ Item color: UM.Theme.getColor("lining") } - Cura.QuickConfigurationSelector + Cura.ConfigurationMenu { Layout.fillHeight: true Layout.fillWidth: true @@ -107,7 +107,6 @@ Item height: UM.Theme.getSize("button_icon").height color: UM.Theme.getColor("toolbar_button_text") - sourceSize.width: width sourceSize.height: height } } diff --git a/plugins/SimulationView/SimulationViewMainComponent.qml b/plugins/SimulationView/SimulationViewMainComponent.qml index 16b9aeaae6..16b049c921 100644 --- a/plugins/SimulationView/SimulationViewMainComponent.qml +++ b/plugins/SimulationView/SimulationViewMainComponent.qml @@ -61,10 +61,9 @@ Item iconSource: !is_simulation_playing ? "./resources/simulation_resume.svg": "./resources/simulation_pause.svg" width: UM.Theme.getSize("small_button").width height: UM.Theme.getSize("small_button").height - hoverBackgroundColor: UM.Theme.getColor("small_button_hover") - hoverColor: UM.Theme.getColor("small_button_text_hover") - color: UM.Theme.getColor("small_button_text") - iconMargin: 0.5 * UM.Theme.getSize("wide_lining").width + hoverColor: UM.Theme.getColor("slider_handle_active") + color: UM.Theme.getColor("slider_handle") + iconMargin: UM.Theme.getSize("thick_lining").width visible: !UM.SimulationView.compatibilityMode Connections diff --git a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml index 4aaea20813..9c1df0c49e 100644 --- a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml @@ -86,13 +86,13 @@ Item Label { text: catalog.i18nc("@label", "Website") + ":" - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("text_medium") } Label { text: catalog.i18nc("@label", "Email") + ":" - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("text_medium") } } @@ -118,7 +118,7 @@ Item } return "" } - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") linkColor: UM.Theme.getColor("text_link") onLinkActivated: Qt.openUrlExternally(link) @@ -134,7 +134,7 @@ Item } return "" } - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") linkColor: UM.Theme.getColor("text_link") onLinkActivated: Qt.openUrlExternally(link) diff --git a/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml b/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml index 4a6268df42..d4c0ae14eb 100644 --- a/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml +++ b/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml @@ -228,7 +228,7 @@ Item return result } - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") linkColor: UM.Theme.getColor("text_link") onLinkActivated: Qt.openUrlExternally(link) diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index c5e9bb0a49..9e2e178b71 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -82,25 +82,25 @@ Item Label { text: catalog.i18nc("@label", "Version") + ":" - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("text_medium") } Label { text: catalog.i18nc("@label", "Last updated") + ":" - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("text_medium") } Label { text: catalog.i18nc("@label", "Author") + ":" - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("text_medium") } Label { text: catalog.i18nc("@label", "Downloads") + ":" - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("text_medium") } } @@ -119,7 +119,7 @@ Item Label { text: details === null ? "" : (details.version || catalog.i18nc("@label", "Unknown")) - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") } Label @@ -133,7 +133,7 @@ Item var date = new Date(details.last_updated) return date.toLocaleString(UM.Preferences.getValue("general/language")) } - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") } Label @@ -149,7 +149,7 @@ Item return "" + details.author_name + "" } } - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") linkColor: UM.Theme.getColor("text_link") onLinkActivated: Qt.openUrlExternally(link) @@ -157,7 +157,7 @@ Item Label { text: details === null ? "" : (details.download_count || catalog.i18nc("@label", "Unknown")) - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index 887140bbfa..61374f9d99 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -52,7 +52,6 @@ Item bottom: parent.bottom right: parent.right } - sourceSize.width: width sourceSize.height: height visible: installedPackages != 0 color: (installedPackages == packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border") @@ -81,7 +80,7 @@ Item width: parent.width wrapMode: Text.WordWrap color: UM.Theme.getColor("text_medium") - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml index 4fb70541d2..8a2fdc8bc8 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml @@ -48,8 +48,6 @@ Rectangle right: parent.right bottomMargin: UM.Theme.getSize("default_lining").width } - sourceSize.width: width - sourceSize.height: height visible: installedPackages != 0 color: (installedPackages == packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border") source: "../images/installed_check.svg" diff --git a/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml b/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml index 967adfc029..bb710127fc 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml @@ -64,6 +64,7 @@ Cura.MachineAction width: parent.width text: catalog.i18nc("@title:window", "Connect to Networked Printer") wrapMode: Text.WordWrap + renderType: Text.NativeRendering font.pointSize: 18 } @@ -72,6 +73,7 @@ Cura.MachineAction id: pageDescription width: parent.width wrapMode: Text.WordWrap + renderType: Text.NativeRendering text: catalog.i18nc("@label", "To print directly to your printer over the network, please make sure your printer is connected to the network using a network cable or by connecting your printer to your WIFI network. If you don't connect Cura with your printer, you can still use a USB drive to transfer g-code files to your printer.\n\nSelect your printer from the list below:") } @@ -182,6 +184,7 @@ Cura.MachineAction text: listview.model[index].name color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text elide: Text.ElideRight + renderType: Text.NativeRendering } MouseArea @@ -204,6 +207,7 @@ Cura.MachineAction anchors.left: parent.left anchors.right: parent.right wrapMode: Text.WordWrap + renderType: Text.NativeRendering text: catalog.i18nc("@label", "If your printer is not listed, read the network printing troubleshooting guide").arg("https://ultimaker.com/en/troubleshooting"); onLinkActivated: Qt.openUrlExternally(link) } @@ -221,6 +225,7 @@ Cura.MachineAction text: base.selectedDevice ? base.selectedDevice.name : "" font: UM.Theme.getFont("large") elide: Text.ElideRight + renderType: Text.NativeRendering } Grid { @@ -231,12 +236,14 @@ Cura.MachineAction { width: Math.round(parent.width * 0.5) wrapMode: Text.WordWrap + renderType: Text.NativeRendering text: catalog.i18nc("@label", "Type") } Label { width: Math.round(parent.width * 0.5) wrapMode: Text.WordWrap + renderType: Text.NativeRendering text: { if(base.selectedDevice) @@ -268,24 +275,28 @@ Cura.MachineAction { width: Math.round(parent.width * 0.5) wrapMode: Text.WordWrap + renderType: Text.NativeRendering text: catalog.i18nc("@label", "Firmware version") } Label { width: Math.round(parent.width * 0.5) wrapMode: Text.WordWrap + renderType: Text.NativeRendering text: base.selectedDevice ? base.selectedDevice.firmwareVersion : "" } Label { width: Math.round(parent.width * 0.5) wrapMode: Text.WordWrap + renderType: Text.NativeRendering text: catalog.i18nc("@label", "Address") } Label { width: Math.round(parent.width * 0.5) wrapMode: Text.WordWrap + renderType: Text.NativeRendering text: base.selectedDevice ? base.selectedDevice.ipAddress : "" } } @@ -294,6 +305,7 @@ Cura.MachineAction { width: parent.width wrapMode: Text.WordWrap + renderType: Text.NativeRendering text:{ // The property cluster size does not exist for older UM3 devices. if(!base.selectedDevice || base.selectedDevice.clusterSize == null || base.selectedDevice.clusterSize == 1) @@ -315,6 +327,7 @@ Cura.MachineAction { width: parent.width wrapMode: Text.WordWrap + renderType: Text.NativeRendering visible: base.selectedDevice != null && !base.completeProperties text: catalog.i18nc("@label", "The printer at this address has not yet responded." ) } @@ -358,9 +371,10 @@ Cura.MachineAction Label { - text: catalog.i18nc("@alabel","Enter the IP address or hostname of your printer on the network.") + text: catalog.i18nc("@alabel", "Enter the IP address or hostname of your printer on the network.") width: parent.width wrapMode: Text.WordWrap + renderType: Text.NativeRendering } TextField diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml index 9ffb1eabb4..7edeb81a96 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml @@ -52,7 +52,7 @@ Item id: buildplateLabel color: "#191919" // TODO: Theme! elide: Text.ElideRight - font: UM.Theme.getFont("very_small") // 12pt, regular + font: UM.Theme.getFont("default") // 12pt, regular text: "" // FIXED-LINE-HEIGHT: diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorExtruderConfiguration.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorExtruderConfiguration.qml index afbd4c3641..1e53191d8c 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorExtruderConfiguration.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorExtruderConfiguration.qml @@ -49,7 +49,7 @@ Item } color: "#191919" // TODO: Theme! elide: Text.ElideRight - font: UM.Theme.getFont("very_small") // 12pt, regular + font: UM.Theme.getFont("default") // 12pt, regular text: "" // FIXED-LINE-HEIGHT: @@ -66,7 +66,7 @@ Item } color: "#191919" // TODO: Theme! elide: Text.ElideRight - font: UM.Theme.getFont("small") // 12pt, bold + font: UM.Theme.getFont("default_bold") // 12pt, bold text: "" // FIXED-LINE-HEIGHT: diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml index 8659037cb8..567fff8489 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml @@ -179,13 +179,15 @@ Item color: "#414054" // TODO: Theme! font: UM.Theme.getFont("large") // 16pt, bold text: { - if (printer && printer.state == "disabled"){ + if (printer && printer.state == "disabled") + { return catalog.i18nc("@label:status", "Unavailable") } - if (printer && printer.state == "unreachable"){ - return catalog.i18nc("@label:status", "Unavailable") + if (printer && printer.state == "unreachable") + { + return catalog.i18nc("@label:status", "Unreachable") } - if (printer && !printer.activePrintJob) + if (printer && printer.state == "idle") { return catalog.i18nc("@label:status", "Idle") } diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index cc5b128479..a5ee3bc650 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -572,7 +572,17 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): def _createMaterialOutputModel(self, material_data: Dict[str, Any]) -> "MaterialOutputModel": material_manager = CuraApplication.getInstance().getMaterialManager() - material_group_list = material_manager.getMaterialGroupListByGUID(material_data["guid"]) or [] + material_group_list = material_manager.getMaterialGroupListByGUID(material_data["guid"]) + # This can happen if the connected machine has no material in one or more extruders (if GUID is empty), or the + # material is unknown to Cura, so we should return an "empty" or "unknown" material model. + if material_group_list is None: + material_name = "Empty" if len(material_data["guid"]) == 0 else "Unknown" + return MaterialOutputModel(guid = material_data["guid"], + type = material_data.get("type", ""), + color = material_data.get("color", ""), + brand = material_data.get("brand", ""), + name = material_data.get("name", material_name) + ) # Sort the material groups by "is_read_only = True" first, and then the name alphabetically. read_only_material_group_list = list(filter(lambda x: x.is_read_only, material_group_list)) diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index b9a04f3b46..fc4a1c05f4 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -7,14 +7,17 @@ import QtQuick.Controls 2.1 import QtGraphicalEffects 1.0 // For the dropshadow import UM 1.1 as UM +import Cura 1.0 as Cura Button { id: button - property alias iconSource: buttonIcon.source + property alias iconSource: buttonIconLeft.source + property bool isIconOnRightSide: false property alias textFont: buttonText.font property alias cornerRadius: backgroundRect.radius property alias tooltip: tooltip.text + property alias cornerSide: backgroundRect.cornerSide property color color: UM.Theme.getColor("primary") property color hoverColor: UM.Theme.getColor("primary_hover") @@ -36,18 +39,21 @@ Button // we elide the text to the right so the text will be cut off with the three dots at the end. property var fixedWidthMode: false + leftPadding: UM.Theme.getSize("default_margin").width + rightPadding: UM.Theme.getSize("default_margin").width + height: UM.Theme.getSize("action_button").height + contentItem: Row { + //Left side icon. Only displayed if !isIconOnRightSide. UM.RecolorImage { - id: buttonIcon + id: buttonIconLeft source: "" - height: Math.round(0.6 * parent.height) - width: height - sourceSize.width: width - sourceSize.height: height + height: buttonText.height + width: visible ? height : 0 color: button.hovered ? button.textHoverColor : button.textColor - visible: source != "" + visible: source != "" && !button.isIconOnRightSide anchors.verticalCenter: parent.verticalCenter } @@ -64,11 +70,24 @@ Button horizontalAlignment: Text.AlignHCenter elide: Text.ElideRight } + + //Right side icon. Only displayed if isIconOnRightSide. + UM.RecolorImage + { + id: buttonIconRight + source: buttonIconLeft.source + height: buttonText.height + width: visible ? height : 0 + color: buttonIconLeft.color + visible: source != "" && button.isIconOnRightSide + anchors.verticalCenter: buttonIconLeft.verticalCenter + } } - background: Rectangle + background: Cura.RoundedRectangle { id: backgroundRect + cornerSide: Cura.RoundedRectangle.Direction.All color: button.enabled ? (button.hovered ? button.hoverColor : button.color) : button.disabledColor radius: UM.Theme.getSize("action_button_radius").width border.width: UM.Theme.getSize("default_lining").width diff --git a/resources/qml/ActionPanel/OutputDevicesActionButton.qml b/resources/qml/ActionPanel/OutputDevicesActionButton.qml index 2111038cfc..95750e6d11 100644 --- a/resources/qml/ActionPanel/OutputDevicesActionButton.qml +++ b/resources/qml/ActionPanel/OutputDevicesActionButton.qml @@ -17,6 +17,7 @@ Item id: saveToButton height: parent.height fixedWidthMode: true + cornerSide: deviceSelectionMenu.visible ? Cura.RoundedRectangle.Direction.Left : Cura.RoundedRectangle.Direction.All anchors { @@ -44,6 +45,7 @@ Item shadowEnabled: true shadowColor: UM.Theme.getColor("primary_shadow") + cornerSide: Cura.RoundedRectangle.Direction.Right anchors { @@ -51,6 +53,8 @@ Item right: parent.right } + leftPadding: UM.Theme.getSize("narrow_margin").width //Need more space than usual here for wide text. + rightPadding: UM.Theme.getSize("narrow_margin").width tooltip: catalog.i18nc("@info:tooltip", "Select the active output device") iconSource: popup.opened ? UM.Theme.getIcon("arrow_top") : UM.Theme.getIcon("arrow_bottom") color: UM.Theme.getColor("action_panel_secondary") diff --git a/resources/qml/ActionPanel/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml index 6ab8dc6fbb..1d1a1e44e1 100644 --- a/resources/qml/ActionPanel/OutputProcessWidget.qml +++ b/resources/qml/ActionPanel/OutputProcessWidget.qml @@ -51,7 +51,7 @@ Column text: preSlicedData ? catalog.i18nc("@label", "No time estimation available") : PrintInformation.currentPrintTime.getDisplayString(UM.DurationFormat.Long) source: UM.Theme.getIcon("clock") - font: UM.Theme.getFont("small") + font: UM.Theme.getFont("default_bold") } Cura.IconLabel @@ -84,7 +84,7 @@ Column return totalWeights + "g · " + totalLengths.toFixed(2) + "m" } source: UM.Theme.getIcon("spool") - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") } } @@ -101,17 +101,25 @@ Column } } - Row + Item { id: buttonRow - spacing: UM.Theme.getSize("default_margin").width - width: parent.width + anchors.right: parent.right + anchors.left: parent.left + height: UM.Theme.getSize("action_button").height Cura.SecondaryButton { id: previewStageShortcut - height: UM.Theme.getSize("action_panel_button").height + anchors + { + left: parent.left + right: outputDevicesButton.left + rightMargin: UM.Theme.getSize("default_margin").width + } + + height: UM.Theme.getSize("action_button").height leftPadding: UM.Theme.getSize("default_margin").width rightPadding: UM.Theme.getSize("default_margin").width text: catalog.i18nc("@button", "Preview") @@ -125,8 +133,11 @@ Column Cura.OutputDevicesActionButton { - width: previewStageShortcut.visible ? UM.Theme.getSize("action_panel_button").width : parent.width - height: UM.Theme.getSize("action_panel_button").height + id: outputDevicesButton + + anchors.right: parent.right + width: previewStageShortcut.visible ? UM.Theme.getSize("action_button").width : parent.width + height: UM.Theme.getSize("action_button").height } } } \ No newline at end of file diff --git a/resources/qml/ActionPanel/PrintInformationWidget.qml b/resources/qml/ActionPanel/PrintInformationWidget.qml index 25e380dea8..554273a818 100644 --- a/resources/qml/ActionPanel/PrintInformationWidget.qml +++ b/resources/qml/ActionPanel/PrintInformationWidget.qml @@ -15,9 +15,6 @@ UM.RecolorImage width: UM.Theme.getSize("section_icon").width height: UM.Theme.getSize("section_icon").height - sourceSize.width: width - sourceSize.height: height - color: popup.opened ? UM.Theme.getColor("primary") : UM.Theme.getColor("text_medium") MouseArea diff --git a/resources/qml/ActionPanel/PrintJobInformation.qml b/resources/qml/ActionPanel/PrintJobInformation.qml index 156111af4d..8bd5d5a0d3 100644 --- a/resources/qml/ActionPanel/PrintJobInformation.qml +++ b/resources/qml/ActionPanel/PrintJobInformation.qml @@ -30,7 +30,7 @@ Column { text: catalog.i18nc("@label", "Time specification").toUpperCase() color: UM.Theme.getColor("primary") - font: UM.Theme.getFont("small") + font: UM.Theme.getFont("default_bold") renderType: Text.NativeRendering } @@ -61,7 +61,7 @@ Column } width: parent.width - 2 * UM.Theme.getSize("default_margin").width color: UM.Theme.getColor("text") - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") renderType: Text.NativeRendering textFormat: Text.RichText } @@ -79,7 +79,7 @@ Column { text: catalog.i18nc("@label", "Material specification").toUpperCase() color: UM.Theme.getColor("primary") - font: UM.Theme.getFont("small") + font: UM.Theme.getFont("default_bold") renderType: Text.NativeRendering } @@ -151,7 +151,7 @@ Column } width: parent.width - 2 * UM.Theme.getSize("default_margin").width color: UM.Theme.getColor("text") - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") renderType: Text.NativeRendering textFormat: Text.RichText } diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index 03d91db530..8f6608e15c 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -48,7 +48,7 @@ Column text: catalog.i18nc("@label:PrintjobStatus", "Auto slicing...") color: UM.Theme.getColor("text") - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") renderType: Text.NativeRendering } @@ -61,7 +61,7 @@ Column text: catalog.i18nc("@label:PrintjobStatus", "Unable to Slice") source: UM.Theme.getIcon("warning") color: UM.Theme.getColor("warning") - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") } // Progress bar, only visible when the backend is in the process of slice the printjob @@ -94,7 +94,6 @@ Column } } - Item { id: prepareButtons @@ -103,7 +102,7 @@ Column // Disable the slice process when width: parent.width - height: UM.Theme.getSize("action_panel_button").height + height: UM.Theme.getSize("action_button").height visible: !autoSlice Cura.PrimaryButton { diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 3578888886..4e8e9ce788 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -88,6 +88,54 @@ UM.MainWindow window: base } + Rectangle + { + id: headerBackground + anchors + { + top: applicationMenu.bottom + left: parent.left + right: parent.right + } + height: stageMenu.source != "" ? Math.round(mainWindowHeader.height + stageMenu.height / 2) : mainWindowHeader.height + + LinearGradient + { + anchors.fill: parent + start: Qt.point(0, 0) + end: Qt.point(parent.width, 0) + gradient: Gradient + { + GradientStop + { + position: 0.0 + color: UM.Theme.getColor("main_window_header_background") + } + GradientStop + { + position: 0.5 + color: UM.Theme.getColor("main_window_header_background_gradient") + } + GradientStop + { + position: 1.0 + color: UM.Theme.getColor("main_window_header_background") + } + } + } + + // This is the new fancy pattern + Image + { + id: backgroundPattern + anchors.fill: parent + fillMode: Image.Tile + source: UM.Theme.getImage("header_pattern") + horizontalAlignment: Image.AlignLeft + verticalAlignment: Image.AlignTop + } + } + MainWindowHeader { id: mainWindowHeader @@ -144,44 +192,6 @@ UM.MainWindow } } - Rectangle - { - id: stageMenuBackground - anchors - { - left: parent.left - right: parent.right - top: parent.top - } - visible: stageMenu.source != "" - height: visible ? Math.round(UM.Theme.getSize("stage_menu").height / 2) : 0 - - LinearGradient - { - anchors.fill: parent - start: Qt.point(0, 0) - end: Qt.point(parent.width, 0) - gradient: Gradient - { - GradientStop - { - position: 0.0 - color: UM.Theme.getColor("main_window_header_background") - } - GradientStop - { - position: 0.5 - color: UM.Theme.getColor("main_window_header_background_gradient") - } - GradientStop - { - position: 1.0 - color: UM.Theme.getColor("main_window_header_background") - } - } - } - } - Connections { target: stageMenu.item @@ -257,7 +267,8 @@ UM.MainWindow anchors { - top: stageMenuBackground.bottom + // Align to the top of the stageMenu since the stageMenu may not exist + top: parent.top left: parent.left right: parent.right bottom: parent.bottom diff --git a/resources/qml/CustomConfigurationSelector.qml b/resources/qml/CustomConfigurationSelector.qml deleted file mode 100644 index c78ca700da..0000000000 --- a/resources/qml/CustomConfigurationSelector.qml +++ /dev/null @@ -1,357 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.7 -import QtQuick.Controls 1.1 -import QtQuick.Controls.Styles 1.1 - -import UM 1.2 as UM -import Cura 1.0 as Cura - -Rectangle -{ - implicitWidth: parent.width - implicitHeight: parent.height - - id: base - color: UM.Theme.getColor("main_background") - - // Height has an extra 2x margin for the top & bottom margin. - height: childrenRect.height + 2 * UM.Theme.getSize("default_margin").width - - Cura.ExtrudersModel { id: extrudersModel } - - ListView - { - // Horizontal list that shows the extruders - id: extrudersList - visible: extrudersModel.items.length > 1 - property var index: 0 - - height: UM.Theme.getSize("configuration_selector_mode_tabs").height - boundsBehavior: Flickable.StopAtBounds - - anchors - { - left: parent.left - right: parent.right - top: parent.top - margins: UM.Theme.getSize("thick_margin").width - } - - ExclusiveGroup { id: extruderMenuGroup } - - orientation: ListView.Horizontal - - model: extrudersModel - - Connections - { - target: Cura.MachineManager - onGlobalContainerChanged: forceActiveFocus() // Changing focus applies the currently-being-typed values so it can change the displayed setting values. - } - - delegate: Button - { - height: parent.height - width: Math.round(ListView.view.width / extrudersModel.rowCount()) - - text: model.name - tooltip: model.name - exclusiveGroup: extruderMenuGroup - checked: Cura.ExtruderManager.activeExtruderIndex == index - - property bool extruder_enabled: true - - MouseArea // TODO; This really should be fixed. It makes absolutely no sense to have a button AND a mouse area. - { - anchors.fill: parent - acceptedButtons: Qt.LeftButton | Qt.RightButton - onClicked: - { - switch (mouse.button) - { - case Qt.LeftButton: - extruder_enabled = Cura.MachineManager.getExtruder(model.index).isEnabled - if (extruder_enabled) - { - forceActiveFocus() // Changing focus applies the currently-being-typed values so it can change the displayed setting values. - Cura.ExtruderManager.setActiveExtruderIndex(index) - } - break - case Qt.RightButton: - extruder_enabled = Cura.MachineManager.getExtruder(model.index).isEnabled - extruderMenu.popup() - break - } - } - } - - Menu - { - id: extruderMenu - - MenuItem - { - text: catalog.i18nc("@action:inmenu", "Enable Extruder") - onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, true) - visible: !extruder_enabled // using an intermediate variable prevents an empty popup that occured now and then - } - - MenuItem - { - text: catalog.i18nc("@action:inmenu", "Disable Extruder") - onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, false) - visible: extruder_enabled - enabled: Cura.MachineManager.numberExtrudersEnabled > 1 - } - } - - style: ButtonStyle - { - background: Rectangle - { - anchors.fill: parent - border.width: control.checked ? UM.Theme.getSize("default_lining").width * 2 : UM.Theme.getSize("default_lining").width - border.color: - { - if (Cura.MachineManager.getExtruder(index).isEnabled) - { - if(control.checked || control.pressed) - { - return UM.Theme.getColor("action_button_active_border") - } - else if (control.hovered) - { - return UM.Theme.getColor("action_button_hovered_border") - } - return UM.Theme.getColor("action_button_border") - } - return UM.Theme.getColor("action_button_disabled_border") - } - color: - { - if (Cura.MachineManager.getExtruder(index).isEnabled) - { - if(control.checked || control.pressed) - { - return UM.Theme.getColor("action_button_active"); - } - else if (control.hovered) - { - return UM.Theme.getColor("action_button_hovered") - } - return UM.Theme.getColor("action_button") - } - return UM.Theme.getColor("action_button_disabled") - } - Behavior on color { ColorAnimation { duration: 50; } } - - Item - { - id: extruderButtonFace - anchors.centerIn: parent - width: childrenRect.width - - Label - { - // Static text that holds the "Extruder" label - id: extruderStaticText - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - - color: - { - if (Cura.MachineManager.getExtruder(index).isEnabled) - { - if(control.checked || control.pressed) - { - return UM.Theme.getColor("action_button_active_text"); - } - else if (control.hovered) - { - return UM.Theme.getColor("action_button_hovered_text") - } - return UM.Theme.getColor("action_button_text") - } - return UM.Theme.getColor("action_button_disabled_text") - } - - font: UM.Theme.getFont("large_nonbold") - text: catalog.i18nc("@label", "Extruder") - visible: width < (control.width - extruderIcon.width - UM.Theme.getSize("default_margin").width) - elide: Text.ElideRight - } - - ExtruderIcon - { - // Round icon with the extruder number and material color indicator. - id: extruderIcon - - anchors.verticalCenter: parent.verticalCenter - anchors.left: extruderStaticText.right - anchors.leftMargin: UM.Theme.getSize("default_margin").width - width: control.height - Math.round(UM.Theme.getSize("default_margin").width / 2) - height: width - - checked: control.checked - materialColor: model.color - textColor: extruderStaticText.color - } - } - } - - label: Item {} - } - } - } - - Item - { - id: materialRow - height: UM.Theme.getSize("print_setup_item").height - visible: Cura.MachineManager.hasMaterials - - anchors - { - left: parent.left - right: parent.right - top: extrudersList.bottom - margins: UM.Theme.getSize("thick_margin").width - } - - Label - { - id: materialLabel - text: catalog.i18nc("@label", "Material"); - width: Math.round(parent.width * 0.45 - UM.Theme.getSize("default_margin").width) - height: parent.height - verticalAlignment: Text.AlignVCenter - font: UM.Theme.getFont("default"); - color: UM.Theme.getColor("text"); - } - - ToolButton - { - id: materialSelection - - property var activeExtruder: Cura.MachineManager.activeStack - property var hasActiveExtruder: activeExtruder != null - property var currentRootMaterialName: hasActiveExtruder ? activeExtruder.material.name : "" - - text: currentRootMaterialName - tooltip: currentRootMaterialName - visible: Cura.MachineManager.hasMaterials - - enabled: !extrudersList.visible || Cura.ExtruderManager.activeExtruderIndex > -1 - - height: UM.Theme.getSize("setting_control").height - width: Math.round(parent.width * 0.7) + UM.Theme.getSize("thick_margin").width - anchors.right: parent.right - style: UM.Theme.styles.sidebar_header_button - activeFocusOnPress: true; - menu: Cura.MaterialMenu - { - extruderIndex: Cura.ExtruderManager.activeExtruderIndex - } - - property var valueError: hasActiveExtruder ? Cura.ContainerManager.getContainerMetaDataEntry(activeExtruder.material.id, "compatible", "") != "True" : true - property var valueWarning: ! Cura.MachineManager.isActiveQualitySupported - } - } - - Item - { - id: variantRow - height: UM.Theme.getSize("print_setup_item").height - visible: Cura.MachineManager.hasVariants - - anchors - { - left: parent.left - right: parent.right - top: materialRow.bottom - margins: UM.Theme.getSize("thick_margin").width - } - - Label - { - id: variantLabel - text: Cura.MachineManager.activeDefinitionVariantsName; - width: Math.round(parent.width * 0.45 - UM.Theme.getSize("default_margin").width) - height: parent.height - verticalAlignment: Text.AlignVCenter - font: UM.Theme.getFont("default"); - color: UM.Theme.getColor("text"); - } - - ToolButton - { - id: variantSelection - text: Cura.MachineManager.activeVariantName - tooltip: Cura.MachineManager.activeVariantName; - visible: Cura.MachineManager.hasVariants - - height: UM.Theme.getSize("setting_control").height - width: Math.round(parent.width * 0.7 + UM.Theme.getSize("thick_margin").width) - anchors.right: parent.right - style: UM.Theme.styles.sidebar_header_button - activeFocusOnPress: true; - - menu: Cura.NozzleMenu { extruderIndex: Cura.ExtruderManager.activeExtruderIndex } - } - } - - Item - { - id: materialCompatibilityLink - height: UM.Theme.getSize("print_setup_item").height - - anchors.right: parent.right - anchors.top: variantRow.bottom - anchors.margins: UM.Theme.getSize("thick_margin").width - UM.RecolorImage - { - id: warningImage - - anchors.right: materialInfoLabel.left - anchors.rightMargin: UM.Theme.getSize("default_margin").width - - source: UM.Theme.getIcon("warning") - width: UM.Theme.getSize("section_icon").width - height: UM.Theme.getSize("section_icon").height - - sourceSize.width: width - sourceSize.height: height - - color: UM.Theme.getColor("material_compatibility_warning") - - visible: !Cura.MachineManager.isCurrentSetupSupported - } - - Label - { - id: materialInfoLabel - wrapMode: Text.WordWrap - text: "" + catalog.i18nc("@label", "Check compatibility") + "" - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - linkColor: UM.Theme.getColor("text_link") - - verticalAlignment: Text.AlignTop - - anchors.right: parent.right - - MouseArea - { - anchors.fill: parent - - onClicked: - { - // open the material URL with web browser - Qt.openUrlExternally("https://ultimaker.com/incoming-links/cura/material-compatibilty"); - } - } - } - } -} diff --git a/resources/qml/Dialogs/AboutDialog.qml b/resources/qml/Dialogs/AboutDialog.qml index 25c9bbf74b..add84614e0 100644 --- a/resources/qml/Dialogs/AboutDialog.qml +++ b/resources/qml/Dialogs/AboutDialog.qml @@ -35,12 +35,10 @@ UM.Dialog { id: logo width: (base.minimumWidth * 0.85) | 0 - height: (width * (1/4.25)) | 0 + height: (width * (UM.Theme.getSize("logo").height / UM.Theme.getSize("logo").width)) | 0 - source: UM.Theme.getImage("logo") + source: UM.Theme.getImage("logo_about") - sourceSize.width: width - sourceSize.height: height anchors.top: parent.top anchors.topMargin: ((base.minimumWidth - width) / 2) | 0 anchors.horizontalCenter: parent.horizontalCenter diff --git a/resources/qml/Dialogs/AddMachineDialog.qml b/resources/qml/Dialogs/AddMachineDialog.qml index 8e966c3df7..f00359869c 100644 --- a/resources/qml/Dialogs/AddMachineDialog.qml +++ b/resources/qml/Dialogs/AddMachineDialog.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.2 @@ -156,7 +156,6 @@ UM.Dialog anchors.rightMargin: UM.Theme.getSize("default_margin").width width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height - sourceSize.width: width sourceSize.height: width color: palette.windowText source: base.activeCategory == section ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_right") @@ -170,7 +169,7 @@ UM.Dialog if (machineList.model.getItem(machineList.currentIndex).section != section) { // Find the first machine from this section - for(var i = 0; i < machineList.model.rowCount(); i++) + for(var i = 0; i < machineList.model.count; i++) { var item = machineList.model.getItem(i); if (item.section == section) diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index b438f0398c..e42aa7e4a1 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -32,6 +32,8 @@ Item property color headerBackgroundColor: UM.Theme.getColor("action_button") property color headerHoverColor: UM.Theme.getColor("action_button_hovered") + property alias enabled: mouseArea.enabled + // Defines the alignment of the popup with respect of the headerItem, by default to the right property int popupAlignment: ExpandableComponent.PopupAlignment.AlignRight @@ -139,9 +141,7 @@ Item verticalCenter: parent.verticalCenter margins: background.padding } - sourceSize.width: width - sourceSize.height: height - visible: source != "" + visible: source != "" && base.enabled width: height height: Math.round(0.2 * base.height) color: UM.Theme.getColor("text") diff --git a/resources/qml/ExtruderIcon.qml b/resources/qml/ExtruderIcon.qml index c1a202050b..49ad73a32e 100644 --- a/resources/qml/ExtruderIcon.qml +++ b/resources/qml/ExtruderIcon.qml @@ -22,8 +22,6 @@ Item id: mainIcon anchors.fill: parent - sourceSize.width: parent.width - sourceSize.height: parent.height source: UM.Theme.getIcon("extruder_button") color: extruderEnabled ? materialColor: "gray" } @@ -50,7 +48,9 @@ Item id: extruderNumberText anchors.centerIn: parent text: index + 1 - font: UM.Theme.getFont("extruder_icon") + font: UM.Theme.getFont("very_small") + width: contentWidth + height: contentHeight visible: extruderEnabled renderType: Text.NativeRendering horizontalAlignment: Text.AlignHCenter @@ -62,7 +62,6 @@ Item id: disabledIcon anchors.fill: parent anchors.margins: UM.Theme.getSize("thick_lining").width - sourceSize.width: width sourceSize.height: width source: UM.Theme.getIcon("cross1") visible: !extruderEnabled diff --git a/resources/qml/IconLabel.qml b/resources/qml/IconLabel.qml index 0941254e7b..f925b6eab5 100644 --- a/resources/qml/IconLabel.qml +++ b/resources/qml/IconLabel.qml @@ -31,9 +31,6 @@ Item width: UM.Theme.getSize("section_icon").width height: width - sourceSize.width: width - sourceSize.height: height - color: label.color visible: source != "" } @@ -48,7 +45,7 @@ Item text: "Empty label" elide: Text.ElideRight color: UM.Theme.getColor("text") - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") renderType: Text.NativeRendering } } \ No newline at end of file diff --git a/resources/qml/IconWithText.qml b/resources/qml/IconWithText.qml index dcb3ef7851..22599b3aed 100644 --- a/resources/qml/IconWithText.qml +++ b/resources/qml/IconWithText.qml @@ -37,8 +37,6 @@ Item width: UM.Theme.getSize("section_icon").width height: UM.Theme.getSize("section_icon").height - sourceSize.width: width - sourceSize.height: height color: "black" anchors diff --git a/resources/qml/JobSpecs.qml b/resources/qml/JobSpecs.qml index 45111992c1..935cb723de 100644 --- a/resources/qml/JobSpecs.qml +++ b/resources/qml/JobSpecs.qml @@ -60,7 +60,6 @@ Item { { width: UM.Theme.getSize("save_button_specs_icons").width; height: UM.Theme.getSize("save_button_specs_icons").height; - sourceSize.width: width; sourceSize.height: width; color: control.hovered ? UM.Theme.getColor("text_scene_hover") : UM.Theme.getColor("text_scene"); source: UM.Theme.getIcon("pencil"); @@ -124,7 +123,7 @@ Item { } height: UM.Theme.getSize("jobspecs_line").height verticalAlignment: Text.AlignVCenter - font: UM.Theme.getFont("small") + font: UM.Theme.getFont("default_bold") color: UM.Theme.getColor("text_scene") text: CuraApplication.getSceneBoundingBoxString } diff --git a/resources/qml/MainWindow/MainWindowHeader.qml b/resources/qml/MainWindow/MainWindowHeader.qml index 34936e9b5a..ae1c13d9c3 100644 --- a/resources/qml/MainWindow/MainWindowHeader.qml +++ b/resources/qml/MainWindow/MainWindowHeader.qml @@ -12,38 +12,13 @@ import QtGraphicalEffects 1.0 import "../Account" -Rectangle +Item { id: base implicitHeight: UM.Theme.getSize("main_window_header").height implicitWidth: UM.Theme.getSize("main_window_header").width - LinearGradient - { - anchors.fill: parent - start: Qt.point(0, 0) - end: Qt.point(parent.width, 0) - gradient: Gradient - { - GradientStop - { - position: 0.0 - color: UM.Theme.getColor("main_window_header_background") - } - GradientStop - { - position: 0.5 - color: UM.Theme.getColor("main_window_header_background_gradient") - } - GradientStop - { - position: 1.0 - color: UM.Theme.getColor("main_window_header_background") - } - } - } - Image { id: logo @@ -54,9 +29,6 @@ Rectangle source: UM.Theme.getImage("logo") width: UM.Theme.getSize("logo").width height: UM.Theme.getSize("logo").height - - sourceSize.width: width - sourceSize.height: height } Row diff --git a/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml new file mode 100644 index 0000000000..68c56c7c4b --- /dev/null +++ b/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml @@ -0,0 +1,39 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.0 + +import UM 1.3 as UM +import Cura 1.0 as Cura + +Item +{ + width: parent.width + height: childrenRect.height + + Label + { + id: header + text: catalog.i18nc("@header", "Configurations") + font: UM.Theme.getFont("large") + color: UM.Theme.getColor("text") + height: contentHeight + renderType: Text.NativeRendering + + anchors + { + left: parent.left + right: parent.right + } + } + + ConfigurationListView + { + anchors.top: header.bottom + anchors.topMargin: UM.Theme.getSize("default_margin").width + width: parent.width + + outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null + } +} \ No newline at end of file diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 7427b5ddff..6ac1e6a2ad 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -7,143 +7,129 @@ import QtQuick.Controls 2.0 import UM 1.2 as UM import Cura 1.0 as Cura -Rectangle +Button { id: configurationItem property var configuration: null - property var selected: false - signal activateConfiguration() + hoverEnabled: true - height: childrenRect.height - border.width: UM.Theme.getSize("default_lining").width - border.color: updateBorderColor() - color: selected ? UM.Theme.getColor("configuration_item_active") : UM.Theme.getColor("configuration_item") - property var textColor: selected ? UM.Theme.getColor("configuration_item_text_active") : UM.Theme.getColor("configuration_item_text") + height: background.height - function updateBorderColor() + background: Rectangle { - border.color = selected ? UM.Theme.getColor("configuration_item_border_active") : UM.Theme.getColor("configuration_item_border") - } + height: childrenRect.height + color: parent.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") + border.color: (parent.checked || parent.hovered) ? UM.Theme.getColor("primary") : UM.Theme.getColor("lining") + border.width: parent.checked ? UM.Theme.getSize("thick_lining").width : UM.Theme.getSize("default_lining").width + radius: UM.Theme.getSize("default_radius").width - Column - { - id: contentColumn - width: parent.width - padding: UM.Theme.getSize("default_margin").width - spacing: Math.round(UM.Theme.getSize("default_margin").height / 2) - - Row + Column { - id: extruderRow + id: contentColumn + width: parent.width + padding: UM.Theme.getSize("wide_margin").width + spacing: Math.round(UM.Theme.getSize("default_margin").height / 2) - width: parent.width - 2 * parent.padding - height: childrenRect.height - - spacing: UM.Theme.getSize("default_margin").width - - Repeater + Row { - id: repeater - height: childrenRect.height - model: configuration.extruderConfigurations - delegate: PrintCoreConfiguration + id: extruderRow + + anchors { - width: Math.round(parent.width / 2) - printCoreConfiguration: modelData - mainColor: textColor + left: parent.left + leftMargin: parent.padding + right: parent.right + rightMargin: parent.padding + } + height: childrenRect.height + + spacing: UM.Theme.getSize("default_margin").width + + Repeater + { + id: repeater + height: childrenRect.height + model: configuration.extruderConfigurations + delegate: PrintCoreConfiguration + { + width: Math.round(parent.width / 2) + printCoreConfiguration: modelData + } + } + } + + //Buildplate row separator + Rectangle + { + id: separator + + visible: buildplateInformation.visible + anchors + { + left: parent.left + leftMargin: parent.padding + right: parent.right + rightMargin: parent.padding + } + height: visible ? Math.round(UM.Theme.getSize("thick_lining").height / 2) : 0 + color: UM.Theme.getColor("text") + } + + Item + { + id: buildplateInformation + + anchors + { + left: parent.left + leftMargin: parent.padding + right: parent.right + rightMargin: parent.padding + } + height: childrenRect.height + visible: configuration.buildplateConfiguration != "" + + UM.RecolorImage + { + id: buildplateIcon + anchors.left: parent.left + width: UM.Theme.getSize("main_window_header_button_icon").width + height: UM.Theme.getSize("main_window_header_button_icon").height + source: UM.Theme.getIcon("buildplate") + color: UM.Theme.getColor("text") + } + + Label + { + id: buildplateLabel + anchors.left: buildplateIcon.right + anchors.verticalCenter: buildplateIcon.verticalCenter + anchors.leftMargin: Math.round(UM.Theme.getSize("default_margin").height / 2) + text: configuration.buildplateConfiguration + renderType: Text.NativeRendering + color: UM.Theme.getColor("text") } } } - //Buildplate row separator - Rectangle + Connections { - id: separator - - visible: buildplateInformation.visible - width: parent.width - 2 * parent.padding - height: visible ? Math.round(UM.Theme.getSize("thick_lining").height / 2) : 0 - color: textColor - } - - Item - { - id: buildplateInformation - width: parent.width - 2 * parent.padding - height: childrenRect.height - visible: configuration.buildplateConfiguration != "" - - UM.RecolorImage { - id: buildplateIcon - anchors.left: parent.left - width: UM.Theme.getSize("main_window_header_button_icon").width - height: UM.Theme.getSize("main_window_header_button_icon").height - sourceSize.width: width - sourceSize.height: height - source: UM.Theme.getIcon("buildplate") - color: textColor - } - - Label + target: Cura.MachineManager + onCurrentConfigurationChanged: { - id: buildplateLabel - anchors.left: buildplateIcon.right - anchors.verticalCenter: buildplateIcon.verticalCenter - anchors.leftMargin: Math.round(UM.Theme.getSize("default_margin").height / 2) - text: configuration.buildplateConfiguration - renderType: Text.NativeRendering - color: textColor + configurationItem.checked = Cura.MachineManager.matchesConfiguration(configuration) } } - } - MouseArea - { - id: mouse - anchors.fill: parent - onClicked: activateConfiguration() - cursorShape: Qt.PointingHandCursor - hoverEnabled: true - onEntered: + Component.onCompleted: { - parent.border.color = UM.Theme.getColor("configuration_item_border_hover") - if (configurationItem.selected == false) - { - configurationItem.color = UM.Theme.getColor("wide_lining") - } - } - onExited: - { - updateBorderColor() - if (configurationItem.selected == false) - { - configurationItem.color = UM.Theme.getColor("configuration_item") - } + configurationItem.checked = Cura.MachineManager.matchesConfiguration(configuration) } } - Connections + onClicked: { - target: Cura.MachineManager - onCurrentConfigurationChanged: { - configurationItem.selected = Cura.MachineManager.matchesConfiguration(configuration) - updateBorderColor() - } - } - - Component.onCompleted: - { - configurationItem.selected = Cura.MachineManager.matchesConfiguration(configuration) - updateBorderColor() - } - - onVisibleChanged: - { - if(visible) - { - // I cannot trigger function updateBorderColor() after visibility change - color = selected ? UM.Theme.getColor("configuration_item_active") : UM.Theme.getColor("configuration_item") - } + Cura.MachineManager.applyRemoteConfiguration(configuration) } } \ No newline at end of file diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index 210ff6057f..e7936b69d2 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -2,8 +2,7 @@ // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 +import QtQuick.Controls 2.3 import UM 1.2 as UM import Cura 1.0 as Cura @@ -12,9 +11,7 @@ Column { id: base property var outputDevice: null - property var computedHeight: container.height + configurationListHeading.height + 3 * padding height: childrenRect.height + 2 * padding - padding: UM.Theme.getSize("default_margin").width spacing: Math.round(UM.Theme.getSize("default_margin").height / 2) function forceModelUpdate() @@ -27,60 +24,60 @@ Column } } - Label - { - id: configurationListHeading - text: catalog.i18nc("@label:header configurations", "Available configurations") - font: UM.Theme.getFont("large") - width: parent.width - 2 * parent.padding - color: UM.Theme.getColor("configuration_item_text") - } - - Component - { - id: sectionHeading - Rectangle - { - height: childrenRect.height + UM.Theme.getSize("default_margin").height - Label - { - text: section - font: UM.Theme.getFont("default_bold") - color: UM.Theme.getColor("configuration_item_text") - } - } - } - ScrollView { id: container - width: parent.width - parent.padding - height: Math.min(configurationList.contentHeight, 350 * screenScaleFactor) + width: parent.width + readonly property int maximumHeight: 350 * screenScaleFactor + height: Math.round(Math.min(configurationList.height, maximumHeight)) + contentHeight: configurationList.height + clip: true - style: UM.Theme.styles.scrollview - __wheelAreaScrollSpeed: 75 // Scroll three lines in one scroll event + ScrollBar.vertical.policy: (configurationList.height > maximumHeight) ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff //The AsNeeded policy also hides it when the cursor is away, and we don't want that. + ScrollBar.vertical.background: Rectangle + { + implicitWidth: UM.Theme.getSize("scrollbar").width + radius: width / 2 + color: UM.Theme.getColor("scrollbar_background") + } + ScrollBar.vertical.contentItem: Rectangle + { + implicitWidth: UM.Theme.getSize("scrollbar").width + radius: width / 2 + color: UM.Theme.getColor(parent.pressed ? "scrollbar_handle_down" : parent.hovered ? "scrollbar_handle_hover" : "scrollbar_handle") + } + + ButtonGroup + { + buttons: configurationList.children + } ListView { id: configurationList spacing: Math.round(UM.Theme.getSize("default_margin").height / 2) - width: container.width + width: container.width - ((height > container.maximumHeight) ? container.ScrollBar.vertical.background.width : 0) //Make room for scroll bar if there is any. contentHeight: childrenRect.height + height: childrenRect.height section.property: "modelData.printerType" section.criteria: ViewSection.FullString - section.delegate: sectionHeading + section.delegate: Item + { + height: printerTypeLabel.height + UM.Theme.getSize("default_margin").height + Cura.PrinterTypeLabel + { + id: printerTypeLabel + text: Cura.MachineManager.getAbbreviatedMachineName(section) + } + } model: (outputDevice != null) ? outputDevice.uniqueConfigurations : [] + delegate: ConfigurationItem { - width: parent.width - UM.Theme.getSize("default_margin").width + width: parent.width configuration: modelData - onActivateConfiguration: - { - switchPopupState() - Cura.MachineManager.applyRemoteConfiguration(configuration) - } } } } diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml new file mode 100644 index 0000000000..1d086acc67 --- /dev/null +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -0,0 +1,203 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.0 +import QtQuick.Controls.Styles 1.4 + +import UM 1.2 as UM +import Cura 1.0 as Cura + + +/** + * Menu that allows you to select the configuration of the current printer, such + * as the nozzle sizes and materials in each extruder. + */ +Cura.ExpandableComponent +{ + id: base + + Cura.ExtrudersModel + { + id: extrudersModel + } + + UM.I18nCatalog + { + id: catalog + name: "cura" + } + + enum ConfigurationMethod + { + AUTO, + CUSTOM + } + + iconSource: expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") + headerItem: Item + { + // Horizontal list that shows the extruders + ListView + { + id: extrudersList + + orientation: ListView.Horizontal + anchors.fill: parent + model: extrudersModel + visible: base.enabled + + delegate: Item + { + height: parent.height + width: Math.round(ListView.view.width / extrudersModel.count) + + // Extruder icon. Shows extruder index and has the same color as the active material. + Cura.ExtruderIcon + { + id: extruderIcon + materialColor: model.color + extruderEnabled: model.enabled + height: parent.height + width: height + } + + // Label for the brand of the material + Label + { + id: brandNameLabel + + text: model.material_brand + elide: Text.ElideRight + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text_inactive") + renderType: Text.NativeRendering + + anchors + { + left: extruderIcon.right + leftMargin: UM.Theme.getSize("default_margin").width + right: parent.right + rightMargin: UM.Theme.getSize("default_margin").width + } + } + + // Label that shows the name of the material + Label + { + text: model.material + elide: Text.ElideRight + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + renderType: Text.NativeRendering + + anchors + { + left: extruderIcon.right + leftMargin: UM.Theme.getSize("default_margin").width + right: parent.right + rightMargin: UM.Theme.getSize("default_margin").width + top: brandNameLabel.bottom + } + } + } + } + } + + //Disable the menu if there are no materials, variants or build plates to change. + function updateEnabled() + { + var active_definition_id = Cura.MachineManager.activeMachine.definition.id; + var has_materials = Cura.ContainerManager.getContainerMetaDataEntry(active_definition_id, "has_materials"); + var has_variants = Cura.ContainerManager.getContainerMetaDataEntry(active_definition_id, "has_variants"); + var has_buildplates = Cura.ContainerManager.getContainerMetaDataEntry(active_definition_id, "has_variant_buildplates"); + base.enabled = has_materials || has_variants || has_buildplates; //Only let it drop down if there is any configuration that you could change. + } + + Connections + { + target: Cura.MachineManager + onGlobalContainerChanged: base.updateEnabled(); + } + Component.onCompleted: updateEnabled(); + + popupItem: Column + { + id: popupItem + width: base.width - 2 * UM.Theme.getSize("default_margin").width + height: implicitHeight //Required because ExpandableComponent will try to use this to determine the size of the background of the pop-up. + spacing: UM.Theme.getSize("default_margin").height + + property bool is_connected: false //If current machine is connected to a printer. Only evaluated upon making popup visible. + onVisibleChanged: + { + is_connected = Cura.MachineManager.activeMachineNetworkKey !== "" && Cura.MachineManager.printerConnected //Re-evaluate. + } + + property int configuration_method: is_connected ? ConfigurationMenu.ConfigurationMethod.AUTO : ConfigurationMenu.ConfigurationMethod.CUSTOM //Auto if connected to a printer at start-up, or Custom if not. + + Item + { + width: parent.width + height: childrenRect.height + AutoConfiguration + { + id: autoConfiguration + visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.AUTO + } + + CustomConfiguration + { + id: customConfiguration + visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.CUSTOM + } + } + + Rectangle + { + id: separator + visible: buttonBar.visible + x: -popupPadding + + width: base.width + height: UM.Theme.getSize("default_lining").height + + color: UM.Theme.getColor("lining") + } + + //Allow switching between custom and auto. + Item + { + id: buttonBar + visible: popupItem.is_connected //Switching only makes sense if the "auto" part is possible. + + width: parent.width + height: childrenRect.height + + Cura.SecondaryButton + { + id: goToCustom + visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.AUTO + text: catalog.i18nc("@label", "Custom") + + anchors.right: parent.right + + iconSource: UM.Theme.getIcon("arrow_right") + isIconOnRightSide: true + + onClicked: popupItem.configuration_method = ConfigurationMenu.ConfigurationMethod.CUSTOM + } + + Cura.SecondaryButton + { + id: goToAuto + visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.CUSTOM + text: catalog.i18nc("@label", "Configurations") + + iconSource: UM.Theme.getIcon("arrow_left") + + onClicked: popupItem.configuration_method = ConfigurationMenu.ConfigurationMethod.AUTO + } + } + } +} diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml new file mode 100644 index 0000000000..8d8f84155a --- /dev/null +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -0,0 +1,250 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.6 +import QtQuick.Controls 2.0 +import QtQuick.Controls 1.1 as OldControls + +import Cura 1.0 as Cura +import UM 1.3 as UM + +Item +{ + UM.I18nCatalog + { + id: catalog + name: "cura" + } + + width: parent.width + height: childrenRect.height + + Label + { + id: header + text: catalog.i18nc("@header", "Custom") + font: UM.Theme.getFont("large") + color: UM.Theme.getColor("text") + height: contentHeight + renderType: Text.NativeRendering + + anchors + { + top: parent.top + left: parent.left + right: parent.right + } + } + + UM.TabRow + { + id: tabBar + anchors.top: header.bottom + anchors.topMargin: UM.Theme.getSize("default_margin").height + visible: extrudersModel.count > 1 + + Repeater + { + id: repeater + model: extrudersModel + delegate: UM.TabRowButton + { + contentItem: Item + { + Cura.ExtruderIcon + { + anchors.horizontalCenter: parent.horizontalCenter + materialColor: model.color + extruderEnabled: model.enabled + width: parent.height + height: parent.height + } + } + onClicked: + { + Cura.ExtruderManager.setActiveExtruderIndex(tabBar.currentIndex) + } + } + } + + //When active extruder changes for some other reason, switch tabs. + //Don't directly link currentIndex to Cura.ExtruderManager.activeExtruderIndex! + //This causes a segfault in Qt 5.11. Something with VisualItemModel removing index -1. We have to use setCurrentIndex instead. + Connections + { + target: Cura.ExtruderManager + onActiveExtruderChanged: + { + tabBar.setCurrentIndex(Cura.ExtruderManager.activeExtruderIndex); + } + } + + //When the model of the extruders is rebuilt, the list of extruders is briefly emptied and rebuilt. + //This causes the currentIndex of the tab to be in an invalid position which resets it to 0. + //Therefore we need to change it back to what it was: The active extruder index. + Connections + { + target: repeater.model + onModelChanged: + { + tabBar.setCurrentIndex(Cura.ExtruderManager.activeExtruderIndex) + } + } + } + + Rectangle + { + width: parent.width + height: childrenRect.height + anchors.top: tabBar.bottom + + radius: tabBar.visible ? UM.Theme.getSize("default_radius").width : 0 + border.width: tabBar.visible ? UM.Theme.getSize("default_lining").width : 0 + border.color: UM.Theme.getColor("lining") + color: UM.Theme.getColor("main_background") + + //Remove rounding and lining at the top. + Rectangle + { + width: parent.width + height: parent.radius + anchors.top: parent.top + color: UM.Theme.getColor("lining") + visible: tabBar.visible + Rectangle + { + anchors + { + left: parent.left + leftMargin: parent.parent.border.width + right: parent.right + rightMargin: parent.parent.border.width + top: parent.top + } + height: parent.parent.radius + color: parent.parent.color + } + } + + Column + { + id: selectors + padding: UM.Theme.getSize("default_margin").width + spacing: UM.Theme.getSize("default_margin").height + + property var model: extrudersModel.items[tabBar.currentIndex] + + readonly property real paddedWidth: parent.width - padding * 2 + property real textWidth: Math.round(paddedWidth * 0.3) + property real controlWidth: paddedWidth - textWidth + + Row + { + height: UM.Theme.getSize("print_setup_item").height + + Label + { + text: catalog.i18nc("@label", "Enabled") + verticalAlignment: Text.AlignVCenter + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + height: parent.height + width: selectors.textWidth + visible: extrudersModel.count > 1 + renderType: Text.NativeRendering + } + + OldControls.CheckBox + { + checked: Cura.MachineManager.activeStack != null ? Cura.MachineManager.activeStack.isEnabled : false + enabled: !checked || Cura.MachineManager.numberExtrudersEnabled > 1 //Disable if it's the last enabled extruder. + height: UM.Theme.getSize("setting_control").height + style: UM.Theme.styles.checkbox + visible: extrudersModel.count > 1 + + /* Use a MouseArea to process the click on this checkbox. + This is necessary because actually clicking the checkbox + causes the "checked" property to be overwritten. After + it's been overwritten, the original link that made it + depend on the active extruder stack is broken. */ + MouseArea + { + anchors.fill: parent + onClicked: Cura.MachineManager.setExtruderEnabled(Cura.ExtruderManager.activeExtruderIndex, !parent.checked) + enabled: parent.enabled + } + } + } + + Row + { + height: UM.Theme.getSize("print_setup_item").height + Label + { + text: catalog.i18nc("@label", "Material") + verticalAlignment: Text.AlignVCenter + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + height: parent.height + width: selectors.textWidth + visible: materialSelection.visible + renderType: Text.NativeRendering + } + + OldControls.ToolButton + { + id: materialSelection + + property bool valueError: Cura.MachineManager.activeStack != null ? Cura.ContainerManager.getContainerMetaDataEntry(Cura.MachineManager.activeStack.material.id, "compatible", "") != "True" : true + property bool valueWarning: !Cura.MachineManager.isActiveQualitySupported + + text: Cura.MachineManager.activeStack != null ? Cura.MachineManager.activeStack.material.name : "" + tooltip: text + visible: Cura.MachineManager.hasMaterials + + height: UM.Theme.getSize("setting_control").height + width: selectors.controlWidth + + style: UM.Theme.styles.sidebar_header_button + activeFocusOnPress: true + menu: Cura.MaterialMenu + { + extruderIndex: Cura.ExtruderManager.activeExtruderIndex + } + } + } + + Row + { + height: UM.Theme.getSize("print_setup_item").height + + Label + { + text: Cura.MachineManager.activeDefinitionVariantsName + verticalAlignment: Text.AlignVCenter + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + height: parent.height + width: selectors.textWidth + visible: variantSelection.visible + renderType: Text.NativeRendering + } + + OldControls.ToolButton + { + id: variantSelection + text: Cura.MachineManager.activeVariantName + tooltip: Cura.MachineManager.activeVariantName; + visible: Cura.MachineManager.hasVariants + + height: UM.Theme.getSize("setting_control").height + width: selectors.controlWidth + style: UM.Theme.styles.sidebar_header_button + activeFocusOnPress: true; + + menu: Cura.NozzleMenu { extruderIndex: Cura.ExtruderManager.activeExtruderIndex } + } + } + } + } +} diff --git a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml index 73fc342d66..885f02d740 100644 --- a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml @@ -5,87 +5,50 @@ import QtQuick 2.7 import QtQuick.Controls 2.0 import UM 1.2 as UM +import Cura 1.0 as Cura - -Column +Row { id: extruderInfo property var printCoreConfiguration - property var mainColor: "black" - spacing: Math.round(UM.Theme.getSize("default_margin").height / 2) - height: childrenRect.height + height: information.height + spacing: UM.Theme.getSize("default_margin").width - Item + //Extruder icon. + Cura.ExtruderIcon { - id: extruder - width: parent.width - height: childrenRect.height + materialColor: printCoreConfiguration.material.color + anchors.verticalCenter: parent.verticalCenter + extruderEnabled: printCoreConfiguration.material.name !== "" && printCoreConfiguration.hotendID !== "" + } + Column + { + id: information Label { - id: extruderLabel - text: catalog.i18nc("@label:extruder label", "Extruder") + text: printCoreConfiguration.material.brand ? printCoreConfiguration.material.brand : " " //Use space so that the height is still correct. renderType: Text.NativeRendering elide: Text.ElideRight - anchors.left: parent.left font: UM.Theme.getFont("default") - color: mainColor + color: UM.Theme.getColor("text_inactive") } - - // Rounded item to show the extruder number - Item + Label { - id: extruderIconItem - anchors.verticalCenter: extruderLabel.verticalCenter - anchors.left: extruderLabel.right - anchors.leftMargin: Math.round(UM.Theme.getSize("default_margin").width / 2) - - width: UM.Theme.getSize("section_icon").width - height: UM.Theme.getSize("section_icon").height - - UM.RecolorImage { - id: mainCircle - anchors.fill: parent - - anchors.centerIn: parent - sourceSize.width: parent.width - sourceSize.height: parent.height - source: UM.Theme.getIcon("extruder_button") - color: mainColor - } - - Label - { - id: extruderNumberText - anchors.centerIn: parent - text: printCoreConfiguration.position + 1 - renderType: Text.NativeRendering - font: UM.Theme.getFont("default") - color: mainColor - } + text: printCoreConfiguration.material.name ? printCoreConfiguration.material.name : " " //Use space so that the height is still correct. + renderType: Text.NativeRendering + elide: Text.ElideRight + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + } + Label + { + text: printCoreConfiguration.hotendID ? printCoreConfiguration.hotendID : " " //Use space so that the height is still correct. + renderType: Text.NativeRendering + elide: Text.ElideRight + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text_inactive") } - } - - Label - { - id: materialLabel - text: printCoreConfiguration.material == null ? "" : printCoreConfiguration.material.name - renderType: Text.NativeRendering - elide: Text.ElideRight - width: parent.width - font: UM.Theme.getFont("default_bold") - color: mainColor - } - - Label - { - id: printCoreTypeLabel - text: printCoreConfiguration.hotendID - renderType: Text.NativeRendering - elide: Text.ElideRight - width: parent.width - font: UM.Theme.getFont("default") - color: mainColor } } diff --git a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml b/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml deleted file mode 100644 index eb6800cb36..0000000000 --- a/resources/qml/Menus/ConfigurationMenu/QuickConfigurationSelector.qml +++ /dev/null @@ -1,243 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.7 -import QtQuick.Controls 2.0 -import QtQuick.Controls.Styles 1.4 -import QtQuick.Layouts 1.3 - -import QtQuick.Controls 1.1 as OldControls - -import UM 1.2 as UM -import Cura 1.0 as Cura - - -Cura.ExpandableComponent -{ - id: base - - Cura.ExtrudersModel - { - id: extrudersModel - } - - UM.I18nCatalog - { - id: catalog - name: "cura" - } - - iconSource: expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") - headerItem: Item - { - // Horizontal list that shows the extruders - ListView - { - id: extrudersList - - orientation: ListView.Horizontal - anchors.fill: parent - model: extrudersModel - - delegate: Item - { - height: parent.height - width: Math.round(ListView.view.width / extrudersModel.rowCount()) - - // Extruder icon. Shows extruder index and has the same color as the active material. - Cura.ExtruderIcon - { - id: extruderIcon - materialColor: model.color - extruderEnabled: model.enabled - anchors.verticalCenter: parent.verticalCenter - } - - // Label for the brand of the material - Label - { - id: brandNameLabel - - text: model.material_brand - elide: Text.ElideRight - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - - anchors - { - left: extruderIcon.right - leftMargin: UM.Theme.getSize("default_margin").width - right: parent.right - rightMargin: UM.Theme.getSize("default_margin").width - } - } - - // Label that shows the name of the material - Label - { - text: model.material - elide: Text.ElideRight - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - - anchors - { - left: extruderIcon.right - leftMargin: UM.Theme.getSize("default_margin").width - right: parent.right - rightMargin: UM.Theme.getSize("default_margin").width - top: brandNameLabel.bottom - } - } - } - } - } - - popupItem: Item - { - width: base.width - 2 * UM.Theme.getSize("default_margin").width - height: 200 - - TabBar - { - id: tabBar - onCurrentIndexChanged: Cura.ExtruderManager.setActiveExtruderIndex(currentIndex) - width: parent.width - height: 50 - Repeater - { - model: extrudersModel - - delegate: TabButton - { - width: ListView.view != null ? Math.round(ListView.view.width / extrudersModel.rowCount()): 0 - height: parent.height - contentItem: Item - { - Cura.ExtruderIcon - { - anchors.horizontalCenter: parent.horizontalCenter - materialColor: model.color - extruderEnabled: model.enabled - width: parent.height - height: parent.height - } - } - } - } - } - - Item - { - id: tabControl - width: parent.width - anchors.top: tabBar.bottom - anchors.bottom: parent.bottom - property var model: extrudersModel.items[tabBar.currentIndex] - property real textWidth: Math.round(width * 0.3) - property real controlWidth: width - textWidth - Column - { - spacing: UM.Theme.getSize("default_margin").height - Row - { - height: UM.Theme.getSize("print_setup_item").height - - Label - { - text: catalog.i18nc("@label", "Enabled") - verticalAlignment: Text.AlignVCenter - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - height: parent.height - width: tabControl.textWidth - renderType: Text.NativeRendering - } - - OldControls.CheckBox - { - checked: tabControl.model != null ? Cura.MachineManager.getExtruder(tabControl.model.index).isEnabled: false - onClicked: Cura.MachineManager.setExtruderEnabled(tabControl.model.index, checked) - height: UM.Theme.getSize("setting_control").height - style: UM.Theme.styles.checkbox - } - } - - Row - { - height: UM.Theme.getSize("print_setup_item").height - Label - { - text: catalog.i18nc("@label", "Material") - verticalAlignment: Text.AlignVCenter - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - height: parent.height - width: tabControl.textWidth - renderType: Text.NativeRendering - } - - OldControls.ToolButton - { - id: materialSelection - - property var activeExtruder: Cura.MachineManager.activeStack - property var hasActiveExtruder: activeExtruder != null - property var currentRootMaterialName: hasActiveExtruder ? activeExtruder.material.name : "" - property var valueError: hasActiveExtruder ? Cura.ContainerManager.getContainerMetaDataEntry(activeExtruder.material.id, "compatible", "") != "True" : true - property var valueWarning: ! Cura.MachineManager.isActiveQualitySupported - - text: currentRootMaterialName - tooltip: currentRootMaterialName - visible: Cura.MachineManager.hasMaterials - - enabled: Cura.ExtruderManager.activeExtruderIndex > -1 - - height: UM.Theme.getSize("setting_control").height - width: tabControl.controlWidth - - style: UM.Theme.styles.sidebar_header_button - activeFocusOnPress: true - menu: Cura.MaterialMenu - { - extruderIndex: Cura.ExtruderManager.activeExtruderIndex - } - - } - } - - Row - { - height: UM.Theme.getSize("print_setup_item").height - - Label - { - text: Cura.MachineManager.activeDefinitionVariantsName - verticalAlignment: Text.AlignVCenter - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - height: parent.height - width: tabControl.textWidth - renderType: Text.NativeRendering - } - - OldControls.ToolButton - { - id: variantSelection - text: Cura.MachineManager.activeVariantName - tooltip: Cura.MachineManager.activeVariantName; - visible: Cura.MachineManager.hasVariants - - height: UM.Theme.getSize("setting_control").height - width: tabControl.controlWidth - style: UM.Theme.styles.sidebar_header_button - activeFocusOnPress: true; - - menu: Cura.NozzleMenu { extruderIndex: Cura.ExtruderManager.activeExtruderIndex } - } - } - } - - } - } -} diff --git a/resources/qml/Menus/ConfigurationMenu/SyncButton.qml b/resources/qml/Menus/ConfigurationMenu/SyncButton.qml deleted file mode 100644 index 558ae1e477..0000000000 --- a/resources/qml/Menus/ConfigurationMenu/SyncButton.qml +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.7 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 - -import UM 1.2 as UM -import Cura 1.0 as Cura - -Button -{ - id: base - property var outputDevice: null - property var matched: updateOnSync() - text: matched == true ? catalog.i18nc("@label:extruder label", "Yes") : catalog.i18nc("@label:extruder label", "No") - width: parent.width - height: parent.height - - function updateOnSync() - { - if (outputDevice != undefined) - { - for (var index in outputDevice.uniqueConfigurations) - { - var configuration = outputDevice.uniqueConfigurations[index] - if (Cura.MachineManager.matchesConfiguration(configuration)) - { - base.matched = true; - return; - } - } - } - base.matched = false; - } - - style: ButtonStyle - { - background: Rectangle - { - color: - { - if(control.pressed) - { - return UM.Theme.getColor("machine_selector_active"); - } - else if(control.hovered) - { - return UM.Theme.getColor("machine_selector_hover"); - } - else - { - return UM.Theme.getColor("machine_selector_bar"); - } - } - Behavior on color { ColorAnimation { duration: 50; } } - - UM.RecolorImage - { - id: downArrow - anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - anchors.rightMargin: UM.Theme.getSize("default_margin").width - width: UM.Theme.getSize("standard_arrow").width - height: UM.Theme.getSize("standard_arrow").height - sourceSize.width: width - sourceSize.height: height - color: UM.Theme.getColor("text_emphasis") - source: UM.Theme.getIcon("arrow_bottom") - } - UM.RecolorImage - { - id: sidebarComboBoxLabel - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("default_margin").width - anchors.verticalCenter: parent.verticalCenter; - - width: UM.Theme.getSize("printer_sync_icon").width - height: UM.Theme.getSize("printer_sync_icon").height - - color: control.matched ? UM.Theme.getColor("printer_config_matched") : UM.Theme.getColor("printer_config_mismatch") - source: UM.Theme.getIcon("tab_status_connected") - sourceSize.width: width - sourceSize.height: height - } - } - label: Label {} - } - - Connections - { - target: outputDevice - onUniqueConfigurationsChanged: updateOnSync() - } - - Connections - { - target: Cura.MachineManager - onCurrentConfigurationChanged: updateOnSync() - onOutputDevicesChanged: updateOnSync() - } -} \ No newline at end of file diff --git a/resources/qml/Menus/ProfileMenu.qml b/resources/qml/Menus/ProfileMenu.qml index fd46d2ef72..bf950aa409 100644 --- a/resources/qml/Menus/ProfileMenu.qml +++ b/resources/qml/Menus/ProfileMenu.qml @@ -37,7 +37,7 @@ Menu MenuSeparator { id: customSeparator - visible: Cura.CustomQualityProfilesDropDownMenuModel.rowCount > 0 + visible: Cura.CustomQualityProfilesDropDownMenuModel.count > 0 } Instantiator @@ -48,7 +48,7 @@ Menu Connections { target: Cura.CustomQualityProfilesDropDownMenuModel - onModelReset: customSeparator.visible = Cura.CustomQualityProfilesDropDownMenuModel.rowCount() > 0 + onModelReset: customSeparator.visible = Cura.CustomQualityProfilesDropDownMenuModel.count > 0 } MenuItem @@ -62,12 +62,12 @@ Menu onObjectAdded: { - customSeparator.visible = model.rowCount() > 0; + customSeparator.visible = model.count > 0; menu.insertItem(index, object); } onObjectRemoved: { - customSeparator.visible = model.rowCount() > 0; + customSeparator.visible = model.count > 0; menu.removeItem(object); } } diff --git a/resources/qml/ObjectsList.qml b/resources/qml/ObjectsList.qml index 8c8eaa16ae..8f45b3744f 100644 --- a/resources/qml/ObjectsList.qml +++ b/resources/qml/ObjectsList.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.2 @@ -55,7 +55,6 @@ Rectangle { width: control.width height: control.height - sourceSize.width: width sourceSize.height: width color: UM.Theme.getColor("setting_control_text") source: collapsed ? UM.Theme.getIcon("arrow_left") : UM.Theme.getIcon("arrow_bottom") diff --git a/resources/qml/Preferences/MachinesPage.qml b/resources/qml/Preferences/MachinesPage.qml index 4dc5465dc6..bc75b9bc72 100644 --- a/resources/qml/Preferences/MachinesPage.qml +++ b/resources/qml/Preferences/MachinesPage.qml @@ -21,8 +21,10 @@ UM.ManagementPage function activeMachineIndex() { - for(var i = 0; i < model.rowCount(); i++) { - if (model.getItem(i).id == Cura.MachineManager.activeMachineId) { + for(var i = 0; i < model.count; i++) + { + if (model.getItem(i).id == Cura.MachineManager.activeMachineId) + { return i; } } @@ -47,7 +49,7 @@ UM.ManagementPage { text: catalog.i18nc("@action:button", "Remove"); iconName: "list-remove"; - enabled: base.currentItem != null && model.rowCount() > 1 + enabled: base.currentItem != null && model.count > 1 onClicked: confirmDialog.open(); }, Button diff --git a/resources/qml/Preferences/Materials/MaterialsBrandSection.qml b/resources/qml/Preferences/Materials/MaterialsBrandSection.qml index c8f391dfb0..a3a0e4708f 100644 --- a/resources/qml/Preferences/Materials/MaterialsBrandSection.qml +++ b/resources/qml/Preferences/Materials/MaterialsBrandSection.qml @@ -55,7 +55,8 @@ Rectangle text: "" implicitWidth: UM.Theme.getSize("favorites_button").width implicitHeight: UM.Theme.getSize("favorites_button").height - UM.RecolorImage { + UM.RecolorImage + { anchors { verticalCenter: parent.verticalCenter @@ -63,8 +64,6 @@ Rectangle } width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height - sourceSize.width: width - sourceSize.height: height color: "black" source: brand_section.expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") } diff --git a/resources/qml/Preferences/Materials/MaterialsList.qml b/resources/qml/Preferences/Materials/MaterialsList.qml index 00bead9650..61f92db84c 100644 --- a/resources/qml/Preferences/Materials/MaterialsList.qml +++ b/resources/qml/Preferences/Materials/MaterialsList.qml @@ -57,7 +57,7 @@ Item var currentItemId = base.currentItem == null ? "" : base.currentItem.root_material_id search_root_id = currentItemId } - for (var material_idx = 0; material_idx < genericMaterialsModel.rowCount(); material_idx++) + for (var material_idx = 0; material_idx < genericMaterialsModel.count; material_idx++) { var material = genericMaterialsModel.getItem(material_idx) if (material.root_material_id == search_root_id) @@ -72,15 +72,15 @@ Item return true } } - for (var brand_idx = 0; brand_idx < materialsModel.rowCount(); brand_idx++) + for (var brand_idx = 0; brand_idx < materialsModel.count; brand_idx++) { var brand = materialsModel.getItem(brand_idx) var types_model = brand.material_types - for (var type_idx = 0; type_idx < types_model.rowCount(); type_idx++) + for (var type_idx = 0; type_idx < types_model.count; type_idx++) { var type = types_model.getItem(type_idx) var colors_model = type.colors - for (var material_idx = 0; material_idx < colors_model.rowCount(); material_idx++) + for (var material_idx = 0; material_idx < colors_model.count; material_idx++) { var material = colors_model.getItem(material_idx) if (material.root_material_id == search_root_id) diff --git a/resources/qml/Preferences/Materials/MaterialsSlot.qml b/resources/qml/Preferences/Materials/MaterialsSlot.qml index a5af17f47a..a706aaf2b9 100644 --- a/resources/qml/Preferences/Materials/MaterialsSlot.qml +++ b/resources/qml/Preferences/Materials/MaterialsSlot.qml @@ -95,8 +95,6 @@ Rectangle } width: UM.Theme.getSize("favorites_button_icon").width height: UM.Theme.getSize("favorites_button_icon").height - sourceSize.width: width - sourceSize.height: height color: { if (favorite_button.hovered) diff --git a/resources/qml/Preferences/Materials/MaterialsTypeSection.qml b/resources/qml/Preferences/Materials/MaterialsTypeSection.qml index f62fc4ee16..f98c19e0b3 100644 --- a/resources/qml/Preferences/Materials/MaterialsTypeSection.qml +++ b/resources/qml/Preferences/Materials/MaterialsTypeSection.qml @@ -74,8 +74,6 @@ Rectangle } width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height - sourceSize.width: width - sourceSize.height: height color: "black" source: material_type_section.expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") } diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index ba0c2848a5..d7ffbb3152 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -188,21 +188,27 @@ Item Connections { target: qualitiesModel - onItemsChanged: { + onItemsChanged: + { var toSelectItemName = base.currentItem == null ? "" : base.currentItem.name; - if (newQualityNameToSelect != "") { + if (newQualityNameToSelect != "") + { toSelectItemName = newQualityNameToSelect; } var newIdx = -1; // Default to nothing if nothing can be found - if (toSelectItemName != "") { + if (toSelectItemName != "") + { // Select the required quality name if given - for (var idx = 0; idx < qualitiesModel.rowCount(); ++idx) { + for (var idx = 0; idx < qualitiesModel.count; ++idx) + { var item = qualitiesModel.getItem(idx); - if (item.name == toSelectItemName) { + if (item.name == toSelectItemName) + { // Switch to the newly created profile if needed newIdx = idx; - if (base.toActivateNewQuality) { + if (base.toActivateNewQuality) + { // Activate this custom quality if required Cura.MachineManager.setQualityChangesGroup(item.quality_changes_group); } @@ -382,9 +388,11 @@ Item var selectedItemName = Cura.MachineManager.activeQualityOrQualityChangesName; // Select the required quality name if given - for (var idx = 0; idx < qualitiesModel.rowCount(); idx++) { + for (var idx = 0; idx < qualitiesModel.count; idx++) + { var item = qualitiesModel.getItem(idx); - if (item.name == selectedItemName) { + if (item.name == selectedItemName) + { currentIndex = idx; break; } diff --git a/resources/qml/Preferences/SettingVisibilityPage.qml b/resources/qml/Preferences/SettingVisibilityPage.qml index 2edbeee960..3f7571a170 100644 --- a/resources/qml/Preferences/SettingVisibilityPage.qml +++ b/resources/qml/Preferences/SettingVisibilityPage.qml @@ -50,7 +50,7 @@ UM.PreferencesPage { return Qt.Unchecked } - else if(definitionsModel.visibleCount == definitionsModel.rowCount(null)) + else if(definitionsModel.visibleCount == definitionsModel.count) { return Qt.Checked } diff --git a/resources/qml/PrinterOutput/ExtruderBox.qml b/resources/qml/PrinterOutput/ExtruderBox.qml index f5a1bd75c4..247bb3a27d 100644 --- a/resources/qml/PrinterOutput/ExtruderBox.qml +++ b/resources/qml/PrinterOutput/ExtruderBox.qml @@ -47,7 +47,7 @@ Item { id: extruderTargetTemperature text: Math.round(extruderModel.targetHotendTemperature) + "°C" - font: UM.Theme.getFont("small") + font: UM.Theme.getFont("default_bold") color: UM.Theme.getColor("text_inactive") anchors.right: parent.right anchors.rightMargin: UM.Theme.getSize("default_margin").width diff --git a/resources/qml/PrinterOutput/HeatedBedBox.qml b/resources/qml/PrinterOutput/HeatedBedBox.qml index 8c99814e02..33cf5cd1e2 100644 --- a/resources/qml/PrinterOutput/HeatedBedBox.qml +++ b/resources/qml/PrinterOutput/HeatedBedBox.qml @@ -35,7 +35,7 @@ Item { id: bedTargetTemperature text: printerModel != null ? printerModel.targetBedTemperature + "°C" : "" - font: UM.Theme.getFont("small") + font: UM.Theme.getFont("default_bold") color: UM.Theme.getColor("text_inactive") anchors.right: parent.right anchors.rightMargin: UM.Theme.getSize("default_margin").width diff --git a/resources/qml/PrinterOutput/OutputDeviceHeader.qml b/resources/qml/PrinterOutput/OutputDeviceHeader.qml index e6328546ef..16280eab5f 100644 --- a/resources/qml/PrinterOutput/OutputDeviceHeader.qml +++ b/resources/qml/PrinterOutput/OutputDeviceHeader.qml @@ -43,7 +43,7 @@ Item { id: outputDeviceAddressLabel text: (outputDevice != null && outputDevice.address != null) ? outputDevice.address : "" - font: UM.Theme.getFont("small") + font: UM.Theme.getFont("default_bold") color: UM.Theme.getColor("text_inactive") anchors.top: outputDeviceNameLabel.bottom anchors.left: parent.left @@ -54,7 +54,7 @@ Item { text: outputDevice != null ? "" : catalog.i18nc("@info:status", "The printer is not connected.") color: outputDevice != null && outputDevice.acceptsCommands ? UM.Theme.getColor("setting_control_text") : UM.Theme.getColor("setting_control_disabled_text") - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") wrapMode: Text.WordWrap anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("default_margin").width diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index 15cd773c90..95abfd6644 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -25,29 +25,52 @@ Cura.ExpandableComponent name: "cura" } - headerItem: Cura.IconLabel + headerItem: Item { - text: isNetworkPrinter ? Cura.MachineManager.activeMachineNetworkGroupName : Cura.MachineManager.activeMachineName - source: - { - if (isNetworkPrinter) - { - if (machineSelector.outputDevice != null && machineSelector.outputDevice.clusterSize > 1) - { - return UM.Theme.getIcon("printer_group") - } - return UM.Theme.getIcon("printer_single") - } - return "" - } - font: UM.Theme.getFont("medium") - color: UM.Theme.getColor("text") - iconSize: UM.Theme.getSize("machine_selector_icon").width + implicitHeight: icon.height UM.RecolorImage { id: icon + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + + source: + { + if (isNetworkPrinter) + { + if (machineSelector.outputDevice != null && machineSelector.outputDevice.clusterSize > 1) + { + return UM.Theme.getIcon("printer_group") + } + return UM.Theme.getIcon("printer_single") + } + return "" + } + width: UM.Theme.getSize("machine_selector_icon").width + height: width + + color: UM.Theme.getColor("machine_selector_printer_icon") + visible: source != "" + } + + Label + { + id: label + anchors.left: icon.visible ? icon.right : parent.left + anchors.right: parent.right + anchors.leftMargin: UM.Theme.getSize("thin_margin").width + anchors.verticalCenter: icon.verticalCenter + text: isNetworkPrinter ? Cura.MachineManager.activeMachineNetworkGroupName : Cura.MachineManager.activeMachineName + elide: Text.ElideRight + color: UM.Theme.getColor("text") + font: UM.Theme.getFont("medium") + renderType: Text.NativeRendering + } + + UM.RecolorImage + { anchors { bottom: parent.bottom @@ -59,9 +82,6 @@ Cura.ExpandableComponent width: UM.Theme.getSize("printer_status_icon").width height: UM.Theme.getSize("printer_status_icon").height - sourceSize.width: width - sourceSize.height: height - color: UM.Theme.getColor("primary") visible: isNetworkPrinter && isPrinterConnected diff --git a/resources/qml/PrinterSelector/MachineSelectorList.qml b/resources/qml/PrinterSelector/MachineSelectorList.qml index 445940ab50..d831f4eb5c 100644 --- a/resources/qml/PrinterSelector/MachineSelectorList.qml +++ b/resources/qml/PrinterSelector/MachineSelectorList.qml @@ -13,7 +13,7 @@ Column Label { - text: catalog.i18nc("@label", "Network connected printers") + text: catalog.i18nc("@label", "Connected printers") visible: networkedPrintersModel.items.length > 0 leftPadding: UM.Theme.getSize("default_margin").width height: visible ? contentHeight + 2 * UM.Theme.getSize("default_margin").height : 0 diff --git a/resources/qml/PrinterSelector/PrinterTypeLabel.qml b/resources/qml/PrinterTypeLabel.qml similarity index 95% rename from resources/qml/PrinterSelector/PrinterTypeLabel.qml rename to resources/qml/PrinterTypeLabel.qml index cd9f3b9743..7feae32e16 100644 --- a/resources/qml/PrinterSelector/PrinterTypeLabel.qml +++ b/resources/qml/PrinterTypeLabel.qml @@ -28,7 +28,7 @@ Item anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter renderType: Text.NativeRendering - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") } } \ No newline at end of file diff --git a/resources/qml/Settings/SettingCategory.qml b/resources/qml/Settings/SettingCategory.qml index aafe36c546..196b2d6b97 100644 --- a/resources/qml/Settings/SettingCategory.qml +++ b/resources/qml/Settings/SettingCategory.qml @@ -129,23 +129,26 @@ Button anchors.rightMargin: UM.Theme.getSize("default_margin").width width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height - sourceSize.width: width sourceSize.height: width color: { if (!base.enabled) { return UM.Theme.getColor("setting_category_disabled_text") - } else if ((base.hovered || base.activeFocus) && base.checkable && base.checked) + } + else if ((base.hovered || base.activeFocus) && base.checkable && base.checked) { return UM.Theme.getColor("setting_category_active_hover_text") - } else if (base.pressed || (base.checkable && base.checked)) + } + else if (base.pressed || (base.checkable && base.checked)) { return UM.Theme.getColor("setting_category_active_text") - } else if (base.hovered || base.activeFocus) + } + else if (base.hovered || base.activeFocus) { return UM.Theme.getColor("setting_category_hover_text") - } else + } + else { return UM.Theme.getColor("setting_category_text") } diff --git a/resources/qml/Settings/SettingCheckBox.qml b/resources/qml/Settings/SettingCheckBox.qml index d37754d27c..fb2d5a2f4d 100644 --- a/resources/qml/Settings/SettingCheckBox.qml +++ b/resources/qml/Settings/SettingCheckBox.qml @@ -115,12 +115,12 @@ SettingItem return UM.Theme.getColor("setting_control_border") } - UM.RecolorImage { + UM.RecolorImage + { anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter width: Math.round(parent.width / 2.5) height: Math.round(parent.height / 2.5) - sourceSize.width: width sourceSize.height: width color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text"); source: UM.Theme.getIcon("check") diff --git a/resources/qml/Settings/SettingOptionalExtruder.qml b/resources/qml/Settings/SettingOptionalExtruder.qml index a3c1422b30..5f0d8327f8 100644 --- a/resources/qml/Settings/SettingOptionalExtruder.qml +++ b/resources/qml/Settings/SettingOptionalExtruder.qml @@ -1,5 +1,5 @@ -// Copyright (c) 2016 Ultimaker B.V. -// Uranium is released under the terms of the LGPLv3 or higher. +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 import QtQuick.Controls 2.0 @@ -31,12 +31,15 @@ SettingItem { forceActiveFocus(); propertyProvider.setPropertyValue("value", model.getItem(index).index); - } else + } + else { if (propertyProvider.properties.value == -1) { - control.currentIndex = model.rowCount() - 1; // we know the last item is "Not overriden" - } else { + control.currentIndex = model.count - 1; // we know the last item is "Not overriden" + } + else + { control.currentIndex = propertyProvider.properties.value; // revert to the old value } } diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index ef1f123953..bb624bcbde 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -1,5 +1,5 @@ -// Copyright (c) 2017 Ultimaker B.V. -// Uranium is released under the terms of the LGPLv3 or higher. +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 import QtQuick.Controls 1.1 @@ -129,13 +129,14 @@ Item } style: ButtonStyle { - background: Item { - UM.RecolorImage { + background: Item + { + UM.RecolorImage + { anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height - sourceSize.width: width sourceSize.height: width color: control.enabled ? UM.Theme.getColor("setting_category_text") : UM.Theme.getColor("setting_category_disabled_text") source: UM.Theme.getIcon("menu") diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index 5e723a3d70..fb4d52979d 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -106,7 +106,7 @@ Item var availableMin = -1 var availableMax = -1 - for (var i = 0; i < Cura.QualityProfilesDropDownMenuModel.rowCount(); i++) + for (var i = 0; i < Cura.QualityProfilesDropDownMenuModel.count; i++) { var qualityItem = Cura.QualityProfilesDropDownMenuModel.getItem(i) @@ -183,7 +183,7 @@ Item qualityModel.existingQualityProfile = 0 // check, the ticks count cannot be less than zero - qualityModel.totalTicks = Math.max(0, Cura.QualityProfilesDropDownMenuModel.rowCount() - 1) + qualityModel.totalTicks = Math.max(0, Cura.QualityProfilesDropDownMenuModel.count - 1) } } @@ -731,7 +731,6 @@ Item { anchors.fill: parent anchors.margins: 2 * screenScaleFactor - sourceSize.width: width sourceSize.height: width source: UM.Theme.getIcon(model.icon) color: UM.Theme.getColor("quality_slider_unavailable") @@ -1156,7 +1155,7 @@ Item function populateExtruderModel() { extruderModel.clear(); - for(var extruderNumber = 0; extruderNumber < extruders.rowCount() ; extruderNumber++) + for(var extruderNumber = 0; extruderNumber < extruders.count; extruderNumber++) { extruderModel.append({ text: extruders.getItem(extruderNumber).name, diff --git a/resources/qml/Toolbar.qml b/resources/qml/Toolbar.qml index 5fbddea9ac..1e335472d4 100644 --- a/resources/qml/Toolbar.qml +++ b/resources/qml/Toolbar.qml @@ -62,7 +62,7 @@ Item enabled: model.enabled && UM.Selection.hasSelection && UM.Controller.toolsEnabled isTopElement: toolsModel.getItem(0).id == model.id - isBottomElement: toolsModel.getItem(toolsModel.rowCount() - 1).id == model.id + isBottomElement: toolsModel.getItem(toolsModel.count - 1).id == model.id toolItem: UM.RecolorImage { diff --git a/resources/qml/ViewsSelector.qml b/resources/qml/ViewsSelector.qml index e9fdd57177..1e42a0b3ba 100644 --- a/resources/qml/ViewsSelector.qml +++ b/resources/qml/ViewsSelector.qml @@ -19,7 +19,7 @@ Cura.ExpandableComponent property var activeView: { - for (var i = 0; i < viewModel.rowCount(); i++) + for (var i = 0; i < viewModel.count; i++) { if (viewModel.items[i].active) { @@ -74,6 +74,8 @@ Cura.ExpandableComponent { id: viewSelectorPopup width: viewSelector.width - 2 * viewSelector.popupPadding + leftPadding: UM.Theme.getSize("default_lining").width + rightPadding: UM.Theme.getSize("default_lining").width // For some reason the height/width of the column gets set to 0 if this is not set... Component.onCompleted: @@ -91,7 +93,7 @@ Cura.ExpandableComponent { id: viewsSelectorButton text: model.name - width: parent.width + width: parent.width - viewSelectorPopup.leftPadding - viewSelectorPopup.rightPadding height: UM.Theme.getSize("action_button").height leftPadding: UM.Theme.getSize("default_margin").width rightPadding: UM.Theme.getSize("default_margin").width diff --git a/resources/qml/qmldir b/resources/qml/qmldir index 2475f398f8..7e57119bc6 100644 --- a/resources/qml/qmldir +++ b/resources/qml/qmldir @@ -1,7 +1,6 @@ module Cura MachineSelector 1.0 MachineSelector.qml -QuickConfigurationSelector 1.0 QuickConfigurationSelector.qml CustomConfigurationSelector 1.0 CustomConfigurationSelector.qml PrintSetupSelector 1.0 PrintSetupSelector.qml ActionButton 1.0 ActionButton.qml diff --git a/resources/themes/cura-dark/theme.json b/resources/themes/cura-dark/theme.json index 34b944b25b..d9ef74ebb9 100644 --- a/resources/themes/cura-dark/theme.json +++ b/resources/themes/cura-dark/theme.json @@ -15,7 +15,7 @@ "primary_hover": [48, 182, 231, 255], "primary_text": [255, 255, 255, 204], "border": [127, 127, 127, 255], - "secondary": [241, 242, 242, 255], + "secondary": [95, 95, 95, 255], "main_window_header_button_text_inactive": [128, 128, 128, 255], "main_window_header_button_text_hovered": [255, 255, 255, 255], @@ -196,14 +196,6 @@ "layerview_support_interface": [64, 192, 255, 255], "layerview_nozzle": [181, 166, 66, 120], - "configuration_item": [0, 0, 0, 0], - "configuration_item_active": [12, 169, 227, 179], - "configuration_item_text": [255, 255, 255, 255], - "configuration_item_text_active": [255, 255, 255, 255], - "configuration_item_border": [255, 255, 255, 255], - "configuration_item_border_active": [12, 169, 227, 179], - "configuration_item_border_hover": [12, 169, 227, 179], - "material_compatibility_warning": [255, 255, 255, 255], "quality_slider_unavailable": [179, 179, 179, 255], diff --git a/resources/themes/cura-light/images/header_pattern.svg b/resources/themes/cura-light/images/header_pattern.svg index 2a9de2f3e9..eff5f01cfa 100644 --- a/resources/themes/cura-light/images/header_pattern.svg +++ b/resources/themes/cura-light/images/header_pattern.svg @@ -1 +1,1901 @@ -Pattern \ No newline at end of file + + + + Desktop HD + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/themes/cura-light/images/logo_about.svg b/resources/themes/cura-light/images/logo_about.svg new file mode 100644 index 0000000000..34301fd6c9 --- /dev/null +++ b/resources/themes/cura-light/images/logo_about.svg @@ -0,0 +1,172 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index f2ad2b6f4a..30cf42859a 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -73,7 +73,6 @@ QtObject anchors.rightMargin: Theme.getSize("default_margin").width width: Theme.getSize("standard_arrow").width height: Theme.getSize("standard_arrow").height - sourceSize.width: width sourceSize.height: width color: control.enabled ? Theme.getColor("setting_category_text") : Theme.getColor("setting_category_disabled_text") source: Theme.getIcon("arrow_bottom") @@ -146,7 +145,7 @@ QtObject text: control.text anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter - font: UM.Theme.getFont("medium_bold") + font: UM.Theme.getFont("medium") color: { if (control.checked) @@ -257,7 +256,6 @@ QtObject anchors.bottomMargin: Theme.getSize("button").height - Math.round(Theme.getSize("button_icon").height / 4) width: Theme.getSize("standard_arrow").width height: Theme.getSize("standard_arrow").height - sourceSize.width: width sourceSize.height: width visible: control.menu != null; color: @@ -529,7 +527,7 @@ QtObject implicitWidth: Theme.getSize("checkbox").width implicitHeight: Theme.getSize("checkbox").height - color: (control.hovered || control._hovered) ? Theme.getColor("checkbox_hover") : Theme.getColor("checkbox") + color: (control.hovered || control._hovered) ? Theme.getColor("checkbox_hover") : (control.enabled ? Theme.getColor("checkbox") : Theme.getColor("checkbox_disabled")) Behavior on color { ColorAnimation { duration: 50; } } radius: control.exclusiveGroup ? Math.round(Theme.getSize("checkbox").width / 2) : 0 @@ -543,7 +541,6 @@ QtObject anchors.horizontalCenter: parent.horizontalCenter width: Math.round(parent.width / 2.5) height: Math.round(parent.height / 2.5) - sourceSize.width: width sourceSize.height: width color: Theme.getColor("checkbox_mark") source: control.exclusiveGroup ? Theme.getIcon("dot") : Theme.getIcon("check") @@ -585,7 +582,6 @@ QtObject anchors.horizontalCenter: parent.horizontalCenter width: Math.round(parent.width / 2.5) height: Math.round(parent.height / 2.5) - sourceSize.width: width sourceSize.height: width color: Theme.getColor("checkbox_mark") source: @@ -836,7 +832,6 @@ QtObject anchors.horizontalCenter: parent.horizontalCenter width: Math.floor(control.width / 2) height: Math.floor(control.height / 2) - sourceSize.width: width sourceSize.height: width color: { diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index dfad5cfd17..2d7e92be4d 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -41,12 +41,12 @@ "family": "Noto Sans" }, "small": { - "size": 1.0, - "weight": 63, + "size": 0.85, + "weight": 50, "family": "Noto Sans" }, "very_small": { - "size": 1.0, + "size": 0.7, "weight": 50, "family": "Noto Sans" }, @@ -64,12 +64,6 @@ "size": 1.15, "weight": 50, "family": "Noto Sans" - }, - "extruder_icon": - { - "size": 0.7, - "weight": 50, - "family": "Noto Sans" } }, @@ -99,14 +93,14 @@ "secondary_button_hover": [228, 228, 228, 255], "secondary_button_text": [30, 102, 215, 255], - "main_window_header_background": [10, 8, 80, 255], + "main_window_header_background": [8, 7, 63, 255], "main_window_header_background_gradient": [25, 23, 91, 255], - "main_window_header_button_text_active": [10, 8, 80, 255], + "main_window_header_button_text_active": [8, 7, 63, 255], "main_window_header_button_text_inactive": [255, 255, 255, 255], "main_window_header_button_text_hovered": [255, 255, 255, 255], "main_window_header_button_background_active": [255, 255, 255, 255], "main_window_header_button_background_inactive": [255, 255, 255, 0], - "main_window_header_button_background_hovered": [255, 255, 255, 102], + "main_window_header_button_background_hovered": [117, 114, 159, 255], "account_widget_outline_active": [70, 66, 126, 255], @@ -114,12 +108,13 @@ "machine_selector_active": [68, 72, 75, 255], "machine_selector_hover": [68, 72, 75, 255], "machine_selector_text_active": [255, 255, 255, 255], + "machine_selector_printer_icon": [8, 7, 63, 255], "action_panel_secondary": [27, 95, 202, 255], "toolbar_background": [255, 255, 255, 255], - "printer_type_label_background": [171, 171, 191, 255], + "printer_type_label_background": [228, 228, 242, 255], "text": [0, 0, 0, 255], "text_detail": [174, 174, 174, 128], @@ -133,9 +128,9 @@ "text_scene_hover": [70, 84, 113, 255], "error": [255, 140, 0, 255], - "warning": [255, 190, 35, 255], + "warning": [245, 166, 35, 255], - "toolbar_button_text": [10, 8, 80, 255], + "toolbar_button_text": [8, 7, 63, 255], "toolbar_button_hover": [232, 242, 252, 255], "toolbar_button_active": [232, 242, 252, 255], "toolbar_button_active_hover": [232, 242, 252, 255], @@ -150,9 +145,9 @@ "button_text_active_hover": [255, 255, 255, 255], "small_button": [0, 0, 0, 0], - "small_button_hover": [10, 8, 80, 255], - "small_button_active": [10, 8, 80, 255], - "small_button_active_hover": [10, 8, 80, 255], + "small_button_hover": [8, 7, 63, 255], + "small_button_active": [8, 7, 63, 255], + "small_button_active_hover": [8, 7, 63, 255], "small_button_text": [171, 171, 191, 255], "small_button_text_hover": [255, 255, 255, 255], "small_button_text_active": [255, 255, 255, 255], @@ -228,8 +223,8 @@ "progressbar_control": [50, 130, 255, 255], "slider_groove": [223, 223, 223, 255], - "slider_groove_fill": [10, 8, 80, 255], - "slider_handle": [10, 8, 80, 255], + "slider_groove_fill": [8, 7, 63, 255], + "slider_handle": [8, 7, 63, 255], "slider_handle_active": [50, 130, 255, 255], "slider_text_background": [255, 255, 255, 255], @@ -241,6 +236,7 @@ "checkbox_border": [64, 69, 72, 255], "checkbox_border_hover": [50, 130, 255, 255], "checkbox_mark": [119, 122, 124, 255], + "checkbox_disabled": [223, 223, 223, 255], "checkbox_text": [27, 27, 27, 255], "tooltip": [68, 192, 255, 255], @@ -310,14 +306,6 @@ "layerview_support_interface": [64, 192, 255, 255], "layerview_nozzle": [181, 166, 66, 50], - "configuration_item": [255, 255, 255, 0], - "configuration_item_active": [12, 169, 227, 32], - "configuration_item_text": [0, 0, 0, 255], - "configuration_item_text_active": [0, 0, 0, 255], - "configuration_item_border": [127, 127, 127, 255], - "configuration_item_border_active": [12, 169, 227, 32], - "configuration_item_border_hover": [50, 130, 255, 255], - "tab_status_connected": [50, 130, 255, 255], "tab_status_disconnected": [200, 200, 200, 255], @@ -377,7 +365,6 @@ "action_panel_widget": [25.0, 0.0], "action_panel_information_widget": [20.0, 0.0], - "action_panel_button": [15.0, 3.0], "machine_selector_widget": [20.0, 4.0], "machine_selector_widget_content": [25.0, 32.0], @@ -423,6 +410,9 @@ "button_icon": [2.5, 2.5], "button_lining": [0, 0], + "action_button": [15.0, 3.0], + "action_button_radius": [0.15, 0.15], + "small_button": [2, 2], "small_button_icon": [1.5, 1.5], @@ -511,9 +501,6 @@ "avatar_image": [6.8, 6.8], - "action_button": [15.0, 3.0], - "action_button_radius": [0.15, 0.15], - "monitor_config_override_box": [1.0, 14.0], "monitor_extruder_circle": [2.75, 2.75], "monitor_text_line": [1.16, 1.16], From 677edd51eea2ba87392851b2a5d01402e133e459 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 7 Dec 2018 10:55:20 +0100 Subject: [PATCH 0759/1292] Remove unnecessary visibles CURA-5941 Because the parent Rows already have it set. --- resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml | 3 --- 1 file changed, 3 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index eb8c81f228..ec9c5d0e38 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -151,7 +151,6 @@ Item color: UM.Theme.getColor("text") height: parent.height width: selectors.textWidth - visible: extrudersModel.count > 1 renderType: Text.NativeRendering } @@ -189,7 +188,6 @@ Item color: UM.Theme.getColor("text") height: parent.height width: selectors.textWidth - visible: materialSelection.visible renderType: Text.NativeRendering } @@ -228,7 +226,6 @@ Item color: UM.Theme.getColor("text") height: parent.height width: selectors.textWidth - visible: variantSelection.visible renderType: Text.NativeRendering } From da052fbe81eb8fc5c03049e867d0d8417146aff9 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 7 Dec 2018 11:21:25 +0100 Subject: [PATCH 0760/1292] Not show a tooltip in the output device selector when the popup shows up --- resources/qml/ActionPanel/OutputDevicesActionButton.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/ActionPanel/OutputDevicesActionButton.qml b/resources/qml/ActionPanel/OutputDevicesActionButton.qml index 95750e6d11..9a6c97bcff 100644 --- a/resources/qml/ActionPanel/OutputDevicesActionButton.qml +++ b/resources/qml/ActionPanel/OutputDevicesActionButton.qml @@ -55,7 +55,7 @@ Item leftPadding: UM.Theme.getSize("narrow_margin").width //Need more space than usual here for wide text. rightPadding: UM.Theme.getSize("narrow_margin").width - tooltip: catalog.i18nc("@info:tooltip", "Select the active output device") + tooltip: popup.opened ? "" : catalog.i18nc("@info:tooltip", "Select the active output device") iconSource: popup.opened ? UM.Theme.getIcon("arrow_top") : UM.Theme.getIcon("arrow_bottom") color: UM.Theme.getColor("action_panel_secondary") visible: (devicesModel.deviceCount > 1) From 898fd25ddb456a3dcfba6900e2ff03d5843fb5f9 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 7 Dec 2018 11:43:41 +0100 Subject: [PATCH 0761/1292] Remove the component IconLabel since we have a similar one in IconWithText Contributes to CURA-5941. --- .../qml/ActionPanel/OutputProcessWidget.qml | 5 +- .../qml/ActionPanel/SliceProcessWidget.qml | 3 +- resources/qml/IconLabel.qml | 50 ------------------- resources/qml/IconWithText.qml | 6 ++- .../PrintSetupSelectorHeader.qml | 1 - resources/qml/qmldir | 1 - 6 files changed, 7 insertions(+), 59 deletions(-) delete mode 100644 resources/qml/IconLabel.qml diff --git a/resources/qml/ActionPanel/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml index 1d1a1e44e1..3f53abf28f 100644 --- a/resources/qml/ActionPanel/OutputProcessWidget.qml +++ b/resources/qml/ActionPanel/OutputProcessWidget.qml @@ -44,7 +44,7 @@ Column rightMargin: UM.Theme.getSize("thin_margin").height } - Cura.IconLabel + Cura.IconWithText { id: estimatedTime width: parent.width @@ -54,7 +54,7 @@ Column font: UM.Theme.getFont("default_bold") } - Cura.IconLabel + Cura.IconWithText { id: estimatedCosts width: parent.width @@ -84,7 +84,6 @@ Column return totalWeights + "g · " + totalLengths.toFixed(2) + "m" } source: UM.Theme.getIcon("spool") - font: UM.Theme.getFont("default") } } diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index 8f6608e15c..18caeafb40 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -52,7 +52,7 @@ Column renderType: Text.NativeRendering } - Cura.IconLabel + Cura.IconWithText { id: unableToSliceMessage width: parent.width @@ -61,7 +61,6 @@ Column text: catalog.i18nc("@label:PrintjobStatus", "Unable to Slice") source: UM.Theme.getIcon("warning") color: UM.Theme.getColor("warning") - font: UM.Theme.getFont("default") } // Progress bar, only visible when the backend is in the process of slice the printjob diff --git a/resources/qml/IconLabel.qml b/resources/qml/IconLabel.qml deleted file mode 100644 index ed41fba499..0000000000 --- a/resources/qml/IconLabel.qml +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.7 -import QtQuick.Controls 2.3 - -import UM 1.1 as UM - -// This item will show a label with a squared icon in the left -Item -{ - id: container - - property alias text: label.text - property alias source: icon.source - property alias color: label.color - property alias font: label.font - property alias iconSize: icon.width - - implicitHeight: icon.height - - UM.RecolorImage - { - id: icon - - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - - source: "" - width: UM.Theme.getSize("section_icon").width - height: width - - color: label.color - visible: source != "" - } - - Label - { - id: label - anchors.left: icon.visible ? icon.right : parent.left - anchors.right: parent.right - anchors.leftMargin: UM.Theme.getSize("thin_margin").width - anchors.verticalCenter: icon.verticalCenter - text: "Empty label" - elide: Text.ElideRight - color: UM.Theme.getColor("text") - font: UM.Theme.getFont("default") - renderType: Text.NativeRendering - } -} \ No newline at end of file diff --git a/resources/qml/IconWithText.qml b/resources/qml/IconWithText.qml index 22599b3aed..5530740040 100644 --- a/resources/qml/IconWithText.qml +++ b/resources/qml/IconWithText.qml @@ -13,9 +13,11 @@ import Cura 1.0 as Cura // It sets the icon size + half of the content as its minium width (in which case it will elide the text) Item { - property alias iconColor: icon.color property alias source: icon.source + property alias iconSize: icon.width + property alias color: label.color property alias text: label.text + property alias font: label.font property real margin: UM.Theme.getSize("narrow_margin").width @@ -37,7 +39,7 @@ Item width: UM.Theme.getSize("section_icon").width height: UM.Theme.getSize("section_icon").height - color: "black" + color: label.color anchors { diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml index d4057289f6..518f3d49eb 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml @@ -43,7 +43,6 @@ RowLayout source: UM.Theme.getIcon("category_support") text: supportEnabled.properties.value == "True" ? enabledText : disabledText - UM.SettingPropertyProvider { id: supportEnabled diff --git a/resources/qml/qmldir b/resources/qml/qmldir index c19b982318..1dc21150ce 100644 --- a/resources/qml/qmldir +++ b/resources/qml/qmldir @@ -7,7 +7,6 @@ ActionButton 1.0 ActionButton.qml MaterialMenu 1.0 MaterialMenu.qml NozzleMenu 1.0 NozzleMenu.qml ActionPanelWidget 1.0 ActionPanelWidget.qml -IconLabel 1.0 IconLabel.qml IconWithText 1.0 IconWithText.qml OutputDevicesActionButton 1.0 OutputDevicesActionButton.qml ExpandableComponent 1.0 ExpandableComponent.qml From 4f82a2759ad78a00b60c5008e78877830c38f2d7 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 7 Dec 2018 12:04:02 +0100 Subject: [PATCH 0762/1292] STAR-322: Improving configuration models interface --- .../NetworkedPrinterOutputDevice.py | 11 +- .../src/Cloud/CloudOutputDevice.py | 360 ++++++++++-------- .../src/Cloud/Models/CloudClusterPrintJob.py | 24 +- .../src/Cloud/Models/CloudClusterPrinter.py | 9 +- .../CloudClusterPrinterConfiguration.py | 19 +- plugins/UM3NetworkPrinting/src/Cloud/Utils.py | 27 ++ .../src/ClusterUM3OutputDevice.py | 11 +- 7 files changed, 278 insertions(+), 183 deletions(-) diff --git a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py index 300ed5194d..b0c8b54a67 100644 --- a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py +++ b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py @@ -4,6 +4,7 @@ from UM.FileHandler.FileHandler import FileHandler #For typing. from UM.Logger import Logger from UM.Scene.SceneNode import SceneNode #For typing. +from cura.API import Account from cura.CuraApplication import CuraApplication from cura.PrinterOutputDevice import PrinterOutputDevice, ConnectionState @@ -162,9 +163,15 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): part.setBody(data) return part - ## Convenience function to get the username from the OS. - # The code was copied from the getpass module, as we try to use as little dependencies as possible. + ## Convenience function to get the username, either from the cloud or from the OS. def _getUserName(self) -> str: + # check first if we are logged in with the Ultimaker Account + account = CuraApplication.getInstance().getCuraAPI().account # type: Account + if account and account.isLoggedIn: + return account.userName + + # Otherwise get the username from the US + # The code below was copied from the getpass module, as we try to use as little dependencies as possible. for name in ("LOGNAME", "USER", "LNAME", "USERNAME"): user = os.environ.get(name) if user: diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 9f5857dff6..3bc16cbfb0 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -16,7 +16,6 @@ from UM.Qt.Duration import Duration, DurationFormat from UM.Scene.SceneNode import SceneNode from cura.CuraApplication import CuraApplication from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState, NetworkedPrinterOutputDevice -from cura.PrinterOutput.PrinterOutputController import PrinterOutputController from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputController import CloudOutputController from ..MeshFormatHandler import MeshFormatHandler @@ -28,7 +27,7 @@ from .Models.CloudPrintResponse import CloudPrintResponse from .Models.CloudJobResponse import CloudJobResponse from .Models.CloudClusterPrinter import CloudClusterPrinter from .Models.CloudClusterPrintJob import CloudClusterPrintJob -from .Utils import findChanges +from .Utils import findChanges, formatDateCompleted, formatTimeCompleted ## Class that contains all the translations for this module. @@ -55,6 +54,12 @@ class T: UPLOAD_SUCCESS_TITLE = _I18N_CATALOG.i18nc("@info:title", "Data Sent") UPLOAD_SUCCESS_TEXT = _I18N_CATALOG.i18nc("@info:status", "Print job was successfully sent to the printer.") + JOB_COMPLETED_TITLE = _I18N_CATALOG.i18nc("@info:status", "Print finished") + JOB_COMPLETED_PRINTER = _I18N_CATALOG.i18nc("@info:status", + "Printer '{printer_name}' has finished printing '{job_name}'.") + + JOB_COMPLETED_NO_PRINTER = _I18N_CATALOG.i18nc("@info:status", "The print job '{job_name}' was finished.") + ## The cloud output device is a network output device that works remotely but has limited functionality. # Currently it only supports viewing the printer and print job status and adding a new job to the queue. @@ -65,7 +70,7 @@ class T: class CloudOutputDevice(NetworkedPrinterOutputDevice): # The interval with which the remote clusters are checked - CHECK_CLUSTER_INTERVAL = 2.0 # seconds + CHECK_CLUSTER_INTERVAL = 4.0 # seconds # Signal triggered when the print jobs in the queue were changed. printJobsChanged = pyqtSignal() @@ -109,6 +114,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # We only allow a single upload at a time. self._sending_job = False + # TODO: handle progress messages in another class. self._progress_message = None # type: Optional[Message] ## Gets the host name of this device @@ -128,7 +134,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): return network_key.startswith(self._host_name) ## Set all the interface elements and texts for this output device. - def _setInterfaceElements(self): + def _setInterfaceElements(self) -> None: self.setPriority(2) # make sure we end up below the local networking and above 'save to file' self.setName(self._id) self.setShortDescription(T.PRINT_VIA_CLOUD_BUTTON) @@ -157,13 +163,192 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # TODO: Remove extension from the file name, since we are using content types now request = CloudJobUploadRequest( - job_name = file_name + "." + mesh_format.file_extension, + job_name = file_name, ## + "." + mesh_format.file_extension, file_size = len(mesh_bytes), content_type = mesh_format.mime_type, ) self._api.requestUpload(request, lambda response: self._onPrintJobCreated(mesh_bytes, response)) - ## Get remote printers. + ## Called when the connection to the cluster changes. + def connect(self) -> None: + super().connect() + + ## Called when the network data should be updated. + def _update(self) -> None: + super()._update() + if self._last_response_time and time() - self._last_response_time < self.CHECK_CLUSTER_INTERVAL: + return # avoid calling the cloud too often + + if self._account.isLoggedIn: + self.setAuthenticationState(AuthState.Authenticated) + self._api.getClusterStatus(self._device_id, self._onStatusCallFinished) + else: + self.setAuthenticationState(AuthState.NotAuthenticated) + + ## Method called when HTTP request to status endpoint is finished. + # Contains both printers and print jobs statuses in a single response. + def _onStatusCallFinished(self, status: CloudClusterStatus) -> None: + # Update all data from the cluster. + self._updatePrinters(status.printers) + self._updatePrintJobs(status.print_jobs) + + ## Updates the local list of printers with the list received from the cloud. + # \param jobs: The printers received from the cloud. + def _updatePrinters(self, printers: List[CloudClusterPrinter]) -> None: + previous = {p.key: p for p in self._printers} # type: Dict[str, PrinterOutputModel] + received = {p.uuid: p for p in printers} # type: Dict[str, CloudClusterPrinter] + + removed_printers, added_printers, updated_printers = findChanges(previous, received) + + for removed_printer in removed_printers: + if self._active_printer == removed_printer: + self.setActivePrinter(None) + self._printers.remove(removed_printer) + + for added_printer in added_printers: + self._printers.append(added_printer.createOutputModel(CloudOutputController(self))) + + for model, printer in updated_printers: + printer.updateOutputModel(model) + + # Always have an active printer + if not self._active_printer: + self.setActivePrinter(self._printers[0]) + + if removed_printers or added_printers or updated_printers: + self._clusterPrintersChanged.emit() + + ## Updates the local list of print jobs with the list received from the cloud. + # \param jobs: The print jobs received from the cloud. + def _updatePrintJobs(self, jobs: List[CloudClusterPrintJob]) -> None: + received = {j.uuid: j for j in jobs} # type: Dict[str, CloudClusterPrintJob] + previous = {j.key: j for j in self._print_jobs} # type: Dict[str, UM3PrintJobOutputModel] + + removed_jobs, added_jobs, updated_jobs = findChanges(previous, received) + + # TODO: we see that not all data in the UI is correctly updated when the queue and active jobs change. + # TODO: we need to fix this here somehow by updating the correct output models. + # TODO: the configuration drop down in the slice window is not populated because we are missing some data. + # TODO: to fix this we need to implement more data as shown in ClusterUM3OutputDevice._createPrintJobModel + + for removed_job in removed_jobs: + self._print_jobs.remove(removed_job) + + for added_job in added_jobs: + self._addPrintJob(added_job) + + for model, job in updated_jobs: + job.updateOutputModel(model) + if job.printer_uuid: + self._updateAssignedPrinter(model, job.printer_uuid) + + # We only have to update when jobs are added or removed + # updated jobs push their changes via their output model + if added_jobs or removed_jobs or updated_jobs: + self.printJobsChanged.emit() + + ## Registers a new print job received via the cloud API. + # \param job: The print job received. + def _addPrintJob(self, job: CloudClusterPrintJob) -> None: + model = job.createOutputModel(CloudOutputController(self)) + model.stateChanged.connect(self._onPrintJobStateChanged) + if job.printer_uuid: + self._updateAssignedPrinter(model, job.printer_uuid) + self._print_jobs.append(model) + + ## Handles the event of a change in a print job state + def _onPrintJobStateChanged(self) -> None: + username = self._account.userName + finished_jobs = [job for job in self._print_jobs if job.state == "wait_cleanup"] + + newly_finished_jobs = [job for job in finished_jobs if job not in self._finished_jobs and job.owner == username] + for job in newly_finished_jobs: + if job.assignedPrinter: + job_completed_text = T.JOB_COMPLETED_PRINTER.format(printer_name=job.assignedPrinter.name, + job_name=job.name) + else: + job_completed_text = T.JOB_COMPLETED_NO_PRINTER.format(job_name=job.name) + job_completed_message = Message(text=job_completed_text, title = T.JOB_COMPLETED_TITLE) + job_completed_message.show() + + # Ensure UI gets updated + self.printJobsChanged.emit() + + ## Updates the printer assignment for the given print job model. + def _updateAssignedPrinter(self, model: UM3PrintJobOutputModel, printer_uuid: str) -> None: + printer = next((p for p in self._printers if printer_uuid == p.key), None) + + if not printer: + return Logger.log("w", "Missing printer %s for job %s in %s", model.assignedPrinter, model.key, + [p.key for p in self._printers]) + + printer.updateActivePrintJob(model) + model.updateAssignedPrinter(printer) + + ## Uploads the mesh when the print job was registered with the cloud API. + # \param mesh: The bytes to upload. + # \param job_response: The response received from the cloud API. + def _onPrintJobCreated(self, mesh: bytes, job_response: CloudJobResponse) -> None: + self._api.uploadMesh(job_response, mesh, self._onPrintJobUploaded, self._updateUploadProgress, + lambda _: self._onUploadError(T.UPLOAD_ERROR)) + + ## Requests the print to be sent to the printer when we finished uploading the mesh. + # \param job_id: The ID of the job. + def _onPrintJobUploaded(self, job_id: str) -> None: + self._api.requestPrint(self._device_id, job_id, self._onUploadSuccess) + + ## Updates the progress of the mesh upload. + # \param progress: The amount of percentage points uploaded until now (0-100). + def _updateUploadProgress(self, progress: int) -> None: + if not self._progress_message: + self._progress_message = Message( + text = T.SENDING_DATA_TEXT, + title = T.SENDING_DATA_TITLE, + progress = -1, + lifetime = 0, + dismissable = False, + use_inactivity_timer = False + ) + self._progress_message.setProgress(progress) + self._progress_message.show() + + ## Hides the upload progress bar + def _resetUploadProgress(self) -> None: + if self._progress_message: + self._progress_message.hide() + self._progress_message = None + + ## Displays the given message if uploading the mesh has failed + # \param message: The message to display. + def _onUploadError(self, message: str = None) -> None: + self._resetUploadProgress() + if message: + message = Message( + text = message, + title = T.ERROR, + lifetime = 10, + dismissable = True + ) + message.show() + self._sending_job = False # the upload has finished so we're not sending a job anymore + self.writeError.emit() + + ## Shows a message when the upload has succeeded + # \param response: The response from the cloud API. + def _onUploadSuccess(self, response: CloudPrintResponse) -> None: + Logger.log("i", "The cluster will be printing this print job with the ID %s", response.cluster_job_id) + self._resetUploadProgress() + message = Message( + text = T.UPLOAD_SUCCESS_TEXT, + title = T.UPLOAD_SUCCESS_TITLE, + lifetime = 5, + dismissable = True, + ) + message.show() + self._sending_job = False # the upload has finished so we're not sending a job anymore + self.writeFinished.emit() + + ## Gets the remote printers. @pyqtProperty("QVariantList", notify = _clusterPrintersChanged) def printers(self) -> List[PrinterOutputModel]: return self._printers @@ -209,170 +394,11 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): @pyqtSlot(int, result = str) def getTimeCompleted(self, time_remaining: int) -> str: # TODO: this really shouldn't be in this class - current_time = time() - datetime_completed = datetime.fromtimestamp(current_time + time_remaining) - return "{hour:02d}:{minute:02d}".format(hour = datetime_completed.hour, minute = datetime_completed.minute) + return formatTimeCompleted(time_remaining) @pyqtSlot(int, result = str) def getDateCompleted(self, time_remaining: int) -> str: - # TODO: this really shouldn't be in this class - current_time = time() - completed = datetime.fromtimestamp(current_time + time_remaining) - today = datetime.fromtimestamp(current_time) - # If finishing date is more than 7 days out, using "Mon Dec 3 at HH:MM" format - if completed.toordinal() > today.toordinal() + 7: - return completed.strftime("%a %b ") + "{day}".format(day = completed.day) - # If finishing date is within the next week, use "Monday at HH:MM" format - elif completed.toordinal() > today.toordinal() + 1: - return completed.strftime("%a") - # If finishing tomorrow, use "tomorrow at HH:MM" format - elif completed.toordinal() > today.toordinal(): - return "tomorrow" - # If finishing today, use "today at HH:MM" format - else: - return "today" - - ## Called when the connection to the cluster changes. - def connect(self) -> None: - super().connect() - - ## Called when the network data should be updated. - def _update(self) -> None: - super()._update() - if self._last_response_time and time() - self._last_response_time < self.CHECK_CLUSTER_INTERVAL: - return # avoid calling the cloud too often - - if self._account.isLoggedIn: - self.setAuthenticationState(AuthState.Authenticated) - self._api.getClusterStatus(self._device_id, self._onStatusCallFinished) - else: - self.setAuthenticationState(AuthState.NotAuthenticated) - - ## Method called when HTTP request to status endpoint is finished. - # Contains both printers and print jobs statuses in a single response. - def _onStatusCallFinished(self, status: CloudClusterStatus) -> None: - # Update all data from the cluster. - self._updatePrinters(status.printers) - self._updatePrintJobs(status.print_jobs) - - def _updatePrinters(self, printers: List[CloudClusterPrinter]) -> None: - previous = {p.key: p for p in self._printers} # type: Dict[str, PrinterOutputModel] - received = {p.uuid: p for p in printers} # type: Dict[str, CloudClusterPrinter] - - removed_printers, added_printers, updated_printers = findChanges(previous, received) - - for removed_printer in removed_printers: - if self._active_printer == removed_printer: - self.setActivePrinter(None) - self._printers.remove(removed_printer) - - for added_printer in added_printers: - self._printers.append(added_printer.createOutputModel(CloudOutputController(self))) - - for model, printer in updated_printers: - printer.updateOutputModel(model) - - # Always have an active printer - if not self._active_printer: - self.setActivePrinter(self._printers[0]) - - if removed_printers or added_printers or updated_printers: - self._clusterPrintersChanged.emit() - - def _updatePrintJobs(self, jobs: List[CloudClusterPrintJob]) -> None: - received = {j.uuid: j for j in jobs} # type: Dict[str, CloudClusterPrintJob] - previous = {j.key: j for j in self._print_jobs} # type: Dict[str, UM3PrintJobOutputModel] - - removed_jobs, added_jobs, updated_jobs = findChanges(previous, received) - - # TODO: we see that not all data in the UI is correctly updated when the queue and active jobs change. - # TODO: we need to fix this here somehow by updating the correct output models. - # TODO: also the configuration drop down in the slice window is not populated because we are missing some data. - # TODO: to fix this we need to implement more data as shown in ClusterUM3OutputDevice._createPrintJobModel - - for removed_job in removed_jobs: - self._print_jobs.remove(removed_job) - - for added_job in added_jobs: - self._addPrintJob(added_job) - - for model, job in updated_jobs: - job.updateOutputModel(model) - self._updatePrintJobDetails(model) - - # We only have to update when jobs are added or removed - # updated jobs push their changes via their output model - if added_jobs or removed_jobs or updated_jobs: - self.printJobsChanged.emit() - - def _addPrintJob(self, job: CloudClusterPrintJob) -> None: - print_job = job.createOutputModel(CloudOutputController(self)) - self._updatePrintJobDetails(print_job) - self._print_jobs.append(print_job) - - def _updatePrintJobDetails(self, print_job: UM3PrintJobOutputModel): - printer = None - try: - printer = next(p for p in self._printers if print_job.assignedPrinter == p.key) - except StopIteration: - Logger.log("w", "Missing printer %s for job %s in %s", print_job.assignedPrinter, print_job.key, - [p.key for p in self._printers]) - - if printer: - printer.updateActivePrintJob(print_job) - print_job.updateAssignedPrinter(printer) - - def _onPrintJobCreated(self, mesh: bytes, job_response: CloudJobResponse) -> None: - self._api.uploadMesh(job_response, mesh, self._onPrintJobUploaded, self._updateUploadProgress, - lambda _: self._onUploadError(T.UPLOAD_ERROR)) - - def _onPrintJobUploaded(self, job_id: str) -> None: - self._api.requestPrint(self._device_id, job_id, self._onUploadSuccess) - - def _updateUploadProgress(self, progress: int): - if not self._progress_message: - self._progress_message = Message( - text = T.SENDING_DATA_TEXT, - title = T.SENDING_DATA_TITLE, - progress = -1, - lifetime = 0, - dismissable = False, - use_inactivity_timer = False - ) - self._progress_message.setProgress(progress) - self._progress_message.show() - - def _resetUploadProgress(self): - if self._progress_message: - self._progress_message.hide() - self._progress_message = None - - def _onUploadError(self, message: str = None): - self._resetUploadProgress() - if message: - message = Message( - text = message, - title = T.ERROR, - lifetime = 10, - dismissable = True - ) - message.show() - self._sending_job = False # the upload has finished so we're not sending a job anymore - self.writeError.emit() - - # Shows a message when the upload has succeeded - def _onUploadSuccess(self, response: CloudPrintResponse): - Logger.log("i", "The cluster will be printing this print job with the ID %s", response.cluster_job_id) - self._resetUploadProgress() - message = Message( - text = T.UPLOAD_SUCCESS_TEXT, - title = T.UPLOAD_SUCCESS_TITLE, - lifetime = 5, - dismissable = True, - ) - message.show() - self._sending_job = False # the upload has finished so we're not sending a job anymore - self.writeFinished.emit() + return formatDateCompleted(time_remaining) ## TODO: The following methods are required by the monitor page QML, but are not actually available using cloud. # TODO: We fake the methods here to not break the monitor page. diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py index c9255b8da8..22c66ddfab 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py @@ -1,7 +1,8 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import List, Optional +from typing import List +from cura.PrinterOutput.ConfigurationModel import ConfigurationModel from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputController import CloudOutputController from .CloudClusterPrinterConfiguration import CloudClusterPrinterConfiguration from .CloudClusterPrintJobConstraint import CloudClusterPrintJobConstraint @@ -31,20 +32,33 @@ class CloudClusterPrintJob(BaseModel): self.time_total = None # type: str self.uuid = None # type: str super().__init__(**kwargs) - self.printers = [CloudClusterPrinterConfiguration(**c) if isinstance(c, dict) else c - for c in self.configuration] - self.print_jobs = [CloudClusterPrintJobConstraint(**p) if isinstance(p, dict) else p - for p in self.constraints] + self.configuration = [CloudClusterPrinterConfiguration(**c) if isinstance(c, dict) else c + for c in self.configuration] + self.constraints = [CloudClusterPrintJobConstraint(**p) if isinstance(p, dict) else p + for p in self.constraints] ## Creates an UM3 print job output model based on this cloud cluster print job. # \param printer: The output model of the printer def createOutputModel(self, controller: CloudOutputController) -> UM3PrintJobOutputModel: model = UM3PrintJobOutputModel(controller, self.uuid, self.name) + self.updateOutputModel(model) + return model + ## Creates a new configuration model + def _createConfigurationModel(self) -> ConfigurationModel: + extruders = [extruder.createConfigurationModel() for extruder in self.configuration or ()] + configuration = ConfigurationModel() + configuration.setExtruderConfigurations(extruders) + return configuration + ## Updates an UM3 print job output model based on this cloud cluster print job. # \param model: The model to update. def updateOutputModel(self, model: UM3PrintJobOutputModel) -> None: + # TODO: Add `compatible_machine_families` to the cloud, than add model.setCompatibleMachineFamilies() + # TODO: Add `impediments_to_printing` to the cloud, see ClusterUM3OutputDevice._updatePrintJob + # TODO: Use model.updateConfigurationChanges, see ClusterUM3OutputDevice#_createConfigurationChanges + model.updateConfiguration(self._createConfigurationModel()) model.updateTimeTotal(self.time_total) model.updateTimeElapsed(self.time_elapsed) model.updateOwner(self.owner) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinter.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinter.py index dd65dffa26..78aa8e3a31 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinter.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinter.py @@ -2,6 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. from typing import List +from cura.PrinterOutput.ConfigurationModel import ConfigurationModel from cura.PrinterOutput.PrinterOutputController import PrinterOutputController from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from .CloudClusterPrinterConfiguration import CloudClusterPrinterConfiguration @@ -40,5 +41,9 @@ class CloudClusterPrinter(BaseModel): model.updateType(self.machine_variant) model.updateState(self.status if self.enabled else "disabled") - for configuration, extruder in zip(self.configuration, model.extruders): - configuration.updateOutputModel(extruder) + for configuration, extruder_output, extruder_config in \ + zip(self.configuration, model.extruders, model.printerConfiguration.extruderConfigurations): + configuration.updateOutputModel(extruder_output) + configuration.updateConfigurationModel(extruder_config) + + pass diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py index be92549015..d60395f6ab 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py @@ -1,5 +1,9 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +from typing import List, Optional + +from cura.PrinterOutput.ConfigurationModel import ConfigurationModel +from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel from cura.PrinterOutput.ExtruderOutputModel import ExtruderOutputModel from .CloudClusterPrinterConfigurationMaterial import CloudClusterPrinterConfigurationMaterial from ...Models import BaseModel @@ -8,7 +12,7 @@ from ...Models import BaseModel ## Class representing a cloud cluster printer configuration class CloudClusterPrinterConfiguration(BaseModel): def __init__(self, **kwargs) -> None: - self.extruder_index = None # type: str + self.extruder_index = None # type: int self.material = None # type: CloudClusterPrinterConfigurationMaterial self.nozzle_diameter = None # type: str self.print_core_id = None # type: str @@ -25,3 +29,16 @@ class CloudClusterPrinterConfiguration(BaseModel): if model.activeMaterial is None or model.activeMaterial.guid != self.material.guid: material = self.material.createOutputModel() model.updateActiveMaterial(material) + + ## Creates a configuration model + def createConfigurationModel(self) -> ExtruderConfigurationModel: + model = ExtruderConfigurationModel(position = self.extruder_index) + self.updateConfigurationModel(model) + return model + + ## Creates a configuration model + def updateConfigurationModel(self, model: ExtruderConfigurationModel) -> ExtruderConfigurationModel: + model.setHotendID(self.print_core_id) + if self.material: + model.setMaterial(self.material.createOutputModel()) + return model diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Utils.py b/plugins/UM3NetworkPrinting/src/Cloud/Utils.py index 58eaf5edb9..eb96e49dad 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Utils.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Utils.py @@ -1,5 +1,8 @@ +from datetime import datetime, timedelta from typing import TypeVar, Dict, Tuple, List +from UM import i18nCatalog + T = TypeVar("T") U = TypeVar("U") @@ -24,3 +27,27 @@ def findChanges(previous: Dict[str, T], received: Dict[str, U]) -> Tuple[List[T] updated = [(previous[updated_id], received[updated_id]) for updated_id in updated_ids] return removed, added, updated + + +def formatTimeCompleted(time_remaining: int) -> str: + completed = datetime.now() + timedelta(seconds=time_remaining) + return "{hour:02d}:{minute:02d}".format(hour = completed.hour, minute = completed.minute) + + +def formatDateCompleted(time_remaining: int) -> str: + remaining = timedelta(seconds=time_remaining) + completed = datetime.now() + remaining + i18n = i18nCatalog("cura") + + # If finishing date is more than 7 days out, using "Mon Dec 3 at HH:MM" format + if remaining.days >= 7: + return completed.strftime("%a %b ") + "{day}".format(day = completed.day) + # If finishing date is within the next week, use "Monday at HH:MM" format + elif remaining.days >= 2: + return completed.strftime("%a") + # If finishing tomorrow, use "tomorrow at HH:MM" format + elif remaining.days >= 1: + return i18n.i18nc("@info:status", "tomorrow") + # If finishing today, use "today at HH:MM" format + else: + return i18n.i18nc("@info:status", "today") diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index a5ee3bc650..93a53373dc 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -25,6 +25,7 @@ from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationM from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState, NetworkedPrinterOutputDevice from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel +from plugins.UM3NetworkPrinting.src.Cloud.Utils import formatTimeCompleted, formatDateCompleted from .ClusterUM3PrinterOutputController import ClusterUM3PrinterOutputController from .ConfigurationChangeModel import ConfigurationChangeModel @@ -337,14 +338,12 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): return self._printers @pyqtSlot(int, result = str) - def formatDuration(self, seconds: int) -> str: - return Duration(seconds).getDisplayString(DurationFormat.Format.Short) + def getTimeCompleted(self, time_remaining: int) -> str: + return formatTimeCompleted(time_remaining) @pyqtSlot(int, result = str) - def getTimeCompleted(self, time_remaining: int) -> str: - current_time = time() - datetime_completed = datetime.fromtimestamp(current_time + time_remaining) - return "{hour:02d}:{minute:02d}".format(hour=datetime_completed.hour, minute=datetime_completed.minute) + def getDateCompleted(self, time_remaining: int) -> str: + return formatDateCompleted(time_remaining) @pyqtSlot(int, result = str) def getDateCompleted(self, time_remaining: int) -> str: From 1d33fe081fd30e257d9b0f5443288ad069b5f73c Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 7 Dec 2018 12:07:41 +0100 Subject: [PATCH 0763/1292] Clean up the code Remove all the references to the sidebar and use the term print_setup instead. Contributes to CURA-5941. --- .../PostProcessingPlugin.qml | 2 +- .../resources/qml/UM3InfoComponents.qml | 4 +- resources/qml/Cura.qml | 2 +- .../ConfigurationMenu/CustomConfiguration.qml | 4 +- resources/qml/MonitorButton.qml | 4 +- resources/qml/MonitorSidebar.qml | 2 +- resources/qml/ObjectsList.qml | 4 +- resources/qml/PrintMonitor.qml | 2 +- .../Custom/GlobalProfileSelector.qml | 2 +- ...debarTooltip.qml => PrintSetupTooltip.qml} | 0 resources/qml/SidebarContents.qml | 43 ------------------- resources/themes/cura-light/styles.qml | 6 +-- 12 files changed, 16 insertions(+), 59 deletions(-) rename resources/qml/{SidebarTooltip.qml => PrintSetupTooltip.qml} (100%) delete mode 100644 resources/qml/SidebarContents.qml diff --git a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml index 3fa10c23b9..b962f4d53b 100644 --- a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml +++ b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml @@ -412,7 +412,7 @@ UM.Dialog } } - Cura.SidebarTooltip + Cura.PrintSetupTooltip { id: tooltip } diff --git a/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml b/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml index 105143c851..643c8164a7 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml @@ -29,7 +29,7 @@ Item { Button { height: UM.Theme.getSize("save_button_save_to_button").height; onClicked: Cura.MachineManager.printerOutputDevices[0].requestAuthentication(); - style: UM.Theme.styles.sidebar_action_button; + style: UM.Theme.styles.print_setup_action_button; text: catalog.i18nc("@action:button", "Request Access"); tooltip: catalog.i18nc("@info:tooltip", "Send access request to the printer"); visible: printerConnected && !printerAcceptsCommands && !authenticationRequested; @@ -38,7 +38,7 @@ Item { Button { height: UM.Theme.getSize("save_button_save_to_button").height; onClicked: connectActionDialog.show(); - style: UM.Theme.styles.sidebar_action_button; + style: UM.Theme.styles.print_setup_action_button; text: catalog.i18nc("@action:button", "Connect"); tooltip: catalog.i18nc("@info:tooltip", "Connect to a printer"); visible: !printerConnected; diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 4e609ccbed..2df79d63c9 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -309,7 +309,7 @@ UM.MainWindow } } - SidebarTooltip + PrintSetupTooltip { id: tooltip } diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index ec9c5d0e38..78f6864c97 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -204,7 +204,7 @@ Item height: UM.Theme.getSize("setting_control").height width: selectors.controlWidth - style: UM.Theme.styles.sidebar_header_button + style: UM.Theme.styles.print_setup_header_button activeFocusOnPress: true menu: Cura.MaterialMenu { @@ -237,7 +237,7 @@ Item height: UM.Theme.getSize("setting_control").height width: selectors.controlWidth - style: UM.Theme.styles.sidebar_header_button + style: UM.Theme.styles.print_setup_header_button activeFocusOnPress: true; menu: Cura.NozzleMenu { extruderIndex: Cura.ExtruderManager.activeExtruderIndex } diff --git a/resources/qml/MonitorButton.qml b/resources/qml/MonitorButton.qml index eef76bcb09..fd7d2287c4 100644 --- a/resources/qml/MonitorButton.qml +++ b/resources/qml/MonitorButton.qml @@ -309,7 +309,7 @@ Item } } - style: UM.Theme.styles.sidebar_action_button + style: UM.Theme.styles.print_setup_action_button } Button @@ -325,7 +325,7 @@ Item text: catalog.i18nc("@label", "Abort Print") onClicked: confirmationDialog.visible = true - style: UM.Theme.styles.sidebar_action_button + style: UM.Theme.styles.print_setup_action_button } MessageDialog diff --git a/resources/qml/MonitorSidebar.qml b/resources/qml/MonitorSidebar.qml index 50416e34ab..669bdbfb8f 100644 --- a/resources/qml/MonitorSidebar.qml +++ b/resources/qml/MonitorSidebar.qml @@ -173,7 +173,7 @@ Rectangle anchors.bottom: parent.bottom } - SidebarTooltip + PrintSetupTooltip { id: tooltip } diff --git a/resources/qml/ObjectsList.qml b/resources/qml/ObjectsList.qml index 8f45b3744f..fd5175fce2 100644 --- a/resources/qml/ObjectsList.qml +++ b/resources/qml/ObjectsList.qml @@ -224,7 +224,7 @@ Rectangle { id: arrangeAllBuildPlatesButton; text: catalog.i18nc("@action:button","Arrange to all build plates"); - style: UM.Theme.styles.sidebar_action_button + style: UM.Theme.styles.print_setup_action_button height: UM.Theme.getSize("objects_menu_button").height; tooltip: ''; anchors @@ -244,7 +244,7 @@ Rectangle { id: arrangeBuildPlateButton; text: catalog.i18nc("@action:button","Arrange current build plate"); - style: UM.Theme.styles.sidebar_action_button + style: UM.Theme.styles.print_setup_action_button height: UM.Theme.getSize("objects_menu_button").height; tooltip: ''; anchors diff --git a/resources/qml/PrintMonitor.qml b/resources/qml/PrintMonitor.qml index 3cc161cbe7..4ed8daa55c 100644 --- a/resources/qml/PrintMonitor.qml +++ b/resources/qml/PrintMonitor.qml @@ -49,7 +49,7 @@ Rectangle property var activePrinter: connectedDevice != null ? connectedDevice.activePrinter : null property var activePrintJob: activePrinter != null ? activePrinter.activePrintJob: null - SidebarTooltip + PrintSetupTooltip { id: tooltip } diff --git a/resources/qml/PrintSetupSelector/Custom/GlobalProfileSelector.qml b/resources/qml/PrintSetupSelector/Custom/GlobalProfileSelector.qml index 11b2d3608b..8baaf9a7ae 100644 --- a/resources/qml/PrintSetupSelector/Custom/GlobalProfileSelector.qml +++ b/resources/qml/PrintSetupSelector/Custom/GlobalProfileSelector.qml @@ -43,7 +43,7 @@ Item right: parent.right } tooltip: Cura.MachineManager.activeQualityOrQualityChangesName - style: UM.Theme.styles.sidebar_header_button + style: UM.Theme.styles.print_setup_header_button activeFocusOnPress: true menu: Cura.ProfileMenu { } diff --git a/resources/qml/SidebarTooltip.qml b/resources/qml/PrintSetupTooltip.qml similarity index 100% rename from resources/qml/SidebarTooltip.qml rename to resources/qml/PrintSetupTooltip.qml diff --git a/resources/qml/SidebarContents.qml b/resources/qml/SidebarContents.qml deleted file mode 100644 index 0b19bfe3c1..0000000000 --- a/resources/qml/SidebarContents.qml +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 2016 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.7 -import QtQuick.Controls 1.1 -import QtQuick.Controls.Styles 1.1 -import QtQuick.Layouts 1.1 - -import UM 1.2 as UM -import Cura 1.0 as Cura - -StackView -{ - id: sidebarContents - - delegate: StackViewDelegate - { - function transitionFinished(properties) - { - properties.exitItem.opacity = 1 - } - - pushTransition: StackViewTransition - { - PropertyAnimation - { - target: enterItem - property: "opacity" - from: 0 - to: 1 - duration: 100 - } - PropertyAnimation - { - target: exitItem - property: "opacity" - from: 1 - to: 0 - duration: 100 - } - } - } -} \ No newline at end of file diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index 18fce7f319..bcc754f4ca 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -9,7 +9,7 @@ import UM 1.1 as UM QtObject { - property Component sidebar_header_button: Component + property Component print_setup_header_button: Component { ButtonStyle { @@ -80,7 +80,7 @@ QtObject } Label { - id: sidebarComboBoxLabel + id: printSetupComboBoxLabel color: control.enabled ? Theme.getColor("setting_control_text") : Theme.getColor("setting_control_disabled_text") text: control.text; elide: Text.ElideRight; @@ -644,7 +644,7 @@ QtObject } } - property Component sidebar_action_button: Component + property Component print_setup_action_button: Component { ButtonStyle { From 2b8358fda855b2dd722f85dc7dcf525ecfb97461 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 7 Dec 2018 12:39:37 +0100 Subject: [PATCH 0764/1292] STAR-322: Improvements to date calculation and signalling --- .../src/Cloud/CloudOutputDevice.py | 10 +++------- plugins/UM3NetworkPrinting/src/Cloud/Utils.py | 17 +++++++++-------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 3bc16cbfb0..108fb0040c 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -1,10 +1,9 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import os -from datetime import datetime from time import time -from typing import Dict, List, Optional, Set +from typing import Dict, List, Optional from PyQt5.QtCore import QObject, QUrl, pyqtProperty, pyqtSignal, pyqtSlot @@ -215,8 +214,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): if not self._active_printer: self.setActivePrinter(self._printers[0]) - if removed_printers or added_printers or updated_printers: - self._clusterPrintersChanged.emit() + self.printersChanged.emit() ## Updates the local list of print jobs with the list received from the cloud. # \param jobs: The print jobs received from the cloud. @@ -388,12 +386,10 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): @pyqtSlot(int, result = str) def formatDuration(self, seconds: int) -> str: - # TODO: this really shouldn't be in this class return Duration(seconds).getDisplayString(DurationFormat.Format.Short) @pyqtSlot(int, result = str) def getTimeCompleted(self, time_remaining: int) -> str: - # TODO: this really shouldn't be in this class return formatTimeCompleted(time_remaining) @pyqtSlot(int, result = str) @@ -413,7 +409,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): @pyqtProperty(bool, notify = printJobsChanged) def receivedPrintJobs(self) -> bool: - return True + return bool(self._print_jobs) @pyqtSlot() def openPrintJobControlPanel(self) -> None: diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Utils.py b/plugins/UM3NetworkPrinting/src/Cloud/Utils.py index eb96e49dad..5136e0e7db 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Utils.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Utils.py @@ -29,24 +29,25 @@ def findChanges(previous: Dict[str, T], received: Dict[str, U]) -> Tuple[List[T] return removed, added, updated -def formatTimeCompleted(time_remaining: int) -> str: - completed = datetime.now() + timedelta(seconds=time_remaining) +def formatTimeCompleted(seconds_remaining: int) -> str: + completed = datetime.now() + timedelta(seconds=seconds_remaining) return "{hour:02d}:{minute:02d}".format(hour = completed.hour, minute = completed.minute) -def formatDateCompleted(time_remaining: int) -> str: - remaining = timedelta(seconds=time_remaining) - completed = datetime.now() + remaining +def formatDateCompleted(seconds_remaining: int) -> str: + now = datetime.now() + completed = now + timedelta(seconds=seconds_remaining) + days = (completed.date() - now.date()).days i18n = i18nCatalog("cura") # If finishing date is more than 7 days out, using "Mon Dec 3 at HH:MM" format - if remaining.days >= 7: + if days >= 7: return completed.strftime("%a %b ") + "{day}".format(day = completed.day) # If finishing date is within the next week, use "Monday at HH:MM" format - elif remaining.days >= 2: + elif days >= 2: return completed.strftime("%a") # If finishing tomorrow, use "tomorrow at HH:MM" format - elif remaining.days >= 1: + elif days >= 1: return i18n.i18nc("@info:status", "tomorrow") # If finishing today, use "today at HH:MM" format else: From dfe55b8f23b90fcdac812fc97a62e22bfcf6eea9 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 7 Dec 2018 12:59:51 +0100 Subject: [PATCH 0765/1292] Fix height of expandable component adapting to contents Since the children don't adjust their height based on if they are visible (which would cause a binding loop) we just need to adjust the height of the total menu based on which children are visible. Easy enough. Contributes to issue CURA-5876. --- .../Menus/ConfigurationMenu/ConfigurationMenu.qml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index 9bef2ca0be..5780649423 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -139,7 +139,19 @@ Cura.ExpandableComponent Item { width: parent.width - height: childrenRect.height + height: + { + var height = 0; + if(autoConfiguration.visible) + { + height += autoConfiguration.height; + } + if(customConfiguration.visible) + { + height += customConfiguration.height; + } + return height; + } AutoConfiguration { id: autoConfiguration From 6a696a57f25e0ac41091320a9abb64a3ccce37c6 Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Fri, 7 Dec 2018 13:01:49 +0100 Subject: [PATCH 0766/1292] Removed unused property --- resources/qml/JobSpecs.qml | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/qml/JobSpecs.qml b/resources/qml/JobSpecs.qml index 8b06ab06db..c7f82b8876 100644 --- a/resources/qml/JobSpecs.qml +++ b/resources/qml/JobSpecs.qml @@ -80,7 +80,6 @@ Item height: UM.Theme.getSize("jobspecs_line").height width: Math.max(__contentWidth + UM.Theme.getSize("default_margin").width, 50) maximumLength: 120 - property int unremovableSpacing: 5 text: PrintInformation.jobName horizontalAlignment: TextInput.AlignLeft From 5b963de2ea64058e5a1ff04b24ef27a1e56e1873 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 7 Dec 2018 13:19:45 +0100 Subject: [PATCH 0767/1292] STAR-322: Checking if response changed before updating cluster --- .../src/Cloud/CloudOutputDevice.py | 21 ++++++++++++------- .../src/Cloud/Models/BaseCloudModel.py | 17 +++++++++++++++ .../src/Cloud/Models/CloudCluster.py | 4 ++-- .../src/Cloud/Models/CloudClusterPrintJob.py | 4 ++-- .../Models/CloudClusterPrintJobConstraint.py | 4 ++-- .../src/Cloud/Models/CloudClusterPrinter.py | 4 ++-- .../CloudClusterPrinterConfiguration.py | 4 ++-- ...loudClusterPrinterConfigurationMaterial.py | 4 ++-- .../src/Cloud/Models/CloudClusterStatus.py | 10 +++++++-- .../src/Cloud/Models/CloudErrorObject.py | 4 ++-- .../src/Cloud/Models/CloudJobResponse.py | 4 ++-- .../src/Cloud/Models/CloudJobUploadRequest.py | 4 ++-- .../src/Cloud/Models/CloudPrintResponse.py | 4 ++-- 13 files changed, 58 insertions(+), 30 deletions(-) create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Models/BaseCloudModel.py diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 108fb0040c..321c40bc74 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -1,6 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import os +from datetime import datetime from time import time from typing import Dict, List, Optional @@ -116,6 +117,10 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # TODO: handle progress messages in another class. self._progress_message = None # type: Optional[Message] + # Keep server string of the last generated time to avoid updating models more than once for the same response + self._received_printers = None # type: Optional[List[CloudClusterPrinter]] + self._received_print_jobs = None # type: Optional[List[CloudClusterPrintJob]] + ## Gets the host name of this device @property def host_name(self) -> str: @@ -188,8 +193,13 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # Contains both printers and print jobs statuses in a single response. def _onStatusCallFinished(self, status: CloudClusterStatus) -> None: # Update all data from the cluster. - self._updatePrinters(status.printers) - self._updatePrintJobs(status.print_jobs) + if self._received_printers != status.printers: + self._received_printers = status.printers + self._updatePrinters(status.printers) + + if status.print_jobs != self._received_print_jobs: + self._received_print_jobs = status.print_jobs + self._updatePrintJobs(status.print_jobs) ## Updates the local list of printers with the list received from the cloud. # \param jobs: The printers received from the cloud. @@ -214,7 +224,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): if not self._active_printer: self.setActivePrinter(self._printers[0]) - self.printersChanged.emit() + self.printersChanged.emit() # TODO: Make this more efficient by not updating every request ## Updates the local list of print jobs with the list received from the cloud. # \param jobs: The print jobs received from the cloud. @@ -224,11 +234,6 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): removed_jobs, added_jobs, updated_jobs = findChanges(previous, received) - # TODO: we see that not all data in the UI is correctly updated when the queue and active jobs change. - # TODO: we need to fix this here somehow by updating the correct output models. - # TODO: the configuration drop down in the slice window is not populated because we are missing some data. - # TODO: to fix this we need to implement more data as shown in ClusterUM3OutputDevice._createPrintJobModel - for removed_job in removed_jobs: self._print_jobs.remove(removed_job) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/BaseCloudModel.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/BaseCloudModel.py new file mode 100644 index 0000000000..1176c4374a --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/BaseCloudModel.py @@ -0,0 +1,17 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +from datetime import datetime, timezone + +from ...Models import BaseModel + + +class BaseCloudModel(BaseModel): + def __eq__(self, other): + return type(self) == type(other) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return type(self) != type(other) or self.__dict__ != other.__dict__ + + @staticmethod + def parseDate(date_str: str) -> datetime: + return datetime.strptime(date_str, "%Y-%m-%dT%H:%M:%S.%fZ").replace(tzinfo=timezone.utc) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudCluster.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudCluster.py index 28e95a097a..e6e2af1466 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudCluster.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudCluster.py @@ -1,10 +1,10 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from ...Models import BaseModel +from .BaseCloudModel import BaseCloudModel ## Class representing a cloud connected cluster. -class CloudCluster(BaseModel): +class CloudCluster(BaseCloudModel): def __init__(self, **kwargs): self.cluster_id = None # type: str self.host_guid = None # type: str diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py index 22c66ddfab..15d256e7d5 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py @@ -6,14 +6,14 @@ from cura.PrinterOutput.ConfigurationModel import ConfigurationModel from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputController import CloudOutputController from .CloudClusterPrinterConfiguration import CloudClusterPrinterConfiguration from .CloudClusterPrintJobConstraint import CloudClusterPrintJobConstraint -from ...Models import BaseModel +from .BaseCloudModel import BaseCloudModel ## Class representing a print job from plugins.UM3NetworkPrinting.src.UM3PrintJobOutputModel import UM3PrintJobOutputModel -class CloudClusterPrintJob(BaseModel): +class CloudClusterPrintJob(BaseCloudModel): def __init__(self, **kwargs) -> None: self.assigned_to = None # type: str self.configuration = [] # type: List[CloudClusterPrinterConfiguration] diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobConstraint.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobConstraint.py index 884ff8f0c2..f13e3098fc 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobConstraint.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobConstraint.py @@ -1,10 +1,10 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from ...Models import BaseModel +from .BaseCloudModel import BaseCloudModel ## Class representing a cloud cluster print job constraint -class CloudClusterPrintJobConstraint(BaseModel): +class CloudClusterPrintJobConstraint(BaseCloudModel): def __init__(self, **kwargs) -> None: self.require_printer_name = None # type: str super().__init__(**kwargs) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinter.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinter.py index 78aa8e3a31..9057743621 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinter.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinter.py @@ -6,11 +6,11 @@ from cura.PrinterOutput.ConfigurationModel import ConfigurationModel from cura.PrinterOutput.PrinterOutputController import PrinterOutputController from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from .CloudClusterPrinterConfiguration import CloudClusterPrinterConfiguration -from ...Models import BaseModel +from .BaseCloudModel import BaseCloudModel ## Class representing a cluster printer -class CloudClusterPrinter(BaseModel): +class CloudClusterPrinter(BaseCloudModel): def __init__(self, **kwargs) -> None: self.configuration = [] # type: List[CloudClusterPrinterConfiguration] self.enabled = None # type: str diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py index d60395f6ab..aa382136d0 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py @@ -6,11 +6,11 @@ from cura.PrinterOutput.ConfigurationModel import ConfigurationModel from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel from cura.PrinterOutput.ExtruderOutputModel import ExtruderOutputModel from .CloudClusterPrinterConfigurationMaterial import CloudClusterPrinterConfigurationMaterial -from ...Models import BaseModel +from .BaseCloudModel import BaseCloudModel ## Class representing a cloud cluster printer configuration -class CloudClusterPrinterConfiguration(BaseModel): +class CloudClusterPrinterConfiguration(BaseCloudModel): def __init__(self, **kwargs) -> None: self.extruder_index = None # type: int self.material = None # type: CloudClusterPrinterConfigurationMaterial diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfigurationMaterial.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfigurationMaterial.py index 8023784925..e5f52ac630 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfigurationMaterial.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfigurationMaterial.py @@ -1,11 +1,11 @@ from UM.Logger import Logger from cura.CuraApplication import CuraApplication from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel -from ...Models import BaseModel +from .BaseCloudModel import BaseCloudModel ## Class representing a cloud cluster printer configuration -class CloudClusterPrinterConfigurationMaterial(BaseModel): +class CloudClusterPrinterConfigurationMaterial(BaseCloudModel): def __init__(self, **kwargs) -> None: self.guid = None # type: str self.brand = None # type: str diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterStatus.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterStatus.py index a44b665973..77ed979dbc 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterStatus.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterStatus.py @@ -1,15 +1,17 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +from datetime import datetime from typing import List from .CloudClusterPrinter import CloudClusterPrinter from .CloudClusterPrintJob import CloudClusterPrintJob -from ...Models import BaseModel +from .BaseCloudModel import BaseCloudModel # Model that represents the status of the cluster for the cloud -class CloudClusterStatus(BaseModel): +class CloudClusterStatus(BaseCloudModel): def __init__(self, **kwargs) -> None: + self.generated_time = None # type: datetime # a list of the printers self.printers = [] # type: List[CloudClusterPrinter] # a list of the print jobs @@ -20,3 +22,7 @@ class CloudClusterStatus(BaseModel): # converting any dictionaries into models self.printers = [CloudClusterPrinter(**p) if isinstance(p, dict) else p for p in self.printers] self.print_jobs = [CloudClusterPrintJob(**j) if isinstance(j, dict) else j for j in self.print_jobs] + + # converting generated time into datetime + if isinstance(self.generated_time, str): + self.generated_time = self.parseDate(self.generated_time) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudErrorObject.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudErrorObject.py index 813ef957e4..9696cbcb7a 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudErrorObject.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudErrorObject.py @@ -2,11 +2,11 @@ # Cura is released under the terms of the LGPLv3 or higher. from typing import Dict -from ...Models import BaseModel +from .BaseCloudModel import BaseCloudModel ## Class representing errors generated by the cloud servers, according to the json-api standard. -class CloudErrorObject(BaseModel): +class CloudErrorObject(BaseCloudModel): def __init__(self, **kwargs) -> None: self.id = None # type: str self.code = None # type: str diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobResponse.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobResponse.py index 0b611dd2d3..e3161449a5 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobResponse.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobResponse.py @@ -1,10 +1,10 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from ...Models import BaseModel +from .BaseCloudModel import BaseCloudModel # Model that represents the response received from the cloud after requesting to upload a print job -class CloudJobResponse(BaseModel): +class CloudJobResponse(BaseCloudModel): def __init__(self, **kwargs) -> None: self.download_url = None # type: str self.job_id = None # type: str diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobUploadRequest.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobUploadRequest.py index 3e038b343e..07a781e2d6 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobUploadRequest.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobUploadRequest.py @@ -1,10 +1,10 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from ...Models import BaseModel +from .BaseCloudModel import BaseCloudModel # Model that represents the request to upload a print job to the cloud -class CloudJobUploadRequest(BaseModel): +class CloudJobUploadRequest(BaseCloudModel): def __init__(self, **kwargs) -> None: self.file_size = None # type: int self.job_name = None # type: str diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintResponse.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintResponse.py index ff05ad5b19..3e9ad584dc 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintResponse.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintResponse.py @@ -1,10 +1,10 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from ...Models import BaseModel +from .BaseCloudModel import BaseCloudModel # Model that represents the responses received from the cloud after requesting a job to be printed. -class CloudPrintResponse(BaseModel): +class CloudPrintResponse(BaseCloudModel): def __init__(self, **kwargs) -> None: self.cluster_job_id = None # type: str self.job_id = None # type: str From 26be65e405f42ea806c10501a8c09793fe58a896 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 7 Dec 2018 13:29:16 +0100 Subject: [PATCH 0768/1292] Fix some other merge conflicts Contributes to CURA-6008. --- resources/qml/ExpandableComponent.qml | 3 +- resources/qml/ExpandablePopup.qml | 2 +- resources/qml/JobSpecs.qml | 1 - resources/themes/cura-light/theme.json | 81 ++++++++++++++------------ 4 files changed, 47 insertions(+), 40 deletions(-) diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index 3f30f8f386..3a03740251 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -109,10 +109,9 @@ Item } source: UM.Theme.getIcon("pencil") visible: source != "" && base.enabled -// color: UM.Theme.getColor("small_button_text") width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height - color: UM.Theme.getColor("text") + color: UM.Theme.getColor("small_button_text") } MouseArea diff --git a/resources/qml/ExpandablePopup.qml b/resources/qml/ExpandablePopup.qml index a1e2fb0fea..c15310f803 100644 --- a/resources/qml/ExpandablePopup.qml +++ b/resources/qml/ExpandablePopup.qml @@ -131,7 +131,7 @@ Item visible: source != "" && base.enabled width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height - color: UM.Theme.getColor("text") + color: UM.Theme.getColor("small_button_text") } MouseArea diff --git a/resources/qml/JobSpecs.qml b/resources/qml/JobSpecs.qml index 8b06ab06db..c7f82b8876 100644 --- a/resources/qml/JobSpecs.qml +++ b/resources/qml/JobSpecs.qml @@ -80,7 +80,6 @@ Item height: UM.Theme.getSize("jobspecs_line").height width: Math.max(__contentWidth + UM.Theme.getSize("default_margin").width, 50) maximumLength: 120 - property int unremovableSpacing: 5 text: PrintInformation.jobName horizontalAlignment: TextInput.AlignLeft diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index f96a785f11..16d13b9652 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -35,7 +35,7 @@ "family": "Noto Sans" }, "default_italic": { - "size": 1.15, + "size": 1.0, "weight": 50, "italic": true, "family": "Noto Sans" @@ -80,7 +80,7 @@ "primary_hover": [48, 182, 231, 255], "primary_text": [255, 255, 255, 255], "border": [127, 127, 127, 255], - "secondary": [240, 240, 240, 255], + "secondary": [245, 245, 245, 255], "secondary_shadow": [216, 216, 216, 255], "primary_button": [38, 113, 231, 255], @@ -178,34 +178,34 @@ "action_button_disabled_shadow": [228, 228, 228, 255], "scrollbar_background": [255, 255, 255, 255], - "scrollbar_handle": [31, 36, 39, 255], - "scrollbar_handle_hover": [12, 159, 227, 255], - "scrollbar_handle_down": [12, 159, 227, 255], + "scrollbar_handle": [10, 8, 80, 255], + "scrollbar_handle_hover": [50, 130, 255, 255], + "scrollbar_handle_down": [50, 130, 255, 255], "setting_category": [245, 245, 245, 255], "setting_category_disabled": [255, 255, 255, 255], - "setting_category_hover": [245, 245, 245, 255], + "setting_category_hover": [232, 242, 252, 255], "setting_category_active": [245, 245, 245, 255], - "setting_category_active_hover": [245, 245, 245, 255], - "setting_category_text": [31, 36, 39, 255], + "setting_category_active_hover": [232, 242, 252, 255], + "setting_category_text": [35, 35, 35, 255], "setting_category_disabled_text": [24, 41, 77, 101], - "setting_category_hover_text": [31, 36, 39, 255], - "setting_category_active_text": [31, 36, 39, 255], - "setting_category_active_hover_text": [31, 36, 39, 255], + "setting_category_hover_text": [35, 35, 35, 255], + "setting_category_active_text": [35, 35, 35, 255], + "setting_category_active_hover_text": [35, 35, 35, 255], "setting_category_border": [245, 245, 245, 255], "setting_category_disabled_border": [245, 245, 245, 255], - "setting_category_hover_border": [12, 159, 227, 255], - "setting_category_active_border": [245, 245, 245, 255], - "setting_category_active_hover_border": [12, 159, 227, 255], + "setting_category_hover_border": [50, 130, 255, 255], + "setting_category_active_border": [50, 130, 255, 255], + "setting_category_active_hover_border": [50, 130, 255, 255], "setting_control": [255, 255, 255, 255], "setting_control_selected": [31, 36, 39, 255], "setting_control_highlight": [255, 255, 255, 255], - "setting_control_border": [127, 127, 127, 255], + "setting_control_border": [199, 199, 199, 255], "setting_control_border_highlight": [50, 130, 255, 255], - "setting_control_text": [27, 27, 27, 255], - "setting_control_depth_line": [127, 127, 127, 255], - "setting_control_button": [127, 127, 127, 255], + "setting_control_text": [35, 35, 35, 255], + "setting_control_depth_line": [199, 199, 199, 255], + "setting_control_button": [199, 199, 199, 255], "setting_control_button_hover": [70, 84, 113, 255], "setting_control_disabled": [245, 245, 245, 255], "setting_control_disabled_text": [127, 127, 127, 255], @@ -216,6 +216,7 @@ "setting_validation_warning_background": [255, 145, 62, 255], "setting_validation_warning": [127, 127, 127, 255], "setting_validation_ok": [255, 255, 255, 255], + "setting_filter_field" : [153, 153, 153, 255], "material_compatibility_warning": [0, 0, 0, 255], @@ -233,11 +234,11 @@ "checkbox": [255, 255, 255, 255], "checkbox_hover": [255, 255, 255, 255], - "checkbox_border": [64, 69, 72, 255], + "checkbox_border": [199, 199, 199, 255], "checkbox_border_hover": [50, 130, 255, 255], - "checkbox_mark": [119, 122, 124, 255], + "checkbox_mark": [50, 130, 255, 255], "checkbox_disabled": [223, 223, 223, 255], - "checkbox_text": [27, 27, 27, 255], + "checkbox_text": [35, 35, 35, 255], "tooltip": [68, 192, 255, 255], "tooltip_text": [255, 255, 255, 255], @@ -293,16 +294,16 @@ "xray_error": [255, 0, 0, 255], "layerview_ghost": [32, 32, 32, 96], - "layerview_none": [255, 255, 255, 255], - "layerview_inset_0": [255, 0, 0, 255], - "layerview_inset_x": [0, 255, 0, 255], - "layerview_skin": [255, 255, 0, 255], - "layerview_support": [0, 255, 255, 255], - "layerview_skirt": [0, 255, 255, 255], - "layerview_infill": [255, 192, 0, 255], - "layerview_support_infill": [0, 255, 255, 255], - "layerview_move_combing": [0, 0, 255, 255], - "layerview_move_retraction": [128, 128, 255, 255], + "layerview_none": [255, 255, 255, 255], + "layerview_inset_0": [255, 0, 0, 255], + "layerview_inset_x": [0, 255, 0, 255], + "layerview_skin": [255, 255, 0, 255], + "layerview_support": [0, 255, 255, 255], + "layerview_skirt": [0, 255, 255, 255], + "layerview_infill": [255, 192, 0, 255], + "layerview_support_infill": [0, 255, 255, 255], + "layerview_move_combing": [0, 0, 255, 255], + "layerview_move_retraction": [128, 128, 255, 255], "layerview_support_interface": [64, 192, 255, 255], "layerview_nozzle": [181, 166, 66, 50], @@ -356,10 +357,16 @@ "account_button": [12, 3], - "print_setup_widget": [30.0, 42.0], + "print_setup_widget": [38.0, 30.0], "print_setup_mode_toggle": [0.0, 2.0], "print_setup_item": [0.0, 2.0], "print_setup_extruder_box": [0.0, 6.0], + "print_setup_widget_header": [0.0, 3.0], + "print_setup_slider_groove": [0.16, 0.16], + "print_setup_slider_handle": [1.0, 1.0], + "print_setup_slider_tickmarks": [0.32, 0.32], + "print_setup_big_item": [28, 2.5], + "print_setup_icon": [1.2, 1.2], "configuration_selector_mode_tabs": [0.0, 3.0], @@ -391,12 +398,13 @@ "extruder_icon": [2.33, 2.33], - "section": [0.0, 2.2], + "section": [0.0, 2], "section_icon": [1.6, 1.6], "section_icon_column": [2.8, 0.0], "setting": [25.0, 1.8], - "setting_control": [10.0, 2.0], + "setting_control": [11.0, 2.0], + "setting_control_radius": [0.15, 0.15], "setting_control_depth_margin": [1.4, 0.0], "setting_preferences_button_margin": [4, 0.0], "setting_control_margin": [0.0, 0.0], @@ -404,7 +412,7 @@ "setting_text_maxwidth": [40.0, 0.0], "standard_list_lineheight": [1.5, 1.5], - "standard_arrow": [0.8, 0.8], + "standard_arrow": [1.0, 1.0], "button": [4, 4], "button_icon": [2.5, 2.5], @@ -444,7 +452,8 @@ "layerview_row": [11.0, 1.5], "layerview_row_spacing": [0.0, 0.5], - "checkbox": [2.0, 2.0], + "checkbox": [1.5, 1.5], + "checkbox_radius": [0.08, 0.08], "tooltip": [20.0, 10.0], "tooltip_margins": [1.0, 1.0], From e74258c26bd1917d87e5fd4bbb1f77719eb947f8 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 7 Dec 2018 13:39:42 +0100 Subject: [PATCH 0769/1292] Don't show materials if printer has no materials But if the printer does have other configurations to change, do show a placeholder text to indicate that the configuration can be selected here. This also simplifies a bit of code where it would need to call an updateEnabled() function, since it turns out that these properties in Cura.MachineManager have proper signals (contrary to what was previously used, the metadata entry stuff). Contributes to issue UCRA-5876. --- .../ConfigurationMenu/ConfigurationMenu.qml | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index c282975cd3..33a317b42b 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -34,9 +34,11 @@ Cura.ExpandablePopup Custom } + enabled: Cura.MachineManager.hasMaterials || Cura.MachineManager.hasVariants || Cura.MachineManager.hasVariantBuildplates; //Only let it drop down if there is any configuration that you could change. + headerItem: Item { - // Horizontal list that shows the extruders + // Horizontal list that shows the extruders and their materials ListView { id: extrudersList @@ -44,7 +46,7 @@ Cura.ExpandablePopup orientation: ListView.Horizontal anchors.fill: parent model: extrudersModel - visible: base.enabled + visible: Cura.MachineManager.hasMaterials delegate: Item { @@ -101,24 +103,26 @@ Cura.ExpandablePopup } } } - } - //Disable the menu if there are no materials, variants or build plates to change. - function updateEnabled() - { - var active_definition_id = Cura.MachineManager.activeMachine.definition.id; - var has_materials = Cura.ContainerManager.getContainerMetaDataEntry(active_definition_id, "has_materials"); - var has_variants = Cura.ContainerManager.getContainerMetaDataEntry(active_definition_id, "has_variants"); - var has_buildplates = Cura.ContainerManager.getContainerMetaDataEntry(active_definition_id, "has_variant_buildplates"); - base.enabled = has_materials || has_variants || has_buildplates; //Only let it drop down if there is any configuration that you could change. - } + //Placeholder text if there is a configuration to select but no materials (so we can't show the materials per extruder). + Label + { + text: catalog.i18nc("@label", "Select configuration") + elide: Text.ElideRight + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + renderType: Text.NativeRendering - Connections - { - target: Cura.MachineManager - onGlobalContainerChanged: base.updateEnabled(); + visible: !Cura.MachineManager.hasMaterials && (Cura.MachineManager.hasVariants || Cura.MachineManager.hasVariantBuildplates) + + anchors + { + left: parent.left + leftMargin: UM.Theme.getSize("default_margin").width + verticalCenter: parent.verticalCenter + } + } } - Component.onCompleted: updateEnabled(); contentItem: Column { From 15f81da95b40e1cb27a73b9f13562bc6f525f296 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 7 Dec 2018 13:47:58 +0100 Subject: [PATCH 0770/1292] Do not show the layer height in the header panel when the profile is not supported --- cura/Settings/MachineManager.py | 4 ++++ .../PrintSetupSelectorHeader.qml | 14 +++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index a472cc7f09..c375ce01d1 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1536,6 +1536,10 @@ class MachineManager(QObject): name = self._current_quality_group.name return name + @pyqtProperty(bool, notify = activeQualityGroupChanged) + def hasNotSupportedQuality(self) -> bool: + return self._current_quality_group is None and self._current_quality_changes_group is None + def _updateUponMaterialMetadataChange(self) -> None: if self._global_container_stack is None: return diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml index 518f3d49eb..d4287045b8 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml @@ -13,7 +13,19 @@ RowLayout Cura.IconWithText { source: UM.Theme.getIcon("category_layer_height") - text: Cura.MachineManager.activeStack ? Cura.MachineManager.activeQualityOrQualityChangesName + " " + layerHeight.properties.value + "mm" : "" + text: + { + if (Cura.MachineManager.activeStack) + { + var text = Cura.MachineManager.activeQualityOrQualityChangesName + if (!Cura.MachineManager.hasNotSupportedQuality) + { + text += " " + layerHeight.properties.value + "mm" + } + return text + } + return "" + } UM.SettingPropertyProvider { From 43a06fdc3d85e618534297d967c560cdc9783c08 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 7 Dec 2018 13:49:17 +0100 Subject: [PATCH 0771/1292] Add more margin above printer type labels A bit of Gestalt. Contributes to issue CURA-5876. --- .../qml/Menus/ConfigurationMenu/ConfigurationListView.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index e7936b69d2..53969a0370 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -64,11 +64,12 @@ Column section.criteria: ViewSection.FullString section.delegate: Item { - height: printerTypeLabel.height + UM.Theme.getSize("default_margin").height + height: printerTypeLabel.height + UM.Theme.getSize("default_margin").height * 2 //Causes a default margin above the label and a default margin below the label. Cura.PrinterTypeLabel { id: printerTypeLabel text: Cura.MachineManager.getAbbreviatedMachineName(section) + anchors.verticalCenter: parent.verticalCenter //One default margin above and one below. } } From c44b74454f927714f891c254024e95679982ef20 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 7 Dec 2018 14:22:39 +0100 Subject: [PATCH 0772/1292] Revert "No longer make BuildVolume set max bounds." This reverts commit 1467e703ae121c3f2fa02ee7258bdeba63f80c5c. This variable was actually used... In Uranium, by the scale tiny models feature. --- cura/BuildVolume.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py index 1589f16afc..f837f5cef7 100755 --- a/cura/BuildVolume.py +++ b/cura/BuildVolume.py @@ -479,6 +479,8 @@ class BuildVolume(SceneNode): maximum = Vector(max_w - bed_adhesion_size - 1, max_h - self._raft_thickness - self._extra_z_clearance, max_d - disallowed_area_size + bed_adhesion_size - 1) ) + self._application.getController().getScene()._maximum_bounds = scale_to_max_bounds + self.updateNodeBoundaryCheck() def getBoundingBox(self) -> AxisAlignedBox: From 8e2c130416ecdf1adf21bc8d5388588442f6f6c7 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 7 Dec 2018 14:31:06 +0100 Subject: [PATCH 0773/1292] Use default lining style as separator for buildplate Normal colour, normal thickness. Contributes to issue CURA-5876. --- resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 6ac1e6a2ad..05cac16e29 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -72,8 +72,8 @@ Button right: parent.right rightMargin: parent.padding } - height: visible ? Math.round(UM.Theme.getSize("thick_lining").height / 2) : 0 - color: UM.Theme.getColor("text") + height: visible ? Math.round(UM.Theme.getSize("default_lining").height / 2) : 0 + color: UM.Theme.getColor("lining") } Item From c663681e66a42b63b1e831a1dbf967e6043f563b Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 7 Dec 2018 14:39:43 +0100 Subject: [PATCH 0774/1292] Simplify buildplate icon Removed all unnecessary crap added by Sketch. Contributes to issue CURA-5876. --- .../themes/cura-light/icons/buildplate.svg | 20 ++++++------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/resources/themes/cura-light/icons/buildplate.svg b/resources/themes/cura-light/icons/buildplate.svg index 9e61296958..d844b91a28 100644 --- a/resources/themes/cura-light/icons/buildplate.svg +++ b/resources/themes/cura-light/icons/buildplate.svg @@ -1,17 +1,9 @@ - - - icn_buildplate - Created with Sketch. - - - - - - - - - - + + + + + + \ No newline at end of file From 78df27369f1cc423fc3e369d22da6115fba43560 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 7 Dec 2018 14:41:30 +0100 Subject: [PATCH 0775/1292] Fill buildplate icon This is according to our newest designs. Contributes to issue CURA-5876. --- resources/themes/cura-light/icons/buildplate.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/themes/cura-light/icons/buildplate.svg b/resources/themes/cura-light/icons/buildplate.svg index d844b91a28..7505c8204e 100644 --- a/resources/themes/cura-light/icons/buildplate.svg +++ b/resources/themes/cura-light/icons/buildplate.svg @@ -4,6 +4,6 @@ - + \ No newline at end of file From ffcac04f9e1bb595bc30a33ba0d9aeb327b7c45d Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 7 Dec 2018 15:21:53 +0100 Subject: [PATCH 0776/1292] Add printer type selector if connected to cluster If there are 2 or more printer types in your connected cluster, you can switch the printer type here. Contributes to issue CURA-5876. --- .../ConfigurationMenu/CustomConfiguration.qml | 49 ++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index 78f6864c97..8429e2c093 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -36,10 +36,57 @@ Item } } + //Printer type selector. + Item + { + id: printerTypeSelectorRow + visible: + { + return Cura.MachineManager.printerOutputDevices.length >= 1 //If connected... + && Cura.MachineManager.printerOutputDevices[0].connectedPrintersTypeCount != null //...and we have configuration information... + && Cura.MachineManager.printerOutputDevices[0].connectedPrintersTypeCount.length > 1; //...and there is more than one type of printer in the configuration list. + } + height: visible ? childrenRect.height : 0 + + anchors + { + left: parent.left + leftMargin: UM.Theme.getSize("default_margin").width + right: parent.right + rightMargin: UM.Theme.getSize("default_margin").width + top: header.bottom + topMargin: visible ? UM.Theme.getSize("default_margin").height : 0 + } + + Label + { + text: catalog.i18nc("@label", "Printer") + width: Math.round(parent.width * 0.3) - UM.Theme.getSize("default_margin").width + height: contentHeight + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + anchors.verticalCenter: printerTypeSelector.verticalCenter + anchors.left: parent.left + } + + OldControls.ToolButton + { + id: printerTypeSelector + text: Cura.MachineManager.activeMachineDefinitionName + tooltip: Cura.MachineManager.activeMachineDefinitionName + height: UM.Theme.getSize("setting_control").height + width: Math.round(parent.width * 0.7) + UM.Theme.getSize("default_margin").width + anchors.right: parent.right + style: UM.Theme.styles.print_setup_header_button + + menu: Cura.PrinterTypeMenu { } + } + } + UM.TabRow { id: tabBar - anchors.top: header.bottom + anchors.top: printerTypeSelectorRow.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height visible: extrudersModel.count > 1 From 6a7bbe5bdb46c3f6db301097d30e472f3b45702e Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 7 Dec 2018 15:31:12 +0100 Subject: [PATCH 0777/1292] Fix hiding materials if material is empty Because the loaded material profile has the name 'Empty' then. Contributes to issue CURA-5876. --- .../qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml index 885f02d740..a344e31d4f 100644 --- a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml @@ -20,7 +20,7 @@ Row { materialColor: printCoreConfiguration.material.color anchors.verticalCenter: parent.verticalCenter - extruderEnabled: printCoreConfiguration.material.name !== "" && printCoreConfiguration.hotendID !== "" + extruderEnabled: printCoreConfiguration.material.brand !== "" && printCoreConfiguration.hotendID !== "" } Column @@ -36,7 +36,7 @@ Row } Label { - text: printCoreConfiguration.material.name ? printCoreConfiguration.material.name : " " //Use space so that the height is still correct. + text: printCoreConfiguration.material.brand ? printCoreConfiguration.material.name : " " //Use space so that the height is still correct. renderType: Text.NativeRendering elide: Text.ElideRight font: UM.Theme.getFont("default") From f4220da550ff4f5c65787b54f413415ac4dce73e Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 7 Dec 2018 15:31:33 +0100 Subject: [PATCH 0778/1292] Adds rough first version of rating stars It's not fully polished just yet CURA-6013 --- cura/API/Account.py | 2 +- .../Toolbox/resources/qml/RatingWidget.qml | 101 ++++++++++++++++++ .../qml/ToolboxDownloadsGridTile.qml | 10 ++ plugins/Toolbox/src/PackagesModel.py | 8 +- plugins/Toolbox/src/Toolbox.py | 53 ++++++--- .../themes/cura-light/icons/star_empty.svg | 11 ++ .../themes/cura-light/icons/star_filled.svg | 11 ++ resources/themes/cura-light/theme.json | 1 + 8 files changed, 180 insertions(+), 17 deletions(-) create mode 100644 plugins/Toolbox/resources/qml/RatingWidget.qml create mode 100644 resources/themes/cura-light/icons/star_empty.svg create mode 100644 resources/themes/cura-light/icons/star_filled.svg diff --git a/cura/API/Account.py b/cura/API/Account.py index 397e220478..be77a6307b 100644 --- a/cura/API/Account.py +++ b/cura/API/Account.py @@ -44,7 +44,7 @@ class Account(QObject): OAUTH_SERVER_URL= self._oauth_root, CALLBACK_PORT=self._callback_port, CALLBACK_URL="http://localhost:{}/callback".format(self._callback_port), - CLIENT_ID="um---------------ultimaker_cura_drive_plugin", + CLIENT_ID="um----------------------------ultimaker_cura", CLIENT_SCOPES="account.user.read drive.backup.read drive.backup.write packages.download packages.rating.read packages.rating.write", AUTH_DATA_PREFERENCE_KEY="general/ultimaker_auth_data", AUTH_SUCCESS_REDIRECT="{}/app/auth-success".format(self._oauth_root), diff --git a/plugins/Toolbox/resources/qml/RatingWidget.qml b/plugins/Toolbox/resources/qml/RatingWidget.qml new file mode 100644 index 0000000000..424f6c91c4 --- /dev/null +++ b/plugins/Toolbox/resources/qml/RatingWidget.qml @@ -0,0 +1,101 @@ +import QtQuick 2.2 +import QtQuick.Controls 2.0 +import UM 1.0 as UM + +Item +{ + id: ratingWidget + + property real rating: 0 + property int indexHovered: -1 + property string packageId: "" + property int numRatings: 0 + property int userRating: 0 + width: contentRow.width + height: contentRow.height + MouseArea + { + id: mouseArea + anchors.fill: parent + hoverEnabled: ratingWidget.enabled + acceptedButtons: Qt.NoButton + onExited: + { + ratingWidget.indexHovered = -1 + } + + Row + { + id: contentRow + height: childrenRect.height + Repeater + { + model: 5 // We need to get 5 stars + Button + { + id: control + hoverEnabled: true + onHoveredChanged: + { + if(hovered) + { + indexHovered = index + } + } + + property bool isStarFilled: + { + // If the entire widget is hovered, override the actual rating. + if(ratingWidget.indexHovered >= 0) + { + return indexHovered >= index + } + + if(ratingWidget.userRating > 0) + { + return userRating >= index +1 + } + + return rating >= index + 1 + } + + contentItem: Item {} + height: UM.Theme.getSize("rating_star").height + width: UM.Theme.getSize("rating_star").width + background: UM.RecolorImage + { + source: UM.Theme.getIcon(control.isStarFilled ? "star_filled" : "star_empty") + + // Unfilled stars should always have the default color. Only filled stars should change on hover + color: + { + if(!enabled) + { + return "#5a5a5a" + } + if((ratingWidget.indexHovered >= 0 || ratingWidget.userRating > 0) && isStarFilled) + { + return UM.Theme.getColor("primary") + } + return "#5a5a5a" + } + } + onClicked: + { + if(userRating == 0) + { + //User didn't vote yet, locally fake it + numRatings += 1 + } + userRating = index + 1 // Fake local data + toolbox.ratePackage(ratingWidget.packageId, index + 1) + } + } + } + Label + { + text: "(" + numRatings + ")" + } + } + } +} \ No newline at end of file diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index cee3f0fd20..a72411ef4b 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -84,6 +84,16 @@ Item color: UM.Theme.getColor("text_medium") font: UM.Theme.getFont("default") } + + RatingWidget + { + visible: model.type == "plugin" + packageId: model.id + rating: model.average_rating != undefined ? model.average_rating : 0 + numRatings: model.num_ratings != undefined ? model.num_ratings : 0 + userRating: model.user_rating + enabled: installedPackages != 0 + } } } MouseArea diff --git a/plugins/Toolbox/src/PackagesModel.py b/plugins/Toolbox/src/PackagesModel.py index bcc02955a2..b3c388bc7c 100644 --- a/plugins/Toolbox/src/PackagesModel.py +++ b/plugins/Toolbox/src/PackagesModel.py @@ -41,6 +41,9 @@ class PackagesModel(ListModel): self.addRoleName(Qt.UserRole + 20, "links") self.addRoleName(Qt.UserRole + 21, "website") self.addRoleName(Qt.UserRole + 22, "login_required") + self.addRoleName(Qt.UserRole + 23, "average_rating") + self.addRoleName(Qt.UserRole + 24, "num_ratings") + self.addRoleName(Qt.UserRole + 25, "user_rating") # List of filters for queries. The result is the union of the each list of results. self._filter = {} # type: Dict[str, str] @@ -101,7 +104,10 @@ class PackagesModel(ListModel): "tags": package["tags"] if "tags" in package else [], "links": links_dict, "website": package["website"] if "website" in package else None, - "login_required": "login-required" in package.get("tags", []) + "login_required": "login-required" in package.get("tags", []), + "average_rating": package.get("rating", {}).get("average", 0), + "num_ratings": package.get("rating", {}).get("count", 0), + "user_rating": package.get("rating", {}).get("user", 0) }) # Filter on all the key-word arguments. diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index ab975548ce..7e35f5d1f4 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -22,7 +22,8 @@ from cura.CuraApplication import CuraApplication from .AuthorsModel import AuthorsModel from .PackagesModel import PackagesModel - +from cura.CuraVersion import CuraVersion +from cura.API import CuraAPI if TYPE_CHECKING: from cura.Settings.GlobalStack import GlobalStack @@ -50,17 +51,10 @@ class Toolbox(QObject, Extension): self._download_progress = 0 # type: float self._is_downloading = False # type: bool self._network_manager = None # type: Optional[QNetworkAccessManager] - self._request_header = [ - b"User-Agent", - str.encode( - "%s/%s (%s %s)" % ( - self._application.getApplicationName(), - self._application.getVersion(), - platform.system(), - platform.machine(), - ) - ) - ] + self._request_headers = [] # type: List[Tuple(bytes, bytes)] + self._updateRequestHeader() + + self._request_urls = {} # type: Dict[str, QUrl] self._to_update = [] # type: List[str] # Package_ids that are waiting to be updated self._old_plugin_ids = set() # type: Set[str] @@ -115,6 +109,7 @@ class Toolbox(QObject, Extension): self._restart_dialog_message = "" # type: str self._application.initializationFinished.connect(self._onAppInitialized) + self._application.getCuraAPI().account.loginStateChanged.connect(self._updateRequestHeader) # Signals: # -------------------------------------------------------------------------- @@ -134,12 +129,38 @@ class Toolbox(QObject, Extension): showLicenseDialog = pyqtSignal() uninstallVariablesChanged = pyqtSignal() + def _updateRequestHeader(self): + self._request_headers = [ + (b"User-Agent", + str.encode( + "%s/%s (%s %s)" % ( + self._application.getApplicationName(), + self._application.getVersion(), + platform.system(), + platform.machine(), + ) + )) + ] + access_token = self._application.getCuraAPI().account.accessToken + if access_token: + self._request_headers.append((b"Authorization", "Bearer {}".format(access_token).encode())) + def _resetUninstallVariables(self) -> None: self._package_id_to_uninstall = None # type: Optional[str] self._package_name_to_uninstall = "" self._package_used_materials = [] # type: List[Tuple[GlobalStack, str, str]] self._package_used_qualities = [] # type: List[Tuple[GlobalStack, str, str]] + @pyqtSlot(str, int) + def ratePackage(self, package_id: str, rating: int) -> None: + url = QUrl("{base_url}/packages/{package_id}/ratings".format(base_url=self._api_url, package_id = package_id)) + + self._rate_request = QNetworkRequest(url) + for header_name, header_value in self._request_headers: + cast(QNetworkRequest, self._rate_request).setRawHeader(header_name, header_value) + data = "{\"data\": {\"cura_version\": \"%s\", \"rating\": %i}}" % (Version(CuraVersion), rating) + self._rate_reply = cast(QNetworkAccessManager, self._network_manager).put(self._rate_request, data.encode()) + @pyqtSlot(result = str) def getLicenseDialogPluginName(self) -> str: return self._license_dialog_plugin_name @@ -563,7 +584,8 @@ class Toolbox(QObject, Extension): def _makeRequestByType(self, request_type: str) -> None: Logger.log("i", "Requesting %s metadata from server.", request_type) request = QNetworkRequest(self._request_urls[request_type]) - request.setRawHeader(*self._request_header) + for header_name, header_value in self._request_headers: + request.setRawHeader(header_name, header_value) if self._network_manager: self._network_manager.get(request) @@ -578,7 +600,8 @@ class Toolbox(QObject, Extension): if hasattr(QNetworkRequest, "RedirectPolicyAttribute"): # Patch for Qt 5.9+ cast(QNetworkRequest, self._download_request).setAttribute(QNetworkRequest.RedirectPolicyAttribute, True) - cast(QNetworkRequest, self._download_request).setRawHeader(*self._request_header) + for header_name, header_value in self._request_headers: + cast(QNetworkRequest, self._download_request).setRawHeader(header_name, header_value) self._download_reply = cast(QNetworkAccessManager, self._network_manager).get(self._download_request) self.setDownloadProgress(0) self.setIsDownloading(True) @@ -660,7 +683,7 @@ class Toolbox(QObject, Extension): else: self.setViewPage("errored") self.resetDownload() - else: + elif reply.operation() == QNetworkAccessManager.PutOperation: # Ignore any operation that is not a get operation pass diff --git a/resources/themes/cura-light/icons/star_empty.svg b/resources/themes/cura-light/icons/star_empty.svg new file mode 100644 index 0000000000..39b5791e91 --- /dev/null +++ b/resources/themes/cura-light/icons/star_empty.svg @@ -0,0 +1,11 @@ + + + + Star Copy 8 + Created with Sketch. + + + + + + \ No newline at end of file diff --git a/resources/themes/cura-light/icons/star_filled.svg b/resources/themes/cura-light/icons/star_filled.svg new file mode 100644 index 0000000000..d4e161f6c6 --- /dev/null +++ b/resources/themes/cura-light/icons/star_filled.svg @@ -0,0 +1,11 @@ + + + + Star Copy 7 + Created with Sketch. + + + + + + \ No newline at end of file diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 2d7e92be4d..8d8f5dd718 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -394,6 +394,7 @@ "section": [0.0, 2.2], "section_icon": [1.6, 1.6], "section_icon_column": [2.8, 0.0], + "rating_star": [1.0, 1.0], "setting": [25.0, 1.8], "setting_control": [10.0, 2.0], From 8b25e6946adb3ea763fc25f22c3226e557d4c8bd Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 7 Dec 2018 15:33:44 +0100 Subject: [PATCH 0779/1292] Prevent attempting to rate when not logged in CURA-6013 --- plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index a72411ef4b..283d9bc0aa 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -6,6 +6,7 @@ import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import QtQuick.Layouts 1.3 import UM 1.1 as UM +import Cura 1.1 as Cura Item { @@ -92,7 +93,7 @@ Item rating: model.average_rating != undefined ? model.average_rating : 0 numRatings: model.num_ratings != undefined ? model.num_ratings : 0 userRating: model.user_rating - enabled: installedPackages != 0 + enabled: installedPackages != 0 && Cura.API.account.isLoggedIn } } } From b565b111c873dd3804f2ce50193c5836850c7fe9 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 7 Dec 2018 15:38:08 +0100 Subject: [PATCH 0780/1292] Adjust disabled extruder colour This also introduces a more global 'disabled' colour as defined by the style guide. I hope that we can gradually transition to this one, but we'll have to adjust some colours here and there. Contributes to issue CURA-5876. --- resources/qml/ExtruderIcon.qml | 2 +- resources/themes/cura-dark/theme.json | 1 + resources/themes/cura-light/theme.json | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/resources/qml/ExtruderIcon.qml b/resources/qml/ExtruderIcon.qml index 49ad73a32e..bb0b347b7e 100644 --- a/resources/qml/ExtruderIcon.qml +++ b/resources/qml/ExtruderIcon.qml @@ -23,7 +23,7 @@ Item anchors.fill: parent source: UM.Theme.getIcon("extruder_button") - color: extruderEnabled ? materialColor: "gray" + color: extruderEnabled ? materialColor: UM.Theme.getColor("disabled") } Rectangle diff --git a/resources/themes/cura-dark/theme.json b/resources/themes/cura-dark/theme.json index d9ef74ebb9..8540abf61a 100644 --- a/resources/themes/cura-dark/theme.json +++ b/resources/themes/cura-dark/theme.json @@ -35,6 +35,7 @@ "text_scene_hover": [255, 255, 255, 204], "error": [212, 31, 53, 255], + "disabled": [32, 32, 32, 255], "button": [39, 44, 48, 255], "button_hover": [39, 44, 48, 255], diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 16d13b9652..d4fb59b7a1 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -129,6 +129,7 @@ "error": [255, 140, 0, 255], "warning": [245, 166, 35, 255], + "disabled": [229, 229, 229, 255], "toolbar_button_text": [8, 7, 63, 255], "toolbar_button_hover": [232, 242, 252, 255], From fed9e2b623fcc2085a8343c479946cc4edc43c2c Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 7 Dec 2018 15:42:46 +0100 Subject: [PATCH 0781/1292] Move the click area of the download tile to just the icon CURA-6013 --- .../qml/ToolboxDownloadsGridTile.qml | 81 +++++++++---------- 1 file changed, 37 insertions(+), 44 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index 283d9bc0aa..472f273817 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -58,13 +58,49 @@ Item color: (installedPackages == packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border") source: "../images/installed_check.svg" } + + MouseArea + { + anchors.fill: thumbnail + hoverEnabled: true + onEntered: thumbnail.border.color = UM.Theme.getColor("primary") + onExited: thumbnail.border.color = UM.Theme.getColor("lining") + onClicked: + { + base.selection = model + switch(toolbox.viewCategory) + { + case "material": + + // If model has a type, it must be a package + if (model.type !== undefined) + { + toolbox.viewPage = "detail" + toolbox.filterModelByProp("packages", "id", model.id) + } + else + { + toolbox.viewPage = "author" + toolbox.setFilters("packages", { + "author_id": model.id, + "type": "material" + }) + } + break + default: + toolbox.viewPage = "detail" + toolbox.filterModelByProp("packages", "id", model.id) + break + } + } + } } Column { width: parent.width - thumbnail.width - parent.spacing spacing: Math.floor(UM.Theme.getSize("narrow_margin").width) anchors.top: parent.top - anchors.topMargin: UM.Theme.getSize("default_margin").height + //anchors.topMargin: UM.Theme.getSize("default_margin").height Label { id: name @@ -97,47 +133,4 @@ Item } } } - MouseArea - { - anchors.fill: parent - hoverEnabled: true - onEntered: - { - thumbnail.border.color = UM.Theme.getColor("primary") - highlight.opacity = 0.1 - } - onExited: - { - thumbnail.border.color = UM.Theme.getColor("lining") - highlight.opacity = 0.0 - } - onClicked: - { - base.selection = model - switch(toolbox.viewCategory) - { - case "material": - - // If model has a type, it must be a package - if (model.type !== undefined) - { - toolbox.viewPage = "detail" - toolbox.filterModelByProp("packages", "id", model.id) - } - else - { - toolbox.viewPage = "author" - toolbox.setFilters("packages", { - "author_id": model.id, - "type": "material" - }) - } - break - default: - toolbox.viewPage = "detail" - toolbox.filterModelByProp("packages", "id", model.id) - break - } - } - } } From 4742db6fec2a82aa5e8d5bc95c764d0ce9d69e0b Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 7 Dec 2018 15:57:52 +0100 Subject: [PATCH 0782/1292] Cleanup gridTile CURA-6013 --- .../qml/ToolboxDownloadsGridTile.qml | 209 +++++++++--------- 1 file changed, 104 insertions(+), 105 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index 472f273817..7ced23aee9 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -13,124 +13,123 @@ Item id: toolboxDownloadsGridTile property int packageCount: (toolbox.viewCategory == "material" && model.type === undefined) ? toolbox.getTotalNumberOfMaterialPackagesByAuthor(model.id) : 1 property int installedPackages: (toolbox.viewCategory == "material" && model.type === undefined) ? toolbox.getNumberOfInstalledPackagesByAuthor(model.id) : (toolbox.isInstalled(model.id) ? 1 : 0) - height: childrenRect.height + height: UM.Theme.getSize("toolbox_thumbnail_small").height Layout.alignment: Qt.AlignTop | Qt.AlignLeft + Rectangle { - id: highlight - anchors.fill: parent - opacity: 0.0 - color: UM.Theme.getColor("primary") - } - Row - { - width: parent.width - height: childrenRect.height - spacing: Math.floor(UM.Theme.getSize("narrow_margin").width) - Rectangle + id: thumbnail + width: UM.Theme.getSize("toolbox_thumbnail_small").width + height: UM.Theme.getSize("toolbox_thumbnail_small").height + color: "white" + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("lining") + + Image { - id: thumbnail - width: UM.Theme.getSize("toolbox_thumbnail_small").width - height: UM.Theme.getSize("toolbox_thumbnail_small").height - color: "white" - border.width: UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("lining") - Image - { - anchors.centerIn: parent - width: UM.Theme.getSize("toolbox_thumbnail_small").width - UM.Theme.getSize("wide_margin").width - height: UM.Theme.getSize("toolbox_thumbnail_small").height - UM.Theme.getSize("wide_margin").width - fillMode: Image.PreserveAspectFit - source: model.icon_url || "../images/logobot.svg" - mipmap: true - } - UM.RecolorImage - { - width: (parent.width * 0.4) | 0 - height: (parent.height * 0.4) | 0 - anchors - { - bottom: parent.bottom - right: parent.right - } - sourceSize.height: height - visible: installedPackages != 0 - color: (installedPackages == packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border") - source: "../images/installed_check.svg" - } + anchors.centerIn: parent + width: UM.Theme.getSize("toolbox_thumbnail_small").width - UM.Theme.getSize("wide_margin").width + height: UM.Theme.getSize("toolbox_thumbnail_small").height - UM.Theme.getSize("wide_margin").width + fillMode: Image.PreserveAspectFit + source: model.icon_url || "../images/logobot.svg" + mipmap: true - MouseArea - { - anchors.fill: thumbnail - hoverEnabled: true - onEntered: thumbnail.border.color = UM.Theme.getColor("primary") - onExited: thumbnail.border.color = UM.Theme.getColor("lining") - onClicked: - { - base.selection = model - switch(toolbox.viewCategory) - { - case "material": - // If model has a type, it must be a package - if (model.type !== undefined) - { - toolbox.viewPage = "detail" - toolbox.filterModelByProp("packages", "id", model.id) - } - else - { - toolbox.viewPage = "author" - toolbox.setFilters("packages", { - "author_id": model.id, - "type": "material" - }) - } - break - default: + } + UM.RecolorImage + { + width: (parent.width * 0.4) | 0 + height: (parent.height * 0.4) | 0 + anchors + { + bottom: parent.bottom + right: parent.right + } + sourceSize.height: height + visible: installedPackages != 0 + color: (installedPackages == packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border") + source: "../images/installed_check.svg" + } + + MouseArea + { + anchors.fill: thumbnail + hoverEnabled: true + onEntered: thumbnail.border.color = UM.Theme.getColor("primary") + onExited: thumbnail.border.color = UM.Theme.getColor("lining") + onClicked: + { + base.selection = model + switch(toolbox.viewCategory) + { + case "material": + + // If model has a type, it must be a package + if (model.type !== undefined) + { toolbox.viewPage = "detail" toolbox.filterModelByProp("packages", "id", model.id) - break - } + } + else + { + toolbox.viewPage = "author" + toolbox.setFilters("packages", { + "author_id": model.id, + "type": "material" + }) + } + break + default: + toolbox.viewPage = "detail" + toolbox.filterModelByProp("packages", "id", model.id) + break } } } - Column + } + Item + { + anchors { - width: parent.width - thumbnail.width - parent.spacing - spacing: Math.floor(UM.Theme.getSize("narrow_margin").width) - anchors.top: parent.top - //anchors.topMargin: UM.Theme.getSize("default_margin").height - Label - { - id: name - text: model.name - width: parent.width - wrapMode: Text.WordWrap - color: UM.Theme.getColor("text") - font: UM.Theme.getFont("default_bold") - } - Label - { - id: info - text: model.description - maximumLineCount: 2 - elide: Text.ElideRight - width: parent.width - wrapMode: Text.WordWrap - color: UM.Theme.getColor("text_medium") - font: UM.Theme.getFont("default") - } + left: thumbnail.right + leftMargin: Math.floor(UM.Theme.getSize("narrow_margin").width) + right: parent.right + top: parent.top + bottom: parent.bottom + } - RatingWidget - { - visible: model.type == "plugin" - packageId: model.id - rating: model.average_rating != undefined ? model.average_rating : 0 - numRatings: model.num_ratings != undefined ? model.num_ratings : 0 - userRating: model.user_rating - enabled: installedPackages != 0 && Cura.API.account.isLoggedIn - } + Label + { + id: name + text: model.name + width: parent.width + elide: Text.ElideRight + color: UM.Theme.getColor("text") + font: UM.Theme.getFont("default_bold") + } + Label + { + id: info + text: model.description + elide: Text.ElideRight + width: parent.width + wrapMode: Text.WordWrap + color: UM.Theme.getColor("text_medium") + font: UM.Theme.getFont("default") + anchors.top: name.bottom + anchors.bottom: rating.top + verticalAlignment: Text.AlignVCenter + } + RatingWidget + { + id: rating + visible: model.type == "plugin" + packageId: model.id + rating: model.average_rating != undefined ? model.average_rating : 0 + numRatings: model.num_ratings != undefined ? model.num_ratings : 0 + userRating: model.user_rating + enabled: installedPackages != 0 && Cura.API.account.isLoggedIn + anchors.bottom: parent.bottom } } } From 50099ab7530da3d307426c4b069ef621fd9654b6 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 7 Dec 2018 16:02:21 +0100 Subject: [PATCH 0783/1292] Make a few missed items themeable as well CURA-6013 --- plugins/Toolbox/resources/qml/ToolboxDetailPage.qml | 2 +- plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 9e2e178b71..4e0bf67544 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -37,7 +37,7 @@ Item leftMargin: UM.Theme.getSize("wide_margin").width topMargin: UM.Theme.getSize("wide_margin").height } - color: "white" //Always a white background for image (regardless of theme). + color: UM.Theme.getColor("main_background") Image { anchors.fill: parent diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index 7ced23aee9..70edee7449 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -21,7 +21,7 @@ Item id: thumbnail width: UM.Theme.getSize("toolbox_thumbnail_small").width height: UM.Theme.getSize("toolbox_thumbnail_small").height - color: "white" + color: UM.Theme.getColor("main_background") border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") From 07801b5394ae654a7fbd40c7f7a82b92baaedc1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Fri, 7 Dec 2018 16:21:08 +0100 Subject: [PATCH 0784/1292] First test for CloudDevices --- .../tests/Cloud/TestCloudApiClient.py | 136 ++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py new file mode 100644 index 0000000000..328bb053b7 --- /dev/null +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py @@ -0,0 +1,136 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +import json +from typing import Dict, Tuple +from unittest import TestCase, mock +from unittest.mock import patch, MagicMock + +from PyQt5.QtCore import QByteArray +from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkReply + +from UM.Application import Application +from UM.Signal import Signal +from cura.CuraApplication import CuraApplication +from plugins.UM3NetworkPrinting.src.Cloud.CloudApiClient import CloudApiClient +from plugins.UM3NetworkPrinting.src.Cloud.Models import CloudCluster, CloudErrorObject + +# This mock application must extend from Application and not QtApplication otherwise some QObjects are created and +# a segfault is raised. +class FixtureApplication(Application): + def __init__(self): + super().__init__(name = "test", version = "1.0", api_version = "5.0.0") + super().initialize() + Signal._signalQueue = self + + def functionEvent(self, event): + event.call() + + def parseCommandLine(self): + pass + + def processEvents(self): + pass + + def getRenderer(self): + return MagicMock() + +class ManagerMock: + finished = Signal() + authenticationRequired = Signal() + + def __init__(self, reply): + self.reply = reply + + def get(self, request): + self.reply.url.return_value = request.url() + + return self.reply + +class ManagerMock2: + finished = Signal() + authenticationRequired = Signal() + + def get(self, request): + reply_mock = MagicMock() + reply_mock.url = request.url + reply_mock.operation.return_value = QNetworkAccessManager.GetOperation + return reply_mock + + @staticmethod + def createReply(method: str, url: str, status_code: int, response: dict): + reply_mock = MagicMock() + reply_mock.url().toString.return_value = url + reply_mock.operation.return_value = { + "GET": QNetworkAccessManager.GetOperation, + "POST": QNetworkAccessManager.PostOperation, + "PUT": QNetworkAccessManager.PutOperation, + "DELETE": QNetworkAccessManager.DeleteOperation, + "HEAD": QNetworkAccessManager.HeadOperation, + }[method] + reply_mock.attribute.return_value = status_code + reply_mock.readAll.return_value = json.dumps(response).encode() + return reply_mock + + +class TestCloudApiClient(TestCase): + + app = CuraApplication.getInstance() or CuraApplication + + def _errorHandler(self, errors: [CloudErrorObject]): + pass + + @patch("cura.NetworkClient.QNetworkAccessManager") + @patch("cura.API.Account") + def test_GetClusters(self, account_mock, manager_mock): + reply_mock = MagicMock() + reply_mock.operation.return_value = 2 + reply_mock.attribute.return_value = 200 + reply_mock.readAll.return_value = b'{"data": [{"cluster_id": "RIZ6cZbWA_Ua7RZVJhrdVfVpf0z-MqaSHQE4v8aRTtYq", "host_guid": "e90ae0ac-1257-4403-91ee-a44c9b7e8050", "host_name": "ultimakersystem-ccbdd30044ec", "host_version": "5.1.2.20180807", "is_online": false, "status": "inactive"}, {"cluster_id": "R0YcLJwar1ugh0ikEZsZs8NWKV6vJP_LdYsXgXqAcaNC", "host_guid": "e90ae0ac-1257-4403-91ee-a44c9b7e8050", "host_name": "ultimakersystem-ccbdd30044ec", "host_version": "5.1.2.20180807", "is_online": true, "status": "active"}]}' + manager_mock.return_value = ManagerMock(reply_mock) + account_mock.isLoggedIn.return_value = True + + result = [] + + def _callback(clusters): + result.extend(clusters) + + with mock.patch.object(Application, "getInstance", new = lambda: FixtureApplication()): + api = CloudApiClient(account_mock, self._errorHandler) + api.getClusters(_callback) + + manager_mock.return_value.finished.emit(reply_mock) + + self.assertEqual(2, len(result)) + + @patch("cura.NetworkClient.QNetworkAccessManager") + @patch("cura.API.Account") + def test_GetClusters2(self, account_mock, manager_mock): + manager = ManagerMock2() + manager_mock.return_value = manager + account_mock.isLoggedIn.return_value = True + + result = [] + + # with mock.patch.object(Application, "getInstance", new = lambda: FixtureApplication()): + api = CloudApiClient(account_mock, self._errorHandler) + api.getClusters(lambda clusters: result.extend(clusters)) + + manager.finished.emit(ManagerMock2.createReply( + "GET", "https://api-staging.ultimaker.com/connect/v1/clusters", + 200, { + "data": [{ + "cluster_id": "RIZ6cZbWA_Ua7RZVJhrdVfVpf0z-MqaSHQE4v8aRTtYq", + "host_guid": "e90ae0ac-1257-4403-91ee-a44c9b7e8050", + "host_name": "ultimakersystem-ccbdd30044ec", "host_version": "5.1.2.20180807", + "is_online": False, "status": "inactive" + }, { + "cluster_id": "R0YcLJwar1ugh0ikEZsZs8NWKV6vJP_LdYsXgXqAcaNC", + "host_guid": "e90ae0ac-1257-4403-91ee-a44c9b7e8050", + "host_name": "ultimakersystem-ccbdd30044ec", "host_version": "5.1.2.20180807", + "is_online": True, "status": "active" + }] + } + )) + + self.assertEqual(2, len(result)) From 63c5b779595cb1488c44094eb431694430161625 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 7 Dec 2018 16:43:53 +0100 Subject: [PATCH 0785/1292] STAR-322: Fixing finished jobs --- .../src/Cloud/CloudOutputDevice.py | 54 +++++++++---------- .../src/Cloud/CloudOutputDeviceManager.py | 9 ++-- 2 files changed, 30 insertions(+), 33 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 321c40bc74..2800bc1c8c 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -1,10 +1,9 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import os -from datetime import datetime from time import time -from typing import Dict, List, Optional +from typing import Dict, List, Optional, Set from PyQt5.QtCore import QObject, QUrl, pyqtProperty, pyqtSignal, pyqtSlot @@ -92,7 +91,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self._host_name = host_name self._setInterfaceElements() - + self._device_id = device_id self._account = CuraApplication.getInstance().getCuraAPI().account @@ -111,7 +110,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # Properties to populate later on with received cloud data. self._print_jobs = [] # type: List[UM3PrintJobOutputModel] self._number_of_extruders = 2 # All networked printers are dual-extrusion Ultimaker machines. - + # We only allow a single upload at a time. self._sending_job = False # TODO: handle progress messages in another class. @@ -121,6 +120,9 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self._received_printers = None # type: Optional[List[CloudClusterPrinter]] self._received_print_jobs = None # type: Optional[List[CloudClusterPrintJob]] + # A set of the user's job IDs that have finished + self._finished_jobs = set() # type: Set[str] + ## Gets the host name of this device @property def host_name(self) -> str: @@ -144,16 +146,16 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self.setShortDescription(T.PRINT_VIA_CLOUD_BUTTON) self.setDescription(T.PRINT_VIA_CLOUD_TOOLTIP) self.setConnectionText(T.CONNECTED_VIA_CLOUD) - + ## Called when Cura requests an output device to receive a (G-code) file. def requestWrite(self, nodes: List[SceneNode], file_name: Optional[str] = None, limit_mime_types: bool = False, file_handler: Optional[FileHandler] = None, **kwargs: str) -> None: - + # Show an error message if we're already sending a job. if self._sending_job: self._onUploadError(T.BLOCKED_UPLOADING) return - + # Indicate we have started sending a job. self._sending_job = True self.writeStarted.emit(self) @@ -165,9 +167,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): mesh_bytes = mesh_format.getBytes(nodes) - # TODO: Remove extension from the file name, since we are using content types now request = CloudJobUploadRequest( - job_name = file_name, ## + "." + mesh_format.file_extension, + job_name = file_name, file_size = len(mesh_bytes), content_type = mesh_format.mime_type, ) @@ -261,18 +262,15 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## Handles the event of a change in a print job state def _onPrintJobStateChanged(self) -> None: - username = self._account.userName - finished_jobs = [job for job in self._print_jobs if job.state == "wait_cleanup"] - - newly_finished_jobs = [job for job in finished_jobs if job not in self._finished_jobs and job.owner == username] - for job in newly_finished_jobs: - if job.assignedPrinter: - job_completed_text = T.JOB_COMPLETED_PRINTER.format(printer_name=job.assignedPrinter.name, - job_name=job.name) - else: - job_completed_text = T.JOB_COMPLETED_NO_PRINTER.format(job_name=job.name) - job_completed_message = Message(text=job_completed_text, title = T.JOB_COMPLETED_TITLE) - job_completed_message.show() + user_name = self._getUserName() + for job in self._print_jobs: + if job.state == "wait_cleanup" and job.key not in self._finished_jobs and job.owner == user_name: + self._finished_jobs.add(job.key) + Message( + title = T.JOB_COMPLETED_TITLE, + text = (T.JOB_COMPLETED_PRINTER.format(printer_name=job.assignedPrinter.name, job_name=job.name) + if job.assignedPrinter else T.JOB_COMPLETED_NO_PRINTER.format(job_name=job.name)), + ).show() # Ensure UI gets updated self.printJobsChanged.emit() @@ -326,13 +324,12 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def _onUploadError(self, message: str = None) -> None: self._resetUploadProgress() if message: - message = Message( + Message( text = message, title = T.ERROR, lifetime = 10, dismissable = True - ) - message.show() + ).show() self._sending_job = False # the upload has finished so we're not sending a job anymore self.writeError.emit() @@ -341,18 +338,17 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def _onUploadSuccess(self, response: CloudPrintResponse) -> None: Logger.log("i", "The cluster will be printing this print job with the ID %s", response.cluster_job_id) self._resetUploadProgress() - message = Message( + Message( text = T.UPLOAD_SUCCESS_TEXT, title = T.UPLOAD_SUCCESS_TITLE, lifetime = 5, dismissable = True, - ) - message.show() + ).show() self._sending_job = False # the upload has finished so we're not sending a job anymore self.writeFinished.emit() ## Gets the remote printers. - @pyqtProperty("QVariantList", notify = _clusterPrintersChanged) + @pyqtProperty("QVariantList", notify=_clusterPrintersChanged) def printers(self) -> List[PrinterOutputModel]: return self._printers @@ -374,7 +370,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## Get remote print jobs. @pyqtProperty("QVariantList", notify = printJobsChanged) - def printJobs(self)-> List[UM3PrintJobOutputModel]: + def printJobs(self) -> List[UM3PrintJobOutputModel]: return self._print_jobs ## Get remote print jobs that are still in the print queue. diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index bc410a4a1d..f06bbb305e 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -7,6 +7,7 @@ from PyQt5.QtCore import QTimer from UM import i18nCatalog from UM.Logger import Logger from UM.Message import Message +from cura.API import Account from cura.CuraApplication import CuraApplication from cura.Settings.GlobalStack import GlobalStack from .CloudApiClient import CloudApiClient @@ -40,7 +41,7 @@ class CloudOutputDeviceManager: application = CuraApplication.getInstance() self._output_device_manager = application.getOutputDeviceManager() - self._account = application.getCuraAPI().account + self._account = application.getCuraAPI().account # type: Account self._account.loginStateChanged.connect(self._onLoginStateChanged) self._api = CloudApiClient(self._account, self._onApiError) @@ -54,11 +55,11 @@ class CloudOutputDeviceManager: self._update_timer.timeout.connect(self._getRemoteClusters) # Make sure the timer is started in case we missed the loginChanged signal - self._onLoginStateChanged() + self._onLoginStateChanged(self._account.isLoggedIn) # Called when the uses logs in or out - def _onLoginStateChanged(self) -> None: - if self._account.isLoggedIn: + def _onLoginStateChanged(self, is_logged_in: bool) -> None: + if is_logged_in: if not self._update_timer.isActive(): self._update_timer.start() else: From e92bd01fb28d460facdd5f0e7883267a25379aeb Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 7 Dec 2018 17:28:42 +0100 Subject: [PATCH 0786/1292] Removed the rating from the download grid It felt a bit weird to already have it in the grid layout CURA-6013 --- .../qml/ToolboxDownloadsGridTile.qml | 112 +++++++++++------- plugins/Toolbox/src/PackagesModel.py | 2 +- 2 files changed, 67 insertions(+), 47 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index 70edee7449..677e532827 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -16,6 +16,42 @@ Item height: UM.Theme.getSize("toolbox_thumbnail_small").height Layout.alignment: Qt.AlignTop | Qt.AlignLeft + MouseArea + { + anchors.fill: parent + hoverEnabled: true + onEntered: thumbnail.border.color = UM.Theme.getColor("primary") + onExited: thumbnail.border.color = UM.Theme.getColor("lining") + onClicked: + { + base.selection = model + switch(toolbox.viewCategory) + { + case "material": + + // If model has a type, it must be a package + if (model.type !== undefined) + { + toolbox.viewPage = "detail" + toolbox.filterModelByProp("packages", "id", model.id) + } + else + { + toolbox.viewPage = "author" + toolbox.setFilters("packages", { + "author_id": model.id, + "type": "material" + }) + } + break + default: + toolbox.viewPage = "detail" + toolbox.filterModelByProp("packages", "id", model.id) + break + } + } + } + Rectangle { id: thumbnail @@ -33,8 +69,6 @@ Item fillMode: Image.PreserveAspectFit source: model.icon_url || "../images/logobot.svg" mipmap: true - - } UM.RecolorImage { @@ -50,42 +84,6 @@ Item color: (installedPackages == packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border") source: "../images/installed_check.svg" } - - MouseArea - { - anchors.fill: thumbnail - hoverEnabled: true - onEntered: thumbnail.border.color = UM.Theme.getColor("primary") - onExited: thumbnail.border.color = UM.Theme.getColor("lining") - onClicked: - { - base.selection = model - switch(toolbox.viewCategory) - { - case "material": - - // If model has a type, it must be a package - if (model.type !== undefined) - { - toolbox.viewPage = "detail" - toolbox.filterModelByProp("packages", "id", model.id) - } - else - { - toolbox.viewPage = "author" - toolbox.setFilters("packages", { - "author_id": model.id, - "type": "material" - }) - } - break - default: - toolbox.viewPage = "detail" - toolbox.filterModelByProp("packages", "id", model.id) - break - } - } - } } Item { @@ -119,17 +117,39 @@ Item anchors.top: name.bottom anchors.bottom: rating.top verticalAlignment: Text.AlignVCenter + maximumLineCount: 2 } - RatingWidget + Row { id: rating - visible: model.type == "plugin" - packageId: model.id - rating: model.average_rating != undefined ? model.average_rating : 0 - numRatings: model.num_ratings != undefined ? model.num_ratings : 0 - userRating: model.user_rating - enabled: installedPackages != 0 && Cura.API.account.isLoggedIn - anchors.bottom: parent.bottom + height: UM.Theme.getSize("rating_star").height + visible: model.average_rating > 0 //Has a rating at all. + spacing: UM.Theme.getSize("thick_lining").width + anchors + { + bottom: parent.bottom + left: parent.left + right: parent.right + } + + UM.RecolorImage + { + id: starIcon + source: UM.Theme.getIcon("star_filled") + color: "#5a5a5a" + height: UM.Theme.getSize("rating_star").height + width: UM.Theme.getSize("rating_star").width + } + + Label + { + text: model.average_rating.toFixed(1) + " (" + model.num_ratings + " " + catalog.i18nc("@label", "ratings") + ")" + verticalAlignment: Text.AlignVCenter + height: starIcon.height + anchors.verticalCenter: starIcon.verticalCenter + color: starIcon.color + font: UM.Theme.getFont("small") + } } } } diff --git a/plugins/Toolbox/src/PackagesModel.py b/plugins/Toolbox/src/PackagesModel.py index b3c388bc7c..3f5be3bc37 100644 --- a/plugins/Toolbox/src/PackagesModel.py +++ b/plugins/Toolbox/src/PackagesModel.py @@ -105,7 +105,7 @@ class PackagesModel(ListModel): "links": links_dict, "website": package["website"] if "website" in package else None, "login_required": "login-required" in package.get("tags", []), - "average_rating": package.get("rating", {}).get("average", 0), + "average_rating": float(package.get("rating", {}).get("average", 0)), "num_ratings": package.get("rating", {}).get("count", 0), "user_rating": package.get("rating", {}).get("user", 0) }) From 9dc8450db0aa3ba21b969f787a29a6fe775058f2 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 7 Dec 2018 17:37:10 +0100 Subject: [PATCH 0787/1292] Fix typo --- .../Recommended/RecommendedQualityProfileSelector.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml index 4963f10792..15d40f545a 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml @@ -350,7 +350,7 @@ Item enabled: !Cura.SimpleModeSettingsManager.isProfileUserCreated onEntered: { - var tooltipContent = catalog.i18nc("@tooltip", "This quality profile is not available for you current material and nozzle configuration. Please change these to enable this quality profile") + var tooltipContent = catalog.i18nc("@tooltip", "This quality profile is not available for your current material and nozzle configuration. Please change these to enable this quality profile") base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, customisedSettings.height), tooltipContent) } onExited: base.hideTooltip() From e0b159e2ad78fe8110a5e959526b8c706ad45eb7 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 7 Dec 2018 17:46:35 +0100 Subject: [PATCH 0788/1292] STAR-322: Creating a network manager mock --- .../tests/Cloud/NetworkManagerMock.py | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py b/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py new file mode 100644 index 0000000000..b14ee760d9 --- /dev/null +++ b/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py @@ -0,0 +1,42 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +import json +from unittest.mock import MagicMock + +from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkReply, QNetworkRequest + +from UM.Signal import Signal + + +class NetworkManagerMock: + finished = Signal() + authenticationRequired = Signal() + + _OPERATIONS = { + "GET": QNetworkAccessManager.GetOperation, + "POST": QNetworkAccessManager.PostOperation, + "PUT": QNetworkAccessManager.PutOperation, + "DELETE": QNetworkAccessManager.DeleteOperation, + "HEAD": QNetworkAccessManager.HeadOperation, + } + + def __getattr__(self, item): + operation = self._OPERATIONS.get(item.upper()) + if operation: + return lambda request, *_: self._fakeReply(operation, request) + return super().__getattribute__(item) + + def _fakeReply(self, operation: QNetworkAccessManager.Operation, request: QNetworkRequest) -> QNetworkReply: + reply_mock = MagicMock() + reply_mock.url = request.url + reply_mock.operation.return_value = operation + return reply_mock + + def respond(self, method: str, url: str, status_code: int, response: dict) -> QNetworkReply: + reply_mock = MagicMock() + reply_mock.url().toString.return_value = url + reply_mock.operation.return_value = self._OPERATIONS[method] + reply_mock.attribute.return_value = status_code + reply_mock.readAll.return_value = json.dumps(response).encode() + self.finished.emit(reply_mock) + return reply_mock From 45f51c358866a09810dacfc9508c4c06cbc18ec4 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 7 Dec 2018 18:09:20 +0100 Subject: [PATCH 0789/1292] STAR-322: First test cloud output device manager --- .../tests/Cloud/NetworkManagerMock.py | 32 +++++++----- .../Cloud/TestCloudOutputDeviceManager.py | 51 +++++++++++++++++++ .../tests/Cloud/__init__.py | 2 + 3 files changed, 71 insertions(+), 14 deletions(-) create mode 100644 plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py create mode 100644 plugins/UM3NetworkPrinting/tests/Cloud/__init__.py diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py b/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py index b14ee760d9..945c526814 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py @@ -1,9 +1,10 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import json +from typing import Dict, Tuple from unittest.mock import MagicMock -from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkReply, QNetworkRequest +from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkReply from UM.Signal import Signal @@ -20,23 +21,26 @@ class NetworkManagerMock: "HEAD": QNetworkAccessManager.HeadOperation, } - def __getattr__(self, item): - operation = self._OPERATIONS.get(item.upper()) + def __init__(self): + self.replies = {} # type: Dict[Tuple[str, str], QNetworkReply] + + def __getattr__(self, method): + operation = self._OPERATIONS.get(method.upper()) if operation: - return lambda request, *_: self._fakeReply(operation, request) - return super().__getattribute__(item) + return lambda request, *_: self.replies[method.upper(), request.url().toString()] + return super().__getattribute__(method) - def _fakeReply(self, operation: QNetworkAccessManager.Operation, request: QNetworkRequest) -> QNetworkReply: - reply_mock = MagicMock() - reply_mock.url = request.url - reply_mock.operation.return_value = operation - return reply_mock - - def respond(self, method: str, url: str, status_code: int, response: dict) -> QNetworkReply: + def prepareResponse(self, method: str, url: str, status_code: int, response: dict) -> None: reply_mock = MagicMock() reply_mock.url().toString.return_value = url reply_mock.operation.return_value = self._OPERATIONS[method] reply_mock.attribute.return_value = status_code reply_mock.readAll.return_value = json.dumps(response).encode() - self.finished.emit(reply_mock) - return reply_mock + self.replies[method, url] = reply_mock + + def flushReplies(self): + for reply in self.replies.values(): + self.finished.emit(reply) + + def reset(self): + self.replies.clear() diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py new file mode 100644 index 0000000000..cf86f713b2 --- /dev/null +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py @@ -0,0 +1,51 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +from unittest import TestCase +from unittest.mock import patch + +from cura.CuraApplication import CuraApplication +from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputDevice import CloudOutputDevice +from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputDeviceManager import CloudOutputDeviceManager +from plugins.UM3NetworkPrinting.tests.Cloud.NetworkManagerMock import NetworkManagerMock + + +@patch("cura.NetworkClient.QNetworkAccessManager") +class TestCloudOutputDeviceManager(TestCase): + app = CuraApplication.getInstance() or CuraApplication() + + def setUp(self): + super().setUp() + self.app.initialize() + + self.network = NetworkManagerMock() + self.network.prepareResponse( + "GET", "https://api-staging.ultimaker.com/connect/v1/clusters", + 200, { + "data": [{ + "cluster_id": "RIZ6cZbWA_Ua7RZVJhrdVfVpf0z-MqaSHQE4v8aRTtYq", + "host_guid": "e90ae0ac-1257-4403-91ee-a44c9b7e8050", + "host_name": "ultimakersystem-ccbdd30044ec", "host_version": "5.1.2.20180807", + "is_online": False, "status": "inactive" + }, { + "cluster_id": "R0YcLJwar1ugh0ikEZsZs8NWKV6vJP_LdYsXgXqAcaNC", + "host_guid": "e90ae0ac-1257-4403-91ee-a44c9b7e8050", + "host_name": "ultimakersystem-ccbdd30044ec", "host_version": "5.1.2.20180807", + "is_online": True, "status": "active" + }] + } + ) + + def tearDown(self): + super().tearDown() + + def test_device(self, network_mock): + network_mock.return_value = self.network + + manager = CloudOutputDeviceManager() + manager._account.loginStateChanged.emit(True) + manager._update_timer.timeout.emit() + + self.network.flushReplies() + + devices = self.app.getOutputDeviceManager().getOutputDevices() + self.assertEqual([CloudOutputDevice], list(map(type, devices))) diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/__init__.py b/plugins/UM3NetworkPrinting/tests/Cloud/__init__.py new file mode 100644 index 0000000000..f3f6970c54 --- /dev/null +++ b/plugins/UM3NetworkPrinting/tests/Cloud/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. From 2bf641efcfef28bbdae869ab3bfb6d8d4f70d8de Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 10 Dec 2018 09:09:58 +0100 Subject: [PATCH 0790/1292] Add a Cura Tooltip to show in some buttons Contributes to CURA-6004. --- resources/qml/ActionButton.qml | 8 ++-- .../ActionPanel/OutputDevicesActionButton.qml | 1 - .../qml/ActionPanel/SliceProcessWidget.qml | 1 + resources/qml/PrintSetupTooltip.qml | 5 +-- resources/qml/ToolTip.qml | 43 +++++++++++++++++++ resources/qml/ToolbarButton.qml | 7 +++ resources/qml/qmldir | 3 +- resources/themes/cura-light/theme.json | 2 +- 8 files changed, 59 insertions(+), 11 deletions(-) create mode 100644 resources/qml/ToolTip.qml diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index 7177120f35..aa4d3f21c0 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -16,7 +16,7 @@ Button property alias iconSource: buttonIconLeft.source property alias textFont: buttonText.font property alias cornerRadius: backgroundRect.radius - property alias tooltip: tooltip.text + property alias tooltip: tooltip.tooltipText property alias cornerSide: backgroundRect.cornerSide property color color: UM.Theme.getColor("primary") @@ -109,11 +109,9 @@ Button z: backgroundRect.z - 1 } - ToolTip + Cura.ToolTip { id: tooltip - text: "" - delay: 500 - visible: text != "" && button.hovered + show: button.hovered } } \ No newline at end of file diff --git a/resources/qml/ActionPanel/OutputDevicesActionButton.qml b/resources/qml/ActionPanel/OutputDevicesActionButton.qml index 9a6c97bcff..2858bc267c 100644 --- a/resources/qml/ActionPanel/OutputDevicesActionButton.qml +++ b/resources/qml/ActionPanel/OutputDevicesActionButton.qml @@ -55,7 +55,6 @@ Item leftPadding: UM.Theme.getSize("narrow_margin").width //Need more space than usual here for wide text. rightPadding: UM.Theme.getSize("narrow_margin").width - tooltip: popup.opened ? "" : catalog.i18nc("@info:tooltip", "Select the active output device") iconSource: popup.opened ? UM.Theme.getIcon("arrow_top") : UM.Theme.getIcon("arrow_bottom") color: UM.Theme.getColor("action_panel_secondary") visible: (devicesModel.deviceCount > 1) diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index 18caeafb40..2d377abcd8 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -109,6 +109,7 @@ Column fixedWidthMode: true anchors.fill: parent text: catalog.i18nc("@button", "Slice") + tooltip: "Start slicing process" enabled: widget.backendState != UM.Backend.Error visible: widget.backendState == UM.Backend.NotStarted || widget.backendState == UM.Backend.Error onClicked: sliceOrStopSlicing() diff --git a/resources/qml/PrintSetupTooltip.qml b/resources/qml/PrintSetupTooltip.qml index 4fa4ef9dd7..693b703813 100644 --- a/resources/qml/PrintSetupTooltip.qml +++ b/resources/qml/PrintSetupTooltip.qml @@ -2,9 +2,7 @@ // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 -import QtQuick.Controls 1.1 -import QtQuick.Controls.Styles 1.1 -import QtQuick.Layouts 1.1 +import QtQuick.Controls 2.3 import UM 1.0 as UM @@ -57,5 +55,6 @@ UM.PointingRectangle { textFormat: Text.RichText font: UM.Theme.getFont("default"); color: UM.Theme.getColor("tooltip_text"); + renderType: Text.NativeRendering } } diff --git a/resources/qml/ToolTip.qml b/resources/qml/ToolTip.qml new file mode 100644 index 0000000000..ed71d3983b --- /dev/null +++ b/resources/qml/ToolTip.qml @@ -0,0 +1,43 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.3 + +import UM 1.0 as UM + +ToolTip +{ + // This property indicates when the tooltip has to show, for instance when a button is hovered + property bool show: false + + property alias tooltipText: tooltip.text + property var targetPoint: Qt.point(0, 0) + + id: tooltip + text: "" + delay: 500 + visible: text != "" && show + font: UM.Theme.getFont("default") + + background: UM.PointingRectangle + { + id: backgroundRect + color: UM.Theme.getColor("tooltip") + + target: Qt.point(targetPoint.x - tooltip.x, targetPoint.y - tooltip.y) + + arrowSize: UM.Theme.getSize("default_arrow").width + } + + contentItem: Label + { + id: label + text: tooltip.text + font: tooltip.font + wrapMode: Text.Wrap + textFormat: Text.RichText + color: UM.Theme.getColor("tooltip_text") + renderType: Text.NativeRendering + } +} \ No newline at end of file diff --git a/resources/qml/ToolbarButton.qml b/resources/qml/ToolbarButton.qml index adff73fb7c..307d49302c 100644 --- a/resources/qml/ToolbarButton.qml +++ b/resources/qml/ToolbarButton.qml @@ -96,4 +96,11 @@ Button height: UM.Theme.getSize("button_icon").height } } + + Cura.ToolTip + { + id: tooltip + tooltipText: base.text + show: base.hovered + } } diff --git a/resources/qml/qmldir b/resources/qml/qmldir index 1dc21150ce..80e0f8be46 100644 --- a/resources/qml/qmldir +++ b/resources/qml/qmldir @@ -14,4 +14,5 @@ PrinterTypeLabel 1.0 PrinterTypeLabel.qml ViewsSelector 1.0 ViewsSelector.qml ToolbarButton 1.0 ToolbarButton.qml SettingView 1.0 SettingView.qml -ProfileMenu 1.0 ProfileMenu.qml \ No newline at end of file +ProfileMenu 1.0 ProfileMenu.qml +ToolTip 1.0 ToolTip.qml \ No newline at end of file diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 16d13b9652..86201db809 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -240,7 +240,7 @@ "checkbox_disabled": [223, 223, 223, 255], "checkbox_text": [35, 35, 35, 255], - "tooltip": [68, 192, 255, 255], + "tooltip": [19, 19, 19, 255], "tooltip_text": [255, 255, 255, 255], "tool_button_border": [255, 255, 255, 0], From c495ade2d363d9f19e3bb6a8444073e1c86fe3fc Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 10 Dec 2018 09:42:26 +0100 Subject: [PATCH 0791/1292] STAR-322: Documenting the network manager mock --- .../tests/Cloud/NetworkManagerMock.py | 46 +++++++++++++++++-- .../Cloud/TestCloudOutputDeviceManager.py | 21 ++------- 2 files changed, 47 insertions(+), 20 deletions(-) diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py b/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py index 945c526814..25107971c0 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py @@ -9,10 +9,15 @@ from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkReply from UM.Signal import Signal +## This class can be used to mock the QNetworkManager class and test the code using it. +# After patching the QNetworkManager class, requests are prepared before they can be executed. +# Any requests not prepared beforehand will cause KeyErrors. class NetworkManagerMock: + # signals used in the network manager. finished = Signal() authenticationRequired = Signal() + # an enumeration of the supported operations and their code for the network access manager. _OPERATIONS = { "GET": QNetworkAccessManager.GetOperation, "POST": QNetworkAccessManager.PostOperation, @@ -22,15 +27,29 @@ class NetworkManagerMock: } def __init__(self): + # a dict with the prepared replies, using the format {(http_method, url): reply} self.replies = {} # type: Dict[Tuple[str, str], QNetworkReply] - def __getattr__(self, method): + ## Mock implementation of the get, post, put, delete and head methods from the network manager. + # Since the methods are very simple and the same it didn't make sense to repeat the code. + # \param method: The method being called. + # \return The mocked function, if the method name is known. Defaults to the standard getattr function. + def __getattr__(self, method: str): operation = self._OPERATIONS.get(method.upper()) if operation: + # this mock implementation will simply return the reply from the prepared ones. + # it raises a KeyError if requests are done without being prepared. return lambda request, *_: self.replies[method.upper(), request.url().toString()] - return super().__getattribute__(method) - def prepareResponse(self, method: str, url: str, status_code: int, response: dict) -> None: + # the attribute is not one of the implemented methods, default to the standard implementation. + return getattr(super(), method) + + ## Prepares a server reply for the given parameters. + # \param method: The HTTP method. + # \param url: The URL being requested. + # \param status_code: The HTTP status code for the response. + # \param response: A dictionary with the response from the server (this is converted to JSON). + def prepareReply(self, method: str, url: str, status_code: int, response: dict) -> None: reply_mock = MagicMock() reply_mock.url().toString.return_value = url reply_mock.operation.return_value = self._OPERATIONS[method] @@ -38,9 +57,30 @@ class NetworkManagerMock: reply_mock.readAll.return_value = json.dumps(response).encode() self.replies[method, url] = reply_mock + ## Prepares a reply for the API call to get clusters. + def prepareGetClusters(self) -> None: + self.prepareReply( + "GET", "https://api-staging.ultimaker.com/connect/v1/clusters", + 200, { + "data": [{ + "cluster_id": "RIZ6cZbWA_Ua7RZVJhrdVfVpf0z-MqaSHQE4v8aRTtYq", + "host_guid": "e90ae0ac-1257-4403-91ee-a44c9b7e8050", + "host_name": "ultimakersystem-ccbdd30044ec", "host_version": "5.1.2.20180807", + "is_online": False, "status": "inactive" + }, { + "cluster_id": "R0YcLJwar1ugh0ikEZsZs8NWKV6vJP_LdYsXgXqAcaNC", + "host_guid": "e90ae0ac-1257-4403-91ee-a44c9b7e8050", + "host_name": "ultimakersystem-ccbdd30044ec", "host_version": "5.1.2.20180807", + "is_online": True, "status": "active" + }] + } + ) + + ## Emits the signal that the reply is ready to all prepared replies. def flushReplies(self): for reply in self.replies.values(): self.finished.emit(reply) + ## Deletes all prepared replies def reset(self): self.replies.clear() diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py index cf86f713b2..b22308ac1e 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py @@ -18,22 +18,7 @@ class TestCloudOutputDeviceManager(TestCase): self.app.initialize() self.network = NetworkManagerMock() - self.network.prepareResponse( - "GET", "https://api-staging.ultimaker.com/connect/v1/clusters", - 200, { - "data": [{ - "cluster_id": "RIZ6cZbWA_Ua7RZVJhrdVfVpf0z-MqaSHQE4v8aRTtYq", - "host_guid": "e90ae0ac-1257-4403-91ee-a44c9b7e8050", - "host_name": "ultimakersystem-ccbdd30044ec", "host_version": "5.1.2.20180807", - "is_online": False, "status": "inactive" - }, { - "cluster_id": "R0YcLJwar1ugh0ikEZsZs8NWKV6vJP_LdYsXgXqAcaNC", - "host_guid": "e90ae0ac-1257-4403-91ee-a44c9b7e8050", - "host_name": "ultimakersystem-ccbdd30044ec", "host_version": "5.1.2.20180807", - "is_online": True, "status": "active" - }] - } - ) + self.network.prepareGetClusters() def tearDown(self): super().tearDown() @@ -48,4 +33,6 @@ class TestCloudOutputDeviceManager(TestCase): self.network.flushReplies() devices = self.app.getOutputDeviceManager().getOutputDevices() - self.assertEqual([CloudOutputDevice], list(map(type, devices))) + self.assertEqual([CloudOutputDevice], [type(d) for d in devices]) + self.assertEqual(["R0YcLJwar1ugh0ikEZsZs8NWKV6vJP_LdYsXgXqAcaNC"], [d.key for d in devices]) + self.assertEqual(["ultimakersystem-ccbdd30044ec"], [d.host_name for d in devices]) From 9e7a52e28bd783876ae8255fc3648f4dbb7fcc4e Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 10 Dec 2018 09:43:50 +0100 Subject: [PATCH 0792/1292] Update the background color for the expandable component when using the close button. Contributes to CURA-5941. --- resources/qml/ExpandableComponent.qml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index 3a03740251..4170a0942e 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -71,7 +71,15 @@ Item function toggleContent() { - content.visible = !content.visible + content.visible = !expanded + } + + // Add this binding since the background color is not updated otherwise + Binding + { + target: background + property: "color" + value: expanded ? headerActiveColor : headerBackgroundColor } implicitHeight: 100 * screenScaleFactor @@ -82,7 +90,7 @@ Item id: background property real padding: UM.Theme.getSize("default_margin").width - color: headerBackgroundColor + color: expanded ? headerActiveColor : headerBackgroundColor anchors.fill: parent Loader From 04f3601c2711426ac5b363ad51e03d468492506f Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 10 Dec 2018 09:54:26 +0100 Subject: [PATCH 0793/1292] Ensure that local votes are displayed right away So even before an update is received, ensure that the data is updated CURA-6013 --- .../Toolbox/resources/qml/RatingWidget.qml | 29 +++++++++++++------ .../resources/qml/ToolboxDetailPage.qml | 18 ++++++++++++ 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/plugins/Toolbox/resources/qml/RatingWidget.qml b/plugins/Toolbox/resources/qml/RatingWidget.qml index 424f6c91c4..b7d07835e8 100644 --- a/plugins/Toolbox/resources/qml/RatingWidget.qml +++ b/plugins/Toolbox/resources/qml/RatingWidget.qml @@ -9,8 +9,16 @@ Item property real rating: 0 property int indexHovered: -1 property string packageId: "" + property int numRatings: 0 + + // If the widget was used to vote, but the vote isn't sent to remote yet, we do want to fake some things. + property int _numRatings: _localRating != 0 ? numRatings + 1 : numRatings + property int _localRating: 0 + onVisibleChanged: _localRating = 0 // Reset the _localRating + property int userRating: 0 + width: contentRow.width height: contentRow.height MouseArea @@ -50,7 +58,10 @@ Item { return indexHovered >= index } - + if(ratingWidget._localRating > 0) + { + return _localRating >= index +1 + } if(ratingWidget.userRating > 0) { return userRating >= index +1 @@ -73,7 +84,7 @@ Item { return "#5a5a5a" } - if((ratingWidget.indexHovered >= 0 || ratingWidget.userRating > 0) && isStarFilled) + if((ratingWidget.indexHovered >= 0 || ratingWidget.userRating > 0 || ratingWidget._localRating > 0) && isStarFilled) { return UM.Theme.getColor("primary") } @@ -82,19 +93,19 @@ Item } onClicked: { - if(userRating == 0) - { - //User didn't vote yet, locally fake it - numRatings += 1 - } - userRating = index + 1 // Fake local data + // Ensure that the local rating is updated (even though it's not on the server just yet) + _localRating = index + 1 toolbox.ratePackage(ratingWidget.packageId, index + 1) } } } Label { - text: "(" + numRatings + ")" + text: "(" + _numRatings + ")" + verticalAlignment: Text.AlignVCenter + height: parent.height + color: "#5a5a5a" + font: UM.Theme.getFont("small") } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 4e0bf67544..dd3f0a6c84 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -6,6 +6,8 @@ import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM +import Cura 1.1 as Cura + Item { id: page @@ -103,6 +105,12 @@ Item font: UM.Theme.getFont("default") color: UM.Theme.getColor("text_medium") } + Label + { + text: catalog.i18nc("@label", "Rating") + ":" + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text_medium") + } } Column { @@ -160,6 +168,16 @@ Item font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") } + RatingWidget + { + id: rating + visible: details.type == "plugin" + packageId: details.id + rating: details.average_rating + numRatings: details.num_ratings + userRating: details.user_rating + enabled: toolbox.isInstalled(details.id) && Cura.API.account.isLoggedIn + } } Rectangle { From 8cfb9350bc2931224d4be597c3650c0b808e4e2c Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 10 Dec 2018 10:36:55 +0100 Subject: [PATCH 0794/1292] Add a mouse area to gather the scroll events in the settings panel Contributes to CURA-5941. --- resources/qml/Settings/SettingView.qml | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 3f84296307..9904770281 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -168,8 +168,10 @@ Item style: ButtonStyle { - background: Item { - UM.RecolorImage { + background: Item + { + UM.RecolorImage + { anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter width: UM.Theme.getSize("standard_arrow").width @@ -180,8 +182,9 @@ Item source: UM.Theme.getIcon("menu") } } - label: Label{} + label: Label {} } + menu: SettingVisibilityPresetsMenu { onShowAllSettings: @@ -192,6 +195,14 @@ Item } } + // Mouse area that gathers the scroll events to not propagate it to the main view. + MouseArea + { + anchors.fill: scrollView + acceptedButtons: Qt.AllButtons + onWheel: wheel.accepted = true + } + ScrollView { id: scrollView From 098adc45ff6464f14e6ba8c2be2deec2df17bb75 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 10 Dec 2018 10:40:54 +0100 Subject: [PATCH 0795/1292] Move the rating logic outside of the rating widget That way it's easier to re-use the component if that's ever required. CURA-6013 --- plugins/Toolbox/resources/qml/RatingWidget.qml | 7 +++++-- .../Toolbox/resources/qml/ToolboxDetailPage.qml | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/plugins/Toolbox/resources/qml/RatingWidget.qml b/plugins/Toolbox/resources/qml/RatingWidget.qml index b7d07835e8..f1499b61a7 100644 --- a/plugins/Toolbox/resources/qml/RatingWidget.qml +++ b/plugins/Toolbox/resources/qml/RatingWidget.qml @@ -19,6 +19,8 @@ Item property int userRating: 0 + signal rated(int rating) + width: contentRow.width height: contentRow.height MouseArea @@ -94,8 +96,9 @@ Item onClicked: { // Ensure that the local rating is updated (even though it's not on the server just yet) - _localRating = index + 1 - toolbox.ratePackage(ratingWidget.packageId, index + 1) + //_localRating = index + 1 + rated(index + 1) + } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index dd3f0a6c84..a503a9d519 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -177,6 +177,21 @@ Item numRatings: details.num_ratings userRating: details.user_rating enabled: toolbox.isInstalled(details.id) && Cura.API.account.isLoggedIn + + onRated: + { + toolbox.ratePackage(details.id, rating) + var index = toolbox.packagesModel.find("id", details.id) + if(index != -1) + { + // Found the package + toolbox.packagesModel.setProperty(index, "user_rating", rating) + toolbox.packagesModel.setProperty(index, "num_ratings", details.num_ratings + 1) + + // Hack; This is because the current selection is an outdated copy, so we need to re-copy it. + base.selection = toolbox.packagesModel.getItem(index) + } + } } } Rectangle From 75c2e25a012c6ae44e81be2c0747f9658a8ce930 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 10 Dec 2018 10:43:22 +0100 Subject: [PATCH 0796/1292] STAR-322: Testing more of the device manager --- .../tests/Cloud/Fixtures/clusters.json | 17 ++++++ .../tests/Cloud/NetworkManagerMock.py | 49 +++++++++------- .../Cloud/TestCloudOutputDeviceManager.py | 58 ++++++++++++++----- 3 files changed, 88 insertions(+), 36 deletions(-) create mode 100644 plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/clusters.json diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/clusters.json b/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/clusters.json new file mode 100644 index 0000000000..79a4c30113 --- /dev/null +++ b/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/clusters.json @@ -0,0 +1,17 @@ +{ + "data": [{ + "cluster_id": "RIZ6cZbWA_Ua7RZVJhrdVfVpf0z-MqaSHQE4v8aRTtYq", + "host_guid": "e90ae0ac-1257-4403-91ee-a44c9b7e8050", + "host_name": "ultimakersystem-ccbdd30044ec", + "host_version": "5.0.0.20170101", + "is_online": true, + "status": "active" + }, { + "cluster_id": "NWKV6vJP_LdYsXgXqAcaNCR0YcLJwar1ugh0ikEZsZs8", + "host_guid": "e0ace90a-91ee-1257-4403-e8050a44c9b7", + "host_name": "ultimakersystem-ccbdd30044ec", + "host_version": "5.1.2.20180807", + "is_online": true, + "status": "active" + }] +} diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py b/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py index 25107971c0..fc84569fa4 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py @@ -1,11 +1,13 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import json -from typing import Dict, Tuple +import os +from typing import Dict, Tuple, Optional from unittest.mock import MagicMock from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkReply +from UM.Logger import Logger from UM.Signal import Signal @@ -26,6 +28,7 @@ class NetworkManagerMock: "HEAD": QNetworkAccessManager.HeadOperation, } + ## Initializes the network manager mock. def __init__(self): # a dict with the prepared replies, using the format {(http_method, url): reply} self.replies = {} # type: Dict[Tuple[str, str], QNetworkReply] @@ -48,33 +51,37 @@ class NetworkManagerMock: # \param method: The HTTP method. # \param url: The URL being requested. # \param status_code: The HTTP status code for the response. - # \param response: A dictionary with the response from the server (this is converted to JSON). - def prepareReply(self, method: str, url: str, status_code: int, response: dict) -> None: + # \param response: The response body from the server (generally json-encoded). + def prepareReply(self, method: str, url: str, status_code: int, response: bytes) -> None: reply_mock = MagicMock() reply_mock.url().toString.return_value = url reply_mock.operation.return_value = self._OPERATIONS[method] reply_mock.attribute.return_value = status_code - reply_mock.readAll.return_value = json.dumps(response).encode() + reply_mock.readAll.return_value = response self.replies[method, url] = reply_mock + Logger.log("i", "Prepared mock {}-response to {} {}", status_code, method, url) ## Prepares a reply for the API call to get clusters. - def prepareGetClusters(self) -> None: - self.prepareReply( - "GET", "https://api-staging.ultimaker.com/connect/v1/clusters", - 200, { - "data": [{ - "cluster_id": "RIZ6cZbWA_Ua7RZVJhrdVfVpf0z-MqaSHQE4v8aRTtYq", - "host_guid": "e90ae0ac-1257-4403-91ee-a44c9b7e8050", - "host_name": "ultimakersystem-ccbdd30044ec", "host_version": "5.1.2.20180807", - "is_online": False, "status": "inactive" - }, { - "cluster_id": "R0YcLJwar1ugh0ikEZsZs8NWKV6vJP_LdYsXgXqAcaNC", - "host_guid": "e90ae0ac-1257-4403-91ee-a44c9b7e8050", - "host_name": "ultimakersystem-ccbdd30044ec", "host_version": "5.1.2.20180807", - "is_online": True, "status": "active" - }] - } - ) + # \param data: The data the server should return. If not given, a default response will be used. + # \return The data in the response. + def prepareGetClusters(self, data: Optional[dict] = None) -> dict: + data, response = self._getResponseData("clusters", data) + self.prepareReply("GET", "https://api-staging.ultimaker.com/connect/v1/clusters", 200, response) + return data + + ## Gets the data that should be in the server's response in both dictionary and JSON-encoded bytes format. + # \param fixture_name: The name of the fixture. + # \param data: The data that should be returned (optional) + # \return The server's response in both dictionary and JSON-encoded bytes format. + @staticmethod + def _getResponseData(fixture_name: str, data: Optional[dict] = None) -> Tuple[dict, bytes]: + if data is None: + with open("{}/Fixtures/{}.json".format(os.path.dirname(__file__), fixture_name), "rb") as f: + response = f.read() + data = json.loads(response.decode()) + else: + response = json.dumps(data).encode() + return data, response ## Emits the signal that the reply is ready to all prepared replies. def flushReplies(self): diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py index b22308ac1e..a043288e59 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py @@ -11,28 +11,56 @@ from plugins.UM3NetworkPrinting.tests.Cloud.NetworkManagerMock import NetworkMan @patch("cura.NetworkClient.QNetworkAccessManager") class TestCloudOutputDeviceManager(TestCase): - app = CuraApplication.getInstance() or CuraApplication() def setUp(self): super().setUp() - self.app.initialize() + self.app = CuraApplication.getInstance() + if not self.app: + self.app = CuraApplication() + self.app.initialize() self.network = NetworkManagerMock() - self.network.prepareGetClusters() + self.manager = CloudOutputDeviceManager() + self.clusters_response = self.network.prepareGetClusters() + ## In the tear down method we check whether the state of the output device manager is what we expect based on the + # mocked API response. def tearDown(self): super().tearDown() - - def test_device(self, network_mock): - network_mock.return_value = self.network - - manager = CloudOutputDeviceManager() - manager._account.loginStateChanged.emit(True) - manager._update_timer.timeout.emit() - + # let the network send replies self.network.flushReplies() - + # get the created devices devices = self.app.getOutputDeviceManager().getOutputDevices() - self.assertEqual([CloudOutputDevice], [type(d) for d in devices]) - self.assertEqual(["R0YcLJwar1ugh0ikEZsZs8NWKV6vJP_LdYsXgXqAcaNC"], [d.key for d in devices]) - self.assertEqual(["ultimakersystem-ccbdd30044ec"], [d.host_name for d in devices]) + # get the server data + clusters = self.clusters_response["data"] + self.assertEqual([CloudOutputDevice] * len(clusters), [type(d) for d in devices]) + self.assertEqual({cluster["cluster_id"] for cluster in clusters}, {device.key for device in devices}) + self.assertEqual({cluster["host_name"] for cluster in clusters}, {device.host_name for device in devices}) + + ## Runs the initial request to retrieve the clusters. + def _loadData(self, network_mock): + network_mock.return_value = self.network + self.manager._account.loginStateChanged.emit(True) + self.manager._update_timer.timeout.emit() + + def test_device_is_created(self, network_mock): + # just create the cluster, it is checked at tearDown + self._loadData(network_mock) + + def test_device_is_updated(self, network_mock): + self._loadData(network_mock) + + # update the cluster from member variable, which is checked at tearDown + self.clusters_response["data"][0]["host_name"] = "New host name" + self.network.prepareGetClusters(self.clusters_response) + + self.manager._update_timer.timeout.emit() + + def test_device_is_removed(self, network_mock): + self._loadData(network_mock) + + # delete the cluster from member variable, which is checked at tearDown + del self.clusters_response["data"][1] + self.network.prepareGetClusters(self.clusters_response) + + self.manager._update_timer.timeout.emit() From 99f0e9613144ceebb30159cc8fc73c6bff25f0e3 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 10 Dec 2018 11:01:55 +0100 Subject: [PATCH 0797/1292] Ensure that the local model is updated correctly on local vote CURA-6013 --- .../Toolbox/resources/qml/RatingWidget.qml | 22 +++----------- .../resources/qml/ToolboxDetailPage.qml | 29 +++++++++++++++---- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/plugins/Toolbox/resources/qml/RatingWidget.qml b/plugins/Toolbox/resources/qml/RatingWidget.qml index f1499b61a7..fbe782b2e2 100644 --- a/plugins/Toolbox/resources/qml/RatingWidget.qml +++ b/plugins/Toolbox/resources/qml/RatingWidget.qml @@ -12,11 +12,6 @@ Item property int numRatings: 0 - // If the widget was used to vote, but the vote isn't sent to remote yet, we do want to fake some things. - property int _numRatings: _localRating != 0 ? numRatings + 1 : numRatings - property int _localRating: 0 - onVisibleChanged: _localRating = 0 // Reset the _localRating - property int userRating: 0 signal rated(int rating) @@ -60,10 +55,7 @@ Item { return indexHovered >= index } - if(ratingWidget._localRating > 0) - { - return _localRating >= index +1 - } + if(ratingWidget.userRating > 0) { return userRating >= index +1 @@ -86,25 +78,19 @@ Item { return "#5a5a5a" } - if((ratingWidget.indexHovered >= 0 || ratingWidget.userRating > 0 || ratingWidget._localRating > 0) && isStarFilled) + if((ratingWidget.indexHovered >= 0 || ratingWidget.userRating > 0) && isStarFilled) { return UM.Theme.getColor("primary") } return "#5a5a5a" } } - onClicked: - { - // Ensure that the local rating is updated (even though it's not on the server just yet) - //_localRating = index + 1 - rated(index + 1) - - } + onClicked: rated(index + 1) // Notify anyone who cares about this. } } Label { - text: "(" + _numRatings + ")" + text: "(" + numRatings + ")" verticalAlignment: Text.AlignVCenter height: parent.height color: "#5a5a5a" diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index a503a9d519..51bb218293 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -181,15 +181,34 @@ Item onRated: { toolbox.ratePackage(details.id, rating) - var index = toolbox.packagesModel.find("id", details.id) + // HACK: This is a far from optimal solution, but without major refactoring, this is the best we can + // do. Since a rework of this is scheduled, it shouldn't live that long... + var index = toolbox.pluginsAvailableModel.find("id", details.id) if(index != -1) { - // Found the package - toolbox.packagesModel.setProperty(index, "user_rating", rating) - toolbox.packagesModel.setProperty(index, "num_ratings", details.num_ratings + 1) + if(details.user_rating == 0) // User never rated before. + { + toolbox.pluginsAvailableModel.setProperty(index, "num_ratings", details.num_ratings + 1) + } + + toolbox.pluginsAvailableModel.setProperty(index, "user_rating", rating) + // Hack; This is because the current selection is an outdated copy, so we need to re-copy it. - base.selection = toolbox.packagesModel.getItem(index) + base.selection = toolbox.pluginsAvailableModel.getItem(index) + return + } + index = toolbox.pluginsShowcaseModel.find("id", details.id) + if(index != -1) + { + if(details.user_rating == 0) // User never rated before. + { + toolbox.pluginsShowcaseModel.setProperty(index, "user_rating", rating) + } + toolbox.pluginsShowcaseModel.setProperty(index, "num_ratings", details.num_ratings + 1) + + // Hack; This is because the current selection is an outdated copy, so we need to re-copy it. + base.selection = toolbox.pluginsShowcaseModel.getItem(index) } } } From 82322d857554b3685394dbee40485c59a973cf02 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 10 Dec 2018 11:12:25 +0100 Subject: [PATCH 0798/1292] Show that a downloaded plugin has a user rating or not CURA-6013 --- plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index 677e532827..f34d982cfb 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -136,14 +136,16 @@ Item { id: starIcon source: UM.Theme.getIcon("star_filled") - color: "#5a5a5a" + color: model.user_rating == 0 ? "#5a5a5a" : UM.Theme.getColor("primary") height: UM.Theme.getSize("rating_star").height width: UM.Theme.getSize("rating_star").width } Label { - text: model.average_rating.toFixed(1) + " (" + model.num_ratings + " " + catalog.i18nc("@label", "ratings") + ")" + // If the user voted, show that value. Otherwsie show the average rating. + property real ratingtoUse: model.user_rating == 0 ? model.average_rating: model.user_rating + text: ratingtoUse.toFixed(1) + " (" + model.num_ratings + " " + catalog.i18nc("@label", "ratings") + ")" verticalAlignment: Text.AlignVCenter height: starIcon.height anchors.verticalCenter: starIcon.verticalCenter From 12522c929372c06ec55731ec381fed3f84bd2f8d Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 10 Dec 2018 11:19:44 +0100 Subject: [PATCH 0799/1292] Change hover colors of the small buttons. Contributes to CURA-5941 --- .../PrintSetupSelectorContents.qml | 4 ++-- resources/qml/Settings/SettingView.qml | 2 +- resources/qml/ViewOrientationButton.qml | 1 - resources/themes/cura-light/theme.json | 14 +++++++------- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml index 47d25edd54..7cd03ff74a 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml @@ -74,6 +74,7 @@ Item id: closeButton width: UM.Theme.getSize("message_close").width height: UM.Theme.getSize("message_close").height + hoverEnabled: true anchors { @@ -86,8 +87,7 @@ Item { anchors.fill: parent sourceSize.width: width - sourceSize.height: width - color: UM.Theme.getColor("message_text") + color: closeButton.hovered ? UM.Theme.getColor("small_button_text_hover") : UM.Theme.getColor("small_button_text") source: UM.Theme.getIcon("cross1") } diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 9904770281..c1b4b28d1d 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -178,7 +178,7 @@ Item height: UM.Theme.getSize("standard_arrow").height sourceSize.width: width sourceSize.height: height - color: control.enabled ? UM.Theme.getColor("setting_category_text") : UM.Theme.getColor("setting_category_disabled_text") + color: control.hovered ? UM.Theme.getColor("small_button_text_hover") : UM.Theme.getColor("small_button_text") source: UM.Theme.getIcon("menu") } } diff --git a/resources/qml/ViewOrientationButton.qml b/resources/qml/ViewOrientationButton.qml index 682fd71b4e..5371f8549b 100644 --- a/resources/qml/ViewOrientationButton.qml +++ b/resources/qml/ViewOrientationButton.qml @@ -9,7 +9,6 @@ UM.SimpleButton { width: UM.Theme.getSize("small_button").width height: UM.Theme.getSize("small_button").height - hoverBackgroundColor: UM.Theme.getColor("small_button_hover") hoverColor: UM.Theme.getColor("small_button_text_hover") color: UM.Theme.getColor("small_button_text") iconMargin: 0.5 * UM.Theme.getSize("wide_lining").width diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index d4fb59b7a1..0ef6c24bfb 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -80,7 +80,7 @@ "primary_hover": [48, 182, 231, 255], "primary_text": [255, 255, 255, 255], "border": [127, 127, 127, 255], - "secondary": [245, 245, 245, 255], + "secondary": [240, 240, 240, 255], "secondary_shadow": [216, 216, 216, 255], "primary_button": [38, 113, 231, 255], @@ -150,7 +150,7 @@ "small_button_active": [10, 8, 80, 255], "small_button_active_hover": [10, 8, 80, 255], "small_button_text": [102, 102, 102, 255], - "small_button_text_hover": [255, 255, 255, 255], + "small_button_text_hover": [8, 7, 63, 255], "small_button_text_active": [255, 255, 255, 255], "small_button_text_active_hover": [255, 255, 255, 255], @@ -183,18 +183,18 @@ "scrollbar_handle_hover": [50, 130, 255, 255], "scrollbar_handle_down": [50, 130, 255, 255], - "setting_category": [245, 245, 245, 255], + "setting_category": [240, 240, 240, 255], "setting_category_disabled": [255, 255, 255, 255], "setting_category_hover": [232, 242, 252, 255], - "setting_category_active": [245, 245, 245, 255], + "setting_category_active": [240, 240, 240, 255], "setting_category_active_hover": [232, 242, 252, 255], "setting_category_text": [35, 35, 35, 255], "setting_category_disabled_text": [24, 41, 77, 101], "setting_category_hover_text": [35, 35, 35, 255], "setting_category_active_text": [35, 35, 35, 255], "setting_category_active_hover_text": [35, 35, 35, 255], - "setting_category_border": [245, 245, 245, 255], - "setting_category_disabled_border": [245, 245, 245, 255], + "setting_category_border": [240, 240, 240, 255], + "setting_category_disabled_border": [240, 240, 240, 255], "setting_category_hover_border": [50, 130, 255, 255], "setting_category_active_border": [50, 130, 255, 255], "setting_category_active_hover_border": [50, 130, 255, 255], @@ -274,7 +274,7 @@ "z_axis": [0, 255, 0, 255], "all_axis": [255, 255, 255, 255], - "viewport_background": [245, 245, 245, 255], + "viewport_background": [250, 250, 250, 255], "volume_outline": [50, 130, 255, 255], "buildplate": [244, 244, 244, 255], "buildplate_grid": [129, 131, 134, 255], From 134f97d5f15064703d9c1b59c7bb8162e7ee5e77 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 10 Dec 2018 11:30:02 +0100 Subject: [PATCH 0800/1292] STAR-322: Finishing the output device manager tests --- .../src/Cloud/CloudOutputDeviceManager.py | 19 +++----- .../tests/Cloud/Fixtures/clusters.json | 2 +- .../Cloud/TestCloudOutputDeviceManager.py | 45 ++++++++++++++++++- 3 files changed, 51 insertions(+), 15 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index f06bbb305e..961f8d696d 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -22,7 +22,6 @@ from .Utils import findChanges # # API spec is available on https://api.ultimaker.com/docs/connect/spec/. # - class CloudOutputDeviceManager: META_CLUSTER_ID = "um_cloud_cluster_id" @@ -32,9 +31,7 @@ class CloudOutputDeviceManager: # The translation catalog for this device. I18N_CATALOG = i18nCatalog("cura") - def __init__(self): - super().__init__() - + def __init__(self) -> None: # Persistent dict containing the remote clusters for the authenticated user. self._remote_clusters = {} # type: Dict[str, CloudOutputDevice] @@ -86,6 +83,7 @@ class CloudOutputDeviceManager: for removed_cluster in removed_devices: if removed_cluster.isConnected(): removed_cluster.disconnect() + removed_cluster.close() self._output_device_manager.removeOutputDevice(removed_cluster.key) del self._remote_clusters[removed_cluster.key] @@ -124,20 +122,17 @@ class CloudOutputDeviceManager: return device = next((c for c in self._remote_clusters.values() if c.matchesNetworkKey(local_network_key)), None) - if not device: - return - - active_machine.setMetaDataEntry(self.META_CLUSTER_ID, device.key) - return device.connect() + if device: + active_machine.setMetaDataEntry(self.META_CLUSTER_ID, device.key) + device.connect() ## Handles an API error received from the cloud. # \param errors: The errors received def _onApiError(self, errors: List[CloudErrorObject]) -> None: message = ". ".join(e.title for e in errors) # TODO: translate errors - message = Message( + Message( text = message, title = self.I18N_CATALOG.i18nc("@info:title", "Error"), lifetime = 10, dismissable = True - ) - message.show() + ).show() diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/clusters.json b/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/clusters.json index 79a4c30113..5200e3b971 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/clusters.json +++ b/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/clusters.json @@ -9,7 +9,7 @@ }, { "cluster_id": "NWKV6vJP_LdYsXgXqAcaNCR0YcLJwar1ugh0ikEZsZs8", "host_guid": "e0ace90a-91ee-1257-4403-e8050a44c9b7", - "host_name": "ultimakersystem-ccbdd30044ec", + "host_name": "ultimakersystem-30044ecccbdd", "host_version": "5.1.2.20180807", "is_online": true, "status": "active" diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py index a043288e59..80ce54aeee 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py @@ -30,13 +30,18 @@ class TestCloudOutputDeviceManager(TestCase): # let the network send replies self.network.flushReplies() # get the created devices - devices = self.app.getOutputDeviceManager().getOutputDevices() + device_manager = self.app.getOutputDeviceManager() + devices = device_manager.getOutputDevices() # get the server data - clusters = self.clusters_response["data"] + clusters = self.clusters_response.get("data", []) self.assertEqual([CloudOutputDevice] * len(clusters), [type(d) for d in devices]) self.assertEqual({cluster["cluster_id"] for cluster in clusters}, {device.key for device in devices}) self.assertEqual({cluster["host_name"] for cluster in clusters}, {device.host_name for device in devices}) + for device in clusters: + device_manager.getOutputDevice(device["cluster_id"]).close() + device_manager.removeOutputDevice(device["cluster_id"]) + ## Runs the initial request to retrieve the clusters. def _loadData(self, network_mock): network_mock.return_value = self.network @@ -64,3 +69,39 @@ class TestCloudOutputDeviceManager(TestCase): self.network.prepareGetClusters(self.clusters_response) self.manager._update_timer.timeout.emit() + + @patch("cura.CuraApplication.CuraApplication.getGlobalContainerStack") + def test_device_connects_by_cluster_id(self, global_container_stack_mock, network_mock): + active_machine_mock = global_container_stack_mock.return_value + cluster1, cluster2 = self.clusters_response["data"] + cluster_id = cluster1["cluster_id"] + active_machine_mock.getMetaDataEntry.side_effect = {"um_cloud_cluster_id": cluster_id}.get + + self._loadData(network_mock) + self.network.flushReplies() + + self.assertTrue(self.app.getOutputDeviceManager().getOutputDevice(cluster1["cluster_id"]).isConnected()) + self.assertFalse(self.app.getOutputDeviceManager().getOutputDevice(cluster2["cluster_id"]).isConnected()) + + @patch("cura.CuraApplication.CuraApplication.getGlobalContainerStack") + def test_device_connects_by_network_key(self, global_container_stack_mock, network_mock): + active_machine_mock = global_container_stack_mock.return_value + + cluster1, cluster2 = self.clusters_response["data"] + network_key = cluster2["host_name"] + ".ultimaker.local" + active_machine_mock.getMetaDataEntry.side_effect = {"um_network_key": network_key}.get + + self._loadData(network_mock) + self.network.flushReplies() + + self.assertFalse(self.app.getOutputDeviceManager().getOutputDevice(cluster1["cluster_id"]).isConnected()) + self.assertTrue(self.app.getOutputDeviceManager().getOutputDevice(cluster2["cluster_id"]).isConnected()) + + active_machine_mock.setMetaDataEntry.assert_called_once_with("um_cloud_cluster_id", cluster2["cluster_id"]) + + @patch("UM.Message.Message.show") + def test_api_error(self, message_mock, network_mock): + self.clusters_response = {"errors": [{"id": "notFound"}]} + self.network.prepareGetClusters(self.clusters_response) + self._loadData(network_mock) + message_mock.assert_called_once_with() From 021c44862752905999fdd0aaf9fac3130cb3e5b2 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 10 Dec 2018 11:31:18 +0100 Subject: [PATCH 0801/1292] Remove depreciated monitor tab stuff Contributes to CL-1152 --- .../resources/qml/PrintCoreConfiguration.qml | 121 ----- .../resources/qml/PrintJobInfoBlock.qml | 505 ------------------ .../resources/qml/PrintJobPreview.qml | 75 --- .../resources/qml/PrintJobTitle.qml | 59 -- .../resources/qml/PrinterCard.qml | 241 --------- .../resources/qml/PrinterCardDetails.qml | 75 --- .../resources/qml/PrinterCardProgressBar.qml | 108 ---- .../resources/qml/PrinterFamilyPill.qml | 32 -- .../resources/qml/PrinterInfoBlock.qml | 83 --- 9 files changed, 1299 deletions(-) delete mode 100644 plugins/UM3NetworkPrinting/resources/qml/PrintCoreConfiguration.qml delete mode 100644 plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml delete mode 100644 plugins/UM3NetworkPrinting/resources/qml/PrintJobPreview.qml delete mode 100644 plugins/UM3NetworkPrinting/resources/qml/PrintJobTitle.qml delete mode 100644 plugins/UM3NetworkPrinting/resources/qml/PrinterCard.qml delete mode 100644 plugins/UM3NetworkPrinting/resources/qml/PrinterCardDetails.qml delete mode 100644 plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml delete mode 100644 plugins/UM3NetworkPrinting/resources/qml/PrinterFamilyPill.qml delete mode 100644 plugins/UM3NetworkPrinting/resources/qml/PrinterInfoBlock.qml diff --git a/plugins/UM3NetworkPrinting/resources/qml/PrintCoreConfiguration.qml b/plugins/UM3NetworkPrinting/resources/qml/PrintCoreConfiguration.qml deleted file mode 100644 index 7bcd9ce6e4..0000000000 --- a/plugins/UM3NetworkPrinting/resources/qml/PrintCoreConfiguration.qml +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.2 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 -import UM 1.2 as UM - -Item { - id: extruderInfo; - property var printCoreConfiguration: null; - height: childrenRect.height; - width: Math.round(parent.width / 2); - - // Extruder circle - Item { - id: extruderCircle; - height: UM.Theme.getSize("monitor_extruder_circle").height; - width: UM.Theme.getSize("monitor_extruder_circle").width; - - // Loading skeleton - Rectangle { - anchors.fill: parent; - color: UM.Theme.getColor("monitor_skeleton_fill"); - radius: Math.round(width / 2); - visible: !printCoreConfiguration; - } - - // Actual content - Rectangle { - anchors.fill: parent; - border.width: UM.Theme.getSize("monitor_thick_lining").width; - border.color: UM.Theme.getColor("monitor_lining_heavy"); - color: "transparent"; - opacity: { - if (printCoreConfiguration == null || printCoreConfiguration.activeMaterial == null || printCoreConfiguration.hotendID == null) { - return 0.5; - } - return 1; - } - radius: Math.round(width / 2); - visible: printCoreConfiguration; - - Label { - anchors.centerIn: parent; - color: UM.Theme.getColor("text"); - font: UM.Theme.getFont("default_bold"); - text: printCoreConfiguration ? printCoreConfiguration.position + 1 : 0; - } - } - } - - // Print core and material labels - Item { - id: materialLabel - anchors { - left: extruderCircle.right; - leftMargin: UM.Theme.getSize("default_margin").width; - right: parent.right; - top: parent.top; - } - height: UM.Theme.getSize("monitor_text_line").height; - - // Loading skeleton - Rectangle { - anchors.fill: parent; - color: UM.Theme.getColor("monitor_skeleton_fill"); - visible: !extruderInfo.printCoreConfiguration; - } - - // Actual content - Label { - anchors.fill: parent; - elide: Text.ElideRight; - color: UM.Theme.getColor("text"); - font: UM.Theme.getFont("default"); - text: { - if (printCoreConfiguration && printCoreConfiguration.activeMaterial != undefined) { - return printCoreConfiguration.activeMaterial.name; - } - return ""; - } - visible: extruderInfo.printCoreConfiguration; - } - } - - Item { - id: printCoreLabel; - anchors { - left: extruderCircle.right; - leftMargin: UM.Theme.getSize("default_margin").width; - right: parent.right; - top: materialLabel.bottom; - topMargin: Math.floor(UM.Theme.getSize("default_margin").height/4); - } - height: UM.Theme.getSize("monitor_text_line").height; - - // Loading skeleton - Rectangle { - color: UM.Theme.getColor("monitor_skeleton_fill"); - height: parent.height; - visible: !extruderInfo.printCoreConfiguration; - width: Math.round(parent.width / 3); - } - - // Actual content - Label { - color: UM.Theme.getColor("text"); - elide: Text.ElideRight; - font: UM.Theme.getFont("default"); - opacity: 0.6; - text: { - if (printCoreConfiguration != undefined && printCoreConfiguration.hotendID != undefined) { - return printCoreConfiguration.hotendID; - } - return ""; - } - visible: extruderInfo.printCoreConfiguration; - } - } -} diff --git a/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml b/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml deleted file mode 100644 index a611cb4ff6..0000000000 --- a/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml +++ /dev/null @@ -1,505 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.2 -import QtQuick.Dialogs 1.1 -import QtQuick.Controls 2.0 -import QtQuick.Controls.Styles 1.4 -import QtGraphicalEffects 1.0 -import QtQuick.Layouts 1.1 -import QtQuick.Dialogs 1.1 -import UM 1.3 as UM - -Item { - id: root; - property var shadowRadius: UM.Theme.getSize("monitor_shadow_radius").width; - property var shadowOffset: 2 * screenScaleFactor; - property var debug: false; - property var printJob: null; - width: parent.width; // Bubbles downward - height: childrenRect.height + shadowRadius * 2; // Bubbles upward - - UM.I18nCatalog { - id: catalog; - name: "cura"; - } - - // The actual card (white block) - Rectangle { - // 5px margin, but shifted 2px vertically because of the shadow - anchors { - bottomMargin: root.shadowRadius + root.shadowOffset; - leftMargin: root.shadowRadius; - rightMargin: root.shadowRadius; - topMargin: root.shadowRadius - root.shadowOffset; - } - color: UM.Theme.getColor("monitor_card_background"); - height: childrenRect.height; - layer.enabled: true - layer.effect: DropShadow { - radius: root.shadowRadius - verticalOffset: 2 * screenScaleFactor - color: "#3F000000" // 25% shadow - } - width: parent.width - shadowRadius * 2; - - Column { - height: childrenRect.height; - width: parent.width; - - // Main content - Item { - id: mainContent; - height: 200 * screenScaleFactor; // TODO: Theme! - width: parent.width; - - // Left content - Item { - anchors { - bottom: parent.bottom; - left: parent.left; - margins: UM.Theme.getSize("wide_margin").width; - right: parent.horizontalCenter; - top: parent.top; - } - - Item { - id: printJobName; - width: parent.width; - height: UM.Theme.getSize("monitor_text_line").height; - - Rectangle { - color: UM.Theme.getColor("monitor_skeleton_fill"); - height: parent.height; - visible: !printJob; - width: Math.round(parent.width / 3); - } - Label { - anchors.fill: parent; - color: UM.Theme.getColor("text"); - elide: Text.ElideRight; - font: UM.Theme.getFont("default_bold"); - text: printJob && printJob.name ? printJob.name : ""; // Supress QML warnings - visible: printJob; - } - } - - Item { - id: printJobOwnerName; - anchors { - top: printJobName.bottom; - topMargin: Math.floor(UM.Theme.getSize("default_margin").height / 2); - } - height: UM.Theme.getSize("monitor_text_line").height; - width: parent.width; - - Rectangle { - color: UM.Theme.getColor("monitor_skeleton_fill"); - height: parent.height; - visible: !printJob; - width: Math.round(parent.width / 2); - } - Label { - anchors.fill: parent; - color: UM.Theme.getColor("text"); - elide: Text.ElideRight; - font: UM.Theme.getFont("default"); - text: printJob ? printJob.owner : ""; // Supress QML warnings - visible: printJob; - } - } - - Item { - id: printJobPreview; - property var useUltibot: false; - anchors { - bottom: parent.bottom; - horizontalCenter: parent.horizontalCenter; - top: printJobOwnerName.bottom; - topMargin: UM.Theme.getSize("default_margin").height; - } - width: height; - - // Skeleton - Rectangle { - anchors.fill: parent; - color: UM.Theme.getColor("monitor_skeleton_fill"); - radius: UM.Theme.getSize("default_margin").width; - visible: !printJob; - } - - // Actual content - Image { - id: previewImage; - anchors.fill: parent; - opacity: printJob && printJob.state == "error" ? 0.5 : 1.0; - source: printJob ? printJob.previewImageUrl : ""; - visible: printJob; - } - - UM.RecolorImage { - id: ultiBotImage; - - anchors.centerIn: printJobPreview; - color: UM.Theme.getColor("monitor_placeholder_image"); - height: printJobPreview.height; - source: "../svg/ultibot.svg"; - sourceSize { - height: height; - width: width; - } - /* Since print jobs ALWAYS have an image url, we have to check if that image URL errors or - not in order to determine if we show the placeholder (ultibot) image instead. */ - visible: printJob && previewImage.status == Image.Error; - width: printJobPreview.width; - } - - UM.RecolorImage { - id: statusImage; - anchors.centerIn: printJobPreview; - color: UM.Theme.getColor("monitor_image_overlay"); - height: 0.5 * printJobPreview.height; - source: printJob && printJob.state == "error" ? "../svg/aborted-icon.svg" : ""; - sourceSize { - height: height; - width: width; - } - visible: source != ""; - width: 0.5 * printJobPreview.width; - } - } - - Label { - id: totalTimeLabel; - anchors { - bottom: parent.bottom; - right: parent.right; - } - color: UM.Theme.getColor("text"); - elide: Text.ElideRight; - font: UM.Theme.getFont("default"); - text: printJob ? OutputDevice.formatDuration(printJob.timeTotal) : ""; - } - } - - // Divider - Rectangle { - anchors { - horizontalCenter: parent.horizontalCenter; - verticalCenter: parent.verticalCenter; - } - color: !printJob ? UM.Theme.getColor("monitor_skeleton_fill") : UM.Theme.getColor("monitor_lining_light"); - height: parent.height - 2 * UM.Theme.getSize("default_margin").height; - width: UM.Theme.getSize("default_lining").width; - } - - // Right content - Item { - anchors { - bottom: parent.bottom; - left: parent.horizontalCenter; - margins: UM.Theme.getSize("wide_margin").width; - right: parent.right; - top: parent.top; - } - - Item { - id: targetPrinterLabel; - height: UM.Theme.getSize("monitor_text_line").height; - width: parent.width; - - Rectangle { - visible: !printJob; - color: UM.Theme.getColor("monitor_skeleton_fill"); - anchors.fill: parent; - } - - Label { - color: UM.Theme.getColor("text"); - elide: Text.ElideRight; - font: UM.Theme.getFont("default_bold"); - text: { - if (printJob !== null) { - if (printJob.assignedPrinter == null) { - if (printJob.state == "error") { - return catalog.i18nc("@label", "Waiting for: Unavailable printer"); - } - return catalog.i18nc("@label", "Waiting for: First available"); - } else { - return catalog.i18nc("@label", "Waiting for: ") + printJob.assignedPrinter.name; - } - } - return ""; - } - visible: printJob; - } - } - - PrinterInfoBlock { - anchors.bottom: parent.bottom; - printer: root.printJon && root.printJob.assignedPrinter; - printJob: root.printJob; - } - } - - PrintJobContextMenu { - id: contextButton; - anchors { - right: mainContent.right; - rightMargin: UM.Theme.getSize("default_margin").width * 3 + root.shadowRadius; - top: mainContent.top; - topMargin: UM.Theme.getSize("default_margin").height; - } - printJob: root.printJob; - visible: root.printJob; - } - } - - Item { - id: configChangesBox; - height: childrenRect.height; - visible: printJob && printJob.configurationChanges.length !== 0; - width: parent.width; - - // Config change toggle - Rectangle { - id: configChangeToggle; - color: { - if (configChangeToggleArea.containsMouse) { - return UM.Theme.getColor("viewport_background"); // TODO: Theme! - } else { - return "transparent"; - } - } - width: parent.width; - height: UM.Theme.getSize("default_margin").height * 4; // TODO: Theme! - anchors { - left: parent.left; - right: parent.right; - top: parent.top; - } - - Rectangle { - color: !printJob ? UM.Theme.getColor("monitor_skeleton_fill") : UM.Theme.getColor("monitor_lining_light"); - height: UM.Theme.getSize("default_lining").height; - width: parent.width; - } - - UM.RecolorImage { - anchors { - right: configChangeToggleLabel.left; - rightMargin: UM.Theme.getSize("default_margin").width; - verticalCenter: parent.verticalCenter; - } - color: UM.Theme.getColor("text"); - height: 23 * screenScaleFactor; // TODO: Theme! - source: "../svg/warning-icon.svg"; - sourceSize { - height: height; - width: width; - } - width: 23 * screenScaleFactor; // TODO: Theme! - } - - Label { - id: configChangeToggleLabel; - anchors { - horizontalCenter: parent.horizontalCenter; - verticalCenter: parent.verticalCenter; - } - color: UM.Theme.getColor("text"); - font: UM.Theme.getFont("default"); - text: catalog.i18nc("@label", "Configuration change"); - } - - UM.RecolorImage { - anchors { - left: configChangeToggleLabel.right; - leftMargin: UM.Theme.getSize("default_margin").width; - verticalCenter: parent.verticalCenter; - } - color: UM.Theme.getColor("text"); - height: 15 * screenScaleFactor; // TODO: Theme! - source: { - if (configChangeDetails.visible) { - return UM.Theme.getIcon("arrow_top"); - } else { - return UM.Theme.getIcon("arrow_bottom"); - } - } - sourceSize { - width: width; - height: height; - } - width: 15 * screenScaleFactor; // TODO: Theme! - } - - MouseArea { - id: configChangeToggleArea; - anchors.fill: parent; - hoverEnabled: true; - onClicked: { - configChangeDetails.visible = !configChangeDetails.visible; - } - } - } - - // Config change details - Item { - id: configChangeDetails; - anchors.top: configChangeToggle.bottom; - Behavior on height { NumberAnimation { duration: 100 } } - // In case of really massive multi-line configuration changes - height: visible ? Math.max(UM.Theme.getSize("monitor_config_override_box").height, childrenRect.height) : 0; - visible: false; - width: parent.width; - - Item { - anchors { - bottomMargin: UM.Theme.getSize("wide_margin").height; - fill: parent; - leftMargin: UM.Theme.getSize("wide_margin").height * 4; - rightMargin: UM.Theme.getSize("wide_margin").height * 4; - topMargin: UM.Theme.getSize("wide_margin").height; - } - clip: true; - - Label { - anchors.fill: parent; - elide: Text.ElideRight; - color: UM.Theme.getColor("text"); - font: UM.Theme.getFont("default"); - text: { - if (!printJob || printJob.configurationChanges.length === 0) { - return ""; - } - var topLine; - if (materialsAreKnown(printJob)) { - topLine = catalog.i18nc("@label", "The assigned printer, %1, requires the following configuration change(s):").arg(printJob.assignedPrinter.name); - } else { - topLine = catalog.i18nc("@label", "The printer %1 is assigned, but the job contains an unknown material configuration.").arg(printJob.assignedPrinter.name); - } - var result = "

    " + topLine +"

    "; - for (var i = 0; i < printJob.configurationChanges.length; i++) { - var change = printJob.configurationChanges[i]; - var text; - switch (change.typeOfChange) { - case "material_change": - text = catalog.i18nc("@label", "Change material %1 from %2 to %3.").arg(change.index + 1).arg(change.originName).arg(change.targetName); - break; - case "material_insert": - text = catalog.i18nc("@label", "Load %3 as material %1 (This cannot be overridden).").arg(change.index + 1).arg(change.targetName); - break; - case "print_core_change": - text = catalog.i18nc("@label", "Change print core %1 from %2 to %3.").arg(change.index + 1).arg(change.originName).arg(change.targetName); - break; - case "buildplate_change": - text = catalog.i18nc("@label", "Change build plate to %1 (This cannot be overridden).").arg(formatBuildPlateType(change.target_name)); - break; - default: - text = ""; - } - result += "

    " + text + "

    "; - } - return result; - } - wrapMode: Text.WordWrap; - } - - Button { - anchors { - bottom: parent.bottom; - left: parent.left; - } - background: Rectangle { - border { - color: UM.Theme.getColor("monitor_lining_heavy"); - width: UM.Theme.getSize("default_lining").width; - } - color: parent.hovered ? UM.Theme.getColor("monitor_card_background_inactive") : UM.Theme.getColor("monitor_card_background"); - implicitHeight: UM.Theme.getSize("default_margin").height * 3; - implicitWidth: UM.Theme.getSize("default_margin").height * 8; - } - contentItem: Label { - color: UM.Theme.getColor("text"); - font: UM.Theme.getFont("medium"); - horizontalAlignment: Text.AlignHCenter; - text: parent.text; - verticalAlignment: Text.AlignVCenter; - } - onClicked: { - overrideConfirmationDialog.visible = true; - } - text: catalog.i18nc("@label", "Override"); - visible: { - if (printJob && printJob.configurationChanges) { - var length = printJob.configurationChanges.length; - for (var i = 0; i < length; i++) { - var typeOfChange = printJob.configurationChanges[i].typeOfChange; - if (typeOfChange === "material_insert" || typeOfChange === "buildplate_change") { - return false; - } - } - } - return true; - } - } - } - } - - MessageDialog { - id: overrideConfirmationDialog; - Component.onCompleted: visible = false; - icon: StandardIcon.Warning; - onYes: OutputDevice.forceSendJob(printJob.key); - standardButtons: StandardButton.Yes | StandardButton.No; - text: { - if (!printJob) { - return ""; - } - var printJobName = formatPrintJobName(printJob.name); - var confirmText = catalog.i18nc("@label", "Starting a print job with an incompatible configuration could damage your 3D printer. Are you sure you want to override the configuration and print %1?").arg(printJobName); - return confirmText; - } - title: catalog.i18nc("@window:title", "Override configuration configuration and start print"); - } - } - } - } - // Utils - function formatPrintJobName(name) { - var extensions = [ ".gz", ".gcode", ".ufp" ]; - for (var i = 0; i < extensions.length; i++) { - var extension = extensions[i]; - if (name.slice(-extension.length) === extension) { - name = name.substring(0, name.length - extension.length); - } - } - return name; - } - function materialsAreKnown(job) { - var conf0 = job.configuration[0]; - if (conf0 && !conf0.material.material) { - return false; - } - var conf1 = job.configuration[1]; - if (conf1 && !conf1.material.material) { - return false; - } - return true; - } - function formatBuildPlateType(buildPlateType) { - var translationText = ""; - switch (buildPlateType) { - case "glass": - translationText = catalog.i18nc("@label", "Glass"); - break; - case "aluminum": - translationText = catalog.i18nc("@label", "Aluminum"); - break; - default: - translationText = null; - } - return translationText; - } -} diff --git a/plugins/UM3NetworkPrinting/resources/qml/PrintJobPreview.qml b/plugins/UM3NetworkPrinting/resources/qml/PrintJobPreview.qml deleted file mode 100644 index b1a73255f4..0000000000 --- a/plugins/UM3NetworkPrinting/resources/qml/PrintJobPreview.qml +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.3 -import QtQuick.Dialogs 1.1 -import QtQuick.Controls 2.0 -import QtQuick.Controls.Styles 1.3 -import QtGraphicalEffects 1.0 -import QtQuick.Controls 1.4 as LegacyControls -import UM 1.3 as UM - -// Includes print job name, owner, and preview - -Item { - property var job: null; - property var useUltibot: false; - height: 100 * screenScaleFactor; - width: height; - - // Skeleton - Rectangle { - anchors.fill: parent; - color: UM.Theme.getColor("monitor_skeleton_fill"); - radius: UM.Theme.getSize("default_margin").width; - visible: !job; - } - - // Actual content - Image { - id: previewImage; - visible: job; - source: job ? job.previewImageUrl : ""; - opacity: { - if (job == null) { - return 1.0; - } - var states = ["wait_cleanup", "wait_user_action", "error", "paused"]; - if (states.indexOf(job.state) !== -1) { - return 0.5; - } - return 1.0; - } - anchors.fill: parent; - } - - UM.RecolorImage { - id: ultibotImage; - anchors.centerIn: parent; - color: UM.Theme.getColor("monitor_placeholder_image"); // TODO: Theme! - height: parent.height; - source: "../svg/ultibot.svg"; - sourceSize { - height: height; - width: width; - } - /* Since print jobs ALWAYS have an image url, we have to check if that image URL errors or - not in order to determine if we show the placeholder (ultibot) image instead. */ - visible: job && previewImage.status == Image.Error; - width: parent.width; - } - - UM.RecolorImage { - id: statusImage; - anchors.centerIn: parent; - color: "black"; // TODO: Theme! - height: Math.round(0.5 * parent.height); - source: job && job.state == "error" ? "../svg/aborted-icon.svg" : ""; - sourceSize { - height: height; - width: width; - } - visible: source != ""; - width: Math.round(0.5 * parent.width); - } -} \ No newline at end of file diff --git a/plugins/UM3NetworkPrinting/resources/qml/PrintJobTitle.qml b/plugins/UM3NetworkPrinting/resources/qml/PrintJobTitle.qml deleted file mode 100644 index f9f7b5ae87..0000000000 --- a/plugins/UM3NetworkPrinting/resources/qml/PrintJobTitle.qml +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.3 -import QtQuick.Controls 2.0 -import UM 1.3 as UM - -Column { - property var job: null; - height: childrenRect.height; - spacing: Math.floor( UM.Theme.getSize("default_margin").height / 2); // TODO: Use explicit theme size - width: parent.width; - - Item { - id: jobName; - height: UM.Theme.getSize("monitor_text_line").height; - width: parent.width; - - // Skeleton loading - Rectangle { - color: UM.Theme.getColor("monitor_skeleton_fill"); - height: parent.height; - visible: !job; - width: Math.round(parent.width / 3); - } - - Label { - anchors.fill: parent; - color: UM.Theme.getColor("text"); - elide: Text.ElideRight; - font: UM.Theme.getFont("default_bold"); - text: job && job.name ? job.name : ""; - visible: job; - } - } - - Item { - id: ownerName; - height: UM.Theme.getSize("monitor_text_line").height; - width: parent.width; - - // Skeleton loading - Rectangle { - color: UM.Theme.getColor("monitor_skeleton_fill"); - height: parent.height; - visible: !job; - width: Math.round(parent.width / 2); - } - - Label { - anchors.fill: parent; - color: UM.Theme.getColor("text") - elide: Text.ElideRight; - font: UM.Theme.getFont("default"); - text: job ? job.owner : ""; - visible: job; - } - } -} \ No newline at end of file diff --git a/plugins/UM3NetworkPrinting/resources/qml/PrinterCard.qml b/plugins/UM3NetworkPrinting/resources/qml/PrinterCard.qml deleted file mode 100644 index 24beaf70fe..0000000000 --- a/plugins/UM3NetworkPrinting/resources/qml/PrinterCard.qml +++ /dev/null @@ -1,241 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.3 -import QtQuick.Dialogs 1.1 -import QtQuick.Controls 2.0 -import QtQuick.Controls.Styles 1.3 -import QtGraphicalEffects 1.0 -import UM 1.3 as UM - -Item { - id: root; - property var shadowRadius: UM.Theme.getSize("monitor_shadow_radius").width; - property var shadowOffset: UM.Theme.getSize("monitor_shadow_offset").width; - property var printer: null; - property var collapsed: true; - height: childrenRect.height + shadowRadius * 2; // Bubbles upward - width: parent.width; // Bubbles downward - - // The actual card (white block) - Rectangle { - // 5px margin, but shifted 2px vertically because of the shadow - anchors { - bottomMargin: root.shadowRadius + root.shadowOffset; - leftMargin: root.shadowRadius; - rightMargin: root.shadowRadius; - topMargin: root.shadowRadius - root.shadowOffset; - } - color: { - if (!printer) { - return UM.Theme.getColor("monitor_card_background_inactive"); - } - if (printer.state == "disabled") { - return UM.Theme.getColor("monitor_card_background_inactive"); - } else { - return UM.Theme.getColor("monitor_card_background"); - } - } - height: childrenRect.height; - layer.effect: DropShadow { - radius: root.shadowRadius; - verticalOffset: root.shadowOffset; - color: "#3F000000"; // 25% shadow - } - layer.enabled: true - width: parent.width - 2 * shadowRadius; - - Column { - id: cardContents; - height: childrenRect.height; - width: parent.width; - - // Main card - Item { - id: mainCard; - anchors { - left: parent.left; - leftMargin: UM.Theme.getSize("default_margin").width; - right: parent.right; - rightMargin: UM.Theme.getSize("default_margin").width; - } - height: 60 * screenScaleFactor + 2 * UM.Theme.getSize("default_margin").height; - width: parent.width; - - // Machine icon - Item { - id: machineIcon; - anchors.verticalCenter: parent.verticalCenter; - height: parent.height - 2 * UM.Theme.getSize("default_margin").width; - width: height; - - // Skeleton - Rectangle { - anchors.fill: parent; - color: UM.Theme.getColor("monitor_skeleton_fill_dark"); - radius: UM.Theme.getSize("default_margin").width; - visible: !printer; - } - - // Content - UM.RecolorImage { - anchors.centerIn: parent; - color: { - if (printer && printer.activePrintJob != undefined) { - return UM.Theme.getColor("monitor_printer_icon"); - } - return UM.Theme.getColor("monitor_printer_icon_inactive"); - } - height: sourceSize.height; - source: { - if (!printer) { - return ""; - } - switch(printer.type) { - case "Ultimaker 3": - return "../svg/UM3-icon.svg"; - case "Ultimaker 3 Extended": - return "../svg/UM3x-icon.svg"; - case "Ultimaker S5": - return "../svg/UMs5-icon.svg"; - } - } - visible: printer; - width: sourceSize.width; - } - } - - // Printer info - Item { - id: printerInfo; - anchors { - left: machineIcon.right; - leftMargin: UM.Theme.getSize("wide_margin").width; - right: collapseIcon.left; - verticalCenter: machineIcon.verticalCenter; - } - height: childrenRect.height; - - // Machine name - Item { - id: machineNameLabel; - height: UM.Theme.getSize("monitor_text_line").height; - width: { - var percent = printer ? 0.75 : 0.3; - return Math.round(parent.width * percent); - } - - // Skeleton - Rectangle { - anchors.fill: parent; - color: UM.Theme.getColor("monitor_skeleton_fill_dark"); - visible: !printer; - } - - // Actual content - Label { - anchors.fill: parent; - color: UM.Theme.getColor("text"); - elide: Text.ElideRight; - font: UM.Theme.getFont("default_bold"); - text: printer ? printer.name : ""; - visible: printer; - width: parent.width; - } - } - - // Job name - Item { - id: activeJobLabel; - anchors { - top: machineNameLabel.bottom; - topMargin: Math.round(UM.Theme.getSize("default_margin").height / 2); - } - height: UM.Theme.getSize("monitor_text_line").height; - width: Math.round(parent.width * 0.75); - - // Skeleton - Rectangle { - anchors.fill: parent; - color: UM.Theme.getColor("monitor_skeleton_fill_dark"); - visible: !printer; - } - - // Actual content - Label { - anchors.fill: parent; - color: UM.Theme.getColor("monitor_text_inactive"); - elide: Text.ElideRight; - font: UM.Theme.getFont("default"); - text: { - if (!printer) { - return ""; - } - if (printer.state == "disabled") { - return catalog.i18nc("@label", "Not available"); - } else if (printer.state == "unreachable") { - return catalog.i18nc("@label", "Unreachable"); - } - if (printer.activePrintJob != null && printer.activePrintJob.name) { - return printer.activePrintJob.name; - } - return catalog.i18nc("@label", "Available"); - } - visible: printer; - } - } - } - - // Collapse icon - UM.RecolorImage { - id: collapseIcon; - anchors { - right: parent.right; - rightMargin: UM.Theme.getSize("default_margin").width; - verticalCenter: parent.verticalCenter; - } - color: UM.Theme.getColor("text"); - height: 15 * screenScaleFactor; // TODO: Theme! - source: root.collapsed ? UM.Theme.getIcon("arrow_left") : UM.Theme.getIcon("arrow_bottom"); - sourceSize { - height: height; - width: width; - } - visible: printer; - width: 15 * screenScaleFactor; // TODO: Theme! - } - - MouseArea { - anchors.fill: parent; - enabled: printer; - onClicked: { - if (model && root.collapsed) { - printerList.currentIndex = model.index; - } else { - printerList.currentIndex = -1; - } - } - } - - Connections { - target: printerList; - onCurrentIndexChanged: { - root.collapsed = printerList.currentIndex != model.index; - } - } - } - // Detailed card - PrinterCardDetails { - collapsed: root.collapsed; - printer: root.printer; - visible: root.printer; - } - - // Progress bar - PrinterCardProgressBar { - visible: printer && printer.activePrintJob != null; - width: parent.width; - } - } - } -} diff --git a/plugins/UM3NetworkPrinting/resources/qml/PrinterCardDetails.qml b/plugins/UM3NetworkPrinting/resources/qml/PrinterCardDetails.qml deleted file mode 100644 index 31da388b00..0000000000 --- a/plugins/UM3NetworkPrinting/resources/qml/PrinterCardDetails.qml +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.3 -import QtQuick.Dialogs 1.1 -import QtQuick.Controls 2.0 -import QtQuick.Controls.Styles 1.3 -import QtGraphicalEffects 1.0 -import QtQuick.Controls 1.4 as LegacyControls -import UM 1.3 as UM - -Item { - id: root; - property var printer: null; - property var printJob: printer ? printer.activePrintJob : null; - property var collapsed: true; - Behavior on height { NumberAnimation { duration: 100 } } - Behavior on opacity { NumberAnimation { duration: 100 } } - height: collapsed ? 0 : childrenRect.height; - opacity: collapsed ? 0 : 1; - width: parent.width; - - Column { - id: contentColumn; - anchors { - left: parent.left; - leftMargin: UM.Theme.getSize("default_margin").width; - right: parent.right; - rightMargin: UM.Theme.getSize("default_margin").width; - } - height: childrenRect.height + UM.Theme.getSize("default_margin").height; - spacing: UM.Theme.getSize("default_margin").height; - width: parent.width; - - HorizontalLine {} - - PrinterInfoBlock { - printer: root.printer; - printJob: root.printer ? root.printer.activePrintJob : null; - } - - HorizontalLine {} - - Row { - height: childrenRect.height; - visible: root.printJob; - width: parent.width; - - PrintJobTitle { - job: root.printer ? root.printer.activePrintJob : null; - } - PrintJobContextMenu { - id: contextButton; - anchors { - right: parent.right; - rightMargin: UM.Theme.getSize("wide_margin").width; - } - printJob: root.printer ? root.printer.activePrintJob : null; - visible: printJob; - } - } - - PrintJobPreview { - anchors.horizontalCenter: parent.horizontalCenter; - job: root.printer && root.printer.activePrintJob ? root.printer.activePrintJob : null; - visible: root.printJob; - } - - CameraButton { - id: showCameraButton; - iconSource: "../svg/camera-icon.svg"; - visible: root.printer; - } - } -} diff --git a/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml b/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml deleted file mode 100644 index e86c959b8c..0000000000 --- a/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.3 -import QtQuick.Controls.Styles 1.3 -import QtQuick.Controls 1.4 -import UM 1.3 as UM - -ProgressBar { - property var progress: { - if (!printer || printer.activePrintJob == null) { - return 0; - } - var result = printer.activePrintJob.timeElapsed / printer.activePrintJob.timeTotal; - if (result > 1.0) { - result = 1.0; - } - return result; - } - style: ProgressBarStyle { - property var remainingTime: { - if (!printer || printer.activePrintJob == null) { - return 0; - } - /* Sometimes total minus elapsed is less than 0. Use Math.max() to prevent remaining - time from ever being less than 0. Negative durations cause strange behavior such - as displaying "-1h -1m". */ - return Math.max(printer.activePrintJob.timeTotal - printer.activePrintJob.timeElapsed, 0); - } - property var progressText: { - if (printer === null ) { - return ""; - } - switch (printer.activePrintJob.state) { - case "wait_cleanup": - if (printer.activePrintJob.timeTotal > printer.activePrintJob.timeElapsed) { - return catalog.i18nc("@label:status", "Aborted"); - } - return catalog.i18nc("@label:status", "Finished"); - case "pre_print": - case "sent_to_printer": - return catalog.i18nc("@label:status", "Preparing"); - case "aborted": - return catalog.i18nc("@label:status", "Aborted"); - case "wait_user_action": - return catalog.i18nc("@label:status", "Aborted"); - case "pausing": - return catalog.i18nc("@label:status", "Pausing"); - case "paused": - return OutputDevice.formatDuration( remainingTime ); - case "resuming": - return catalog.i18nc("@label:status", "Resuming"); - case "queued": - return catalog.i18nc("@label:status", "Action required"); - default: - return OutputDevice.formatDuration( remainingTime ); - } - } - background: Rectangle { - color: UM.Theme.getColor("monitor_progress_background"); - implicitHeight: visible ? 24 : 0; - implicitWidth: 100; - } - progress: Rectangle { - id: progressItem; - color: { - if (! printer || !printer.activePrintJob) { - return "black"; - } - var state = printer.activePrintJob.state - var inactiveStates = [ - "pausing", - "paused", - "resuming", - "wait_cleanup" - ]; - if (inactiveStates.indexOf(state) > -1 && remainingTime > 0) { - return UM.Theme.getColor("monitor_progress_fill_inactive"); - } else { - return UM.Theme.getColor("monitor_progress_fill"); - } - } - - Label { - id: progressLabel; - anchors { - left: parent.left; - leftMargin: getTextOffset(); - } - text: progressText; - anchors.verticalCenter: parent.verticalCenter; - color: progressItem.width + progressLabel.width < control.width ? UM.Theme.getColor("text") : UM.Theme.getColor("monitor_progress_fill_text"); - width: contentWidth; - font: UM.Theme.getFont("default"); - } - - function getTextOffset() { - if (progressItem.width + progressLabel.width + 16 < control.width) { - return progressItem.width + UM.Theme.getSize("default_margin").width; - } else { - return progressItem.width - progressLabel.width - UM.Theme.getSize("default_margin").width; - } - } - } - } - value: progress; - width: parent.width; -} \ No newline at end of file diff --git a/plugins/UM3NetworkPrinting/resources/qml/PrinterFamilyPill.qml b/plugins/UM3NetworkPrinting/resources/qml/PrinterFamilyPill.qml deleted file mode 100644 index 0a88b053a8..0000000000 --- a/plugins/UM3NetworkPrinting/resources/qml/PrinterFamilyPill.qml +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.2 -import QtQuick.Controls 1.4 -import UM 1.2 as UM - -Item { - property alias text: familyNameLabel.text; - property var padding: 3 * screenScaleFactor; // TODO: Theme! - implicitHeight: familyNameLabel.contentHeight + 2 * padding; // Apply the padding to top and bottom. - implicitWidth: Math.max(48 * screenScaleFactor, familyNameLabel.contentWidth + implicitHeight); // The extra height is added to ensure the radius doesn't cut something off. - - Rectangle { - id: background; - anchors { - horizontalCenter: parent.horizontalCenter; - right: parent.right; - } - color: familyNameLabel.text.length < 1 ? UM.Theme.getColor("monitor_skeleton_fill") : UM.Theme.getColor("monitor_pill_background"); - height: parent.height; - radius: 0.5 * height; - width: parent.width; - } - - Label { - id: familyNameLabel; - anchors.centerIn: parent; - color: UM.Theme.getColor("text"); - text: ""; - } -} \ No newline at end of file diff --git a/plugins/UM3NetworkPrinting/resources/qml/PrinterInfoBlock.qml b/plugins/UM3NetworkPrinting/resources/qml/PrinterInfoBlock.qml deleted file mode 100644 index 92a8f1dcb3..0000000000 --- a/plugins/UM3NetworkPrinting/resources/qml/PrinterInfoBlock.qml +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.3 -import QtQuick.Dialogs 1.1 -import QtQuick.Controls 2.0 -import QtQuick.Controls.Styles 1.3 -import QtGraphicalEffects 1.0 -import QtQuick.Controls 1.4 as LegacyControls -import UM 1.3 as UM - -// Includes printer type pill and extuder configurations - -Item { - id: root; - property var printer: null; - property var printJob: null; - width: parent.width; - height: childrenRect.height; - - // Printer family pills - Row { - id: printerFamilyPills; - anchors { - left: parent.left; - right: parent.right; - } - height: childrenRect.height; - spacing: Math.round(0.5 * UM.Theme.getSize("default_margin").width); - width: parent.width; - - Repeater { - id: compatiblePills; - delegate: PrinterFamilyPill { - text: modelData; - } - model: printJob ? printJob.compatibleMachineFamilies : []; - visible: printJob; - - } - - PrinterFamilyPill { - text: printer ? printer.type : ""; - visible: !compatiblePills.visible && printer; - } - } - - // Extruder info - Row { - id: extrudersInfo; - anchors { - left: parent.left; - right: parent.right; - rightMargin: UM.Theme.getSize("default_margin").width; - top: printerFamilyPills.bottom; - topMargin: UM.Theme.getSize("default_margin").height; - } - height: childrenRect.height; - spacing: UM.Theme.getSize("default_margin").width; - width: parent.width; - - PrintCoreConfiguration { - width: Math.round(parent.width / 2) * screenScaleFactor; - printCoreConfiguration: getExtruderConfig(0); - } - - PrintCoreConfiguration { - width: Math.round(parent.width / 2) * screenScaleFactor; - printCoreConfiguration: getExtruderConfig(1); - } - } - - function getExtruderConfig( i ) { - if (root.printJob) { - // Use more-specific print job if possible - return root.printJob.configuration.extruderConfigurations[i]; - } - if (root.printer) { - return root.printer.printerConfiguration.extruderConfigurations[i]; - } - return null; - } -} \ No newline at end of file From 0d55d023a193c651a28e69cae667d5daa0ae2548 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 10 Dec 2018 11:36:03 +0100 Subject: [PATCH 0802/1292] Align the message colors with the ones in the designs. Contributes to CURA-6018. --- resources/themes/cura-light/theme.json | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 0ef6c24bfb..738f3e5c3f 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -248,11 +248,13 @@ "message_background": [255, 255, 255, 255], "message_shadow": [0, 0, 0, 120], - "message_border": [127, 127, 127, 255], + "message_border": [192, 193, 194, 255], "message_text": [0, 0, 0, 255], - "message_button": [50, 130, 255, 255], - "message_button_hover": [50, 130, 255, 255], - "message_button_active": [50, 130, 255, 255], + "message_close": [102, 102, 102, 255], + "message_close_hover": [8, 7, 63, 255], + "message_button": [38, 113, 231, 255], + "message_button_hover": [81, 145, 247, 255], + "message_button_active": [38, 113, 231, 255], "message_button_text": [255, 255, 255, 255], "message_button_text_hover": [255, 255, 255, 255], "message_button_text_active": [255, 255, 255, 255], @@ -478,6 +480,8 @@ "message_shadow": [0, 0], "message_margin": [0, 1.0], "message_inner_margin": [1.5, 1.5], + "message_radius": [0.25, 0.25], + "message_button_radius": [0.15, 0.15], "infill_button_margin": [0.5, 0.5], From ad7dcf6fc0700ebfdb424644fbeb8569a2f9f446 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 10 Dec 2018 11:36:12 +0100 Subject: [PATCH 0803/1292] Delete ClusterControlItem.qml Contributes to CL-1152 --- .../resources/qml/ClusterControlItem.qml | 110 ------------------ 1 file changed, 110 deletions(-) delete mode 100644 plugins/UM3NetworkPrinting/resources/qml/ClusterControlItem.qml diff --git a/plugins/UM3NetworkPrinting/resources/qml/ClusterControlItem.qml b/plugins/UM3NetworkPrinting/resources/qml/ClusterControlItem.qml deleted file mode 100644 index 94e75a6de0..0000000000 --- a/plugins/UM3NetworkPrinting/resources/qml/ClusterControlItem.qml +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.3 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.3 -import UM 1.3 as UM -import Cura 1.0 as Cura - -Component { - Rectangle { - id: base; - property var shadowRadius: UM.Theme.getSize("monitor_shadow_radius").width; - property var cornerRadius: UM.Theme.getSize("monitor_corner_radius").width; - anchors.fill: parent; - color: UM.Theme.getColor("main_background"); - visible: OutputDevice != null; - - UM.I18nCatalog { - id: catalog; - name: "cura"; - } - - Label { - id: printingLabel; - anchors { - left: parent.left; - leftMargin: 4 * UM.Theme.getSize("default_margin").width; - margins: 2 * UM.Theme.getSize("default_margin").width; - right: parent.right; - top: parent.top; - } - color: UM.Theme.getColor("text"); - elide: Text.ElideRight; - font: UM.Theme.getFont("large"); - text: catalog.i18nc("@label", "Printing"); - } - - Label { - id: managePrintersLabel; - anchors { - bottom: printingLabel.bottom; - right: printerScrollView.right; - rightMargin: 4 * UM.Theme.getSize("default_margin").width; - } - color: UM.Theme.getColor("primary"); // "Cura Blue" - font: UM.Theme.getFont("default"); - linkColor: UM.Theme.getColor("primary"); // "Cura Blue" - text: catalog.i18nc("@label link to connect manager", "Manage printers"); - } - - MouseArea { - anchors.fill: managePrintersLabel; - hoverEnabled: true; - onClicked: Cura.MachineManager.printerOutputDevices[0].openPrinterControlPanel(); - onEntered: managePrintersLabel.font.underline = true; - onExited: managePrintersLabel.font.underline = false; - } - - // Skeleton loading - Column { - id: skeletonLoader; - anchors { - left: parent.left; - leftMargin: UM.Theme.getSize("wide_margin").width; - right: parent.right; - rightMargin: UM.Theme.getSize("wide_margin").width; - top: printingLabel.bottom; - topMargin: UM.Theme.getSize("default_margin").height; - } - spacing: UM.Theme.getSize("default_margin").height - 10; - visible: printerList.count === 0; - - PrinterCard { - printer: null; - } - PrinterCard { - printer: null; - } - } - - // Actual content - ScrollView { - id: printerScrollView; - anchors { - bottom: parent.bottom; - left: parent.left; - right: parent.right; - top: printingLabel.bottom; - topMargin: UM.Theme.getSize("default_margin").height; - } - style: UM.Theme.styles.scrollview; - - ListView { - id: printerList; - property var currentIndex: -1; - anchors { - fill: parent; - leftMargin: UM.Theme.getSize("wide_margin").width; - rightMargin: UM.Theme.getSize("wide_margin").width; - } - delegate: PrinterCard { - printer: modelData; - } - model: OutputDevice.printers; - spacing: UM.Theme.getSize("default_margin").height - 10; - } - } - } -} From 8a856f13d26c44668cb086729b22534b438d9a2b Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 10 Dec 2018 11:36:51 +0100 Subject: [PATCH 0804/1292] Re-add config changes in monitor tab Contributes to CL-1152 --- .../resources/qml/ClusterMonitorItem.qml | 2 +- .../resources/qml/DiscoverUM3Action.qml | 2 +- .../resources/qml/HorizontalLine.qml | 12 -- .../qml/MonitorConfigOverrideDialog.qml | 131 ++++++++++++++++++ .../resources/qml/MonitorPrintJobCard.qml | 1 + .../resources/qml/MonitorPrintJobPreview.qml | 7 +- .../qml/MonitorPrintJobProgressBar.qml | 2 + .../resources/qml/MonitorPrinterCard.qml | 75 +++++++++- .../src/ClusterUM3OutputDevice.py | 10 -- 9 files changed, 210 insertions(+), 32 deletions(-) delete mode 100644 plugins/UM3NetworkPrinting/resources/qml/HorizontalLine.qml create mode 100644 plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml diff --git a/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml b/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml index adf5ea5e1c..31b3f4d4f5 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml @@ -130,7 +130,7 @@ Component verticalCenter: externalLinkIcon.verticalCenter } color: UM.Theme.getColor("primary") - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("default") // 12pt, regular linkColor: UM.Theme.getColor("primary") text: catalog.i18nc("@label link to connect manager", "Manage queue in Cura Connect") } diff --git a/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml b/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml index bb710127fc..e5f668c70d 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml @@ -57,7 +57,7 @@ Cura.MachineAction spacing: UM.Theme.getSize("default_margin").height SystemPalette { id: palette } - UM.I18nCatalog { id: catalog; name: "cura" } + UM.I18nCatalog { id: catalog; name:"cura" } Label { id: pageTitle diff --git a/plugins/UM3NetworkPrinting/resources/qml/HorizontalLine.qml b/plugins/UM3NetworkPrinting/resources/qml/HorizontalLine.qml deleted file mode 100644 index aeb92697ad..0000000000 --- a/plugins/UM3NetworkPrinting/resources/qml/HorizontalLine.qml +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.3 -import QtQuick.Controls 2.0 -import UM 1.3 as UM - -Rectangle { - color: UM.Theme.getColor("monitor_lining_light"); // TODO: Maybe theme separately? Maybe not. - height: UM.Theme.getSize("default_lining").height; - width: parent.width; -} \ No newline at end of file diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml new file mode 100644 index 0000000000..aa62afa083 --- /dev/null +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml @@ -0,0 +1,131 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.3 +import QtQuick.Controls 1.4 +import QtQuick.Layouts 1.3 +import QtQuick.Dialogs 1.2 +import UM 1.3 as UM + +UM.Dialog +{ + id: overrideConfirmationDialog + + property var printer: null + + minimumWidth: screenScaleFactor * 640; + minimumHeight: screenScaleFactor * 320; + width: minimumWidth + height: minimumHeight + title: catalog.i18nc("@title:window", "Configuration Changes") + rightButtons: + [ + Button + { + id: overrideButton + anchors.margins: UM.Theme.getSize("default_margin").width + text: catalog.i18nc("@action:button", "Override") + onClicked: + { + OutputDevice.forceSendJob(printer.activePrintJob.key) + overrideConfirmationDialog.close() + } + }, + Button + { + id: cancelButton + anchors.margins: UM.Theme.getSize("default_margin").width + text: catalog.i18nc("@action:button", "Cancel") + onClicked: + { + overrideConfirmationDialog.reject() + } + } + ] + + Label + { + anchors + { + fill: parent + leftMargin: 60 + rightMargin: 60 + topMargin: 18 + bottomMargin: 56 + } + wrapMode: Text.WordWrap + text: + { + var topLine + if (materialsAreKnown(printer.activePrintJob)) + { + topLine = catalog.i18nc("@label", "The assigned printer, %1, requires the following configuration change(s):").arg(printer.name) + } + else + { + topLine = catalog.i18nc("@label", "The printer %1 is assigned, but the job contains an unknown material configuration.").arg(printer.name) + } + var result = "

    " + topLine +"

    " + for (var i = 0; i < printer.activePrintJob.configurationChanges.length; i++) + { + var change = printer.activePrintJob.configurationChanges[i] + var text + switch (change.typeOfChange) + { + case "material_change": + text = catalog.i18nc("@label", "Change material %1 from %2 to %3.").arg(change.index + 1).arg(change.originName).arg(change.targetName) + break + case "material_insert": + text = catalog.i18nc("@label", "Load %3 as material %1 (This cannot be overridden).").arg(change.index + 1).arg(change.targetName) + break + case "print_core_change": + text = catalog.i18nc("@label", "Change print core %1 from %2 to %3.").arg(change.index + 1).arg(change.originName).arg(change.targetName) + break + case "buildplate_change": + text = catalog.i18nc("@label", "Change build plate to %1 (This cannot be overridden).").arg(formatBuildPlateType(change.target_name)) + break + default: + text = "unknown" + } + result += "

    " + text + "

    " + } + return result + } + } + // Utils + function formatPrintJobName(name) { + var extensions = [ ".gz", ".gcode", ".ufp" ]; + for (var i = 0; i < extensions.length; i++) { + var extension = extensions[i]; + if (name.slice(-extension.length) === extension) { + name = name.substring(0, name.length - extension.length); + } + } + return name; + } + function materialsAreKnown(job) { + var conf0 = job.configuration[0]; + if (conf0 && !conf0.material.material) { + return false; + } + var conf1 = job.configuration[1]; + if (conf1 && !conf1.material.material) { + return false; + } + return true; + } + function formatBuildPlateType(buildPlateType) { + var translationText = ""; + switch (buildPlateType) { + case "glass": + translationText = catalog.i18nc("@label", "Glass"); + break; + case "aluminum": + translationText = catalog.i18nc("@label", "Aluminum"); + break; + default: + translationText = null; + } + return translationText; + } +} \ No newline at end of file diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml index 8231870c21..5eaeff2e84 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml @@ -26,6 +26,7 @@ Item ExpandableCard { + borderColor: printJob.configurationChanges.length !== 0 ? "#f5a623" : "#EAEAEC" // TODO: Theme! headerItem: Row { height: 48 * screenScaleFactor // TODO: Theme! diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml index ec26bbe568..5acd350abb 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml @@ -23,7 +23,7 @@ Item anchors.fill: parent opacity: { - if (printJob && (printJob.state == "error" || !printJob.isActive)) + if (printJob && (printJob.state == "error" || printJob.configurationChanges.length > 0 || !printJob.isActive)) { return 0.5 } @@ -60,6 +60,10 @@ Item height: 0.5 * printJobPreview.height source: { + if (printJob.configurationChanges.length > 0) + { + return "../svg/warning-icon.svg" + } switch(printJob.state) { case "error": @@ -75,6 +79,7 @@ Item default: return "" } + return "" } sourceSize { diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml index 88418516ed..e646172a6c 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml @@ -88,6 +88,8 @@ Item return catalog.i18nc("@label:status", "Aborted") } return catalog.i18nc("@label:status", "Finished") + case "finished": + return catalog.i18nc("@label:status", "Finished") case "sent_to_printer": return catalog.i18nc("@label:status", "Preparing...") case "pre_print": diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml index 567fff8489..1676c51edf 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml @@ -3,6 +3,7 @@ import QtQuick 2.3 import QtQuick.Controls 2.0 +import QtQuick.Dialogs 1.1 import UM 1.3 as UM /** @@ -66,7 +67,7 @@ Item { verticalCenter: parent.verticalCenter } - width: 216 * screenScaleFactor // TODO: Theme! + width: 180 * screenScaleFactor // TODO: Theme! height: printerNameLabel.height + printerFamilyPill.height + 6 * screenScaleFactor // TODO: Theme! Label @@ -150,7 +151,7 @@ Item } border { - color: "#EAEAEC" // TODO: Theme! + color: printer.activePrintJob && printer.activePrintJob.configurationChanges.length > 0 ? "#f5a623" : "#EAEAEC" // TODO: Theme! width: borderSize // TODO: Remove once themed } color: "white" // TODO: Theme! @@ -185,14 +186,15 @@ Item } if (printer && printer.state == "unreachable") { - return catalog.i18nc("@label:status", "Unreachable") + return catalog.i18nc("@label:status", "Unavailable") } - if (printer && printer.state == "idle") + if (printer && !printer.activePrintJob && printer.state == "idle") { return catalog.i18nc("@label:status", "Idle") } return "" } + visible: text !== "" } Item @@ -218,7 +220,7 @@ Item { verticalCenter: parent.verticalCenter } - width: 216 * screenScaleFactor // TODO: Theme! + width: 180 * screenScaleFactor // TODO: Theme! height: printerNameLabel.height + printerFamilyPill.height + 6 * screenScaleFactor // TODO: Theme! visible: printer.activePrintJob @@ -247,7 +249,7 @@ Item } color: printer.activePrintJob && printer.activePrintJob.isActive ? "#53657d" : "#babac1" // TODO: Theme! elide: Text.ElideRight - font: UM.Theme.getFont("very_small") // 12pt, regular + font: UM.Theme.getFont("default") // 12pt, regular text: printer.activePrintJob ? printer.activePrintJob.owner : "Anonymous" // TODO: I18N width: parent.width @@ -264,8 +266,67 @@ Item verticalCenter: parent.verticalCenter } printJob: printer.activePrintJob - visible: printer.activePrintJob + visible: printer.activePrintJob && printer.activePrintJob.configurationChanges.length === 0 + } + + Label + { + anchors + { + verticalCenter: parent.verticalCenter + } + font: UM.Theme.getFont("default") + text: "Requires configuration changes" + visible: printer.activePrintJob && printer.activePrintJob.configurationChanges.length > 0 + + // FIXED-LINE-HEIGHT: + height: 18 * screenScaleFactor // TODO: Theme! + verticalAlignment: Text.AlignVCenter } } + + Button + { + id: detailsButton + anchors + { + verticalCenter: parent.verticalCenter + right: parent.right + rightMargin: 18 * screenScaleFactor // TODO: Theme! + } + background: Rectangle + { + color: "#d8d8d8" // TODO: Theme! + radius: 2 * screenScaleFactor // Todo: Theme! + Rectangle + { + anchors.fill: parent + anchors.bottomMargin: 2 * screenScaleFactor // TODO: Theme! + color: detailsButton.hovered ? "#e4e4e4" : "#f0f0f0" // TODO: Theme! + radius: 2 * screenScaleFactor // Todo: Theme! + } + } + contentItem: Label + { + anchors.fill: parent + anchors.bottomMargin: 2 * screenScaleFactor // TODO: Theme! + color: "#1e66d7" // TODO: Theme! + font: UM.Theme.getFont("medium") // 14pt, regular + text: "Details" // TODO: I18NC! + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + height: 18 * screenScaleFactor // TODO: Theme! + } + implicitHeight: 32 * screenScaleFactor // TODO: Theme! + implicitWidth: 96 * screenScaleFactor // TODO: Theme! + visible: printer.activePrintJob && printer.activePrintJob.configurationChanges.length > 0 + onClicked: overrideConfirmationDialog.open() + } + } + + MonitorConfigOverrideDialog + { + id: overrideConfirmationDialog + printer: base.printer } } \ No newline at end of file diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index e31229680c..292011929d 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -608,16 +608,6 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): def _createMaterialOutputModel(self, material_data: Dict[str, Any]) -> "MaterialOutputModel": material_manager = CuraApplication.getInstance().getMaterialManager() material_group_list = material_manager.getMaterialGroupListByGUID(material_data["guid"]) - # This can happen if the connected machine has no material in one or more extruders (if GUID is empty), or the - # material is unknown to Cura, so we should return an "empty" or "unknown" material model. - if material_group_list is None: - material_name = "Empty" if len(material_data["guid"]) == 0 else "Unknown" - return MaterialOutputModel(guid = material_data["guid"], - type = material_data.get("type", ""), - color = material_data.get("color", ""), - brand = material_data.get("brand", ""), - name = material_data.get("name", material_name) - ) # Sort the material groups by "is_read_only = True" first, and then the name alphabetically. read_only_material_group_list = list(filter(lambda x: x.is_read_only, material_group_list)) From dff364ee30870822158de7beaeb1faf7722f3d37 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 10 Dec 2018 12:03:29 +0100 Subject: [PATCH 0805/1292] Change the panel to have also rounded rectangle in the top part Contributes to CURA-5941. --- resources/qml/ExpandableComponent.qml | 2 +- .../qml/PrintSetupSelector/PrintSetupSelectorContents.qml | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index 4170a0942e..04793653fe 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -162,7 +162,7 @@ Item background: Cura.RoundedRectangle { - cornerSide: Cura.RoundedRectangle.Direction.Down + cornerSide: Cura.RoundedRectangle.Direction.All color: contentBackgroundColor border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml index 7cd03ff74a..313bf0830c 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml @@ -38,11 +38,13 @@ Item // Header of the popup - Rectangle + Cura.RoundedRectangle { id: header height: UM.Theme.getSize("print_setup_widget_header").height color: UM.Theme.getColor("secondary") + cornerSide: Cura.RoundedRectangle.Direction.Up + radius: UM.Theme.getSize("default_radius").width anchors { From df4e5c40df403f76dfede9b74d358a075ff951c0 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 10 Dec 2018 12:19:52 +0100 Subject: [PATCH 0806/1292] Rename ClusterMonitorItem Contributes to CL-1152 --- .../resources/qml/{ClusterMonitorItem.qml => MonitorStage.qml} | 1 + plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) rename plugins/UM3NetworkPrinting/resources/qml/{ClusterMonitorItem.qml => MonitorStage.qml} (99%) diff --git a/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml similarity index 99% rename from plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml rename to plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml index 31b3f4d4f5..4d59e0eb6b 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml @@ -8,6 +8,7 @@ import UM 1.3 as UM import Cura 1.0 as Cura import QtGraphicalEffects 1.0 +// Root component for the monitor tab (stage) Component { Item diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index 292011929d..08592df603 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -64,7 +64,7 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): self._print_jobs = [] # type: List[UM3PrintJobOutputModel] self._received_print_jobs = False # type: bool - self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../resources/qml/ClusterMonitorItem.qml") + self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../resources/qml/MonitorStage.qml") # See comments about this hack with the clusterPrintersChanged signal self.printersChanged.connect(self.clusterPrintersChanged) From 70b9a44ae42de5ae7a796285338f7abad673f984 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 10 Dec 2018 13:04:02 +0100 Subject: [PATCH 0807/1292] Removed import of CuraVersion CURA-6013 --- plugins/Toolbox/src/Toolbox.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 7e35f5d1f4..b88e1aa973 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -13,7 +13,6 @@ from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkRepl from UM.Logger import Logger from UM.PluginRegistry import PluginRegistry from UM.Extension import Extension -from UM.Qt.ListModel import ListModel from UM.i18n import i18nCatalog from UM.Version import Version @@ -22,8 +21,7 @@ from cura.CuraApplication import CuraApplication from .AuthorsModel import AuthorsModel from .PackagesModel import PackagesModel -from cura.CuraVersion import CuraVersion -from cura.API import CuraAPI + if TYPE_CHECKING: from cura.Settings.GlobalStack import GlobalStack @@ -158,7 +156,7 @@ class Toolbox(QObject, Extension): self._rate_request = QNetworkRequest(url) for header_name, header_value in self._request_headers: cast(QNetworkRequest, self._rate_request).setRawHeader(header_name, header_value) - data = "{\"data\": {\"cura_version\": \"%s\", \"rating\": %i}}" % (Version(CuraVersion), rating) + data = "{\"data\": {\"cura_version\": \"%s\", \"rating\": %i}}" % (Version(self._application.getVersion()), rating) self._rate_reply = cast(QNetworkAccessManager, self._network_manager).put(self._rate_request, data.encode()) @pyqtSlot(result = str) From f432d7c858862bfbc1e671c79718f57aee3a7c07 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 10 Dec 2018 13:11:42 +0100 Subject: [PATCH 0808/1292] STAR-322: Using a test setup to run tests with Cura app --- .../tests/Cloud/NetworkManagerMock.py | 4 +- .../tests/Cloud/TestCloudApiClient.py | 5 +-- .../Cloud/TestCloudOutputDeviceManager.py | 27 ++++++++------ .../tests/TestSendMaterialJob.py | 2 +- plugins/UM3NetworkPrinting/tests/conftest.py | 37 +++++++++++++++++++ 5 files changed, 58 insertions(+), 17 deletions(-) create mode 100644 plugins/UM3NetworkPrinting/tests/conftest.py diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py b/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py index fc84569fa4..e8e4fc8de7 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py @@ -66,7 +66,8 @@ class NetworkManagerMock: # \return The data in the response. def prepareGetClusters(self, data: Optional[dict] = None) -> dict: data, response = self._getResponseData("clusters", data) - self.prepareReply("GET", "https://api-staging.ultimaker.com/connect/v1/clusters", 200, response) + status_code = 200 if "data" in data else int(data["errors"][0]["http_status"]) + self.prepareReply("GET", "https://api-staging.ultimaker.com/connect/v1/clusters", status_code, response) return data ## Gets the data that should be in the server's response in both dictionary and JSON-encoded bytes format. @@ -87,6 +88,7 @@ class NetworkManagerMock: def flushReplies(self): for reply in self.replies.values(): self.finished.emit(reply) + self.reset() ## Deletes all prepared replies def reset(self): diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py index 328bb053b7..91f367f9ad 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py @@ -95,9 +95,8 @@ class TestCloudApiClient(TestCase): def _callback(clusters): result.extend(clusters) - with mock.patch.object(Application, "getInstance", new = lambda: FixtureApplication()): - api = CloudApiClient(account_mock, self._errorHandler) - api.getClusters(_callback) + api = CloudApiClient(account_mock, self._errorHandler) + api.getClusters(_callback) manager_mock.return_value.finished.emit(reply_mock) diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py index 80ce54aeee..799e715f0d 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py @@ -4,9 +4,9 @@ from unittest import TestCase from unittest.mock import patch from cura.CuraApplication import CuraApplication -from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputDevice import CloudOutputDevice -from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputDeviceManager import CloudOutputDeviceManager -from plugins.UM3NetworkPrinting.tests.Cloud.NetworkManagerMock import NetworkManagerMock +from src.Cloud.CloudOutputDevice import CloudOutputDevice +from src.Cloud.CloudOutputDeviceManager import CloudOutputDeviceManager +from .NetworkManagerMock import NetworkManagerMock @patch("cura.NetworkClient.QNetworkAccessManager") @@ -15,18 +15,19 @@ class TestCloudOutputDeviceManager(TestCase): def setUp(self): super().setUp() self.app = CuraApplication.getInstance() - if not self.app: - self.app = CuraApplication() - self.app.initialize() - self.network = NetworkManagerMock() self.manager = CloudOutputDeviceManager() self.clusters_response = self.network.prepareGetClusters() - ## In the tear down method we check whether the state of the output device manager is what we expect based on the - # mocked API response. def tearDown(self): - super().tearDown() + try: + self._beforeTearDown() + finally: + super().tearDown() + + ## Before tear down method we check whether the state of the output device manager is what we expect based on the + # mocked API response. + def _beforeTearDown(self): # let the network send replies self.network.flushReplies() # get the created devices @@ -82,6 +83,7 @@ class TestCloudOutputDeviceManager(TestCase): self.assertTrue(self.app.getOutputDeviceManager().getOutputDevice(cluster1["cluster_id"]).isConnected()) self.assertFalse(self.app.getOutputDeviceManager().getOutputDevice(cluster2["cluster_id"]).isConnected()) + self.assertEquals([], active_machine_mock.setMetaDataEntry.mock_calls) @patch("cura.CuraApplication.CuraApplication.getGlobalContainerStack") def test_device_connects_by_network_key(self, global_container_stack_mock, network_mock): @@ -97,11 +99,12 @@ class TestCloudOutputDeviceManager(TestCase): self.assertFalse(self.app.getOutputDeviceManager().getOutputDevice(cluster1["cluster_id"]).isConnected()) self.assertTrue(self.app.getOutputDeviceManager().getOutputDevice(cluster2["cluster_id"]).isConnected()) - active_machine_mock.setMetaDataEntry.assert_called_once_with("um_cloud_cluster_id", cluster2["cluster_id"]) + active_machine_mock.setMetaDataEntry.assert_called_with("um_cloud_cluster_id", cluster2["cluster_id"]) @patch("UM.Message.Message.show") def test_api_error(self, message_mock, network_mock): - self.clusters_response = {"errors": [{"id": "notFound"}]} + self.clusters_response = {"errors": [{"id": "notFound", "title": "Not found!", "http_status": "404"}]} self.network.prepareGetClusters(self.clusters_response) self._loadData(network_mock) + self.network.flushReplies() message_mock.assert_called_once_with() diff --git a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py index e3ec9faeaf..7db5ebdedf 100644 --- a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py @@ -10,7 +10,7 @@ from PyQt5.QtCore import QByteArray from UM.MimeTypeDatabase import MimeType from UM.Application import Application -from ..src.SendMaterialJob import SendMaterialJob +from src.SendMaterialJob import SendMaterialJob @patch("builtins.open", lambda _, __: io.StringIO("")) diff --git a/plugins/UM3NetworkPrinting/tests/conftest.py b/plugins/UM3NetworkPrinting/tests/conftest.py new file mode 100644 index 0000000000..6f245f8f2f --- /dev/null +++ b/plugins/UM3NetworkPrinting/tests/conftest.py @@ -0,0 +1,37 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Uranium is released under the terms of the LGPLv3 or higher. + +import pytest +import Arcus #Prevents error: "PyCapsule_GetPointer called with incorrect name" with conflicting SIP configurations between Arcus and PyQt: Import Arcus first! +from UM.Qt.QtApplication import QtApplication # QT application import is required, even though it isn't used. +from UM.Application import Application +from UM.Signal import Signal + +from cura.CuraApplication import CuraApplication + + +# This mock application must extend from Application and not QtApplication otherwise some QObjects are created and +# a segfault is raised. +class FixtureApplication(CuraApplication): + def __init__(self): + super().__init__() + super().initialize() + Signal._signalQueue = self + + def functionEvent(self, event): + event.call() + + def parseCommandLine(self): + pass + + def processEvents(self): + pass + + +@pytest.fixture(autouse=True) +def application(): + # Since we need to use it more that once, we create the application the first time and use its instance the second + application = FixtureApplication.getInstance() + if application is None: + application = FixtureApplication() + return application From 1487af167b616a190e320e6d05c94fad3a3ff95b Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 10 Dec 2018 13:20:36 +0100 Subject: [PATCH 0809/1292] Disable async loading for ToolboxDetailTile CURA-6006 --- plugins/Toolbox/resources/qml/ToolboxDetailList.qml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailList.qml b/plugins/Toolbox/resources/qml/ToolboxDetailList.qml index 1700a58ebe..4e44ea7d0b 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailList.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailList.qml @@ -32,7 +32,11 @@ Item model: toolbox.packagesModel delegate: Loader { - asynchronous: true + // FIXME: When using asynchronous loading, on Mac and Windows, the tile may fail to load complete, + // leaving an empty space below the title part. We turn it off for now to make it work on Mac and + // Windows. + // Can be related to this QT bug: https://bugreports.qt.io/browse/QTBUG-50992 + asynchronous: false source: "ToolboxDetailTile.qml" } } From b745755a7d1a0b7b482add455cb20535bc265247 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 10 Dec 2018 13:22:28 +0100 Subject: [PATCH 0810/1292] Remove TODO in ToolboxProgressButton CURA-6006 This file has been refactored. --- plugins/Toolbox/resources/qml/ToolboxProgressButton.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml b/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml index 3ca18a52ed..933e3a5900 100644 --- a/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml +++ b/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml @@ -7,7 +7,7 @@ import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM import Cura 1.0 as Cura -// TODO; This is in quite some need for refactoring. + Item { id: base From 9d1701aacbef8273f3225f26c158ceb2d6b6b8f3 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 10 Dec 2018 13:29:58 +0100 Subject: [PATCH 0811/1292] Removed hardcoded color CURA-6013 --- plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml index 8a2fdc8bc8..ceaadc110d 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml @@ -20,7 +20,7 @@ Rectangle Rectangle { id: thumbnail - color: "white" + color: UM.Theme.getColor("main_background") width: UM.Theme.getSize("toolbox_thumbnail_large").width height: UM.Theme.getSize("toolbox_thumbnail_large").height anchors From af37f51cf8aa9acd121d02d4b891d72444556350 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 10 Dec 2018 13:36:06 +0100 Subject: [PATCH 0812/1292] Make the expandable content header to be a common header for every expandable component. Contributes to CURA-5941. --- .../SimulationViewMenuComponent.qml | 1 + resources/qml/ExpandableComponent.qml | 68 +++++++++++----- resources/qml/ExpandablePopup.qml | 3 + .../PrintSetupSelector/PrintSetupSelector.qml | 10 +-- .../PrintSetupSelectorContents.qml | 77 +------------------ .../PrintSetupSelectorHeader.qml | 3 + resources/themes/cura-light/theme.json | 3 +- 7 files changed, 64 insertions(+), 101 deletions(-) diff --git a/plugins/SimulationView/SimulationViewMenuComponent.qml b/plugins/SimulationView/SimulationViewMenuComponent.qml index 76875a035d..58b2bfe520 100644 --- a/plugins/SimulationView/SimulationViewMenuComponent.qml +++ b/plugins/SimulationView/SimulationViewMenuComponent.qml @@ -16,6 +16,7 @@ Cura.ExpandableComponent id: base width: UM.Theme.getSize("layerview_menu_size").width + contentHeaderTitle: catalog.i18nc("@label", "Color scheme") Connections { diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index 04793653fe..3c898caeb8 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -1,3 +1,6 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + import QtQuick 2.7 import QtQuick.Controls 2.3 @@ -40,6 +43,9 @@ Item // How much spacing is needed around the contentItem property alias contentPadding: content.padding + // Adds a title to the content item + property alias contentHeaderTitle: contentHeader.headerTitle + // How much spacing is needed for the contentItem by Y coordinate property var contentSpacingY: UM.Theme.getSize("narrow_margin").width @@ -55,7 +61,7 @@ Item property alias iconSize: collapseButton.height // Is the "drawer" open? - readonly property alias expanded: content.visible + readonly property alias expanded: contentContainer.visible // What should the radius of the header be. This is also influenced by the headerCornerSide property alias headerRadius: background.radius @@ -71,7 +77,7 @@ Item function toggleContent() { - content.visible = !expanded + contentContainer.visible = !expanded } // Add this binding since the background color is not updated otherwise @@ -147,10 +153,13 @@ Item z: background.z - 1 } - Control + Cura.RoundedRectangle { - id: content + id: contentContainer + visible: false + width: childrenRect.width + height: childrenRect.height // Ensure that the content is located directly below the headerItem y: background.height + base.shadowOffset + base.contentSpacingY @@ -158,25 +167,42 @@ Item // Make the content aligned with the rest, using the property contentAlignment to decide whether is right or left. // In case of right alignment, the 3x padding is due to left, right and padding between the button & text. x: contentAlignment == ExpandableComponent.ContentAlignment.AlignRight ? -width + collapseButton.width + headerItemLoader.width + 3 * background.padding : 0 - padding: UM.Theme.getSize("default_margin").width - background: Cura.RoundedRectangle + cornerSide: Cura.RoundedRectangle.Direction.All + color: contentBackgroundColor + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("lining") + radius: UM.Theme.getSize("default_radius").width + + ExpandableComponentHeader { - cornerSide: Cura.RoundedRectangle.Direction.All - color: contentBackgroundColor - border.width: UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("lining") - radius: UM.Theme.getSize("default_radius").width + id: contentHeader + headerTitle: "" + anchors + { + top: parent.top + right: parent.right + left: parent.left + } + } - contentItem: Item {} - - onContentItemChanged: + Control { - // Since we want the size of the content to be set by the size of the content, - // we need to do it like this. - content.width = contentItem.width + 2 * content.padding - content.height = contentItem.height + 2 * content.padding + id: content + + anchors.top: contentHeader.bottom + padding: UM.Theme.getSize("default_margin").width + + contentItem: Item {} + + onContentItemChanged: + { + // Since we want the size of the content to be set by the size of the content, + // we need to do it like this. + content.width = contentItem.width + 2 * content.padding + content.height = contentItem.height + 2 * content.padding + } } } @@ -187,6 +213,10 @@ Item // Since it could be that the content is dynamically populated, we should also take these changes into account. target: content.contentItem onWidthChanged: content.width = content.contentItem.width + 2 * content.padding - onHeightChanged: content.height = content.contentItem.height + 2 * content.padding + onHeightChanged: + { + content.height = content.contentItem.height + 2 * content.padding + contentContainer.height = contentHeader.height + content.height + } } } diff --git a/resources/qml/ExpandablePopup.qml b/resources/qml/ExpandablePopup.qml index c15310f803..475f7f9f59 100644 --- a/resources/qml/ExpandablePopup.qml +++ b/resources/qml/ExpandablePopup.qml @@ -1,3 +1,6 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + import QtQuick 2.7 import QtQuick.Controls 2.3 diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector/PrintSetupSelector.qml index 19c8067683..01886a5ea5 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelector.qml @@ -11,10 +11,11 @@ Cura.ExpandableComponent { id: printSetupSelector - property string enabledText: catalog.i18nc("@label:Should be short", "On") - property string disabledText: catalog.i18nc("@label:Should be short", "Off") + property bool preSlicedData: PrintInformation.preSliced contentPadding: UM.Theme.getSize("default_lining").width + contentHeaderTitle: catalog.i18nc("@label", "Print settings") + enabled: !preSlicedData UM.I18nCatalog { @@ -22,10 +23,7 @@ Cura.ExpandableComponent name: "cura" } - headerItem: PrintSetupSelectorHeader - { - anchors.fill: parent - } + headerItem: PrintSetupSelectorHeader {} Cura.ExtrudersModel { diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml index 313bf0830c..6c678f7ce5 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml @@ -12,7 +12,7 @@ import "Custom" Item { - id: popup + id: content width: UM.Theme.getSize("print_setup_widget").width - 2 * UM.Theme.getSize("default_margin").width height: childrenRect.height @@ -36,79 +36,6 @@ Item } onCurrentModeIndexChanged: UM.Preferences.setValue("cura/active_mode", currentModeIndex) - - // Header of the popup - Cura.RoundedRectangle - { - id: header - height: UM.Theme.getSize("print_setup_widget_header").height - color: UM.Theme.getColor("secondary") - cornerSide: Cura.RoundedRectangle.Direction.Up - radius: UM.Theme.getSize("default_radius").width - - anchors - { - top: parent.top - right: parent.right - left: parent.left - } - - Label - { - id: headerLabel - text: catalog.i18nc("@label", "Print settings") - font: UM.Theme.getFont("default") - renderType: Text.NativeRendering - verticalAlignment: Text.AlignVCenter - color: UM.Theme.getColor("text") - height: parent.height - - anchors - { - topMargin: UM.Theme.getSize("default_margin").height - left: parent.left - leftMargin: UM.Theme.getSize("default_margin").height - } - } - - Button - { - id: closeButton - width: UM.Theme.getSize("message_close").width - height: UM.Theme.getSize("message_close").height - hoverEnabled: true - - anchors - { - right: parent.right - rightMargin: UM.Theme.getSize("default_margin").width - verticalCenter: parent.verticalCenter - } - - contentItem: UM.RecolorImage - { - anchors.fill: parent - sourceSize.width: width - color: closeButton.hovered ? UM.Theme.getColor("small_button_text_hover") : UM.Theme.getColor("small_button_text") - source: UM.Theme.getIcon("cross1") - } - - background: Item {} - - onClicked: toggleContent() // Will hide the popup item - } - } - - Rectangle - { - id: topSeparator - - anchors.bottom: header.bottom - width: parent.width - height: UM.Theme.getSize("default_lining").height - color: UM.Theme.getColor("lining") - } - Item { id: contents @@ -118,7 +45,7 @@ Item anchors { - top: header.bottom + top: parent.top left: parent.left right: parent.right } diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml index d4287045b8..94da5bdd6f 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml @@ -10,6 +10,9 @@ import Cura 1.0 as Cura RowLayout { + property string enabledText: catalog.i18nc("@label:Should be short", "On") + property string disabledText: catalog.i18nc("@label:Should be short", "Off") + Cura.IconWithText { source: UM.Theme.getIcon("category_layer_height") diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 0ef6c24bfb..54b41fe348 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -362,13 +362,14 @@ "print_setup_mode_toggle": [0.0, 2.0], "print_setup_item": [0.0, 2.0], "print_setup_extruder_box": [0.0, 6.0], - "print_setup_widget_header": [0.0, 3.0], "print_setup_slider_groove": [0.16, 0.16], "print_setup_slider_handle": [1.0, 1.0], "print_setup_slider_tickmarks": [0.32, 0.32], "print_setup_big_item": [28, 2.5], "print_setup_icon": [1.2, 1.2], + "expandable_component_content_header": [0.0, 3.0], + "configuration_selector_mode_tabs": [0.0, 3.0], "action_panel_widget": [25.0, 0.0], From 154c6c1ff226a820e7737dc09952043701f42069 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 10 Dec 2018 13:42:33 +0100 Subject: [PATCH 0813/1292] Change the color of the setting control button to be the same as for the small buttons Contributes to CURA-5941. --- resources/themes/cura-light/theme.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 54b41fe348..5bad1cf7ae 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -205,9 +205,8 @@ "setting_control_border": [199, 199, 199, 255], "setting_control_border_highlight": [50, 130, 255, 255], "setting_control_text": [35, 35, 35, 255], - "setting_control_depth_line": [199, 199, 199, 255], - "setting_control_button": [199, 199, 199, 255], - "setting_control_button_hover": [70, 84, 113, 255], + "setting_control_button": [102, 102, 102, 255], + "setting_control_button_hover": [8, 7, 63, 255], "setting_control_disabled": [245, 245, 245, 255], "setting_control_disabled_text": [127, 127, 127, 255], "setting_control_disabled_border": [127, 127, 127, 255], From 90f822f6835471890a753dff0b5e4614d2d6e06b Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 10 Dec 2018 13:44:50 +0100 Subject: [PATCH 0814/1292] Add the component header that I miss in a previous commit Contributes to CURA-5941. --- resources/qml/ExpandableComponentHeader.qml | 68 +++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 resources/qml/ExpandableComponentHeader.qml diff --git a/resources/qml/ExpandableComponentHeader.qml b/resources/qml/ExpandableComponentHeader.qml new file mode 100644 index 0000000000..b1fd49cd1b --- /dev/null +++ b/resources/qml/ExpandableComponentHeader.qml @@ -0,0 +1,68 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.3 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +// Header of the popup +Cura.RoundedRectangle +{ + id: header + + property alias headerTitle: headerLabel.text + + height: UM.Theme.getSize("expandable_component_content_header").height + color: UM.Theme.getColor("secondary") + cornerSide: Cura.RoundedRectangle.Direction.Up + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("lining") + radius: UM.Theme.getSize("default_radius").width + + Label + { + id: headerLabel + text: "Title" + font: UM.Theme.getFont("default") + renderType: Text.NativeRendering + verticalAlignment: Text.AlignVCenter + color: UM.Theme.getColor("small_button_text") + height: parent.height + + anchors + { + topMargin: UM.Theme.getSize("default_margin").height + left: parent.left + leftMargin: UM.Theme.getSize("default_margin").height + } + } + + Button + { + id: closeButton + width: UM.Theme.getSize("message_close").width + height: UM.Theme.getSize("message_close").height + hoverEnabled: true + + anchors + { + right: parent.right + rightMargin: UM.Theme.getSize("default_margin").width + verticalCenter: parent.verticalCenter + } + + contentItem: UM.RecolorImage + { + anchors.fill: parent + sourceSize.width: width + color: closeButton.hovered ? UM.Theme.getColor("small_button_text_hover") : UM.Theme.getColor("small_button_text") + source: UM.Theme.getIcon("cross1") + } + + background: Item {} + + onClicked: toggleContent() // Will hide the popup item + } +} \ No newline at end of file From e5124532f83ffb062ec6fba9a88fd0b258ce0136 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Mon, 10 Dec 2018 14:03:43 +0100 Subject: [PATCH 0815/1292] getClusterStatusResponse as fixture --- .../Fixtures/getClusterStatusResponse.json | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/getClusterStatusResponse.json diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/getClusterStatusResponse.json b/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/getClusterStatusResponse.json new file mode 100644 index 0000000000..711e429a72 --- /dev/null +++ b/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/getClusterStatusResponse.json @@ -0,0 +1,97 @@ +{ + "data": [ + { + "generated_time": "2018-12-10T08:23:55.110Z", + "printers": [ + { + "configuration": [ + { + "extruder_index": 0, + "material": { + "material": "empty" + }, + "print_core_id": "AA 0.4" + }, + { + "extruder_index": 1, + "material": { + "material": "empty" + }, + "print_core_id": "AA 0.4" + } + ], + "enabled": true, + "firmware_version": "5.1.2.20180807", + "friendly_name": "Master-Luke", + "ip_address": "10.183.1.140", + "machine_variant": "Ultimaker 3", + "status": "maintenance", + "unique_name": "ultimakersystem-ccbdd30044ec", + "uuid": "b3a47ea3-1eeb-4323-9626-6f9c3c888f9e" + }, + { + "configuration": [ + { + "extruder_index": 0, + "material": { + "brand": "Generic", + "color": "Generic", + "guid": "506c9f0d-e3aa-4bd4-b2d2-23e2425b1aa9", + "material": "PLA" + }, + "print_core_id": "AA 0.4" + }, + { + "extruder_index": 1, + "material": { + "brand": "Ultimaker", + "color": "Red", + "guid": "9cfe5bf1-bdc5-4beb-871a-52c70777842d", + "material": "PLA" + }, + "print_core_id": "AA 0.4" + } + ], + "enabled": true, + "firmware_version": "4.3.3.20180529", + "friendly_name": "UM-Marijn", + "ip_address": "10.183.1.166", + "machine_variant": "Ultimaker 3", + "status": "idle", + "unique_name": "ultimakersystem-ccbdd30058ab", + "uuid": "6e62c40a-4601-4b0e-9fec-c7c02c59c30a" + } + ], + "print_jobs": [ + { + "assigned_to": "6e62c40a-4601-4b0e-9fec-c7c02c59c30a", + "configuration": [ + { + "extruder_index": 0, + "material": { + "brand": "Ultimaker", + "color": "Black", + "guid": "3ee70a86-77d8-4b87-8005-e4a1bc57d2ce", + "material": "PLA" + }, + "print_core_id": "AA 0.4" + } + ], + "constraints": {}, + "created_at": "2018-12-10T08:28:04.108Z", + "force": false, + "last_seen": 500165.109491861, + "machine_variant": "Ultimaker 3", + "name": "UM3_dragon", + "network_error_count": 0, + "owner": "Daniel Testing", + "started": false, + "status": "queued", + "time_elapsed": 0, + "time_total": 14145, + "uuid": "d1c8bd52-5e9f-486a-8c25-a123cc8c7702" + } + ] + } + ] +} From 3f97f83c473dd015353e7ca82003042cd2d11308 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 10 Dec 2018 14:17:56 +0100 Subject: [PATCH 0816/1292] Add a disabled state to the expandable components In this case, when the component is disabled, there is an optional message that will show. It works for instance when loading a gcode and the print setup panel has to be disabled. Contributes to CURA-5941. --- resources/qml/ExpandableComponent.qml | 70 +++++++++----- resources/qml/ExpandablePopup.qml | 96 ++++++++++++------- .../PrintSetupSelector/PrintSetupSelector.qml | 1 + 3 files changed, 110 insertions(+), 57 deletions(-) diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index 3c898caeb8..55271d99c3 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -37,6 +37,9 @@ Item property alias enabled: mouseArea.enabled + // Text to show when this component is disabled + property alias disabledText: disabledLabel.text + // Defines the alignment of the content with respect of the headerItem, by default to the right property int contentAlignment: ExpandableComponent.ContentAlignment.AlignRight @@ -85,7 +88,7 @@ Item { target: background property: "color" - value: expanded ? headerActiveColor : headerBackgroundColor + value: enabled ? (expanded ? headerActiveColor : headerBackgroundColor) : UM.Theme.getColor("disabled") } implicitHeight: 100 * screenScaleFactor @@ -96,36 +99,55 @@ Item id: background property real padding: UM.Theme.getSize("default_margin").width - color: expanded ? headerActiveColor : headerBackgroundColor + color: base.enabled ? (base.expanded ? headerActiveColor : headerBackgroundColor) : UM.Theme.getColor("disabled") anchors.fill: parent - Loader + Label { - id: headerItemLoader - anchors - { - left: parent.left - right: collapseButton.visible ? collapseButton.left : parent.right - top: parent.top - bottom: parent.bottom - margins: background.padding - } + id: disabledLabel + visible: !base.enabled + leftPadding: background.padding + text: "This component is disabled" + font: UM.Theme.getFont("default") + renderType: Text.NativeRendering + verticalAlignment: Text.AlignVCenter + color: UM.Theme.getColor("text") + height: parent.height } - UM.RecolorImage + Item { - id: collapseButton - anchors + anchors.fill: parent + visible: base.enabled + + Loader { - right: parent.right - verticalCenter: parent.verticalCenter - margins: background.padding + id: headerItemLoader + anchors + { + left: parent.left + right: collapseButton.visible ? collapseButton.left : parent.right + top: parent.top + bottom: parent.bottom + margins: background.padding + } + } + + UM.RecolorImage + { + id: collapseButton + anchors + { + right: parent.right + verticalCenter: parent.verticalCenter + margins: background.padding + } + source: UM.Theme.getIcon("pencil") + visible: source != "" + width: UM.Theme.getSize("standard_arrow").width + height: UM.Theme.getSize("standard_arrow").height + color: UM.Theme.getColor("small_button_text") } - source: UM.Theme.getIcon("pencil") - visible: source != "" && base.enabled - width: UM.Theme.getSize("standard_arrow").width - height: UM.Theme.getSize("standard_arrow").height - color: UM.Theme.getColor("small_button_text") } MouseArea @@ -135,7 +157,7 @@ Item onClicked: toggleContent() hoverEnabled: true onEntered: background.color = headerHoverColor - onExited: background.color = expanded ? headerActiveColor : headerBackgroundColor + onExited: background.color = base.enabled ? (base.expanded ? headerActiveColor : headerBackgroundColor) : UM.Theme.getColor("disabled") } } diff --git a/resources/qml/ExpandablePopup.qml b/resources/qml/ExpandablePopup.qml index 475f7f9f59..75f718abf5 100644 --- a/resources/qml/ExpandablePopup.qml +++ b/resources/qml/ExpandablePopup.qml @@ -37,6 +37,9 @@ Item property alias enabled: mouseArea.enabled + // Text to show when this component is disabled + property alias disabledText: disabledLabel.text + // Defines the alignment of the content with respect of the headerItem, by default to the right property int contentAlignment: ExpandablePopup.ContentAlignment.AlignRight @@ -86,6 +89,14 @@ Item } } + // Add this binding since the background color is not updated otherwise + Binding + { + target: background + property: "color" + value: enabled ? headerBackgroundColor : UM.Theme.getColor("disabled") + } + implicitHeight: 100 * screenScaleFactor implicitWidth: 400 * screenScaleFactor @@ -94,47 +105,66 @@ Item id: background property real padding: UM.Theme.getSize("default_margin").width - color: headerBackgroundColor + color: base.enabled ? headerBackgroundColor : UM.Theme.getColor("disabled") anchors.fill: parent - Loader + Label { - id: headerItemLoader - anchors - { - left: parent.left - right: collapseButton.visible ? collapseButton.left : parent.right - top: parent.top - bottom: parent.bottom - margins: background.padding - } + id: disabledLabel + visible: !base.enabled + leftPadding: background.padding + text: "This component is disabled" + font: UM.Theme.getFont("default") + renderType: Text.NativeRendering + verticalAlignment: Text.AlignVCenter + color: UM.Theme.getColor("text") + height: parent.height } - // A highlight that is shown when the content is expanded - Rectangle + Item { - id: expandedHighlight - width: parent.width - height: UM.Theme.getSize("thick_lining").height - color: UM.Theme.getColor("primary") - visible: expanded - anchors.bottom: parent.bottom - } + anchors.fill: parent + visible: base.enabled - UM.RecolorImage - { - id: collapseButton - anchors + Loader { - right: parent.right - verticalCenter: parent.verticalCenter - margins: background.padding + id: headerItemLoader + anchors + { + left: parent.left + right: collapseButton.visible ? collapseButton.left : parent.right + top: parent.top + bottom: parent.bottom + margins: background.padding + } + } + + // A highlight that is shown when the content is expanded + Rectangle + { + id: expandedHighlight + width: parent.width + height: UM.Theme.getSize("thick_lining").height + color: UM.Theme.getColor("primary") + visible: expanded + anchors.bottom: parent.bottom + } + + UM.RecolorImage + { + id: collapseButton + anchors + { + right: parent.right + verticalCenter: parent.verticalCenter + margins: background.padding + } + source: expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") + visible: source != "" + width: UM.Theme.getSize("standard_arrow").width + height: UM.Theme.getSize("standard_arrow").height + color: UM.Theme.getColor("small_button_text") } - source: expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") - visible: source != "" && base.enabled - width: UM.Theme.getSize("standard_arrow").width - height: UM.Theme.getSize("standard_arrow").height - color: UM.Theme.getColor("small_button_text") } MouseArea @@ -144,7 +174,7 @@ Item onClicked: toggleContent() hoverEnabled: true onEntered: background.color = headerHoverColor - onExited: background.color = headerBackgroundColor + onExited: background.color = base.enabled ? headerBackgroundColor : UM.Theme.getColor("disabled") } } diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector/PrintSetupSelector.qml index 01886a5ea5..fe642bd3c1 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelector.qml @@ -16,6 +16,7 @@ Cura.ExpandableComponent contentPadding: UM.Theme.getSize("default_lining").width contentHeaderTitle: catalog.i18nc("@label", "Print settings") enabled: !preSlicedData + disabledText: catalog.i18nc("@label shown when we load a Gcode file", "Print setup disabled. G code file can not be modified." UM.I18nCatalog { From c62cb84c75c158a21ea703fd853fb5f68f3d2789 Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Mon, 10 Dec 2018 14:18:10 +0100 Subject: [PATCH 0817/1292] Added CuraDirve plugin to Cura build CURA-6005 --- .gitignore | 1 - plugins/CuraDrive/__init__.py | 14 ++ plugins/CuraDrive/plugin.json | 8 + plugins/CuraDrive/src/DriveApiService.py | 185 ++++++++++++++++ plugins/CuraDrive/src/DrivePluginExtension.py | 200 ++++++++++++++++++ plugins/CuraDrive/src/Settings.py | 36 ++++ plugins/CuraDrive/src/UploadBackupJob.py | 39 ++++ plugins/CuraDrive/src/__init__.py | 0 .../CuraDrive/src/models/BackupListModel.py | 38 ++++ plugins/CuraDrive/src/models/__init__.py | 0 .../src/qml/components/ActionButton.qml | 67 ++++++ .../src/qml/components/ActionCheckBox.qml | 49 +++++ .../src/qml/components/ActionToolTip.qml | 29 +++ .../src/qml/components/BackupList.qml | 31 +++ .../src/qml/components/BackupListFooter.qml | 42 ++++ .../src/qml/components/BackupListItem.qml | 112 ++++++++++ .../qml/components/BackupListItemDetails.qml | 61 ++++++ .../components/BackupListItemDetailsRow.qml | 52 +++++ .../CuraDrive/src/qml/components/Divider.qml | 11 + plugins/CuraDrive/src/qml/components/Icon.qml | 56 +++++ .../src/qml/components/RightSideScrollBar.qml | 13 ++ .../src/qml/images/avatar_default.png | Bin 0 -> 3115 bytes .../CuraDrive/src/qml/images/background.svg | 12 ++ plugins/CuraDrive/src/qml/images/backup.svg | 3 + plugins/CuraDrive/src/qml/images/cura.svg | 7 + .../CuraDrive/src/qml/images/cura_logo.jpg | Bin 0 -> 19308 bytes .../CuraDrive/src/qml/images/cura_logo.png | Bin 0 -> 13258 bytes plugins/CuraDrive/src/qml/images/delete.svg | 7 + plugins/CuraDrive/src/qml/images/folder.svg | 7 + plugins/CuraDrive/src/qml/images/home.svg | 3 + plugins/CuraDrive/src/qml/images/icon.png | Bin 0 -> 21924 bytes plugins/CuraDrive/src/qml/images/info.svg | 4 + .../src/qml/images/inverted_circle.png | Bin 0 -> 1608 bytes plugins/CuraDrive/src/qml/images/loading.gif | Bin 0 -> 6762 bytes plugins/CuraDrive/src/qml/images/material.svg | 7 + plugins/CuraDrive/src/qml/images/plugin.svg | 7 + .../src/qml/images/preview_banner.png | Bin 0 -> 8324 bytes plugins/CuraDrive/src/qml/images/printer.svg | 14 ++ plugins/CuraDrive/src/qml/images/profile.svg | 3 + plugins/CuraDrive/src/qml/images/restore.svg | 7 + plugins/CuraDrive/src/qml/main.qml | 42 ++++ .../CuraDrive/src/qml/pages/BackupsPage.qml | 73 +++++++ .../CuraDrive/src/qml/pages/WelcomePage.qml | 48 +++++ 43 files changed, 1287 insertions(+), 1 deletion(-) create mode 100644 plugins/CuraDrive/__init__.py create mode 100644 plugins/CuraDrive/plugin.json create mode 100644 plugins/CuraDrive/src/DriveApiService.py create mode 100644 plugins/CuraDrive/src/DrivePluginExtension.py create mode 100644 plugins/CuraDrive/src/Settings.py create mode 100644 plugins/CuraDrive/src/UploadBackupJob.py create mode 100644 plugins/CuraDrive/src/__init__.py create mode 100644 plugins/CuraDrive/src/models/BackupListModel.py create mode 100644 plugins/CuraDrive/src/models/__init__.py create mode 100644 plugins/CuraDrive/src/qml/components/ActionButton.qml create mode 100644 plugins/CuraDrive/src/qml/components/ActionCheckBox.qml create mode 100644 plugins/CuraDrive/src/qml/components/ActionToolTip.qml create mode 100644 plugins/CuraDrive/src/qml/components/BackupList.qml create mode 100644 plugins/CuraDrive/src/qml/components/BackupListFooter.qml create mode 100644 plugins/CuraDrive/src/qml/components/BackupListItem.qml create mode 100644 plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml create mode 100644 plugins/CuraDrive/src/qml/components/BackupListItemDetailsRow.qml create mode 100644 plugins/CuraDrive/src/qml/components/Divider.qml create mode 100644 plugins/CuraDrive/src/qml/components/Icon.qml create mode 100644 plugins/CuraDrive/src/qml/components/RightSideScrollBar.qml create mode 100644 plugins/CuraDrive/src/qml/images/avatar_default.png create mode 100644 plugins/CuraDrive/src/qml/images/background.svg create mode 100644 plugins/CuraDrive/src/qml/images/backup.svg create mode 100644 plugins/CuraDrive/src/qml/images/cura.svg create mode 100644 plugins/CuraDrive/src/qml/images/cura_logo.jpg create mode 100644 plugins/CuraDrive/src/qml/images/cura_logo.png create mode 100644 plugins/CuraDrive/src/qml/images/delete.svg create mode 100644 plugins/CuraDrive/src/qml/images/folder.svg create mode 100644 plugins/CuraDrive/src/qml/images/home.svg create mode 100644 plugins/CuraDrive/src/qml/images/icon.png create mode 100644 plugins/CuraDrive/src/qml/images/info.svg create mode 100644 plugins/CuraDrive/src/qml/images/inverted_circle.png create mode 100644 plugins/CuraDrive/src/qml/images/loading.gif create mode 100644 plugins/CuraDrive/src/qml/images/material.svg create mode 100644 plugins/CuraDrive/src/qml/images/plugin.svg create mode 100644 plugins/CuraDrive/src/qml/images/preview_banner.png create mode 100644 plugins/CuraDrive/src/qml/images/printer.svg create mode 100644 plugins/CuraDrive/src/qml/images/profile.svg create mode 100644 plugins/CuraDrive/src/qml/images/restore.svg create mode 100644 plugins/CuraDrive/src/qml/main.qml create mode 100644 plugins/CuraDrive/src/qml/pages/BackupsPage.qml create mode 100644 plugins/CuraDrive/src/qml/pages/WelcomePage.qml diff --git a/.gitignore b/.gitignore index 0a66b6eb33..60b59e6829 100644 --- a/.gitignore +++ b/.gitignore @@ -42,7 +42,6 @@ plugins/cura-siemensnx-plugin plugins/CuraBlenderPlugin plugins/CuraCloudPlugin plugins/CuraDrivePlugin -plugins/CuraDrive plugins/CuraLiveScriptingPlugin plugins/CuraOpenSCADPlugin plugins/CuraPrintProfileCreator diff --git a/plugins/CuraDrive/__init__.py b/plugins/CuraDrive/__init__.py new file mode 100644 index 0000000000..6612a5d614 --- /dev/null +++ b/plugins/CuraDrive/__init__.py @@ -0,0 +1,14 @@ +# Copyright (c) 2017 Ultimaker B.V. +import os + +is_testing = os.getenv('ENV_NAME', "development") == "testing" + +# Only load the whole plugin when not running tests as __init__.py is automatically loaded by PyTest +if not is_testing: + from .src.DrivePluginExtension import DrivePluginExtension + + def getMetaData(): + return {} + + def register(app): + return {"extension": DrivePluginExtension(app)} diff --git a/plugins/CuraDrive/plugin.json b/plugins/CuraDrive/plugin.json new file mode 100644 index 0000000000..134cd31a77 --- /dev/null +++ b/plugins/CuraDrive/plugin.json @@ -0,0 +1,8 @@ +{ + "name": "Cura Backups", + "author": "Ultimaker B.V.", + "description": "Backup and restore your configuration.", + "version": "1.2.1", + "api": 5, + "i18n-catalog": "cura_drive" +} \ No newline at end of file diff --git a/plugins/CuraDrive/src/DriveApiService.py b/plugins/CuraDrive/src/DriveApiService.py new file mode 100644 index 0000000000..a677466838 --- /dev/null +++ b/plugins/CuraDrive/src/DriveApiService.py @@ -0,0 +1,185 @@ +# Copyright (c) 2017 Ultimaker B.V. +import base64 +import hashlib +from datetime import datetime +from tempfile import NamedTemporaryFile +from typing import Optional, List, Dict + +import requests + +from UM.Logger import Logger +from UM.Message import Message +from UM.Signal import Signal + +from .UploadBackupJob import UploadBackupJob +from .Settings import Settings + + +class DriveApiService: + """ + The DriveApiService is responsible for interacting with the CuraDrive API and Cura's backup handling. + """ + + GET_BACKUPS_URL = "{}/backups".format(Settings.DRIVE_API_URL) + PUT_BACKUP_URL = "{}/backups".format(Settings.DRIVE_API_URL) + DELETE_BACKUP_URL = "{}/backups".format(Settings.DRIVE_API_URL) + + # Emit signal when restoring backup started or finished. + onRestoringStateChanged = Signal() + + # Emit signal when creating backup started or finished. + onCreatingStateChanged = Signal() + + def __init__(self, cura_api) -> None: + """Create a new instance of the Drive API service and set the cura_api object.""" + self._cura_api = cura_api + + def getBackups(self) -> List[Dict[str, any]]: + """Get all backups from the API.""" + access_token = self._cura_api.account.accessToken + if not access_token: + Logger.log("w", "Could not get access token.") + return [] + + backup_list_request = requests.get(self.GET_BACKUPS_URL, headers={ + "Authorization": "Bearer {}".format(access_token) + }) + if backup_list_request.status_code > 299: + Logger.log("w", "Could not get backups list from remote: %s", backup_list_request.text) + Message(Settings.translatable_messages["get_backups_error"], title = Settings.MESSAGE_TITLE, + lifetime = 10).show() + return [] + return backup_list_request.json()["data"] + + def createBackup(self) -> None: + """Create a backup and upload it to CuraDrive cloud storage.""" + self.onCreatingStateChanged.emit(is_creating=True) + + # Create the backup. + backup_zip_file, backup_meta_data = self._cura_api.backups.createBackup() + if not backup_zip_file or not backup_meta_data: + self.onCreatingStateChanged.emit(is_creating=False, error_message="Could not create backup.") + return + + # Create an upload entry for the backup. + timestamp = datetime.now().isoformat() + backup_meta_data["description"] = "{}.backup.{}.cura.zip".format(timestamp, backup_meta_data["cura_release"]) + backup_upload_url = self._requestBackupUpload(backup_meta_data, len(backup_zip_file)) + if not backup_upload_url: + self.onCreatingStateChanged.emit(is_creating=False, error_message="Could not upload backup.") + return + + # Upload the backup to storage. + upload_backup_job = UploadBackupJob(backup_upload_url, backup_zip_file) + upload_backup_job.finished.connect(self._onUploadFinished) + upload_backup_job.start() + + def _onUploadFinished(self, job: "UploadBackupJob") -> None: + """ + Callback handler for the upload job. + :param job: The executed job. + """ + if job.backup_upload_error_message != "": + # If the job contains an error message we pass it along so the UI can display it. + self.onCreatingStateChanged.emit(is_creating=False, error_message=job.backup_upload_error_message) + else: + self.onCreatingStateChanged.emit(is_creating=False) + + def restoreBackup(self, backup: Dict[str, any]) -> None: + """ + Restore a previously exported backup from cloud storage. + :param backup: A dict containing an entry from the API list response. + """ + self.onRestoringStateChanged.emit(is_restoring=True) + download_url = backup.get("download_url") + if not download_url: + # If there is no download URL, we can't restore the backup. + return self._emitRestoreError() + + download_package = requests.get(download_url, stream=True) + if download_package.status_code != 200: + # Something went wrong when attempting to download the backup. + Logger.log("w", "Could not download backup from url %s: %s", download_url, download_package.text) + return self._emitRestoreError() + + # We store the file in a temporary path fist to ensure integrity. + temporary_backup_file = NamedTemporaryFile(delete=False) + with open(temporary_backup_file.name, "wb") as write_backup: + for chunk in download_package: + write_backup.write(chunk) + + if not self._verifyMd5Hash(temporary_backup_file.name, backup.get("md5_hash")): + # Don't restore the backup if the MD5 hashes do not match. + # This can happen if the download was interrupted. + Logger.log("w", "Remote and local MD5 hashes do not match, not restoring backup.") + return self._emitRestoreError() + + # Tell Cura to place the backup back in the user data folder. + with open(temporary_backup_file.name, "rb") as read_backup: + self._cura_api.backups.restoreBackup(read_backup.read(), backup.get("data")) + self.onRestoringStateChanged.emit(is_restoring=False) + + def _emitRestoreError(self, error_message: str = Settings.translatable_messages["backup_restore_error_message"]): + """Helper method for emitting a signal when restoring failed.""" + self.onRestoringStateChanged.emit( + is_restoring=False, + error_message=error_message + ) + + @staticmethod + def _verifyMd5Hash(file_path: str, known_hash: str) -> bool: + """ + Verify the MD5 hash of a file. + :param file_path: Full path to the file. + :param known_hash: The known MD5 hash of the file. + :return: Success or not. + """ + with open(file_path, "rb") as read_backup: + local_md5_hash = base64.b64encode(hashlib.md5(read_backup.read()).digest(), altchars=b"_-").decode("utf-8") + return known_hash == local_md5_hash + + def deleteBackup(self, backup_id: str) -> bool: + """ + Delete a backup from the server by ID. + :param backup_id: The ID of the backup to delete. + :return: Success bool. + """ + access_token = self._cura_api.account.accessToken + if not access_token: + Logger.log("w", "Could not get access token.") + return False + + delete_backup = requests.delete("{}/{}".format(self.DELETE_BACKUP_URL, backup_id), headers = { + "Authorization": "Bearer {}".format(access_token) + }) + if delete_backup.status_code > 299: + Logger.log("w", "Could not delete backup: %s", delete_backup.text) + return False + return True + + def _requestBackupUpload(self, backup_metadata: Dict[str, any], backup_size: int) -> Optional[str]: + """ + Request a backup upload slot from the API. + :param backup_metadata: A dict containing some meta data about the backup. + :param backup_size: The size of the backup file in bytes. + :return: The upload URL for the actual backup file if successful, otherwise None. + """ + access_token = self._cura_api.account.accessToken + if not access_token: + Logger.log("w", "Could not get access token.") + return None + + backup_upload_request = requests.put(self.PUT_BACKUP_URL, json={ + "data": { + "backup_size": backup_size, + "metadata": backup_metadata + } + }, headers={ + "Authorization": "Bearer {}".format(access_token) + }) + + if backup_upload_request.status_code > 299: + Logger.log("w", "Could not request backup upload: %s", backup_upload_request.text) + return None + + return backup_upload_request.json()["data"]["upload_url"] diff --git a/plugins/CuraDrive/src/DrivePluginExtension.py b/plugins/CuraDrive/src/DrivePluginExtension.py new file mode 100644 index 0000000000..556fb187df --- /dev/null +++ b/plugins/CuraDrive/src/DrivePluginExtension.py @@ -0,0 +1,200 @@ +# Copyright (c) 2017 Ultimaker B.V. +import os +from datetime import datetime +from typing import Optional + +from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal + +from UM.Extension import Extension +from UM.Message import Message + +from .Settings import Settings +from .DriveApiService import DriveApiService +from .models.BackupListModel import BackupListModel + + +class DrivePluginExtension(QObject, Extension): + """ + The DivePluginExtension provides functionality to backup and restore your Cura configuration to Ultimaker's cloud. + """ + + # Signal emitted when the list of backups changed. + backupsChanged = pyqtSignal() + + # Signal emitted when restoring has started. Needed to prevent parallel restoring. + restoringStateChanged = pyqtSignal() + + # Signal emitted when creating has started. Needed to prevent parallel creation of backups. + creatingStateChanged = pyqtSignal() + + # Signal emitted when preferences changed (like auto-backup). + preferencesChanged = pyqtSignal() + + DATE_FORMAT = "%d/%m/%Y %H:%M:%S" + + def __init__(self, application): + super(DrivePluginExtension, self).__init__() + + # Re-usable instance of application. + self._application = application + + # Local data caching for the UI. + self._drive_window = None # type: Optional[QObject] + self._backups_list_model = BackupListModel() + self._is_restoring_backup = False + self._is_creating_backup = False + + # Initialize services. + self._preferences = self._application.getPreferences() + self._cura_api = self._application.getCuraAPI() + self._drive_api_service = DriveApiService(self._cura_api) + + # Attach signals. + self._cura_api.account.loginStateChanged.connect(self._onLoginStateChanged) + self._drive_api_service.onRestoringStateChanged.connect(self._onRestoringStateChanged) + self._drive_api_service.onCreatingStateChanged.connect(self._onCreatingStateChanged) + + # Register preferences. + self._preferences.addPreference(Settings.AUTO_BACKUP_ENABLED_PREFERENCE_KEY, False) + self._preferences.addPreference(Settings.AUTO_BACKUP_LAST_DATE_PREFERENCE_KEY, datetime.now() + .strftime(self.DATE_FORMAT)) + + # Register menu items. + self._updateMenuItems() + + # Make auto-backup on boot if required. + self._application.engineCreatedSignal.connect(self._autoBackup) + + def showDriveWindow(self) -> None: + """Show the Drive UI popup window.""" + if not self._drive_window: + self._drive_window = self.createDriveWindow() + self.refreshBackups() + self._drive_window.show() + + def createDriveWindow(self) -> Optional["QObject"]: + """ + Create an instance of the Drive UI popup window. + :return: The popup window object. + """ + path = os.path.join(os.path.dirname(__file__), "qml", "main.qml") + return self._application.createQmlComponent(path, {"CuraDrive": self}) + + def _updateMenuItems(self) -> None: + """Update the menu items.""" + self.addMenuItem(Settings.translatable_messages["extension_menu_entry"], self.showDriveWindow) + + def _autoBackup(self) -> None: + """Automatically make a backup on boot if enabled.""" + if self._preferences.getValue(Settings.AUTO_BACKUP_ENABLED_PREFERENCE_KEY) and self._lastBackupTooLongAgo(): + self.createBackup() + + def _lastBackupTooLongAgo(self) -> bool: + """Check if the last backup was longer than 1 day ago.""" + current_date = datetime.now() + last_backup_date = self._getLastBackupDate() + date_diff = current_date - last_backup_date + return date_diff.days > 1 + + def _getLastBackupDate(self) -> "datetime": + """Get the last backup date as datetime object.""" + last_backup_date = self._preferences.getValue(Settings.AUTO_BACKUP_LAST_DATE_PREFERENCE_KEY) + return datetime.strptime(last_backup_date, self.DATE_FORMAT) + + def _storeBackupDate(self) -> None: + """Store the current date as last backup date.""" + backup_date = datetime.now().strftime(self.DATE_FORMAT) + self._preferences.setValue(Settings.AUTO_BACKUP_LAST_DATE_PREFERENCE_KEY, backup_date) + + def _onLoginStateChanged(self, logged_in: bool = False) -> None: + """Callback handler for changes in the login state.""" + if logged_in: + self.refreshBackups() + + def _onRestoringStateChanged(self, is_restoring: bool = False, error_message: str = None) -> None: + """Callback handler for changes in the restoring state.""" + self._is_restoring_backup = is_restoring + self.restoringStateChanged.emit() + if error_message: + Message(error_message, title = Settings.MESSAGE_TITLE, lifetime = 5).show() + + def _onCreatingStateChanged(self, is_creating: bool = False, error_message: str = None) -> None: + """Callback handler for changes in the creation state.""" + self._is_creating_backup = is_creating + self.creatingStateChanged.emit() + if error_message: + Message(error_message, title = Settings.MESSAGE_TITLE, lifetime = 5).show() + else: + self._storeBackupDate() + if not is_creating: + # We've finished creating a new backup, to the list has to be updated. + self.refreshBackups() + + @pyqtSlot(bool, name = "toggleAutoBackup") + def toggleAutoBackup(self, enabled: bool) -> None: + """Enable or disable the auto-backup feature.""" + self._preferences.setValue(Settings.AUTO_BACKUP_ENABLED_PREFERENCE_KEY, enabled) + self.preferencesChanged.emit() + + @pyqtProperty(bool, notify = preferencesChanged) + def autoBackupEnabled(self) -> bool: + """Check if auto-backup is enabled or not.""" + return bool(self._preferences.getValue(Settings.AUTO_BACKUP_ENABLED_PREFERENCE_KEY)) + + @pyqtProperty(QObject, notify = backupsChanged) + def backups(self) -> BackupListModel: + """ + Get a list of the backups. + :return: The backups as Qt List Model. + """ + return self._backups_list_model + + @pyqtSlot(name = "refreshBackups") + def refreshBackups(self) -> None: + """ + Forcefully refresh the backups list. + """ + self._backups_list_model.loadBackups(self._drive_api_service.getBackups()) + self.backupsChanged.emit() + + @pyqtProperty(bool, notify = restoringStateChanged) + def isRestoringBackup(self) -> bool: + """ + Get the current restoring state. + :return: Boolean if we are restoring or not. + """ + return self._is_restoring_backup + + @pyqtProperty(bool, notify = creatingStateChanged) + def isCreatingBackup(self) -> bool: + """ + Get the current creating state. + :return: Boolean if we are creating or not. + """ + return self._is_creating_backup + + @pyqtSlot(str, name = "restoreBackup") + def restoreBackup(self, backup_id: str) -> None: + """ + Download and restore a backup by ID. + :param backup_id: The ID of the backup. + """ + index = self._backups_list_model.find("backup_id", backup_id) + backup = self._backups_list_model.getItem(index) + self._drive_api_service.restoreBackup(backup) + + @pyqtSlot(name = "createBackup") + def createBackup(self) -> None: + """ + Create a new backup. + """ + self._drive_api_service.createBackup() + + @pyqtSlot(str, name = "deleteBackup") + def deleteBackup(self, backup_id: str) -> None: + """ + Delete a backup by ID. + :param backup_id: The ID of the backup. + """ + self._drive_api_service.deleteBackup(backup_id) + self.refreshBackups() diff --git a/plugins/CuraDrive/src/Settings.py b/plugins/CuraDrive/src/Settings.py new file mode 100644 index 0000000000..277a976cc7 --- /dev/null +++ b/plugins/CuraDrive/src/Settings.py @@ -0,0 +1,36 @@ +# Copyright (c) 2018 Ultimaker B.V. +from UM import i18nCatalog + + +class Settings: + """ + Keeps the application settings. + """ + UM_CLOUD_API_ROOT = "https://api.ultimaker.com" + DRIVE_API_VERSION = 1 + DRIVE_API_URL = "{}/cura-drive/v{}".format(UM_CLOUD_API_ROOT, str(DRIVE_API_VERSION)) + + AUTO_BACKUP_ENABLED_PREFERENCE_KEY = "cura_drive/auto_backup_enabled" + AUTO_BACKUP_LAST_DATE_PREFERENCE_KEY = "cura_drive/auto_backup_date" + + I18N_CATALOG_ID = "cura_drive" + I18N_CATALOG = i18nCatalog(I18N_CATALOG_ID) + + MESSAGE_TITLE = I18N_CATALOG.i18nc("@info:title", "Backups"), + + # Translatable messages for the entire plugin. + translatable_messages = { + + # Menu items. + "extension_menu_entry": I18N_CATALOG.i18nc("@item:inmenu", "Manage backups"), + + # Notification messages. + "backup_failed": I18N_CATALOG.i18nc("@info:backup_status", "There was an error while creating your backup."), + "uploading_backup": I18N_CATALOG.i18nc("@info:backup_status", "Uploading your backup..."), + "uploading_backup_success": I18N_CATALOG.i18nc("@info:backup_status", "Your backup has finished uploading."), + "uploading_backup_error": I18N_CATALOG.i18nc("@info:backup_status", + "There was an error while uploading your backup."), + "get_backups_error": I18N_CATALOG.i18nc("@info:backup_status", "There was an error listing your backups."), + "backup_restore_error_message": I18N_CATALOG.i18nc("@info:backup_status", + "There was an error trying to restore your backup.") + } diff --git a/plugins/CuraDrive/src/UploadBackupJob.py b/plugins/CuraDrive/src/UploadBackupJob.py new file mode 100644 index 0000000000..039e6d1a09 --- /dev/null +++ b/plugins/CuraDrive/src/UploadBackupJob.py @@ -0,0 +1,39 @@ +# Copyright (c) 2018 Ultimaker B.V. +import requests + +from UM.Job import Job +from UM.Logger import Logger +from UM.Message import Message + +from .Settings import Settings + + +class UploadBackupJob(Job): + """ + This job is responsible for uploading the backup file to cloud storage. + As it can take longer than some other tasks, we schedule this using a Cura Job. + """ + + def __init__(self, signed_upload_url: str, backup_zip: bytes): + super().__init__() + self._signed_upload_url = signed_upload_url + self._backup_zip = backup_zip + self._upload_success = False + self.backup_upload_error_message = "" + + def run(self): + Message(Settings.translatable_messages["uploading_backup"], title = Settings.MESSAGE_TITLE, + lifetime = 10).show() + + backup_upload = requests.put(self._signed_upload_url, data = self._backup_zip) + if backup_upload.status_code not in (200, 201): + self.backup_upload_error_message = backup_upload.text + Logger.log("w", "Could not upload backup file: %s", backup_upload.text) + Message(Settings.translatable_messages["uploading_backup_error"], title = Settings.MESSAGE_TITLE, + lifetime = 10).show() + else: + self._upload_success = True + Message(Settings.translatable_messages["uploading_backup_success"], title = Settings.MESSAGE_TITLE, + lifetime = 10).show() + + self.finished.emit(self) diff --git a/plugins/CuraDrive/src/__init__.py b/plugins/CuraDrive/src/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/plugins/CuraDrive/src/models/BackupListModel.py b/plugins/CuraDrive/src/models/BackupListModel.py new file mode 100644 index 0000000000..9567b3d255 --- /dev/null +++ b/plugins/CuraDrive/src/models/BackupListModel.py @@ -0,0 +1,38 @@ +# Copyright (c) 2018 Ultimaker B.V. +from typing import List, Dict + +from UM.Qt.ListModel import ListModel + +from PyQt5.QtCore import Qt + + +class BackupListModel(ListModel): + """ + The BackupListModel transforms the backups data that came from the server so it can be served to the Qt UI. + """ + + def __init__(self, parent=None): + super().__init__(parent) + self.addRoleName(Qt.UserRole + 1, "backup_id") + self.addRoleName(Qt.UserRole + 2, "download_url") + self.addRoleName(Qt.UserRole + 3, "generated_time") + self.addRoleName(Qt.UserRole + 4, "md5_hash") + self.addRoleName(Qt.UserRole + 5, "data") + + def loadBackups(self, data: List[Dict[str, any]]) -> None: + """ + Populate the model with server data. + :param data: + """ + items = [] + for backup in data: + # We do this loop because we only want to append these specific fields. + # Without this, ListModel will break. + items.append({ + "backup_id": backup["backup_id"], + "download_url": backup["download_url"], + "generated_time": backup["generated_time"], + "md5_hash": backup["md5_hash"], + "data": backup["metadata"] + }) + self.setItems(items) diff --git a/plugins/CuraDrive/src/models/__init__.py b/plugins/CuraDrive/src/models/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/plugins/CuraDrive/src/qml/components/ActionButton.qml b/plugins/CuraDrive/src/qml/components/ActionButton.qml new file mode 100644 index 0000000000..843079ed88 --- /dev/null +++ b/plugins/CuraDrive/src/qml/components/ActionButton.qml @@ -0,0 +1,67 @@ +// Copyright (c) 2018 Ultimaker B.V. +import QtQuick 2.7 +import QtQuick.Controls 2.1 +import QtQuick.Layouts 1.3 + +import UM 1.1 as UM + +Button +{ + id: button + property alias cursorShape: mouseArea.cursorShape + property var iconSource: "" + property var busy: false + property var color: UM.Theme.getColor("primary") + property var hoverColor: UM.Theme.getColor("primary_hover") + property var disabledColor: color + property var textColor: UM.Theme.getColor("button_text") + property var textHoverColor: UM.Theme.getColor("button_text_hover") + property var textDisabledColor: textColor + property var textFont: UM.Theme.getFont("action_button") + + contentItem: RowLayout + { + Icon + { + id: buttonIcon + iconSource: button.iconSource + width: 16 * screenScaleFactor + color: button.hovered ? button.textHoverColor : button.textColor + visible: button.iconSource != "" && !loader.visible + } + + Icon + { + id: loader + iconSource: "../images/loading.gif" + width: 16 * screenScaleFactor + color: button.hovered ? button.textHoverColor : button.textColor + visible: button.busy + animated: true + } + + Label + { + id: buttonText + text: button.text + color: button.enabled ? (button.hovered ? button.textHoverColor : button.textColor): button.textDisabledColor + font: button.textFont + visible: button.text != "" + renderType: Text.NativeRendering + } + } + + background: Rectangle + { + color: button.enabled ? (button.hovered ? button.hoverColor : button.color) : button.disabledColor + } + + MouseArea + { + id: mouseArea + anchors.fill: parent + onPressed: mouse.accepted = false + hoverEnabled: true + cursorShape: button.enabled ? (hovered ? Qt.PointingHandCursor : Qt.ArrowCursor) : Qt.ForbiddenCursor + } +} diff --git a/plugins/CuraDrive/src/qml/components/ActionCheckBox.qml b/plugins/CuraDrive/src/qml/components/ActionCheckBox.qml new file mode 100644 index 0000000000..71f5e6035d --- /dev/null +++ b/plugins/CuraDrive/src/qml/components/ActionCheckBox.qml @@ -0,0 +1,49 @@ +// Copyright (c) 2018 Ultimaker B.V. +import QtQuick 2.7 +import QtQuick.Controls 2.1 +import QtQuick.Layouts 1.3 + +import UM 1.3 as UM + +CheckBox +{ + id: checkbox + hoverEnabled: true + + property var label: "" + + indicator: Rectangle { + implicitWidth: 30 * screenScaleFactor + implicitHeight: 30 * screenScaleFactor + x: 0 + y: Math.round(parent.height / 2 - height / 2) + color: UM.Theme.getColor("sidebar") + border.color: UM.Theme.getColor("text") + + Rectangle { + width: 14 * screenScaleFactor + height: 14 * screenScaleFactor + x: 8 * screenScaleFactor + y: 8 * screenScaleFactor + color: UM.Theme.getColor("primary") + visible: checkbox.checked + } + } + + contentItem: Label { + anchors + { + left: checkbox.indicator.right + leftMargin: 5 * screenScaleFactor + } + text: catalog.i18nc("@checkbox:description", "Auto Backup") + color: UM.Theme.getColor("text") + renderType: Text.NativeRendering + verticalAlignment: Text.AlignVCenter + } + + ActionToolTip + { + text: checkbox.label + } +} diff --git a/plugins/CuraDrive/src/qml/components/ActionToolTip.qml b/plugins/CuraDrive/src/qml/components/ActionToolTip.qml new file mode 100644 index 0000000000..93b92bc2df --- /dev/null +++ b/plugins/CuraDrive/src/qml/components/ActionToolTip.qml @@ -0,0 +1,29 @@ +// Copyright (c) 2018 Ultimaker B.V. +import QtQuick 2.7 +import QtQuick.Controls 2.1 +import QtQuick.Layouts 1.3 + +import UM 1.1 as UM + +ToolTip +{ + id: tooltip + visible: parent.hovered + opacity: 0.9 + delay: 500 + + background: Rectangle + { + color: UM.Theme.getColor("sidebar") + border.color: UM.Theme.getColor("primary") + border.width: 1 * screenScaleFactor + } + + contentItem: Label + { + text: tooltip.text + color: UM.Theme.getColor("text") + font: UM.Theme.getFont("very_small") + renderType: Text.NativeRendering + } +} diff --git a/plugins/CuraDrive/src/qml/components/BackupList.qml b/plugins/CuraDrive/src/qml/components/BackupList.qml new file mode 100644 index 0000000000..231f25afc8 --- /dev/null +++ b/plugins/CuraDrive/src/qml/components/BackupList.qml @@ -0,0 +1,31 @@ +// Copyright (c) 2018 Ultimaker B.V. +import QtQuick 2.7 +import QtQuick.Controls 2.1 +import QtQuick.Layouts 1.3 + +import UM 1.1 as UM + +ListView +{ + id: backupList + width: parent.width + clip: true + delegate: Item + { + width: parent.width + height: childrenRect.height + + BackupListItem + { + id: backupListItem + width: parent.width + } + + Divider + { + width: parent.width + anchors.top: backupListItem.bottom + } + } + ScrollBar.vertical: RightSideScrollBar {} +} diff --git a/plugins/CuraDrive/src/qml/components/BackupListFooter.qml b/plugins/CuraDrive/src/qml/components/BackupListFooter.qml new file mode 100644 index 0000000000..80f47d6cba --- /dev/null +++ b/plugins/CuraDrive/src/qml/components/BackupListFooter.qml @@ -0,0 +1,42 @@ +// Copyright (c) 2018 Ultimaker B.V. +import QtQuick 2.7 +import QtQuick.Controls 2.1 +import QtQuick.Layouts 1.3 + +import UM 1.3 as UM + +import "../components" + +RowLayout +{ + id: backupListFooter + width: parent.width + property bool showInfoButton: false + + ActionButton + { + id: infoButton + text: catalog.i18nc("@button", "Want more?") + iconSource: "../images/info.svg" + onClicked: Qt.openUrlExternally("https://goo.gl/forms/QACEP8pP3RV60QYG2") + visible: backupListFooter.showInfoButton + } + + ActionButton + { + id: createBackupButton + text: catalog.i18nc("@button", "Backup Now") + iconSource: "../images/backup.svg" + enabled: !CuraDrive.isCreatingBackup && !CuraDrive.isRestoringBackup + onClicked: CuraDrive.createBackup() + busy: CuraDrive.isCreatingBackup + } + + ActionCheckBox + { + id: autoBackupEnabled + checked: CuraDrive.autoBackupEnabled + onClicked: CuraDrive.toggleAutoBackup(autoBackupEnabled.checked) + label: catalog.i18nc("@checkbox:description", "Automatically create a backup each day that Cura is started.") + } +} diff --git a/plugins/CuraDrive/src/qml/components/BackupListItem.qml b/plugins/CuraDrive/src/qml/components/BackupListItem.qml new file mode 100644 index 0000000000..abe9a1acf9 --- /dev/null +++ b/plugins/CuraDrive/src/qml/components/BackupListItem.qml @@ -0,0 +1,112 @@ +// Copyright (c) 2018 Ultimaker B.V. +import QtQuick 2.7 +import QtQuick.Controls 2.1 +import QtQuick.Layouts 1.3 +import QtQuick.Dialogs 1.1 + +import UM 1.1 as UM + +Item +{ + id: backupListItem + width: parent.width + height: showDetails ? dataRow.height + backupDetails.height : dataRow.height + property bool showDetails: false + + // Backup details toggle animation. + Behavior on height + { + PropertyAnimation + { + duration: 70 + } + } + + RowLayout + { + id: dataRow + spacing: UM.Theme.getSize("default_margin").width * 2 + width: parent.width + height: 50 * screenScaleFactor + + ActionButton + { + color: "transparent" + hoverColor: "transparent" + textColor: UM.Theme.getColor("text") + textHoverColor: UM.Theme.getColor("primary") + iconSource: "../images/info.svg" + onClicked: backupListItem.showDetails = !backupListItem.showDetails + } + + Label + { + text: new Date(model["generated_time"]).toLocaleString(UM.Preferences.getValue("general/language")) + color: UM.Theme.getColor("text") + elide: Text.ElideRight + Layout.minimumWidth: 100 * screenScaleFactor + Layout.maximumWidth: 500 * screenScaleFactor + Layout.fillWidth: true + renderType: Text.NativeRendering + } + + Label + { + text: model["data"]["description"] + color: UM.Theme.getColor("text") + elide: Text.ElideRight + Layout.minimumWidth: 100 * screenScaleFactor + Layout.maximumWidth: 500 * screenScaleFactor + Layout.fillWidth: true + renderType: Text.NativeRendering + } + + ActionButton + { + text: catalog.i18nc("@button", "Restore") + color: "transparent" + hoverColor: "transparent" + textColor: UM.Theme.getColor("text") + textHoverColor: UM.Theme.getColor("text_link") + enabled: !CuraDrive.isCreatingBackup && !CuraDrive.isRestoringBackup + onClicked: confirmRestoreDialog.visible = true + } + + ActionButton + { + color: "transparent" + hoverColor: "transparent" + textColor: UM.Theme.getColor("setting_validation_error") + textHoverColor: UM.Theme.getColor("setting_validation_error") + iconSource: "../images/delete.svg" + onClicked: confirmDeleteDialog.visible = true + } + } + + BackupListItemDetails + { + id: backupDetails + backupDetailsData: model + width: parent.width + visible: parent.showDetails + anchors.top: dataRow.bottom + } + + MessageDialog + { + id: confirmDeleteDialog + title: catalog.i18nc("@dialog:title", "Delete Backup") + text: catalog.i18nc("@dialog:info", "Are you sure you want to delete this backup? This cannot be undone.") + standardButtons: StandardButton.Yes | StandardButton.No + onYes: CuraDrive.deleteBackup(model["backup_id"]) + } + + MessageDialog + { + id: confirmRestoreDialog + title: catalog.i18nc("@dialog:title", "Restore Backup") + text: catalog.i18nc("@dialog:info", "You will need to restart Cura before your backup is restored. Do you want to close Cura now?") + standardButtons: StandardButton.Yes | StandardButton.No + onYes: CuraDrive.restoreBackup(model["backup_id"]) + } +} diff --git a/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml b/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml new file mode 100644 index 0000000000..74d4c5ab57 --- /dev/null +++ b/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml @@ -0,0 +1,61 @@ +// Copyright (c) 2018 Ultimaker B.V. +import QtQuick 2.7 +import QtQuick.Controls 2.1 +import QtQuick.Layouts 1.3 + +import UM 1.1 as UM + +ColumnLayout +{ + id: backupDetails + width: parent.width + spacing: 10 * screenScaleFactor + property var backupDetailsData + + // Cura version + BackupListItemDetailsRow + { + iconSource: "../images/cura.svg" + label: catalog.i18nc("@backuplist:label", "Cura Version") + value: backupDetailsData["data"]["cura_release"] + } + + // Machine count. + BackupListItemDetailsRow + { + iconSource: "../images/printer.svg" + label: catalog.i18nc("@backuplist:label", "Machines") + value: backupDetailsData["data"]["machine_count"] + } + + // Meterial count. + BackupListItemDetailsRow + { + iconSource: "../images/material.svg" + label: catalog.i18nc("@backuplist:label", "Materials") + value: backupDetailsData["data"]["material_count"] + } + + // Meterial count. + BackupListItemDetailsRow + { + iconSource: "../images/profile.svg" + label: catalog.i18nc("@backuplist:label", "Profiles") + value: backupDetailsData["data"]["profile_count"] + } + + // Meterial count. + BackupListItemDetailsRow + { + iconSource: "../images/plugin.svg" + label: catalog.i18nc("@backuplist:label", "Plugins") + value: backupDetailsData["data"]["plugin_count"] + } + + // Spacer. + Item + { + width: parent.width + height: 10 * screenScaleFactor + } +} diff --git a/plugins/CuraDrive/src/qml/components/BackupListItemDetailsRow.qml b/plugins/CuraDrive/src/qml/components/BackupListItemDetailsRow.qml new file mode 100644 index 0000000000..dad1674fe7 --- /dev/null +++ b/plugins/CuraDrive/src/qml/components/BackupListItemDetailsRow.qml @@ -0,0 +1,52 @@ +// Copyright (c) 2018 Ultimaker B.V. +import QtQuick 2.7 +import QtQuick.Controls 2.1 +import QtQuick.Layouts 1.3 + +import UM 1.3 as UM + +RowLayout +{ + id: detailsRow + width: parent.width + height: 40 * screenScaleFactor + + property var iconSource + property var label + property var value + + // Spacing. + Item + { + width: 40 * screenScaleFactor + } + + Icon + { + width: 18 * screenScaleFactor + iconSource: detailsRow.iconSource + color: UM.Theme.getColor("text") + } + + Label + { + text: detailsRow.label + color: UM.Theme.getColor("text") + elide: Text.ElideRight + Layout.minimumWidth: 50 * screenScaleFactor + Layout.maximumWidth: 100 * screenScaleFactor + Layout.fillWidth: true + renderType: Text.NativeRendering + } + + Label + { + text: detailsRow.value + color: UM.Theme.getColor("text") + elide: Text.ElideRight + Layout.minimumWidth: 50 * screenScaleFactor + Layout.maximumWidth: 100 * screenScaleFactor + Layout.fillWidth: true + renderType: Text.NativeRendering + } +} diff --git a/plugins/CuraDrive/src/qml/components/Divider.qml b/plugins/CuraDrive/src/qml/components/Divider.qml new file mode 100644 index 0000000000..bba2f2f29c --- /dev/null +++ b/plugins/CuraDrive/src/qml/components/Divider.qml @@ -0,0 +1,11 @@ +// Copyright (c) 2018 Ultimaker B.V. +import QtQuick 2.7 + +import UM 1.3 as UM + +Rectangle +{ + id: divider + color: UM.Theme.getColor("lining") + height: UM.Theme.getSize("default_lining").height +} diff --git a/plugins/CuraDrive/src/qml/components/Icon.qml b/plugins/CuraDrive/src/qml/components/Icon.qml new file mode 100644 index 0000000000..3cb822bf82 --- /dev/null +++ b/plugins/CuraDrive/src/qml/components/Icon.qml @@ -0,0 +1,56 @@ +// Copyright (c) 2018 Ultimaker B.V. +import QtQuick 2.7 +import QtQuick.Controls 2.1 +import QtGraphicalEffects 1.0 + +Item +{ + id: icon + width: parent.height + height: width + property var color: "transparent" + property var iconSource + property bool animated: false + + Image + { + id: iconImage + width: parent.height + height: width + smooth: true + source: icon.iconSource + sourceSize.width: width + sourceSize.height: height + antialiasing: true + visible: !icon.animated + } + + AnimatedImage + { + id: animatedIconImage + width: parent.height + height: width + smooth: true + antialiasing: true + source: "../images/loading.gif" + visible: icon.animated + } + + ColorOverlay + { + anchors.fill: iconImage + source: iconImage + color: icon.color + antialiasing: true + visible: !icon.animated + } + + ColorOverlay + { + anchors.fill: animatedIconImage + source: animatedIconImage + color: icon.color + antialiasing: true + visible: icon.animated + } +} diff --git a/plugins/CuraDrive/src/qml/components/RightSideScrollBar.qml b/plugins/CuraDrive/src/qml/components/RightSideScrollBar.qml new file mode 100644 index 0000000000..5ac5df15ff --- /dev/null +++ b/plugins/CuraDrive/src/qml/components/RightSideScrollBar.qml @@ -0,0 +1,13 @@ +// Copyright (c) 2018 Ultimaker B.V. +import QtQuick 2.7 +import QtQuick.Controls 2.1 +import QtQuick.Layouts 1.3 + +ScrollBar +{ + active: true + size: parent.height + anchors.top: parent.top + anchors.right: parent.right + anchors.bottom: parent.bottom +} diff --git a/plugins/CuraDrive/src/qml/images/avatar_default.png b/plugins/CuraDrive/src/qml/images/avatar_default.png new file mode 100644 index 0000000000000000000000000000000000000000..0c306680f721dba0de73fb7be90fe5c548608692 GIT binary patch literal 3115 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 + + + Polygon 18 + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/plugins/CuraDrive/src/qml/images/backup.svg b/plugins/CuraDrive/src/qml/images/backup.svg new file mode 100644 index 0000000000..51f6be4cba --- /dev/null +++ b/plugins/CuraDrive/src/qml/images/backup.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/plugins/CuraDrive/src/qml/images/cura.svg b/plugins/CuraDrive/src/qml/images/cura.svg new file mode 100644 index 0000000000..6b1b6c0c79 --- /dev/null +++ b/plugins/CuraDrive/src/qml/images/cura.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/plugins/CuraDrive/src/qml/images/cura_logo.jpg b/plugins/CuraDrive/src/qml/images/cura_logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..621c03f035cddb3c9337099c25bccf19a5866968 GIT binary patch literal 19308 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 V{_(E9+wT8(SKsZ~f4r-A{|^$iZYBT# literal 0 HcmV?d00001 diff --git a/plugins/CuraDrive/src/qml/images/cura_logo.png b/plugins/CuraDrive/src/qml/images/cura_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f846f2a0f0934f4843c3279ed741c149c77b2e1e GIT binary patch literal 13258 zcmeHu;4V*)BSRu^XaTvbLN?uz4uJ)2XzHpY!LRVSFdoD6lJwuy+WyZdCve~ygc*u(2ZXX z6n8BJ=~tEGlzXpU@kS`gN`3M{In2g&`K-Ng?48+YOUK6%Q!&j{8UO%f(B`2OjGe6E z=pFl$ws^S=Htqi&Eu+nt`f5zkAyuM|<9+lUC7ObBbhAJ)l>)Q49oq{+g+>xugU({Y z!PhW}n#xpMueQi{{k(Xgq^qIfb|t>U@SfRMr>zd5Z{lC^?1wlPJ#bg}3RdVQbU~*? z`TxiNdl#7g_x2?FIG|)>n5~LZ=;-U{r$9xWcyi_~xxLz49$qf=d`tG6X zIStGm9v<#dC-s0$b#qRMgsHFQp^FeRDg%|8>pO3^vnue#Z%ltH62Zo)abYu)lLUvz zhB9bh6s{bH^OfNC;bPHuwsUnckKTeN_+-^P3q;Rl_BXG`4v(a2lIvSvy%OYFLvt*Z39TCgr_a$F=Mp8M>*tj%kWC~v)94VFN5 z1qXZl?GEiRi;f`o`qcv{-e76%eFdNVsQd3-SZTWP)QI7xn+|JN!Q5xxAATLlA*Y)u z8pe!KMjd{a`|_;R{4@b4QtZ`tcX#VkMd;L<4<)IL{^KurzKG;6p8r3E0*#`BRc1%Z4{vHItk9179tO)8Rr)A_% z^@S+;h%bJ(TWOfDQ?c0pN|yDfn~1yLxnevG5wggjcb=tILHvFOzr@qF%`oJMOSJ+{ zvx|e^`kBeW*=VvqpXlg0-=GhY0MM;vt$z~ATSwB$WVr;veV2t$H*iB= z9Qz*R+wd#7o~OW+AvB*R9cy`8kkDbTmzQzWzP^*cskOBg%~EfKP~j8Ris_&aPFLcN zUi#uzboWne?!(MqzJEh8^?ZVidSPC0n3@71p>*8%Z)6$;fFKy%0QQAvykQl%ipl86D zp6LP5w;D0G`6p$=CEh&yyO5|8W$0;Ch)sve$3xGmuBW@dNk;N!XYs*xus)kGap#&jjLnRa>E$AcC6{{L0hB2p z(d5UzFVqZCgKNN3ck+4~>(E_#s08-L_qzM?y77I))HmP8By}+g-%woX6(1QP(8wUT z8_$T)hmPi*wF8sEf`U=ZECL~5A8}a?!?V`I{7*d4ZwX7Lx}uJP?o@<9_<=V#dT;p< zkU)+;E_S^HTK+lpxLcUa<4?$|o6Zp!vVcu&0D#Dwt;O`Ed(S5i;&3`TIyU^WPfJ>o zMJ{QDzv6}BI!lIRtO*usuLGIrp1YIl0XL^Co4C=jrpf69aHA(>N7tQyTpu5(GS~d5%UqzuqpMu?ZR; zn5YT+op(z-ohE~l$Y}oqN`(%5@MOS)F7%$_xUvh1wzo$U0txB7mObYxX2K4(z=BQ| zLm$e;sDrk?iu{re_7*`Ura)P?pJy5L-*KN1(;Z=9a~CixFsrkfDi}Z}`u3eqNJx

    {tidI^DPfL*th*F*+_ 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 literal 0 HcmV?d00001 diff --git a/plugins/CuraDrive/src/qml/images/delete.svg b/plugins/CuraDrive/src/qml/images/delete.svg new file mode 100644 index 0000000000..2f6190ad43 --- /dev/null +++ b/plugins/CuraDrive/src/qml/images/delete.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/plugins/CuraDrive/src/qml/images/folder.svg b/plugins/CuraDrive/src/qml/images/folder.svg new file mode 100644 index 0000000000..f66f83a888 --- /dev/null +++ b/plugins/CuraDrive/src/qml/images/folder.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/plugins/CuraDrive/src/qml/images/home.svg b/plugins/CuraDrive/src/qml/images/home.svg new file mode 100644 index 0000000000..9d0e4d802c --- /dev/null +++ b/plugins/CuraDrive/src/qml/images/home.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/plugins/CuraDrive/src/qml/images/icon.png b/plugins/CuraDrive/src/qml/images/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3f75491786dcc0939175ffbab5e791e27eaefc2c GIT binary patch literal 21924 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�>#6>;@A&7;Ub9*u@xRReL>D;wp-rSVGg8b(Ftu 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 d{(EOoFjyv&`}RG)N<`qZ!PU# + + + \ No newline at end of file diff --git a/plugins/CuraDrive/src/qml/images/inverted_circle.png b/plugins/CuraDrive/src/qml/images/inverted_circle.png new file mode 100644 index 0000000000000000000000000000000000000000..3612b37d4d38cd7b1218be42c943932a79f7b465 GIT binary patch literal 1608 zcmV-O2DkZ%P)Px*0!c(cRCodHojY&bMihm$2^^$|ogzu+GJuKziK{dQ0@$6KbS?t}`UTGaabp-t z;i~kgR zm9(f#Bk`Hh#bQJToQuwp^t1Gf^xI;wNV0G!$A#wim2^+K zFMT83l8Q%Z1I|R?x%5mr7Vv*8h{%xl)y`e%JL#eHu~Z~V7{F5fT6!wI6!f=6GOrqy z86Rr&Tj`PXKw@pN3pPPU@weJJl)kXbZnu``Th&MUY7%<}t&q$U>GR!il>0P&t@@nZ zh};GoD-m{nlMMPUkwdn~WxyZm@quK!J<0Kd99kqasqEGcb@~(JT5IK!cP27c-S#u#kG0(8mB)x!EuI zv3W3&cHSKAY5+T(*>3Y==1IR!KzbqHGm%;v-v;2 z4RYK2u#!6cSnF!Qxky!b|3W&lo2<^=jwe1)mBu@+orz~NMqnp!_)z@gNL*nofa?r5*u znHuo8zp#~HypGs_SMis8IxPW_f3>Esk@uq6KaHk+GChGN|X7 z)YpLLr7x7tnD=OAT`}g0@KppSG~}9j4+8?Q4&1{|_)ITw&Af*J0a!~gU+;vEtZt4l z$ZzybRIHEaXxImETabq>ffaLB1BD-WvxU#5{|?|8IhXvfv%LWvraosAbfRrilDiR& zbC`5<74ws&0h7*T+MRa;3j5~MnScA#mXalmQ=Fbpry4LcAnp|E$84L0IpEm`5cgIC|7%EK z$vhZv->_kCYDHkhoYg?#mnIr67UI3WG%@T0Fu^a*H8KI#04KsGh^8rI?O{XU9qW}3 z%fEhuh5>w$-g<)uCETeZ?va-OjA6Zs+8V&9-=r77WEzU`k9FqtoiMNaZK|2TGh6X( zy-gJp{6_6eCcqZJ^@!I1-t$rg84M8D&ZP=4!HabyHUXx9jpMR4fX}cN_+2xJOn_y@ zRD))0Gk{Nd!KMTTh-0sUO~Iyv1bvwGECjN5$udmvqJ0AvAMqPpv=0-!Y-LXqU{d?E`(IhHzx!sYx(+Mfoo zK~Pay#k1N~OD$HkXlch*$LY3i$6D7J9oktfbz0YT_xt35v>xp%^o5gmkk9}7`~LpV z!yAhh&Y7F0C-lT#f?(2_whG(eM}xtE!MAVSo<4PY&+eYl2cvR#d2vy(fG22fZNB!! zwTQ3?|JnX0-aGO5(c{{h+TqK?Blkv_Y^JT+Hh6I`cwzAEJGcF3`u82~8+|yc)~d_a zl?g3{s>@slS{h?nrs@IQWJNL*~tg6NQ$zJ3fEeuUu{CYMEc6Vu5b zM}AF$Z5?PR2vuve?TZR8nQF8`9?>oFKN23Ed6^|Rni{(Q>rbsmcCb%>J@+-ky`M&p z7ye0B6dB-kToIHbm#*0mB4L?0?o|Cgk3TBVMQj{`VPp`*Ry+VyKjA0rM0r_kKkj1w9DY}n{!%r)npIDP``@Gsj? z)_=C&lx_kz{9lqe=?c`f1KSEh1)7;^apjU|dDoS+^Lirj$n}8YX(RfhsROspub*xF z_TN=0+EoX#{r1kN`j~4Qs$BeW50@q>D-M!n%T=~$oo6cFy=I9jRkW>Pi!@QZeHlYR zh`5y8TO!4XFf2jRcc2gP1OrIGfc#Qs z;6%V7T5KVs4L``u|Lc6{BFm)cvn)Q!WOswO&Z5$A<-Fz{)jM`}b?@4}r)TfJ{k>0HTE-Qp zyhsr+Z~{Qjz8*lL3m{ipUyETzG!ZpWp)7z0T^NHC35F1Cs8T?zkymITujFa`FoHD0 z55a{u{BQ_p2ebxgC(4q&CZM?>G`LOBWYaU!1Lj}omA`d&6BHlbnv=Bes?{=oxnSVJ z#j4?p%jGNl4}5-@F{daktyVAbTB9m8y7Bouu`$r7qUlVM(o&%yS?bc*IN6iqv9hhL zu=_=dWFk+FOB!D&Nd@XaA29J{k*2s9QWAy;Ao7K;4;B;wQU*pRAcPTH00NoR(~@04 z3Zo800vKY>QJYVRxn$L`vs;?0tNg?_cJSTZawO%8c{-EcQXQhn;nhWWnWT*i z`57^8=Iz1FDGfV=6ef>7L0Wx`AiOtFB~$8m9~rC3@!bla8a_T2kMf5TqDAuggfeiT>TSWj!sJF2evH$t7p1u>yUBg z@g?&b-1yzEl_W2a(o^|a{zop+w@>@IqKc5G`j@i(Z{0Yu9_`xOC|oQY2kcWkzqiRGZ<^BhFCuNX1H} zxF<+j@quHXU;KFJ(&cg3XLdTmirJ<15Ux^~T~j8xhmc6%U?%~JOr8T4n2>}sbxlHd zQema;QPhnKH2{2ab>U+0l5N>#n97M3n$+W+Oo{5$mE#W>kTxsvQll{2N( z(<)uf@=9rzn@6QAOWVN8T2-kL^O*LAz{1niMJak5bnSM&x!8QRR@{0U{ zk20b(A%%4VTpR$n$wjlSj55VOf;$9p9>7Jo5p?t?<&H*0C7^);J+Z{NBw?}t3VNlt zIP6f&U!(_Lr61emJL&rZ<`jl9-7q8==!xRbPHj3nH21E(ztMNrm%4mru4{!YTUwsE zF@0UGPqt5yEM2R~buUhCv?m*i2t&H6NS_uziBsf}EzcF@GioGB`7Cx{K5m}zB0Y)m;)M9Ug5JQcAfG$OdRKpLh6dQ^HW@rY~F3ixvfSg!4 z=de3Juq{uA(_xu>6IXjV7zBXPfvn7Z#@}-)kB7J!_J>I2*(8r5f^0}Ey6&>6a@fvBq{GCL#J4fP{ z@_ytv<@5JV@~O%38FxOmFd{_fAn}P z&m!`2iU4Emk#i(=Vz)fIl)P^~6H5o>C*QC8a5$_gJkXEF&U=f-qa_i=%D`pzJG3Fc6FjSW z+fe${)d8%$3k44ddAvwcVr9gNbnZ-Rkub`jWj0sW6ADq3WP82Bvq9EbDr}Dux$G(4 z6hrHzbGl;<9KJ%z*K^oT%4e_e)i$#2aPdSc_x0c!1Wi~VaX>*%QF~Nhf{eVRPbDu# zq|u|t(8L)~!NhsMj(i+KW~mKzmV729%d)W<2Y}2{_fy1qqHx(oiMY~Hu^rmuaKjfz5b>>1lE@{vsLlj6`V&gz zI}=MW6-Q(dr$8>8dm}gn$fGJzm?(n@UoyYVBK4VF{Cib7o=9Ks*Wdgk;FdItFS2&T zq@~V!FyGo8+8rdoTM`DlJj{Jvjf+z0S)-58acWvxM3!)YzO|EZX^U{@@2t^83#5v@ z45>ZZLnV_i7!sL^<%E3pK?r%o{&vhJBrx5;z_SoGE&>P-DvX#}2muW0P(;wseW0Sk zNF|yw?$}9|DWXax5$Ax@cuC6#kCb>2`u#l4QSl0O{DB4OpQRH80s3WagS6I7{}KIc zI?5<35#}xRt{|9tv0I#hx2eEI;^oDyi^7|ZwX35It{sKCswk;sHzA5Ou;>l!1P;rU zr`5{UdqaPxB&oY0=8}x$9rE!TUmU?iJaO*UYU}?QYa{!i9OfZQi+B&9!N(*AVnX zjed>TJyB9YXf+AyI;EDI7pvJ&M<~i-`0aJ-r5fH2W`astp{(+h7I2oaIBvovZNJ(Zm)0n(BrEM%SMOheM7h>v8?hW zj#aQek#6NxS|yA`vB0WsO3+ye$y*5?xCAAL-8#w=Joj5Yn|G}eWF`t#82Ds^_}vxG z3+1!7Ajfc%d&047V1jTVebhAuEEr;>4+(`2B;khPM(ALLc=FaP(aV@tssZHN7W_t_U zkFv7Gxjxp6ignqX#7x(GQ7$Wgd8Q#>ydhKFxGi5;xPne1LsRJ^ zlPbE7ldpwC{xFvqTWaCpsS%Da0v0vD+M3bSIhP^dW$WM z)1sxhyBj)Nyt&&>kG#PsF=bH>7-T< z8iAyCyu|}M_09v~CJ#j`L6VyFF36+efiNcu>b91hmeBYW~6B{LvzC0rBUs^hE{1IfW%@@vDpG z#D>R2g~vs%Hbo{USr)yqE+{U3jo%`3PI6dGaeBTbdZA_E;#tKx(Rm54&0HB@GBZCs F;r|kGDY5_n literal 0 HcmV?d00001 diff --git a/plugins/CuraDrive/src/qml/images/material.svg b/plugins/CuraDrive/src/qml/images/material.svg new file mode 100644 index 0000000000..eac724e471 --- /dev/null +++ b/plugins/CuraDrive/src/qml/images/material.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/plugins/CuraDrive/src/qml/images/plugin.svg b/plugins/CuraDrive/src/qml/images/plugin.svg new file mode 100644 index 0000000000..674eb99a54 --- /dev/null +++ b/plugins/CuraDrive/src/qml/images/plugin.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/plugins/CuraDrive/src/qml/images/preview_banner.png b/plugins/CuraDrive/src/qml/images/preview_banner.png new file mode 100644 index 0000000000000000000000000000000000000000..414019531beed2e503e05cc394fc7e6de246830a GIT binary patch literal 8324 zcmY+pc|4Tg`#*kW%rM3_LUwME>|3_Va@&vJ_^F zvXre5vMXEmC59~D+w1qo@BNv7=AQfUyq?!}u5)eY%snd$6E?g69st00+|=+i04U@U z1#pbW*SQ;c?t8y(o;J}3#ce{<06;p&4fSjSP;(hfDYo738+#yD*4t4J`8av5@x`5z zQ$A(Gt@byhojdN)tLDSG)e;x7rte9wDJ-8n`CMW-t3*m7@E*4R@uxh!3*5mBa+(bF z-0o5ghtJLo^{qb-o?QL7p1->t;xnIK)~>Vretlu~?bn~Tv-MquA&2FO3t6?6g-*SU zw&Z#Bqi%oh6co;|1s!aQM*B)x+4)+-Wc`OeVE{dPtKJrQ!win2AaWf$k;ur&X@tSE zVu%CWgbqj>BI_9%p0`H@gC=tnitRfCTENhdn~}$d@&5o!QU3oIz`gi?058s>!azbA z8ZD5`gi(!&ky4cz5d}A_VK`#-Kb?`1*l-l=g~we^5JB`F$m$@&KL1e)e|PIGW#r*B zx{klgKpfyAP+n5J@20E*XtJ!F=td9a$Zi1|g=NVfasxzLeE5 z@H>|X zC1x`ba9&SQb^y&FQO7QiPhlcTa1lCO<&f3K#AKZyT?UW_7E_STv2q9^7^|K8RRrGx z3910ymb4gxAuP)CSghJW4#4yVKv}*F$OO0m&%1}WqzKwT!j?!B?GH$2zy;v$*6VP` zFo8!(Ff}@`+5&~C=BD}jW5*cwtn{gPSn`rcRD9<1=rwu?4L`!*dIcnVEnq0cS<_LP zpbI1p5{YFdY>qIQap^|z6%_z2BfG64hJ?VUb4H0mAZC_GjA~&*)~c*=N`eI(I0li$ zR!~Spv>0(WGZ35DahIF!?78%?sF4Z^D%%qm-4j1)l6dZa#owNi5d2^9i`>mj|0~XG zbQJurxKX0W|B4?z#d@OqaaZ@>@BG%2j|0B82Jn4JdIs%Y;RwmhJ?O2VK(z@Th*7$Z zPiZ>uuGWOYWDgAgCHby)3^1!+Nnz$fq1_K(3A$j}bBJi$6C28&M+;l-ilTMu^bZ*{ z%6q@?FJE)Wbnf)N!+v?6%KLBGyx>4!17zhyw=G6vp6u)Wa|Rj&1T_^j>J_bol^rK_ zu(Ug$c#q>`#`MZVS%&LqzetLwiQ@L}XY4=w`t3Sgca;sMNL(F~BN<{o#sutl4iNa0 z+kl$Cn7KK^xY=ece5)bT5k-QI2uw1bhPE@ok4E#pNuuLuSY=@FbhD1~Yf_SsT9O~X zjViAW(~0jRCUN+S$OagnfJQ17W&i!ub8QQe@2Y02VK^avEkZUS&JxVrd^K_tx;&cP z_|dI336;snoe&in}Ylb;5!~JrdTJy_4;Bi0!3!tAOpM z;{pc^mppHdl}`hN*IYQ%N1EdCZQ8Hv7q=&pLoCiOc@EzC{5B(}URTpcb?)$0pK0$J zU4W_yl2k08MZ@nb2$*y{MPj9qDK1yrWd49|NTldaO+;$Nyj;30Tf~Z=@WjjqpF=35 z{+Kn|_AwHBArzrhcI$il@Hgvg)Zm_&x>dsZ(!WT!r%flQIK)Icy7igryVd>{4wxES zywsQ)0%97J^${1E>F(ZJ_a?8+jY6f7Vq{uz{dSK?ms(u~5%y_)6lSCYAio$C+AGqf zc0;tkGQ%PW(!@xvu-1t;^d#Ttu}%v*L22Cqn3g|+A+sAO;$=ZGOf{aO@}3K`COS7z z>c9OWuFKvF`(K|=gy3_b(usHkM7AxLdRpP=yd;-c+iW51r zEe5TVyvo^imbDu-A2!)V?JU=YG@duu56vsyUhVK6?sW+GC8`l9WiEQQn16Nc@3%Kv z0*i@BBsCztMLBvyPPj`od&ClmGj=A*zqGg%ih@oE5{bAEi>1a#y(gN&<+u0m(3-b~ z&$~r;?5e=o9#nbL(cOjuzYl+^S{W>?BX?J)Kc~|ElxJCU!mdP{s^LU$5VOIiKT@O} z{V!<6Zj#m@c6;@0K|$@`bd3-G9nZpk8gi(4znxduDpuI~gMndb(ra53fV-41q-R?C z3z2O%!fI>-bSb+VPHeZd?EZPEvA@V4=wA0I{-fwZd74z*uYX;8+zaMOwjQ->M4@sp zGJ?B^GB*2NuubCdvbSt4~IO{HR-as07H1s>`9T08LUs4Ii`leqN4aV#d=hC zE-`NP{nNQyxu5f!Q0LMJ?fP6fh5Etp0@3d{n@NlS{GKXZ$Xv;@b7>%$OnX&nw$!u# z)qy-_sY}Z>STH-AxerH|-}=M(|66dX##|EO;#B)#_Usgm!T4K%xHiM1eO;L9SpqP{pk3)U>l(7vfEc9gTHn1oWpG#(P?(Cv}&fy9Yhz zB|If?qsPu(7UqyWGrG;S-2)*RR8EAIYFaYc0Op$}Bd(GsbYsG$y^yhev^%0+pE_nA zBgr1&@dD}-W0^z)z1MvI<;{s8dz?_Sb0qu3G)<;x`1CE+f*th=BXeqcdEEs@5I$|I zbqu}dZf~IKGZ;tBf)pBPn2GH^1w+*|49-3F8Pu=tOOA6bLx++b3KP7jx>< zv*^@zMd<`a-Hi$VnLlqMsAX;qJOdBEa=Y=cUlTfM*^*{hHdcy9T&gRq#gcz>)fDa)W)7>H_LIbi-afa51keEZD1 zYcH7xx({I~&INqidJk(BhTI*-N6y&{JRNQd#p$k0NfsI98GdalPiIkChTmvK>EY5_ zoo+gNhko=JO3t{iQx}TOL2~Qb2-aAqHtVU#9S`zN&MFH$rRXdqa$kwmWZrxW+2>n* ztprSVV%v15aWKbA_>oHG8pS?&t9g1uo(&o^pZ(B0n+R z{ZSK|vNQQ$jhR)QH7bx$=$jMoGI0O(wYeAF)kXFlwB4kfB=G9M`J%)Y&!RwyXVNDf z3-)19&qQ6>B0}u@=UaDi$3zDw{b#0AC%@ce0;s~W>Fqgjv+VWJ3ub|6$fwP@ewrc4 z$RHG)mg>Rb|?MRT{=52jjFaxXA|ll+RtxRy(nvB?lOgp4!)o29k4p3>fzDNTd1Rkw#IhG8GHXA3j7RIczbU(Je!2Z1Em&dN}Fk z@y*PGRhEQP3shF;=n>097G&n6%w!aHG_zhh8O9tAAL#V=| z)ATq2nA`6@SrU3c+}Y{%<%!&Fdq22Z)fmnbn&`%SjAiMUI6;jhr4rv441oJz`9?23 zblKI#mT%*4w&T5fEne;BKP~DE`Fby3Xw+j+k>WjezR6>)MAkl}Xww@eJ0#xPW&?&- z6e9?i-6=rk-6AQ5KiTN ze)(mZi%c>1oz4eNs}o5ogrfK<8+uOR!rgz4riU;)x1*$a-BOG$zrP|+8SEh!A9O!A zQ$&QxCEhynfsflqTZ+U?#fJmqD|jwAbY2=BUN}SV)}X+y8%tbM32**J1~Q!HN?7#t z;$6fqAA$4)7{l6>Hk%KRlMI}D7L2eg z-AEVhr>asixTe~n+FF{8t1cm7#j?MKwBs?Cbh^FXYc}NKF-zmCew&hs5A>PjboMzM zttEgwBW>Xx0U~_6ESx*^_Vw2UtEHwj#RyP5t(cA)8iuHakZNpx8aem z|6;SF>OSAkh4;EtVfN*rtn*5-WB~JZpFHP=Lys*Q{AD*S`)rUP$AyIHok#~rDO@|@ zj<5T-*Utuut_Le_Z;dOsth4#=g9tVnnSIdZcbd9S(2Ni{h^dH>()dt+{;2yMa{^sG zSg>HdN&7pS=8v+0-uLbPr-S1=$-k}c_nkuq>6o!fmN??W@1Fvwa6Ost=by_q&*$eW z%D*>?48cjthQ%DO1sE^!zj0ge^b_)g5@Wc=>~xPl^AmL5+PXYhu`6OWoU8r|Sj8iu znsc}RN5rUC@>q&8cAqoXqRdv-*XdwZMWp=x+vHU@v8Rte%wvwhJEPQqV&s_C^Nv(v zvc#kO=NqnpgCusZfF~7{cZUo`t+;$Th17t??J=FCJ&0VHK;rFhiGuVwQOnWfCs~ps z?uvkFo*^M*CWcYaBF~DG9}n-?Io@Gz5SNBVvX6n0?30hyUg6LtmU*vUO0vr5`-@Yy z9o_OblOJ{LG7$348168FS)1cywNK!Y17G`H7=@j-@AyVtP?11RGjjmg$Ugc_;bJG9 zbz|(5)@p#U&yuReeq+e_Y!UbwzJkit>qrzN0itc3>efR7x@Sq^Ii&YPEN{les~VY~ zo%qN4UGTLhMS{k~t*7*yANyoof=(s8tITAI0@doY5PuDfKQHl71gkmO?)q!cC!9okH}*$3U+&lls>jBLl>-=%NBH*I>2vG zni$QQ# zavq%-X!F?+i(9=GY*|;s2aV*UtRv%v7w9?dg@k?P@-M`xXq`}4h#A&kDj4{fqg?rZB3U`1kC;E(dCU?z!Q zTiad7RUd3`9k(y{GJDbAQGCoY3NyTQn%Ajbgp|HtPTKIoN~Y5&C0&RGbX$LEf#ytRC7{HE1Nd2=WiBU*w>lX6~c zq3qSK@~a6~-rrKWZxx05`u+EL!I{UW=;O_0+ee5msNGc>o?$GQwv?lpJ;W;W$(PMa z=L=t+x);o&sIb}0BY0(E;Ya6z;$@Sw^qjf#eagQsKXUPJBz=;CU6tdjTh0aQu|ZbG zrqj)gSJ7YkOQlrYx<>TvhC*g4y5+1=G$`CV(GwQgHAjS(Ezdyuyf1XE$!ye2i$2Y- zu4zPe(p6+`Vw-4SZW1o*M&csx+~efy`eNk5McKo9*B|TGCu*+@i1M1Sm|YRP%#~+! z)+y2@NZ7_IBC8B<4c0zf3@&*QRi~6SEwdFiSedal-q2Vm*O`Dqc|RE8LiT(1 zIp@kGv5ls?zLWHwCT>^j!7A^%U??+k6P8x?VF9dN5-!0P!io8`l2|6>>^o2ah#z$} zGzF9~CwW6JsUin~(P}J6f8X4b7y}V(N9`K+8uyx`D*ETlBT5aYD(fGatqbX&OZ=YJ zZVblWt}F0UW&MCdvf_bemDa^PNhSYfs}JjRW}Zhut$*G=Tr8|i*qyqRiT2R_aBn~5 zhf_$?n)k<4YWhEiyd%WP3;i+I{c}A^30FZmW6P3-ff{LC>tq0DJKjbNX)49FPq!>- zkaO5bvWfb)t?5g4zh%5WzIHMnsjIU02WsHsKzPWQOfW${@TTv1^>j&XiMR4vMTtj) zH_uJ3^w(_UESlM6-W@;pIAEc2leXaCiB8t))Ef>ecu7d!*?r`~1;DDK_AzAvA~9Lh zE0PjdC-%bEG-E$*E2@SoV`K7+%FG?jJ^}#MH!cpvo8VALM}7A43@*LagkkWFyBTr| z&~%+U%&q-XpeMp*^N{xAEC~k@vKI^Q{=lPn+D+HIHfhn4os!N(!`yw7%;?J)n=0Vw zfn`-=Ef9>7-n#Mn&c1Z&9QwQ*@+jd*H`fGC`TTyd z4=Q8{p}$~5+NWnEb*Or6q-RaOU62rcAg;RW*|P+#cKzJvU9q7tYR*_zy%CdH=a!#F zy;R#}$9Ms=(3;?GG|6+Q-}G$*K#TSM@wriBSw`jMnt?s%SL+4^PBc1CO-Wa(%g!mSi622+6U%?3o)fuO zoB80^;X9yHnlme&O@mHd>yELu**g7GSRA#hwpBCv=Bj204ef$kSOl_m`+U+`>oG4 zh(y?oCa=`)TnvtlbU95Jo?4Q-w4&>R_C?l2A75Pv*v zh73Y=5r0(FE)W1N{i`pj5X~G(zEdymr9qChE^;2h`i~Fc?>@N@z zma31^)pfhuKdvV9VE!gjPU=opcIlCDVv7sW8b>6uZmh3!2$^$5KQ+N-tOumIRb&<2 z*&1Q~HC^o1V8?o@yrGiBD^@ihSr)-HqpVGNi5N_7bco4uK*D#?ecfVnsdL`j_xO*{ z0iX3t#kGY#{hm&@bTxKtqooJ5>0iZDr%Dc4?p->`3eQhX%hP!VuKEfsZd3fNf+=C) z-|zhlONj<&n0|Pv8rq+Rp^hGnOl_7Wg|-%fZ~^s!FV_CvAvq76hi0{UO$O(WdR0I6 z_Gf-Q&=a=v#qV}r>C;gf%bK7O(!}o@vno)y{MXjLwY$t`E%=__MRCZA{LuA)_X}+B zFT_i7Ly$=71aH#q&O6oseoKxiK7leI&>vcAI4=w9CQtI@`HU8*U!4|R6gMR_Ldil} zQA283Wl{s%Kh8Lmmc>0EH>Pb@G5XFAjW2Ao1PlO6`&gxv2zcDugl<}C`;c1+pmhH< z8y>hqwLWjOqQ3cA_Os6J%Z8rEEtvFHN6&!V*U<_AWpVR?AGhxLjElKlPTmptq|F+o zyG)si;78Kyo1;pme=G{kySPd0G}(_FSM4U-L#}a|3%+4#Hl@Z}7OqOl$+CpSd-7B) zdPI&}XIiAHJh6E0kghD1iDBVmU&3x9c{cXeeP>=s4CD8Uw6XiW)PHUzW8h%#@eJF)K}Y5a48Ex0u5j27&JWuW-^pvX8rw|cYr9!c0IJ0L z7|G)eF(lc_pE?8I$r_m~l-pYrE!x~H4?TxKMsx5 znte_!^1CuyPqeZ54F>N^f@IaAN|y8Vd=0aLxGwhkJQ73drXy#V$xEUhuH~6(*BZa` zaP`Z@244RW=h6PR#+`R}NCqWKw|le~bf!GkD#dQC%t{^&xOVAfRu`1bxg;lE%XqZ} z8C9H*pc-4HU2$k$-NED5bcU?~{?B!~DhVdFOXH5i?N4^62dwBkp^poF#1xhO+{)?vrl&B^=9hE zXKQC=!{phavibN4f1h^!Jd~ju|G;N66oVS7#PN)1a>ZzOk{9LRfSIfO*17&yE9-*C zRo*oHtcR9NkJW8x-SC+f^kv<5+HzktGHpoBmBzV{QpBM8@a`t+yl~BGtL?a#?vli< zmC?A>`P?tYwF){5`@CE#myd+au}m1TGok>s+Q=sw!hgb`He!>Hpk&T%47dkHm@LJJ zlFR~ktF+c#0{5MsZ2ChR9tlLdB<~{da+Jt?ldn>0$b@Fr%+)nEtP#m=0WuE7ye16;3tQ`=Z3;-tlCC>J{-dWgkAf zjmf1idOsiwINNby|NM`c_adgN-s@3%0Q%NoFcu)P1+5(_wNKVX9Wx56vw+(suqSML z8@8hh1g+MNR}7gCygpPZdx|gr zevhWK{o3jARfNk8_|X6^m(OT@br_JY;m6l(j1Uic35?p`-~kxb-rRY007t~e9FW8U zQfed51N`(1QE!DL!BfFp(I z;=Bmc!NUyTp!A}+9rBF5$pEUp{0->EBhqLfa|5%}lz~1H4M4(2p?D?{GW-y!0<2AJ zy@_Vn8+fEZC07Y^TrY&#k=MNwnAw)s=pzvbx251Vy?ktbIa9RQVF-Q=k_=T=>dBiqX{ExStFtYPf-~WuybtuG=i*!pa8dxfTtI{Y3J;@@XENY!dV$^rejnw|-g0XA2$0WlBMZY~eb?~+ E2O#6GiU0rr literal 0 HcmV?d00001 diff --git a/plugins/CuraDrive/src/qml/images/printer.svg b/plugins/CuraDrive/src/qml/images/printer.svg new file mode 100644 index 0000000000..f7dc83987d --- /dev/null +++ b/plugins/CuraDrive/src/qml/images/printer.svg @@ -0,0 +1,14 @@ + + + + icn_singlePrinter + Created with Sketch. + + + + + + + + + \ No newline at end of file diff --git a/plugins/CuraDrive/src/qml/images/profile.svg b/plugins/CuraDrive/src/qml/images/profile.svg new file mode 100644 index 0000000000..ec2130f3d6 --- /dev/null +++ b/plugins/CuraDrive/src/qml/images/profile.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/plugins/CuraDrive/src/qml/images/restore.svg b/plugins/CuraDrive/src/qml/images/restore.svg new file mode 100644 index 0000000000..803215eada --- /dev/null +++ b/plugins/CuraDrive/src/qml/images/restore.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/plugins/CuraDrive/src/qml/main.qml b/plugins/CuraDrive/src/qml/main.qml new file mode 100644 index 0000000000..4a2219cf1f --- /dev/null +++ b/plugins/CuraDrive/src/qml/main.qml @@ -0,0 +1,42 @@ +// Copyright (c) 2018 Ultimaker B.V. +import QtQuick 2.7 +import QtQuick.Controls 2.1 +import QtQuick.Window 2.2 + +import UM 1.3 as UM +import Cura 1.1 as Cura + +import "components" +import "pages" + +Window +{ + id: curaDriveDialog + minimumWidth: Math.round(UM.Theme.getSize("modal_window_minimum").width) + minimumHeight: Math.round(UM.Theme.getSize("modal_window_minimum").height) + maximumWidth: minimumWidth * 1.2 + maximumHeight: minimumHeight * 1.2 + width: minimumWidth + height: minimumHeight + color: UM.Theme.getColor("sidebar") + title: catalog.i18nc("@title:window", "Cura Backups") + + // Globally available. + UM.I18nCatalog + { + id: catalog + name: "cura_drive" + } + + WelcomePage + { + id: welcomePage + visible: !Cura.API.account.isLoggedIn + } + + BackupsPage + { + id: backupsPage + visible: Cura.API.account.isLoggedIn + } +} diff --git a/plugins/CuraDrive/src/qml/pages/BackupsPage.qml b/plugins/CuraDrive/src/qml/pages/BackupsPage.qml new file mode 100644 index 0000000000..88ce766383 --- /dev/null +++ b/plugins/CuraDrive/src/qml/pages/BackupsPage.qml @@ -0,0 +1,73 @@ +// Copyright (c) 2018 Ultimaker B.V. +import QtQuick 2.7 +import QtQuick.Controls 2.1 +import QtQuick.Layouts 1.3 + +import UM 1.3 as UM +import Cura 1.1 as Cura + +import "../components" + +Item +{ + id: backupsPage + anchors.fill: parent + anchors.margins: UM.Theme.getSize("default_margin").width * 3 + + ColumnLayout + { + spacing: UM.Theme.getSize("default_margin").height * 2 + width: parent.width + anchors.fill: parent + + Label + { + id: backupTitle + text: catalog.i18nc("@title", "My Backups") + font: UM.Theme.getFont("large") + color: UM.Theme.getColor("text") + Layout.fillWidth: true + renderType: Text.NativeRendering + } + + Label + { + text: catalog.i18nc("@empty_state", + "You don't have any backups currently. Use the 'Backup Now' button to create one.") + width: parent.width + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + wrapMode: Label.WordWrap + visible: backupList.count == 0 + Layout.fillWidth: true + Layout.fillHeight: true + renderType: Text.NativeRendering + } + + BackupList + { + id: backupList + model: CuraDrive.backups + Layout.fillWidth: true + Layout.fillHeight: true + } + + Label + { + text: catalog.i18nc("@backup_limit_info", + "During the preview phase, you'll be limited to 5 visible backups. Remove a backup to see older ones.") + width: parent.width + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + wrapMode: Label.WordWrap + visible: backupList.count > 4 + renderType: Text.NativeRendering + } + + BackupListFooter + { + id: backupListFooter + showInfoButton: backupList.count > 4 + } + } +} diff --git a/plugins/CuraDrive/src/qml/pages/WelcomePage.qml b/plugins/CuraDrive/src/qml/pages/WelcomePage.qml new file mode 100644 index 0000000000..882656dc4a --- /dev/null +++ b/plugins/CuraDrive/src/qml/pages/WelcomePage.qml @@ -0,0 +1,48 @@ +// Copyright (c) 2018 Ultimaker B.V. +import QtQuick 2.7 +import QtQuick.Controls 2.1 +import QtQuick.Window 2.2 + +import UM 1.3 as UM +import Cura 1.1 as Cura + +import "../components" + +Column +{ + id: welcomePage + spacing: UM.Theme.getSize("wide_margin").height + width: parent.width + topPadding: 150 * screenScaleFactor + + Image + { + id: profileImage + fillMode: Image.PreserveAspectFit + source: "../images/icon.png" + anchors.horizontalCenter: parent.horizontalCenter + width: Math.round(parent.width / 4) + } + + Label + { + id: welcomeTextLabel + text: catalog.i18nc("@description", "Backup and synchronize your Cura settings.") + width: Math.round(parent.width / 2) + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + anchors.horizontalCenter: parent.horizontalCenter + wrapMode: Label.WordWrap + renderType: Text.NativeRendering + } + + ActionButton + { + id: loginButton + onClicked: Cura.API.account.login() + text: catalog.i18nc("@button", "Sign In") + anchors.horizontalCenter: parent.horizontalCenter + } +} From 437ba3848db12db4f024911c1bc6b761134f0bb0 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 10 Dec 2018 14:26:20 +0100 Subject: [PATCH 0818/1292] Fix typo. Missing parenthesis Contributes to CURA-5941. --- resources/qml/PrintSetupSelector/PrintSetupSelector.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector/PrintSetupSelector.qml index fe642bd3c1..599eac957e 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelector.qml @@ -16,7 +16,7 @@ Cura.ExpandableComponent contentPadding: UM.Theme.getSize("default_lining").width contentHeaderTitle: catalog.i18nc("@label", "Print settings") enabled: !preSlicedData - disabledText: catalog.i18nc("@label shown when we load a Gcode file", "Print setup disabled. G code file can not be modified." + disabledText: catalog.i18nc("@label shown when we load a Gcode file", "Print setup disabled. G code file can not be modified.") UM.I18nCatalog { From 315bcf50c746ee6a25aed8ae95c6245d898b7525 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 10 Dec 2018 14:31:49 +0100 Subject: [PATCH 0819/1292] Get some personal space up in this personal space Contributes to CL-1152 --- .../resources/qml/MonitorConfigOverrideDialog.qml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml index aa62afa083..14bdd07313 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml @@ -48,10 +48,7 @@ UM.Dialog anchors { fill: parent - leftMargin: 60 - rightMargin: 60 - topMargin: 18 - bottomMargin: 56 + margins: 60 * screenScaleFactor // TODO: Theme! } wrapMode: Text.WordWrap text: From 861deaa9f74f4e3bc32db5f6c8e0628406c5e2e1 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 10 Dec 2018 14:20:19 +0100 Subject: [PATCH 0820/1292] Add renderType native for toolbox QML Labels CURA-6006 --- plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml | 8 +++++++- plugins/Toolbox/resources/qml/ToolboxBackColumn.qml | 3 ++- .../resources/qml/ToolboxCompatibilityChart.qml | 8 +++++++- .../qml/ToolboxConfirmUninstallResetDialog.qml | 3 ++- plugins/Toolbox/resources/qml/ToolboxDetailPage.qml | 11 ++++++++++- plugins/Toolbox/resources/qml/ToolboxDetailTile.qml | 4 +++- .../resources/qml/ToolboxDetailTileActions.qml | 4 +++- .../Toolbox/resources/qml/ToolboxDownloadsGrid.qml | 3 ++- .../resources/qml/ToolboxDownloadsGridTile.qml | 4 +++- .../resources/qml/ToolboxDownloadsShowcase.qml | 3 ++- .../resources/qml/ToolboxDownloadsShowcaseTile.qml | 3 ++- plugins/Toolbox/resources/qml/ToolboxErrorPage.qml | 3 ++- plugins/Toolbox/resources/qml/ToolboxFooter.qml | 5 +++-- .../Toolbox/resources/qml/ToolboxInstalledPage.qml | 4 +++- .../Toolbox/resources/qml/ToolboxInstalledTile.qml | 6 +++++- .../resources/qml/ToolboxInstalledTileActions.qml | 5 ++++- .../Toolbox/resources/qml/ToolboxLicenseDialog.qml | 3 ++- plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml | 3 ++- plugins/Toolbox/resources/qml/ToolboxTabButton.qml | 5 +++-- 19 files changed, 67 insertions(+), 21 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml index 9c1df0c49e..7b026566c3 100644 --- a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml @@ -1,7 +1,7 @@ // Copyright (c) 2018 Ultimaker B.V. // Toolbox is released under the terms of the LGPLv3 or higher. -import QtQuick 2.3 +import QtQuick 2.10 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM @@ -59,6 +59,7 @@ Item wrapMode: Text.WordWrap width: parent.width height: UM.Theme.getSize("toolbox_property_label").height + renderType: Text.NativeRendering } Label { @@ -70,6 +71,7 @@ Item left: title.left topMargin: UM.Theme.getSize("default_margin").height } + renderType: Text.NativeRendering } Column { @@ -88,12 +90,14 @@ Item text: catalog.i18nc("@label", "Website") + ":" font: UM.Theme.getFont("default") color: UM.Theme.getColor("text_medium") + renderType: Text.NativeRendering } Label { text: catalog.i18nc("@label", "Email") + ":" font: UM.Theme.getFont("default") color: UM.Theme.getColor("text_medium") + renderType: Text.NativeRendering } } Column @@ -122,6 +126,7 @@ Item color: UM.Theme.getColor("text") linkColor: UM.Theme.getColor("text_link") onLinkActivated: Qt.openUrlExternally(link) + renderType: Text.NativeRendering } Label @@ -138,6 +143,7 @@ Item color: UM.Theme.getColor("text") linkColor: UM.Theme.getColor("text_link") onLinkActivated: Qt.openUrlExternally(link) + renderType: Text.NativeRendering } } Rectangle diff --git a/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml b/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml index 8524b7d1e5..edb1967fee 100644 --- a/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml +++ b/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml @@ -1,7 +1,7 @@ // Copyright (c) 2018 Ultimaker B.V. // Toolbox is released under the terms of the LGPLv3 or higher. -import QtQuick 2.2 +import QtQuick 2.10 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM @@ -64,6 +64,7 @@ Item font: UM.Theme.getFont("default_bold") horizontalAlignment: Text.AlignRight width: control.width + renderType: Text.NativeRendering } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml b/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml index d4c0ae14eb..db4e8c628f 100644 --- a/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml +++ b/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml @@ -1,7 +1,7 @@ // Copyright (c) 2018 Ultimaker B.V. // Toolbox is released under the terms of the LGPLv3 or higher. -import QtQuick 2.7 +import QtQuick 2.10 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM @@ -67,6 +67,7 @@ Item wrapMode: Text.WordWrap color: UM.Theme.getColor("text_medium") font: UM.Theme.getFont("medium") + renderType: Text.NativeRendering } TableView @@ -99,6 +100,7 @@ Item text: styleData.value || "" color: UM.Theme.getColor("text") font: UM.Theme.getFont("default_bold") + renderType: Text.NativeRendering } Rectangle { @@ -118,6 +120,7 @@ Item text: styleData.value || "" color: UM.Theme.getColor("text_medium") font: UM.Theme.getFont("default") + renderType: Text.NativeRendering } } itemDelegate: Item @@ -130,6 +133,7 @@ Item text: styleData.value || "" color: UM.Theme.getColor("text_medium") font: UM.Theme.getFont("default") + renderType: Text.NativeRendering } } @@ -144,6 +148,7 @@ Item elide: Text.ElideRight color: UM.Theme.getColor("text_medium") font: UM.Theme.getFont("default") + renderType: Text.NativeRendering } } @@ -232,5 +237,6 @@ Item color: UM.Theme.getColor("text") linkColor: UM.Theme.getColor("text_link") onLinkActivated: Qt.openUrlExternally(link) + renderType: Text.NativeRendering } } diff --git a/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml b/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml index 2c5d08aa72..e238132680 100644 --- a/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml +++ b/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml @@ -1,7 +1,7 @@ // Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.2 +import QtQuick 2.10 import QtQuick.Controls 1.1 import QtQuick.Controls.Styles 1.1 import QtQuick.Layouts 1.1 @@ -66,6 +66,7 @@ UM.Dialog anchors.right: parent.right font: UM.Theme.getFont("default") wrapMode: Text.WordWrap + renderType: Text.NativeRendering } // Buttons diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 9e2e178b71..7983be8aef 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -1,7 +1,7 @@ // Copyright (c) 2018 Ultimaker B.V. // Toolbox is released under the terms of the LGPLv3 or higher. -import QtQuick 2.3 +import QtQuick 2.10 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM @@ -65,6 +65,7 @@ Item wrapMode: Text.WordWrap width: parent.width height: UM.Theme.getSize("toolbox_property_label").height + renderType: Text.NativeRendering } Column @@ -84,24 +85,28 @@ Item text: catalog.i18nc("@label", "Version") + ":" font: UM.Theme.getFont("default") color: UM.Theme.getColor("text_medium") + renderType: Text.NativeRendering } Label { text: catalog.i18nc("@label", "Last updated") + ":" font: UM.Theme.getFont("default") color: UM.Theme.getColor("text_medium") + renderType: Text.NativeRendering } Label { text: catalog.i18nc("@label", "Author") + ":" font: UM.Theme.getFont("default") color: UM.Theme.getColor("text_medium") + renderType: Text.NativeRendering } Label { text: catalog.i18nc("@label", "Downloads") + ":" font: UM.Theme.getFont("default") color: UM.Theme.getColor("text_medium") + renderType: Text.NativeRendering } } Column @@ -121,6 +126,7 @@ Item text: details === null ? "" : (details.version || catalog.i18nc("@label", "Unknown")) font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") + renderType: Text.NativeRendering } Label { @@ -135,6 +141,7 @@ Item } font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") + renderType: Text.NativeRendering } Label { @@ -153,12 +160,14 @@ Item color: UM.Theme.getColor("text") linkColor: UM.Theme.getColor("text_link") onLinkActivated: Qt.openUrlExternally(link) + renderType: Text.NativeRendering } Label { text: details === null ? "" : (details.download_count || catalog.i18nc("@label", "Unknown")) font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") + renderType: Text.NativeRendering } } Rectangle diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml index 1d701543ce..43f97baf3f 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml @@ -1,7 +1,7 @@ // Copyright (c) 2018 Ultimaker B.V. // Toolbox is released under the terms of the LGPLv3 or higher. -import QtQuick 2.7 +import QtQuick 2.10 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM @@ -31,6 +31,7 @@ Item wrapMode: Text.WordWrap color: UM.Theme.getColor("text") font: UM.Theme.getFont("medium_bold") + renderType: Text.NativeRendering } Label { @@ -42,6 +43,7 @@ Item wrapMode: Text.WordWrap color: UM.Theme.getColor("text") font: UM.Theme.getFont("default") + renderType: Text.NativeRendering } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml b/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml index 848acfbf4f..7160dafa2d 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml @@ -1,7 +1,7 @@ // Copyright (c) 2018 Ultimaker B.V. // Toolbox is released under the terms of the LGPLv3 or higher. -import QtQuick 2.7 +import QtQuick 2.10 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM @@ -57,6 +57,8 @@ Column linkColor: UM.Theme.getColor("text_link") visible: loginRequired width: installButton.width + renderType: Text.NativeRendering + MouseArea { anchors.fill: parent diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml index 3e2643938b..8e15882ae1 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml @@ -1,7 +1,7 @@ // Copyright (c) 2018 Ultimaker B.V. // Toolbox is released under the terms of the LGPLv3 or higher. -import QtQuick 2.7 +import QtQuick 2.10 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import QtQuick.Layouts 1.3 @@ -23,6 +23,7 @@ Column width: parent.width color: UM.Theme.getColor("text_medium") font: UM.Theme.getFont("medium") + renderType: Text.NativeRendering } Grid { diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index cee3f0fd20..357e9e9a72 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -1,7 +1,7 @@ // Copyright (c) 2018 Ultimaker B.V. // Toolbox is released under the terms of the LGPLv3 or higher. -import QtQuick 2.3 +import QtQuick 2.10 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import QtQuick.Layouts 1.3 @@ -72,6 +72,7 @@ Item wrapMode: Text.WordWrap color: UM.Theme.getColor("text") font: UM.Theme.getFont("default_bold") + renderType: Text.NativeRendering } Label { @@ -83,6 +84,7 @@ Item wrapMode: Text.WordWrap color: UM.Theme.getColor("text_medium") font: UM.Theme.getFont("default") + renderType: Text.NativeRendering } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml index 9851128076..820b74554a 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml @@ -1,7 +1,7 @@ // Copyright (c) 2018 Ultimaker B.V. // Toolbox is released under the terms of the LGPLv3 or higher. -import QtQuick 2.7 +import QtQuick 2.10 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM @@ -24,6 +24,7 @@ Rectangle width: parent.width color: UM.Theme.getColor("text_medium") font: UM.Theme.getFont("medium") + renderType: Text.NativeRendering } Grid { diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml index 8a2fdc8bc8..d1130cf63f 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml @@ -1,7 +1,7 @@ // Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.7 +import QtQuick 2.10 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import QtGraphicalEffects 1.0 @@ -79,6 +79,7 @@ Rectangle wrapMode: Text.WordWrap color: UM.Theme.getColor("button_text") font: UM.Theme.getFont("medium_bold") + renderType: Text.NativeRendering } } MouseArea diff --git a/plugins/Toolbox/resources/qml/ToolboxErrorPage.qml b/plugins/Toolbox/resources/qml/ToolboxErrorPage.qml index 600ae2b39f..e57e63dbb9 100644 --- a/plugins/Toolbox/resources/qml/ToolboxErrorPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxErrorPage.qml @@ -1,7 +1,7 @@ // Copyright (c) 2018 Ultimaker B.V. // Toolbox is released under the terms of the LGPLv3 or higher. -import QtQuick 2.7 +import QtQuick 2.10 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 @@ -18,5 +18,6 @@ Rectangle { centerIn: parent } + renderType: Text.NativeRendering } } diff --git a/plugins/Toolbox/resources/qml/ToolboxFooter.qml b/plugins/Toolbox/resources/qml/ToolboxFooter.qml index 5c2a6577ad..2d42ca7269 100644 --- a/plugins/Toolbox/resources/qml/ToolboxFooter.qml +++ b/plugins/Toolbox/resources/qml/ToolboxFooter.qml @@ -1,7 +1,7 @@ // Copyright (c) 2018 Ultimaker B.V. // Toolbox is released under the terms of the LGPLv3 or higher. -import QtQuick 2.2 +import QtQuick 2.10 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM @@ -26,7 +26,7 @@ Item right: restartButton.right rightMargin: UM.Theme.getSize("default_margin").width } - + renderType: Text.NativeRendering } Button { @@ -56,6 +56,7 @@ Item text: control.text verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter + renderType: Text.NativeRendering } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml index 3d5cd1c8d4..e1d01db59a 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml @@ -1,7 +1,7 @@ // Copyright (c) 2018 Ultimaker B.V. // Toolbox is released under the terms of the LGPLv3 or higher. -import QtQuick 2.7 +import QtQuick 2.10 import QtQuick.Dialogs 1.1 import QtQuick.Window 2.2 import QtQuick.Controls 1.4 @@ -38,6 +38,7 @@ ScrollView text: catalog.i18nc("@title:tab", "Plugins") color: UM.Theme.getColor("text_medium") font: UM.Theme.getFont("medium") + renderType: Text.NativeRendering } Rectangle { @@ -68,6 +69,7 @@ ScrollView text: catalog.i18nc("@title:tab", "Materials") color: UM.Theme.getColor("text_medium") font: UM.Theme.getFont("medium") + renderType: Text.NativeRendering } Rectangle diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml index b16564fdd2..593e024309 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml @@ -1,7 +1,7 @@ // Copyright (c) 2018 Ultimaker B.V. // Toolbox is released under the terms of the LGPLv3 or higher. -import QtQuick 2.7 +import QtQuick 2.10 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM @@ -51,6 +51,7 @@ Item wrapMode: Text.WordWrap font: UM.Theme.getFont("default_bold") color: pluginInfo.color + renderType: Text.NativeRendering } Label { @@ -60,6 +61,7 @@ Item width: parent.width wrapMode: Text.WordWrap color: pluginInfo.color + renderType: Text.NativeRendering } } Column @@ -88,6 +90,7 @@ Item onLinkActivated: Qt.openUrlExternally("mailto:" + model.author_email + "?Subject=Cura: " + model.name + " Plugin") color: model.enabled ? UM.Theme.getColor("text") : UM.Theme.getColor("lining") linkColor: UM.Theme.getColor("text_link") + renderType: Text.NativeRendering } Label @@ -98,6 +101,7 @@ Item color: UM.Theme.getColor("text") verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignLeft + renderType: Text.NativeRendering } } ToolboxInstalledTileActions diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml index 39528f6437..61af84fbe5 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml @@ -1,7 +1,7 @@ // Copyright (c) 2018 Ultimaker B.V. // Toolbox is released under the terms of the LGPLv3 or higher. -import QtQuick 2.7 +import QtQuick 2.10 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM @@ -24,6 +24,7 @@ Column font: UM.Theme.getFont("default") wrapMode: Text.WordWrap width: parent.width + renderType: Text.NativeRendering } ToolboxProgressButton @@ -55,6 +56,8 @@ Column linkColor: UM.Theme.getColor("text_link") visible: loginRequired width: updateButton.width + renderType: Text.NativeRendering + MouseArea { anchors.fill: parent diff --git a/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml b/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml index b8baf7bc83..40b22c268d 100644 --- a/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml +++ b/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml @@ -1,7 +1,7 @@ // Copyright (c) 2018 Ultimaker B.V. // Toolbox is released under the terms of the LGPLv3 or higher. -import QtQuick 2.2 +import QtQuick 2.10 import QtQuick.Dialogs 1.1 import QtQuick.Window 2.2 import QtQuick.Controls 1.4 @@ -32,6 +32,7 @@ UM.Dialog anchors.right: parent.right text: licenseDialog.pluginName + catalog.i18nc("@label", "This plugin contains a license.\nYou need to accept this license to install this plugin.\nDo you agree with the terms below?") wrapMode: Text.Wrap + renderType: Text.NativeRendering } TextArea { diff --git a/plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml b/plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml index 1ba271dcab..025239bd43 100644 --- a/plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml @@ -1,7 +1,7 @@ // Copyright (c) 2018 Ultimaker B.V. // Toolbox is released under the terms of the LGPLv3 or higher. -import QtQuick 2.7 +import QtQuick 2.10 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 @@ -18,5 +18,6 @@ Rectangle { centerIn: parent } + renderType: Text.NativeRendering } } diff --git a/plugins/Toolbox/resources/qml/ToolboxTabButton.qml b/plugins/Toolbox/resources/qml/ToolboxTabButton.qml index fa4f75d6fe..5e1aeaa636 100644 --- a/plugins/Toolbox/resources/qml/ToolboxTabButton.qml +++ b/plugins/Toolbox/resources/qml/ToolboxTabButton.qml @@ -1,8 +1,8 @@ // Copyright (c) 2018 Ultimaker B.V. // Toolbox is released under the terms of the LGPLv3 or higher. -import QtQuick 2.2 -import QtQuick.Controls 2.0 +import QtQuick 2.10 +import QtQuick.Controls 2.3 import UM 1.1 as UM Button @@ -46,5 +46,6 @@ Button font: control.enabled ? (control.active ? UM.Theme.getFont("medium_bold") : UM.Theme.getFont("medium")) : UM.Theme.getFont("default_italic") verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter + renderType: Text.NativeRendering } } \ No newline at end of file From 69744282e6208ef959035c7237a9685d9d85b819 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 10 Dec 2018 14:37:44 +0100 Subject: [PATCH 0821/1292] Fix rounding issue in toolbox QML widget size CURA-6006 --- plugins/Toolbox/resources/qml/Toolbox.qml | 4 ++-- plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/Toolbox/resources/qml/Toolbox.qml b/plugins/Toolbox/resources/qml/Toolbox.qml index 7cc5a730f2..9ede2a6bda 100644 --- a/plugins/Toolbox/resources/qml/Toolbox.qml +++ b/plugins/Toolbox/resources/qml/Toolbox.qml @@ -14,8 +14,8 @@ Window modality: Qt.ApplicationModal flags: Qt.Dialog | Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowCloseButtonHint - width: 720 * screenScaleFactor - height: 640 * screenScaleFactor + width: Math.floor(720 * screenScaleFactor) + height: Math.floor(640 * screenScaleFactor) minimumWidth: width maximumWidth: minimumWidth minimumHeight: height diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml index 8e15882ae1..85f0ff8be4 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml @@ -38,7 +38,7 @@ Column delegate: Loader { asynchronous: true - width: (grid.width - (grid.columns - 1) * grid.columnSpacing) / grid.columns + width: Math.round((grid.width - (grid.columns - 1) * grid.columnSpacing) / grid.columns) height: UM.Theme.getSize("toolbox_thumbnail_small").height source: "ToolboxDownloadsGridTile.qml" } From df0ae20ddedf42040dee95243a5a236a0a65afea Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 10 Dec 2018 14:39:15 +0100 Subject: [PATCH 0822/1292] Let's just get stepped up in here and get some personal space Contributes to CL-1152 --- .../resources/qml/MonitorConfigOverrideDialog.qml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml index 14bdd07313..a283824bcf 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml @@ -48,7 +48,8 @@ UM.Dialog anchors { fill: parent - margins: 60 * screenScaleFactor // TODO: Theme! + margins: 36 * screenScaleFactor // TODO: Theme! + bottomMargin: 56 * screenScaleFactor // TODO: Theme! } wrapMode: Text.WordWrap text: @@ -62,7 +63,7 @@ UM.Dialog { topLine = catalog.i18nc("@label", "The printer %1 is assigned, but the job contains an unknown material configuration.").arg(printer.name) } - var result = "

    " + topLine +"

    " + var result = "

    " + topLine +"

    \n\n" for (var i = 0; i < printer.activePrintJob.configurationChanges.length; i++) { var change = printer.activePrintJob.configurationChanges[i] From 590e8f5eb19cff433d1d5e1926dd4bcb89f4ea76 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 10 Dec 2018 14:41:15 +0100 Subject: [PATCH 0823/1292] Wrap the disabled text in case it's too long. Contributes to CURA-5941. --- resources/qml/ExpandableComponent.qml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index 55271d99c3..74adec5bc6 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -106,13 +106,15 @@ Item { id: disabledLabel visible: !base.enabled + anchors.fill: parent leftPadding: background.padding + rightPadding: background.padding text: "This component is disabled" font: UM.Theme.getFont("default") renderType: Text.NativeRendering verticalAlignment: Text.AlignVCenter color: UM.Theme.getColor("text") - height: parent.height + wrapMode: Text.WordWrap } Item From d482924ea299eed06939564483fd00789e9b9da6 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 10 Dec 2018 14:43:02 +0100 Subject: [PATCH 0824/1292] STAR-322: First tests for cloud output device --- .../src/Cloud/CloudApiClient.py | 7 +- .../src/Cloud/CloudOutputDevice.py | 7 +- .../CloudClusterPrinterConfiguration.py | 3 - .../Fixtures/getClusterStatusResponse.json | 184 +++++++++--------- .../tests/Cloud/NetworkManagerMock.py | 30 +-- .../tests/Cloud/TestCloudOutputDevice.py | 73 +++++++ .../Cloud/TestCloudOutputDeviceManager.py | 14 +- plugins/UM3NetworkPrinting/tests/conftest.py | 11 +- 8 files changed, 191 insertions(+), 138 deletions(-) create mode 100644 plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py index b4c8774140..b3abc74ff4 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py @@ -36,6 +36,11 @@ class CloudApiClient(NetworkClient): self._account = account self._on_error = on_error + ## Gets the account used for the API. + @property + def account(self) -> Account: + return self._account + ## Retrieves all the clusters for the user that is currently logged in. # \param on_finished: The function to be called after the result is parsed. def getClusters(self, on_finished: Callable[[List[CloudCluster]], any]) -> None: @@ -46,7 +51,7 @@ class CloudApiClient(NetworkClient): # \param cluster_id: The ID of the cluster. # \param on_finished: The function to be called after the result is parsed. def getClusterStatus(self, cluster_id: str, on_finished: Callable[[CloudClusterStatus], any]) -> None: - url = "{}/cluster/{}/status".format(self.CLUSTER_API_ROOT, cluster_id) + url = "{}/clusters/{}/status".format(self.CLUSTER_API_ROOT, cluster_id) self.get(url, on_finished=self._wrapCallback(on_finished, CloudClusterStatus)) ## Requests the cloud to register the upload of a print job mesh. diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 2800bc1c8c..a137e5261f 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -13,7 +13,6 @@ from UM.Logger import Logger from UM.Message import Message from UM.Qt.Duration import Duration, DurationFormat from UM.Scene.SceneNode import SceneNode -from cura.CuraApplication import CuraApplication from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState, NetworkedPrinterOutputDevice from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputController import CloudOutputController @@ -93,7 +92,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self._setInterfaceElements() self._device_id = device_id - self._account = CuraApplication.getInstance().getCuraAPI().account + self._account = api_client.account # We use the Cura Connect monitor tab to get most functionality right away. self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), @@ -174,10 +173,6 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ) self._api.requestUpload(request, lambda response: self._onPrintJobCreated(mesh_bytes, response)) - ## Called when the connection to the cluster changes. - def connect(self) -> None: - super().connect() - ## Called when the network data should be updated. def _update(self) -> None: super()._update() diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py index aa382136d0..c14a7f85c3 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py @@ -1,8 +1,5 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import List, Optional - -from cura.PrinterOutput.ConfigurationModel import ConfigurationModel from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel from cura.PrinterOutput.ExtruderOutputModel import ExtruderOutputModel from .CloudClusterPrinterConfigurationMaterial import CloudClusterPrinterConfigurationMaterial diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/getClusterStatusResponse.json b/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/getClusterStatusResponse.json index 711e429a72..4f9f47fc75 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/getClusterStatusResponse.json +++ b/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/getClusterStatusResponse.json @@ -1,97 +1,95 @@ { - "data": [ - { - "generated_time": "2018-12-10T08:23:55.110Z", - "printers": [ - { - "configuration": [ - { - "extruder_index": 0, - "material": { - "material": "empty" - }, - "print_core_id": "AA 0.4" + "data": { + "generated_time": "2018-12-10T08:23:55.110Z", + "printers": [ + { + "configuration": [ + { + "extruder_index": 0, + "material": { + "material": "empty" }, - { - "extruder_index": 1, - "material": { - "material": "empty" - }, - "print_core_id": "AA 0.4" - } - ], - "enabled": true, - "firmware_version": "5.1.2.20180807", - "friendly_name": "Master-Luke", - "ip_address": "10.183.1.140", - "machine_variant": "Ultimaker 3", - "status": "maintenance", - "unique_name": "ultimakersystem-ccbdd30044ec", - "uuid": "b3a47ea3-1eeb-4323-9626-6f9c3c888f9e" - }, - { - "configuration": [ - { - "extruder_index": 0, - "material": { - "brand": "Generic", - "color": "Generic", - "guid": "506c9f0d-e3aa-4bd4-b2d2-23e2425b1aa9", - "material": "PLA" - }, - "print_core_id": "AA 0.4" + "print_core_id": "AA 0.4" + }, + { + "extruder_index": 1, + "material": { + "material": "empty" }, - { - "extruder_index": 1, - "material": { - "brand": "Ultimaker", - "color": "Red", - "guid": "9cfe5bf1-bdc5-4beb-871a-52c70777842d", - "material": "PLA" - }, - "print_core_id": "AA 0.4" - } - ], - "enabled": true, - "firmware_version": "4.3.3.20180529", - "friendly_name": "UM-Marijn", - "ip_address": "10.183.1.166", - "machine_variant": "Ultimaker 3", - "status": "idle", - "unique_name": "ultimakersystem-ccbdd30058ab", - "uuid": "6e62c40a-4601-4b0e-9fec-c7c02c59c30a" - } - ], - "print_jobs": [ - { - "assigned_to": "6e62c40a-4601-4b0e-9fec-c7c02c59c30a", - "configuration": [ - { - "extruder_index": 0, - "material": { - "brand": "Ultimaker", - "color": "Black", - "guid": "3ee70a86-77d8-4b87-8005-e4a1bc57d2ce", - "material": "PLA" - }, - "print_core_id": "AA 0.4" - } - ], - "constraints": {}, - "created_at": "2018-12-10T08:28:04.108Z", - "force": false, - "last_seen": 500165.109491861, - "machine_variant": "Ultimaker 3", - "name": "UM3_dragon", - "network_error_count": 0, - "owner": "Daniel Testing", - "started": false, - "status": "queued", - "time_elapsed": 0, - "time_total": 14145, - "uuid": "d1c8bd52-5e9f-486a-8c25-a123cc8c7702" - } - ] - } - ] + "print_core_id": "AA 0.4" + } + ], + "enabled": true, + "firmware_version": "5.1.2.20180807", + "friendly_name": "Master-Luke", + "ip_address": "10.183.1.140", + "machine_variant": "Ultimaker 3", + "status": "maintenance", + "unique_name": "ultimakersystem-ccbdd30044ec", + "uuid": "b3a47ea3-1eeb-4323-9626-6f9c3c888f9e" + }, + { + "configuration": [ + { + "extruder_index": 0, + "material": { + "brand": "Generic", + "color": "Generic", + "guid": "506c9f0d-e3aa-4bd4-b2d2-23e2425b1aa9", + "material": "PLA" + }, + "print_core_id": "AA 0.4" + }, + { + "extruder_index": 1, + "material": { + "brand": "Ultimaker", + "color": "Red", + "guid": "9cfe5bf1-bdc5-4beb-871a-52c70777842d", + "material": "PLA" + }, + "print_core_id": "AA 0.4" + } + ], + "enabled": true, + "firmware_version": "4.3.3.20180529", + "friendly_name": "UM-Marijn", + "ip_address": "10.183.1.166", + "machine_variant": "Ultimaker 3", + "status": "idle", + "unique_name": "ultimakersystem-ccbdd30058ab", + "uuid": "6e62c40a-4601-4b0e-9fec-c7c02c59c30a" + } + ], + "print_jobs": [ + { + "assigned_to": "6e62c40a-4601-4b0e-9fec-c7c02c59c30a", + "configuration": [ + { + "extruder_index": 0, + "material": { + "brand": "Ultimaker", + "color": "Black", + "guid": "3ee70a86-77d8-4b87-8005-e4a1bc57d2ce", + "material": "PLA" + }, + "print_core_id": "AA 0.4" + } + ], + "constraints": {}, + "created_at": "2018-12-10T08:28:04.108Z", + "force": false, + "last_seen": 500165.109491861, + "machine_variant": "Ultimaker 3", + "name": "UM3_dragon", + "network_error_count": 0, + "owner": "Daniel Testing", + "started": false, + "status": "queued", + "time_elapsed": 0, + "time_total": 14145, + "uuid": "d1c8bd52-5e9f-486a-8c25-a123cc8c7702" + } + ] + } } diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py b/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py index e8e4fc8de7..c7dc1bac35 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py @@ -1,8 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import json -import os -from typing import Dict, Tuple, Optional +from typing import Dict, Tuple, Union from unittest.mock import MagicMock from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkReply @@ -52,38 +51,15 @@ class NetworkManagerMock: # \param url: The URL being requested. # \param status_code: The HTTP status code for the response. # \param response: The response body from the server (generally json-encoded). - def prepareReply(self, method: str, url: str, status_code: int, response: bytes) -> None: + def prepareReply(self, method: str, url: str, status_code: int, response: Union[bytes, dict]) -> None: reply_mock = MagicMock() reply_mock.url().toString.return_value = url reply_mock.operation.return_value = self._OPERATIONS[method] reply_mock.attribute.return_value = status_code - reply_mock.readAll.return_value = response + reply_mock.readAll.return_value = response if isinstance(response, bytes) else json.dumps(response).encode() self.replies[method, url] = reply_mock Logger.log("i", "Prepared mock {}-response to {} {}", status_code, method, url) - ## Prepares a reply for the API call to get clusters. - # \param data: The data the server should return. If not given, a default response will be used. - # \return The data in the response. - def prepareGetClusters(self, data: Optional[dict] = None) -> dict: - data, response = self._getResponseData("clusters", data) - status_code = 200 if "data" in data else int(data["errors"][0]["http_status"]) - self.prepareReply("GET", "https://api-staging.ultimaker.com/connect/v1/clusters", status_code, response) - return data - - ## Gets the data that should be in the server's response in both dictionary and JSON-encoded bytes format. - # \param fixture_name: The name of the fixture. - # \param data: The data that should be returned (optional) - # \return The server's response in both dictionary and JSON-encoded bytes format. - @staticmethod - def _getResponseData(fixture_name: str, data: Optional[dict] = None) -> Tuple[dict, bytes]: - if data is None: - with open("{}/Fixtures/{}.json".format(os.path.dirname(__file__), fixture_name), "rb") as f: - response = f.read() - data = json.loads(response.decode()) - else: - response = json.dumps(data).encode() - return data, response - ## Emits the signal that the reply is ready to all prepared replies. def flushReplies(self): for reply in self.replies.values(): diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py new file mode 100644 index 0000000000..4ed2767288 --- /dev/null +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py @@ -0,0 +1,73 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +import json +import os +from unittest import TestCase +from unittest.mock import patch, MagicMock + +from cura.CuraApplication import CuraApplication +from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel +from src.Cloud.CloudApiClient import CloudApiClient +from src.Cloud.CloudOutputController import CloudOutputController +from src.Cloud.CloudOutputDevice import CloudOutputDevice +from .NetworkManagerMock import NetworkManagerMock + + +@patch("cura.NetworkClient.QNetworkAccessManager") +class TestCloudOutputDevice(TestCase): + CLUSTER_ID = "RIZ6cZbWA_Ua7RZVJhrdVfVpf0z-MqaSHQE4v8aRTtYq" + HOST_NAME = "ultimakersystem-ccbdd30044ec" + URL = "https://api-staging.ultimaker.com/connect/v1/clusters/{}/status".format(CLUSTER_ID) + with open("{}/Fixtures/getClusterStatusResponse.json".format(os.path.dirname(__file__)), "rb") as f: + DEFAULT_RESPONSE = f.read() + + def setUp(self): + super().setUp() + self.app = CuraApplication.getInstance() + self.network = NetworkManagerMock() + self.account = MagicMock(isLoggedIn=True, accessToken="TestAccessToken") + self.onError = MagicMock() + self.device = CloudOutputDevice(CloudApiClient(self.account, self.onError), self.CLUSTER_ID, self.HOST_NAME) + self.cluster_status = json.loads(self.DEFAULT_RESPONSE.decode()) + self.network.prepareReply("GET", self.URL, 200, self.DEFAULT_RESPONSE) + + def tearDown(self): + try: + self._beforeTearDown() + finally: + super().tearDown() + + ## Before tear down method we check whether the state of the output device manager is what we expect based on the + # mocked API response. + def _beforeTearDown(self): + # let the network send replies + self.network.flushReplies() + # TODO + + def test_status(self, network_mock): + network_mock.return_value = self.network + self.device._update() + self.network.flushReplies() + + self.assertEqual([PrinterOutputModel, PrinterOutputModel], [type(printer) for printer in self.device.printers]) + + controller_fields = { + "_output_device": self.device, + "can_abort": False, + "can_control_manually": False, + "can_pause": False, + "can_pre_heat_bed": False, + "can_pre_heat_hotends": False, + "can_send_raw_gcode": False, + "can_update_firmware": False, + } + + self.assertEqual({printer["uuid"] for printer in self.cluster_status["data"]["printers"]}, + {printer.key for printer in self.device.printers}) + self.assertEqual([controller_fields, controller_fields], + [printer.getController().__dict__ for printer in self.device.printers]) + + self.assertEqual({job["uuid"] for job in self.cluster_status["data"]["print_jobs"]}, + {job.key for job in self.device.printJobs}) + self.assertEqual(["Daniel Testing"], [job.owner for job in self.device.printJobs]) + self.assertEqual(["UM3_dragon"], [job.name for job in self.device.printJobs]) diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py index 799e715f0d..9e980a8681 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py @@ -1,5 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +import json +import os from unittest import TestCase from unittest.mock import patch @@ -11,13 +13,17 @@ from .NetworkManagerMock import NetworkManagerMock @patch("cura.NetworkClient.QNetworkAccessManager") class TestCloudOutputDeviceManager(TestCase): + URL = "https://api-staging.ultimaker.com/connect/v1/clusters" + with open("{}/Fixtures/clusters.json".format(os.path.dirname(__file__)), "rb") as f: + DEFAULT_RESPONSE = f.read() def setUp(self): super().setUp() self.app = CuraApplication.getInstance() self.network = NetworkManagerMock() self.manager = CloudOutputDeviceManager() - self.clusters_response = self.network.prepareGetClusters() + self.clusters_response = json.loads(self.DEFAULT_RESPONSE.decode()) + self.network.prepareReply("GET", self.URL, 200, self.DEFAULT_RESPONSE) def tearDown(self): try: @@ -58,7 +64,7 @@ class TestCloudOutputDeviceManager(TestCase): # update the cluster from member variable, which is checked at tearDown self.clusters_response["data"][0]["host_name"] = "New host name" - self.network.prepareGetClusters(self.clusters_response) + self.network.prepareReply("GET", self.URL, 200, self.clusters_response) self.manager._update_timer.timeout.emit() @@ -67,7 +73,7 @@ class TestCloudOutputDeviceManager(TestCase): # delete the cluster from member variable, which is checked at tearDown del self.clusters_response["data"][1] - self.network.prepareGetClusters(self.clusters_response) + self.network.prepareReply("GET", self.URL, 200, self.clusters_response) self.manager._update_timer.timeout.emit() @@ -104,7 +110,7 @@ class TestCloudOutputDeviceManager(TestCase): @patch("UM.Message.Message.show") def test_api_error(self, message_mock, network_mock): self.clusters_response = {"errors": [{"id": "notFound", "title": "Not found!", "http_status": "404"}]} - self.network.prepareGetClusters(self.clusters_response) + self.network.prepareReply("GET", self.URL, 200, self.clusters_response) self._loadData(network_mock) self.network.flushReplies() message_mock.assert_called_once_with() diff --git a/plugins/UM3NetworkPrinting/tests/conftest.py b/plugins/UM3NetworkPrinting/tests/conftest.py index 6f245f8f2f..ce49bd3cb7 100644 --- a/plugins/UM3NetworkPrinting/tests/conftest.py +++ b/plugins/UM3NetworkPrinting/tests/conftest.py @@ -1,13 +1,11 @@ # Copyright (c) 2018 Ultimaker B.V. -# Uranium is released under the terms of the LGPLv3 or higher. +# Cura is released under the terms of the LGPLv3 or higher. import pytest -import Arcus #Prevents error: "PyCapsule_GetPointer called with incorrect name" with conflicting SIP configurations between Arcus and PyQt: Import Arcus first! -from UM.Qt.QtApplication import QtApplication # QT application import is required, even though it isn't used. -from UM.Application import Application from UM.Signal import Signal from cura.CuraApplication import CuraApplication +from cura.Machines.MaterialManager import MaterialManager # This mock application must extend from Application and not QtApplication otherwise some QObjects are created and @@ -18,6 +16,11 @@ class FixtureApplication(CuraApplication): super().initialize() Signal._signalQueue = self + self.getPreferences().addPreference("cura/favorite_materials", "") + + self._material_manager = MaterialManager(self._container_registry, parent = self) + self._material_manager.initialize() + def functionEvent(self, event): event.call() From aa376e60da409e87f49150900570cb957dbfd610 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 10 Dec 2018 14:45:11 +0100 Subject: [PATCH 0825/1292] Make the disabled text translatable Contributes to CURA-5941. --- resources/qml/ExpandableComponent.qml | 2 +- resources/qml/ExpandableComponentHeader.qml | 2 +- resources/qml/ExpandablePopup.qml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index 74adec5bc6..c2b9d715d5 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -109,7 +109,7 @@ Item anchors.fill: parent leftPadding: background.padding rightPadding: background.padding - text: "This component is disabled" + text: catalog.i18nc("@label default disabled text", "This component is disabled") font: UM.Theme.getFont("default") renderType: Text.NativeRendering verticalAlignment: Text.AlignVCenter diff --git a/resources/qml/ExpandableComponentHeader.qml b/resources/qml/ExpandableComponentHeader.qml index b1fd49cd1b..09ea262c82 100644 --- a/resources/qml/ExpandableComponentHeader.qml +++ b/resources/qml/ExpandableComponentHeader.qml @@ -24,7 +24,7 @@ Cura.RoundedRectangle Label { id: headerLabel - text: "Title" + text: "" font: UM.Theme.getFont("default") renderType: Text.NativeRendering verticalAlignment: Text.AlignVCenter diff --git a/resources/qml/ExpandablePopup.qml b/resources/qml/ExpandablePopup.qml index 75f718abf5..2d34b134e0 100644 --- a/resources/qml/ExpandablePopup.qml +++ b/resources/qml/ExpandablePopup.qml @@ -113,7 +113,7 @@ Item id: disabledLabel visible: !base.enabled leftPadding: background.padding - text: "This component is disabled" + text: catalog.i18nc("@label default disabled text", "This component is disabled") font: UM.Theme.getFont("default") renderType: Text.NativeRendering verticalAlignment: Text.AlignVCenter From 2db5d2b23128be682e97ff34f5bbcf67aef1ccca Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 10 Dec 2018 14:54:45 +0100 Subject: [PATCH 0826/1292] Add support for translation plurals Contributes to CL-1152 --- .../resources/qml/MonitorConfigOverrideDialog.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml index a283824bcf..127078d460 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml @@ -57,7 +57,7 @@ UM.Dialog var topLine if (materialsAreKnown(printer.activePrintJob)) { - topLine = catalog.i18nc("@label", "The assigned printer, %1, requires the following configuration change(s):").arg(printer.name) + topLine = catalog.i18ncp("@label", "The assigned printer, %1, requires the following configuration change:", "The assigned printer, %1, requires the following configuration changes:").arg(printer.name) } else { From 32f2b7ec1f293c4dde0b6575aa469e3d1c40aa8c Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 10 Dec 2018 15:05:01 +0100 Subject: [PATCH 0827/1292] Fix some warnings Contributes to CL-1152 --- .../resources/qml/MonitorConfigOverrideDialog.qml | 4 ++++ .../resources/qml/MonitorPrintJobPreview.qml | 4 ++++ .../resources/qml/MonitorPrintJobProgressBar.qml | 2 +- .../UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml | 2 +- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml index 127078d460..cf8326a504 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml @@ -54,6 +54,10 @@ UM.Dialog wrapMode: Text.WordWrap text: { + if (!printer.activePrintJob) + { + return "" + } var topLine if (materialsAreKnown(printer.activePrintJob)) { diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml index 5acd350abb..2f17db0c65 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml @@ -60,6 +60,10 @@ Item height: 0.5 * printJobPreview.height source: { + if (!printJob) + { + return "" + } if (printJob.configurationChanges.length > 0) { return "../svg/warning-icon.svg" diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml index e646172a6c..cfb7aba84d 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml @@ -55,7 +55,7 @@ Item left: progressBar.right leftMargin: 18 * screenScaleFactor // TODO: Theme! } - text: Math.round(printJob.progress * 100) + "%" + text: printJob ? Math.round(printJob.progress * 100) + "%" : "0%" color: printJob && printJob.isActive ? "#374355" : "#babac1" // TODO: Theme! width: contentWidth font: UM.Theme.getFont("medium") // 14pt, regular diff --git a/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml b/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml index 02a8e7ae69..1edbf9f6a2 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml @@ -182,7 +182,7 @@ Item { abortConfirmationDialog.visible = true; popup.close(); } - text: printJob.state == "aborting" ? catalog.i18nc("@label", "Aborting...") : catalog.i18nc("@label", "Abort"); + text: printJob && printJob.state == "aborting" ? catalog.i18nc("@label", "Aborting...") : catalog.i18nc("@label", "Abort"); visible: { if (!printJob) { return false; From 028d993babdff046b9404a84271b07b00e426fef Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 10 Dec 2018 15:27:51 +0100 Subject: [PATCH 0828/1292] Format .gcode.gz files too Contributes to CL-1152 --- .../resources/qml/MonitorConfigOverrideDialog.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml index cf8326a504..df3c99e0a1 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml @@ -96,7 +96,7 @@ UM.Dialog } // Utils function formatPrintJobName(name) { - var extensions = [ ".gz", ".gcode", ".ufp" ]; + var extensions = [ ".gz", ".gcode", ".gcode.gz", ".ufp" ]; for (var i = 0; i < extensions.length; i++) { var extension = extensions[i]; if (name.slice(-extension.length) === extension) { From d495ec18bb7ab42de07bfb3617c00e7598a20e9e Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 10 Dec 2018 15:28:20 +0100 Subject: [PATCH 0829/1292] Filter a bit more intelligently on when to check for errors CURA-6016 --- cura/Machines/MachineErrorChecker.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/cura/Machines/MachineErrorChecker.py b/cura/Machines/MachineErrorChecker.py index 06f064315b..fb11123af6 100644 --- a/cura/Machines/MachineErrorChecker.py +++ b/cura/Machines/MachineErrorChecker.py @@ -64,21 +64,21 @@ class MachineErrorChecker(QObject): def _onMachineChanged(self) -> None: if self._global_stack: - self._global_stack.propertyChanged.disconnect(self.startErrorCheck) + self._global_stack.propertyChanged.disconnect(self.startErrorCheckPropertyChanged) self._global_stack.containersChanged.disconnect(self.startErrorCheck) for extruder in self._global_stack.extruders.values(): - extruder.propertyChanged.disconnect(self.startErrorCheck) + extruder.propertyChanged.disconnect(self.startErrorCheckPropertyChanged) extruder.containersChanged.disconnect(self.startErrorCheck) self._global_stack = self._machine_manager.activeMachine if self._global_stack: - self._global_stack.propertyChanged.connect(self.startErrorCheck) + self._global_stack.propertyChanged.connect(self.startErrorCheckPropertyChanged) self._global_stack.containersChanged.connect(self.startErrorCheck) for extruder in self._global_stack.extruders.values(): - extruder.propertyChanged.connect(self.startErrorCheck) + extruder.propertyChanged.connect(self.startErrorCheckPropertyChanged) extruder.containersChanged.connect(self.startErrorCheck) hasErrorUpdated = pyqtSignal() @@ -93,6 +93,13 @@ class MachineErrorChecker(QObject): def needToWaitForResult(self) -> bool: return self._need_to_check or self._check_in_progress + # Start the error check for property changed + # this is seperate from the startErrorCheck because it ignores a number property types + def startErrorCheckPropertyChanged(self, key, property_name): + if property_name != "value": + return + self.startErrorCheck() + # Starts the error check timer to schedule a new error check. def startErrorCheck(self, *args) -> None: if not self._check_in_progress: From 04af8fbd5018d7bfdf488ddd98b1d4ccabab1bfb Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 10 Dec 2018 15:33:16 +0100 Subject: [PATCH 0830/1292] Update MonitorConfigOverrideDialog.qml Contributes to CL-1152 --- .../resources/qml/MonitorConfigOverrideDialog.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml index df3c99e0a1..7f7dc24350 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml @@ -96,7 +96,7 @@ UM.Dialog } // Utils function formatPrintJobName(name) { - var extensions = [ ".gz", ".gcode", ".gcode.gz", ".ufp" ]; + var extensions = [ ".gcode.gz", ".gz", ".gcode", ".ufp" ]; for (var i = 0; i < extensions.length; i++) { var extension = extensions[i]; if (name.slice(-extension.length) === extension) { From 1cd0d26db420af72d92c5b2538caa93a44495dcb Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 10 Dec 2018 15:34:48 +0100 Subject: [PATCH 0831/1292] Change margins Instead of using multiplications and divisions, just use the corresponding margins. Contributes to CURA-5876. --- resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml | 2 +- .../qml/Menus/ConfigurationMenu/ConfigurationListView.qml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 05cac16e29..728a0cbe9a 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -29,7 +29,7 @@ Button id: contentColumn width: parent.width padding: UM.Theme.getSize("wide_margin").width - spacing: Math.round(UM.Theme.getSize("default_margin").height / 2) + spacing: UM.Theme.getSize("narrow_margin").height Row { diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index 53969a0370..3cc0754284 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -12,7 +12,7 @@ Column id: base property var outputDevice: null height: childrenRect.height + 2 * padding - spacing: Math.round(UM.Theme.getSize("default_margin").height / 2) + spacing: UM.Theme.getSize("narrow_margin").height function forceModelUpdate() { @@ -55,7 +55,7 @@ Column ListView { id: configurationList - spacing: Math.round(UM.Theme.getSize("default_margin").height / 2) + spacing: UM.Theme.getSize("narrow_margin").height width: container.width - ((height > container.maximumHeight) ? container.ScrollBar.vertical.background.width : 0) //Make room for scroll bar if there is any. contentHeight: childrenRect.height height: childrenRect.height @@ -64,7 +64,7 @@ Column section.criteria: ViewSection.FullString section.delegate: Item { - height: printerTypeLabel.height + UM.Theme.getSize("default_margin").height * 2 //Causes a default margin above the label and a default margin below the label. + height: printerTypeLabel.height + UM.Theme.getSize("wide_margin").height //Causes a default margin above the label and a default margin below the label. Cura.PrinterTypeLabel { id: printerTypeLabel From 11d8831d7a9a15e3e916d5d9762bfe1f755042e5 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 10 Dec 2018 15:40:18 +0100 Subject: [PATCH 0832/1292] Use the capitalized version of the buildplate name --- cura/PrinterOutput/ConfigurationModel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/PrinterOutput/ConfigurationModel.py b/cura/PrinterOutput/ConfigurationModel.py index 89e609c913..6f55aa3b1f 100644 --- a/cura/PrinterOutput/ConfigurationModel.py +++ b/cura/PrinterOutput/ConfigurationModel.py @@ -44,7 +44,7 @@ class ConfigurationModel(QObject): @pyqtProperty(str, fset = setBuildplateConfiguration, notify = configurationChanged) def buildplateConfiguration(self) -> str: - return self._buildplate_configuration + return self._buildplate_configuration.capitalize() ## This method is intended to indicate whether the configuration is valid or not. # The method checks if the mandatory fields are or not set From 0e19fa731f8bc391c3b17ab33db0197410633ef0 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 10 Dec 2018 15:47:45 +0100 Subject: [PATCH 0833/1292] Codestyle Contributes to CL-1152 --- .../qml/MonitorConfigOverrideDialog.qml | 51 +++++++++++-------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml index 7f7dc24350..1b9a03ea99 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml @@ -95,39 +95,46 @@ UM.Dialog } } // Utils - function formatPrintJobName(name) { - var extensions = [ ".gcode.gz", ".gz", ".gcode", ".ufp" ]; - for (var i = 0; i < extensions.length; i++) { - var extension = extensions[i]; - if (name.slice(-extension.length) === extension) { - name = name.substring(0, name.length - extension.length); + function formatPrintJobName(name) + { + var extensions = [ ".gcode.gz", ".gz", ".gcode", ".ufp" ] + for (var i = 0; i < extensions.length; i++) + { + var extension = extensions[i] + if (name.slice(-extension.length) === extension) + { + name = name.substring(0, name.length - extension.length) } } return name; } - function materialsAreKnown(job) { - var conf0 = job.configuration[0]; - if (conf0 && !conf0.material.material) { - return false; + function materialsAreKnown(job) + { + var conf0 = job.configuration[0] + if (conf0 && !conf0.material.material) + { + return false } - var conf1 = job.configuration[1]; - if (conf1 && !conf1.material.material) { - return false; + var conf1 = job.configuration[1] + if (conf1 && !conf1.material.material) + { + return false } - return true; + return true } - function formatBuildPlateType(buildPlateType) { - var translationText = ""; + function formatBuildPlateType(buildPlateType) + { + var translationText = "" switch (buildPlateType) { case "glass": - translationText = catalog.i18nc("@label", "Glass"); - break; + translationText = catalog.i18nc("@label", "Glass") + break case "aluminum": - translationText = catalog.i18nc("@label", "Aluminum"); - break; + translationText = catalog.i18nc("@label", "Aluminum") + break default: - translationText = null; + translationText = null } - return translationText; + return translationText } } \ No newline at end of file From 4fc4aecf17e33da689463c0d899f36a564fe2f83 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 10 Dec 2018 15:48:59 +0100 Subject: [PATCH 0834/1292] Avoid the overlapping of text when the name is too long Normally I happens in other languages other than English. --- resources/qml/ViewsSelector.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/qml/ViewsSelector.qml b/resources/qml/ViewsSelector.qml index ed0b694aed..f2906f9d4c 100644 --- a/resources/qml/ViewsSelector.qml +++ b/resources/qml/ViewsSelector.qml @@ -60,6 +60,7 @@ Cura.ExpandablePopup { left: title.right leftMargin: UM.Theme.getSize("default_margin").width + right: parent.right } height: parent.height elide: Text.ElideRight From bfd236dae417815c3f1308465f4587cf270ea449 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 10 Dec 2018 16:11:43 +0100 Subject: [PATCH 0835/1292] STAR-322: Testing cloud printing --- .../src/Cloud/CloudApiClient.py | 2 +- .../src/Cloud/CloudOutputDevice.py | 2 +- .../tests/Cloud/Fixtures/__init__.py | 12 +++ .../{clusters.json => getClusters.json} | 0 .../Cloud/Fixtures/postJobPrintResponse.json | 7 ++ .../Cloud/Fixtures/putJobUploadResponse.json | 10 ++ .../tests/Cloud/NetworkManagerMock.py | 33 +++++-- .../tests/Cloud/TestCloudOutputDevice.py | 91 +++++++++++++++---- .../Cloud/TestCloudOutputDeviceManager.py | 9 +- 9 files changed, 129 insertions(+), 37 deletions(-) create mode 100644 plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/__init__.py rename plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/{clusters.json => getClusters.json} (100%) create mode 100644 plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/postJobPrintResponse.json create mode 100644 plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/putJobUploadResponse.json diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py index b3abc74ff4..448aa4d2e7 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py @@ -92,7 +92,7 @@ class CloudApiClient(NetworkClient): # \param job_id: The ID of the print job. # \param on_finished: The function to be called after the result is parsed. def requestPrint(self, cluster_id: str, job_id: str, on_finished: Callable[[CloudPrintResponse], any]) -> None: - url = "{}/cluster/{}/print/{}".format(self.CLUSTER_API_ROOT, cluster_id, job_id) + url = "{}/clusters/{}/print/{}".format(self.CLUSTER_API_ROOT, cluster_id, job_id) self.post(url, data = "", on_finished=self._wrapCallback(on_finished, CloudPrintResponse)) ## We override _createEmptyRequest in order to add the user credentials. diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index a137e5261f..17acbe2e3f 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -217,7 +217,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): printer.updateOutputModel(model) # Always have an active printer - if not self._active_printer: + if self._printers and not self._active_printer: self.setActivePrinter(self._printers[0]) self.printersChanged.emit() # TODO: Make this more efficient by not updating every request diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/__init__.py b/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/__init__.py new file mode 100644 index 0000000000..777afc92c2 --- /dev/null +++ b/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/__init__.py @@ -0,0 +1,12 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +import json +import os + + +def readFixture(fixture_name: str) -> bytes: + with open("{}/{}.json".format(os.path.dirname(__file__), fixture_name), "rb") as f: + return f.read() + +def parseFixture(fixture_name: str) -> dict: + return json.loads(readFixture(fixture_name).decode()) diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/clusters.json b/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/getClusters.json similarity index 100% rename from plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/clusters.json rename to plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/getClusters.json diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/postJobPrintResponse.json b/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/postJobPrintResponse.json new file mode 100644 index 0000000000..8b9574359f --- /dev/null +++ b/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/postJobPrintResponse.json @@ -0,0 +1,7 @@ +{ + "data": { + "cluster_job_id": "9a59d8e9-91d3-4ff6-b4cb-9db91c4094dd", + "job_id": "ABCDefGHIjKlMNOpQrSTUvYxWZ0-1234567890abcDE=", + "status": "queued" + } +} diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/putJobUploadResponse.json b/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/putJobUploadResponse.json new file mode 100644 index 0000000000..0474862720 --- /dev/null +++ b/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/putJobUploadResponse.json @@ -0,0 +1,10 @@ +{ + "data": { + "content_type": "text/plain", + "download_url": "https://api.ultimaker.com/print-job-download", + "job_id": "ABCDefGHIjKlMNOpQrSTUvYxWZ0-1234567890abcDE=", + "job_name": "Ultimaker Robot v3.0", + "status": "queued", + "upload_url": "https://api.ultimaker.com/print-job-upload" + } +} diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py b/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py index c7dc1bac35..5a76672b83 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py @@ -1,10 +1,10 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import json -from typing import Dict, Tuple, Union +from typing import Dict, Tuple, Union, Optional from unittest.mock import MagicMock -from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkReply +from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkReply, QNetworkRequest from UM.Logger import Logger from UM.Signal import Signal @@ -25,23 +25,30 @@ class NetworkManagerMock: "PUT": QNetworkAccessManager.PutOperation, "DELETE": QNetworkAccessManager.DeleteOperation, "HEAD": QNetworkAccessManager.HeadOperation, - } + } # type: Dict[str, int] ## Initializes the network manager mock. - def __init__(self): + def __init__(self) -> None: # a dict with the prepared replies, using the format {(http_method, url): reply} self.replies = {} # type: Dict[Tuple[str, str], QNetworkReply] + self.request_bodies = {} # type: Dict[Tuple[str, str], bytes] ## Mock implementation of the get, post, put, delete and head methods from the network manager. # Since the methods are very simple and the same it didn't make sense to repeat the code. # \param method: The method being called. # \return The mocked function, if the method name is known. Defaults to the standard getattr function. - def __getattr__(self, method: str): + def __getattr__(self, method: str) -> any: + ## This mock implementation will simply return the reply from the prepared ones. + # it raises a KeyError if requests are done without being prepared. + def doRequest(request: QNetworkRequest, body: Optional[bytes] = None, *_): + key = method.upper(), request.url().toString() + if body: + self.request_bodies[key] = body + return self.replies[key] + operation = self._OPERATIONS.get(method.upper()) if operation: - # this mock implementation will simply return the reply from the prepared ones. - # it raises a KeyError if requests are done without being prepared. - return lambda request, *_: self.replies[method.upper(), request.url().toString()] + return doRequest # the attribute is not one of the implemented methods, default to the standard implementation. return getattr(super(), method) @@ -60,12 +67,18 @@ class NetworkManagerMock: self.replies[method, url] = reply_mock Logger.log("i", "Prepared mock {}-response to {} {}", status_code, method, url) + ## Gets the request that was sent to the network manager for the given method and URL. + # \param method: The HTTP method. + # \param url: The URL. + def getRequestBody(self, method: str, url: str) -> Optional[bytes]: + return self.request_bodies.get((method.upper(), url)) + ## Emits the signal that the reply is ready to all prepared replies. - def flushReplies(self): + def flushReplies(self) -> None: for reply in self.replies.values(): self.finished.emit(reply) self.reset() ## Deletes all prepared replies - def reset(self): + def reset(self) -> None: self.replies.clear() diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py index 4ed2767288..6eca5d250d 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py @@ -1,25 +1,28 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import json -import os from unittest import TestCase from unittest.mock import patch, MagicMock +from UM.Scene.SceneNode import SceneNode from cura.CuraApplication import CuraApplication from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from src.Cloud.CloudApiClient import CloudApiClient -from src.Cloud.CloudOutputController import CloudOutputController from src.Cloud.CloudOutputDevice import CloudOutputDevice +from tests.Cloud.Fixtures import readFixture, parseFixture from .NetworkManagerMock import NetworkManagerMock @patch("cura.NetworkClient.QNetworkAccessManager") class TestCloudOutputDevice(TestCase): CLUSTER_ID = "RIZ6cZbWA_Ua7RZVJhrdVfVpf0z-MqaSHQE4v8aRTtYq" + JOB_ID = "ABCDefGHIjKlMNOpQrSTUvYxWZ0-1234567890abcDE=" HOST_NAME = "ultimakersystem-ccbdd30044ec" - URL = "https://api-staging.ultimaker.com/connect/v1/clusters/{}/status".format(CLUSTER_ID) - with open("{}/Fixtures/getClusterStatusResponse.json".format(os.path.dirname(__file__)), "rb") as f: - DEFAULT_RESPONSE = f.read() + + BASE_URL = "https://api-staging.ultimaker.com" + STATUS_URL = "{}/connect/v1/clusters/{}/status".format(BASE_URL, CLUSTER_ID) + PRINT_URL = "{}/connect/v1/clusters/{}/print/{}".format(BASE_URL, CLUSTER_ID, JOB_ID) + REQUEST_UPLOAD_URL = "{}/cura/v1/jobs/upload".format(BASE_URL) def setUp(self): super().setUp() @@ -28,21 +31,12 @@ class TestCloudOutputDevice(TestCase): self.account = MagicMock(isLoggedIn=True, accessToken="TestAccessToken") self.onError = MagicMock() self.device = CloudOutputDevice(CloudApiClient(self.account, self.onError), self.CLUSTER_ID, self.HOST_NAME) - self.cluster_status = json.loads(self.DEFAULT_RESPONSE.decode()) - self.network.prepareReply("GET", self.URL, 200, self.DEFAULT_RESPONSE) + self.cluster_status = parseFixture("getClusterStatusResponse") + self.network.prepareReply("GET", self.STATUS_URL, 200, readFixture("getClusterStatusResponse")) def tearDown(self): - try: - self._beforeTearDown() - finally: - super().tearDown() - - ## Before tear down method we check whether the state of the output device manager is what we expect based on the - # mocked API response. - def _beforeTearDown(self): - # let the network send replies + super().tearDown() self.network.flushReplies() - # TODO def test_status(self, network_mock): network_mock.return_value = self.network @@ -67,7 +61,66 @@ class TestCloudOutputDevice(TestCase): self.assertEqual([controller_fields, controller_fields], [printer.getController().__dict__ for printer in self.device.printers]) + self.assertEqual(["UM3PrintJobOutputModel"], [type(printer).__name__ for printer in self.device.printJobs]) self.assertEqual({job["uuid"] for job in self.cluster_status["data"]["print_jobs"]}, {job.key for job in self.device.printJobs}) - self.assertEqual(["Daniel Testing"], [job.owner for job in self.device.printJobs]) - self.assertEqual(["UM3_dragon"], [job.name for job in self.device.printJobs]) + self.assertEqual({job["owner"] for job in self.cluster_status["data"]["print_jobs"]}, + {job.owner for job in self.device.printJobs}) + self.assertEqual({job["name"] for job in self.cluster_status["data"]["print_jobs"]}, + {job.name for job in self.device.printJobs}) + + def test_remove_print_job(self, network_mock): + network_mock.return_value = self.network + self.device._update() + self.network.flushReplies() + self.assertEqual(1, len(self.device.printJobs)) + + self.cluster_status["data"]["print_jobs"].clear() + self.network.prepareReply("GET", self.STATUS_URL, 200, self.cluster_status) + self.device._update() + self.network.flushReplies() + self.assertEqual([], self.device.printJobs) + + def test_remove_printers(self, network_mock): + network_mock.return_value = self.network + self.device._update() + self.network.flushReplies() + self.assertEqual(2, len(self.device.printers)) + + self.cluster_status["data"]["printers"].clear() + self.network.prepareReply("GET", self.STATUS_URL, 200, self.cluster_status) + self.device._update() + self.network.flushReplies() + self.assertEqual([], self.device.printers) + + @patch("cura.CuraApplication.CuraApplication.getGlobalContainerStack") + def test_print_to_cloud(self, global_container_stack_mock, network_mock): + active_machine_mock = global_container_stack_mock.return_value + active_machine_mock.getMetaDataEntry.side_effect = {"file_formats": "application/gzip"}.get + + request_upload_response = parseFixture("putJobUploadResponse") + request_print_response = parseFixture("postJobPrintResponse") + self.network.prepareReply("PUT", self.REQUEST_UPLOAD_URL, 201, request_upload_response) + self.network.prepareReply("PUT", request_upload_response["data"]["upload_url"], 201, b"{}") + self.network.prepareReply("POST", self.PRINT_URL, 200, request_print_response) + + network_mock.return_value = self.network + file_handler = MagicMock() + file_handler.getSupportedFileTypesWrite.return_value = [{ + "extension": "gcode.gz", + "mime_type": "application/gzip", + "mode": 2, + }] + file_handler.getWriterByMimeType.return_value.write.side_effect = \ + lambda stream, nodes: stream.write(str(nodes).encode()) + + scene_nodes = [SceneNode()] + self.device.requestWrite(scene_nodes, file_handler=file_handler, file_name="FileName") + + self.network.flushReplies() + self.assertEqual({"data": {"content_type": "application/gzip", "file_size": 57, "job_name": "FileName"}}, + json.loads(self.network.getRequestBody("PUT", self.REQUEST_UPLOAD_URL).decode())) + self.assertEqual(str(scene_nodes).encode(), + self.network.getRequestBody("PUT", request_upload_response["data"]["upload_url"])) + + self.assertIsNone(self.network.getRequestBody("POST", self.PRINT_URL)) diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py index 9e980a8681..420d71d0fe 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py @@ -1,29 +1,26 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -import json -import os from unittest import TestCase from unittest.mock import patch from cura.CuraApplication import CuraApplication from src.Cloud.CloudOutputDevice import CloudOutputDevice from src.Cloud.CloudOutputDeviceManager import CloudOutputDeviceManager +from tests.Cloud.Fixtures import parseFixture, readFixture from .NetworkManagerMock import NetworkManagerMock @patch("cura.NetworkClient.QNetworkAccessManager") class TestCloudOutputDeviceManager(TestCase): URL = "https://api-staging.ultimaker.com/connect/v1/clusters" - with open("{}/Fixtures/clusters.json".format(os.path.dirname(__file__)), "rb") as f: - DEFAULT_RESPONSE = f.read() def setUp(self): super().setUp() self.app = CuraApplication.getInstance() self.network = NetworkManagerMock() self.manager = CloudOutputDeviceManager() - self.clusters_response = json.loads(self.DEFAULT_RESPONSE.decode()) - self.network.prepareReply("GET", self.URL, 200, self.DEFAULT_RESPONSE) + self.clusters_response = parseFixture("getClusters") + self.network.prepareReply("GET", self.URL, 200, readFixture("getClusters")) def tearDown(self): try: From 1436301d780572e976ed0c62edbebee42a404729 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 10 Dec 2018 16:20:00 +0100 Subject: [PATCH 0836/1292] Ensure setActiveExtruderIndex only gets called once when switching machines CURA-6016 --- cura/Settings/ExtruderManager.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index b0bcf3b100..8fa0172305 100755 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -83,8 +83,9 @@ class ExtruderManager(QObject): # \param index The index of the new active extruder. @pyqtSlot(int) def setActiveExtruderIndex(self, index: int) -> None: - self._active_extruder_index = index - self.activeExtruderChanged.emit() + if self._active_extruder_index != index: + self._active_extruder_index = index + self.activeExtruderChanged.emit() @pyqtProperty(int, notify = activeExtruderChanged) def activeExtruderIndex(self) -> int: @@ -344,6 +345,7 @@ class ExtruderManager(QObject): if extruders_changed: self.extrudersChanged.emit(global_stack_id) self.setActiveExtruderIndex(0) + self.activeExtruderChanged.emit() # After 3.4, all single-extrusion machines have their own extruder definition files instead of reusing # "fdmextruder". We need to check a machine here so its extruder definition is correct according to this. From 3132b1f689ad6f83479db5bd19a071e6d47bf74e Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 10 Dec 2018 16:56:44 +0100 Subject: [PATCH 0837/1292] Update the extruder Model a whole lot less CURA-6016 --- cura/Settings/ExtrudersModel.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cura/Settings/ExtrudersModel.py b/cura/Settings/ExtrudersModel.py index 5f10ac99d4..e19617c8ef 100644 --- a/cura/Settings/ExtrudersModel.py +++ b/cura/Settings/ExtrudersModel.py @@ -224,6 +224,6 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): "definition": "" } items.append(item) - - self.setItems(items) - self.modelChanged.emit() + if self._items != items: + self.setItems(items) + self.modelChanged.emit() From 716fedc7820c6a406d3ba431d99284e264cc5541 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 10 Dec 2018 17:06:51 +0100 Subject: [PATCH 0838/1292] Use no text by default for the disabled state of the panels Contributes to CURA-5941. --- resources/qml/ExpandableComponent.qml | 2 +- resources/qml/ExpandablePopup.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index c2b9d715d5..2b07aa7d37 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -109,7 +109,7 @@ Item anchors.fill: parent leftPadding: background.padding rightPadding: background.padding - text: catalog.i18nc("@label default disabled text", "This component is disabled") + text: "" font: UM.Theme.getFont("default") renderType: Text.NativeRendering verticalAlignment: Text.AlignVCenter diff --git a/resources/qml/ExpandablePopup.qml b/resources/qml/ExpandablePopup.qml index 2d34b134e0..4bf1684f18 100644 --- a/resources/qml/ExpandablePopup.qml +++ b/resources/qml/ExpandablePopup.qml @@ -113,7 +113,7 @@ Item id: disabledLabel visible: !base.enabled leftPadding: background.padding - text: catalog.i18nc("@label default disabled text", "This component is disabled") + text: "" font: UM.Theme.getFont("default") renderType: Text.NativeRendering verticalAlignment: Text.AlignVCenter From e7ba4455e06617d6af7ee7b84e41c8eb189f8b80 Mon Sep 17 00:00:00 2001 From: Arseniy Pavlenko Date: Mon, 10 Dec 2018 19:42:23 +0200 Subject: [PATCH 0839/1292] default is 2650, not 2620, probably typo --- resources/definitions/tevo_tarantula.def.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/definitions/tevo_tarantula.def.json b/resources/definitions/tevo_tarantula.def.json index 570ae24a3d..ec4ae667d5 100644 --- a/resources/definitions/tevo_tarantula.def.json +++ b/resources/definitions/tevo_tarantula.def.json @@ -42,7 +42,7 @@ "machine_max_feedrate_x": { "default_value": 255 }, "machine_max_feedrate_y": { "default_value": 225 }, "machine_max_feedrate_z": { "default_value": 3 }, - "machine_max_acceleration_x": { "default_value": 2620 }, + "machine_max_acceleration_x": { "default_value": 2650 }, "machine_max_acceleration_y": { "default_value": 2650 }, "acceleration_print": { "default_value": 2650 }, "machine_start_gcode": { "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." }, From 0357003e6991652c7b07762c2cca0a218b3cc5f6 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 10 Dec 2018 21:47:06 +0100 Subject: [PATCH 0840/1292] STAR-322: Testing encode independent --- .../tests/Cloud/TestCloudOutputDevice.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py index 6eca5d250d..287f2dda98 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py @@ -115,12 +115,15 @@ class TestCloudOutputDevice(TestCase): lambda stream, nodes: stream.write(str(nodes).encode()) scene_nodes = [SceneNode()] + expected_mesh = str(scene_nodes).encode() self.device.requestWrite(scene_nodes, file_handler=file_handler, file_name="FileName") self.network.flushReplies() - self.assertEqual({"data": {"content_type": "application/gzip", "file_size": 57, "job_name": "FileName"}}, - json.loads(self.network.getRequestBody("PUT", self.REQUEST_UPLOAD_URL).decode())) - self.assertEqual(str(scene_nodes).encode(), + self.assertEqual( + {"data": {"content_type": "application/gzip", "file_size": len(expected_mesh), "job_name": "FileName"}}, + json.loads(self.network.getRequestBody("PUT", self.REQUEST_UPLOAD_URL).decode()) + ) + self.assertEqual(expected_mesh, self.network.getRequestBody("PUT", request_upload_response["data"]["upload_url"])) self.assertIsNone(self.network.getRequestBody("POST", self.PRINT_URL)) From 909f36d28ede29c0c9fc5f69db7f8941fc5a8429 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 11 Dec 2018 09:24:22 +0100 Subject: [PATCH 0841/1292] Let the settingsMenu use the extruders of the active machine instead of the extruderModel The extruder model gets updated way to much (for all material changes) but we only need the number and names of the extruders, since the other menu's do this by themselves --- cura/Settings/GlobalStack.py | 16 +++++++++++++--- resources/qml/Menus/SettingsMenu.qml | 5 +++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/cura/Settings/GlobalStack.py b/cura/Settings/GlobalStack.py index da1ec61254..44ceee9511 100755 --- a/cura/Settings/GlobalStack.py +++ b/cura/Settings/GlobalStack.py @@ -3,8 +3,8 @@ from collections import defaultdict import threading -from typing import Any, Dict, Optional, Set, TYPE_CHECKING -from PyQt5.QtCore import pyqtProperty, pyqtSlot +from typing import Any, Dict, Optional, Set, TYPE_CHECKING, List +from PyQt5.QtCore import pyqtProperty, pyqtSlot, pyqtSignal from UM.Decorators import override from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase @@ -42,13 +42,23 @@ class GlobalStack(CuraContainerStack): # Per thread we have our own resolving_settings, or strange things sometimes occur. self._resolving_settings = defaultdict(set) #type: Dict[str, Set[str]] # keys are thread names + extrudersChanged = pyqtSignal() + ## Get the list of extruders of this stack. # # \return The extruders registered with this stack. - @pyqtProperty("QVariantMap") + @pyqtProperty("QVariantMap", notify = extrudersChanged) def extruders(self) -> Dict[str, "ExtruderStack"]: return self._extruders + @pyqtProperty("QVariantList", notify = extrudersChanged) + def extruderList(self) -> List["ExtruderStack"]: + result_tuple_list = sorted(list(self.extruders.items()), key=lambda x: int(x[0])) + result_list = [item[1] for item in result_tuple_list] + + machine_extruder_count = self.getProperty("machine_extruder_count", "value") + return result_list[:machine_extruder_count] + @classmethod def getLoadingPriority(cls) -> int: return 2 diff --git a/resources/qml/Menus/SettingsMenu.qml b/resources/qml/Menus/SettingsMenu.qml index 79f8c5b7bf..4ea3a4d71a 100644 --- a/resources/qml/Menus/SettingsMenu.qml +++ b/resources/qml/Menus/SettingsMenu.qml @@ -16,10 +16,11 @@ Menu Instantiator { - model: Cura.ExtrudersModel { simpleNames: true } + model: Cura.MachineManager.activeMachine.extruderList + Menu { - title: model.name + title: modelData.name NozzleMenu { title: Cura.MachineManager.activeDefinitionVariantsName; visible: Cura.MachineManager.hasVariants; extruderIndex: index } MaterialMenu { title: catalog.i18nc("@title:menu", "&Material"); visible: Cura.MachineManager.hasMaterials; extruderIndex: index } From 99cfef6cdc33d222178ee6f7418d40b5c1727525 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Tue, 11 Dec 2018 09:25:26 +0100 Subject: [PATCH 0842/1292] Use the NetworkManagerMock, added tests for the other functions --- .../Cloud/Fixtures/requestPrintResponse.json | 7 + .../tests/Cloud/TestCloudApiClient.py | 212 +++++++++--------- 2 files changed, 109 insertions(+), 110 deletions(-) create mode 100644 plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/requestPrintResponse.json diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/requestPrintResponse.json b/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/requestPrintResponse.json new file mode 100644 index 0000000000..e69589784d --- /dev/null +++ b/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/requestPrintResponse.json @@ -0,0 +1,7 @@ +{ + "data": { + "cluster_job_id": "", + "job_id": "db34b096-c4d5-46f3-bea7-da6a19905e6c", + "status": "queued" + } +} diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py index 91f367f9ad..07c7733ac1 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py @@ -2,134 +2,126 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import json -from typing import Dict, Tuple -from unittest import TestCase, mock +import os +from unittest import TestCase from unittest.mock import patch, MagicMock -from PyQt5.QtCore import QByteArray -from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkReply - -from UM.Application import Application -from UM.Signal import Signal from cura.CuraApplication import CuraApplication -from plugins.UM3NetworkPrinting.src.Cloud.CloudApiClient import CloudApiClient -from plugins.UM3NetworkPrinting.src.Cloud.Models import CloudCluster, CloudErrorObject - -# This mock application must extend from Application and not QtApplication otherwise some QObjects are created and -# a segfault is raised. -class FixtureApplication(Application): - def __init__(self): - super().__init__(name = "test", version = "1.0", api_version = "5.0.0") - super().initialize() - Signal._signalQueue = self - - def functionEvent(self, event): - event.call() - - def parseCommandLine(self): - pass - - def processEvents(self): - pass - - def getRenderer(self): - return MagicMock() - -class ManagerMock: - finished = Signal() - authenticationRequired = Signal() - - def __init__(self, reply): - self.reply = reply - - def get(self, request): - self.reply.url.return_value = request.url() - - return self.reply - -class ManagerMock2: - finished = Signal() - authenticationRequired = Signal() - - def get(self, request): - reply_mock = MagicMock() - reply_mock.url = request.url - reply_mock.operation.return_value = QNetworkAccessManager.GetOperation - return reply_mock - - @staticmethod - def createReply(method: str, url: str, status_code: int, response: dict): - reply_mock = MagicMock() - reply_mock.url().toString.return_value = url - reply_mock.operation.return_value = { - "GET": QNetworkAccessManager.GetOperation, - "POST": QNetworkAccessManager.PostOperation, - "PUT": QNetworkAccessManager.PutOperation, - "DELETE": QNetworkAccessManager.DeleteOperation, - "HEAD": QNetworkAccessManager.HeadOperation, - }[method] - reply_mock.attribute.return_value = status_code - reply_mock.readAll.return_value = json.dumps(response).encode() - return reply_mock +from src.Cloud.CloudApiClient import CloudApiClient +from src.Cloud.CloudOutputDeviceManager import CloudOutputDeviceManager +from src.Cloud.Models.CloudJobResponse import CloudJobResponse +from src.Cloud.Models.CloudJobUploadRequest import CloudJobUploadRequest +from .NetworkManagerMock import NetworkManagerMock +@patch("cura.NetworkClient.QNetworkAccessManager") class TestCloudApiClient(TestCase): - - app = CuraApplication.getInstance() or CuraApplication - - def _errorHandler(self, errors: [CloudErrorObject]): + def _errorHandler(self): pass - @patch("cura.NetworkClient.QNetworkAccessManager") - @patch("cura.API.Account") - def test_GetClusters(self, account_mock, manager_mock): - reply_mock = MagicMock() - reply_mock.operation.return_value = 2 - reply_mock.attribute.return_value = 200 - reply_mock.readAll.return_value = b'{"data": [{"cluster_id": "RIZ6cZbWA_Ua7RZVJhrdVfVpf0z-MqaSHQE4v8aRTtYq", "host_guid": "e90ae0ac-1257-4403-91ee-a44c9b7e8050", "host_name": "ultimakersystem-ccbdd30044ec", "host_version": "5.1.2.20180807", "is_online": false, "status": "inactive"}, {"cluster_id": "R0YcLJwar1ugh0ikEZsZs8NWKV6vJP_LdYsXgXqAcaNC", "host_guid": "e90ae0ac-1257-4403-91ee-a44c9b7e8050", "host_name": "ultimakersystem-ccbdd30044ec", "host_version": "5.1.2.20180807", "is_online": true, "status": "active"}]}' - manager_mock.return_value = ManagerMock(reply_mock) - account_mock.isLoggedIn.return_value = True + def setUp(self): + super().setUp() + self.account = MagicMock() + self.account.isLoggedIn.return_value = True + + self.app = CuraApplication.getInstance() + self.network = NetworkManagerMock() + self.manager = CloudOutputDeviceManager() + self.api = CloudApiClient(self.account, self._errorHandler) + + def test_GetClusters(self, network_mock): + network_mock.return_value = self.network result = [] - def _callback(clusters): - result.extend(clusters) + with open("{}/Fixtures/getClusters.json".format(os.path.dirname(__file__)), "rb") as f: + response = f.read() - api = CloudApiClient(account_mock, self._errorHandler) - api.getClusters(_callback) + self.network.prepareReply("GET", "https://api-staging.ultimaker.com/connect/v1/clusters", 200, response) + # the callback is a function that adds the result of the call to getClusters to the result list + self.api.getClusters(lambda clusters: result.extend(clusters)) - manager_mock.return_value.finished.emit(reply_mock) + self.network.flushReplies() self.assertEqual(2, len(result)) - @patch("cura.NetworkClient.QNetworkAccessManager") - @patch("cura.API.Account") - def test_GetClusters2(self, account_mock, manager_mock): - manager = ManagerMock2() - manager_mock.return_value = manager - account_mock.isLoggedIn.return_value = True + def test_getClusterStatus(self, network_mock): + network_mock.return_value = self.network result = [] - # with mock.patch.object(Application, "getInstance", new = lambda: FixtureApplication()): - api = CloudApiClient(account_mock, self._errorHandler) - api.getClusters(lambda clusters: result.extend(clusters)) + with open("{}/Fixtures/getClusterStatusResponse.json".format(os.path.dirname(__file__)), "rb") as f: + response = f.read() - manager.finished.emit(ManagerMock2.createReply( - "GET", "https://api-staging.ultimaker.com/connect/v1/clusters", - 200, { - "data": [{ - "cluster_id": "RIZ6cZbWA_Ua7RZVJhrdVfVpf0z-MqaSHQE4v8aRTtYq", - "host_guid": "e90ae0ac-1257-4403-91ee-a44c9b7e8050", - "host_name": "ultimakersystem-ccbdd30044ec", "host_version": "5.1.2.20180807", - "is_online": False, "status": "inactive" - }, { - "cluster_id": "R0YcLJwar1ugh0ikEZsZs8NWKV6vJP_LdYsXgXqAcaNC", - "host_guid": "e90ae0ac-1257-4403-91ee-a44c9b7e8050", - "host_name": "ultimakersystem-ccbdd30044ec", "host_version": "5.1.2.20180807", - "is_online": True, "status": "active" - }] - } - )) + self.network.prepareReply("GET", + "https://api-staging.ultimaker.com/connect/v1/clusters/R0YcLJwar1ugh0ikEZsZs8NWKV6vJP_LdYsXgXqAcaNC/status", + 200, response + ) + self.api.getClusterStatus("R0YcLJwar1ugh0ikEZsZs8NWKV6vJP_LdYsXgXqAcaNC", lambda status: result.append(status)) - self.assertEqual(2, len(result)) + self.network.flushReplies() + + self.assertEqual(len(result), 1) + status = result[0] + + self.assertEqual(len(status.printers), 2) + self.assertEqual(len(status.print_jobs), 1) + + def test_requestUpload(self, network_mock): + network_mock.return_value = self.network + results = [] + + with open("{}/Fixtures/requestUploadResponse.json".format(os.path.dirname(__file__)), "rb") as f: + response = f.read() + + self.network.prepareReply("PUT", "https://api-staging.ultimaker.com/cura/v1/jobs/upload", 200, response) + self.api.requestUpload(CloudJobUploadRequest(job_name = "job name", file_size = 143234, content_type = "text/plain"), + lambda r: results.append(r)) + self.network.flushReplies() + + self.assertEqual(results[0].content_type, "text/plain") + self.assertEqual(results[0].status, "uploading") + + def test_uploadMesh(self, network_mock): + network_mock.return_value = self.network + results = [] + progress = MagicMock() + + with open("{}/Fixtures/requestUploadResponse.json".format(os.path.dirname(__file__)), "rb") as f: + thedata = json.loads(f.read().decode("ascii")) + data = thedata["data"] + upload_response = CloudJobResponse(**data) + + self.network.prepareReply("PUT", upload_response.upload_url, 200, + '{ data : "" }') # Network client doesn't look into the reply + + self.api.uploadMesh(upload_response, b'', lambda job_id: results.append(job_id), + progress.advance, progress.error) + + self.network.flushReplies() + + self.assertEqual(len(results), 1) + self.assertEqual(results[0], upload_response.job_id) + + def test_requestPrint(self, network_mock): + network_mock.return_value = self.network + results = [] + + cluster_id = "NWKV6vJP_LdYsXgXqAcaNCR0YcLJwar1ugh0ikEZsZs8" + job_id = "db34b096-c4d5-46f3-bea7-da6a19905e6c" + + with open("{}/Fixtures/requestPrintResponse.json".format(os.path.dirname(__file__)), "rb") as f: + response = f.read() + + self.network.prepareReply("POST", + "https://api-staging.ultimaker.com/connect/v1/clusters/{}/print/{}" + .format(cluster_id, job_id), + 200, response) + + self.api.requestPrint(cluster_id, job_id, lambda r: results.append(r)) + + self.network.flushReplies() + + self.assertEqual(len(results), 1) + self.assertEqual(results[0].job_id, "db34b096-c4d5-46f3-bea7-da6a19905e6c") + self.assertEqual(results[0].status, "queued") From 3b54cb4b241187562341d7435c391dbefe0949b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marijn=20De=C3=A9?= Date: Tue, 11 Dec 2018 09:27:40 +0100 Subject: [PATCH 0843/1292] Use the NetworkManagerMock, added tests for the other functions --- .../tests/Cloud/Fixtures/requestUploadResponse.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/requestUploadResponse.json diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/requestUploadResponse.json b/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/requestUploadResponse.json new file mode 100644 index 0000000000..6168e5205f --- /dev/null +++ b/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/requestUploadResponse.json @@ -0,0 +1,11 @@ +{ + "data": { + "content_type": "text/plain", + "generated_time": "2018-12-10T09:33:00.009Z", + "job_id": "j9KUn4D6FRRRmdtbCo4OGAwUf6Ml3p3oU-Zv7RNRv92T", + "job_name": "job name", + "status": "uploading", + "status_description": "The print job has been created. Please upload the file.", + "upload_url": "https://www.googleapis.com/upload/storage/v1/b/ultimaker-storage-1/o?uploadType=resumable&upload_id=AEnB2Uqhg1H7BXQVeLJEWw6AheqMicydZVLuH9bnkh6Oge0e6i5X76MW3NZHWRmUTmjzulAF42mkczcC7rsAuPg1Nn8JeFpnNA" + } +} From bb1950525a5e67ae9ee0e7163d720e0d14b72f16 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 11 Dec 2018 09:42:34 +0100 Subject: [PATCH 0844/1292] Limit the amount of times the buildplate rebuild is done CURA-6016 --- cura/BuildVolume.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py index f837f5cef7..aa1f170707 100755 --- a/cura/BuildVolume.py +++ b/cura/BuildVolume.py @@ -83,7 +83,14 @@ class BuildVolume(SceneNode): " with printed models."), title = catalog.i18nc("@info:title", "Build Volume")) self._global_container_stack = None + + self._stack_change_timer = QTimer() + self._stack_change_timer.setInterval(100) + self._stack_change_timer.setSingleShot(True) + self._stack_change_timer.timeout.connect(self._onStackChangeTimerFinished) + self._application.globalContainerStackChanged.connect(self._onStackChanged) + self._onStackChanged() self._engine_ready = False @@ -105,6 +112,8 @@ class BuildVolume(SceneNode): self._setting_change_timer.setSingleShot(True) self._setting_change_timer.timeout.connect(self._onSettingChangeTimerFinished) + + # Must be after setting _build_volume_message, apparently that is used in getMachineManager. # activeQualityChanged is always emitted after setActiveVariant, setActiveMaterial and setActiveQuality. # Therefore this works. @@ -526,8 +535,11 @@ class BuildVolume(SceneNode): if extra_z != self._extra_z_clearance: self._extra_z_clearance = extra_z - ## Update the build volume visualization def _onStackChanged(self): + self._stack_change_timer.start() + + ## Update the build volume visualization + def _onStackChangeTimerFinished(self): if self._global_container_stack: self._global_container_stack.propertyChanged.disconnect(self._onSettingPropertyChanged) extruders = ExtruderManager.getInstance().getActiveExtruderStacks() From 77703e1fb8f2a0c60a56126b9ccc90d5aba8f8a3 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 11 Dec 2018 09:58:23 +0100 Subject: [PATCH 0845/1292] Catch an exception from numpy that happens when loading some models --- cura/Scene/ConvexHullDecorator.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cura/Scene/ConvexHullDecorator.py b/cura/Scene/ConvexHullDecorator.py index 0c03ae615b..661106dec7 100644 --- a/cura/Scene/ConvexHullDecorator.py +++ b/cura/Scene/ConvexHullDecorator.py @@ -187,7 +187,10 @@ class ConvexHullDecorator(SceneNodeDecorator): for child in self._node.getChildren(): child_hull = child.callDecoration("_compute2DConvexHull") if child_hull: - points = numpy.append(points, child_hull.getPoints(), axis = 0) + try: + points = numpy.append(points, child_hull.getPoints(), axis = 0) + except ValueError: + pass if points.size < 3: return None From badf2962bc90c910fc10b09ecb309b10604d5090 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 11 Dec 2018 10:34:00 +0100 Subject: [PATCH 0846/1292] Change CuraDrive version to 1.2.0 CURA-6005 Because the previously version is 1.1.1 --- plugins/CuraDrive/plugin.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/CuraDrive/plugin.json b/plugins/CuraDrive/plugin.json index 134cd31a77..44bf955f41 100644 --- a/plugins/CuraDrive/plugin.json +++ b/plugins/CuraDrive/plugin.json @@ -2,7 +2,7 @@ "name": "Cura Backups", "author": "Ultimaker B.V.", "description": "Backup and restore your configuration.", - "version": "1.2.1", + "version": "1.2.0", "api": 5, "i18n-catalog": "cura_drive" -} \ No newline at end of file +} From 9618e8d4e096aaaeaf6e510a00b7436bd4cc852f Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 11 Dec 2018 10:34:49 +0100 Subject: [PATCH 0847/1292] Add CuraDrive 1.2.0 to bundled_packages CURA-6005 --- resources/bundled_packages/cura.json | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/resources/bundled_packages/cura.json b/resources/bundled_packages/cura.json index d8a7df2478..33c6304fc5 100644 --- a/resources/bundled_packages/cura.json +++ b/resources/bundled_packages/cura.json @@ -50,6 +50,23 @@ } } }, + "CuraDrive": { + "package_info": { + "package_id": "CuraDrive", + "package_type": "plugin", + "display_name": "Cura Backups", + "description": "Backup and restore your configuration.", + "package_version": "1.2.0", + "sdk_version": 5, + "website": "https://ultimaker.com", + "author": { + "author_id": "UltimakerPackages", + "display_name": "Ultimaker B.V.", + "email": "plugins@ultimaker.com", + "website": "https://ultimaker.com" + } + } + }, "CuraEngineBackend": { "package_info": { "package_id": "CuraEngineBackend", From 4dab33d41babdb0d961d3d1bcb54479b5e8c3691 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 11 Dec 2018 10:44:30 +0100 Subject: [PATCH 0848/1292] Remove the fancy snowflakes pattern --- resources/qml/Cura.qml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 3e019cdcd5..a4faa27b67 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -123,17 +123,6 @@ UM.MainWindow } } } - - // This is the new fancy pattern - Image - { - id: backgroundPattern - anchors.fill: parent - fillMode: Image.Tile - source: UM.Theme.getImage("header_pattern") - horizontalAlignment: Image.AlignLeft - verticalAlignment: Image.AlignTop - } } MainWindowHeader From 0f357e1078b6a30a5b3ddda88bbc9fcd736f0bb4 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 11 Dec 2018 10:51:05 +0100 Subject: [PATCH 0849/1292] Replace fix for 'None' materials This was fixed in 4.0 and accidentally got reverted when merging another branch in. Contributes to CL-1160 --- .../UM3NetworkPrinting/src/ClusterUM3OutputDevice.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index 08592df603..60474156a8 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -609,6 +609,17 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): material_manager = CuraApplication.getInstance().getMaterialManager() material_group_list = material_manager.getMaterialGroupListByGUID(material_data["guid"]) + # This can happen if the connected machine has no material in one or more extruders (if GUID is empty), or the + # material is unknown to Cura, so we should return an "empty" or "unknown" material model. + if material_group_list is None: + material_name = "Empty" if len(material_data["guid"]) == 0 else "Unknown" + return MaterialOutputModel(guid = material_data["guid"], + type = material_data.get("type", ""), + color = material_data.get("color", ""), + brand = material_data.get("brand", ""), + name = material_data.get("name", material_name) + ) + # Sort the material groups by "is_read_only = True" first, and then the name alphabetically. read_only_material_group_list = list(filter(lambda x: x.is_read_only, material_group_list)) non_read_only_material_group_list = list(filter(lambda x: not x.is_read_only, material_group_list)) From f67ac8d7c4f937a323f8b1a520abfaecad5b438a Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 11 Dec 2018 10:59:17 +0100 Subject: [PATCH 0850/1292] Update far less agressively for the material models CURA-6016 --- cura/Machines/Models/BaseMaterialsModel.py | 14 ++++++++++---- cura/Machines/Models/FavoriteMaterialsModel.py | 5 +---- cura/Machines/Models/GenericMaterialsModel.py | 3 --- cura/Machines/Models/MaterialBrandsModel.py | 4 ---- 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/cura/Machines/Models/BaseMaterialsModel.py b/cura/Machines/Models/BaseMaterialsModel.py index ef2e760330..3cd92bb6b4 100644 --- a/cura/Machines/Models/BaseMaterialsModel.py +++ b/cura/Machines/Models/BaseMaterialsModel.py @@ -1,5 +1,6 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +from typing import Optional, Dict, Set from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty from UM.Qt.ListModel import ListModel @@ -9,6 +10,9 @@ from UM.Qt.ListModel import ListModel # Those 2 models are used by the material drop down menu to show generic materials and branded materials separately. # The extruder position defined here is being used to bound a menu to the correct extruder. This is used in the top # bar menu "Settings" -> "Extruder nr" -> "Material" -> this menu +from cura.Machines.MaterialNode import MaterialNode + + class BaseMaterialsModel(ListModel): extruderPositionChanged = pyqtSignal() @@ -54,8 +58,8 @@ class BaseMaterialsModel(ListModel): self._extruder_position = 0 self._extruder_stack = None - self._available_materials = None - self._favorite_ids = None + self._available_materials = None # type: Optional[Dict[str, MaterialNode]] + self._favorite_ids = set() # type: Set(str) def _updateExtruderStack(self): global_stack = self._machine_manager.activeMachine @@ -102,8 +106,10 @@ class BaseMaterialsModel(ListModel): return False extruder_stack = global_stack.extruders[extruder_position] - - self._available_materials = self._material_manager.getAvailableMaterialsForMachineExtruder(global_stack, extruder_stack) + available_materials = self._material_manager.getAvailableMaterialsForMachineExtruder(global_stack, extruder_stack) + if available_materials == self._available_materials: + return False + self._available_materials = available_materials if self._available_materials is None: return False diff --git a/cura/Machines/Models/FavoriteMaterialsModel.py b/cura/Machines/Models/FavoriteMaterialsModel.py index 18fe310c44..cc273e55ce 100644 --- a/cura/Machines/Models/FavoriteMaterialsModel.py +++ b/cura/Machines/Models/FavoriteMaterialsModel.py @@ -4,17 +4,14 @@ from UM.Logger import Logger from cura.Machines.Models.BaseMaterialsModel import BaseMaterialsModel -class FavoriteMaterialsModel(BaseMaterialsModel): +class FavoriteMaterialsModel(BaseMaterialsModel): def __init__(self, parent = None): super().__init__(parent) self._update() def _update(self): - - # Perform standard check and reset if the check fails if not self._canUpdate(): - self.setItems([]) return # Get updated list of favorites diff --git a/cura/Machines/Models/GenericMaterialsModel.py b/cura/Machines/Models/GenericMaterialsModel.py index c276b865bf..8f41dd6a70 100644 --- a/cura/Machines/Models/GenericMaterialsModel.py +++ b/cura/Machines/Models/GenericMaterialsModel.py @@ -11,10 +11,7 @@ class GenericMaterialsModel(BaseMaterialsModel): self._update() def _update(self): - - # Perform standard check and reset if the check fails if not self._canUpdate(): - self.setItems([]) return # Get updated list of favorites diff --git a/cura/Machines/Models/MaterialBrandsModel.py b/cura/Machines/Models/MaterialBrandsModel.py index 458e4d9b47..ac82cf6670 100644 --- a/cura/Machines/Models/MaterialBrandsModel.py +++ b/cura/Machines/Models/MaterialBrandsModel.py @@ -28,12 +28,8 @@ class MaterialBrandsModel(BaseMaterialsModel): self._update() def _update(self): - - # Perform standard check and reset if the check fails if not self._canUpdate(): - self.setItems([]) return - # Get updated list of favorites self._favorite_ids = self._material_manager.getFavorites() From 4b6f4af44eeef9b0d39c3161d7e577d66d57388c Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 11 Dec 2018 11:10:45 +0100 Subject: [PATCH 0851/1292] Close the expandable panel when it becomes disabled It happens when it's open and the user loads a GCode. Contributes to CURA-5941 --- resources/qml/ExpandableComponent.qml | 18 +++++++++++++++++- resources/qml/ExpandablePopup.qml | 15 ++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index 2b07aa7d37..afe15bcb1d 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -88,7 +88,23 @@ Item { target: background property: "color" - value: enabled ? (expanded ? headerActiveColor : headerBackgroundColor) : UM.Theme.getColor("disabled") + value: + { + return base.enabled ? (expanded ? headerActiveColor : headerBackgroundColor) : UM.Theme.getColor("disabled") + } + } + + // The panel needs to close when it becomes disabled + Connections + { + target: base + onEnabledChanged: + { + if (!base.enabled && expanded) + { + toggleContent() + } + } } implicitHeight: 100 * screenScaleFactor diff --git a/resources/qml/ExpandablePopup.qml b/resources/qml/ExpandablePopup.qml index 4bf1684f18..2d2665373e 100644 --- a/resources/qml/ExpandablePopup.qml +++ b/resources/qml/ExpandablePopup.qml @@ -94,7 +94,20 @@ Item { target: background property: "color" - value: enabled ? headerBackgroundColor : UM.Theme.getColor("disabled") + value: base.enabled ? headerBackgroundColor : UM.Theme.getColor("disabled") + } + + // The panel needs to close when it becomes disabled + Connections + { + target: base + onEnabledChanged: + { + if (!base.enabled && expanded) + { + toggleContent() + } + } } implicitHeight: 100 * screenScaleFactor From 76688015645f6e3cce3fd66d7d6539ef870200a0 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Tue, 11 Dec 2018 11:12:32 +0100 Subject: [PATCH 0852/1292] STAR-322: Adding documentation and fixing model types --- .../src/Cloud/CloudApiClient.py | 25 +++--- .../src/Cloud/CloudOutputDevice.py | 26 +++--- .../src/Cloud/CloudOutputDeviceManager.py | 6 +- .../src/Cloud/Models/BaseCloudModel.py | 48 ++++++++-- .../src/Cloud/Models/CloudCluster.py | 21 ----- .../src/Cloud/Models/CloudClusterPrintJob.py | 65 -------------- .../Models/CloudClusterPrintJobConstraint.py | 12 ++- .../Models/CloudClusterPrintJobStatus.py | 87 +++++++++++++++++++ .../src/Cloud/Models/CloudClusterPrinter.py | 49 ----------- .../CloudClusterPrinterConfiguration.py | 23 +++-- ...loudClusterPrinterConfigurationMaterial.py | 19 ++-- .../Cloud/Models/CloudClusterPrinterStatus.py | 60 +++++++++++++ .../src/Cloud/Models/CloudClusterResponse.py | 32 +++++++ .../src/Cloud/Models/CloudClusterStatus.py | 34 ++++---- .../src/Cloud/Models/CloudErrorObject.py | 29 +++++-- .../src/Cloud/Models/CloudJobResponse.py | 16 ---- .../src/Cloud/Models/CloudJobUploadRequest.py | 12 --- .../src/Cloud/Models/CloudPrintJobResponse.py | 33 +++++++ .../Models/CloudPrintJobUploadRequest.py | 17 ++++ .../src/Cloud/Models/CloudPrintResponse.py | 19 +++- .../Cloud/Fixtures/postJobPrintResponse.json | 3 +- .../Cloud/Fixtures/putJobUploadResponse.json | 3 +- .../Cloud/Fixtures/requestPrintResponse.json | 7 -- .../Cloud/Fixtures/requestUploadResponse.json | 11 --- .../tests/Cloud/TestCloudApiClient.py | 32 ++++--- .../Cloud/TestCloudOutputDeviceManager.py | 4 +- 26 files changed, 411 insertions(+), 282 deletions(-) delete mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Models/CloudCluster.py delete mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py delete mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinter.py create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterStatus.py create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterResponse.py delete mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobResponse.py delete mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobUploadRequest.py create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintJobResponse.py create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintJobUploadRequest.py delete mode 100644 plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/requestPrintResponse.json delete mode 100644 plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/requestUploadResponse.json diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py index 448aa4d2e7..9cc70587a3 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py @@ -10,12 +10,12 @@ from UM.Logger import Logger from cura.API import Account from cura.NetworkClient import NetworkClient from ..Models import BaseModel -from .Models.CloudCluster import CloudCluster +from .Models.CloudClusterResponse import CloudClusterResponse from .Models.CloudErrorObject import CloudErrorObject from .Models.CloudClusterStatus import CloudClusterStatus -from .Models.CloudJobUploadRequest import CloudJobUploadRequest +from .Models.CloudPrintJobUploadRequest import CloudPrintJobUploadRequest from .Models.CloudPrintResponse import CloudPrintResponse -from .Models.CloudJobResponse import CloudJobResponse +from .Models.CloudPrintJobResponse import CloudPrintJobResponse ## The cloud API client is responsible for handling the requests and responses from the cloud. @@ -43,9 +43,9 @@ class CloudApiClient(NetworkClient): ## Retrieves all the clusters for the user that is currently logged in. # \param on_finished: The function to be called after the result is parsed. - def getClusters(self, on_finished: Callable[[List[CloudCluster]], any]) -> None: + def getClusters(self, on_finished: Callable[[List[CloudClusterResponse]], any]) -> None: url = "{}/clusters".format(self.CLUSTER_API_ROOT) - self.get(url, on_finished=self._wrapCallback(on_finished, CloudCluster)) + self.get(url, on_finished=self._wrapCallback(on_finished, CloudClusterResponse)) ## Retrieves the status of the given cluster. # \param cluster_id: The ID of the cluster. @@ -57,10 +57,11 @@ class CloudApiClient(NetworkClient): ## Requests the cloud to register the upload of a print job mesh. # \param request: The request object. # \param on_finished: The function to be called after the result is parsed. - def requestUpload(self, request: CloudJobUploadRequest, on_finished: Callable[[CloudJobResponse], any]) -> None: + def requestUpload(self, request: CloudPrintJobUploadRequest, on_finished: Callable[[CloudPrintJobResponse], any] + ) -> None: url = "{}/jobs/upload".format(self.CURA_API_ROOT) - body = json.dumps({"data": request.__dict__}) - self.put(url, body, on_finished=self._wrapCallback(on_finished, CloudJobResponse)) + body = json.dumps({"data": request.toDict()}) + self.put(url, body, on_finished=self._wrapCallback(on_finished, CloudPrintJobResponse)) ## Requests the cloud to register the upload of a print job mesh. # \param upload_response: The object received after requesting an upload with `self.requestUpload`. @@ -68,7 +69,7 @@ class CloudApiClient(NetworkClient): # \param on_finished: The function to be called after the result is parsed. It receives the print job ID. # \param on_progress: A function to be called during upload progress. It receives a percentage (0-100). # \param on_error: A function to be called if the upload fails. It receives a dict with the error. - def uploadMesh(self, upload_response: CloudJobResponse, mesh: bytes, on_finished: Callable[[str], any], + def uploadMesh(self, upload_response: CloudPrintJobResponse, mesh: bytes, on_finished: Callable[[str], any], on_progress: Callable[[int], any], on_error: Callable[[dict], any]): def progressCallback(bytes_sent: int, bytes_total: int) -> None: @@ -126,13 +127,13 @@ class CloudApiClient(NetworkClient): ## Parses the given models and calls the correct callback depending on the result. # \param response: The response from the server, after being converted to a dict. # \param on_finished: The callback in case the response is successful. - # \param model: The type of the model to convert the response to. It may either be a single record or a list. + # \param model_class: The type of the model to convert the response to. It may either be a single record or a list. def _parseModels(self, response: Dict[str, any], on_finished: Callable[[Union[Model, List[Model]]], any], - model: Type[Model]) -> None: + model_class: Type[Model]) -> None: if "data" in response: data = response["data"] - result = [model(**c) for c in data] if isinstance(data, list) else model(**data) + result = [model_class(**c) for c in data] if isinstance(data, list) else model_class(**data) on_finished(result) elif "errors" in response: self._on_error([CloudErrorObject(**error) for error in response["errors"]]) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 17acbe2e3f..15eeed108d 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -20,11 +20,11 @@ from ..MeshFormatHandler import MeshFormatHandler from ..UM3PrintJobOutputModel import UM3PrintJobOutputModel from .CloudApiClient import CloudApiClient from .Models.CloudClusterStatus import CloudClusterStatus -from .Models.CloudJobUploadRequest import CloudJobUploadRequest +from .Models.CloudPrintJobUploadRequest import CloudPrintJobUploadRequest from .Models.CloudPrintResponse import CloudPrintResponse -from .Models.CloudJobResponse import CloudJobResponse -from .Models.CloudClusterPrinter import CloudClusterPrinter -from .Models.CloudClusterPrintJob import CloudClusterPrintJob +from .Models.CloudPrintJobResponse import CloudPrintJobResponse +from .Models.CloudClusterPrinterStatus import CloudClusterPrinterStatus +from .Models.CloudClusterPrintJobStatus import CloudClusterPrintJobStatus from .Utils import findChanges, formatDateCompleted, formatTimeCompleted @@ -116,8 +116,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self._progress_message = None # type: Optional[Message] # Keep server string of the last generated time to avoid updating models more than once for the same response - self._received_printers = None # type: Optional[List[CloudClusterPrinter]] - self._received_print_jobs = None # type: Optional[List[CloudClusterPrintJob]] + self._received_printers = None # type: Optional[List[CloudClusterPrinterStatus]] + self._received_print_jobs = None # type: Optional[List[CloudClusterPrintJobStatus]] # A set of the user's job IDs that have finished self._finished_jobs = set() # type: Set[str] @@ -166,7 +166,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): mesh_bytes = mesh_format.getBytes(nodes) - request = CloudJobUploadRequest( + request = CloudPrintJobUploadRequest( job_name = file_name, file_size = len(mesh_bytes), content_type = mesh_format.mime_type, @@ -199,9 +199,9 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## Updates the local list of printers with the list received from the cloud. # \param jobs: The printers received from the cloud. - def _updatePrinters(self, printers: List[CloudClusterPrinter]) -> None: + def _updatePrinters(self, printers: List[CloudClusterPrinterStatus]) -> None: previous = {p.key: p for p in self._printers} # type: Dict[str, PrinterOutputModel] - received = {p.uuid: p for p in printers} # type: Dict[str, CloudClusterPrinter] + received = {p.uuid: p for p in printers} # type: Dict[str, CloudClusterPrinterStatus] removed_printers, added_printers, updated_printers = findChanges(previous, received) @@ -224,8 +224,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## Updates the local list of print jobs with the list received from the cloud. # \param jobs: The print jobs received from the cloud. - def _updatePrintJobs(self, jobs: List[CloudClusterPrintJob]) -> None: - received = {j.uuid: j for j in jobs} # type: Dict[str, CloudClusterPrintJob] + def _updatePrintJobs(self, jobs: List[CloudClusterPrintJobStatus]) -> None: + received = {j.uuid: j for j in jobs} # type: Dict[str, CloudClusterPrintJobStatus] previous = {j.key: j for j in self._print_jobs} # type: Dict[str, UM3PrintJobOutputModel] removed_jobs, added_jobs, updated_jobs = findChanges(previous, received) @@ -248,7 +248,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## Registers a new print job received via the cloud API. # \param job: The print job received. - def _addPrintJob(self, job: CloudClusterPrintJob) -> None: + def _addPrintJob(self, job: CloudClusterPrintJobStatus) -> None: model = job.createOutputModel(CloudOutputController(self)) model.stateChanged.connect(self._onPrintJobStateChanged) if job.printer_uuid: @@ -284,7 +284,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## Uploads the mesh when the print job was registered with the cloud API. # \param mesh: The bytes to upload. # \param job_response: The response received from the cloud API. - def _onPrintJobCreated(self, mesh: bytes, job_response: CloudJobResponse) -> None: + def _onPrintJobCreated(self, mesh: bytes, job_response: CloudPrintJobResponse) -> None: self._api.uploadMesh(job_response, mesh, self._onPrintJobUploaded, self._updateUploadProgress, lambda _: self._onUploadError(T.UPLOAD_ERROR)) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 961f8d696d..c9b30d7c79 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -12,7 +12,7 @@ from cura.CuraApplication import CuraApplication from cura.Settings.GlobalStack import GlobalStack from .CloudApiClient import CloudApiClient from .CloudOutputDevice import CloudOutputDevice -from .Models.CloudCluster import CloudCluster +from .Models.CloudClusterResponse import CloudClusterResponse from .Models.CloudErrorObject import CloudErrorObject from .Utils import findChanges @@ -72,8 +72,8 @@ class CloudOutputDeviceManager: self._api.getClusters(self._onGetRemoteClustersFinished) ## Callback for when the request for getting the clusters. is finished. - def _onGetRemoteClustersFinished(self, clusters: List[CloudCluster]) -> None: - online_clusters = {c.cluster_id: c for c in clusters if c.is_online} # type: Dict[str, CloudCluster] + def _onGetRemoteClustersFinished(self, clusters: List[CloudClusterResponse]) -> None: + online_clusters = {c.cluster_id: c for c in clusters if c.is_online} # type: Dict[str, CloudClusterResponse] removed_devices, added_clusters, updates = findChanges(self._remote_clusters, online_clusters) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/BaseCloudModel.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/BaseCloudModel.py index 1176c4374a..3a0e93e836 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/BaseCloudModel.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/BaseCloudModel.py @@ -1,17 +1,55 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. from datetime import datetime, timezone +from typing import Dict, Union, TypeVar, Type, List from ...Models import BaseModel +## Base class for the models used in the interface with the Ultimaker cloud APIs. class BaseCloudModel(BaseModel): + ## Checks whether the two models are equal. + # \param other: The other model. + # \return True if they are equal, False if they are different. def __eq__(self, other): - return type(self) == type(other) and self.__dict__ == other.__dict__ + return type(self) == type(other) and self.toDict() == other.toDict() - def __ne__(self, other): - return type(self) != type(other) or self.__dict__ != other.__dict__ + ## Checks whether the two models are different. + # \param other: The other model. + # \return True if they are different, False if they are the same. + def __ne__(self, other) -> bool: + return type(self) != type(other) or self.toDict() != other.toDict() + ## Converts the model into a serializable dictionary + def toDict(self) -> Dict[str, any]: + return self.__dict__ + + # Type variable used in the parse methods below, which should be a subclass of BaseModel. + T = TypeVar("T", bound=BaseModel) + + ## Parses a single model. + # \param model_class: The model class. + # \param values: The value of the model, which is usually a dictionary, but may also be already parsed. + # \return An instance of the model_class given. @staticmethod - def parseDate(date_str: str) -> datetime: - return datetime.strptime(date_str, "%Y-%m-%dT%H:%M:%S.%fZ").replace(tzinfo=timezone.utc) + def parseModel(model_class: Type[T], values: Union[T, Dict[str, any]]) -> T: + if isinstance(values, dict): + return model_class(**values) + return values + + ## Parses a list of models. + # \param model_class: The model class. + # \param values: The value of the list. Each value is usually a dictionary, but may also be already parsed. + # \return A list of instances of the model_class given. + @classmethod + def parseModels(cls, model_class: Type[T], values: List[Union[T, Dict[str, any]]]) -> List[T]: + return [cls.parseModel(model_class, value) for value in values] + + ## Parses the given date string. + # \param date: The date to parse. + # \return The parsed date. + @staticmethod + def parseDate(date: Union[str, datetime]) -> datetime: + if isinstance(date, datetime): + return date + return datetime.strptime(date, "%Y-%m-%dT%H:%M:%S.%fZ").replace(tzinfo=timezone.utc) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudCluster.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudCluster.py deleted file mode 100644 index e6e2af1466..0000000000 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudCluster.py +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (c) 2018 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. -from .BaseCloudModel import BaseCloudModel - - -## Class representing a cloud connected cluster. -class CloudCluster(BaseCloudModel): - def __init__(self, **kwargs): - self.cluster_id = None # type: str - self.host_guid = None # type: str - self.host_name = None # type: str - self.host_version = None # type: str - self.status = None # type: str - self.is_online = False # type: bool - super().__init__(**kwargs) - - # Validates the model, raising an exception if the model is invalid. - def validate(self) -> None: - super().validate() - if not self.cluster_id: - raise ValueError("cluster_id is required on CloudCluster") diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py deleted file mode 100644 index 15d256e7d5..0000000000 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py +++ /dev/null @@ -1,65 +0,0 @@ -# Copyright (c) 2018 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. -from typing import List - -from cura.PrinterOutput.ConfigurationModel import ConfigurationModel -from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputController import CloudOutputController -from .CloudClusterPrinterConfiguration import CloudClusterPrinterConfiguration -from .CloudClusterPrintJobConstraint import CloudClusterPrintJobConstraint -from .BaseCloudModel import BaseCloudModel - - -## Class representing a print job -from plugins.UM3NetworkPrinting.src.UM3PrintJobOutputModel import UM3PrintJobOutputModel - - -class CloudClusterPrintJob(BaseCloudModel): - def __init__(self, **kwargs) -> None: - self.assigned_to = None # type: str - self.configuration = [] # type: List[CloudClusterPrinterConfiguration] - self.constraints = [] # type: List[CloudClusterPrintJobConstraint] - self.created_at = None # type: str - self.force = None # type: str - self.last_seen = None # type: str - self.machine_variant = None # type: str - self.name = None # type: str - self.network_error_count = None # type: int - self.owner = None # type: str - self.printer_uuid = None # type: str - self.started = None # type: str - self.status = None # type: str - self.time_elapsed = None # type: str - self.time_total = None # type: str - self.uuid = None # type: str - super().__init__(**kwargs) - self.configuration = [CloudClusterPrinterConfiguration(**c) if isinstance(c, dict) else c - for c in self.configuration] - self.constraints = [CloudClusterPrintJobConstraint(**p) if isinstance(p, dict) else p - for p in self.constraints] - - ## Creates an UM3 print job output model based on this cloud cluster print job. - # \param printer: The output model of the printer - def createOutputModel(self, controller: CloudOutputController) -> UM3PrintJobOutputModel: - model = UM3PrintJobOutputModel(controller, self.uuid, self.name) - self.updateOutputModel(model) - - return model - - ## Creates a new configuration model - def _createConfigurationModel(self) -> ConfigurationModel: - extruders = [extruder.createConfigurationModel() for extruder in self.configuration or ()] - configuration = ConfigurationModel() - configuration.setExtruderConfigurations(extruders) - return configuration - - ## Updates an UM3 print job output model based on this cloud cluster print job. - # \param model: The model to update. - def updateOutputModel(self, model: UM3PrintJobOutputModel) -> None: - # TODO: Add `compatible_machine_families` to the cloud, than add model.setCompatibleMachineFamilies() - # TODO: Add `impediments_to_printing` to the cloud, see ClusterUM3OutputDevice._updatePrintJob - # TODO: Use model.updateConfigurationChanges, see ClusterUM3OutputDevice#_createConfigurationChanges - model.updateConfiguration(self._createConfigurationModel()) - model.updateTimeTotal(self.time_total) - model.updateTimeElapsed(self.time_elapsed) - model.updateOwner(self.owner) - model.updateState(self.status) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobConstraint.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobConstraint.py index f13e3098fc..8236ec06b9 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobConstraint.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobConstraint.py @@ -1,10 +1,16 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +from typing import Optional + from .BaseCloudModel import BaseCloudModel ## Class representing a cloud cluster print job constraint -class CloudClusterPrintJobConstraint(BaseCloudModel): - def __init__(self, **kwargs) -> None: - self.require_printer_name = None # type: str +# Spec: https://api-staging.ultimaker.com/connect/v1/spec +class CloudClusterPrintJobConstraints(BaseCloudModel): + ## Creates a new print job constraint. + # \param require_printer_name: Unique name of the printer that this job should be printed on. + # Should be one of the unique_name field values in the cluster, e.g. 'ultimakersystem-ccbdd30044ec' + def __init__(self, require_printer_name: Optional[str] = None, **kwargs) -> None: + self.require_printer_name = require_printer_name super().__init__(**kwargs) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py new file mode 100644 index 0000000000..24ef9078d6 --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py @@ -0,0 +1,87 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +from typing import List, Optional, Union, Dict + +from cura.PrinterOutput.ConfigurationModel import ConfigurationModel +from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputController import CloudOutputController +from .CloudClusterPrinterConfiguration import CloudClusterPrinterConfiguration +from .CloudClusterPrintJobConstraint import CloudClusterPrintJobConstraints +from .BaseCloudModel import BaseCloudModel + + +## Class representing a print job +from plugins.UM3NetworkPrinting.src.UM3PrintJobOutputModel import UM3PrintJobOutputModel + + +## Model for the status of a single print job in a cluster. +# Spec: https://api-staging.ultimaker.com/connect/v1/spec +class CloudClusterPrintJobStatus(BaseCloudModel): + ## Creates a new cloud print job status model. + # \param assigned_to: The name of the printer this job is assigned to while being queued. + # \param configuration: The required print core configurations of this print job. + # \param constraints: Print job constraints object. + # \param created_at: The timestamp when the job was created in Cura Connect. + # \param force: Allow this job to be printed despite of mismatching configurations. + # \param last_seen: The number of seconds since this job was checked. + # \param machine_variant: The machine type that this job should be printed on.Coincides with the machine_type field + # of the printer object. + # \param name: The name of the print job. Usually the name of the .gcode file. + # \param network_error_count: The number of errors encountered when requesting data for this print job. + # \param owner: The name of the user who added the print job to Cura Connect. + # \param printer_uuid: UUID of the printer that the job is currently printing on or assigned to. + # \param started: Whether the job has started printing or not. + # \param status: The status of the print job. + # \param time_elapsed: The remaining printing time in seconds. + # \param time_total: The total printing time in seconds. + # \param uuid: UUID of this print job. Should be used for identification purposes. + def __init__(self, created_at: str, force: bool, machine_variant: str, name: str, started: bool, status: str, + time_total: int, uuid: str, + configuration: List[Union[Dict[str, any], CloudClusterPrinterConfiguration]], + constraints: List[Union[Dict[str, any], CloudClusterPrintJobConstraints]], + last_seen: Optional[float] = None, network_error_count: Optional[int] = None, + owner: Optional[str] = None, printer_uuid: Optional[str] = None, time_elapsed: Optional[int] = None, + assigned_to: Optional[str] = None, **kwargs) -> None: + self.assigned_to = assigned_to # type: str + self.configuration = self.parseModels(CloudClusterPrinterConfiguration, configuration) + self.constraints = self.parseModels(CloudClusterPrintJobConstraints, constraints) + self.created_at = created_at + self.force = force + self.last_seen = last_seen + self.machine_variant = machine_variant + self.name = name + self.network_error_count = network_error_count + self.owner = owner + self.printer_uuid = printer_uuid + self.started = started + self.status = status + self.time_elapsed = time_elapsed + self.time_total = time_total + self.uuid = uuid + super().__init__(**kwargs) + + ## Creates an UM3 print job output model based on this cloud cluster print job. + # \param printer: The output model of the printer + def createOutputModel(self, controller: CloudOutputController) -> UM3PrintJobOutputModel: + model = UM3PrintJobOutputModel(controller, self.uuid, self.name) + self.updateOutputModel(model) + + return model + + ## Creates a new configuration model + def _createConfigurationModel(self) -> ConfigurationModel: + extruders = [extruder.createConfigurationModel() for extruder in self.configuration or ()] + configuration = ConfigurationModel() + configuration.setExtruderConfigurations(extruders) + return configuration + + ## Updates an UM3 print job output model based on this cloud cluster print job. + # \param model: The model to update. + def updateOutputModel(self, model: UM3PrintJobOutputModel) -> None: + # TODO: Add `compatible_machine_families` to the cloud, than add model.setCompatibleMachineFamilies() + # TODO: Add `impediments_to_printing` to the cloud, see ClusterUM3OutputDevice._updatePrintJob + # TODO: Use model.updateConfigurationChanges, see ClusterUM3OutputDevice#_createConfigurationChanges + model.updateConfiguration(self._createConfigurationModel()) + model.updateTimeTotal(self.time_total) + model.updateTimeElapsed(self.time_elapsed) + model.updateOwner(self.owner) + model.updateState(self.status) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinter.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinter.py deleted file mode 100644 index 9057743621..0000000000 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinter.py +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright (c) 2018 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. -from typing import List - -from cura.PrinterOutput.ConfigurationModel import ConfigurationModel -from cura.PrinterOutput.PrinterOutputController import PrinterOutputController -from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel -from .CloudClusterPrinterConfiguration import CloudClusterPrinterConfiguration -from .BaseCloudModel import BaseCloudModel - - -## Class representing a cluster printer -class CloudClusterPrinter(BaseCloudModel): - def __init__(self, **kwargs) -> None: - self.configuration = [] # type: List[CloudClusterPrinterConfiguration] - self.enabled = None # type: str - self.firmware_version = None # type: str - self.friendly_name = None # type: str - self.ip_address = None # type: str - self.machine_variant = None # type: str - self.status = None # type: str - self.unique_name = None # type: str - self.uuid = None # type: str - super().__init__(**kwargs) - - self.configuration = [CloudClusterPrinterConfiguration(**c) - if isinstance(c, dict) else c for c in self.configuration] - - ## Creates a new output model. - # \param controller - The controller of the model. - def createOutputModel(self, controller: PrinterOutputController) -> PrinterOutputModel: - model = PrinterOutputModel(controller, len(self.configuration), firmware_version = self.firmware_version) - self.updateOutputModel(model) - return model - - ## Updates the given output model. - # \param model - The output model to update. - def updateOutputModel(self, model: PrinterOutputModel) -> None: - model.updateKey(self.uuid) - model.updateName(self.friendly_name) - model.updateType(self.machine_variant) - model.updateState(self.status if self.enabled else "disabled") - - for configuration, extruder_output, extruder_config in \ - zip(self.configuration, model.extruders, model.printerConfiguration.extruderConfigurations): - configuration.updateOutputModel(extruder_output) - configuration.updateConfigurationModel(extruder_config) - - pass diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py index c14a7f85c3..a6319ed6bb 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py @@ -1,5 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +from typing import Union, Dict, Optional + from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel from cura.PrinterOutput.ExtruderOutputModel import ExtruderOutputModel from .CloudClusterPrinterConfigurationMaterial import CloudClusterPrinterConfigurationMaterial @@ -7,17 +9,22 @@ from .BaseCloudModel import BaseCloudModel ## Class representing a cloud cluster printer configuration +# Spec: https://api-staging.ultimaker.com/connect/v1/spec class CloudClusterPrinterConfiguration(BaseCloudModel): - def __init__(self, **kwargs) -> None: - self.extruder_index = None # type: int - self.material = None # type: CloudClusterPrinterConfigurationMaterial - self.nozzle_diameter = None # type: str - self.print_core_id = None # type: str + ## Creates a new cloud cluster printer configuration object + # \param extruder_index: The position of the extruder on the machine as list index. Numbered from left to right. + # \param material: The material of a configuration object in a cluster printer. May be in a dict or an object. + # \param nozzle_diameter: The diameter of the print core at this position in millimeters, e.g. '0.4'. + # \param print_core_id: The type of print core inserted at this position, e.g. 'AA 0.4'. + def __init__(self, extruder_index: int, + material: Union[None, Dict[str, any], CloudClusterPrinterConfigurationMaterial], + nozzle_diameter: Optional[str] = None, print_core_id: Optional[str] = None, **kwargs) -> None: + self.extruder_index = extruder_index + self.material = self.parseModel(CloudClusterPrinterConfigurationMaterial, material) + self.nozzle_diameter = nozzle_diameter + self.print_core_id = print_core_id super().__init__(**kwargs) - if isinstance(self.material, dict): - self.material = CloudClusterPrinterConfigurationMaterial(**self.material) - ## Updates the given output model. # \param model - The output model to update. def updateOutputModel(self, model: ExtruderOutputModel) -> None: diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfigurationMaterial.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfigurationMaterial.py index e5f52ac630..652cbdabda 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfigurationMaterial.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfigurationMaterial.py @@ -1,3 +1,5 @@ +from typing import Optional + from UM.Logger import Logger from cura.CuraApplication import CuraApplication from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel @@ -5,12 +7,19 @@ from .BaseCloudModel import BaseCloudModel ## Class representing a cloud cluster printer configuration +# Spec: https://api-staging.ultimaker.com/connect/v1/spec class CloudClusterPrinterConfigurationMaterial(BaseCloudModel): - def __init__(self, **kwargs) -> None: - self.guid = None # type: str - self.brand = None # type: str - self.color = None # type: str - self.material = None # type: str + ## Creates a new material configuration model. + # \param brand: The brand of material in this print core, e.g. 'Ultimaker'. + # \param color: The color of material in this print core, e.g. 'Blue'. + # \param guid: he GUID of the material in this print core, e.g. '506c9f0d-e3aa-4bd4-b2d2-23e2425b1aa9'. + # \param material: The type of material in this print core, e.g. 'PLA'. + def __init__(self, brand: Optional[str] = None, color: Optional[str] = None, guid: Optional[str] = None, + material: Optional[str] = None, **kwargs) -> None: + self.guid = guid + self.brand = brand + self.color = color + self.material = material super().__init__(**kwargs) ## Creates a material output model based on this cloud printer material. diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterStatus.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterStatus.py new file mode 100644 index 0000000000..b25f21fde2 --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterStatus.py @@ -0,0 +1,60 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +from typing import List, Union, Dict, Optional + +from cura.PrinterOutput.PrinterOutputController import PrinterOutputController +from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel +from .CloudClusterPrinterConfiguration import CloudClusterPrinterConfiguration +from .BaseCloudModel import BaseCloudModel + + +## Class representing a cluster printer +# Spec: https://api-staging.ultimaker.com/connect/v1/spec +class CloudClusterPrinterStatus(BaseCloudModel): + ## Creates a new cluster printer status + # \param enabled: A printer can be disabled if it should not receive new jobs. By default every printer is enabled. + # \param firmware_version: Firmware version installed on the printer. Can differ for each printer in a cluster. + # \param friendly_name: Human readable name of the printer. Can be used for identification purposes. + # \param ip_address: The IP address of the printer in the local network. + # \param machine_variant: The type of printer. Can be 'Ultimaker 3' or 'Ultimaker 3ext'. + # \param status: The status of the printer. + # \param unique_name: The unique name of the printer in the network. + # \param uuid: The unique ID of the printer, also known as GUID. + # \param configuration: The active print core configurations of this printer. + # \param reserved_by: A printer can be claimed by a specific print job. + def __init__(self, enabled: bool, firmware_version: str, friendly_name: str, ip_address: str, machine_variant: str, + status: str, unique_name: str, uuid: str, + configuration: List[Union[Dict[str, any], CloudClusterPrinterConfiguration]], + reserved_by: Optional[str] = None, **kwargs) -> None: + + self.configuration = self.parseModels(CloudClusterPrinterConfiguration, configuration) + self.enabled = enabled + self.firmware_version = firmware_version + self.friendly_name = friendly_name + self.ip_address = ip_address + self.machine_variant = machine_variant + self.status = status + self.unique_name = unique_name + self.uuid = uuid + self.reserved_by = reserved_by + super().__init__(**kwargs) + + ## Creates a new output model. + # \param controller - The controller of the model. + def createOutputModel(self, controller: PrinterOutputController) -> PrinterOutputModel: + model = PrinterOutputModel(controller, len(self.configuration), firmware_version = self.firmware_version) + self.updateOutputModel(model) + return model + + ## Updates the given output model. + # \param model - The output model to update. + def updateOutputModel(self, model: PrinterOutputModel) -> None: + model.updateKey(self.uuid) + model.updateName(self.friendly_name) + model.updateType(self.machine_variant) + model.updateState(self.status if self.enabled else "disabled") + + for configuration, extruder_output, extruder_config in \ + zip(self.configuration, model.extruders, model.printerConfiguration.extruderConfigurations): + configuration.updateOutputModel(extruder_output) + configuration.updateConfigurationModel(extruder_config) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterResponse.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterResponse.py new file mode 100644 index 0000000000..a3eda54a76 --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterResponse.py @@ -0,0 +1,32 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +from typing import Optional + +from .BaseCloudModel import BaseCloudModel + + +## Class representing a cloud connected cluster. +# Spec: https://api-staging.ultimaker.com/connect/v1/spec +class CloudClusterResponse(BaseCloudModel): + ## Creates a new cluster response object. + # \param cluster_id: The secret unique ID, e.g. 'kBEeZWEifXbrXviO8mRYLx45P8k5lHVGs43XKvRniPg='. + # \param host_guid: The unique identifier of the print cluster host, e.g. 'e90ae0ac-1257-4403-91ee-a44c9b7e8050'. + # \param host_name: The name of the printer as configured during the Wi-Fi setup. Used as identifier for end users. + # \param is_online: Whether this cluster is currently connected to the cloud. + # \param status: The status of the cluster authentication (active or inactive). + # \param host_version: The firmware version of the cluster host. This is where the Stardust client is running on. + def __init__(self, cluster_id: str, host_guid: str, host_name: str, is_online: bool, status: str, + host_version: Optional[str] = None, **kwargs): + self.cluster_id = cluster_id + self.host_guid = host_guid + self.host_name = host_name + self.status = status + self.is_online = is_online + self.host_version = host_version + super().__init__(**kwargs) + + # Validates the model, raising an exception if the model is invalid. + def validate(self) -> None: + super().validate() + if not self.cluster_id: + raise ValueError("cluster_id is required on CloudCluster") diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterStatus.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterStatus.py index 77ed979dbc..2cebb1b592 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterStatus.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterStatus.py @@ -1,28 +1,26 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. from datetime import datetime -from typing import List +from typing import List, Dict, Union -from .CloudClusterPrinter import CloudClusterPrinter -from .CloudClusterPrintJob import CloudClusterPrintJob +from .CloudClusterPrinterStatus import CloudClusterPrinterStatus +from .CloudClusterPrintJobStatus import CloudClusterPrintJobStatus from .BaseCloudModel import BaseCloudModel # Model that represents the status of the cluster for the cloud +# Spec: https://api-staging.ultimaker.com/connect/v1/spec class CloudClusterStatus(BaseCloudModel): - def __init__(self, **kwargs) -> None: - self.generated_time = None # type: datetime - # a list of the printers - self.printers = [] # type: List[CloudClusterPrinter] - # a list of the print jobs - self.print_jobs = [] # type: List[CloudClusterPrintJob] - + ## Creates a new cluster status model object. + # \param printers: The latest status of each printer in the cluster. + # \param print_jobs: The latest status of each print job in the cluster. + # \param generated_time: The datetime when the object was generated on the server-side. + def __init__(self, + printers: List[Union[CloudClusterPrinterStatus, Dict[str, any]]], + print_jobs: List[Union[CloudClusterPrintJobStatus, Dict[str, any]]], + generated_time: Union[str, datetime], + **kwargs) -> None: + self.generated_time = self.parseDate(generated_time) + self.printers = self.parseModels(CloudClusterPrinterStatus, printers) + self.print_jobs = self.parseModels(CloudClusterPrintJobStatus, print_jobs) super().__init__(**kwargs) - - # converting any dictionaries into models - self.printers = [CloudClusterPrinter(**p) if isinstance(p, dict) else p for p in self.printers] - self.print_jobs = [CloudClusterPrintJob(**j) if isinstance(j, dict) else j for j in self.print_jobs] - - # converting generated time into datetime - if isinstance(self.generated_time, str): - self.generated_time = self.parseDate(self.generated_time) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudErrorObject.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudErrorObject.py index 9696cbcb7a..c02a21d4da 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudErrorObject.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudErrorObject.py @@ -1,17 +1,28 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import Dict +from typing import Dict, Optional from .BaseCloudModel import BaseCloudModel -## Class representing errors generated by the cloud servers, according to the json-api standard. +## Class representing errors generated by the cloud servers, according to the JSON-API standard. +# Spec: https://api-staging.ultimaker.com/connect/v1/spec class CloudErrorObject(BaseCloudModel): - def __init__(self, **kwargs) -> None: - self.id = None # type: str - self.code = None # type: str - self.http_status = None # type: str - self.title = None # type: str - self.detail = None # type: str - self.meta = None # type: Dict[str, any] + ## Creates a new error object. + # \param id: Unique identifier for this particular occurrence of the problem. + # \param title: A short, human-readable summary of the problem that SHOULD NOT change from occurrence to occurrence + # of the problem, except for purposes of localization. + # \param code: An application-specific error code, expressed as a string value. + # \param detail: A human-readable explanation specific to this occurrence of the problem. Like title, this field's + # value can be localized. + # \param http_status: The HTTP status code applicable to this problem, converted to string. + # \param meta: Non-standard meta-information about the error, depending on the error code. + def __init__(self, id: str, code: str, title: str, http_status: str, detail: Optional[str] = None, + meta: Optional[Dict[str, any]] = None, **kwargs) -> None: + self.id = id + self.code = code + self.http_status = http_status + self.title = title + self.detail = detail + self.meta = meta super().__init__(**kwargs) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobResponse.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobResponse.py deleted file mode 100644 index e3161449a5..0000000000 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobResponse.py +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (c) 2018 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. -from .BaseCloudModel import BaseCloudModel - - -# Model that represents the response received from the cloud after requesting to upload a print job -class CloudJobResponse(BaseCloudModel): - def __init__(self, **kwargs) -> None: - self.download_url = None # type: str - self.job_id = None # type: str - self.job_name = None # type: str - self.slicing_details = None # type: str - self.status = None # type: str - self.upload_url = None # type: str - self.content_type = None # type: str - super().__init__(**kwargs) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobUploadRequest.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobUploadRequest.py deleted file mode 100644 index 07a781e2d6..0000000000 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudJobUploadRequest.py +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright (c) 2018 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. -from .BaseCloudModel import BaseCloudModel - - -# Model that represents the request to upload a print job to the cloud -class CloudJobUploadRequest(BaseCloudModel): - def __init__(self, **kwargs) -> None: - self.file_size = None # type: int - self.job_name = None # type: str - self.content_type = None # type: str - super().__init__(**kwargs) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintJobResponse.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintJobResponse.py new file mode 100644 index 0000000000..79196ee38c --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintJobResponse.py @@ -0,0 +1,33 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +from typing import Optional + +from .BaseCloudModel import BaseCloudModel + + +# Model that represents the response received from the cloud after requesting to upload a print job +# Spec: https://api-staging.ultimaker.com/cura/v1/spec +class CloudPrintJobResponse(BaseCloudModel): + ## Creates a new print job response model. + # \param job_id: The job unique ID, e.g. 'kBEeZWEifXbrXviO8mRYLx45P8k5lHVGs43XKvRniPg='. + # \param status: The status of the print job. + # \param status_description: Contains more details about the status, e.g. the cause of failures. + # \param download_url: A signed URL to download the resulting status. Only available when the job is finished. + # \param job_name: The name of the print job. + # \param slicing_details: Model for slice information. + # \param upload_url: The one-time use URL where the toolpath must be uploaded to (only if status is uploading). + # \param content_type: The content type of the print job (e.g. text/plain or application/gzip) + # \param generated_time: The datetime when the object was generated on the server-side. + def __init__(self, job_id: str, status: str, download_url: Optional[str] = None, job_name: Optional[str] = None, + upload_url: Optional[str] = None, content_type: Optional[str] = None, + status_description: Optional[str] = None, slicing_details: Optional[dict] = None, **kwargs) -> None: + self.job_id = job_id + self.status = status + self.download_url = download_url + self.job_name = job_name + self.upload_url = upload_url + self.content_type = content_type + self.status_description = status_description + # TODO: Implement slicing details + self.slicing_details = slicing_details + super().__init__(**kwargs) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintJobUploadRequest.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintJobUploadRequest.py new file mode 100644 index 0000000000..e59c571558 --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintJobUploadRequest.py @@ -0,0 +1,17 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +from .BaseCloudModel import BaseCloudModel + + +# Model that represents the request to upload a print job to the cloud +# Spec: https://api-staging.ultimaker.com/cura/v1/spec +class CloudPrintJobUploadRequest(BaseCloudModel): + ## Creates a new print job upload request. + # \param job_name: The name of the print job. + # \param file_size: The size of the file in bytes. + # \param content_type: The content type of the print job (e.g. text/plain or application/gzip) + def __init__(self, job_name: str, file_size: int, content_type: str, **kwargs) -> None: + self.job_name = job_name + self.file_size = file_size + self.content_type = content_type + super().__init__(**kwargs) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintResponse.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintResponse.py index 3e9ad584dc..919d1b3c3a 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintResponse.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintResponse.py @@ -1,12 +1,23 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +from datetime import datetime +from typing import Optional, Union + from .BaseCloudModel import BaseCloudModel # Model that represents the responses received from the cloud after requesting a job to be printed. +# Spec: https://api-staging.ultimaker.com/connect/v1/spec class CloudPrintResponse(BaseCloudModel): - def __init__(self, **kwargs) -> None: - self.cluster_job_id = None # type: str - self.job_id = None # type: str - self.status = None # type: str + ## Creates a new print response object. + # \param job_id: The unique ID of a print job inside of the cluster. This ID is generated by Cura Connect. + # \param status: The status of the print request (queued or failed). + # \param generated_time: The datetime when the object was generated on the server-side. + # \param cluster_job_id: The unique ID of a print job inside of the cluster. This ID is generated by Cura Connect. + def __init__(self, job_id: str, status: str, generated_time: Union[str, datetime], + cluster_job_id: Optional[str] = None, **kwargs) -> None: + self.job_id = job_id + self.status = status + self.cluster_job_id = cluster_job_id + self.generated_time = self.parseDate(generated_time) super().__init__(**kwargs) diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/postJobPrintResponse.json b/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/postJobPrintResponse.json index 8b9574359f..caedcd8732 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/postJobPrintResponse.json +++ b/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/postJobPrintResponse.json @@ -2,6 +2,7 @@ "data": { "cluster_job_id": "9a59d8e9-91d3-4ff6-b4cb-9db91c4094dd", "job_id": "ABCDefGHIjKlMNOpQrSTUvYxWZ0-1234567890abcDE=", - "status": "queued" + "status": "queued", + "generated_time": "2018-12-10T08:23:55.110Z" } } diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/putJobUploadResponse.json b/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/putJobUploadResponse.json index 0474862720..1304f3a9f6 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/putJobUploadResponse.json +++ b/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/putJobUploadResponse.json @@ -1,10 +1,9 @@ { "data": { "content_type": "text/plain", - "download_url": "https://api.ultimaker.com/print-job-download", "job_id": "ABCDefGHIjKlMNOpQrSTUvYxWZ0-1234567890abcDE=", "job_name": "Ultimaker Robot v3.0", - "status": "queued", + "status": "uploading", "upload_url": "https://api.ultimaker.com/print-job-upload" } } diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/requestPrintResponse.json b/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/requestPrintResponse.json deleted file mode 100644 index e69589784d..0000000000 --- a/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/requestPrintResponse.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "data": { - "cluster_job_id": "", - "job_id": "db34b096-c4d5-46f3-bea7-da6a19905e6c", - "status": "queued" - } -} diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/requestUploadResponse.json b/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/requestUploadResponse.json deleted file mode 100644 index 6168e5205f..0000000000 --- a/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/requestUploadResponse.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "data": { - "content_type": "text/plain", - "generated_time": "2018-12-10T09:33:00.009Z", - "job_id": "j9KUn4D6FRRRmdtbCo4OGAwUf6Ml3p3oU-Zv7RNRv92T", - "job_name": "job name", - "status": "uploading", - "status_description": "The print job has been created. Please upload the file.", - "upload_url": "https://www.googleapis.com/upload/storage/v1/b/ultimaker-storage-1/o?uploadType=resumable&upload_id=AEnB2Uqhg1H7BXQVeLJEWw6AheqMicydZVLuH9bnkh6Oge0e6i5X76MW3NZHWRmUTmjzulAF42mkczcC7rsAuPg1Nn8JeFpnNA" - } -} diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py index 07c7733ac1..84f0254b55 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py @@ -1,7 +1,6 @@ # Copyright (c) 2018 Ultimaker B.V. # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -import json import os from unittest import TestCase from unittest.mock import patch, MagicMock @@ -9,8 +8,9 @@ from unittest.mock import patch, MagicMock from cura.CuraApplication import CuraApplication from src.Cloud.CloudApiClient import CloudApiClient from src.Cloud.CloudOutputDeviceManager import CloudOutputDeviceManager -from src.Cloud.Models.CloudJobResponse import CloudJobResponse -from src.Cloud.Models.CloudJobUploadRequest import CloudJobUploadRequest +from src.Cloud.Models.CloudPrintJobResponse import CloudPrintJobResponse +from src.Cloud.Models.CloudPrintJobUploadRequest import CloudPrintJobUploadRequest +from tests.Cloud.Fixtures import readFixture, parseFixture from .NetworkManagerMock import NetworkManagerMock @@ -71,12 +71,11 @@ class TestCloudApiClient(TestCase): network_mock.return_value = self.network results = [] - with open("{}/Fixtures/requestUploadResponse.json".format(os.path.dirname(__file__)), "rb") as f: - response = f.read() + response = readFixture("putJobUploadResponse") self.network.prepareReply("PUT", "https://api-staging.ultimaker.com/cura/v1/jobs/upload", 200, response) - self.api.requestUpload(CloudJobUploadRequest(job_name = "job name", file_size = 143234, content_type = "text/plain"), - lambda r: results.append(r)) + request = CloudPrintJobUploadRequest(job_name = "job name", file_size = 143234, content_type = "text/plain") + self.api.requestUpload(request, lambda r: results.append(r)) self.network.flushReplies() self.assertEqual(results[0].content_type, "text/plain") @@ -87,13 +86,11 @@ class TestCloudApiClient(TestCase): results = [] progress = MagicMock() - with open("{}/Fixtures/requestUploadResponse.json".format(os.path.dirname(__file__)), "rb") as f: - thedata = json.loads(f.read().decode("ascii")) - data = thedata["data"] - upload_response = CloudJobResponse(**data) + data = parseFixture("putJobUploadResponse")["data"] + upload_response = CloudPrintJobResponse(**data) self.network.prepareReply("PUT", upload_response.upload_url, 200, - '{ data : "" }') # Network client doesn't look into the reply + b'{ data : "" }') # Network client doesn't look into the reply self.api.uploadMesh(upload_response, b'', lambda job_id: results.append(job_id), progress.advance, progress.error) @@ -107,11 +104,11 @@ class TestCloudApiClient(TestCase): network_mock.return_value = self.network results = [] - cluster_id = "NWKV6vJP_LdYsXgXqAcaNCR0YcLJwar1ugh0ikEZsZs8" - job_id = "db34b096-c4d5-46f3-bea7-da6a19905e6c" + response = readFixture("postJobPrintResponse") - with open("{}/Fixtures/requestPrintResponse.json".format(os.path.dirname(__file__)), "rb") as f: - response = f.read() + cluster_id = "NWKV6vJP_LdYsXgXqAcaNCR0YcLJwar1ugh0ikEZsZs8" + cluster_job_id = "9a59d8e9-91d3-4ff6-b4cb-9db91c4094dd" + job_id = "ABCDefGHIjKlMNOpQrSTUvYxWZ0-1234567890abcDE=" self.network.prepareReply("POST", "https://api-staging.ultimaker.com/connect/v1/clusters/{}/print/{}" @@ -123,5 +120,6 @@ class TestCloudApiClient(TestCase): self.network.flushReplies() self.assertEqual(len(results), 1) - self.assertEqual(results[0].job_id, "db34b096-c4d5-46f3-bea7-da6a19905e6c") + self.assertEqual(results[0].job_id, job_id) + self.assertEqual(results[0].cluster_job_id, cluster_job_id) self.assertEqual(results[0].status, "queued") diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py index 420d71d0fe..b6bcde6e55 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py @@ -106,7 +106,9 @@ class TestCloudOutputDeviceManager(TestCase): @patch("UM.Message.Message.show") def test_api_error(self, message_mock, network_mock): - self.clusters_response = {"errors": [{"id": "notFound", "title": "Not found!", "http_status": "404"}]} + self.clusters_response = { + "errors": [{"id": "notFound", "title": "Not found!", "http_status": "404", "code": "notFound"}] + } self.network.prepareReply("GET", self.URL, 200, self.clusters_response) self._loadData(network_mock) self.network.flushReplies() From 816c6bd4ec56204b4654cd23ba71de188180e03d Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 11 Dec 2018 11:12:36 +0100 Subject: [PATCH 0853/1292] Fixes after merging UI changes --- plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 17acbe2e3f..a77a25c375 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -96,9 +96,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # We use the Cura Connect monitor tab to get most functionality right away. self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), - "../../resources/qml/ClusterMonitorItem.qml") - self._control_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), - "../../resources/qml/ClusterControlItem.qml") + "../../resources/qml/MonitorStage.qml") # Trigger the printersChanged signal when the private signal is triggered. self.printersChanged.connect(self._clusterPrintersChanged) From 2b2e8ebb31ffaacdcd6cac3851585de94af556c4 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 11 Dec 2018 11:37:01 +0100 Subject: [PATCH 0854/1292] Add some safety checks when checking for the guid of the material Don't crash if the guid doesn't exist. Contributes to CL-1160. --- .../UM3NetworkPrinting/src/ClusterUM3OutputDevice.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index 60474156a8..d39cf6e41c 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -607,13 +607,18 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): def _createMaterialOutputModel(self, material_data: Dict[str, Any]) -> "MaterialOutputModel": material_manager = CuraApplication.getInstance().getMaterialManager() - material_group_list = material_manager.getMaterialGroupListByGUID(material_data["guid"]) + material_group_list = None + + # Avoid crashing if there is no "guid" field in the metadata + material_guid = material_data.get("guid") + if material_guid: + material_group_list = material_manager.getMaterialGroupListByGUID(material_guid) # This can happen if the connected machine has no material in one or more extruders (if GUID is empty), or the # material is unknown to Cura, so we should return an "empty" or "unknown" material model. if material_group_list is None: - material_name = "Empty" if len(material_data["guid"]) == 0 else "Unknown" - return MaterialOutputModel(guid = material_data["guid"], + material_name = "Empty" if len(material_data.get("guid", "") == 0 else "Unknown" + return MaterialOutputModel(guid = material_data.get("guid", ""), type = material_data.get("type", ""), color = material_data.get("color", ""), brand = material_data.get("brand", ""), From 1c373b720541691f4bd8d9e20a93b5596de04c32 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 11 Dec 2018 11:51:13 +0100 Subject: [PATCH 0855/1292] Improve config override text Contributes to CL-1152 --- .../resources/qml/MonitorConfigOverrideDialog.qml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml index 1b9a03ea99..6a32310dd5 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml @@ -61,7 +61,7 @@ UM.Dialog var topLine if (materialsAreKnown(printer.activePrintJob)) { - topLine = catalog.i18ncp("@label", "The assigned printer, %1, requires the following configuration change:", "The assigned printer, %1, requires the following configuration changes:").arg(printer.name) + topLine = catalog.i18ncp("@label", "The assigned printer, %1, requires the following configuration change:", "The assigned printer, %1, requires the following configuration changes:", printer.activePrintJob.configurationChanges.length).arg(printer.name) } else { @@ -89,8 +89,10 @@ UM.Dialog default: text = "unknown" } - result += "

    " + text + "

    " + result += "

    " + text + "

    \n\n" } + var bottomLine = catalog.i18nc("@label", "Override will use the specified settings with the existing printer configuration. This may result in a failed print.") + result += "

    " + bottomLine + "

    \n\n" return result } } From 70b0d16fa4827f74632e8b57e3c01db0ed3aabdf Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 11 Dec 2018 11:53:26 +0100 Subject: [PATCH 0856/1292] Fix typo Missing parenthesis. Contributes to CL-1160. --- plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index d39cf6e41c..275087447e 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -617,7 +617,7 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): # This can happen if the connected machine has no material in one or more extruders (if GUID is empty), or the # material is unknown to Cura, so we should return an "empty" or "unknown" material model. if material_group_list is None: - material_name = "Empty" if len(material_data.get("guid", "") == 0 else "Unknown" + material_name = "Empty" if len(material_data.get("guid", "")) == 0 else "Unknown" return MaterialOutputModel(guid = material_data.get("guid", ""), type = material_data.get("type", ""), color = material_data.get("color", ""), From 76b9fa79986d2622eca7a7316ba65a05aaaa95bd Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 11 Dec 2018 11:53:12 +0100 Subject: [PATCH 0857/1292] Use "cura" as i18n catalog for CuraDrive CURA-6005 --- plugins/CuraDrive/plugin.json | 2 +- plugins/CuraDrive/src/Settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/CuraDrive/plugin.json b/plugins/CuraDrive/plugin.json index 44bf955f41..6cf1fa273c 100644 --- a/plugins/CuraDrive/plugin.json +++ b/plugins/CuraDrive/plugin.json @@ -4,5 +4,5 @@ "description": "Backup and restore your configuration.", "version": "1.2.0", "api": 5, - "i18n-catalog": "cura_drive" + "i18n-catalog": "cura" } diff --git a/plugins/CuraDrive/src/Settings.py b/plugins/CuraDrive/src/Settings.py index 277a976cc7..f10a7d3bf7 100644 --- a/plugins/CuraDrive/src/Settings.py +++ b/plugins/CuraDrive/src/Settings.py @@ -13,7 +13,7 @@ class Settings: AUTO_BACKUP_ENABLED_PREFERENCE_KEY = "cura_drive/auto_backup_enabled" AUTO_BACKUP_LAST_DATE_PREFERENCE_KEY = "cura_drive/auto_backup_date" - I18N_CATALOG_ID = "cura_drive" + I18N_CATALOG_ID = "cura" I18N_CATALOG = i18nCatalog(I18N_CATALOG_ID) MESSAGE_TITLE = I18N_CATALOG.i18nc("@info:title", "Backups"), From d54fc4182b6355123a6ef3c51c51e974fcc188bb Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Tue, 11 Dec 2018 11:56:36 +0100 Subject: [PATCH 0858/1292] STAR-322: Fixing style errors --- .../src/Cloud/CloudApiClient.py | 2 +- .../src/Cloud/Models/BaseCloudModel.py | 8 +++--- .../Models/CloudClusterPrintJobStatus.py | 8 +++--- .../CloudClusterPrinterConfiguration.py | 19 ++++++++----- .../Cloud/Models/CloudClusterPrinterStatus.py | 4 +-- .../src/Cloud/Models/CloudClusterResponse.py | 2 +- .../src/Cloud/Models/CloudClusterStatus.py | 6 ++-- .../src/Cloud/Models/CloudErrorObject.py | 4 +-- .../src/ClusterUM3OutputDevice.py | 28 +++---------------- .../src/MeshFormatHandler.py | 26 +++++++++++------ .../UM3NetworkPrinting/src/SendMaterialJob.py | 8 ++++-- .../src/UM3PrintJobOutputModel.py | 9 +++--- .../tests/Cloud/Models/__init__.py | 2 ++ .../tests/Cloud/NetworkManagerMock.py | 7 +++-- .../tests/Cloud/TestCloudApiClient.py | 8 +++--- 15 files changed, 69 insertions(+), 72 deletions(-) create mode 100644 plugins/UM3NetworkPrinting/tests/Cloud/Models/__init__.py diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py index 9cc70587a3..474d76d85a 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py @@ -31,7 +31,7 @@ class CloudApiClient(NetworkClient): ## Initializes a new cloud API client. # \param account: The user's account object # \param on_error: The callback to be called whenever we receive errors from the server. - def __init__(self, account: Account, on_error: Callable[[List[CloudErrorObject]], None]): + def __init__(self, account: Account, on_error: Callable[[List[CloudErrorObject]], None]) -> None: super().__init__() self._account = account self._on_error = on_error diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/BaseCloudModel.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/BaseCloudModel.py index 3a0e93e836..18a8cb5cba 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/BaseCloudModel.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/BaseCloudModel.py @@ -1,7 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. from datetime import datetime, timezone -from typing import Dict, Union, TypeVar, Type, List +from typing import Dict, Union, TypeVar, Type, List, Any from ...Models import BaseModel @@ -21,7 +21,7 @@ class BaseCloudModel(BaseModel): return type(self) != type(other) or self.toDict() != other.toDict() ## Converts the model into a serializable dictionary - def toDict(self) -> Dict[str, any]: + def toDict(self) -> Dict[str, Any]: return self.__dict__ # Type variable used in the parse methods below, which should be a subclass of BaseModel. @@ -32,7 +32,7 @@ class BaseCloudModel(BaseModel): # \param values: The value of the model, which is usually a dictionary, but may also be already parsed. # \return An instance of the model_class given. @staticmethod - def parseModel(model_class: Type[T], values: Union[T, Dict[str, any]]) -> T: + def parseModel(model_class: Type[T], values: Union[T, Dict[str, Any]]) -> T: if isinstance(values, dict): return model_class(**values) return values @@ -42,7 +42,7 @@ class BaseCloudModel(BaseModel): # \param values: The value of the list. Each value is usually a dictionary, but may also be already parsed. # \return A list of instances of the model_class given. @classmethod - def parseModels(cls, model_class: Type[T], values: List[Union[T, Dict[str, any]]]) -> List[T]: + def parseModels(cls, model_class: Type[T], values: List[Union[T, Dict[str, Any]]]) -> List[T]: return [cls.parseModel(model_class, value) for value in values] ## Parses the given date string. diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py index 24ef9078d6..f451665a4f 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py @@ -1,6 +1,6 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import List, Optional, Union, Dict +from typing import List, Optional, Union, Dict, Any from cura.PrinterOutput.ConfigurationModel import ConfigurationModel from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputController import CloudOutputController @@ -36,12 +36,12 @@ class CloudClusterPrintJobStatus(BaseCloudModel): # \param uuid: UUID of this print job. Should be used for identification purposes. def __init__(self, created_at: str, force: bool, machine_variant: str, name: str, started: bool, status: str, time_total: int, uuid: str, - configuration: List[Union[Dict[str, any], CloudClusterPrinterConfiguration]], - constraints: List[Union[Dict[str, any], CloudClusterPrintJobConstraints]], + configuration: List[Union[Dict[str, Any], CloudClusterPrinterConfiguration]], + constraints: List[Union[Dict[str, Any], CloudClusterPrintJobConstraints]], last_seen: Optional[float] = None, network_error_count: Optional[int] = None, owner: Optional[str] = None, printer_uuid: Optional[str] = None, time_elapsed: Optional[int] = None, assigned_to: Optional[str] = None, **kwargs) -> None: - self.assigned_to = assigned_to # type: str + self.assigned_to = assigned_to self.configuration = self.parseModels(CloudClusterPrinterConfiguration, configuration) self.constraints = self.parseModels(CloudClusterPrintJobConstraints, constraints) self.created_at = created_at diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py index a6319ed6bb..3e06d0e2e7 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py @@ -1,6 +1,6 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import Union, Dict, Optional +from typing import Union, Dict, Optional, Any from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel from cura.PrinterOutput.ExtruderOutputModel import ExtruderOutputModel @@ -17,10 +17,10 @@ class CloudClusterPrinterConfiguration(BaseCloudModel): # \param nozzle_diameter: The diameter of the print core at this position in millimeters, e.g. '0.4'. # \param print_core_id: The type of print core inserted at this position, e.g. 'AA 0.4'. def __init__(self, extruder_index: int, - material: Union[None, Dict[str, any], CloudClusterPrinterConfigurationMaterial], + material: Union[None, Dict[str, Any], CloudClusterPrinterConfigurationMaterial], nozzle_diameter: Optional[str] = None, print_core_id: Optional[str] = None, **kwargs) -> None: self.extruder_index = extruder_index - self.material = self.parseModel(CloudClusterPrinterConfigurationMaterial, material) + self.material = self.parseModel(CloudClusterPrinterConfigurationMaterial, material) if material else None self.nozzle_diameter = nozzle_diameter self.print_core_id = print_core_id super().__init__(**kwargs) @@ -28,11 +28,16 @@ class CloudClusterPrinterConfiguration(BaseCloudModel): ## Updates the given output model. # \param model - The output model to update. def updateOutputModel(self, model: ExtruderOutputModel) -> None: - model.updateHotendID(self.print_core_id) + if self.print_core_id is not None: + model.updateHotendID(self.print_core_id) - if model.activeMaterial is None or model.activeMaterial.guid != self.material.guid: - material = self.material.createOutputModel() - model.updateActiveMaterial(material) + if self.material: + active_material = model.activeMaterial + if active_material is None or active_material.guid != self.material.guid: + material = self.material.createOutputModel() + model.updateActiveMaterial(material) + else: + model.updateActiveMaterial(None) ## Creates a configuration model def createConfigurationModel(self) -> ExtruderConfigurationModel: diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterStatus.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterStatus.py index b25f21fde2..cd3b6bbdca 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterStatus.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterStatus.py @@ -1,6 +1,6 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import List, Union, Dict, Optional +from typing import List, Union, Dict, Optional, Any from cura.PrinterOutput.PrinterOutputController import PrinterOutputController from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel @@ -24,7 +24,7 @@ class CloudClusterPrinterStatus(BaseCloudModel): # \param reserved_by: A printer can be claimed by a specific print job. def __init__(self, enabled: bool, firmware_version: str, friendly_name: str, ip_address: str, machine_variant: str, status: str, unique_name: str, uuid: str, - configuration: List[Union[Dict[str, any], CloudClusterPrinterConfiguration]], + configuration: List[Union[Dict[str, Any], CloudClusterPrinterConfiguration]], reserved_by: Optional[str] = None, **kwargs) -> None: self.configuration = self.parseModels(CloudClusterPrinterConfiguration, configuration) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterResponse.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterResponse.py index a3eda54a76..9c0853e7c9 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterResponse.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterResponse.py @@ -16,7 +16,7 @@ class CloudClusterResponse(BaseCloudModel): # \param status: The status of the cluster authentication (active or inactive). # \param host_version: The firmware version of the cluster host. This is where the Stardust client is running on. def __init__(self, cluster_id: str, host_guid: str, host_name: str, is_online: bool, status: str, - host_version: Optional[str] = None, **kwargs): + host_version: Optional[str] = None, **kwargs) -> None: self.cluster_id = cluster_id self.host_guid = host_guid self.host_name = host_name diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterStatus.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterStatus.py index 2cebb1b592..b0250c2ebb 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterStatus.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterStatus.py @@ -1,7 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. from datetime import datetime -from typing import List, Dict, Union +from typing import List, Dict, Union, Any from .CloudClusterPrinterStatus import CloudClusterPrinterStatus from .CloudClusterPrintJobStatus import CloudClusterPrintJobStatus @@ -16,8 +16,8 @@ class CloudClusterStatus(BaseCloudModel): # \param print_jobs: The latest status of each print job in the cluster. # \param generated_time: The datetime when the object was generated on the server-side. def __init__(self, - printers: List[Union[CloudClusterPrinterStatus, Dict[str, any]]], - print_jobs: List[Union[CloudClusterPrintJobStatus, Dict[str, any]]], + printers: List[Union[CloudClusterPrinterStatus, Dict[str, Any]]], + print_jobs: List[Union[CloudClusterPrintJobStatus, Dict[str, Any]]], generated_time: Union[str, datetime], **kwargs) -> None: self.generated_time = self.parseDate(generated_time) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudErrorObject.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudErrorObject.py index c02a21d4da..28b4d916a1 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudErrorObject.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudErrorObject.py @@ -1,6 +1,6 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import Dict, Optional +from typing import Dict, Optional, Any from .BaseCloudModel import BaseCloudModel @@ -18,7 +18,7 @@ class CloudErrorObject(BaseCloudModel): # \param http_status: The HTTP status code applicable to this problem, converted to string. # \param meta: Non-standard meta-information about the error, depending on the error code. def __init__(self, id: str, code: str, title: str, http_status: str, detail: Optional[str] = None, - meta: Optional[Dict[str, any]] = None, **kwargs) -> None: + meta: Optional[Dict[str, Any]] = None, **kwargs) -> None: self.id = id self.code = code self.http_status = http_status diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index 93a53373dc..394c3d8552 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -56,7 +56,8 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): self._number_of_extruders = 2 - self._dummy_lambdas = ("", {}, io.BytesIO()) #type: Tuple[str, Dict, Union[io.StringIO, io.BytesIO]] + self._dummy_lambdas = ("", {}, io.BytesIO() + ) # type: Tuple[str, Dict[str, Union[str, int, bool]], Union[io.StringIO, io.BytesIO]] self._print_jobs = [] # type: List[UM3PrintJobOutputModel] self._received_print_jobs = False # type: bool @@ -254,7 +255,8 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): # Treat upload progress as response. Uploading can take more than 10 seconds, so if we don't, we can get # timeout responses if this happens. self._last_response_time = time() - if self._progress_message and new_progress > self._progress_message.getProgress(): + old_progress = self._progress_message.getProgress() + if self._progress_message and (old_progress is None or new_progress > old_progress): self._progress_message.show() # Ensure that the message is visible. self._progress_message.setProgress(bytes_sent / bytes_total * 100) @@ -345,28 +347,6 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): def getDateCompleted(self, time_remaining: int) -> str: return formatDateCompleted(time_remaining) - @pyqtSlot(int, result = str) - def getDateCompleted(self, time_remaining: int) -> str: - current_time = time() - completed = datetime.fromtimestamp(current_time + time_remaining) - today = datetime.fromtimestamp(current_time) - - # If finishing date is more than 7 days out, using "Mon Dec 3 at HH:MM" format - if completed.toordinal() > today.toordinal() + 7: - return completed.strftime("%a %b ") + "{day}".format(day=completed.day) - - # If finishing date is within the next week, use "Monday at HH:MM" format - elif completed.toordinal() > today.toordinal() + 1: - return completed.strftime("%a") - - # If finishing tomorrow, use "tomorrow at HH:MM" format - elif completed.toordinal() > today.toordinal(): - return "tomorrow" - - # If finishing today, use "today at HH:MM" format - else: - return "today" - @pyqtSlot(str) def sendJobToTop(self, print_job_uuid: str) -> None: # This function is part of the output device (and not of the printjob output model) as this type of operation diff --git a/plugins/UM3NetworkPrinting/src/MeshFormatHandler.py b/plugins/UM3NetworkPrinting/src/MeshFormatHandler.py index d64861ea91..72da3c4e6b 100644 --- a/plugins/UM3NetworkPrinting/src/MeshFormatHandler.py +++ b/plugins/UM3NetworkPrinting/src/MeshFormatHandler.py @@ -1,7 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import io -from typing import Optional, Dict, Union, List +from typing import Optional, Dict, Union, List, cast from UM.FileHandler.FileHandler import FileHandler from UM.FileHandler.FileWriter import FileWriter @@ -26,7 +26,7 @@ class MeshFormatHandler: def __init__(self, file_handler: Optional[FileHandler], firmware_version: str) -> None: self._file_handler = file_handler or CuraApplication.getInstance().getMeshFileHandler() self._preferred_format = self._getPreferredFormat(firmware_version) - self._writer = self._getWriter(self._preferred_format["mime_type"]) if self._preferred_format else None + self._writer = self._getWriter(self.mime_type) if self._preferred_format else None @property def is_valid(self) -> bool: @@ -47,32 +47,40 @@ class MeshFormatHandler: @property def mime_type(self) -> str: - return self._preferred_format["mime_type"] + return cast(str, self._preferred_format["mime_type"]) ## Gets the file mode (FileWriter.OutputMode.TextMode or FileWriter.OutputMode.BinaryMode) @property def file_mode(self) -> int: - return self._preferred_format["mode"] + return cast(int, self._preferred_format["mode"]) ## Gets the file extension @property def file_extension(self) -> str: - return self._preferred_format["extension"] + return cast(str, self._preferred_format["extension"]) ## Creates the right kind of stream based on the preferred format. def createStream(self) -> Union[io.BytesIO, io.StringIO]: - return io.StringIO() if self.file_mode == FileWriter.OutputMode.TextMode else io.BytesIO() + if self.file_mode == FileWriter.OutputMode.TextMode: + return io.StringIO() + else: + return io.BytesIO() ## Writes the mesh and returns its value. def getBytes(self, nodes: List[SceneNode]) -> bytes: + if self.writer is None: + raise ValueError("There is no writer for the mesh format handler.") stream = self.createStream() self.writer.write(stream, nodes) - return stream.getvalue() + value = stream.getvalue() + if isinstance(value, str): + value = value.encode() + return value ## Chooses the preferred file format for the given file handler. # \param firmware_version: The version of the firmware. # \return A dict with the file format details. - def _getPreferredFormat(self, firmware_version: str) -> Optional[Dict[str, Union[str, int, bool]]]: + def _getPreferredFormat(self, firmware_version: str) -> Dict[str, Union[str, int, bool]]: # Formats supported by this application (file types that we can actually write). application = CuraApplication.getInstance() @@ -82,7 +90,7 @@ class MeshFormatHandler: # Create a list from the supported file formats string. if not global_stack: Logger.log("e", "Missing global stack!") - return + return {} machine_file_formats = global_stack.getMetaDataEntry("file_formats").split(";") machine_file_formats = [file_type.strip() for file_type in machine_file_formats] diff --git a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py index f536fad49a..cbcfe73c71 100644 --- a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py @@ -3,7 +3,7 @@ import json import os import urllib.parse -from typing import Dict, TYPE_CHECKING, Set +from typing import Dict, TYPE_CHECKING, Set, Optional from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest @@ -151,7 +151,7 @@ class SendMaterialJob(Job): # \return a dictionary of ClusterMaterial objects by GUID # \throw KeyError Raised when on of the materials does not include a valid guid @classmethod - def _parseReply(cls, reply: QNetworkReply) -> Dict[str, ClusterMaterial]: + def _parseReply(cls, reply: QNetworkReply) -> Optional[Dict[str, ClusterMaterial]]: try: remote_materials = json.loads(reply.readAll().data().decode("utf-8")) return {material["guid"]: ClusterMaterial(**material) for material in remote_materials} @@ -163,6 +163,7 @@ class SendMaterialJob(Job): Logger.log("e", "Request material storage on printer: Printer's answer had an incorrect value.") except TypeError: Logger.log("e", "Request material storage on printer: Printer's answer was missing a required value.") + return None ## Retrieves a list of local materials # @@ -184,7 +185,8 @@ class SendMaterialJob(Job): local_material = LocalMaterial(**material) if local_material.GUID not in result or \ - local_material.version > result.get(local_material.GUID).version: + local_material.GUID not in result or \ + local_material.version > result[local_material.GUID].version: result[local_material.GUID] = local_material except KeyError: diff --git a/plugins/UM3NetworkPrinting/src/UM3PrintJobOutputModel.py b/plugins/UM3NetworkPrinting/src/UM3PrintJobOutputModel.py index 2ac3e6ba4f..4f44ca4af8 100644 --- a/plugins/UM3NetworkPrinting/src/UM3PrintJobOutputModel.py +++ b/plugins/UM3NetworkPrinting/src/UM3PrintJobOutputModel.py @@ -1,13 +1,12 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, pyqtSlot -from typing import Optional, TYPE_CHECKING, List -from PyQt5.QtCore import QUrl -from PyQt5.QtGui import QImage +from typing import List + +from PyQt5.QtCore import pyqtProperty, pyqtSignal from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel - +from cura.PrinterOutput.PrinterOutputController import PrinterOutputController from .ConfigurationChangeModel import ConfigurationChangeModel diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/Models/__init__.py b/plugins/UM3NetworkPrinting/tests/Cloud/Models/__init__.py new file mode 100644 index 0000000000..f3f6970c54 --- /dev/null +++ b/plugins/UM3NetworkPrinting/tests/Cloud/Models/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py b/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py index 5a76672b83..94cc239c0a 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py @@ -14,9 +14,6 @@ from UM.Signal import Signal # After patching the QNetworkManager class, requests are prepared before they can be executed. # Any requests not prepared beforehand will cause KeyErrors. class NetworkManagerMock: - # signals used in the network manager. - finished = Signal() - authenticationRequired = Signal() # an enumeration of the supported operations and their code for the network access manager. _OPERATIONS = { @@ -33,6 +30,10 @@ class NetworkManagerMock: self.replies = {} # type: Dict[Tuple[str, str], QNetworkReply] self.request_bodies = {} # type: Dict[Tuple[str, str], bytes] + # signals used in the network manager. + self.finished = Signal() + self.authenticationRequired = Signal() + ## Mock implementation of the get, post, put, delete and head methods from the network manager. # Since the methods are very simple and the same it didn't make sense to repeat the code. # \param method: The method being called. diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py index 84f0254b55..d673554640 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py @@ -2,22 +2,23 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import os +from typing import List from unittest import TestCase from unittest.mock import patch, MagicMock from cura.CuraApplication import CuraApplication from src.Cloud.CloudApiClient import CloudApiClient -from src.Cloud.CloudOutputDeviceManager import CloudOutputDeviceManager from src.Cloud.Models.CloudPrintJobResponse import CloudPrintJobResponse from src.Cloud.Models.CloudPrintJobUploadRequest import CloudPrintJobUploadRequest +from src.Cloud.Models.CloudErrorObject import CloudErrorObject from tests.Cloud.Fixtures import readFixture, parseFixture from .NetworkManagerMock import NetworkManagerMock @patch("cura.NetworkClient.QNetworkAccessManager") class TestCloudApiClient(TestCase): - def _errorHandler(self): - pass + def _errorHandler(self, errors: List[CloudErrorObject]): + raise Exception("Received unexpected error: {}".format(errors)) def setUp(self): super().setUp() @@ -26,7 +27,6 @@ class TestCloudApiClient(TestCase): self.app = CuraApplication.getInstance() self.network = NetworkManagerMock() - self.manager = CloudOutputDeviceManager() self.api = CloudApiClient(self.account, self._errorHandler) def test_GetClusters(self, network_mock): From 4949f39c34e6ffee888fb9eed49181879c02b9d1 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 11 Dec 2018 12:10:32 +0100 Subject: [PATCH 0859/1292] Add translatable strings to empty and unknown material Contributes to CL-1160. --- .../UM3NetworkPrinting/src/ClusterUM3OutputDevice.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index 275087447e..ef890fc4ed 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -617,7 +617,8 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): # This can happen if the connected machine has no material in one or more extruders (if GUID is empty), or the # material is unknown to Cura, so we should return an "empty" or "unknown" material model. if material_group_list is None: - material_name = "Empty" if len(material_data.get("guid", "")) == 0 else "Unknown" + material_name = i18n_catalog.i18nc("@label:material", "Empty") if len(material_data.get("guid", "")) == 0 \ + else i18n_catalog.i18nc("@label:material", "Unknown") return MaterialOutputModel(guid = material_data.get("guid", ""), type = material_data.get("type", ""), color = material_data.get("color", ""), @@ -649,9 +650,10 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): color = material_data["color"] brand = material_data["brand"] material_type = material_data["material"] - name = "Empty" if material_data["material"] == "empty" else "Unknown" - return MaterialOutputModel(guid=material_data["guid"], type=material_type, - brand=brand, color=color, name=name) + name = i18n_catalog.i18nc("@label:material", "Empty") if material_data["material"] == "empty" \ + else i18n_catalog.i18nc("@label:material", "Unknown") + return MaterialOutputModel(guid = material_data["guid"], type = material_type, + brand = brand, color = color, name = name) def _updatePrinter(self, printer: PrinterOutputModel, data: Dict[str, Any]) -> None: # For some unknown reason the cluster wants UUID for everything, except for sending a job directly to a printer. From 8e4ad23da104ead8ee5ce3658e7132d3d8e9eaec Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 11 Dec 2018 12:12:32 +0100 Subject: [PATCH 0860/1292] Add CuraConstants CURA-6005 Put constant values into a separate file CuraConstants.py --- cura/CuraConstants.py | 54 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 cura/CuraConstants.py diff --git a/cura/CuraConstants.py b/cura/CuraConstants.py new file mode 100644 index 0000000000..331937a0c2 --- /dev/null +++ b/cura/CuraConstants.py @@ -0,0 +1,54 @@ +# +# This file contains all constant values in Cura +# + +# ------------- +# Cura Versions +# ------------- +DEFAULT_CURA_DISPLAY_NAME = "Ultimaker Cura" +DEFAULT_CURA_VERSION = "master" +DEFAULT_CURA_BUILD_TYPE = "" +DEFAULT_CURA_DEBUG_MODE = False +DEFAULT_CURA_SDK_VERSION = "5.0.0" + +try: + from cura.CuraVersion import CuraAppDisplayName # type: ignore +except ImportError: + CuraAppDisplayName = DEFAULT_CURA_DISPLAY_NAME + +try: + from cura.CuraVersion import CuraVersion # type: ignore +except ImportError: + CuraVersion = DEFAULT_CURA_VERSION # [CodeStyle: Reflecting imported value] + +try: + from cura.CuraVersion import CuraBuildType # type: ignore +except ImportError: + CuraBuildType = DEFAULT_CURA_BUILD_TYPE + +try: + from cura.CuraVersion import CuraDebugMode # type: ignore +except ImportError: + CuraDebugMode = DEFAULT_CURA_DEBUG_MODE + +try: + from cura.CuraVersion import CuraSDKVersion # type: ignore +except ImportError: + CuraSDKVersion = DEFAULT_CURA_SDK_VERSION + + +# --------- +# Cloud API +# --------- +DEFAULT_CLOUD_API_ROOT = "https://api.ultimaker.com" # type: str +DEFAULT_CLOUD_API_VERSION = 1 # type: int + +try: + from cura.CuraVersion import CuraCloudAPIRoot # type: ignore +except ImportError: + CuraCloudAPIRoot = DEFAULT_CLOUD_API_ROOT + +try: + from cura.CuraVersion import CuraCloudAPIVersion # type: ignore +except ImportError: + CuraCloudAPIVersion = DEFAULT_CLOUD_API_VERSION From 2275e5c71f2ddd2181bdb54bb7c775165f14f1a6 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 11 Dec 2018 12:13:34 +0100 Subject: [PATCH 0861/1292] Refactor code to use constants in CuraConstants CURA-6005 --- cura/CuraApplication.py | 23 +++++++----------- plugins/CuraDrive/src/Settings.py | 9 +++---- plugins/Toolbox/src/Toolbox.py | 40 ++++--------------------------- 3 files changed, 17 insertions(+), 55 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index dfdb50515f..95b94c01c7 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -115,6 +115,8 @@ from cura.ObjectsModel import ObjectsModel from cura.PrinterOutput.NetworkMJPGImage import NetworkMJPGImage +from cura import CuraConstants + from UM.FlameProfiler import pyqtSlot from UM.Decorators import override @@ -127,15 +129,6 @@ if TYPE_CHECKING: numpy.seterr(all = "ignore") -try: - from cura.CuraVersion import CuraAppDisplayName, CuraVersion, CuraBuildType, CuraDebugMode, CuraSDKVersion # type: ignore -except ImportError: - CuraAppDisplayName = "Ultimaker Cura" - CuraVersion = "master" # [CodeStyle: Reflecting imported value] - CuraBuildType = "" - CuraDebugMode = False - CuraSDKVersion = "5.0.0" - class CuraApplication(QtApplication): # SettingVersion represents the set of settings available in the machine/extruder definitions. @@ -162,11 +155,11 @@ class CuraApplication(QtApplication): def __init__(self, *args, **kwargs): super().__init__(name = "cura", - app_display_name = CuraAppDisplayName, - version = CuraVersion, - api_version = CuraSDKVersion, - buildtype = CuraBuildType, - is_debug_mode = CuraDebugMode, + app_display_name = CuraConstants.CuraAppDisplayName, + version = CuraConstants.CuraVersion, + api_version = CuraConstants.CuraSDKVersion, + buildtype = CuraConstants.CuraBuildType, + is_debug_mode = CuraConstants.CuraDebugMode, tray_icon_name = "cura-icon-32.png", **kwargs) @@ -937,7 +930,7 @@ class CuraApplication(QtApplication): engine.rootContext().setContextProperty("CuraApplication", self) engine.rootContext().setContextProperty("PrintInformation", self._print_information) engine.rootContext().setContextProperty("CuraActions", self._cura_actions) - engine.rootContext().setContextProperty("CuraSDKVersion", CuraSDKVersion) + engine.rootContext().setContextProperty("CuraSDKVersion", CuraConstants.CuraSDKVersion) qmlRegisterUncreatableType(CuraApplication, "Cura", 1, 0, "ResourceTypes", "Just an Enum type") diff --git a/plugins/CuraDrive/src/Settings.py b/plugins/CuraDrive/src/Settings.py index f10a7d3bf7..c0df66b950 100644 --- a/plugins/CuraDrive/src/Settings.py +++ b/plugins/CuraDrive/src/Settings.py @@ -1,21 +1,22 @@ # Copyright (c) 2018 Ultimaker B.V. from UM import i18nCatalog +from cura import CuraConstants + class Settings: """ Keeps the application settings. """ - UM_CLOUD_API_ROOT = "https://api.ultimaker.com" DRIVE_API_VERSION = 1 - DRIVE_API_URL = "{}/cura-drive/v{}".format(UM_CLOUD_API_ROOT, str(DRIVE_API_VERSION)) - + DRIVE_API_URL = "{}/cura-drive/v{}".format(CuraConstants.CuraCloudAPIRoot, str(DRIVE_API_VERSION)) + AUTO_BACKUP_ENABLED_PREFERENCE_KEY = "cura_drive/auto_backup_enabled" AUTO_BACKUP_LAST_DATE_PREFERENCE_KEY = "cura_drive/auto_backup_date" I18N_CATALOG_ID = "cura" I18N_CATALOG = i18nCatalog(I18N_CATALOG_ID) - + MESSAGE_TITLE = I18N_CATALOG.i18nc("@info:title", "Backups"), # Translatable messages for the entire plugin. diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 562a964f01..667b28c018 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -18,6 +18,7 @@ from UM.i18n import i18nCatalog from UM.Version import Version import cura +from cura import CuraConstants from cura.CuraApplication import CuraApplication from .AuthorsModel import AuthorsModel @@ -39,9 +40,9 @@ class Toolbox(QObject, Extension): self._application = application # type: CuraApplication - self._sdk_version = None # type: Optional[Union[str, int]] - self._cloud_api_version = None # type: Optional[int] - self._cloud_api_root = None # type: Optional[str] + self._sdk_version = CuraConstants.CuraSDKVersion # type: Union[str, int] + self._cloud_api_version = CuraConstants.CuraCloudAPIVersion # type: int + self._cloud_api_root = CuraConstants.CuraCloudAPIRoot # type: str self._api_url = None # type: Optional[str] # Network: @@ -168,9 +169,6 @@ class Toolbox(QObject, Extension): def _onAppInitialized(self) -> None: self._plugin_registry = self._application.getPluginRegistry() self._package_manager = self._application.getPackageManager() - self._sdk_version = self._getSDKVersion() - self._cloud_api_version = self._getCloudAPIVersion() - self._cloud_api_root = self._getCloudAPIRoot() self._api_url = "{cloud_api_root}/cura-packages/v{cloud_api_version}/cura/v{sdk_version}".format( cloud_api_root = self._cloud_api_root, cloud_api_version = self._cloud_api_version, @@ -186,36 +184,6 @@ class Toolbox(QObject, Extension): "materials_generic": QUrl("{base_url}/packages?package_type=material&tags=generic".format(base_url = self._api_url)) } - # Get the API root for the packages API depending on Cura version settings. - def _getCloudAPIRoot(self) -> str: - if not hasattr(cura, "CuraVersion"): - return self.DEFAULT_CLOUD_API_ROOT - if not hasattr(cura.CuraVersion, "CuraCloudAPIRoot"): # type: ignore - return self.DEFAULT_CLOUD_API_ROOT - if not cura.CuraVersion.CuraCloudAPIRoot: # type: ignore - return self.DEFAULT_CLOUD_API_ROOT - return cura.CuraVersion.CuraCloudAPIRoot # type: ignore - - # Get the cloud API version from CuraVersion - def _getCloudAPIVersion(self) -> int: - if not hasattr(cura, "CuraVersion"): - return self.DEFAULT_CLOUD_API_VERSION - if not hasattr(cura.CuraVersion, "CuraCloudAPIVersion"): # type: ignore - return self.DEFAULT_CLOUD_API_VERSION - if not cura.CuraVersion.CuraCloudAPIVersion: # type: ignore - return self.DEFAULT_CLOUD_API_VERSION - return cura.CuraVersion.CuraCloudAPIVersion # type: ignore - - # Get the packages version depending on Cura version settings. - def _getSDKVersion(self) -> Union[int, str]: - if not hasattr(cura, "CuraVersion"): - return self._application.getAPIVersion().getMajor() - if not hasattr(cura.CuraVersion, "CuraSDKVersion"): # type: ignore - return self._application.getAPIVersion().getMajor() - if not cura.CuraVersion.CuraSDKVersion: # type: ignore - return self._application.getAPIVersion().getMajor() - return cura.CuraVersion.CuraSDKVersion # type: ignore - @pyqtSlot() def browsePackages(self) -> None: # Create the network manager: From a766effce8917337624b3d030400797fa73c2adb Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 11 Dec 2018 12:43:43 +0100 Subject: [PATCH 0862/1292] Fix typing for optional callback for on_progress --- cura/NetworkClient.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/NetworkClient.py b/cura/NetworkClient.py index 5294813fb7..6abf4f3d47 100644 --- a/cura/NetworkClient.py +++ b/cura/NetworkClient.py @@ -203,7 +203,7 @@ class NetworkClient: ## Does a POST request with form data to the given URL. def postForm(self, url: str, header_data: str, body_data: bytes, on_finished: Optional[Callable[[QNetworkReply], None]], - on_progress: Callable = None) -> None: + on_progress: Optional[Callable[[int, int], None]] = None) -> None: post_part = QHttpPart() post_part.setHeader(QNetworkRequest.ContentDispositionHeader, header_data) post_part.setBody(body_data) @@ -212,7 +212,7 @@ class NetworkClient: ## Does a POST request with form parts to the given URL. def postFormWithParts(self, target: str, parts: List[QHttpPart], on_finished: Optional[Callable[[QNetworkReply], None]], - on_progress: Callable = None) -> Optional[QNetworkReply]: + on_progress: Optional[Callable[[int, int], None]] = None) -> Optional[QNetworkReply]: self._validateManager() request = self._createEmptyRequest(target, content_type = None) From e52339a4248a5cf3a1aa423528e3c654defeb2e2 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 11 Dec 2018 12:44:37 +0100 Subject: [PATCH 0863/1292] Fix typing for output_device param in cloud output controller --- plugins/UM3NetworkPrinting/src/Cloud/CloudOutputController.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputController.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputController.py index d31d2bf486..b2a8d8649b 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputController.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputController.py @@ -1,10 +1,11 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +from UM.OutputDevice.OutputDevice import OutputDevice from cura.PrinterOutput.PrinterOutputController import PrinterOutputController class CloudOutputController(PrinterOutputController): - def __init__(self, output_device): + def __init__(self, output_device: OutputDevice): super().__init__(output_device) # The cloud connection only supports fetching the printer and queue status and adding a job to the queue. From 7b7c687db7792634a178a2a6b001d6566b40f4c6 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 11 Dec 2018 12:46:05 +0100 Subject: [PATCH 0864/1292] Remove dismissable = False from messages as it's the default --- plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index e68eb47839..5e0d34e902 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -320,8 +320,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): Message( text = message, title = T.ERROR, - lifetime = 10, - dismissable = True + lifetime = 10 ).show() self._sending_job = False # the upload has finished so we're not sending a job anymore self.writeError.emit() @@ -334,8 +333,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): Message( text = T.UPLOAD_SUCCESS_TEXT, title = T.UPLOAD_SUCCESS_TITLE, - lifetime = 5, - dismissable = True, + lifetime = 5 ).show() self._sending_job = False # the upload has finished so we're not sending a job anymore self.writeFinished.emit() From 6c70543d11bdc37ab658e53686882bcd5a6e4452 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 11 Dec 2018 12:46:11 +0100 Subject: [PATCH 0865/1292] Only set the containerID when the dialog is visible This prevents unneeded updates CURA-6016 --- resources/qml/Dialogs/WorkspaceSummaryDialog.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/qml/Dialogs/WorkspaceSummaryDialog.qml b/resources/qml/Dialogs/WorkspaceSummaryDialog.qml index 1b3a7aac55..35630bd19b 100644 --- a/resources/qml/Dialogs/WorkspaceSummaryDialog.qml +++ b/resources/qml/Dialogs/WorkspaceSummaryDialog.qml @@ -11,6 +11,7 @@ import Cura 1.0 as Cura UM.Dialog { + id: base title: catalog.i18nc("@title:window", "Save Project") minimumWidth: 500 * screenScaleFactor @@ -49,7 +50,7 @@ UM.Dialog UM.SettingDefinitionsModel { id: definitionsModel - containerId: Cura.MachineManager.activeDefinitionId + containerId: base.visible ? Cura.MachineManager.activeDefinitionId: "" showAll: true exclude: ["command_line_settings"] showAncestors: true From e4939cf0051d4f679e8156df26b46e5a22f8b26d Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 11 Dec 2018 12:55:49 +0100 Subject: [PATCH 0866/1292] Remove outdated cloud icon, will be done in another PR --- .../cura-light/icons/printer_cloud_connected.svg | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 resources/themes/cura-light/icons/printer_cloud_connected.svg diff --git a/resources/themes/cura-light/icons/printer_cloud_connected.svg b/resources/themes/cura-light/icons/printer_cloud_connected.svg deleted file mode 100644 index 59ca67e93e..0000000000 --- a/resources/themes/cura-light/icons/printer_cloud_connected.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - noun_Cloud_377836 - Created with Sketch. - - - - - - - - \ No newline at end of file From 75ff03f3c8e55c2d2a651da0f36b3d0ee6c0fb8f Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 11 Dec 2018 13:13:20 +0100 Subject: [PATCH 0867/1292] Use setState instead of emitting the backend state CURA-6016 --- .../CuraEngineBackend/CuraEngineBackend.py | 38 +++++++++---------- plugins/CuraEngineBackend/StartSliceJob.py | 2 +- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 58bc74f3f1..7ede6b6736 100755 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -203,7 +203,7 @@ class CuraEngineBackend(QObject, Backend): @pyqtSlot() def stopSlicing(self) -> None: - self.backendStateChange.emit(BackendState.NotStarted) + self.setState(BackendState.NotStarted) if self._slicing: # We were already slicing. Stop the old job. self._terminate() self._createSocket() @@ -322,7 +322,7 @@ class CuraEngineBackend(QObject, Backend): self._start_slice_job = None if job.isCancelled() or job.getError() or job.getResult() == StartJobResult.Error: - self.backendStateChange.emit(BackendState.Error) + self.setState(BackendState.Error) self.backendError.emit(job) return @@ -331,10 +331,10 @@ class CuraEngineBackend(QObject, Backend): self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice with the current material as it is incompatible with the selected machine or configuration."), title = catalog.i18nc("@info:title", "Unable to slice")) self._error_message.show() - self.backendStateChange.emit(BackendState.Error) + self.setState(BackendState.Error) self.backendError.emit(job) else: - self.backendStateChange.emit(BackendState.NotStarted) + self.setState(BackendState.NotStarted) return if job.getResult() == StartJobResult.SettingError: @@ -362,10 +362,10 @@ class CuraEngineBackend(QObject, Backend): self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice with the current settings. The following settings have errors: {0}").format(", ".join(error_labels)), title = catalog.i18nc("@info:title", "Unable to slice")) self._error_message.show() - self.backendStateChange.emit(BackendState.Error) + self.setState(BackendState.Error) self.backendError.emit(job) else: - self.backendStateChange.emit(BackendState.NotStarted) + self.setState(BackendState.NotStarted) return elif job.getResult() == StartJobResult.ObjectSettingError: @@ -386,7 +386,7 @@ class CuraEngineBackend(QObject, Backend): self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice due to some per-model settings. The following settings have errors on one or more models: {error_labels}").format(error_labels = ", ".join(errors.values())), title = catalog.i18nc("@info:title", "Unable to slice")) self._error_message.show() - self.backendStateChange.emit(BackendState.Error) + self.setState(BackendState.Error) self.backendError.emit(job) return @@ -395,16 +395,16 @@ class CuraEngineBackend(QObject, Backend): self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice because the prime tower or prime position(s) are invalid."), title = catalog.i18nc("@info:title", "Unable to slice")) self._error_message.show() - self.backendStateChange.emit(BackendState.Error) + self.setState(BackendState.Error) self.backendError.emit(job) else: - self.backendStateChange.emit(BackendState.NotStarted) + self.setState(BackendState.NotStarted) if job.getResult() == StartJobResult.ObjectsWithDisabledExtruder: self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice because there are objects associated with disabled Extruder %s." % job.getMessage()), title = catalog.i18nc("@info:title", "Unable to slice")) self._error_message.show() - self.backendStateChange.emit(BackendState.Error) + self.setState(BackendState.Error) self.backendError.emit(job) return @@ -413,10 +413,10 @@ class CuraEngineBackend(QObject, Backend): self._error_message = Message(catalog.i18nc("@info:status", "Nothing to slice because none of the models fit the build volume. Please scale or rotate models to fit."), title = catalog.i18nc("@info:title", "Unable to slice")) self._error_message.show() - self.backendStateChange.emit(BackendState.Error) + self.setState(BackendState.Error) self.backendError.emit(job) else: - self.backendStateChange.emit(BackendState.NotStarted) + self.setState(BackendState.NotStarted) self._invokeSlice() return @@ -424,7 +424,7 @@ class CuraEngineBackend(QObject, Backend): self._socket.sendMessage(job.getSliceMessage()) # Notify the user that it's now up to the backend to do it's job - self.backendStateChange.emit(BackendState.Processing) + self.setState(BackendState.Processing) if self._slice_start_time: Logger.log("d", "Sending slice message took %s seconds", time() - self._slice_start_time ) @@ -442,7 +442,7 @@ class CuraEngineBackend(QObject, Backend): for node in DepthFirstIterator(self._scene.getRoot()): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax. if node.callDecoration("isBlockSlicing"): enable_timer = False - self.backendStateChange.emit(BackendState.Disabled) + self.setState(BackendState.Disabled) self._is_disabled = True gcode_list = node.callDecoration("getGCodeList") if gcode_list is not None: @@ -451,7 +451,7 @@ class CuraEngineBackend(QObject, Backend): if self._use_timer == enable_timer: return self._use_timer if enable_timer: - self.backendStateChange.emit(BackendState.NotStarted) + self.setState(BackendState.NotStarted) self.enableTimer() return True else: @@ -518,7 +518,7 @@ class CuraEngineBackend(QObject, Backend): self._build_plates_to_be_sliced.append(build_plate_number) self.printDurationMessage.emit(source_build_plate_number, {}, []) self.processingProgress.emit(0.0) - self.backendStateChange.emit(BackendState.NotStarted) + self.setState(BackendState.NotStarted) # if not self._use_timer: # With manually having to slice, we want to clear the old invalid layer data. self._clearLayerData(build_plate_changed) @@ -567,7 +567,7 @@ class CuraEngineBackend(QObject, Backend): self.stopSlicing() self.markSliceAll() self.processingProgress.emit(0.0) - self.backendStateChange.emit(BackendState.NotStarted) + self.setState(BackendState.NotStarted) if not self._use_timer: # With manually having to slice, we want to clear the old invalid layer data. self._clearLayerData() @@ -613,7 +613,7 @@ class CuraEngineBackend(QObject, Backend): # \param message The protobuf message containing the slicing progress. def _onProgressMessage(self, message: Arcus.PythonMessage) -> None: self.processingProgress.emit(message.amount) - self.backendStateChange.emit(BackendState.Processing) + self.setState(BackendState.Processing) def _invokeSlice(self) -> None: if self._use_timer: @@ -632,7 +632,7 @@ class CuraEngineBackend(QObject, Backend): # # \param message The protobuf message signalling that slicing is finished. def _onSlicingFinishedMessage(self, message: Arcus.PythonMessage) -> None: - self.backendStateChange.emit(BackendState.Done) + self.setState(BackendState.Done) self.processingProgress.emit(1.0) gcode_list = self._scene.gcode_dict[self._start_slice_job_build_plate] #type: ignore #Because we generate this attribute dynamically. diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index 9679360ad5..d3882a1209 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -323,7 +323,7 @@ class StartSliceJob(Job): value = stack.getProperty(key, "value") result[key] = value Job.yieldThread() - + result["print_bed_temperature"] = result["material_bed_temperature"] # Renamed settings. result["print_temperature"] = result["material_print_temperature"] result["time"] = time.strftime("%H:%M:%S") #Some extra settings. From 4baf0d1bdb8c9aeab709cde37f400ae7db304543 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 11 Dec 2018 13:49:20 +0100 Subject: [PATCH 0868/1292] Always show average rating CURA-6013 --- plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index f34d982cfb..f217d901b8 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -143,9 +143,7 @@ Item Label { - // If the user voted, show that value. Otherwsie show the average rating. - property real ratingtoUse: model.user_rating == 0 ? model.average_rating: model.user_rating - text: ratingtoUse.toFixed(1) + " (" + model.num_ratings + " " + catalog.i18nc("@label", "ratings") + ")" + text: model.average_rating.toFixed(1) + " (" + model.num_ratings + " " + catalog.i18nc("@label", "ratings") + ")" verticalAlignment: Text.AlignVCenter height: starIcon.height anchors.verticalCenter: starIcon.verticalCenter From 30057e2fcd4c1b6370178d24db903d84e83b0619 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 11 Dec 2018 13:49:45 +0100 Subject: [PATCH 0869/1292] Use user_rating instead of user In the end it was implemented as user_rating (and not as user) CURA-6013 --- plugins/Toolbox/src/PackagesModel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Toolbox/src/PackagesModel.py b/plugins/Toolbox/src/PackagesModel.py index 3f5be3bc37..d94fdf6bb7 100644 --- a/plugins/Toolbox/src/PackagesModel.py +++ b/plugins/Toolbox/src/PackagesModel.py @@ -107,7 +107,7 @@ class PackagesModel(ListModel): "login_required": "login-required" in package.get("tags", []), "average_rating": float(package.get("rating", {}).get("average", 0)), "num_ratings": package.get("rating", {}).get("count", 0), - "user_rating": package.get("rating", {}).get("user", 0) + "user_rating": package.get("rating", {}).get("user_rating", 0) }) # Filter on all the key-word arguments. From faa3f42acc6f88a63b26443b6edd500061689e93 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 11 Dec 2018 13:53:05 +0100 Subject: [PATCH 0870/1292] Modify the header in the simulation view menu component This is needed to align with the designs. --- .../SimulationViewMenuComponent.qml | 40 ++++++++++++++----- resources/qml/ViewsSelector.qml | 2 +- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/plugins/SimulationView/SimulationViewMenuComponent.qml b/plugins/SimulationView/SimulationViewMenuComponent.qml index 58b2bfe520..ed615bf4f6 100644 --- a/plugins/SimulationView/SimulationViewMenuComponent.qml +++ b/plugins/SimulationView/SimulationViewMenuComponent.qml @@ -35,14 +35,36 @@ Cura.ExpandableComponent } } - headerItem: Label + headerItem: Item { - id: layerViewTypesLabel - text: catalog.i18nc("@label", "Color scheme") - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("setting_control_text") - height: base.height - verticalAlignment: Text.AlignVCenter + Label + { + id: colorSchemeLabel + text: catalog.i18nc("@label", "Color scheme") + verticalAlignment: Text.AlignVCenter + height: parent.height + elide: Text.ElideRight + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text_medium") + renderType: Text.NativeRendering + } + + Label + { + text: layerTypeCombobox.currentText + verticalAlignment: Text.AlignVCenter + anchors + { + left: colorSchemeLabel.right + leftMargin: UM.Theme.getSize("default_margin").width + right: parent.right + } + height: parent.height + elide: Text.ElideRight + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + renderType: Text.NativeRendering + } } contentItem: Column @@ -125,7 +147,7 @@ Cura.ExpandableComponent Label { id: compatibilityModeLabel - text: catalog.i18nc("@label","Compatibility Mode") + text: catalog.i18nc("@label", "Compatibility Mode") font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") visible: UM.SimulationView.compatibilityMode @@ -136,7 +158,7 @@ Cura.ExpandableComponent Item // Spacer { - height: Math.round(UM.Theme.getSize("default_margin").width / 2) + height: UM.Theme.getSize("narrow_margin").width width: width } diff --git a/resources/qml/ViewsSelector.qml b/resources/qml/ViewsSelector.qml index f2906f9d4c..0e2598a0d8 100644 --- a/resources/qml/ViewsSelector.qml +++ b/resources/qml/ViewsSelector.qml @@ -43,7 +43,7 @@ Cura.ExpandablePopup Label { id: title - text: catalog.i18nc("@button", "View types") + text: catalog.i18nc("@label", "View types") verticalAlignment: Text.AlignVCenter height: parent.height elide: Text.ElideRight From db56aa028ca24e92ce8366063066f4fef466b6a6 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 11 Dec 2018 13:59:36 +0100 Subject: [PATCH 0871/1292] Change the swatch from a circle to the extruder icon --- plugins/SimulationView/SimulationViewMenuComponent.qml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/plugins/SimulationView/SimulationViewMenuComponent.qml b/plugins/SimulationView/SimulationViewMenuComponent.qml index ed615bf4f6..c2e9b0d6fa 100644 --- a/plugins/SimulationView/SimulationViewMenuComponent.qml +++ b/plugins/SimulationView/SimulationViewMenuComponent.qml @@ -183,17 +183,16 @@ Cura.ExpandableComponent style: UM.Theme.styles.checkbox - Rectangle + + UM.RecolorImage { + id: swatch anchors.verticalCenter: parent.verticalCenter anchors.right: extrudersModelCheckBox.right width: UM.Theme.getSize("layerview_legend_size").width height: UM.Theme.getSize("layerview_legend_size").height + source: UM.Theme.getIcon("extruder_button") color: model.color - radius: Math.round(width / 2) - border.width: UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("lining") - visible: !viewSettings.show_legend && !viewSettings.show_gradient } Label From 7a5701b00121e3a481e6f7dbd496c3250a299018 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 11 Dec 2018 14:12:34 +0100 Subject: [PATCH 0872/1292] Made smallrating widget re-usable Also added it to the details page CURA-6013 --- .../resources/qml/SmallRatingWidget.qml | 33 +++++ .../resources/qml/ToolboxDetailPage.qml | 114 +++++++++--------- .../qml/ToolboxDownloadsGridTile.qml | 24 +--- 3 files changed, 94 insertions(+), 77 deletions(-) create mode 100644 plugins/Toolbox/resources/qml/SmallRatingWidget.qml diff --git a/plugins/Toolbox/resources/qml/SmallRatingWidget.qml b/plugins/Toolbox/resources/qml/SmallRatingWidget.qml new file mode 100644 index 0000000000..f69e9349cf --- /dev/null +++ b/plugins/Toolbox/resources/qml/SmallRatingWidget.qml @@ -0,0 +1,33 @@ +import QtQuick 2.3 +import QtQuick.Controls 1.4 +import UM 1.1 as UM +import Cura 1.1 as Cura + + + +Row +{ + id: rating + height: UM.Theme.getSize("rating_star").height + visible: model.average_rating > 0 //Has a rating at all. + spacing: UM.Theme.getSize("thick_lining").width + + UM.RecolorImage + { + id: starIcon + source: UM.Theme.getIcon("star_filled") + color: model.user_rating == 0 ? "#5a5a5a" : UM.Theme.getColor("primary") + height: UM.Theme.getSize("rating_star").height + width: UM.Theme.getSize("rating_star").width + } + + Label + { + text: model.average_rating.toFixed(1) + " (" + model.num_ratings + " " + catalog.i18nc("@label", "ratings") + ")" + verticalAlignment: Text.AlignVCenter + height: starIcon.height + anchors.verticalCenter: starIcon.verticalCenter + color: starIcon.color + font: UM.Theme.getFont("small") + } +} \ No newline at end of file diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 51bb218293..4adbaa2435 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -57,16 +57,22 @@ Item top: thumbnail.top left: thumbnail.right leftMargin: UM.Theme.getSize("default_margin").width - right: parent.right - rightMargin: UM.Theme.getSize("wide_margin").width bottomMargin: UM.Theme.getSize("default_margin").height } text: details === null ? "" : (details.name || "") font: UM.Theme.getFont("large") color: UM.Theme.getColor("text") wrapMode: Text.WordWrap - width: parent.width - height: UM.Theme.getSize("toolbox_property_label").height + width: properties.width + values.width + height: contentHeight + } + + SmallRatingWidget + { + anchors.left: title.right + anchors.leftMargin: UM.Theme.getSize("default_margin").width + anchors.verticalCenter: title.verticalCenter + property var model: details } Column @@ -82,6 +88,12 @@ Item width: childrenRect.width height: childrenRect.height Label + { + text: catalog.i18nc("@label", "Rating") + ":" + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text_medium") + } + Label { text: catalog.i18nc("@label", "Version") + ":" font: UM.Theme.getFont("default") @@ -105,12 +117,6 @@ Item font: UM.Theme.getFont("default") color: UM.Theme.getColor("text_medium") } - Label - { - text: catalog.i18nc("@label", "Rating") + ":" - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text_medium") - } } Column { @@ -124,50 +130,6 @@ Item } spacing: Math.floor(UM.Theme.getSize("narrow_margin").height) height: childrenRect.height - Label - { - text: details === null ? "" : (details.version || catalog.i18nc("@label", "Unknown")) - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - } - Label - { - text: - { - if (details === null) - { - return "" - } - var date = new Date(details.last_updated) - return date.toLocaleString(UM.Preferences.getValue("general/language")) - } - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - } - Label - { - text: - { - if (details === null) - { - return "" - } - else - { - return "" + details.author_name + "" - } - } - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - linkColor: UM.Theme.getColor("text_link") - onLinkActivated: Qt.openUrlExternally(link) - } - Label - { - text: details === null ? "" : (details.download_count || catalog.i18nc("@label", "Unknown")) - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - } RatingWidget { id: rating @@ -212,6 +174,50 @@ Item } } } + Label + { + text: details === null ? "" : (details.version || catalog.i18nc("@label", "Unknown")) + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + } + Label + { + text: + { + if (details === null) + { + return "" + } + var date = new Date(details.last_updated) + return date.toLocaleString(UM.Preferences.getValue("general/language")) + } + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + } + Label + { + text: + { + if (details === null) + { + return "" + } + else + { + return "" + details.author_name + "" + } + } + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + linkColor: UM.Theme.getColor("text_link") + onLinkActivated: Qt.openUrlExternally(link) + } + Label + { + text: details === null ? "" : (details.download_count || catalog.i18nc("@label", "Unknown")) + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + } } Rectangle { diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index f217d901b8..8cd8f2ffef 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -119,37 +119,15 @@ Item verticalAlignment: Text.AlignVCenter maximumLineCount: 2 } - Row + SmallRatingWidget { id: rating - height: UM.Theme.getSize("rating_star").height - visible: model.average_rating > 0 //Has a rating at all. - spacing: UM.Theme.getSize("thick_lining").width anchors { bottom: parent.bottom left: parent.left right: parent.right } - - UM.RecolorImage - { - id: starIcon - source: UM.Theme.getIcon("star_filled") - color: model.user_rating == 0 ? "#5a5a5a" : UM.Theme.getColor("primary") - height: UM.Theme.getSize("rating_star").height - width: UM.Theme.getSize("rating_star").width - } - - Label - { - text: model.average_rating.toFixed(1) + " (" + model.num_ratings + " " + catalog.i18nc("@label", "ratings") + ")" - verticalAlignment: Text.AlignVCenter - height: starIcon.height - anchors.verticalCenter: starIcon.verticalCenter - color: starIcon.color - font: UM.Theme.getFont("small") - } } } } From a5d8e6ceb8da1e5df1d0a5bc72dd962457f1b216 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Tue, 11 Dec 2018 14:28:00 +0100 Subject: [PATCH 0873/1292] STAR-322: Removing the print job after it was done --- .../src/Cloud/CloudApiClient.py | 24 +++++++++---------- .../src/Cloud/CloudOutputDevice.py | 3 +++ .../src/ClusterUM3OutputDevice.py | 24 +++++++++---------- 3 files changed, 27 insertions(+), 24 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py index 474d76d85a..b08bac6670 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py @@ -2,7 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. import json from json import JSONDecodeError -from typing import Callable, List, Type, TypeVar, Union, Optional, Tuple, Dict +from typing import Callable, List, Type, TypeVar, Union, Optional, Tuple, Dict, Any from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply @@ -19,7 +19,7 @@ from .Models.CloudPrintJobResponse import CloudPrintJobResponse ## The cloud API client is responsible for handling the requests and responses from the cloud. -# Each method should only handle models instead of exposing any HTTP details. +# Each method should only handle models instead of exposing Any HTTP details. class CloudApiClient(NetworkClient): # The cloud URL to use for this remote cluster. @@ -43,21 +43,21 @@ class CloudApiClient(NetworkClient): ## Retrieves all the clusters for the user that is currently logged in. # \param on_finished: The function to be called after the result is parsed. - def getClusters(self, on_finished: Callable[[List[CloudClusterResponse]], any]) -> None: + def getClusters(self, on_finished: Callable[[List[CloudClusterResponse]], Any]) -> None: url = "{}/clusters".format(self.CLUSTER_API_ROOT) self.get(url, on_finished=self._wrapCallback(on_finished, CloudClusterResponse)) ## Retrieves the status of the given cluster. # \param cluster_id: The ID of the cluster. # \param on_finished: The function to be called after the result is parsed. - def getClusterStatus(self, cluster_id: str, on_finished: Callable[[CloudClusterStatus], any]) -> None: + def getClusterStatus(self, cluster_id: str, on_finished: Callable[[CloudClusterStatus], Any]) -> None: url = "{}/clusters/{}/status".format(self.CLUSTER_API_ROOT, cluster_id) self.get(url, on_finished=self._wrapCallback(on_finished, CloudClusterStatus)) ## Requests the cloud to register the upload of a print job mesh. # \param request: The request object. # \param on_finished: The function to be called after the result is parsed. - def requestUpload(self, request: CloudPrintJobUploadRequest, on_finished: Callable[[CloudPrintJobResponse], any] + def requestUpload(self, request: CloudPrintJobUploadRequest, on_finished: Callable[[CloudPrintJobResponse], Any] ) -> None: url = "{}/jobs/upload".format(self.CURA_API_ROOT) body = json.dumps({"data": request.toDict()}) @@ -69,8 +69,8 @@ class CloudApiClient(NetworkClient): # \param on_finished: The function to be called after the result is parsed. It receives the print job ID. # \param on_progress: A function to be called during upload progress. It receives a percentage (0-100). # \param on_error: A function to be called if the upload fails. It receives a dict with the error. - def uploadMesh(self, upload_response: CloudPrintJobResponse, mesh: bytes, on_finished: Callable[[str], any], - on_progress: Callable[[int], any], on_error: Callable[[dict], any]): + def uploadMesh(self, upload_response: CloudPrintJobResponse, mesh: bytes, on_finished: Callable[[str], Any], + on_progress: Callable[[int], Any], on_error: Callable[[dict], Any]): def progressCallback(bytes_sent: int, bytes_total: int) -> None: if bytes_total: @@ -92,7 +92,7 @@ class CloudApiClient(NetworkClient): # \param cluster_id: The ID of the cluster. # \param job_id: The ID of the print job. # \param on_finished: The function to be called after the result is parsed. - def requestPrint(self, cluster_id: str, job_id: str, on_finished: Callable[[CloudPrintResponse], any]) -> None: + def requestPrint(self, cluster_id: str, job_id: str, on_finished: Callable[[CloudPrintResponse], Any]) -> None: url = "{}/clusters/{}/print/{}".format(self.CLUSTER_API_ROOT, cluster_id, job_id) self.post(url, data = "", on_finished=self._wrapCallback(on_finished, CloudPrintResponse)) @@ -110,7 +110,7 @@ class CloudApiClient(NetworkClient): # \param reply: The reply from the server. # \return A tuple with a status code and a dictionary. @staticmethod - def _parseReply(reply: QNetworkReply) -> Tuple[int, Dict[str, any]]: + def _parseReply(reply: QNetworkReply) -> Tuple[int, Dict[str, Any]]: status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) try: response = bytes(reply.readAll()).decode() @@ -128,8 +128,8 @@ class CloudApiClient(NetworkClient): # \param response: The response from the server, after being converted to a dict. # \param on_finished: The callback in case the response is successful. # \param model_class: The type of the model to convert the response to. It may either be a single record or a list. - def _parseModels(self, response: Dict[str, any], - on_finished: Callable[[Union[Model, List[Model]]], any], + def _parseModels(self, response: Dict[str, Any], + on_finished: Callable[[Union[Model, List[Model]]], Any], model_class: Type[Model]) -> None: if "data" in response: data = response["data"] @@ -145,7 +145,7 @@ class CloudApiClient(NetworkClient): # \param model: The type of the model to convert the response to. It may either be a single record or a list. # \return: A function that can be passed to the def _wrapCallback(self, - on_finished: Callable[[Union[Model, List[Model]]], any], + on_finished: Callable[[Union[Model, List[Model]]], Any], model: Type[Model], ) -> Callable[[QNetworkReply], None]: def parse(reply: QNetworkReply) -> None: diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index e68eb47839..bf80e0f84c 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -229,6 +229,9 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): removed_jobs, added_jobs, updated_jobs = findChanges(previous, received) for removed_job in removed_jobs: + if removed_job.assignedPrinter: + removed_job.assignedPrinter.updateActivePrintJob(None) + removed_job.stateChanged.disconnect(self._onPrintJobStateChanged) self._print_jobs.remove(removed_job) for added_job in added_jobs: diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index 5e43b602cc..96fee0d96d 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -56,8 +56,9 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): self._number_of_extruders = 2 - self._dummy_lambdas = ("", {}, io.BytesIO() - ) # type: Tuple[str, Dict[str, Union[str, int, bool]], Union[io.StringIO, io.BytesIO]] + self._dummy_lambdas = ( + "", {}, io.BytesIO() + ) # type: Tuple[Optional[str], Dict[str, Union[str, int, bool]], Union[io.StringIO, io.BytesIO]] self._print_jobs = [] # type: List[UM3PrintJobOutputModel] self._received_print_jobs = False # type: bool @@ -165,7 +166,8 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): self._sending_gcode = True - target_printer = yield #Potentially wait on the user to select a target printer. + # Potentially wait on the user to select a target printer. + target_printer = yield # type: Optional[str] # Using buffering greatly reduces the write time for many lines of gcode @@ -179,13 +181,12 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): use_inactivity_timer = False) self._write_job_progress_message.show() - self._dummy_lambdas = (target_printer, mesh_format.preferred_format, stream) - job.finished.connect(self._sendPrintJobWaitOnWriteJobFinished) - - job.start() - - yield True # Return that we had success! - yield # To prevent having to catch the StopIteration exception. + if mesh_format.preferred_format is not None: + self._dummy_lambdas = (target_printer, mesh_format.preferred_format, stream) + job.finished.connect(self._sendPrintJobWaitOnWriteJobFinished) + job.start() + yield True # Return that we had success! + yield # To prevent having to catch the StopIteration exception. def _sendPrintJobWaitOnWriteJobFinished(self, job: WriteFileJob) -> None: if self._write_job_progress_message: @@ -255,8 +256,7 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): # Treat upload progress as response. Uploading can take more than 10 seconds, so if we don't, we can get # timeout responses if this happens. self._last_response_time = time() - old_progress = self._progress_message.getProgress() - if self._progress_message and (old_progress is None or new_progress > old_progress): + if self._progress_message is not None and new_progress > self._progress_message.getProgress(): self._progress_message.show() # Ensure that the message is visible. self._progress_message.setProgress(bytes_sent / bytes_total * 100) From 742fc34e75305cbefdb339ef6fa08f239c538f61 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 11 Dec 2018 14:31:12 +0100 Subject: [PATCH 0874/1292] Change labels in the layer view legend --- plugins/SimulationView/SimulationViewMenuComponent.qml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/SimulationView/SimulationViewMenuComponent.qml b/plugins/SimulationView/SimulationViewMenuComponent.qml index c2e9b0d6fa..95d7d20006 100644 --- a/plugins/SimulationView/SimulationViewMenuComponent.qml +++ b/plugins/SimulationView/SimulationViewMenuComponent.qml @@ -222,25 +222,25 @@ Cura.ExpandableComponent Component.onCompleted: { typesLegendModel.append({ - label: catalog.i18nc("@label", "Show Travels"), + label: catalog.i18nc("@label", "Travels"), initialValue: viewSettings.show_travel_moves, preference: "layerview/show_travel_moves", colorId: "layerview_move_combing" }); typesLegendModel.append({ - label: catalog.i18nc("@label", "Show Helpers"), + label: catalog.i18nc("@label", "Helpers"), initialValue: viewSettings.show_helpers, preference: "layerview/show_helpers", colorId: "layerview_support" }); typesLegendModel.append({ - label: catalog.i18nc("@label", "Show Shell"), + label: catalog.i18nc("@label", "Shell"), initialValue: viewSettings.show_skin, preference: "layerview/show_skin", colorId: "layerview_inset_0" }); typesLegendModel.append({ - label: catalog.i18nc("@label", "Show Infill"), + label: catalog.i18nc("@label", "Infill"), initialValue: viewSettings.show_infill, preference: "layerview/show_infill", colorId: "layerview_infill" From fcaa23ed0ae2c168ff405ce7d9a66acf1ae19351 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 11 Dec 2018 15:16:21 +0100 Subject: [PATCH 0875/1292] Added smallRating widget to featured plugins CURA-6013 --- .../resources/qml/SmallRatingWidget.qml | 4 +- .../qml/ToolboxDownloadsShowcaseTile.qml | 103 +++++++----------- 2 files changed, 43 insertions(+), 64 deletions(-) diff --git a/plugins/Toolbox/resources/qml/SmallRatingWidget.qml b/plugins/Toolbox/resources/qml/SmallRatingWidget.qml index f69e9349cf..0b93131cfd 100644 --- a/plugins/Toolbox/resources/qml/SmallRatingWidget.qml +++ b/plugins/Toolbox/resources/qml/SmallRatingWidget.qml @@ -11,7 +11,7 @@ Row height: UM.Theme.getSize("rating_star").height visible: model.average_rating > 0 //Has a rating at all. spacing: UM.Theme.getSize("thick_lining").width - + width: starIcon.width + spacing + numRatingsLabel.width UM.RecolorImage { id: starIcon @@ -23,9 +23,11 @@ Row Label { + id: numRatingsLabel text: model.average_rating.toFixed(1) + " (" + model.num_ratings + " " + catalog.i18nc("@label", "ratings") + ")" verticalAlignment: Text.AlignVCenter height: starIcon.height + width: contentWidth anchors.verticalCenter: starIcon.verticalCenter color: starIcon.color font: UM.Theme.getFont("small") diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml index ceaadc110d..3e09654173 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml @@ -13,90 +13,67 @@ Rectangle property int installedPackages: toolbox.viewCategory == "material" ? toolbox.getNumberOfInstalledPackagesByAuthor(model.id) : (toolbox.isInstalled(model.id) ? 1 : 0) id: tileBase width: UM.Theme.getSize("toolbox_thumbnail_large").width + (2 * UM.Theme.getSize("default_lining").width) - height: thumbnail.height + packageNameBackground.height + (2 * UM.Theme.getSize("default_lining").width) + height: thumbnail.height + packageName.height + rating.height + UM.Theme.getSize("default_margin").width border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") - color: "transparent" - Rectangle + color: UM.Theme.getColor("main_background") + Image { id: thumbnail - color: UM.Theme.getColor("main_background") - width: UM.Theme.getSize("toolbox_thumbnail_large").width - height: UM.Theme.getSize("toolbox_thumbnail_large").height + height: UM.Theme.getSize("toolbox_thumbnail_large").height - 4 * UM.Theme.getSize("default_margin").height + width: UM.Theme.getSize("toolbox_thumbnail_large").height - 4 * UM.Theme.getSize("default_margin").height + fillMode: Image.PreserveAspectFit + source: model.icon_url || "../images/logobot.svg" + mipmap: true anchors { top: parent.top + topMargin: UM.Theme.getSize("default_margin").height horizontalCenter: parent.horizontalCenter - topMargin: UM.Theme.getSize("default_lining").width - } - Image - { - anchors.centerIn: parent - width: UM.Theme.getSize("toolbox_thumbnail_large").width - 2 * UM.Theme.getSize("default_margin").width - height: UM.Theme.getSize("toolbox_thumbnail_large").height - 2 * UM.Theme.getSize("default_margin").height - fillMode: Image.PreserveAspectFit - source: model.icon_url || "../images/logobot.svg" - mipmap: true - } - UM.RecolorImage - { - width: (parent.width * 0.3) | 0 - height: (parent.height * 0.3) | 0 - anchors - { - bottom: parent.bottom - right: parent.right - bottomMargin: UM.Theme.getSize("default_lining").width - } - visible: installedPackages != 0 - color: (installedPackages == packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border") - source: "../images/installed_check.svg" } } - Rectangle + Label { - id: packageNameBackground - color: UM.Theme.getColor("primary") + id: packageName + text: model.name anchors { - top: thumbnail.bottom horizontalCenter: parent.horizontalCenter + top: thumbnail.bottom } + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter height: UM.Theme.getSize("toolbox_heading_label").height width: parent.width - Label - { - id: packageName - text: model.name - anchors - { - horizontalCenter: parent.horizontalCenter - } - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - height: UM.Theme.getSize("toolbox_heading_label").height - width: parent.width - wrapMode: Text.WordWrap - color: UM.Theme.getColor("button_text") - font: UM.Theme.getFont("medium_bold") - } + wrapMode: Text.WordWrap + font: UM.Theme.getFont("medium_bold") } + UM.RecolorImage + { + width: (parent.width * 0.20) | 0 + height: (parent.height * 0.20) | 0 + anchors + { + bottom: parent.bottom + right: parent.right + bottomMargin: UM.Theme.getSize("default_lining").width + } + visible: installedPackages != 0 + color: (installedPackages == packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border") + source: "../images/installed_check.svg" + } + + SmallRatingWidget + { + id: rating + anchors.bottom: parent.bottom + anchors.bottomMargin: UM.Theme.getSize("narrow_margin").height + anchors.horizontalCenter: parent.horizontalCenter + } + MouseArea { anchors.fill: parent - hoverEnabled: true - onEntered: - { - packageName.color = UM.Theme.getColor("button_text_hover") - packageNameBackground.color = UM.Theme.getColor("primary_hover") - tileBase.border.color = UM.Theme.getColor("primary_hover") - } - onExited: - { - packageName.color = UM.Theme.getColor("button_text") - packageNameBackground.color = UM.Theme.getColor("primary") - tileBase.border.color = UM.Theme.getColor("lining") - } onClicked: { base.selection = model From c804610fa6ab8cad1b52b34666200c2026ef3732 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 11 Dec 2018 15:19:40 +0100 Subject: [PATCH 0876/1292] Make the stage menu in the preview using 85 percent of the total width in order to prevent the print setup panel to be in the middle --- plugins/PreviewStage/PreviewMenu.qml | 92 +++++++++++-------- .../SimulationViewMenuComponent.qml | 1 - resources/themes/cura-light/theme.json | 4 +- 3 files changed, 54 insertions(+), 43 deletions(-) diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index 1543536160..4e1fbac837 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -2,6 +2,7 @@ // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 +import QtQuick.Layouts 1.1 import QtQuick.Controls 2.3 import UM 1.3 as UM @@ -19,56 +20,67 @@ Item name: "cura" } - - Row + // Item to ensure that all of the buttons are nicely centered. + Item { - id: stageMenuRow - anchors.centerIn: parent + anchors.horizontalCenter: parent.horizontalCenter + width: stageMenuRow.width height: parent.height - Cura.ViewsSelector + RowLayout { - id: viewsSelector + id: stageMenuRow + width: Math.round(0.85 * previewMenu.width) height: parent.height - width: UM.Theme.getSize("views_selector").width - headerCornerSide: Cura.RoundedRectangle.Direction.Left - } + spacing: 0 - // Separator line - Rectangle - { - height: parent.height - // If there is no viewPanel, we only need a single spacer, so hide this one. - visible: viewPanel.source != "" - width: visible ? UM.Theme.getSize("default_lining").width : 0 + Cura.ViewsSelector + { + id: viewsSelector + headerCornerSide: Cura.RoundedRectangle.Direction.Left + Layout.minimumWidth: UM.Theme.getSize("views_selector").width + Layout.maximumWidth: UM.Theme.getSize("views_selector").width + Layout.fillWidth: true + Layout.fillHeight: true + } - color: UM.Theme.getColor("lining") - } + // Separator line + Rectangle + { + height: parent.height + // If there is no viewPanel, we only need a single spacer, so hide this one. + visible: viewPanel.source != "" + width: UM.Theme.getSize("default_lining").width - Loader - { - id: viewPanel - height: parent.height - width: childrenRect.width - source: UM.Controller.activeView != null && UM.Controller.activeView.stageMenuComponent != null ? UM.Controller.activeView.stageMenuComponent : "" - } + color: UM.Theme.getColor("lining") + } - // Separator line - Rectangle - { - height: parent.height - width: UM.Theme.getSize("default_lining").width - color: UM.Theme.getColor("lining") - } + Loader + { + id: viewPanel + Layout.fillHeight: true + Layout.fillWidth: true + Layout.preferredWidth: stageMenuRow.width - viewsSelector.width - printSetupSelectorItem.width - 2 * UM.Theme.getSize("default_lining").width + source: UM.Controller.activeView != null && UM.Controller.activeView.stageMenuComponent != null ? UM.Controller.activeView.stageMenuComponent : "" + } - Item - { - id: printSetupSelectorItem - // This is a work around to prevent the printSetupSelector from having to be re-loaded every time - // a stage switch is done. - children: [printSetupSelector] - height: childrenRect.height - width: childrenRect.width + // Separator line + Rectangle + { + height: parent.height + width: UM.Theme.getSize("default_lining").width + color: UM.Theme.getColor("lining") + } + + Item + { + id: printSetupSelectorItem + // This is a work around to prevent the printSetupSelector from having to be re-loaded every time + // a stage switch is done. + children: [printSetupSelector] + height: childrenRect.height + width: childrenRect.width + } } } } diff --git a/plugins/SimulationView/SimulationViewMenuComponent.qml b/plugins/SimulationView/SimulationViewMenuComponent.qml index 95d7d20006..9f43252126 100644 --- a/plugins/SimulationView/SimulationViewMenuComponent.qml +++ b/plugins/SimulationView/SimulationViewMenuComponent.qml @@ -15,7 +15,6 @@ Cura.ExpandableComponent { id: base - width: UM.Theme.getSize("layerview_menu_size").width contentHeaderTitle: catalog.i18nc("@label", "Color scheme") Connections diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 3dc216ad70..0c17a34e9a 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -380,7 +380,7 @@ "machine_selector_widget_content": [25.0, 32.0], "machine_selector_icon": [2.66, 2.66], - "views_selector": [16.0, 4.5], + "views_selector": [23.0, 4.0], "printer_type_label": [3.5, 1.5], @@ -450,7 +450,7 @@ "slider_handle": [1.5, 1.5], "slider_layerview_size": [1.0, 26.0], - "layerview_menu_size": [15, 20], + "layerview_menu_size": [16.0, 4.0], "layerview_legend_size": [1.0, 1.0], "layerview_row": [11.0, 1.5], "layerview_row_spacing": [0.0, 0.5], From 64dc73aed3f6d043c5ab7c81c54f54495b951abe Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 11 Dec 2018 15:47:57 +0100 Subject: [PATCH 0877/1292] remove incorrect __init__.py --- __init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 __init__.py diff --git a/__init__.py b/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 From daeb86bdb1ec55400b86edc14ec76c66cba4dfbd Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 11 Dec 2018 15:55:03 +0100 Subject: [PATCH 0878/1292] Use short printer family tags Contributes to CL-1173 --- .../resources/qml/MonitorPrintJobCard.qml | 1 + .../resources/qml/MonitorPrinterPill.qml | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml index 5eaeff2e84..d8c5d1ec28 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml @@ -97,6 +97,7 @@ Item return "" } visible: printJob + width: 120 * screenScaleFactor // TODO: Theme! // FIXED-LINE-HEIGHT: height: 18 * screenScaleFactor // TODO: Theme! diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterPill.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterPill.qml index cd78f1b11f..94d9c7e7d0 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterPill.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterPill.qml @@ -12,7 +12,19 @@ import UM 1.2 as UM Item { // The printer name - property alias text: printerNameLabel.text; + property var text: "" + property var tagText: { + switch(text) { + case "Ultimaker 3": + return "UM 3" + case "Ultimaker 3 Extended": + return "UM 3 EXT" + case "Ultimaker S5": + return "UM S5" + default: + return "" + } + } implicitHeight: 18 * screenScaleFactor // TODO: Theme! implicitWidth: printerNameLabel.contentWidth + 12 // TODO: Theme! @@ -28,7 +40,7 @@ Item id: printerNameLabel anchors.centerIn: parent color: "#535369" // TODO: Theme! - text: "" + text: tagText font.pointSize: 10 } } \ No newline at end of file From 0467756ed6ef4d4ae194cccede5465dd78a401c9 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Tue, 11 Dec 2018 16:01:52 +0100 Subject: [PATCH 0879/1292] STAR-322: Adding return type to init method --- plugins/UM3NetworkPrinting/src/Cloud/CloudOutputController.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputController.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputController.py index b2a8d8649b..c139be0c38 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputController.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputController.py @@ -5,7 +5,7 @@ from cura.PrinterOutput.PrinterOutputController import PrinterOutputController class CloudOutputController(PrinterOutputController): - def __init__(self, output_device: OutputDevice): + def __init__(self, output_device: OutputDevice) -> None: super().__init__(output_device) # The cloud connection only supports fetching the printer and queue status and adding a job to the queue. From b993a7b0d92c8d1d357d639716aab280bb8f0da0 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 11 Dec 2018 16:05:24 +0100 Subject: [PATCH 0880/1292] Change the header color and font in the configuration popup Also fix some alignments with the printer type selector. Contributes to CURA-5876. --- resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml | 5 ++--- .../qml/Menus/ConfigurationMenu/CustomConfiguration.qml | 6 ++---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml index 68c56c7c4b..2e8be05fef 100644 --- a/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml @@ -16,8 +16,8 @@ Item { id: header text: catalog.i18nc("@header", "Configurations") - font: UM.Theme.getFont("large") - color: UM.Theme.getColor("text") + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("small_button_text") height: contentHeight renderType: Text.NativeRendering @@ -31,7 +31,6 @@ Item ConfigurationListView { anchors.top: header.bottom - anchors.topMargin: UM.Theme.getSize("default_margin").width width: parent.width outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index 8429e2c093..cbe4263e33 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -23,8 +23,8 @@ Item { id: header text: catalog.i18nc("@header", "Custom") - font: UM.Theme.getFont("large") - color: UM.Theme.getColor("text") + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("small_button_text") height: contentHeight renderType: Text.NativeRendering @@ -51,9 +51,7 @@ Item anchors { left: parent.left - leftMargin: UM.Theme.getSize("default_margin").width right: parent.right - rightMargin: UM.Theme.getSize("default_margin").width top: header.bottom topMargin: visible ? UM.Theme.getSize("default_margin").height : 0 } From f99c788eb63bef4035ce7694c3a94b77277e40ad Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 11 Dec 2018 16:35:59 +0100 Subject: [PATCH 0881/1292] Change some colors for the arrows in some setting selectors Contributes to CURA-5876. --- resources/qml/ActionButton.qml | 2 +- .../ConfigurationMenu/ConfigurationItem.qml | 4 ++-- .../ConfigurationMenu/CustomConfiguration.qml | 12 +++++----- resources/qml/PrinterOutput/ExtruderBox.qml | 2 +- resources/qml/PrinterOutput/HeatedBedBox.qml | 2 +- .../qml/PrinterOutput/MonitorSection.qml | 2 +- .../PrinterSelector/MachineSelectorButton.qml | 2 +- resources/qml/Settings/SettingCategory.qml | 23 ++----------------- resources/qml/Settings/SettingComboBox.qml | 2 +- resources/qml/Settings/SettingExtruder.qml | 2 +- .../qml/Settings/SettingOptionalExtruder.qml | 2 +- resources/qml/ViewsSelector.qml | 2 +- resources/themes/cura-light/styles.qml | 10 ++++---- resources/themes/cura-light/theme.json | 15 ------------ 14 files changed, 24 insertions(+), 58 deletions(-) diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index 7177120f35..c3d39e8251 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -62,7 +62,7 @@ Button id: buttonText text: button.text color: button.enabled ? (button.hovered ? button.textHoverColor : button.textColor): button.textDisabledColor - font: UM.Theme.getFont("action_button") + font: UM.Theme.getFont("medium") visible: text != "" renderType: Text.NativeRendering anchors.verticalCenter: parent.verticalCenter diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 728a0cbe9a..9dae075b48 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -20,8 +20,8 @@ Button { height: childrenRect.height color: parent.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") - border.color: (parent.checked || parent.hovered) ? UM.Theme.getColor("primary") : UM.Theme.getColor("lining") - border.width: parent.checked ? UM.Theme.getSize("thick_lining").width : UM.Theme.getSize("default_lining").width + border.color: parent.checked ? UM.Theme.getColor("primary") : UM.Theme.getColor("lining") + border.width: UM.Theme.getSize("default_lining").width radius: UM.Theme.getSize("default_radius").width Column diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index cbe4263e33..7181f841d1 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -60,7 +60,7 @@ Item { text: catalog.i18nc("@label", "Printer") width: Math.round(parent.width * 0.3) - UM.Theme.getSize("default_margin").width - height: contentHeight +// height: contentHeight font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") anchors.verticalCenter: printerTypeSelector.verticalCenter @@ -72,7 +72,7 @@ Item id: printerTypeSelector text: Cura.MachineManager.activeMachineDefinitionName tooltip: Cura.MachineManager.activeMachineDefinitionName - height: UM.Theme.getSize("setting_control").height + height: UM.Theme.getSize("print_setup_big_item").height width: Math.round(parent.width * 0.7) + UM.Theme.getSize("default_margin").width anchors.right: parent.right style: UM.Theme.styles.print_setup_header_button @@ -222,7 +222,7 @@ Item Row { - height: UM.Theme.getSize("print_setup_item").height + height: UM.Theme.getSize("print_setup_big_item").height visible: Cura.MachineManager.hasMaterials Label @@ -246,7 +246,7 @@ Item text: Cura.MachineManager.activeStack != null ? Cura.MachineManager.activeStack.material.name : "" tooltip: text - height: UM.Theme.getSize("setting_control").height + height: UM.Theme.getSize("print_setup_big_item").height width: selectors.controlWidth style: UM.Theme.styles.print_setup_header_button @@ -260,7 +260,7 @@ Item Row { - height: UM.Theme.getSize("print_setup_item").height + height: UM.Theme.getSize("print_setup_big_item").height visible: Cura.MachineManager.hasVariants Label @@ -280,7 +280,7 @@ Item text: Cura.MachineManager.activeVariantName tooltip: Cura.MachineManager.activeVariantName - height: UM.Theme.getSize("setting_control").height + height: UM.Theme.getSize("print_setup_big_item").height width: selectors.controlWidth style: UM.Theme.styles.print_setup_header_button activeFocusOnPress: true; diff --git a/resources/qml/PrinterOutput/ExtruderBox.qml b/resources/qml/PrinterOutput/ExtruderBox.qml index 247bb3a27d..9ba78f778f 100644 --- a/resources/qml/PrinterOutput/ExtruderBox.qml +++ b/resources/qml/PrinterOutput/ExtruderBox.qml @@ -326,7 +326,7 @@ Item return UM.Theme.getColor("action_button_text"); } } - font: UM.Theme.getFont("action_button") + font: UM.Theme.getFont("medium") text: { if(extruderModel == null) diff --git a/resources/qml/PrinterOutput/HeatedBedBox.qml b/resources/qml/PrinterOutput/HeatedBedBox.qml index 33cf5cd1e2..ac541f707c 100644 --- a/resources/qml/PrinterOutput/HeatedBedBox.qml +++ b/resources/qml/PrinterOutput/HeatedBedBox.qml @@ -320,7 +320,7 @@ Item return UM.Theme.getColor("action_button_text"); } } - font: UM.Theme.getFont("action_button") + font: UM.Theme.getFont("medium") text: { if(printerModel == null) diff --git a/resources/qml/PrinterOutput/MonitorSection.qml b/resources/qml/PrinterOutput/MonitorSection.qml index 7ef89dabf7..1d9df777b6 100644 --- a/resources/qml/PrinterOutput/MonitorSection.qml +++ b/resources/qml/PrinterOutput/MonitorSection.qml @@ -27,7 +27,7 @@ Item anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("default_margin").width text: label - font: UM.Theme.getFont("setting_category") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("setting_category_text") } } diff --git a/resources/qml/PrinterSelector/MachineSelectorButton.qml b/resources/qml/PrinterSelector/MachineSelectorButton.qml index b88af35f82..39e63d27c3 100644 --- a/resources/qml/PrinterSelector/MachineSelectorButton.qml +++ b/resources/qml/PrinterSelector/MachineSelectorButton.qml @@ -42,7 +42,7 @@ Button } text: machineSelectorButton.text color: UM.Theme.getColor("text") - font: UM.Theme.getFont("action_button") + font: UM.Theme.getFont("medium") visible: text != "" renderType: Text.NativeRendering verticalAlignment: Text.AlignVCenter diff --git a/resources/qml/Settings/SettingCategory.qml b/resources/qml/Settings/SettingCategory.qml index 5676bcedf9..da731bcd55 100644 --- a/resources/qml/Settings/SettingCategory.qml +++ b/resources/qml/Settings/SettingCategory.qml @@ -73,7 +73,7 @@ Button text: definition.label textFormat: Text.PlainText renderType: Text.NativeRendering - font: UM.Theme.getFont("setting_category") + font: UM.Theme.getFont("default") color: { if (!base.enabled) @@ -106,26 +106,7 @@ Button width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height sourceSize.height: width - color: - { - if (!base.enabled) - { - return UM.Theme.getColor("setting_category_disabled_text") - } - else if ((base.hovered || base.activeFocus) && base.checkable && base.checked) - { - return UM.Theme.getColor("setting_category_active_hover_text") - } - else if (base.pressed || (base.checkable && base.checked)) - { - return UM.Theme.getColor("setting_category_active_text") - } - else if (base.hovered || base.activeFocus) - { - return UM.Theme.getColor("setting_category_hover_text") - } - return UM.Theme.getColor("setting_category_text") - } + color: UM.Theme.getColor("setting_control_button") source: base.checked ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") } } diff --git a/resources/qml/Settings/SettingComboBox.qml b/resources/qml/Settings/SettingComboBox.qml index 13d2a0eb8f..a287e0c3ce 100644 --- a/resources/qml/Settings/SettingComboBox.qml +++ b/resources/qml/Settings/SettingComboBox.qml @@ -63,7 +63,7 @@ SettingItem sourceSize.width: width + 5 * screenScaleFactor sourceSize.height: width + 5 * screenScaleFactor - color: UM.Theme.getColor("setting_control_text") + color: UM.Theme.getColor("setting_control_button") } contentItem: Label diff --git a/resources/qml/Settings/SettingExtruder.qml b/resources/qml/Settings/SettingExtruder.qml index e1fedd9274..a6c1beb3e5 100644 --- a/resources/qml/Settings/SettingExtruder.qml +++ b/resources/qml/Settings/SettingExtruder.qml @@ -105,7 +105,7 @@ SettingItem sourceSize.width: width + 5 * screenScaleFactor sourceSize.height: width + 5 * screenScaleFactor - color: UM.Theme.getColor("setting_control_text"); + color: UM.Theme.getColor("setting_control_button"); } background: Rectangle diff --git a/resources/qml/Settings/SettingOptionalExtruder.qml b/resources/qml/Settings/SettingOptionalExtruder.qml index 200a3f64f1..aa843e2719 100644 --- a/resources/qml/Settings/SettingOptionalExtruder.qml +++ b/resources/qml/Settings/SettingOptionalExtruder.qml @@ -102,7 +102,7 @@ SettingItem sourceSize.width: width + 5 * screenScaleFactor sourceSize.height: width + 5 * screenScaleFactor - color: UM.Theme.getColor("setting_control_text"); + color: UM.Theme.getColor("setting_control_button"); } background: Rectangle diff --git a/resources/qml/ViewsSelector.qml b/resources/qml/ViewsSelector.qml index f2906f9d4c..58749c09f2 100644 --- a/resources/qml/ViewsSelector.qml +++ b/resources/qml/ViewsSelector.qml @@ -105,7 +105,7 @@ Cura.ExpandablePopup id: buttonText text: viewsSelectorButton.text color: UM.Theme.getColor("text") - font: UM.Theme.getFont("action_button") + font: UM.Theme.getFont("medium") renderType: Text.NativeRendering verticalAlignment: Text.AlignVCenter elide: Text.ElideRight diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index bcc754f4ca..42b63e84f7 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -75,7 +75,7 @@ QtObject width: Theme.getSize("standard_arrow").width height: Theme.getSize("standard_arrow").height sourceSize.height: width - color: control.enabled ? Theme.getColor("setting_category_text") : Theme.getColor("setting_category_disabled_text") + color: control.enabled ? Theme.getColor("setting_control_button") : Theme.getColor("setting_category_disabled_text") source: Theme.getIcon("arrow_bottom") } Label @@ -208,7 +208,7 @@ QtObject anchors.verticalCenter: parent.verticalCenter; text: control.text; - font: Theme.getFont("button_tooltip"); + font: Theme.getFont("default"); color: Theme.getColor("tooltip_text"); } } @@ -446,7 +446,7 @@ QtObject sourceSize.width: width + 5 * screenScaleFactor sourceSize.height: width + 5 * screenScaleFactor - color: Theme.getColor("setting_control_text"); + color: Theme.getColor("setting_control_button"); } } } @@ -513,7 +513,7 @@ QtObject sourceSize.width: width + 5 * screenScaleFactor sourceSize.height: width + 5 * screenScaleFactor - color: UM.Theme.getColor("setting_control_text") + color: UM.Theme.getColor("setting_control_button") } } } @@ -716,7 +716,7 @@ QtObject return UM.Theme.getColor("action_button_text"); } } - font: UM.Theme.getFont("action_button") + font: UM.Theme.getFont("medium") text: control.text } } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 3dc216ad70..f812d4245f 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -49,21 +49,6 @@ "size": 0.7, "weight": 50, "family": "Noto Sans" - }, - "button_tooltip": { - "size": 1.0, - "weight": 50, - "family": "Noto Sans" - }, - "setting_category": { - "size": 1.15, - "weight": 63, - "family": "Noto Sans" - }, - "action_button": { - "size": 1.15, - "weight": 50, - "family": "Noto Sans" } }, From 1ababf38ad1cd50946ebca15a72e971e949223a7 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 11 Dec 2018 16:42:44 +0100 Subject: [PATCH 0882/1292] Use full printer name if no tag is known Contributes to CL-1173 --- plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterPill.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterPill.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterPill.qml index 94d9c7e7d0..80a089cc2a 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterPill.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterPill.qml @@ -22,7 +22,7 @@ Item case "Ultimaker S5": return "UM S5" default: - return "" + return text } } From ed8292c47243c0329c3b2bed04a49acc15b79852 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 11 Dec 2018 17:00:02 +0100 Subject: [PATCH 0883/1292] Adjust size and margins of the icon in the action button Contributes to CURA-5876. --- resources/qml/ActionButton.qml | 5 +++-- .../qml/Menus/ConfigurationMenu/CustomConfiguration.qml | 2 +- resources/themes/cura-light/theme.json | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index c3d39e8251..3a9552cd9c 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -43,12 +43,13 @@ Button contentItem: Row { + spacing: UM.Theme.getSize("narrow_margin").width //Left side icon. Only displayed if !isIconOnRightSide. UM.RecolorImage { id: buttonIconLeft source: "" - height: buttonText.height + height: UM.Theme.getSize("action_button_icon").height width: visible ? height : 0 sourceSize.width: width sourceSize.height: height @@ -76,7 +77,7 @@ Button { id: buttonIconRight source: buttonIconLeft.source - height: buttonText.height + height: UM.Theme.getSize("action_button_icon").height width: visible ? height : 0 sourceSize.width: width sourceSize.height: height diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index 7181f841d1..4d6d80c1b4 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -60,7 +60,7 @@ Item { text: catalog.i18nc("@label", "Printer") width: Math.round(parent.width * 0.3) - UM.Theme.getSize("default_margin").width -// height: contentHeight + height: contentHeight font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") anchors.verticalCenter: printerTypeSelector.verticalCenter diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index f812d4245f..b4d0ab7092 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -407,6 +407,7 @@ "button_lining": [0, 0], "action_button": [15.0, 3.0], + "action_button_icon": [1.0, 1.0], "action_button_radius": [0.15, 0.15], "small_button": [2, 2], From b413b4cdb69fd3f6c46f93c3797c92bd9abc53b8 Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Tue, 11 Dec 2018 17:21:14 +0100 Subject: [PATCH 0884/1292] Correct a typo in typing. [CURA-6016] --- cura/Machines/Models/BaseMaterialsModel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Machines/Models/BaseMaterialsModel.py b/cura/Machines/Models/BaseMaterialsModel.py index 3cd92bb6b4..629e5c2b48 100644 --- a/cura/Machines/Models/BaseMaterialsModel.py +++ b/cura/Machines/Models/BaseMaterialsModel.py @@ -59,7 +59,7 @@ class BaseMaterialsModel(ListModel): self._extruder_stack = None self._available_materials = None # type: Optional[Dict[str, MaterialNode]] - self._favorite_ids = set() # type: Set(str) + self._favorite_ids = set() # type: Set[str] def _updateExtruderStack(self): global_stack = self._machine_manager.activeMachine From 0b6841e5d9ba0af192866c1dbe0cec21c14debe1 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 12 Dec 2018 09:19:43 +0100 Subject: [PATCH 0885/1292] Revert "Use the capitalized version of the buildplate name" This reverts commit 11d8831d7a9a15e3e916d5d9762bfe1f755042e5. Contributes to CURA-6021. --- cura/PrinterOutput/ConfigurationModel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/PrinterOutput/ConfigurationModel.py b/cura/PrinterOutput/ConfigurationModel.py index 6f55aa3b1f..89e609c913 100644 --- a/cura/PrinterOutput/ConfigurationModel.py +++ b/cura/PrinterOutput/ConfigurationModel.py @@ -44,7 +44,7 @@ class ConfigurationModel(QObject): @pyqtProperty(str, fset = setBuildplateConfiguration, notify = configurationChanged) def buildplateConfiguration(self) -> str: - return self._buildplate_configuration.capitalize() + return self._buildplate_configuration ## This method is intended to indicate whether the configuration is valid or not. # The method checks if the mandatory fields are or not set From 4d57aa8ea42096dde3ef1db3f370e672ebd89b2b Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 12 Dec 2018 09:28:15 +0100 Subject: [PATCH 0886/1292] Simplify the rating widget CURA-6013 --- plugins/Toolbox/resources/qml/RatingWidget.qml | 10 ---------- plugins/Toolbox/resources/qml/ToolboxDetailPage.qml | 2 -- 2 files changed, 12 deletions(-) diff --git a/plugins/Toolbox/resources/qml/RatingWidget.qml b/plugins/Toolbox/resources/qml/RatingWidget.qml index fbe782b2e2..355b99c0c4 100644 --- a/plugins/Toolbox/resources/qml/RatingWidget.qml +++ b/plugins/Toolbox/resources/qml/RatingWidget.qml @@ -10,8 +10,6 @@ Item property int indexHovered: -1 property string packageId: "" - property int numRatings: 0 - property int userRating: 0 signal rated(int rating) @@ -88,14 +86,6 @@ Item onClicked: rated(index + 1) // Notify anyone who cares about this. } } - Label - { - text: "(" + numRatings + ")" - verticalAlignment: Text.AlignVCenter - height: parent.height - color: "#5a5a5a" - font: UM.Theme.getFont("small") - } } } } \ No newline at end of file diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 4adbaa2435..52af1d6ddf 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -135,8 +135,6 @@ Item id: rating visible: details.type == "plugin" packageId: details.id - rating: details.average_rating - numRatings: details.num_ratings userRating: details.user_rating enabled: toolbox.isInstalled(details.id) && Cura.API.account.isLoggedIn From a6dbba709088c93b110abd874b82785eb612f4f7 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 12 Dec 2018 09:41:35 +0100 Subject: [PATCH 0887/1292] Minor UI tweaks CURA-6013 --- plugins/Toolbox/resources/qml/ToolboxDetailPage.qml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 52af1d6ddf..1d977883f9 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -26,7 +26,7 @@ Item right: parent.right rightMargin: UM.Theme.getSize("wide_margin").width } - height: UM.Theme.getSize("toolbox_detail_header").height + height: childrenRect.height + 3 * UM.Theme.getSize("default_margin").width Rectangle { id: thumbnail @@ -62,8 +62,7 @@ Item text: details === null ? "" : (details.name || "") font: UM.Theme.getFont("large") color: UM.Theme.getColor("text") - wrapMode: Text.WordWrap - width: properties.width + values.width + width: contentWidth height: contentHeight } From 8c07a6e89b97c6a545720e481a606f4f2a7e29f7 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 12 Dec 2018 10:35:36 +0100 Subject: [PATCH 0888/1292] Fix typing issues CURA-6005 --- plugins/CuraDrive/src/DriveApiService.py | 8 ++++---- plugins/CuraDrive/src/DrivePluginExtension.py | 3 ++- plugins/CuraDrive/src/UploadBackupJob.py | 4 ++-- plugins/CuraDrive/src/models/BackupListModel.py | 6 +++--- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/plugins/CuraDrive/src/DriveApiService.py b/plugins/CuraDrive/src/DriveApiService.py index a677466838..6963e595b5 100644 --- a/plugins/CuraDrive/src/DriveApiService.py +++ b/plugins/CuraDrive/src/DriveApiService.py @@ -3,7 +3,7 @@ import base64 import hashlib from datetime import datetime from tempfile import NamedTemporaryFile -from typing import Optional, List, Dict +from typing import Any, Optional, List, Dict import requests @@ -34,7 +34,7 @@ class DriveApiService: """Create a new instance of the Drive API service and set the cura_api object.""" self._cura_api = cura_api - def getBackups(self) -> List[Dict[str, any]]: + def getBackups(self) -> List[Dict[str, Any]]: """Get all backups from the API.""" access_token = self._cura_api.account.accessToken if not access_token: @@ -85,7 +85,7 @@ class DriveApiService: else: self.onCreatingStateChanged.emit(is_creating=False) - def restoreBackup(self, backup: Dict[str, any]) -> None: + def restoreBackup(self, backup: Dict[str, Any]) -> None: """ Restore a previously exported backup from cloud storage. :param backup: A dict containing an entry from the API list response. @@ -157,7 +157,7 @@ class DriveApiService: return False return True - def _requestBackupUpload(self, backup_metadata: Dict[str, any], backup_size: int) -> Optional[str]: + def _requestBackupUpload(self, backup_metadata: Dict[str, Any], backup_size: int) -> Optional[str]: """ Request a backup upload slot from the API. :param backup_metadata: A dict containing some meta data about the backup. diff --git a/plugins/CuraDrive/src/DrivePluginExtension.py b/plugins/CuraDrive/src/DrivePluginExtension.py index 556fb187df..7e1472b988 100644 --- a/plugins/CuraDrive/src/DrivePluginExtension.py +++ b/plugins/CuraDrive/src/DrivePluginExtension.py @@ -70,7 +70,8 @@ class DrivePluginExtension(QObject, Extension): if not self._drive_window: self._drive_window = self.createDriveWindow() self.refreshBackups() - self._drive_window.show() + if self._drive_window: + self._drive_window.show() def createDriveWindow(self) -> Optional["QObject"]: """ diff --git a/plugins/CuraDrive/src/UploadBackupJob.py b/plugins/CuraDrive/src/UploadBackupJob.py index 039e6d1a09..bcecce554a 100644 --- a/plugins/CuraDrive/src/UploadBackupJob.py +++ b/plugins/CuraDrive/src/UploadBackupJob.py @@ -14,14 +14,14 @@ class UploadBackupJob(Job): As it can take longer than some other tasks, we schedule this using a Cura Job. """ - def __init__(self, signed_upload_url: str, backup_zip: bytes): + def __init__(self, signed_upload_url: str, backup_zip: bytes) -> None: super().__init__() self._signed_upload_url = signed_upload_url self._backup_zip = backup_zip self._upload_success = False self.backup_upload_error_message = "" - def run(self): + def run(self) -> None: Message(Settings.translatable_messages["uploading_backup"], title = Settings.MESSAGE_TITLE, lifetime = 10).show() diff --git a/plugins/CuraDrive/src/models/BackupListModel.py b/plugins/CuraDrive/src/models/BackupListModel.py index 9567b3d255..93b0c4c48c 100644 --- a/plugins/CuraDrive/src/models/BackupListModel.py +++ b/plugins/CuraDrive/src/models/BackupListModel.py @@ -1,5 +1,5 @@ # Copyright (c) 2018 Ultimaker B.V. -from typing import List, Dict +from typing import Any, List, Dict from UM.Qt.ListModel import ListModel @@ -11,7 +11,7 @@ class BackupListModel(ListModel): The BackupListModel transforms the backups data that came from the server so it can be served to the Qt UI. """ - def __init__(self, parent=None): + def __init__(self, parent = None) -> None: super().__init__(parent) self.addRoleName(Qt.UserRole + 1, "backup_id") self.addRoleName(Qt.UserRole + 2, "download_url") @@ -19,7 +19,7 @@ class BackupListModel(ListModel): self.addRoleName(Qt.UserRole + 4, "md5_hash") self.addRoleName(Qt.UserRole + 5, "data") - def loadBackups(self, data: List[Dict[str, any]]) -> None: + def loadBackups(self, data: List[Dict[str, Any]]) -> None: """ Populate the model with server data. :param data: From 95f70a75d8629663dd42b2fdac148407cc993ed9 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 12 Dec 2018 10:39:56 +0100 Subject: [PATCH 0889/1292] Ensure that package name has margins in showcase tile CURA-6013 --- plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml index 3e09654173..ca0226b39d 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml @@ -44,7 +44,7 @@ Rectangle verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter height: UM.Theme.getSize("toolbox_heading_label").height - width: parent.width + width: parent.width - UM.Theme.getSize("default_margin").width wrapMode: Text.WordWrap font: UM.Theme.getFont("medium_bold") } From 31331e36d2fa6468973f1f1d26ae7df3d8c0d6a9 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 12 Dec 2018 09:19:43 +0100 Subject: [PATCH 0890/1292] Revert "Use the capitalized version of the buildplate name" This reverts commit 11d8831d7a9a15e3e916d5d9762bfe1f755042e5. Contributes to CURA-6021. --- cura/PrinterOutput/ConfigurationModel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/PrinterOutput/ConfigurationModel.py b/cura/PrinterOutput/ConfigurationModel.py index 6f55aa3b1f..89e609c913 100644 --- a/cura/PrinterOutput/ConfigurationModel.py +++ b/cura/PrinterOutput/ConfigurationModel.py @@ -44,7 +44,7 @@ class ConfigurationModel(QObject): @pyqtProperty(str, fset = setBuildplateConfiguration, notify = configurationChanged) def buildplateConfiguration(self) -> str: - return self._buildplate_configuration.capitalize() + return self._buildplate_configuration ## This method is intended to indicate whether the configuration is valid or not. # The method checks if the mandatory fields are or not set From f302a76d3aedf38e051e692f59246d406a1295d9 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 12 Dec 2018 10:47:15 +0100 Subject: [PATCH 0891/1292] Fix typing issue in Toolbox CURA-6006 --- plugins/Toolbox/src/Toolbox.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index ab975548ce..d957b7aae1 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -670,7 +670,8 @@ class Toolbox(QObject, Extension): self.setDownloadProgress(new_progress) if bytes_sent == bytes_total: self.setIsDownloading(False) - cast(QNetworkReply, self._download_reply).downloadProgress.disconnect(self._onDownloadProgress) + self._download_reply = cast(QNetworkReply, self._download_reply) + self._download_reply.downloadProgress.disconnect(self._onDownloadProgress) # Check if the download was sucessfull if self._download_reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) != 200: From a6663ea0e8cf80cfc6bcd4d71db593009b83f514 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 12 Dec 2018 10:51:11 +0100 Subject: [PATCH 0892/1292] Fix typing issues CURA-6005 --- cura/CuraConstants.py | 2 +- plugins/CuraDrive/src/DriveApiService.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/CuraConstants.py b/cura/CuraConstants.py index 331937a0c2..c573d550c5 100644 --- a/cura/CuraConstants.py +++ b/cura/CuraConstants.py @@ -41,7 +41,7 @@ except ImportError: # Cloud API # --------- DEFAULT_CLOUD_API_ROOT = "https://api.ultimaker.com" # type: str -DEFAULT_CLOUD_API_VERSION = 1 # type: int +DEFAULT_CLOUD_API_VERSION = "1" # type: str try: from cura.CuraVersion import CuraCloudAPIRoot # type: ignore diff --git a/plugins/CuraDrive/src/DriveApiService.py b/plugins/CuraDrive/src/DriveApiService.py index 6963e595b5..98199c91cf 100644 --- a/plugins/CuraDrive/src/DriveApiService.py +++ b/plugins/CuraDrive/src/DriveApiService.py @@ -108,7 +108,7 @@ class DriveApiService: for chunk in download_package: write_backup.write(chunk) - if not self._verifyMd5Hash(temporary_backup_file.name, backup.get("md5_hash")): + if not self._verifyMd5Hash(temporary_backup_file.name, backup.get("md5_hash", "")): # Don't restore the backup if the MD5 hashes do not match. # This can happen if the download was interrupted. Logger.log("w", "Remote and local MD5 hashes do not match, not restoring backup.") From 5fd0f2b5f69e8f0597b4550a828a88da16eb8621 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 12 Dec 2018 11:09:58 +0100 Subject: [PATCH 0893/1292] Add tooltip to rating if the rating is disabled This makes it clearer what the user needs to do in order to rate (install package or login) CURA-6013 --- plugins/Toolbox/resources/qml/RatingWidget.qml | 16 ++++++++++------ .../Toolbox/resources/qml/ToolboxDetailPage.qml | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/plugins/Toolbox/resources/qml/RatingWidget.qml b/plugins/Toolbox/resources/qml/RatingWidget.qml index 355b99c0c4..9d9eb8bca8 100644 --- a/plugins/Toolbox/resources/qml/RatingWidget.qml +++ b/plugins/Toolbox/resources/qml/RatingWidget.qml @@ -1,7 +1,7 @@ -import QtQuick 2.2 -import QtQuick.Controls 2.0 +import QtQuick 2.7 +import QtQuick.Controls 2.1 import UM 1.0 as UM - +import Cura 1.1 as Cura Item { id: ratingWidget @@ -11,6 +11,7 @@ Item property string packageId: "" property int userRating: 0 + property bool canRate: false signal rated(int rating) @@ -20,7 +21,7 @@ Item { id: mouseArea anchors.fill: parent - hoverEnabled: ratingWidget.enabled + hoverEnabled: ratingWidget.canRate acceptedButtons: Qt.NoButton onExited: { @@ -40,12 +41,15 @@ Item hoverEnabled: true onHoveredChanged: { - if(hovered) + if(hovered && ratingWidget.canRate) { indexHovered = index } } + ToolTip.visible: control.hovered && !ratingWidget.canRate + ToolTip.text: !Cura.API.account.isLoggedIn ? catalog.i18nc("@label", "You need to login first before you can rate"): catalog.i18nc("@label", "You need to install the package before you can rate") + property bool isStarFilled: { // If the entire widget is hovered, override the actual rating. @@ -72,7 +76,7 @@ Item // Unfilled stars should always have the default color. Only filled stars should change on hover color: { - if(!enabled) + if(!ratingWidget.canRate) { return "#5a5a5a" } diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 1d977883f9..d0608be4de 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -135,7 +135,7 @@ Item visible: details.type == "plugin" packageId: details.id userRating: details.user_rating - enabled: toolbox.isInstalled(details.id) && Cura.API.account.isLoggedIn + canRate: toolbox.isInstalled(details.id) && Cura.API.account.isLoggedIn onRated: { From a6a16a682dd6995c7b84e597710765c3e21cd0a1 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 12 Dec 2018 11:17:44 +0100 Subject: [PATCH 0894/1292] Fix some alignments Also modify a bit the code in the ConfigurationItem, trying to get rid of a binding loop, but I couldn't (so weird) Contributes to CURA-5876. --- .../ConfigurationMenu/AutoConfiguration.qml | 1 + .../ConfigurationMenu/ConfigurationItem.qml | 167 +++++++++--------- .../ConfigurationListView.qml | 3 +- .../ConfigurationMenu/ConfigurationMenu.qml | 25 +-- resources/themes/cura-light/theme.json | 1 + 5 files changed, 98 insertions(+), 99 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml index 2e8be05fef..a3ed5040b7 100644 --- a/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml @@ -31,6 +31,7 @@ Item ConfigurationListView { anchors.top: header.bottom + anchors.topMargin: UM.Theme.getSize("default_margin").width width: parent.width outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 9dae075b48..a73cd3b46c 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -14,120 +14,115 @@ Button property var configuration: null hoverEnabled: true - height: background.height - background: Rectangle { - height: childrenRect.height color: parent.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") border.color: parent.checked ? UM.Theme.getColor("primary") : UM.Theme.getColor("lining") border.width: UM.Theme.getSize("default_lining").width radius: UM.Theme.getSize("default_radius").width + } - Column + contentItem: Column + { + id: contentColumn + width: parent.width + padding: UM.Theme.getSize("default_margin").width + spacing: UM.Theme.getSize("narrow_margin").height + + Row { - id: contentColumn - width: parent.width - padding: UM.Theme.getSize("wide_margin").width - spacing: UM.Theme.getSize("narrow_margin").height + id: extruderRow - Row + anchors { - id: extruderRow - - anchors - { - left: parent.left - leftMargin: parent.padding - right: parent.right - rightMargin: parent.padding - } - height: childrenRect.height - - spacing: UM.Theme.getSize("default_margin").width - - Repeater - { - id: repeater - height: childrenRect.height - model: configuration.extruderConfigurations - delegate: PrintCoreConfiguration - { - width: Math.round(parent.width / 2) - printCoreConfiguration: modelData - } - } + left: parent.left + leftMargin: 2 * parent.padding + right: parent.right + rightMargin: 2 * parent.padding } - //Buildplate row separator - Rectangle + spacing: UM.Theme.getSize("default_margin").width + + Repeater { - id: separator - - visible: buildplateInformation.visible - anchors + id: repeater + model: configuration.extruderConfigurations + delegate: PrintCoreConfiguration { - left: parent.left - leftMargin: parent.padding - right: parent.right - rightMargin: parent.padding - } - height: visible ? Math.round(UM.Theme.getSize("default_lining").height / 2) : 0 - color: UM.Theme.getColor("lining") - } - - Item - { - id: buildplateInformation - - anchors - { - left: parent.left - leftMargin: parent.padding - right: parent.right - rightMargin: parent.padding - } - height: childrenRect.height - visible: configuration.buildplateConfiguration != "" - - UM.RecolorImage - { - id: buildplateIcon - anchors.left: parent.left - width: UM.Theme.getSize("main_window_header_button_icon").width - height: UM.Theme.getSize("main_window_header_button_icon").height - source: UM.Theme.getIcon("buildplate") - color: UM.Theme.getColor("text") - } - - Label - { - id: buildplateLabel - anchors.left: buildplateIcon.right - anchors.verticalCenter: buildplateIcon.verticalCenter - anchors.leftMargin: Math.round(UM.Theme.getSize("default_margin").height / 2) - text: configuration.buildplateConfiguration - renderType: Text.NativeRendering - color: UM.Theme.getColor("text") + width: Math.round(parent.width / 2) + printCoreConfiguration: modelData } } } - Connections + //Buildplate row separator + Rectangle { - target: Cura.MachineManager - onCurrentConfigurationChanged: + id: separator + + visible: buildplateInformation.visible + anchors { - configurationItem.checked = Cura.MachineManager.matchesConfiguration(configuration) + left: parent.left + leftMargin: 2 * parent.padding + right: parent.right + rightMargin: 2 * parent.padding } + height: visible ? Math.round(UM.Theme.getSize("default_lining").height / 2) : 0 + color: UM.Theme.getColor("lining") } - Component.onCompleted: + Item + { + id: buildplateInformation + + anchors + { + left: parent.left + leftMargin: 2 * parent.padding + right: parent.right + rightMargin: 2 * parent.padding + } + height: childrenRect.height + visible: configuration.buildplateConfiguration != "" + + UM.RecolorImage + { + id: buildplateIcon + anchors.left: parent.left + width: UM.Theme.getSize("main_window_header_button_icon").width + height: UM.Theme.getSize("main_window_header_button_icon").height + source: UM.Theme.getIcon("buildplate") + color: UM.Theme.getColor("text") + } + + Label + { + id: buildplateLabel + anchors.left: buildplateIcon.right + anchors.verticalCenter: buildplateIcon.verticalCenter + anchors.leftMargin: Math.round(UM.Theme.getSize("default_margin").height / 2) + text: configuration.buildplateConfiguration + renderType: Text.NativeRendering + color: UM.Theme.getColor("text") + } + } + } + + Connections + { + target: Cura.MachineManager + onCurrentConfigurationChanged: { configurationItem.checked = Cura.MachineManager.matchesConfiguration(configuration) } } + Component.onCompleted: + { + configurationItem.checked = Cura.MachineManager.matchesConfiguration(configuration) + } + onClicked: { Cura.MachineManager.applyRemoteConfiguration(configuration) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index 3cc0754284..d7ffa0d8ff 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -11,7 +11,7 @@ Column { id: base property var outputDevice: null - height: childrenRect.height + 2 * padding + height: childrenRect.height + padding spacing: UM.Theme.getSize("narrow_margin").height function forceModelUpdate() @@ -57,7 +57,6 @@ Column id: configurationList spacing: UM.Theme.getSize("narrow_margin").height width: container.width - ((height > container.maximumHeight) ? container.ScrollBar.vertical.background.width : 0) //Make room for scroll bar if there is any. - contentHeight: childrenRect.height height: childrenRect.height section.property: "modelData.printerType" diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index 33a317b42b..2165f001f9 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -34,6 +34,8 @@ Cura.ExpandablePopup Custom } + contentPadding: UM.Theme.getSize("default_lining").width + contentAlignment: Cura.ExpandablePopup.ContentAlignment.AlignLeft enabled: Cura.MachineManager.hasMaterials || Cura.MachineManager.hasVariants || Cura.MachineManager.hasVariantBuildplates; //Only let it drop down if there is any configuration that you could change. headerItem: Item @@ -127,8 +129,9 @@ Cura.ExpandablePopup contentItem: Column { id: popupItem - width: base.width - 2 * UM.Theme.getSize("default_margin").width + width: UM.Theme.getSize("configuration_selector").width height: implicitHeight //Required because ExpandableComponent will try to use this to determine the size of the background of the pop-up. + padding: UM.Theme.getSize("default_margin").height spacing: UM.Theme.getSize("default_margin").height property bool is_connected: false //If current machine is connected to a printer. Only evaluated upon making popup visible. @@ -141,19 +144,19 @@ Cura.ExpandablePopup Item { - width: parent.width + width: parent.width - 2 * parent.padding height: { - var height = 0; - if(autoConfiguration.visible) + var height = 0 + if (autoConfiguration.visible) { - height += autoConfiguration.height; + height += autoConfiguration.height } - if(customConfiguration.visible) + if (customConfiguration.visible) { - height += customConfiguration.height; + height += customConfiguration.height } - return height; + return height } AutoConfiguration { @@ -172,9 +175,9 @@ Cura.ExpandablePopup { id: separator visible: buttonBar.visible - x: -contentPadding + x: -parent.padding - width: base.width + width: parent.width height: UM.Theme.getSize("default_lining").height color: UM.Theme.getColor("lining") @@ -186,7 +189,7 @@ Cura.ExpandablePopup id: buttonBar visible: popupItem.is_connected //Switching only makes sense if the "auto" part is possible. - width: parent.width + width: parent.width - 2 * parent.padding height: childrenRect.height Cura.SecondaryButton diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index b4d0ab7092..201703c6be 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -356,6 +356,7 @@ "expandable_component_content_header": [0.0, 3.0], + "configuration_selector": [38.0, 4.0], "configuration_selector_mode_tabs": [0.0, 3.0], "action_panel_widget": [25.0, 0.0], From b1244b6bde57b158dc0629dcd66f32644582487e Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 12 Dec 2018 11:22:35 +0100 Subject: [PATCH 0895/1292] Remove file MonitorSidebar It's not used anymore. Contributes to CURA-5876. --- resources/qml/MonitorSidebar.qml | 212 ------------------------------- 1 file changed, 212 deletions(-) delete mode 100644 resources/qml/MonitorSidebar.qml diff --git a/resources/qml/MonitorSidebar.qml b/resources/qml/MonitorSidebar.qml deleted file mode 100644 index 669bdbfb8f..0000000000 --- a/resources/qml/MonitorSidebar.qml +++ /dev/null @@ -1,212 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.10 -import QtQuick.Controls 2.0 -import QtQuick.Layouts 1.3 - -import UM 1.2 as UM -import Cura 1.0 as Cura - -import "Menus" -import "Menus/ConfigurationMenu" - - -Rectangle -{ - id: base - - property int currentModeIndex - property bool hideSettings: PrintInformation.preSliced - property bool hideView: Cura.MachineManager.activeMachineName == "" - - // Is there an output device for this printer? - property bool isNetworkPrinter: Cura.MachineManager.activeMachineNetworkKey != "" - property bool printerConnected: Cura.MachineManager.printerConnected - property bool printerAcceptsCommands: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands - property var connectedPrinter: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null - - property variant printDuration: PrintInformation.currentPrintTime - property variant printMaterialLengths: PrintInformation.materialLengths - property variant printMaterialWeights: PrintInformation.materialWeights - property variant printMaterialCosts: PrintInformation.materialCosts - property variant printMaterialNames: PrintInformation.materialNames - - color: UM.Theme.getColor("main_background") - UM.I18nCatalog { id: catalog; name: "cura"} - - Timer { - id: tooltipDelayTimer - interval: 500 - repeat: false - property var item - property string text - - onTriggered: - { - base.showTooltip(base, {x: 0, y: item.y}, text); - } - } - - function showTooltip(item, position, text) - { - tooltip.text = text; - position = item.mapToItem(base, position.x - UM.Theme.getSize("default_arrow").width, position.y); - tooltip.show(position); - } - - function hideTooltip() - { - tooltip.hide(); - } - - function strPadLeft(string, pad, length) { - return (new Array(length + 1).join(pad) + string).slice(-length); - } - - function getPrettyTime(time) - { - var hours = Math.floor(time / 3600) - time -= hours * 3600 - var minutes = Math.floor(time / 60); - time -= minutes * 60 - var seconds = Math.floor(time); - - var finalTime = strPadLeft(hours, "0", 2) + ":" + strPadLeft(minutes, "0", 2) + ":" + strPadLeft(seconds, "0", 2); - return finalTime; - } - - MouseArea - { - anchors.fill: parent - acceptedButtons: Qt.AllButtons - - onWheel: - { - wheel.accepted = true; - } - } - - MachineSelector - { - id: machineSelection - width: base.width - configSelection.width - separator.width - height: UM.Theme.getSize("stage_menu").height - anchors.top: base.top - anchors.left: parent.left - } - - Rectangle - { - id: separator - visible: configSelection.visible - width: visible ? Math.round(UM.Theme.getSize("thick_lining").height / 2) : 0 - height: UM.Theme.getSize("stage_menu").height - color: UM.Theme.getColor("thick_lining") - anchors.left: machineSelection.right - } - - CustomConfigurationSelector - { - id: configSelection - visible: isNetworkPrinter && printerConnected - width: visible ? Math.round(base.width * 0.15) : 0 - height: UM.Theme.getSize("stage_menu").height - anchors.top: base.top - anchors.right: parent.right - } - - Loader - { - id: controlItem - anchors.bottom: footerSeparator.top - anchors.top: machineSelection.bottom - anchors.left: base.left - anchors.right: base.right - sourceComponent: - { - if(connectedPrinter != null) - { - if(connectedPrinter.controlItem != null) - { - return connectedPrinter.controlItem - } - } - return null - } - } - - Loader - { - anchors.bottom: footerSeparator.top - anchors.top: machineSelection.bottom - anchors.left: base.left - anchors.right: base.right - source: - { - if(controlItem.sourceComponent == null) - { - return "PrintMonitor.qml" - } - else - { - return "" - } - } - } - - Rectangle - { - id: footerSeparator - width: parent.width - height: UM.Theme.getSize("wide_lining").height - color: UM.Theme.getColor("wide_lining") - anchors.bottom: monitorButton.top - anchors.bottomMargin: UM.Theme.getSize("thick_margin").height - } - - // MonitorButton is actually the bottom footer panel. - MonitorButton - { - id: monitorButton - implicitWidth: base.width - anchors.bottom: parent.bottom - } - - PrintSetupTooltip - { - id: tooltip - } - - UM.SettingPropertyProvider - { - id: machineExtruderCount - - containerStack: Cura.MachineManager.activeMachine - key: "machine_extruder_count" - watchedProperties: [ "value" ] - storeIndex: 0 - } - - UM.SettingPropertyProvider - { - id: machineHeatedBed - - containerStack: Cura.MachineManager.activeMachine - key: "machine_heated_bed" - watchedProperties: [ "value" ] - storeIndex: 0 - } - - // Make the ConfigurationSelector react when the global container changes, otherwise if Cura is not connected to the printer, - // switching printers make no reaction - Connections - { - target: Cura.MachineManager - onGlobalContainerChanged: - { - base.isNetworkPrinter = Cura.MachineManager.activeMachineNetworkKey != "" - base.printerConnected = Cura.MachineManager.printerOutputDevices.length != 0 - } - } -} From dbf91fca7f42e34111134d5e794267c1f917ee09 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 12 Dec 2018 11:40:51 +0100 Subject: [PATCH 0896/1292] Re-added hover on showcase tiles CURA-6013 --- .../qml/ToolboxDownloadsShowcaseTile.qml | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml index ca0226b39d..73d3acc76f 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml @@ -51,12 +51,11 @@ Rectangle UM.RecolorImage { width: (parent.width * 0.20) | 0 - height: (parent.height * 0.20) | 0 + height: width anchors { - bottom: parent.bottom + bottom: bottomBorder.top right: parent.right - bottomMargin: UM.Theme.getSize("default_lining").width } visible: installedPackages != 0 color: (installedPackages == packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border") @@ -70,10 +69,21 @@ Rectangle anchors.bottomMargin: UM.Theme.getSize("narrow_margin").height anchors.horizontalCenter: parent.horizontalCenter } + Rectangle + { + id: bottomBorder + color: UM.Theme.getColor("primary") + anchors.bottom: parent.bottom + width: parent.width + height: UM.Theme.getSize("toolbox_header_highlight").height + } MouseArea { anchors.fill: parent + hoverEnabled: true + onEntered: tileBase.border.color = UM.Theme.getColor("primary") + onExited: tileBase.border.color = UM.Theme.getColor("lining") onClicked: { base.selection = model From 901c19e270e3c3258e734b14c1f2433135f99695 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 12 Dec 2018 11:52:04 +0100 Subject: [PATCH 0897/1292] Prevent QML warning CURA-6013 --- plugins/Toolbox/resources/qml/SmallRatingWidget.qml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/Toolbox/resources/qml/SmallRatingWidget.qml b/plugins/Toolbox/resources/qml/SmallRatingWidget.qml index 0b93131cfd..439a7baec0 100644 --- a/plugins/Toolbox/resources/qml/SmallRatingWidget.qml +++ b/plugins/Toolbox/resources/qml/SmallRatingWidget.qml @@ -3,8 +3,6 @@ import QtQuick.Controls 1.4 import UM 1.1 as UM import Cura 1.1 as Cura - - Row { id: rating @@ -24,7 +22,7 @@ Row Label { id: numRatingsLabel - text: model.average_rating.toFixed(1) + " (" + model.num_ratings + " " + catalog.i18nc("@label", "ratings") + ")" + text: model.average_rating != undefined ? model.average_rating.toFixed(1) + " (" + model.num_ratings + " " + catalog.i18nc("@label", "ratings") + ")": "" verticalAlignment: Text.AlignVCenter height: starIcon.height width: contentWidth From 4ba448077e59791e655a497196ef65aaaae5e3c1 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 12 Dec 2018 13:33:46 +0100 Subject: [PATCH 0898/1292] Add an empty state, when there are no configurations, showing a label indicating that the list is empty Contributes to CURA-5876. --- .../ConfigurationListView.qml | 18 ++++++++++++++---- .../ConfigurationMenu/ConfigurationMenu.qml | 12 ++++++------ resources/themes/cura-light/theme.json | 2 +- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index d7ffa0d8ff..7943bba81d 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -7,16 +7,15 @@ import QtQuick.Controls 2.3 import UM 1.2 as UM import Cura 1.0 as Cura -Column +Item { id: base property var outputDevice: null - height: childrenRect.height + padding - spacing: UM.Theme.getSize("narrow_margin").height + height: childrenRect.height function forceModelUpdate() { - // FIXME For now the model should be removed and then created again, otherwise changes in the printer don't automatically update the UI + // FIXME For now the model has to be removed and then created again, otherwise changes in the printer don't automatically update the UI configurationList.model = [] if (outputDevice) { @@ -24,6 +23,17 @@ Column } } + // This component will appear when there is no configurations (e.g. when loosing connection) + Label + { + width: parent.width + visible: configurationList.model.length == 0 + text: "Configuration list empty. Probably because of lost connection" // TODO change this to a proper component + horizontalAlignment: Text.AlignHCenter + wrapMode: Text.WordWrap + renderType: Text.NativeRendering + } + ScrollView { id: container diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index 2165f001f9..e04c04f83b 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -35,7 +35,6 @@ Cura.ExpandablePopup } contentPadding: UM.Theme.getSize("default_lining").width - contentAlignment: Cura.ExpandablePopup.ContentAlignment.AlignLeft enabled: Cura.MachineManager.hasMaterials || Cura.MachineManager.hasVariants || Cura.MachineManager.hasVariantBuildplates; //Only let it drop down if there is any configuration that you could change. headerItem: Item @@ -130,18 +129,19 @@ Cura.ExpandablePopup { id: popupItem width: UM.Theme.getSize("configuration_selector").width - height: implicitHeight //Required because ExpandableComponent will try to use this to determine the size of the background of the pop-up. + height: implicitHeight // Required because ExpandableComponent will try to use this to determine the size of the background of the pop-up. padding: UM.Theme.getSize("default_margin").height spacing: UM.Theme.getSize("default_margin").height - property bool is_connected: false //If current machine is connected to a printer. Only evaluated upon making popup visible. + property bool is_connected: false // If current machine is connected to a printer. Only evaluated upon making popup visible. + property int configuration_method: ConfigurationMenu.ConfigurationMethod.Custom // Type of configuration being used. Only evaluated upon making popup visible. + onVisibleChanged: { - is_connected = Cura.MachineManager.activeMachineNetworkKey !== "" && Cura.MachineManager.printerConnected //Re-evaluate. + is_connected = Cura.MachineManager.activeMachineNetworkKey !== "" && Cura.MachineManager.printerConnected // Re-evaluate. + configuration_method = is_connected ? ConfigurationMenu.ConfigurationMethod.Auto : ConfigurationMenu.ConfigurationMethod.Custom // Auto if connected to a printer at start-up, or Custom if not. } - property int configuration_method: is_connected ? ConfigurationMenu.ConfigurationMethod.Auto : ConfigurationMenu.ConfigurationMethod.Custom //Auto if connected to a printer at start-up, or Custom if not. - Item { width: parent.width - 2 * parent.padding diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 201703c6be..413d547d5d 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -356,7 +356,7 @@ "expandable_component_content_header": [0.0, 3.0], - "configuration_selector": [38.0, 4.0], + "configuration_selector": [35.0, 4.0], "configuration_selector_mode_tabs": [0.0, 3.0], "action_panel_widget": [25.0, 0.0], From 1d3da3244f593a978693e9bb8030bc01177032bb Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 12 Dec 2018 14:09:15 +0100 Subject: [PATCH 0899/1292] Remember the previous selected method in the configuration The current behavior now is to open the configuration panel in the previous state, in case it was manually selected. That means that after selecting a printer, the manual state is reset so it will open the auto configuration if it is a connected printer. It will open the custom state in case it's not connected or the printer has no connection. Contributes to CURA-5876. --- .../ConfigurationMenu/ConfigurationMenu.qml | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index e04c04f83b..6aea5b9009 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -135,11 +135,15 @@ Cura.ExpandablePopup property bool is_connected: false // If current machine is connected to a printer. Only evaluated upon making popup visible. property int configuration_method: ConfigurationMenu.ConfigurationMethod.Custom // Type of configuration being used. Only evaluated upon making popup visible. + property int manual_selected_method: -1 // It stores the configuration method selected by the user. By default the selected method is onVisibleChanged: { is_connected = Cura.MachineManager.activeMachineNetworkKey !== "" && Cura.MachineManager.printerConnected // Re-evaluate. - configuration_method = is_connected ? ConfigurationMenu.ConfigurationMethod.Auto : ConfigurationMenu.ConfigurationMethod.Custom // Auto if connected to a printer at start-up, or Custom if not. + + // If the printer is not connected, we switch always to the custom mode. If is connected instead, the auto mode + // or the previous state is selected + configuration_method = is_connected ? (manual_selected_method == -1 ? ConfigurationMenu.ConfigurationMethod.Auto : manual_selected_method) : ConfigurationMenu.ConfigurationMethod.Custom } Item @@ -158,6 +162,7 @@ Cura.ExpandablePopup } return height } + AutoConfiguration { id: autoConfiguration @@ -203,7 +208,11 @@ Cura.ExpandablePopup iconSource: UM.Theme.getIcon("arrow_right") isIconOnRightSide: true - onClicked: popupItem.configuration_method = ConfigurationMenu.ConfigurationMethod.Custom + onClicked: + { + popupItem.configuration_method = ConfigurationMenu.ConfigurationMethod.Custom + popupItem.manual_selected_method = popupItem.configuration_method + } } Cura.SecondaryButton @@ -214,8 +223,18 @@ Cura.ExpandablePopup iconSource: UM.Theme.getIcon("arrow_left") - onClicked: popupItem.configuration_method = ConfigurationMenu.ConfigurationMethod.Auto + onClicked: + { + popupItem.configuration_method = ConfigurationMenu.ConfigurationMethod.Auto + popupItem.manual_selected_method = popupItem.configuration_method + } } } } + + Connections + { + target: Cura.MachineManager + onGlobalContainerChanged: popupItem.manual_selected_method = -1 // When switching printers, reset the value of the manual selected method + } } From 17173aba0637b1a2ea22692ff3935801bb62c1a2 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 12 Dec 2018 17:04:17 +0100 Subject: [PATCH 0900/1292] Add a component to show when no configurations are available because lack of connection. Contributes to CURA-5876. --- .../qml/ActionPanel/OutputProcessWidget.qml | 2 - .../qml/ActionPanel/SliceProcessWidget.qml | 2 +- resources/qml/IconWithText.qml | 3 +- .../ConfigurationListView.qml | 37 ++++++++++++--- .../qml/PrinterSelector/MachineSelector.qml | 47 +++++-------------- resources/themes/cura-light/icons/warning.svg | 13 +++-- resources/themes/cura-light/theme.json | 2 +- 7 files changed, 56 insertions(+), 50 deletions(-) diff --git a/resources/qml/ActionPanel/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml index 3f53abf28f..5ac777e2ad 100644 --- a/resources/qml/ActionPanel/OutputProcessWidget.qml +++ b/resources/qml/ActionPanel/OutputProcessWidget.qml @@ -119,8 +119,6 @@ Column } height: UM.Theme.getSize("action_button").height - leftPadding: UM.Theme.getSize("default_margin").width - rightPadding: UM.Theme.getSize("default_margin").width text: catalog.i18nc("@button", "Preview") onClicked: UM.Controller.setActiveStage("PreviewStage") diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index 18caeafb40..3756d0d452 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -60,7 +60,7 @@ Column text: catalog.i18nc("@label:PrintjobStatus", "Unable to Slice") source: UM.Theme.getIcon("warning") - color: UM.Theme.getColor("warning") + iconColor: UM.Theme.getColor("warning") } // Progress bar, only visible when the backend is in the process of slice the printjob diff --git a/resources/qml/IconWithText.qml b/resources/qml/IconWithText.qml index 5530740040..9fd527b27e 100644 --- a/resources/qml/IconWithText.qml +++ b/resources/qml/IconWithText.qml @@ -15,6 +15,7 @@ Item { property alias source: icon.source property alias iconSize: icon.width + property alias iconColor: icon.color property alias color: label.color property alias text: label.text property alias font: label.font @@ -37,7 +38,7 @@ Item { id: icon width: UM.Theme.getSize("section_icon").width - height: UM.Theme.getSize("section_icon").height + height: width color: label.color diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index 7943bba81d..3ddbb49fe8 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -23,15 +23,40 @@ Item } } - // This component will appear when there is no configurations (e.g. when loosing connection) - Label + // This component will appear when there is no configurations (e.g. when losing connection) + Item { width: parent.width visible: configurationList.model.length == 0 - text: "Configuration list empty. Probably because of lost connection" // TODO change this to a proper component - horizontalAlignment: Text.AlignHCenter - wrapMode: Text.WordWrap - renderType: Text.NativeRendering + height: label.height + 2 * UM.Theme.getSize("default_margin").height + anchors.top: parent.top + anchors.topMargin: UM.Theme.getSize("default_margin").height + + UM.RecolorImage + { + id: icon + + anchors.left: parent.left + anchors.verticalCenter: label.verticalCenter + + source: UM.Theme.getIcon("warning") + color: UM.Theme.getColor("warning") + width: UM.Theme.getSize("section_icon").width + height: width + } + + Label + { + id: label + anchors.left: icon.right + anchors.right: parent.right + anchors.leftMargin: UM.Theme.getSize("default_margin").width + text: catalog.i18nc("@label", "The configurations are not available because the printer is disconnected.") + color: UM.Theme.getColor("text") + font: UM.Theme.getFont("default") + renderType: Text.NativeRendering + wrapMode: Text.WordWrap + } } ScrollView diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index 7cda4f1d2e..db9c38b9f1 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -24,49 +24,24 @@ Cura.ExpandablePopup name: "cura" } - headerItem: Item + headerItem: Cura.IconWithText { - implicitHeight: icon.height - - UM.RecolorImage + text: isNetworkPrinter ? Cura.MachineManager.activeMachineNetworkGroupName : Cura.MachineManager.activeMachineName + source: { - id: icon - - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - - source: + if (isNetworkPrinter) { - if (isNetworkPrinter) + if (machineSelector.outputDevice != null && machineSelector.outputDevice.clusterSize > 1) { - if (machineSelector.outputDevice != null && machineSelector.outputDevice.clusterSize > 1) - { - return UM.Theme.getIcon("printer_group") - } - return UM.Theme.getIcon("printer_single") + return UM.Theme.getIcon("printer_group") } - return "" + return UM.Theme.getIcon("printer_single") } - width: UM.Theme.getSize("machine_selector_icon").width - height: width - - color: UM.Theme.getColor("machine_selector_printer_icon") - visible: source != "" - } - - Label - { - id: label - anchors.left: icon.visible ? icon.right : parent.left - anchors.right: parent.right - anchors.leftMargin: UM.Theme.getSize("thin_margin").width - anchors.verticalCenter: icon.verticalCenter - text: isNetworkPrinter ? Cura.MachineManager.activeMachineNetworkGroupName : Cura.MachineManager.activeMachineName - elide: Text.ElideRight - color: UM.Theme.getColor("text") - font: UM.Theme.getFont("medium") - renderType: Text.NativeRendering + return "" } + font: UM.Theme.getFont("medium") + iconColor: UM.Theme.getColor("machine_selector_printer_icon") + iconSize: UM.Theme.getSize("machine_selector_icon").width UM.RecolorImage { diff --git a/resources/themes/cura-light/icons/warning.svg b/resources/themes/cura-light/icons/warning.svg index ae8a7a6430..14b7d797d0 100644 --- a/resources/themes/cura-light/icons/warning.svg +++ b/resources/themes/cura-light/icons/warning.svg @@ -1,4 +1,11 @@ - - - + + + + Icon/warning-s + Created with Sketch. + + + + + \ No newline at end of file diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 413d547d5d..1a9dec5deb 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -101,7 +101,7 @@ "printer_type_label_background": [228, 228, 242, 255], - "text": [0, 0, 0, 255], + "text": [25, 25, 25, 255], "text_detail": [174, 174, 174, 128], "text_link": [50, 130, 255, 255], "text_inactive": [174, 174, 174, 255], From a1d7fa893da138f241fd1cc74895ec8e5d928eb6 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 12 Dec 2018 17:26:13 +0100 Subject: [PATCH 0901/1292] Change the style for the toolbuttons that appear in the popup panel of some tools Contributes to CURA-6024 --- resources/themes/cura-light/styles.qml | 94 ++++++-------------------- resources/themes/cura-light/theme.json | 2 - 2 files changed, 20 insertions(+), 76 deletions(-) diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index bcc754f4ca..c940052668 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -177,8 +177,8 @@ QtObject { background: Item { - implicitWidth: Theme.getSize("button").width; - implicitHeight: Theme.getSize("button").height; + implicitWidth: Theme.getSize("button").width + implicitHeight: Theme.getSize("button").height UM.PointingRectangle { @@ -205,20 +205,20 @@ QtObject id: button_tip anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter; + anchors.verticalCenter: parent.verticalCenter text: control.text; - font: Theme.getFont("button_tooltip"); - color: Theme.getColor("tooltip_text"); + font: Theme.getFont("button_tooltip") + color: Theme.getColor("tooltip_text") } } Rectangle { - id: buttonFace; + id: buttonFace - anchors.fill: parent; - property bool down: control.pressed || (control.checkable && control.checked); + anchors.fill: parent + property bool down: control.pressed || (control.checkable && control.checked) color: { @@ -228,58 +228,22 @@ QtObject } else if(control.checkable && control.checked && control.hovered) { - return Theme.getColor("button_active_hover"); + return Theme.getColor("toolbar_button_active_hover") } else if(control.pressed || (control.checkable && control.checked)) { - return Theme.getColor("button_active"); + return Theme.getColor("toolbar_button_active") } else if(control.hovered) { - return Theme.getColor("button_hover"); - } - else - { - return Theme.getColor("button"); + return Theme.getColor("toolbar_button_hover") } + return Theme.getColor("toolbar_background") } Behavior on color { ColorAnimation { duration: 50; } } - border.width: (control.hasOwnProperty("needBorder") && control.needBorder) ? 2 * screenScaleFactor : 0 - border.color: Theme.getColor("tool_button_border") - - UM.RecolorImage - { - id: tool_button_arrow - anchors.right: parent.right; - anchors.rightMargin: Theme.getSize("button").width - Math.round(Theme.getSize("button_icon").width / 4) - anchors.bottom: parent.bottom; - anchors.bottomMargin: Theme.getSize("button").height - Math.round(Theme.getSize("button_icon").height / 4) - width: Theme.getSize("standard_arrow").width - height: Theme.getSize("standard_arrow").height - sourceSize.height: width - visible: control.menu != null; - color: - { - if(control.checkable && control.checked && control.hovered) - { - return Theme.getColor("button_text_active_hover"); - } - else if(control.pressed || (control.checkable && control.checked)) - { - return Theme.getColor("button_text_active"); - } - else if(control.hovered) - { - return Theme.getColor("button_text_hover"); - } - else - { - return Theme.getColor("button_text"); - } - } - source: Theme.getIcon("arrow_bottom") - } + border.width: (control.hasOwnProperty("needBorder") && control.needBorder) ? Theme.getSize("default_lining").width : 0 + border.color: Theme.getColor("lining") } } @@ -287,30 +251,12 @@ QtObject { UM.RecolorImage { - anchors.centerIn: parent; - opacity: !control.enabled ? 0.2 : 1.0 - source: control.iconSource; - width: Theme.getSize("button_icon").width; - height: Theme.getSize("button_icon").height; - color: - { - if(control.checkable && control.checked && control.hovered) - { - return Theme.getColor("button_text_active_hover"); - } - else if(control.pressed || (control.checkable && control.checked)) - { - return Theme.getColor("button_text_active"); - } - else if(control.hovered) - { - return Theme.getColor("button_text_hover"); - } - else - { - return Theme.getColor("button_text"); - } - } + anchors.centerIn: parent + opacity: control.enabled ? 1.0 : 0.2 + source: control.iconSource + width: Theme.getSize("button_icon").width + height: Theme.getSize("button_icon").height + color: Theme.getColor("toolbar_button_text") sourceSize: Theme.getSize("button_icon") } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 3dc216ad70..59596e9a3f 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -243,8 +243,6 @@ "tooltip": [68, 192, 255, 255], "tooltip_text": [255, 255, 255, 255], - "tool_button_border": [255, 255, 255, 0], - "message_background": [255, 255, 255, 255], "message_shadow": [0, 0, 0, 120], "message_border": [192, 193, 194, 255], From fed779d0d2cfd6a81fa5747a0a10debbcdb8c8ec Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 12 Dec 2018 17:31:08 +0100 Subject: [PATCH 0902/1292] STAR-322: Implementing multi-part upload (doesnt always work) --- .../src/Cloud/CloudApiClient.py | 23 +---- .../src/Cloud/CloudOutputDevice.py | 56 +++-------- .../src/Cloud/CloudProgressMessage.py | 37 ++++++++ .../src/Cloud/ResumableUpload.py | 94 +++++++++++++++++++ .../tests/Cloud/NetworkManagerMock.py | 3 +- .../tests/Cloud/TestCloudApiClient.py | 15 +-- 6 files changed, 161 insertions(+), 67 deletions(-) create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/CloudProgressMessage.py create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/ResumableUpload.py diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py index b08bac6670..2637f17010 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py @@ -9,6 +9,7 @@ from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply from UM.Logger import Logger from cura.API import Account from cura.NetworkClient import NetworkClient +from .ResumableUpload import ResumableUpload from ..Models import BaseModel from .Models.CloudClusterResponse import CloudClusterResponse from .Models.CloudErrorObject import CloudErrorObject @@ -69,24 +70,10 @@ class CloudApiClient(NetworkClient): # \param on_finished: The function to be called after the result is parsed. It receives the print job ID. # \param on_progress: A function to be called during upload progress. It receives a percentage (0-100). # \param on_error: A function to be called if the upload fails. It receives a dict with the error. - def uploadMesh(self, upload_response: CloudPrintJobResponse, mesh: bytes, on_finished: Callable[[str], Any], - on_progress: Callable[[int], Any], on_error: Callable[[dict], Any]): - - def progressCallback(bytes_sent: int, bytes_total: int) -> None: - if bytes_total: - on_progress(int((bytes_sent / bytes_total) * 100)) - - def finishedCallback(reply: QNetworkReply): - status_code, response = self._parseReply(reply) - if status_code < 300: - on_finished(upload_response.job_id) - else: - Logger.log("e", "Received unexpected response %s uploading mesh: %s", status_code, response) - on_error(response) - - # TODO: Multipart upload - self.put(upload_response.upload_url, data = mesh, content_type = upload_response.content_type, - on_finished = finishedCallback, on_progress = progressCallback) + def uploadMesh(self, upload_response: CloudPrintJobResponse, mesh: bytes, on_finished: Callable[[], Any], + on_progress: Callable[[int], Any], on_error: Callable[[], Any]): + ResumableUpload(upload_response.upload_url, upload_response.content_type, mesh, on_finished, + on_progress, on_error).start() # Requests a cluster to print the given print job. # \param cluster_id: The ID of the cluster. diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index c4ab752163..e75989a6a8 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -18,6 +18,7 @@ from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputController import CloudOutputController from ..MeshFormatHandler import MeshFormatHandler from ..UM3PrintJobOutputModel import UM3PrintJobOutputModel +from .CloudProgressMessage import CloudProgressMessage from .CloudApiClient import CloudApiClient from .Models.CloudClusterStatus import CloudClusterStatus from .Models.CloudPrintJobUploadRequest import CloudPrintJobUploadRequest @@ -43,9 +44,6 @@ class T: COULD_NOT_EXPORT = _I18N_CATALOG.i18nc("@info:status", "Could not export print job.") - SENDING_DATA_TEXT = _I18N_CATALOG.i18nc("@info:status", "Sending data to remote cluster") - SENDING_DATA_TITLE = _I18N_CATALOG.i18nc("@info:status", "Sending data to remote cluster") - ERROR = _I18N_CATALOG.i18nc("@info:title", "Error") UPLOAD_ERROR = _I18N_CATALOG.i18nc("@info:text", "Could not upload the data to the printer.") @@ -68,7 +66,7 @@ class T: class CloudOutputDevice(NetworkedPrinterOutputDevice): # The interval with which the remote clusters are checked - CHECK_CLUSTER_INTERVAL = 4.0 # seconds + CHECK_CLUSTER_INTERVAL = 5.0 # seconds # Signal triggered when the print jobs in the queue were changed. printJobsChanged = pyqtSignal() @@ -109,9 +107,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self._number_of_extruders = 2 # All networked printers are dual-extrusion Ultimaker machines. # We only allow a single upload at a time. - self._sending_job = False - # TODO: handle progress messages in another class. - self._progress_message = None # type: Optional[Message] + self._progress = CloudProgressMessage() # Keep server string of the last generated time to avoid updating models more than once for the same response self._received_printers = None # type: Optional[List[CloudClusterPrinterStatus]] @@ -149,7 +145,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): file_handler: Optional[FileHandler] = None, **kwargs: str) -> None: # Show an error message if we're already sending a job. - if self._sending_job: + if self._progress.visible: self._onUploadError(T.BLOCKED_UPLOADING) return @@ -286,53 +282,31 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # \param mesh: The bytes to upload. # \param job_response: The response received from the cloud API. def _onPrintJobCreated(self, mesh: bytes, job_response: CloudPrintJobResponse) -> None: - self._api.uploadMesh(job_response, mesh, self._onPrintJobUploaded, self._updateUploadProgress, - lambda _: self._onUploadError(T.UPLOAD_ERROR)) + self._progress.show() + self._api.uploadMesh(job_response, mesh, lambda: self._onPrintJobUploaded(job_response.job_id), + self._progress.update, self._onUploadError) ## Requests the print to be sent to the printer when we finished uploading the mesh. # \param job_id: The ID of the job. def _onPrintJobUploaded(self, job_id: str) -> None: self._api.requestPrint(self._device_id, job_id, self._onUploadSuccess) - ## Updates the progress of the mesh upload. - # \param progress: The amount of percentage points uploaded until now (0-100). - def _updateUploadProgress(self, progress: int) -> None: - if not self._progress_message: - self._progress_message = Message( - text = T.SENDING_DATA_TEXT, - title = T.SENDING_DATA_TITLE, - progress = -1, - lifetime = 0, - dismissable = False, - use_inactivity_timer = False - ) - self._progress_message.setProgress(progress) - self._progress_message.show() - - ## Hides the upload progress bar - def _resetUploadProgress(self) -> None: - if self._progress_message: - self._progress_message.hide() - self._progress_message = None - ## Displays the given message if uploading the mesh has failed # \param message: The message to display. - def _onUploadError(self, message: str = None) -> None: - self._resetUploadProgress() - if message: - Message( - text = message, - title = T.ERROR, - lifetime = 10 - ).show() - self._sending_job = False # the upload has finished so we're not sending a job anymore + def _onUploadError(self, message = None) -> None: + self._progress.hide() + Message( + text = message or T.UPLOAD_ERROR, + title = T.ERROR, + lifetime = 10 + ).show() self.writeError.emit() ## Shows a message when the upload has succeeded # \param response: The response from the cloud API. def _onUploadSuccess(self, response: CloudPrintResponse) -> None: Logger.log("i", "The cluster will be printing this print job with the ID %s", response.cluster_job_id) - self._resetUploadProgress() + self._progress.hide() Message( text = T.UPLOAD_SUCCESS_TEXT, title = T.UPLOAD_SUCCESS_TITLE, diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudProgressMessage.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudProgressMessage.py new file mode 100644 index 0000000000..e3e0cefc0c --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudProgressMessage.py @@ -0,0 +1,37 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +from UM import i18nCatalog +from UM.Message import Message + + +## Class that contains all the translations for this module. +class T: + _I18N_CATALOG = i18nCatalog("cura") + + SENDING_DATA_TEXT = _I18N_CATALOG.i18nc("@info:status", "Sending data to remote cluster") + SENDING_DATA_TITLE = _I18N_CATALOG.i18nc("@info:status", "Sending data to remote cluster") + + +class CloudProgressMessage(Message): + def __init__(self): + super().__init__( + text = T.SENDING_DATA_TEXT, + title = T.SENDING_DATA_TITLE, + progress = -1, + lifetime = 0, + dismissable = False, + use_inactivity_timer = False + ) + + def show(self): + self.setProgress(0) + super().show() + + def update(self, percentage: int) -> None: + if not self._visible: + super().show() + self.setProgress(percentage) + + @property + def visible(self) -> bool: + return self._visible diff --git a/plugins/UM3NetworkPrinting/src/Cloud/ResumableUpload.py b/plugins/UM3NetworkPrinting/src/Cloud/ResumableUpload.py new file mode 100644 index 0000000000..52b8e5c2d7 --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Cloud/ResumableUpload.py @@ -0,0 +1,94 @@ +# Copyright (c) 2018 Ultimaker B.V. +# !/usr/bin/env python +# -*- coding: utf-8 -*- +from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply +from typing import Optional, Callable, Any, Tuple + +from UM.Logger import Logger +from cura.NetworkClient import NetworkClient + + +class ResumableUpload(NetworkClient): + MAX_RETRIES = 10 + BYTES_PER_REQUEST = 256 * 1024 + RETRY_HTTP_CODES = {500, 502, 503, 504} + + ## Creates a resumable upload + # \param url: The URL to which we shall upload. + # \param content_length: The total content length of the file, in bytes. + # \param http_method: The HTTP method to be used, e.g. "POST" or "PUT". + # \param timeout: The timeout for each chunk upload. Important: If None, no timeout is applied at all. + def __init__(self, url: str, content_type: str, data: bytes, + on_finished: Callable[[], Any], on_progress: Callable[[int], Any], on_error: Callable[[], Any]): + super().__init__() + self._url = url + self._content_type = content_type + self._data = data + + self._on_finished = on_finished + self._on_progress = on_progress + self._on_error = on_error + + self._sent_bytes = 0 + self._retries = 0 + self._finished = False + + ## We override _createEmptyRequest in order to add the user credentials. + # \param url: The URL to request + # \param content_type: The type of the body contents. + def _createEmptyRequest(self, path: str, content_type: Optional[str] = "application/json") -> QNetworkRequest: + request = super()._createEmptyRequest(path, content_type = self._content_type) + + first_byte, last_byte = self._chunkRange() + content_range = "bytes {}-{}/{}".format(first_byte, last_byte - 1, len(self._data)) + request.setRawHeader(b"Content-Range", content_range.encode()) + Logger.log("i", "Uploading %s to %s", content_range, self._url) + + return request + + def _chunkRange(self) -> Tuple[int, int]: + last_byte = min(len(self._data), self._sent_bytes + self.BYTES_PER_REQUEST) + return self._sent_bytes, last_byte + + def start(self) -> None: + self._uploadChunk() + + def _uploadChunk(self) -> None: + if self._finished: + raise ValueError("The upload is already finished") + + first_byte, last_byte = self._chunkRange() + Logger.log("i", "PUT %s - %s", first_byte, last_byte) + self.put(self._url, data = self._data[first_byte:last_byte], content_type = self._content_type, + on_finished = self.finishedCallback, on_progress = self.progressCallback) + + def progressCallback(self, bytes_sent: int, bytes_total: int) -> None: + if bytes_total: + self._on_progress(int((self._sent_bytes + bytes_sent) / len(self._data) * 100)) + + def finishedCallback(self, reply: QNetworkReply) -> None: + status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) + + if self._retries < self.MAX_RETRIES and status_code in self.RETRY_HTTP_CODES: + self._retries += 1 + Logger.log("i", "Retrying %s/%s request %s", tries, self.MAX_RETRIES, request.url) + self._uploadChunk() + return + + body = bytes(reply.readAll()).decode() + Logger.log("w", "status_code: %s, Headers: %s, body: %s", status_code, + [bytes(header).decode() for header in reply.rawHeaderList()], body) + + if status_code > 308: + self._finished = True + Logger.log("e", "Received error while uploading: %s", body) + self._on_error() + return + + first_byte, last_byte = self._chunkRange() + self._sent_bytes += last_byte - first_byte + self._finished = self._sent_bytes >= len(self._data) + if self._finished: + self._on_finished() + else: + self._uploadChunk() diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py b/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py index 94cc239c0a..60627cbe7c 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py @@ -76,7 +76,8 @@ class NetworkManagerMock: ## Emits the signal that the reply is ready to all prepared replies. def flushReplies(self) -> None: - for reply in self.replies.values(): + for key, reply in self.replies.items(): + Logger.log("i", "Flushing reply to {} {}", *key) self.finished.emit(reply) self.reset() diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py index d673554640..e377627465 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py @@ -89,16 +89,17 @@ class TestCloudApiClient(TestCase): data = parseFixture("putJobUploadResponse")["data"] upload_response = CloudPrintJobResponse(**data) - self.network.prepareReply("PUT", upload_response.upload_url, 200, - b'{ data : "" }') # Network client doesn't look into the reply + # Network client doesn't look into the reply + self.network.prepareReply("PUT", upload_response.upload_url, 200, b'{}') - self.api.uploadMesh(upload_response, b'', lambda job_id: results.append(job_id), - progress.advance, progress.error) + mesh = ("1234" * 100000).encode() + self.api.uploadMesh(upload_response, mesh, lambda: results.append("sent"), progress.advance, progress.error) - self.network.flushReplies() + for _ in range(10): + self.network.flushReplies() + self.network.prepareReply("PUT", upload_response.upload_url, 200, b'{}') - self.assertEqual(len(results), 1) - self.assertEqual(results[0], upload_response.job_id) + self.assertEqual(["sent"], results) def test_requestPrint(self, network_mock): network_mock.return_value = self.network From 77ede1ae6bbd6c1a53b6682640fb754f186eee42 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 12 Dec 2018 17:50:21 +0100 Subject: [PATCH 0903/1292] Unify the fonts to only have 8 instead of 13. Contributes to CURA-6025. --- .../PostProcessingPlugin.qml | 4 +- .../resources/qml/ToolboxAuthorPage.qml | 2 +- .../resources/qml/ToolboxDetailPage.qml | 2 +- .../resources/qml/DiscoverUM3Action.qml | 2 +- .../resources/qml/MonitorPrinterCard.qml | 6 +-- .../resources/qml/MonitorStage.qml | 2 +- resources/qml/Account/AccountDetails.qml | 2 +- resources/qml/ActionButton.qml | 2 +- resources/qml/Dialogs/AboutDialog.qml | 2 +- resources/qml/ExtruderIcon.qml | 2 +- .../ConfigurationMenu/AutoConfiguration.qml | 2 +- .../ConfigurationMenu/CustomConfiguration.qml | 2 +- resources/qml/MonitorButton.qml | 4 +- resources/qml/Preferences/MachinesPage.qml | 2 +- .../Materials/MaterialsDetailsPanel.qml | 2 +- resources/qml/Preferences/ProfilesPage.qml | 2 +- resources/qml/PrinterOutput/ExtruderBox.qml | 4 +- resources/qml/PrinterOutput/HeatedBedBox.qml | 4 +- .../qml/PrinterOutput/MonitorSection.qml | 2 +- .../qml/PrinterOutput/OutputDeviceHeader.qml | 2 +- .../PrinterSelector/MachineSelectorButton.qml | 2 +- resources/qml/Settings/SettingCategory.qml | 2 +- resources/qml/ViewsSelector.qml | 2 +- resources/themes/cura-light/styles.qml | 6 +-- resources/themes/cura-light/theme.json | 38 +++++-------------- 25 files changed, 41 insertions(+), 61 deletions(-) diff --git a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml index b962f4d53b..580bb8c878 100644 --- a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml +++ b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml @@ -61,7 +61,7 @@ UM.Dialog anchors.leftMargin: base.textMargin anchors.right: parent.right anchors.rightMargin: base.textMargin - font: UM.Theme.getFont("large") + font: UM.Theme.getFont("large_bold") elide: Text.ElideRight } ListView @@ -276,7 +276,7 @@ UM.Dialog anchors.rightMargin: base.textMargin elide: Text.ElideRight height: 20 * screenScaleFactor - font: UM.Theme.getFont("large") + font: UM.Theme.getFont("large_bold") color: UM.Theme.getColor("text") } diff --git a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml index 7b026566c3..b653f1a73b 100644 --- a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml @@ -55,7 +55,7 @@ Item bottomMargin: UM.Theme.getSize("default_margin").height } text: details.name || "" - font: UM.Theme.getFont("large") + font: UM.Theme.getFont("large_bold") wrapMode: Text.WordWrap width: parent.width height: UM.Theme.getSize("toolbox_property_label").height diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 7983be8aef..fa91fa4884 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -60,7 +60,7 @@ Item bottomMargin: UM.Theme.getSize("default_margin").height } text: details === null ? "" : (details.name || "") - font: UM.Theme.getFont("large") + font: UM.Theme.getFont("large_bold") color: UM.Theme.getColor("text") wrapMode: Text.WordWrap width: parent.width diff --git a/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml b/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml index e5f668c70d..65fe859772 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml @@ -223,7 +223,7 @@ Cura.MachineAction width: parent.width wrapMode: Text.WordWrap text: base.selectedDevice ? base.selectedDevice.name : "" - font: UM.Theme.getFont("large") + font: UM.Theme.getFont("large_bold") elide: Text.ElideRight renderType: Text.NativeRendering } diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml index 1676c51edf..67a8af727a 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml @@ -76,7 +76,7 @@ Item text: printer && printer.name ? printer.name : "" color: "#414054" // TODO: Theme! elide: Text.ElideRight - font: UM.Theme.getFont("large") // 16pt, bold + font: UM.Theme.getFont("large_bold") // 16pt, bold width: parent.width // FIXED-LINE-HEIGHT: @@ -178,7 +178,7 @@ Item verticalCenter: parent.verticalCenter } color: "#414054" // TODO: Theme! - font: UM.Theme.getFont("large") // 16pt, bold + font: UM.Theme.getFont("large_bold") // 16pt, bold text: { if (printer && printer.state == "disabled") { @@ -229,7 +229,7 @@ Item id: printerJobNameLabel color: printer.activePrintJob && printer.activePrintJob.isActive ? "#414054" : "#babac1" // TODO: Theme! elide: Text.ElideRight - font: UM.Theme.getFont("large") // 16pt, bold + font: UM.Theme.getFont("large_bold") // 16pt, bold text: base.printer.activePrintJob ? base.printer.activePrintJob.name : "Untitled" // TODO: I18N width: parent.width diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml index 4d59e0eb6b..0008295301 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml @@ -97,7 +97,7 @@ Component top: parent.top } color: UM.Theme.getColor("text") - font: UM.Theme.getFont("large_nonbold") + font: UM.Theme.getFont("large") text: catalog.i18nc("@label", "Queued") } diff --git a/resources/qml/Account/AccountDetails.qml b/resources/qml/Account/AccountDetails.qml index bfb23930c6..45f822e41f 100644 --- a/resources/qml/Account/AccountDetails.qml +++ b/resources/qml/Account/AccountDetails.qml @@ -44,7 +44,7 @@ Column horizontalAlignment: Text.AlignHCenter renderType: Text.NativeRendering text: loggedIn ? profile["username"] : catalog.i18nc("@label", "Please log in or create an account to\nenjoy all features of Ultimaker Cura.") - font: loggedIn ? UM.Theme.getFont("large") : UM.Theme.getFont("default") + font: loggedIn ? UM.Theme.getFont("large_bold") : UM.Theme.getFont("default") color: UM.Theme.getColor("text") } diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index 7177120f35..c3d39e8251 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -62,7 +62,7 @@ Button id: buttonText text: button.text color: button.enabled ? (button.hovered ? button.textHoverColor : button.textColor): button.textDisabledColor - font: UM.Theme.getFont("action_button") + font: UM.Theme.getFont("medium") visible: text != "" renderType: Text.NativeRendering anchors.verticalCenter: parent.verticalCenter diff --git a/resources/qml/Dialogs/AboutDialog.qml b/resources/qml/Dialogs/AboutDialog.qml index add84614e0..ac115a0e5f 100644 --- a/resources/qml/Dialogs/AboutDialog.qml +++ b/resources/qml/Dialogs/AboutDialog.qml @@ -51,7 +51,7 @@ UM.Dialog id: version text: catalog.i18nc("@label","version: %1").arg(UM.Application.version) - font: UM.Theme.getFont("large") + font: UM.Theme.getFont("large_bold") color: UM.Theme.getColor("text") anchors.right : logo.right anchors.top: logo.bottom diff --git a/resources/qml/ExtruderIcon.qml b/resources/qml/ExtruderIcon.qml index bb0b347b7e..0ab9df308e 100644 --- a/resources/qml/ExtruderIcon.qml +++ b/resources/qml/ExtruderIcon.qml @@ -48,7 +48,7 @@ Item id: extruderNumberText anchors.centerIn: parent text: index + 1 - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("small") width: contentWidth height: contentHeight visible: extruderEnabled diff --git a/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml index 68c56c7c4b..af229e4cc0 100644 --- a/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml @@ -16,7 +16,7 @@ Item { id: header text: catalog.i18nc("@header", "Configurations") - font: UM.Theme.getFont("large") + font: UM.Theme.getFont("large_bold") color: UM.Theme.getColor("text") height: contentHeight renderType: Text.NativeRendering diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index 8429e2c093..8f38edfe5b 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -23,7 +23,7 @@ Item { id: header text: catalog.i18nc("@header", "Custom") - font: UM.Theme.getFont("large") + font: UM.Theme.getFont("large_bold") color: UM.Theme.getColor("text") height: contentHeight renderType: Text.NativeRendering diff --git a/resources/qml/MonitorButton.qml b/resources/qml/MonitorButton.qml index fd7d2287c4..99640b1059 100644 --- a/resources/qml/MonitorButton.qml +++ b/resources/qml/MonitorButton.qml @@ -168,7 +168,7 @@ Item anchors.leftMargin: UM.Theme.getSize("thick_margin").width color: base.statusColor - font: UM.Theme.getFont("large") + font: UM.Theme.getFont("large_bold") text: statusText } @@ -179,7 +179,7 @@ Item anchors.right: progressBar.right color: base.statusColor - font: UM.Theme.getFont("large") + font: UM.Theme.getFont("large_bold") text: Math.round(progress) + "%" visible: showProgress } diff --git a/resources/qml/Preferences/MachinesPage.qml b/resources/qml/Preferences/MachinesPage.qml index bc75b9bc72..de65579cd3 100644 --- a/resources/qml/Preferences/MachinesPage.qml +++ b/resources/qml/Preferences/MachinesPage.qml @@ -70,7 +70,7 @@ UM.ManagementPage { id: machineName text: base.currentItem && base.currentItem.name ? base.currentItem.name : "" - font: UM.Theme.getFont("large") + font: UM.Theme.getFont("large_bold") width: parent.width elide: Text.ElideRight } diff --git a/resources/qml/Preferences/Materials/MaterialsDetailsPanel.qml b/resources/qml/Preferences/Materials/MaterialsDetailsPanel.qml index 92970f40e2..eb4a63250f 100644 --- a/resources/qml/Preferences/Materials/MaterialsDetailsPanel.qml +++ b/resources/qml/Preferences/Materials/MaterialsDetailsPanel.qml @@ -65,7 +65,7 @@ Item Label { text: materialProperties.name - font: UM.Theme.getFont("large") + font: UM.Theme.getFont("large_bold") } } diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index d7ffbb3152..70f9881b1e 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -471,7 +471,7 @@ Item Label { text: base.currentItemName - font: UM.Theme.getFont("large") + font: UM.Theme.getFont("large_bold") } } diff --git a/resources/qml/PrinterOutput/ExtruderBox.qml b/resources/qml/PrinterOutput/ExtruderBox.qml index 247bb3a27d..a19c02b0dd 100644 --- a/resources/qml/PrinterOutput/ExtruderBox.qml +++ b/resources/qml/PrinterOutput/ExtruderBox.qml @@ -80,7 +80,7 @@ Item id: extruderCurrentTemperature text: Math.round(extruderModel.hotendTemperature) + "°C" color: UM.Theme.getColor("text") - font: UM.Theme.getFont("large") + font: UM.Theme.getFont("large_bold") anchors.right: extruderTargetTemperature.left anchors.top: parent.top anchors.margins: UM.Theme.getSize("default_margin").width @@ -326,7 +326,7 @@ Item return UM.Theme.getColor("action_button_text"); } } - font: UM.Theme.getFont("action_button") + font: UM.Theme.getFont("medium") text: { if(extruderModel == null) diff --git a/resources/qml/PrinterOutput/HeatedBedBox.qml b/resources/qml/PrinterOutput/HeatedBedBox.qml index 33cf5cd1e2..77421c8aad 100644 --- a/resources/qml/PrinterOutput/HeatedBedBox.qml +++ b/resources/qml/PrinterOutput/HeatedBedBox.qml @@ -67,7 +67,7 @@ Item { id: bedCurrentTemperature text: printerModel != null ? printerModel.bedTemperature + "°C" : "" - font: UM.Theme.getFont("large") + font: UM.Theme.getFont("large_bold") color: UM.Theme.getColor("text") anchors.right: bedTargetTemperature.left anchors.top: parent.top @@ -320,7 +320,7 @@ Item return UM.Theme.getColor("action_button_text"); } } - font: UM.Theme.getFont("action_button") + font: UM.Theme.getFont("medium") text: { if(printerModel == null) diff --git a/resources/qml/PrinterOutput/MonitorSection.qml b/resources/qml/PrinterOutput/MonitorSection.qml index 7ef89dabf7..63b4b385e5 100644 --- a/resources/qml/PrinterOutput/MonitorSection.qml +++ b/resources/qml/PrinterOutput/MonitorSection.qml @@ -27,7 +27,7 @@ Item anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("default_margin").width text: label - font: UM.Theme.getFont("setting_category") + font: UM.Theme.getFont("medium_bold") color: UM.Theme.getColor("setting_category_text") } } diff --git a/resources/qml/PrinterOutput/OutputDeviceHeader.qml b/resources/qml/PrinterOutput/OutputDeviceHeader.qml index 16280eab5f..47f855266b 100644 --- a/resources/qml/PrinterOutput/OutputDeviceHeader.qml +++ b/resources/qml/PrinterOutput/OutputDeviceHeader.qml @@ -31,7 +31,7 @@ Item Label { id: outputDeviceNameLabel - font: UM.Theme.getFont("large") + font: UM.Theme.getFont("large_bold") color: UM.Theme.getColor("text") anchors.left: parent.left anchors.top: parent.top diff --git a/resources/qml/PrinterSelector/MachineSelectorButton.qml b/resources/qml/PrinterSelector/MachineSelectorButton.qml index b88af35f82..39e63d27c3 100644 --- a/resources/qml/PrinterSelector/MachineSelectorButton.qml +++ b/resources/qml/PrinterSelector/MachineSelectorButton.qml @@ -42,7 +42,7 @@ Button } text: machineSelectorButton.text color: UM.Theme.getColor("text") - font: UM.Theme.getFont("action_button") + font: UM.Theme.getFont("medium") visible: text != "" renderType: Text.NativeRendering verticalAlignment: Text.AlignVCenter diff --git a/resources/qml/Settings/SettingCategory.qml b/resources/qml/Settings/SettingCategory.qml index 5676bcedf9..93627dcb52 100644 --- a/resources/qml/Settings/SettingCategory.qml +++ b/resources/qml/Settings/SettingCategory.qml @@ -73,7 +73,7 @@ Button text: definition.label textFormat: Text.PlainText renderType: Text.NativeRendering - font: UM.Theme.getFont("setting_category") + font: UM.Theme.getFont("medium_bold") color: { if (!base.enabled) diff --git a/resources/qml/ViewsSelector.qml b/resources/qml/ViewsSelector.qml index f2906f9d4c..58749c09f2 100644 --- a/resources/qml/ViewsSelector.qml +++ b/resources/qml/ViewsSelector.qml @@ -105,7 +105,7 @@ Cura.ExpandablePopup id: buttonText text: viewsSelectorButton.text color: UM.Theme.getColor("text") - font: UM.Theme.getFont("action_button") + font: UM.Theme.getFont("medium") renderType: Text.NativeRendering verticalAlignment: Text.AlignVCenter elide: Text.ElideRight diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index bcc754f4ca..86f4100687 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -208,8 +208,8 @@ QtObject anchors.verticalCenter: parent.verticalCenter; text: control.text; - font: Theme.getFont("button_tooltip"); - color: Theme.getColor("tooltip_text"); + font: Theme.getFont("default") + color: Theme.getColor("tooltip_text") } } @@ -716,7 +716,7 @@ QtObject return UM.Theme.getColor("action_button_text"); } } - font: UM.Theme.getFont("action_button") + font: UM.Theme.getFont("medium") text: control.text } } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 3dc216ad70..9cfae3b311 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -6,63 +6,43 @@ "fonts": { "large": { "size": 1.35, - "weight": 63, + "weight": 40, "family": "Noto Sans" }, - "large_nonbold": { + "large_bold": { "size": 1.35, - "weight": 50, + "weight": 60, "family": "Noto Sans" }, "medium": { "size": 1.16, - "weight": 50, + "weight": 40, "family": "Noto Sans" }, "medium_bold": { "size": 1.16, - "weight": 63, + "weight": 60, "family": "Noto Sans" }, "default": { "size": 1.0, - "weight": 50, + "weight": 40, "family": "Noto Sans" }, "default_bold": { "size": 1.0, - "weight": 63, + "weight": 60, "family": "Noto Sans" }, "default_italic": { "size": 1.0, - "weight": 50, + "weight": 40, "italic": true, "family": "Noto Sans" }, "small": { - "size": 0.85, - "weight": 50, - "family": "Noto Sans" - }, - "very_small": { "size": 0.7, - "weight": 50, - "family": "Noto Sans" - }, - "button_tooltip": { - "size": 1.0, - "weight": 50, - "family": "Noto Sans" - }, - "setting_category": { - "size": 1.15, - "weight": 63, - "family": "Noto Sans" - }, - "action_button": { - "size": 1.15, - "weight": 50, + "weight": 40, "family": "Noto Sans" } }, From e7fe7571aafdb89f24af2a687ca13e067b07d425 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 13 Dec 2018 09:02:14 +0100 Subject: [PATCH 0904/1292] Change the behaviour of the output device selector Now the behavior is the following: - The active output device is the one that shows up in the button (same as before) - The list of the output devices don't show the active device - When clicking in one item of the list, it becomes the active output and automatically it performs the action. Contributes to CURA-6026. --- .../qml/ActionPanel/OutputDevicesActionButton.qml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/resources/qml/ActionPanel/OutputDevicesActionButton.qml b/resources/qml/ActionPanel/OutputDevicesActionButton.qml index 9a6c97bcff..b56f50b9a9 100644 --- a/resources/qml/ActionPanel/OutputDevicesActionButton.qml +++ b/resources/qml/ActionPanel/OutputDevicesActionButton.qml @@ -12,6 +12,12 @@ Item { id: widget + function requestWriteToDevice() + { + UM.OutputDeviceManager.requestWriteToDevice(UM.OutputDeviceManager.activeDevice, PrintInformation.jobName, + { "filter_by_machine": true, "preferred_mimetypes": Cura.MachineManager.activeMachine.preferred_output_file_formats }); + } + Cura.PrimaryButton { id: saveToButton @@ -32,9 +38,8 @@ Item onClicked: { - forceActiveFocus(); - UM.OutputDeviceManager.requestWriteToDevice(UM.OutputDeviceManager.activeDevice, PrintInformation.jobName, - { "filter_by_machine": true, "preferred_mimetypes": Cura.MachineManager.activeMachine.preferred_output_file_formats }); + forceActiveFocus() + widget.requestWriteToDevice() } } @@ -81,6 +86,7 @@ Item delegate: Cura.ActionButton { text: model.description + visible: model.id != UM.OutputDeviceManager.activeDevice // Don't show the active device in the list color: "transparent" cornerRadius: 0 hoverColor: UM.Theme.getColor("primary") @@ -88,6 +94,7 @@ Item onClicked: { UM.OutputDeviceManager.setActiveDevice(model.id) + widget.requestWriteToDevice() popup.close() } } From 121af7ad6085096bb9c8bbae4643516de342eb93 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 13 Dec 2018 09:41:07 +0100 Subject: [PATCH 0905/1292] Reuse the primary button in the toolbox for the "Quit Cura" button --- .../Toolbox/resources/qml/ToolboxFooter.qml | 36 ++++++------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxFooter.qml b/plugins/Toolbox/resources/qml/ToolboxFooter.qml index 2d42ca7269..6f46e939ff 100644 --- a/plugins/Toolbox/resources/qml/ToolboxFooter.qml +++ b/plugins/Toolbox/resources/qml/ToolboxFooter.qml @@ -2,21 +2,23 @@ // Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.10 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 +import QtQuick.Controls 2.3 + import UM 1.1 as UM +import Cura 1.0 as Cura Item { id: footer width: parent.width anchors.bottom: parent.bottom - height: visible ? Math.floor(UM.Theme.getSize("toolbox_footer").height) : 0 + height: visible ? UM.Theme.getSize("toolbox_footer").height : 0 + Label { text: catalog.i18nc("@info", "You will need to restart Cura before changes in packages have effect.") color: UM.Theme.getColor("text") - height: Math.floor(UM.Theme.getSize("toolbox_footer_button").height) + height: UM.Theme.getSize("toolbox_footer_button").height verticalAlignment: Text.AlignVCenter anchors { @@ -28,10 +30,10 @@ Item } renderType: Text.NativeRendering } - Button + + Cura.PrimaryButton { id: restartButton - text: catalog.i18nc("@info:button", "Quit Cura") anchors { top: parent.top @@ -39,27 +41,11 @@ Item right: parent.right rightMargin: UM.Theme.getSize("wide_margin").width } - iconName: "dialog-restart" + height: UM.Theme.getSize("toolbox_footer_button").height + text: catalog.i18nc("@info:button", "Quit Cura") onClicked: toolbox.restart() - style: ButtonStyle - { - background: Rectangle - { - implicitWidth: UM.Theme.getSize("toolbox_footer_button").width - implicitHeight: Math.floor(UM.Theme.getSize("toolbox_footer_button").height) - color: control.hovered ? UM.Theme.getColor("primary_hover") : UM.Theme.getColor("primary") - } - label: Label - { - color: UM.Theme.getColor("button_text") - font: UM.Theme.getFont("default_bold") - text: control.text - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - renderType: Text.NativeRendering - } - } } + ToolboxShadow { visible: footer.visible From f72b58386b39d1140ffdc489127eb396604afb77 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Thu, 13 Dec 2018 11:46:11 +0100 Subject: [PATCH 0906/1292] Also use CuraConstants for account API root --- cura/API/Account.py | 10 ++++++---- cura/CuraConstants.py | 6 ++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/cura/API/Account.py b/cura/API/Account.py index 397e220478..7b4bc32e99 100644 --- a/cura/API/Account.py +++ b/cura/API/Account.py @@ -6,6 +6,7 @@ from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot, pyqtProperty from UM.i18n import i18nCatalog from UM.Message import Message +from cura import CuraConstants from cura.OAuth2.AuthorizationService import AuthorizationService from cura.OAuth2.Models import OAuth2Settings @@ -37,15 +38,16 @@ class Account(QObject): self._logged_in = False self._callback_port = 32118 - self._oauth_root = "https://account.ultimaker.com" - self._cloud_api_root = "https://api.ultimaker.com" + self._oauth_root = CuraConstants.CuraCloudAccountAPIRoot self._oauth_settings = OAuth2Settings( OAUTH_SERVER_URL= self._oauth_root, CALLBACK_PORT=self._callback_port, CALLBACK_URL="http://localhost:{}/callback".format(self._callback_port), - CLIENT_ID="um---------------ultimaker_cura_drive_plugin", - CLIENT_SCOPES="account.user.read drive.backup.read drive.backup.write packages.download packages.rating.read packages.rating.write", + CLIENT_ID="um----------------------------ultimaker_cura", + CLIENT_SCOPES="account.user.read drive.backup.read drive.backup.write packages.download " + "packages.rating.read packages.rating.write connect.cluster.read connect.cluster.write " + "cura.printjob.read cura.printjob.write cura.mesh.read cura.mesh.write", AUTH_DATA_PREFERENCE_KEY="general/ultimaker_auth_data", AUTH_SUCCESS_REDIRECT="{}/app/auth-success".format(self._oauth_root), AUTH_FAILED_REDIRECT="{}/app/auth-error".format(self._oauth_root) diff --git a/cura/CuraConstants.py b/cura/CuraConstants.py index c573d550c5..7ca8ea865b 100644 --- a/cura/CuraConstants.py +++ b/cura/CuraConstants.py @@ -42,6 +42,7 @@ except ImportError: # --------- DEFAULT_CLOUD_API_ROOT = "https://api.ultimaker.com" # type: str DEFAULT_CLOUD_API_VERSION = "1" # type: str +DEFAULT_CLOUD_ACCOUNT_API_ROOT = "https://account.ultimaker.com" # type: str try: from cura.CuraVersion import CuraCloudAPIRoot # type: ignore @@ -52,3 +53,8 @@ try: from cura.CuraVersion import CuraCloudAPIVersion # type: ignore except ImportError: CuraCloudAPIVersion = DEFAULT_CLOUD_API_VERSION + +try: + from cura.CuraVersion import CuraCloudAccountAPIRoot # type: ignore +except ImportError: + CuraCloudAccountAPIRoot = DEFAULT_CLOUD_ACCOUNT_API_ROOT From 819f8531a21f68ebf47f18c347043f30117dbf35 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Thu, 13 Dec 2018 11:54:10 +0100 Subject: [PATCH 0907/1292] Use CuraConstants for Cloud printing API root --- plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py index b08bac6670..2dd0c84442 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py @@ -7,6 +7,7 @@ from typing import Callable, List, Type, TypeVar, Union, Optional, Tuple, Dict, from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply from UM.Logger import Logger +from cura import CuraConstants from cura.API import Account from cura.NetworkClient import NetworkClient from ..Models import BaseModel @@ -23,8 +24,7 @@ from .Models.CloudPrintJobResponse import CloudPrintJobResponse class CloudApiClient(NetworkClient): # The cloud URL to use for this remote cluster. - # TODO: Make sure that this URL goes to the live api before release - ROOT_PATH = "https://api-staging.ultimaker.com" + ROOT_PATH = CuraConstants.CuraCloudAPIRoot CLUSTER_API_ROOT = "{}/connect/v1".format(ROOT_PATH) CURA_API_ROOT = "{}/cura/v1".format(ROOT_PATH) From 0a6c1a7c14e2d67ec8879ec2dc24e2acbade0c1d Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 13 Dec 2018 13:12:57 +0100 Subject: [PATCH 0908/1292] Fix CLIENT_ID (again) It got messed up in a merge again. Ugh. --- cura/API/Account.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/API/Account.py b/cura/API/Account.py index 397e220478..be77a6307b 100644 --- a/cura/API/Account.py +++ b/cura/API/Account.py @@ -44,7 +44,7 @@ class Account(QObject): OAUTH_SERVER_URL= self._oauth_root, CALLBACK_PORT=self._callback_port, CALLBACK_URL="http://localhost:{}/callback".format(self._callback_port), - CLIENT_ID="um---------------ultimaker_cura_drive_plugin", + CLIENT_ID="um----------------------------ultimaker_cura", CLIENT_SCOPES="account.user.read drive.backup.read drive.backup.write packages.download packages.rating.read packages.rating.write", AUTH_DATA_PREFERENCE_KEY="general/ultimaker_auth_data", AUTH_SUCCESS_REDIRECT="{}/app/auth-success".format(self._oauth_root), From 2cf80b457820595cee714f012f3e9b46ef1c6348 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 12 Dec 2018 09:57:25 +0100 Subject: [PATCH 0909/1292] Remove unused simpleNames flag CURA-6015 --- cura/Settings/ExtrudersModel.py | 17 ----------------- .../resources/qml/UM3InfoComponents.qml | 4 +--- resources/qml/PrintMonitor.qml | 1 - 3 files changed, 1 insertion(+), 21 deletions(-) diff --git a/cura/Settings/ExtrudersModel.py b/cura/Settings/ExtrudersModel.py index e19617c8ef..84d40cea6e 100644 --- a/cura/Settings/ExtrudersModel.py +++ b/cura/Settings/ExtrudersModel.py @@ -78,8 +78,6 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): self._update_extruder_timer.setSingleShot(True) self._update_extruder_timer.timeout.connect(self.__updateExtruders) - self._simple_names = False - self._active_machine_extruders = [] # type: Iterable[ExtruderStack] self._add_optional_extruder = False @@ -101,21 +99,6 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): def addOptionalExtruder(self): return self._add_optional_extruder - ## Set the simpleNames property. - def setSimpleNames(self, simple_names): - if simple_names != self._simple_names: - self._simple_names = simple_names - self.simpleNamesChanged.emit() - self._updateExtruders() - - ## Emitted when the simpleNames property changes. - simpleNamesChanged = pyqtSignal() - - ## Whether or not the model should show all definitions regardless of visibility. - @pyqtProperty(bool, fset = setSimpleNames, notify = simpleNamesChanged) - def simpleNames(self): - return self._simple_names - ## Links to the stack-changed signal of the new extruders when an extruder # is swapped out or added in the current machine. # diff --git a/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml b/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml index 643c8164a7..0ee8880c36 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml @@ -83,9 +83,7 @@ Item { Column { Repeater { - model: Cura.ExtrudersModel { - simpleNames: true; - } + model: Cura.ExtrudersModel { } Label { text: model.name; diff --git a/resources/qml/PrintMonitor.qml b/resources/qml/PrintMonitor.qml index 4ed8daa55c..316dcad653 100644 --- a/resources/qml/PrintMonitor.qml +++ b/resources/qml/PrintMonitor.qml @@ -63,7 +63,6 @@ Rectangle Cura.ExtrudersModel { id: extrudersModel - simpleNames: true } OutputDeviceHeader From 620790ae3de03113f23eafc0e1374fad7d222eb7 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 12 Dec 2018 11:08:33 +0100 Subject: [PATCH 0910/1292] Reduce the creations of ExtrudersModels CURA-6015 --- cura/CuraApplication.py | 15 +++++++++++++++ .../MachineSettingsAction.qml | 2 +- .../SimulationViewMenuComponent.qml | 2 +- plugins/SolidView/SolidView.py | 6 ++++-- .../resources/qml/UM3InfoComponents.qml | 2 +- .../Menus/ConfigurationMenu/ConfigurationMenu.qml | 5 +---- resources/qml/Menus/ContextMenu.qml | 2 +- resources/qml/Preferences/ProfilesPage.qml | 2 +- resources/qml/PrintMonitor.qml | 5 +---- .../Custom/CustomPrintSetup.qml | 5 +---- .../qml/PrintSetupSelector/PrintSetupSelector.qml | 5 +---- .../Recommended/RecommendedSupportSelector.qml | 5 +++-- resources/qml/Settings/SettingExtruder.qml | 9 +++++++-- .../qml/Settings/SettingOptionalExtruder.qml | 8 +++++--- resources/qml/Toolbar.qml | 5 +---- 15 files changed, 44 insertions(+), 34 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 7e11fd4d59..55e37617d5 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -205,6 +205,8 @@ class CuraApplication(QtApplication): self._container_manager = None self._object_manager = None + self._extruders_model = None + self._extruders_model_with_optional = None self._build_plate_model = None self._multi_build_plate_model = None self._setting_visibility_presets_model = None @@ -862,6 +864,19 @@ class CuraApplication(QtApplication): self._object_manager = ObjectsModel.createObjectsModel() return self._object_manager + @pyqtSlot(result = QObject) + def getExtrudersModel(self, *args) -> "ExtrudersModel": + if self._extruders_model is None: + self._extruders_model = ExtrudersModel(self) + return self._extruders_model + + @pyqtSlot(result = QObject) + def getExtrudersModelWithOptional(self, *args) -> "ExtrudersModel": + if self._extruders_model_with_optional is None: + self._extruders_model_with_optional = ExtrudersModel(self) + self._extruders_model_with_optional.setAddOptionalExtruder(True) + return self._extruders_model_with_optional + @pyqtSlot(result = QObject) def getMultiBuildPlateModel(self, *args) -> MultiBuildPlateModel: if self._multi_build_plate_model is None: diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index c88a721a84..d8efe6f8b8 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -13,7 +13,7 @@ import Cura 1.0 as Cura Cura.MachineAction { id: base - property var extrudersModel: Cura.ExtrudersModel{} + property var extrudersModel: CuraApplication.getExtrudersModel() property int extruderTabsCount: 0 property var activeMachineId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.id : "" diff --git a/plugins/SimulationView/SimulationViewMenuComponent.qml b/plugins/SimulationView/SimulationViewMenuComponent.qml index 9f43252126..eec254c0dd 100644 --- a/plugins/SimulationView/SimulationViewMenuComponent.qml +++ b/plugins/SimulationView/SimulationViewMenuComponent.qml @@ -163,7 +163,7 @@ Cura.ExpandableComponent Repeater { - model: Cura.ExtrudersModel{} + model: CuraApplication.getExtrudersModel() CheckBox { diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index b9ad5c8829..797d6dabec 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -12,7 +12,6 @@ from UM.Math.Color import Color from UM.View.GL.OpenGL import OpenGL from cura.Settings.ExtruderManager import ExtruderManager -from cura.Settings.ExtrudersModel import ExtrudersModel import math @@ -29,13 +28,16 @@ class SolidView(View): self._non_printing_shader = None self._support_mesh_shader = None - self._extruders_model = ExtrudersModel() + self._extruders_model = None self._theme = None def beginRendering(self): scene = self.getController().getScene() renderer = self.getRenderer() + if not self._extruders_model: + self._extruders_model = Application.getInstance().getExtrudersModel() + if not self._theme: self._theme = Application.getInstance().getTheme() diff --git a/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml b/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml index 0ee8880c36..42e3b7d160 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml @@ -83,7 +83,7 @@ Item { Column { Repeater { - model: Cura.ExtrudersModel { } + model: CuraApplication.getExtrudersModel() Label { text: model.name; diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index 33a317b42b..d95dd9ebfa 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -17,10 +17,7 @@ Cura.ExpandablePopup { id: base - Cura.ExtrudersModel - { - id: extrudersModel - } + property var extrudersModel: CuraApplication.getExtrudersModel() UM.I18nCatalog { diff --git a/resources/qml/Menus/ContextMenu.qml b/resources/qml/Menus/ContextMenu.qml index 1ea402d815..cb10d50ce8 100644 --- a/resources/qml/Menus/ContextMenu.qml +++ b/resources/qml/Menus/ContextMenu.qml @@ -27,7 +27,7 @@ Menu MenuItem { id: extruderHeader; text: catalog.i18ncp("@label", "Print Selected Model With:", "Print Selected Models With:", UM.Selection.selectionCount); enabled: false; visible: base.shouldShowExtruders } Instantiator { - model: Cura.ExtrudersModel { id: extrudersModel } + model: CuraApplication.getExtrudersModel() MenuItem { text: "%1: %2 - %3".arg(model.name).arg(model.material).arg(model.variant) visible: base.shouldShowExtruders diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index d7ffbb3152..7fb17b7aa1 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -16,7 +16,7 @@ Item property QtObject qualityManager: CuraApplication.getQualityManager() property var resetEnabled: false // Keep PreferencesDialog happy - property var extrudersModel: Cura.ExtrudersModel {} + property var extrudersModel: CuraApplication.getExtrudersModel() UM.I18nCatalog { id: catalog; name: "cura"; } diff --git a/resources/qml/PrintMonitor.qml b/resources/qml/PrintMonitor.qml index 316dcad653..6d8edf0deb 100644 --- a/resources/qml/PrintMonitor.qml +++ b/resources/qml/PrintMonitor.qml @@ -60,10 +60,7 @@ Rectangle anchors.fill: parent - Cura.ExtrudersModel - { - id: extrudersModel - } + property var extrudersModel: CuraApplication.getExtrudersModel() OutputDeviceHeader { diff --git a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml index b28c9ceb46..27de8df835 100644 --- a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml +++ b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml @@ -16,10 +16,7 @@ Item property real padding: UM.Theme.getSize("default_margin").width property bool multipleExtruders: extrudersModel.count > 1 - Cura.ExtrudersModel - { - id: extrudersModel - } + property var extrudersModel: CuraApplication.getExtrudersModel() // Profile selector row GlobalProfileSelector diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector/PrintSetupSelector.qml index 599eac957e..2d4d7f6cf1 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelector.qml @@ -26,10 +26,7 @@ Cura.ExpandableComponent headerItem: PrintSetupSelectorHeader {} - Cura.ExtrudersModel - { - id: extrudersModel - } + property var extrudersModel: CuraApplication.getExtrudersModel() contentItem: PrintSetupSelectorContents {} } \ No newline at end of file diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml index 57e0c8ce6b..87fb664713 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml @@ -156,9 +156,10 @@ Item } //: Model used to populate the extrudelModel - Cura.ExtrudersModel + property var extruders: CuraApplication.getExtrudersModel() + Connections { - id: extruders + target: extruders onModelChanged: populateExtruderModel() } diff --git a/resources/qml/Settings/SettingExtruder.qml b/resources/qml/Settings/SettingExtruder.qml index e1fedd9274..024eb17639 100644 --- a/resources/qml/Settings/SettingExtruder.qml +++ b/resources/qml/Settings/SettingExtruder.qml @@ -17,11 +17,16 @@ SettingItem id: control anchors.fill: parent - model: Cura.ExtrudersModel + property var extrudersModel: CuraApplication.getExtrudersModel() + + model: extrudersModel + + Connections { + target: extrudersModel onModelChanged: { - control.color = getItem(control.currentIndex).color + control.color = extrudersModel.getItem(control.currentIndex).color } } diff --git a/resources/qml/Settings/SettingOptionalExtruder.qml b/resources/qml/Settings/SettingOptionalExtruder.qml index 200a3f64f1..d9ec1f07c4 100644 --- a/resources/qml/Settings/SettingOptionalExtruder.qml +++ b/resources/qml/Settings/SettingOptionalExtruder.qml @@ -17,10 +17,12 @@ SettingItem id: control anchors.fill: parent - model: Cura.ExtrudersModel + model: CuraApplication.getExtrudersModelWithOptional() + + Connections { - onModelChanged: control.color = getItem(control.currentIndex).color - addOptionalExtruder: true + target: model + onModelChanged: control.color = model.getItem(control.currentIndex).color } textRole: "name" diff --git a/resources/qml/Toolbar.qml b/resources/qml/Toolbar.qml index 1e335472d4..1df516a315 100644 --- a/resources/qml/Toolbar.qml +++ b/resources/qml/Toolbar.qml @@ -144,10 +144,7 @@ Item } } - Cura.ExtrudersModel - { - id: extrudersModel - } + property var extrudersModel: CuraApplication.getExtrudersModel() UM.PointingRectangle { From 935f7a2512e14e361903155acbfc7198fa881512 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 12 Dec 2018 11:09:22 +0100 Subject: [PATCH 0911/1292] Remove unused imports CURA-6015 --- cura/Settings/ExtrudersModel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Settings/ExtrudersModel.py b/cura/Settings/ExtrudersModel.py index 84d40cea6e..b7fa659554 100644 --- a/cura/Settings/ExtrudersModel.py +++ b/cura/Settings/ExtrudersModel.py @@ -1,7 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot, pyqtProperty, QTimer +from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty, QTimer from typing import Iterable from UM.i18n import i18nCatalog From df0b1c6c7735757e73317881fdc1f3b461cdabbd Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 12 Dec 2018 11:10:22 +0100 Subject: [PATCH 0912/1292] Fix ExtruderManager creation in MachineManager CURA-6015 --- cura/Settings/MachineManager.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index c375ce01d1..e26b82e487 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -88,12 +88,14 @@ class MachineManager(QObject): self._onGlobalContainerChanged() - ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderStackChanged) + extruder_manager = self._application.getExtruderManager() + + extruder_manager.activeExtruderChanged.connect(self._onActiveExtruderStackChanged) self._onActiveExtruderStackChanged() - ExtruderManager.getInstance().activeExtruderChanged.connect(self.activeMaterialChanged) - ExtruderManager.getInstance().activeExtruderChanged.connect(self.activeVariantChanged) - ExtruderManager.getInstance().activeExtruderChanged.connect(self.activeQualityChanged) + extruder_manager.activeExtruderChanged.connect(self.activeMaterialChanged) + extruder_manager.activeExtruderChanged.connect(self.activeVariantChanged) + extruder_manager.activeExtruderChanged.connect(self.activeQualityChanged) self.globalContainerChanged.connect(self.activeStackChanged) self.globalValueChanged.connect(self.activeStackValueChanged) From d879cab91ae2030a2aeb7a32c772dce7cfaf28e8 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 13 Dec 2018 13:49:06 +0100 Subject: [PATCH 0913/1292] Add all fields for optional extruder in ExtruderModel CURA-6015 --- cura/Settings/ExtrudersModel.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cura/Settings/ExtrudersModel.py b/cura/Settings/ExtrudersModel.py index b7fa659554..076cebf60d 100644 --- a/cura/Settings/ExtrudersModel.py +++ b/cura/Settings/ExtrudersModel.py @@ -204,7 +204,12 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): "enabled": True, "color": "#ffffff", "index": -1, - "definition": "" + "definition": "", + "material": "", + "variant": "", + "stack": None, + "material_brand": "", + "color_name": "", } items.append(item) if self._items != items: From 8021c8e44900aa89ae4254b09e17be2179165b18 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 13 Dec 2018 13:49:45 +0100 Subject: [PATCH 0914/1292] Fix errors in SettingOptionalExtruder.qml CURA-6015 --- resources/qml/Settings/SettingOptionalExtruder.qml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/resources/qml/Settings/SettingOptionalExtruder.qml b/resources/qml/Settings/SettingOptionalExtruder.qml index d9ec1f07c4..aabf808d83 100644 --- a/resources/qml/Settings/SettingOptionalExtruder.qml +++ b/resources/qml/Settings/SettingOptionalExtruder.qml @@ -12,17 +12,24 @@ SettingItem id: base property var focusItem: control + // Somehow if we directory set control.model to CuraApplication.getExtrudersModelWithOptional() + // and in the Connections.onModelChanged use control.model as a reference, it will complain about + // non-existing properties such as "onModelChanged" and "getItem". I guess if we access the model + // via "control.model", it gives back a generic/abstract model instance. To avoid this, we add + // this extra property to keep the ExtrudersModel and use this in the rest of the code. + property var extrudersWithOptionalModel: CuraApplication.getExtrudersModelWithOptional() + contents: ComboBox { id: control anchors.fill: parent - model: CuraApplication.getExtrudersModelWithOptional() + model: base.extrudersWithOptionalModel Connections { - target: model - onModelChanged: control.color = model.getItem(control.currentIndex).color + target: base.extrudersWithOptionalModel + onModelChanged: control.color = base.extrudersWithOptionalModel.getItem(control.currentIndex).color } textRole: "name" From a1a9b058f5e874f0ab41871afc94a7ac712badd0 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 13 Dec 2018 14:28:32 +0100 Subject: [PATCH 0915/1292] Let header listen to activeStageId instead of the model CURA-6028 --- resources/qml/MainWindow/MainWindowHeader.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/qml/MainWindow/MainWindowHeader.qml b/resources/qml/MainWindow/MainWindowHeader.qml index ae1c13d9c3..6cb7370ec2 100644 --- a/resources/qml/MainWindow/MainWindowHeader.qml +++ b/resources/qml/MainWindow/MainWindowHeader.qml @@ -54,7 +54,8 @@ Item { text: model.name.toUpperCase() checkable: true - checked: model.active + checked: model.id == UM.Controller.activeStage.stageId + anchors.verticalCenter: parent.verticalCenter exclusiveGroup: mainWindowHeaderMenuGroup style: UM.Theme.styles.main_window_header_tab From c4700b27522dafa6d2164ea08b2215e1f738e013 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 13 Dec 2018 14:30:00 +0100 Subject: [PATCH 0916/1292] Also update the model if the data changed CURA-6028 --- .../Recommended/RecommendedQualityProfileSelector.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml index 15d40f545a..349c6dbb57 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml @@ -39,6 +39,7 @@ Item { target: Cura.QualityProfilesDropDownMenuModel onItemsChanged: qualityModel.update() + onDataChanged: qualityModel.update() } Connections { From 17f0c12858ae2a3cf6466e8e5bc900338d22f444 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 13 Dec 2018 14:31:34 +0100 Subject: [PATCH 0917/1292] Make the middle component to have zero width if there is no component to fill the gap. Contributes to CURA-6020. --- plugins/PreviewStage/PreviewMenu.qml | 95 +++++++++++++--------------- 1 file changed, 44 insertions(+), 51 deletions(-) diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml index 4e1fbac837..62f814aac9 100644 --- a/plugins/PreviewStage/PreviewMenu.qml +++ b/plugins/PreviewStage/PreviewMenu.qml @@ -20,67 +20,60 @@ Item name: "cura" } - // Item to ensure that all of the buttons are nicely centered. - Item + Row { - anchors.horizontalCenter: parent.horizontalCenter - width: stageMenuRow.width + id: stageMenuRow + anchors.centerIn: parent height: parent.height + width: childrenRect.width - RowLayout + // We want this row to have a preferred with equals to the 85% of the parent + property int preferredWidth: Math.round(0.85 * previewMenu.width) + + Cura.ViewsSelector { - id: stageMenuRow - width: Math.round(0.85 * previewMenu.width) + id: viewsSelector height: parent.height - spacing: 0 + width: UM.Theme.getSize("views_selector").width + headerCornerSide: Cura.RoundedRectangle.Direction.Left + } - Cura.ViewsSelector - { - id: viewsSelector - headerCornerSide: Cura.RoundedRectangle.Direction.Left - Layout.minimumWidth: UM.Theme.getSize("views_selector").width - Layout.maximumWidth: UM.Theme.getSize("views_selector").width - Layout.fillWidth: true - Layout.fillHeight: true - } + // Separator line + Rectangle + { + height: parent.height + // If there is no viewPanel, we only need a single spacer, so hide this one. + visible: viewPanel.source != "" + width: visible ? UM.Theme.getSize("default_lining").width : 0 - // Separator line - Rectangle - { - height: parent.height - // If there is no viewPanel, we only need a single spacer, so hide this one. - visible: viewPanel.source != "" - width: UM.Theme.getSize("default_lining").width + color: UM.Theme.getColor("lining") + } - color: UM.Theme.getColor("lining") - } + // This component will grow freely up to complete the preferredWidth of the row. + Loader + { + id: viewPanel + height: parent.height + width: source != "" ? (stageMenuRow.preferredWidth - viewsSelector.width - printSetupSelectorItem.width - 2 * UM.Theme.getSize("default_lining").width) : 0 + source: UM.Controller.activeView != null && UM.Controller.activeView.stageMenuComponent != null ? UM.Controller.activeView.stageMenuComponent : "" + } - Loader - { - id: viewPanel - Layout.fillHeight: true - Layout.fillWidth: true - Layout.preferredWidth: stageMenuRow.width - viewsSelector.width - printSetupSelectorItem.width - 2 * UM.Theme.getSize("default_lining").width - source: UM.Controller.activeView != null && UM.Controller.activeView.stageMenuComponent != null ? UM.Controller.activeView.stageMenuComponent : "" - } + // Separator line + Rectangle + { + height: parent.height + width: UM.Theme.getSize("default_lining").width + color: UM.Theme.getColor("lining") + } - // Separator line - Rectangle - { - height: parent.height - width: UM.Theme.getSize("default_lining").width - color: UM.Theme.getColor("lining") - } - - Item - { - id: printSetupSelectorItem - // This is a work around to prevent the printSetupSelector from having to be re-loaded every time - // a stage switch is done. - children: [printSetupSelector] - height: childrenRect.height - width: childrenRect.width - } + Item + { + id: printSetupSelectorItem + // This is a work around to prevent the printSetupSelector from having to be re-loaded every time + // a stage switch is done. + children: [printSetupSelector] + height: childrenRect.height + width: childrenRect.width } } } From 8091b2810c2feb04af81c8deef362688ed26eea4 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 13 Dec 2018 14:36:58 +0100 Subject: [PATCH 0918/1292] Apply suggestions from code review Change some margins for the corresponding absolute values instead of adding formulas. Contributes to CURA-5876. Co-Authored-By: diegopradogesto --- .../ConfigurationMenu/ConfigurationItem.qml | 16 ++++++++-------- .../ConfigurationMenu/ConfigurationListView.qml | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index a73cd3b46c..862e1475a9 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -36,9 +36,9 @@ Button anchors { left: parent.left - leftMargin: 2 * parent.padding + leftMargin: UM.Theme.getSize("wide_margin").width right: parent.right - rightMargin: 2 * parent.padding + rightMargin: UM.Theme.getSize("wide_margin").width } spacing: UM.Theme.getSize("default_margin").width @@ -64,9 +64,9 @@ Button anchors { left: parent.left - leftMargin: 2 * parent.padding + leftMargin: UM.Theme.getSize("wide_margin").width right: parent.right - rightMargin: 2 * parent.padding + rightMargin: UM.Theme.getSize("wide_margin").width } height: visible ? Math.round(UM.Theme.getSize("default_lining").height / 2) : 0 color: UM.Theme.getColor("lining") @@ -79,9 +79,9 @@ Button anchors { left: parent.left - leftMargin: 2 * parent.padding + leftMargin: UM.Theme.getSize("wide_margin").width right: parent.right - rightMargin: 2 * parent.padding + rightMargin: UM.Theme.getSize("wide_margin").width } height: childrenRect.height visible: configuration.buildplateConfiguration != "" @@ -101,7 +101,7 @@ Button id: buildplateLabel anchors.left: buildplateIcon.right anchors.verticalCenter: buildplateIcon.verticalCenter - anchors.leftMargin: Math.round(UM.Theme.getSize("default_margin").height / 2) + anchors.leftMargin: UM.Theme.getSize("narrow_margin").height text: configuration.buildplateConfiguration renderType: Text.NativeRendering color: UM.Theme.getColor("text") @@ -127,4 +127,4 @@ Button { Cura.MachineManager.applyRemoteConfiguration(configuration) } -} \ No newline at end of file +} diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index 3ddbb49fe8..684e575bfd 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -28,7 +28,7 @@ Item { width: parent.width visible: configurationList.model.length == 0 - height: label.height + 2 * UM.Theme.getSize("default_margin").height + height: label.height + UM.Theme.getSize("wide_margin").height anchors.top: parent.top anchors.topMargin: UM.Theme.getSize("default_margin").height @@ -134,4 +134,4 @@ Item forceModelUpdate() } } -} \ No newline at end of file +} From b48eedfb805fd8ed6aa3accb4658622dcd57ef43 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 13 Dec 2018 15:15:22 +0100 Subject: [PATCH 0919/1292] Modify color for the progress bar in the messages. --- resources/themes/cura-light/theme.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 1a7d377fa7..6d76004739 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -255,8 +255,8 @@ "message_button_text": [255, 255, 255, 255], "message_button_text_hover": [255, 255, 255, 255], "message_button_text_active": [255, 255, 255, 255], - "message_progressbar_background": [200, 200, 200, 255], - "message_progressbar_control": [77, 182, 226, 255], + "message_progressbar_background": [245, 245, 245, 255], + "message_progressbar_control": [50, 130, 255, 255], "tool_panel_background": [255, 255, 255, 255], From 3225512851f61f0ac9f18ae6322f8eeb2c3bfd79 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 13 Dec 2018 15:48:03 +0100 Subject: [PATCH 0920/1292] Fix typing CURA-6013 --- plugins/Toolbox/src/Toolbox.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 715c105bad..05669e55d8 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -49,7 +49,7 @@ class Toolbox(QObject, Extension): self._download_progress = 0 # type: float self._is_downloading = False # type: bool self._network_manager = None # type: Optional[QNetworkAccessManager] - self._request_headers = [] # type: List[Tuple(bytes, bytes)] + self._request_headers = [] # type: List[Tuple[bytes, bytes]] self._updateRequestHeader() From 1b3cb323344cd6c75ec160ca936a1aff379ad64f Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 13 Dec 2018 15:59:15 +0100 Subject: [PATCH 0921/1292] Fix the simulation view not being selected as default CURA-6028 --- resources/qml/ViewsSelector.qml | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/resources/qml/ViewsSelector.qml b/resources/qml/ViewsSelector.qml index 0e2598a0d8..d91412cad0 100644 --- a/resources/qml/ViewsSelector.qml +++ b/resources/qml/ViewsSelector.qml @@ -14,24 +14,31 @@ Cura.ExpandablePopup contentPadding: UM.Theme.getSize("default_lining").width contentAlignment: Cura.ExpandablePopup.ContentAlignment.AlignLeft - property var viewModel: UM.ViewModel { } - - property var activeView: + property var viewModel: UM.ViewModel { - for (var i = 0; i < viewModel.count; i++) + onDataChanged: updateActiveView() + } + + + property var activeView: null + + function updateActiveView() + { + for (var index in viewModel.items) { - if (viewModel.items[i].active) + + if (viewModel.items[index].active) { - return viewModel.items[i] + activeView = viewModel.items[index] + return } } - return null + activeView = null } Component.onCompleted: { - // Nothing was active, so just return the first one (the list is sorted by priority, so the most - // important one should be returned) + updateActiveView() if (activeView == null) { UM.Controller.setActiveView(viewModel.getItem(0).id) From 973970a89505fea4cb3e0f4d003c8360b2b2353e Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Wed, 12 Dec 2018 09:53:26 +0100 Subject: [PATCH 0922/1292] Every print ouput device should define its connection type(usb, network, cluster and etc) CURA-6011 --- .../NetworkedPrinterOutputDevice.py | 6 ++--- cura/PrinterOutputDevice.py | 19 ++++++++++++++- .../resources/qml/DiscoverUM3Action.qml | 2 +- .../src/ClusterUM3OutputDevice.py | 3 ++- .../src/DiscoverUM3Action.py | 23 ++++++++++++------- .../src/LegacyUM3OutputDevice.py | 3 ++- plugins/USBPrinting/USBPrinterOutputDevice.py | 4 ++-- .../PrinterSelector/MachineSelectorList.qml | 2 +- 8 files changed, 44 insertions(+), 18 deletions(-) diff --git a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py index 9a3be936a2..c288596f0c 100644 --- a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py +++ b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py @@ -6,7 +6,7 @@ from UM.Logger import Logger from UM.Scene.SceneNode import SceneNode #For typing. from cura.CuraApplication import CuraApplication -from cura.PrinterOutputDevice import PrinterOutputDevice, ConnectionState +from cura.PrinterOutputDevice import PrinterOutputDevice, ConnectionState, ConnectionType from PyQt5.QtNetwork import QHttpMultiPart, QHttpPart, QNetworkRequest, QNetworkAccessManager, QNetworkReply, QAuthenticator from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QUrl, QCoreApplication @@ -28,8 +28,8 @@ class AuthState(IntEnum): class NetworkedPrinterOutputDevice(PrinterOutputDevice): authenticationStateChanged = pyqtSignal() - def __init__(self, device_id, address: str, properties: Dict[bytes, bytes], parent: QObject = None) -> None: - super().__init__(device_id = device_id, parent = parent) + def __init__(self, device_id, address: str, properties: Dict[bytes, bytes], connection_type: ConnectionType = ConnectionType.networkConnection, parent: QObject = None) -> None: + super().__init__(device_id = device_id, connection_type = connection_type, parent = parent) self._manager = None # type: Optional[QNetworkAccessManager] self._last_manager_create_time = None # type: Optional[float] self._recreate_network_manager_time = 30 diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index 99c48189cc..3a72fba4e3 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -34,6 +34,12 @@ class ConnectionState(IntEnum): busy = 3 error = 4 +class ConnectionType(IntEnum): + none = 0 + usbConnection = 1 + networkConnection = 2 + clusterConnection = 3 + cloudConnection = 4 ## Printer output device adds extra interface options on top of output device. # @@ -62,7 +68,7 @@ class PrinterOutputDevice(QObject, OutputDevice): # Signal to indicate that the configuration of one of the printers has changed. uniqueConfigurationsChanged = pyqtSignal() - def __init__(self, device_id: str, parent: QObject = None) -> None: + def __init__(self, device_id: str, connection_type: ConnectionType, parent: QObject = None) -> None: super().__init__(device_id = device_id, parent = parent) # type: ignore # MyPy complains with the multiple inheritance self._printers = [] # type: List[PrinterOutputModel] @@ -84,6 +90,7 @@ class PrinterOutputDevice(QObject, OutputDevice): self._update_timer.timeout.connect(self._update) self._connection_state = ConnectionState.closed #type: ConnectionState + self._connection_type = connection_type self._firmware_updater = None #type: Optional[FirmwareUpdater] self._firmware_name = None #type: Optional[str] @@ -117,6 +124,16 @@ class PrinterOutputDevice(QObject, OutputDevice): self._connection_state = connection_state self.connectionStateChanged.emit(self._id) + def checkConnectionType(self, connection_type: ConnectionType) -> bool: + return connection_type == self._connection_type + + def getConnectionType(self) -> ConnectionType: + return self._connection_type + + def setConnectionType(self, new_connection_type: ConnectionType) -> None: + if self._connection_type != new_connection_type: + self._connection_type = new_connection_type + @pyqtProperty(str, notify = connectionStateChanged) def connectionState(self) -> ConnectionState: return self._connection_state diff --git a/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml b/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml index e5f668c70d..2c9ab2df03 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml @@ -28,7 +28,7 @@ Cura.MachineAction // Check if there is another instance with the same key if (!manager.existsKey(printerKey)) { - manager.setKey(printerKey) + manager.setKey(base.selectedDevice) manager.setGroupName(printerName) // TODO To change when the groups have a name completed() } diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index ef890fc4ed..206654ff88 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -22,6 +22,7 @@ from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationM from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice, AuthState from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel +from cura.PrinterOutputDevice import ConnectionType from .ClusterUM3PrinterOutputController import ClusterUM3PrinterOutputController from .SendMaterialJob import SendMaterialJob @@ -54,7 +55,7 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): clusterPrintersChanged = pyqtSignal() def __init__(self, device_id, address, properties, parent = None) -> None: - super().__init__(device_id = device_id, address = address, properties=properties, parent = parent) + super().__init__(device_id = device_id, address = address, properties=properties, connection_type = ConnectionType.clusterConnection, parent = parent) self._api_prefix = "/cluster-api/v1/" self._number_of_extruders = 2 diff --git a/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py b/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py index be83e04585..9cd21de036 100644 --- a/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py +++ b/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py @@ -3,7 +3,7 @@ import os.path import time -from typing import cast, Optional +from typing import Optional from PyQt5.QtCore import pyqtSignal, pyqtProperty, pyqtSlot, QObject @@ -13,6 +13,7 @@ from UM.i18n import i18nCatalog from cura.CuraApplication import CuraApplication from cura.MachineAction import MachineAction +from cura.PrinterOutputDevice import PrinterOutputDevice from .UM3OutputDevicePlugin import UM3OutputDevicePlugin @@ -116,22 +117,28 @@ class DiscoverUM3Action(MachineAction): # Ensure that the connection states are refreshed. self._network_plugin.reCheckConnections() - @pyqtSlot(str) - def setKey(self, key: str) -> None: - Logger.log("d", "Attempting to set the network key of the active machine to %s", key) + @pyqtSlot(QObject) + def setKey(self, printer_device: Optional[PrinterOutputDevice]) -> None: + Logger.log("d", "Attempting to set the network key of the active machine to %s", printer_device.key) global_container_stack = CuraApplication.getInstance().getGlobalContainerStack() if global_container_stack: meta_data = global_container_stack.getMetaData() if "um_network_key" in meta_data: previous_network_key= meta_data["um_network_key"] - global_container_stack.setMetaDataEntry("um_network_key", key) + global_container_stack.setMetaDataEntry("um_network_key", printer_device.key) # Delete old authentication data. - Logger.log("d", "Removing old authentication id %s for device %s", global_container_stack.getMetaDataEntry("network_authentication_id", None), key) + Logger.log("d", "Removing old authentication id %s for device %s", global_container_stack.getMetaDataEntry("network_authentication_id", None), printer_device.key) global_container_stack.removeMetaDataEntry("network_authentication_id") global_container_stack.removeMetaDataEntry("network_authentication_key") - CuraApplication.getInstance().getMachineManager().replaceContainersMetadata(key = "um_network_key", value = previous_network_key, new_value = key) + CuraApplication.getInstance().getMachineManager().replaceContainersMetadata(key = "um_network_key", value = previous_network_key, new_value = printer_device.key) + + if "um_connection_type" in meta_data: + previous_connection_type = meta_data["um_connection_type"] + global_container_stack.setMetaDataEntry("um_connection_type", printer_device.getConnectionType().value) + CuraApplication.getInstance().getMachineManager().replaceContainersMetadata(key = "um_connection_type", value = previous_connection_type, new_value = printer_device.getConnectionType().value) else: - global_container_stack.setMetaDataEntry("um_network_key", key) + global_container_stack.setMetaDataEntry("um_network_key", printer_device.key) + global_container_stack.setMetaDataEntry("um_connection_type", printer_device.getConnectionType().value) if self._network_plugin: # Ensure that the connection states are refreshed. diff --git a/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py index 18af22e72f..0ae9e8a004 100644 --- a/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py @@ -7,6 +7,7 @@ from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutp from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel +from cura.PrinterOutputDevice import ConnectionType from cura.Settings.ContainerManager import ContainerManager from cura.Settings.ExtruderManager import ExtruderManager @@ -43,7 +44,7 @@ i18n_catalog = i18nCatalog("cura") # 5. As a final step, we verify the authentication, as this forces the QT manager to setup the authenticator. class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice): def __init__(self, device_id, address: str, properties, parent = None) -> None: - super().__init__(device_id = device_id, address = address, properties = properties, parent = parent) + super().__init__(device_id = device_id, address = address, properties = properties, connection_type = ConnectionType.networkConnection, parent = parent) self._api_prefix = "/api/v1/" self._number_of_extruders = 2 diff --git a/plugins/USBPrinting/USBPrinterOutputDevice.py b/plugins/USBPrinting/USBPrinterOutputDevice.py index 1d42e70366..a8cb240b03 100644 --- a/plugins/USBPrinting/USBPrinterOutputDevice.py +++ b/plugins/USBPrinting/USBPrinterOutputDevice.py @@ -7,7 +7,7 @@ from UM.i18n import i18nCatalog from UM.Qt.Duration import DurationFormat from cura.CuraApplication import CuraApplication -from cura.PrinterOutputDevice import PrinterOutputDevice, ConnectionState +from cura.PrinterOutputDevice import PrinterOutputDevice, ConnectionState, ConnectionType from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel from cura.PrinterOutput.GenericOutputController import GenericOutputController @@ -29,7 +29,7 @@ catalog = i18nCatalog("cura") class USBPrinterOutputDevice(PrinterOutputDevice): def __init__(self, serial_port: str, baud_rate: Optional[int] = None) -> None: - super().__init__(serial_port) + super().__init__(serial_port, connection_type=ConnectionType.usbConnection) self.setName(catalog.i18nc("@item:inmenu", "USB printing")) self.setShortDescription(catalog.i18nc("@action:button Preceded by 'Ready to'.", "Print via USB")) self.setDescription(catalog.i18nc("@info:tooltip", "Print via USB")) diff --git a/resources/qml/PrinterSelector/MachineSelectorList.qml b/resources/qml/PrinterSelector/MachineSelectorList.qml index 54d766a6e0..3324b9948b 100644 --- a/resources/qml/PrinterSelector/MachineSelectorList.qml +++ b/resources/qml/PrinterSelector/MachineSelectorList.qml @@ -32,7 +32,7 @@ Column id: networkedPrintersModel filter: { - "type": "machine", "um_network_key": "*", "hidden": "False" + "type": "machine", "um_network_key": "*", "hidden": "False", "um_connection_type": "[2,3,4]" } } From d48e89e22432ae9146c404a745d785af9491da37 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 13 Dec 2018 16:32:48 +0100 Subject: [PATCH 0923/1292] Prevent the parent of printSetupSelector from being set to null If it's parent gets set to null it will break the focus, which we need for the binding updates. CURA-5941 --- resources/qml/Cura.qml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index a4faa27b67..cf6f36a492 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -278,6 +278,14 @@ UM.MainWindow height: UM.Theme.getSize("stage_menu").height source: UM.Controller.activeStage != null ? UM.Controller.activeStage.stageMenuComponent : "" + + // HACK: This is to ensure that the parent never gets set to null, as this wreaks havoc on the focus. + function onParentDestroyed() + { + printSetupSelector.parent = stageMenu + printSetupSelector.visible = false + } + // The printSetupSelector is defined here so that the setting list doesn't need to get re-instantiated // Every time the stage is changed. property var printSetupSelector: Cura.PrintSetupSelector @@ -285,6 +293,11 @@ UM.MainWindow width: UM.Theme.getSize("print_setup_widget").width height: UM.Theme.getSize("stage_menu").height headerCornerSide: RoundedRectangle.Direction.Right + onParentChanged: + { + visible = parent != stageMenu + parent.Component.destruction.connect(stageMenu.onParentDestroyed) + } } } From 3f3cd5e33443ebe1f01671f5c08e3397c85fd962 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 13 Dec 2018 16:32:27 +0100 Subject: [PATCH 0924/1292] Remove broken load of PrepareSidebar.qml This file no longer exists. Loading it gives a warning. --- cura/Stages/CuraStage.py | 4 ---- plugins/PrepareStage/PrepareStage.py | 6 +----- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/cura/Stages/CuraStage.py b/cura/Stages/CuraStage.py index e8537fb6b9..844b0d0768 100644 --- a/cura/Stages/CuraStage.py +++ b/cura/Stages/CuraStage.py @@ -24,10 +24,6 @@ class CuraStage(Stage): def mainComponent(self) -> QUrl: return self.getDisplayComponent("main") - @pyqtProperty(QUrl, constant = True) - def sidebarComponent(self) -> QUrl: - return self.getDisplayComponent("sidebar") - @pyqtProperty(QUrl, constant = True) def stageMenuComponent(self) -> QUrl: return self.getDisplayComponent("menu") \ No newline at end of file diff --git a/plugins/PrepareStage/PrepareStage.py b/plugins/PrepareStage/PrepareStage.py index b22f3385b8..b0f862dc48 100644 --- a/plugins/PrepareStage/PrepareStage.py +++ b/plugins/PrepareStage/PrepareStage.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 os.path from UM.Application import Application @@ -15,9 +15,5 @@ class PrepareStage(CuraStage): Application.getInstance().engineCreatedSignal.connect(self._engineCreated) def _engineCreated(self): - sidebar_component_path = os.path.join(Resources.getPath(Application.getInstance().ResourceTypes.QmlFiles), - "PrepareSidebar.qml") - menu_component_path = os.path.join(PluginRegistry.getInstance().getPluginPath("PrepareStage"), "PrepareMenu.qml") self.addDisplayComponent("menu", menu_component_path) - self.addDisplayComponent("sidebar", sidebar_component_path) From 012ee0c02a66ef4e1bbbc5dde6aee8d8fec9988a Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 13 Dec 2018 16:44:49 +0100 Subject: [PATCH 0925/1292] Use the MouseArea trick to assure that the binding still works for the checked property of the button. Contributes to CURA-6028. --- resources/qml/MainWindow/MainWindowHeader.qml | 8 +++++++- resources/qml/ViewsSelector.qml | 3 --- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/resources/qml/MainWindow/MainWindowHeader.qml b/resources/qml/MainWindow/MainWindowHeader.qml index 6cb7370ec2..793df42da0 100644 --- a/resources/qml/MainWindow/MainWindowHeader.qml +++ b/resources/qml/MainWindow/MainWindowHeader.qml @@ -60,11 +60,17 @@ Item exclusiveGroup: mainWindowHeaderMenuGroup style: UM.Theme.styles.main_window_header_tab height: UM.Theme.getSize("main_window_header_button").height - onClicked: UM.Controller.setActiveStage(model.id) iconSource: model.stage.iconSource property color overlayColor: "transparent" property string overlayIconSource: "" + + // This is a trick to assure the activeStage is correctly changed. It doesn't work propertly if done in the onClicked (see CURA-6028) + MouseArea + { + anchors.fill: parent + onClicked: UM.Controller.setActiveStage(model.id) + } } } diff --git a/resources/qml/ViewsSelector.qml b/resources/qml/ViewsSelector.qml index d91412cad0..06d2e662b5 100644 --- a/resources/qml/ViewsSelector.qml +++ b/resources/qml/ViewsSelector.qml @@ -19,14 +19,12 @@ Cura.ExpandablePopup onDataChanged: updateActiveView() } - property var activeView: null function updateActiveView() { for (var index in viewModel.items) { - if (viewModel.items[index].active) { activeView = viewModel.items[index] @@ -38,7 +36,6 @@ Cura.ExpandablePopup Component.onCompleted: { - updateActiveView() if (activeView == null) { UM.Controller.setActiveView(viewModel.getItem(0).id) From 3d4da94b36593505a4e86f41e46999f9660337f1 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 13 Dec 2018 16:49:27 +0100 Subject: [PATCH 0926/1292] Remove obsolete description detail about old Cura versions This setting had a detail in the description about how the setting used to behave in old Cura versions. Let's remove it since it is not relevant any more. Fixes #4536. --- 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 c015ab8ccb..f39e267354 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -3385,7 +3385,7 @@ "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 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.", + "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 or to only comb within the infill.", "type": "enum", "options": { From 473160a102c902bd4161d3b7d4027414a71c144a Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 13 Dec 2018 17:02:13 +0100 Subject: [PATCH 0927/1292] Add a check for null to avoid warnings in the logs. --- resources/qml/MainWindow/MainWindowHeader.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/MainWindow/MainWindowHeader.qml b/resources/qml/MainWindow/MainWindowHeader.qml index 793df42da0..8f6957d9cd 100644 --- a/resources/qml/MainWindow/MainWindowHeader.qml +++ b/resources/qml/MainWindow/MainWindowHeader.qml @@ -54,7 +54,7 @@ Item { text: model.name.toUpperCase() checkable: true - checked: model.id == UM.Controller.activeStage.stageId + checked: UM.Controller.activeStage != null ? model.id == UM.Controller.activeStage.stageId : false anchors.verticalCenter: parent.verticalCenter exclusiveGroup: mainWindowHeaderMenuGroup From 856c1dcb20d42a624bfc367ca135042d7404953f Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 13 Dec 2018 17:21:07 +0100 Subject: [PATCH 0928/1292] Also disconnect the signal for the old parent of printSetupSelector --- resources/qml/Cura.qml | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index cf6f36a492..ff5a603fda 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -278,29 +278,33 @@ UM.MainWindow height: UM.Theme.getSize("stage_menu").height source: UM.Controller.activeStage != null ? UM.Controller.activeStage.stageMenuComponent : "" - // HACK: This is to ensure that the parent never gets set to null, as this wreaks havoc on the focus. function onParentDestroyed() { printSetupSelector.parent = stageMenu printSetupSelector.visible = false } + property item oldParent: null // The printSetupSelector is defined here so that the setting list doesn't need to get re-instantiated // Every time the stage is changed. property var printSetupSelector: Cura.PrintSetupSelector { - width: UM.Theme.getSize("print_setup_widget").width - height: UM.Theme.getSize("stage_menu").height - headerCornerSide: RoundedRectangle.Direction.Right - onParentChanged: - { - visible = parent != stageMenu - parent.Component.destruction.connect(stageMenu.onParentDestroyed) - } + width: UM.Theme.getSize("print_setup_widget").width + height: UM.Theme.getSize("stage_menu").height + headerCornerSide: RoundedRectangle.Direction.Right + onParentChanged: + { + if(stageMenu.oldParent !=null) + { + stageMenu.oldParent.Component.destruction.disconnect(stageMenu.onParentDestroyed) + } + stageMenu.oldParent = parent + visible = parent != stageMenu + parent.Component.destruction.connect(stageMenu.onParentDestroyed) + } } } - UM.MessageStack { anchors From 8dc2a41fb7af876a2f4c041fd68482f131b4385c Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Thu, 13 Dec 2018 17:27:16 +0100 Subject: [PATCH 0929/1292] Typo, wrong item type, "item" CURA-5941 --- resources/qml/Cura.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index ff5a603fda..2b6f989e0b 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -284,7 +284,7 @@ UM.MainWindow printSetupSelector.parent = stageMenu printSetupSelector.visible = false } - property item oldParent: null + property Item oldParent: null // The printSetupSelector is defined here so that the setting list doesn't need to get re-instantiated // Every time the stage is changed. From 6bf39a32a941dfc4ef96a3f250527c04d9060541 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 14 Dec 2018 09:56:06 +0100 Subject: [PATCH 0930/1292] Rename Enum names to camal cases CURA-6011 --- .../NetworkedPrinterOutputDevice.py | 10 +++---- cura/PrinterOutputDevice.py | 26 ++++++++++--------- .../src/ClusterUM3OutputDevice.py | 2 +- .../src/LegacyUM3OutputDevice.py | 2 +- plugins/USBPrinting/USBPrinterOutputDevice.py | 8 +++--- .../USBPrinterOutputDeviceManager.py | 2 +- 6 files changed, 26 insertions(+), 24 deletions(-) diff --git a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py index c288596f0c..14f1364601 100644 --- a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py +++ b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py @@ -28,7 +28,7 @@ class AuthState(IntEnum): class NetworkedPrinterOutputDevice(PrinterOutputDevice): authenticationStateChanged = pyqtSignal() - def __init__(self, device_id, address: str, properties: Dict[bytes, bytes], connection_type: ConnectionType = ConnectionType.networkConnection, parent: QObject = None) -> None: + def __init__(self, device_id, address: str, properties: Dict[bytes, bytes], connection_type: ConnectionType = ConnectionType.NetworkConnection, parent: QObject = None) -> None: super().__init__(device_id = device_id, connection_type = connection_type, parent = parent) self._manager = None # type: Optional[QNetworkAccessManager] self._last_manager_create_time = None # type: Optional[float] @@ -125,7 +125,7 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): if self._connection_state_before_timeout is None: self._connection_state_before_timeout = self._connection_state - self.setConnectionState(ConnectionState.closed) + self.setConnectionState(ConnectionState.Closed) # We need to check if the manager needs to be re-created. If we don't, we get some issues when OSX goes to # sleep. @@ -133,7 +133,7 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): if self._last_manager_create_time is None or time() - self._last_manager_create_time > self._recreate_network_manager_time: self._createNetworkManager() assert(self._manager is not None) - elif self._connection_state == ConnectionState.closed: + elif self._connection_state == ConnectionState.Closed: # Go out of timeout. if self._connection_state_before_timeout is not None: # sanity check, but it should never be None here self.setConnectionState(self._connection_state_before_timeout) @@ -285,8 +285,8 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): self._last_response_time = time() - if self._connection_state == ConnectionState.connecting: - self.setConnectionState(ConnectionState.connected) + if self._connection_state == ConnectionState.Connecting: + self.setConnectionState(ConnectionState.Connected) callback_key = reply.url().toString() + str(reply.operation()) try: diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index 3a72fba4e3..51be3c0465 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -28,18 +28,20 @@ i18n_catalog = i18nCatalog("cura") ## The current processing state of the backend. class ConnectionState(IntEnum): - closed = 0 - connecting = 1 - connected = 2 - busy = 3 + Closed = 0 + Connecting = 1 + Connected = 2 + Busy = 3 error = 4 + class ConnectionType(IntEnum): none = 0 - usbConnection = 1 - networkConnection = 2 - clusterConnection = 3 - cloudConnection = 4 + UsbConnection = 1 + NetworkConnection = 2 + ClusterConnection = 3 + CloudConnection = 4 + ## Printer output device adds extra interface options on top of output device. # @@ -89,7 +91,7 @@ class PrinterOutputDevice(QObject, OutputDevice): self._update_timer.setSingleShot(False) self._update_timer.timeout.connect(self._update) - self._connection_state = ConnectionState.closed #type: ConnectionState + self._connection_state = ConnectionState.Closed #type: ConnectionState self._connection_type = connection_type self._firmware_updater = None #type: Optional[FirmwareUpdater] @@ -117,7 +119,7 @@ class PrinterOutputDevice(QObject, OutputDevice): callback(QMessageBox.Yes) def isConnected(self) -> bool: - return self._connection_state != ConnectionState.closed and self._connection_state != ConnectionState.error + return self._connection_state != ConnectionState.Closed and self._connection_state != ConnectionState.error def setConnectionState(self, connection_state: ConnectionState) -> None: if self._connection_state != connection_state: @@ -191,13 +193,13 @@ class PrinterOutputDevice(QObject, OutputDevice): ## Attempt to establish connection def connect(self) -> None: - self.setConnectionState(ConnectionState.connecting) + self.setConnectionState(ConnectionState.Connecting) self._update_timer.start() ## Attempt to close the connection def close(self) -> None: self._update_timer.stop() - self.setConnectionState(ConnectionState.closed) + self.setConnectionState(ConnectionState.Closed) ## Ensure that close gets called when object is destroyed def __del__(self) -> None: diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index 206654ff88..d85cbeb27b 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -55,7 +55,7 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): clusterPrintersChanged = pyqtSignal() def __init__(self, device_id, address, properties, parent = None) -> None: - super().__init__(device_id = device_id, address = address, properties=properties, connection_type = ConnectionType.clusterConnection, parent = parent) + super().__init__(device_id = device_id, address = address, properties=properties, connection_type = ConnectionType.ClusterConnection, parent = parent) self._api_prefix = "/cluster-api/v1/" self._number_of_extruders = 2 diff --git a/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py index 0ae9e8a004..3ce0460d6b 100644 --- a/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py @@ -44,7 +44,7 @@ i18n_catalog = i18nCatalog("cura") # 5. As a final step, we verify the authentication, as this forces the QT manager to setup the authenticator. class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice): def __init__(self, device_id, address: str, properties, parent = None) -> None: - super().__init__(device_id = device_id, address = address, properties = properties, connection_type = ConnectionType.networkConnection, parent = parent) + super().__init__(device_id = device_id, address = address, properties = properties, connection_type = ConnectionType.NetworkConnection, parent = parent) self._api_prefix = "/api/v1/" self._number_of_extruders = 2 diff --git a/plugins/USBPrinting/USBPrinterOutputDevice.py b/plugins/USBPrinting/USBPrinterOutputDevice.py index a8cb240b03..08cf29baf4 100644 --- a/plugins/USBPrinting/USBPrinterOutputDevice.py +++ b/plugins/USBPrinting/USBPrinterOutputDevice.py @@ -29,7 +29,7 @@ catalog = i18nCatalog("cura") class USBPrinterOutputDevice(PrinterOutputDevice): def __init__(self, serial_port: str, baud_rate: Optional[int] = None) -> None: - super().__init__(serial_port, connection_type=ConnectionType.usbConnection) + super().__init__(serial_port, connection_type=ConnectionType.UsbConnection) self.setName(catalog.i18nc("@item:inmenu", "USB printing")) self.setShortDescription(catalog.i18nc("@action:button Preceded by 'Ready to'.", "Print via USB")) self.setDescription(catalog.i18nc("@info:tooltip", "Print via USB")) @@ -179,7 +179,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice): return CuraApplication.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerStackChanged) self._onGlobalContainerStackChanged() - self.setConnectionState(ConnectionState.connected) + self.setConnectionState(ConnectionState.Connected) self._update_thread.start() def _onGlobalContainerStackChanged(self): @@ -208,7 +208,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice): self._sendCommand(command) def _sendCommand(self, command: Union[str, bytes]): - if self._serial is None or self._connection_state != ConnectionState.connected: + if self._serial is None or self._connection_state != ConnectionState.Connected: return new_command = cast(bytes, command) if type(command) is bytes else cast(str, command).encode() # type: bytes @@ -222,7 +222,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice): self._command_received.set() def _update(self): - while self._connection_state == ConnectionState.connected and self._serial is not None: + while self._connection_state == ConnectionState.Connected and self._serial is not None: try: line = self._serial.readline() except: diff --git a/plugins/USBPrinting/USBPrinterOutputDeviceManager.py b/plugins/USBPrinting/USBPrinterOutputDeviceManager.py index bd207d9d96..d4c0d1828e 100644 --- a/plugins/USBPrinting/USBPrinterOutputDeviceManager.py +++ b/plugins/USBPrinting/USBPrinterOutputDeviceManager.py @@ -66,7 +66,7 @@ class USBPrinterOutputDeviceManager(QObject, OutputDevicePlugin): return changed_device = self._usb_output_devices[serial_port] - if changed_device.connectionState == ConnectionState.connected: + if changed_device.connectionState == ConnectionState.Connected: self.getOutputDeviceManager().addOutputDevice(changed_device) else: self.getOutputDeviceManager().removeOutputDevice(serial_port) From 0aa49270ebb53521b3364ce5ab795b51d3e3adba Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 14 Dec 2018 09:57:40 +0100 Subject: [PATCH 0931/1292] Remove unused function checkConnectionType() CURA-6011 --- cura/PrinterOutputDevice.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index 51be3c0465..dce470f442 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -126,9 +126,6 @@ class PrinterOutputDevice(QObject, OutputDevice): self._connection_state = connection_state self.connectionStateChanged.emit(self._id) - def checkConnectionType(self, connection_type: ConnectionType) -> bool: - return connection_type == self._connection_type - def getConnectionType(self) -> ConnectionType: return self._connection_type From 644944bc4171a98b9abd8ee54493d967d6732779 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 14 Dec 2018 10:00:18 +0100 Subject: [PATCH 0932/1292] Remove unused function setConnectionType() CURA-6011 --- cura/PrinterOutputDevice.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index dce470f442..0b2f10c570 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -129,10 +129,6 @@ class PrinterOutputDevice(QObject, OutputDevice): def getConnectionType(self) -> ConnectionType: return self._connection_type - def setConnectionType(self, new_connection_type: ConnectionType) -> None: - if self._connection_type != new_connection_type: - self._connection_type = new_connection_type - @pyqtProperty(str, notify = connectionStateChanged) def connectionState(self) -> ConnectionState: return self._connection_state From 3e1993d87679c0d29f3df5cc1a14962b32ccb18a Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 14 Dec 2018 10:10:54 +0100 Subject: [PATCH 0933/1292] Rename Enum name to camal cases CURA-6011 --- cura/PrinterOutputDevice.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index 0b2f10c570..f6d15f5a4a 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -32,7 +32,7 @@ class ConnectionState(IntEnum): Connecting = 1 Connected = 2 Busy = 3 - error = 4 + Error = 4 class ConnectionType(IntEnum): From bb1bf14a0182710ebb5c08fcbc8248e8d67c711e Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 14 Dec 2018 10:46:31 +0100 Subject: [PATCH 0934/1292] Prevent rating when user is not logged in CURA-6013 --- plugins/Toolbox/resources/qml/RatingWidget.qml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/plugins/Toolbox/resources/qml/RatingWidget.qml b/plugins/Toolbox/resources/qml/RatingWidget.qml index 9d9eb8bca8..2623d13c0e 100644 --- a/plugins/Toolbox/resources/qml/RatingWidget.qml +++ b/plugins/Toolbox/resources/qml/RatingWidget.qml @@ -25,7 +25,10 @@ Item acceptedButtons: Qt.NoButton onExited: { - ratingWidget.indexHovered = -1 + if(ratingWidget.canRate) + { + ratingWidget.indexHovered = -1 + } } Row @@ -87,7 +90,13 @@ Item return "#5a5a5a" } } - onClicked: rated(index + 1) // Notify anyone who cares about this. + onClicked: + { + if(ratingWidget.canRate) + { + rated(index + 1) // Notify anyone who cares about this. + } + } } } } From 8bb8ae8652d1abb7f153aa8bcd309dd183b2b262 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 14 Dec 2018 10:48:23 +0100 Subject: [PATCH 0935/1292] Rename ConnectionType.none to ConnectionType.Unknown CURA-6011 Cannot use None --- cura/PrinterOutputDevice.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index f6d15f5a4a..b664e30d0b 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -36,7 +36,7 @@ class ConnectionState(IntEnum): class ConnectionType(IntEnum): - none = 0 + Unknown = 0 UsbConnection = 1 NetworkConnection = 2 ClusterConnection = 3 From 99cee1dfe766b16b5a9b0cedf3c439ca7ded39b5 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 14 Dec 2018 10:54:52 +0100 Subject: [PATCH 0936/1292] Use double-quotes for custom type hinting in functions CURA-6011 --- cura/PrinterOutputDevice.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index b664e30d0b..2db03a4e87 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -70,7 +70,7 @@ class PrinterOutputDevice(QObject, OutputDevice): # Signal to indicate that the configuration of one of the printers has changed. uniqueConfigurationsChanged = pyqtSignal() - def __init__(self, device_id: str, connection_type: ConnectionType, parent: QObject = None) -> None: + def __init__(self, device_id: str, connection_type: "ConnectionType", parent: QObject = None) -> None: super().__init__(device_id = device_id, parent = parent) # type: ignore # MyPy complains with the multiple inheritance self._printers = [] # type: List[PrinterOutputModel] @@ -119,18 +119,18 @@ class PrinterOutputDevice(QObject, OutputDevice): callback(QMessageBox.Yes) def isConnected(self) -> bool: - return self._connection_state != ConnectionState.Closed and self._connection_state != ConnectionState.error + return self._connection_state != ConnectionState.Closed and self._connection_state != ConnectionState.Error - def setConnectionState(self, connection_state: ConnectionState) -> None: + def setConnectionState(self, connection_state: "ConnectionState") -> None: if self._connection_state != connection_state: self._connection_state = connection_state self.connectionStateChanged.emit(self._id) - def getConnectionType(self) -> ConnectionType: + def getConnectionType(self) -> "ConnectionType": return self._connection_type @pyqtProperty(str, notify = connectionStateChanged) - def connectionState(self) -> ConnectionState: + def connectionState(self) -> "ConnectionState": return self._connection_state def _update(self) -> None: From aba3b6dd8ee66ea05273e8f0ec74ae7a9c06611b Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 14 Dec 2018 10:55:34 +0100 Subject: [PATCH 0937/1292] Rename setKey() and add docs CURA-6011 --- .../resources/qml/DiscoverUM3Action.qml | 2 +- plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml b/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml index 2c9ab2df03..80b5c2f99e 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml @@ -28,7 +28,7 @@ Cura.MachineAction // Check if there is another instance with the same key if (!manager.existsKey(printerKey)) { - manager.setKey(base.selectedDevice) + manager.associateActiveMachineWithPrinterDevice(base.selectedDevice) manager.setGroupName(printerName) // TODO To change when the groups have a name completed() } diff --git a/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py b/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py index 9cd21de036..2e59810317 100644 --- a/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py +++ b/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py @@ -3,7 +3,7 @@ import os.path import time -from typing import Optional +from typing import Optional, TYPE_CHECKING from PyQt5.QtCore import pyqtSignal, pyqtProperty, pyqtSlot, QObject @@ -13,10 +13,12 @@ from UM.i18n import i18nCatalog from cura.CuraApplication import CuraApplication from cura.MachineAction import MachineAction -from cura.PrinterOutputDevice import PrinterOutputDevice from .UM3OutputDevicePlugin import UM3OutputDevicePlugin +if TYPE_CHECKING: + from cura.PrinterOutputDevice import PrinterOutputDevice + catalog = i18nCatalog("cura") @@ -117,8 +119,10 @@ class DiscoverUM3Action(MachineAction): # Ensure that the connection states are refreshed. self._network_plugin.reCheckConnections() + # Associates the currently active machine with the given printer device. The network connection information will be + # stored into the metadata of the currently active machine. @pyqtSlot(QObject) - def setKey(self, printer_device: Optional[PrinterOutputDevice]) -> None: + def associateActiveMachineWithPrinterDevice(self, printer_device: Optional["PrinterOutputDevice"]) -> None: Logger.log("d", "Attempting to set the network key of the active machine to %s", printer_device.key) global_container_stack = CuraApplication.getInstance().getGlobalContainerStack() if global_container_stack: From 450f301c8c1211684db866eee9e1d8573a4d8665 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 14 Dec 2018 10:56:13 +0100 Subject: [PATCH 0938/1292] Fix binding loop CURA-6013 --- plugins/Toolbox/resources/qml/ToolboxDetailPage.qml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 0e183c2860..95c3a20e1e 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -57,7 +57,6 @@ Item top: thumbnail.top left: thumbnail.right leftMargin: UM.Theme.getSize("default_margin").width - bottomMargin: UM.Theme.getSize("default_margin").height } text: details === null ? "" : (details.name || "") font: UM.Theme.getFont("large") @@ -226,13 +225,6 @@ Item renderType: Text.NativeRendering } } - Rectangle - { - color: UM.Theme.getColor("lining") - width: parent.width - height: UM.Theme.getSize("default_lining").height - anchors.bottom: parent.bottom - } } ToolboxDetailList { From 7616f9c97db92a7b213bd45232bb419e51581436 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 14 Dec 2018 10:59:59 +0100 Subject: [PATCH 0939/1292] Make hardcoded color themeable CURA-6013 --- plugins/Toolbox/resources/qml/RatingWidget.qml | 4 ++-- plugins/Toolbox/resources/qml/SmallRatingWidget.qml | 2 +- resources/themes/cura-light/theme.json | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/plugins/Toolbox/resources/qml/RatingWidget.qml b/plugins/Toolbox/resources/qml/RatingWidget.qml index 2623d13c0e..3dcae6d602 100644 --- a/plugins/Toolbox/resources/qml/RatingWidget.qml +++ b/plugins/Toolbox/resources/qml/RatingWidget.qml @@ -81,13 +81,13 @@ Item { if(!ratingWidget.canRate) { - return "#5a5a5a" + return UM.Theme.getColor("rating_star") } if((ratingWidget.indexHovered >= 0 || ratingWidget.userRating > 0) && isStarFilled) { return UM.Theme.getColor("primary") } - return "#5a5a5a" + return UM.Theme.getColor("rating_star") } } onClicked: diff --git a/plugins/Toolbox/resources/qml/SmallRatingWidget.qml b/plugins/Toolbox/resources/qml/SmallRatingWidget.qml index 439a7baec0..bab219d294 100644 --- a/plugins/Toolbox/resources/qml/SmallRatingWidget.qml +++ b/plugins/Toolbox/resources/qml/SmallRatingWidget.qml @@ -14,7 +14,7 @@ Row { id: starIcon source: UM.Theme.getIcon("star_filled") - color: model.user_rating == 0 ? "#5a5a5a" : UM.Theme.getColor("primary") + color: model.user_rating == 0 ? UM.Theme.getColor("rating_star") : UM.Theme.getColor("primary") height: UM.Theme.getSize("rating_star").height width: UM.Theme.getSize("rating_star").width } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 969f5666a6..16f885c0b5 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -160,6 +160,8 @@ "extruder_button_material_border": [255, 255, 255, 255], + "rating_star": [90, 90, 90, 255], + "sync_button_text": [120, 120, 120, 255], "sync_button_text_hovered": [0, 0, 0, 255], From edd4f6e1faa7062299d832ceac2e412a3aec23b6 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 14 Dec 2018 11:02:10 +0100 Subject: [PATCH 0940/1292] Fix some minor QML warnings CURA-6013 --- plugins/Toolbox/resources/qml/ToolboxDetailPage.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 95c3a20e1e..92b9fb1198 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -138,8 +138,8 @@ Item { id: rating visible: details.type == "plugin" - packageId: details.id - userRating: details.user_rating + packageId: details.id != undefined ? details.id: "" + userRating: details.user_rating != undefined ? details.user_rating: 0 canRate: toolbox.isInstalled(details.id) && Cura.API.account.isLoggedIn onRated: From 5e4e52e6fc8fc912e9c43492f418cb77a6c12655 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 14 Dec 2018 11:09:48 +0100 Subject: [PATCH 0941/1292] Fix blue square being shown in selector if no icon is set CURA-5876 --- resources/qml/PrinterSelector/MachineSelector.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index db9c38b9f1..fb8f0a58e1 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -41,7 +41,7 @@ Cura.ExpandablePopup } font: UM.Theme.getFont("medium") iconColor: UM.Theme.getColor("machine_selector_printer_icon") - iconSize: UM.Theme.getSize("machine_selector_icon").width + iconSize: source != "" ? UM.Theme.getSize("machine_selector_icon").width: 0 UM.RecolorImage { From 4252b956039f4875e63735944ee8d1f36d5c1cb8 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 14 Dec 2018 11:28:18 +0100 Subject: [PATCH 0942/1292] Make ConnectionType Enum type accessible to QML CURA-6011 --- cura/CuraApplication.py | 3 +++ cura/PrinterOutputDevice.py | 8 +++++++- resources/qml/PrinterSelector/MachineSelectorList.qml | 9 ++++++++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 7e11fd4d59..a50d7d55c8 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -113,6 +113,7 @@ from cura.Settings.CuraFormulaFunctions import CuraFormulaFunctions from cura.ObjectsModel import ObjectsModel +from cura.PrinterOutputDevice import PrinterOutputDevice from cura.PrinterOutput.NetworkMJPGImage import NetworkMJPGImage from UM.FlameProfiler import pyqtSlot @@ -975,6 +976,8 @@ class CuraApplication(QtApplication): qmlRegisterSingletonType(ContainerManager, "Cura", 1, 0, "ContainerManager", ContainerManager.getInstance) qmlRegisterType(SidebarCustomMenuItemsModel, "Cura", 1, 0, "SidebarCustomMenuItemsModel") + qmlRegisterType(PrinterOutputDevice, "Cura", 1, 0, "PrinterOutputDevice") + from cura.API import CuraAPI qmlRegisterSingletonType(CuraAPI, "Cura", 1, 1, "API", self.getCuraAPI) diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index 2db03a4e87..298c690b01 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -4,7 +4,7 @@ from UM.Decorators import deprecated from UM.i18n import i18nCatalog from UM.OutputDevice.OutputDevice import OutputDevice -from PyQt5.QtCore import pyqtProperty, pyqtSignal, QObject, QTimer, QUrl +from PyQt5.QtCore import pyqtProperty, pyqtSignal, QObject, QTimer, QUrl, Q_ENUMS from PyQt5.QtWidgets import QMessageBox from UM.Logger import Logger @@ -54,6 +54,12 @@ class ConnectionType(IntEnum): # For all other uses it should be used in the same way as a "regular" OutputDevice. @signalemitter class PrinterOutputDevice(QObject, OutputDevice): + + # Put ConnectionType here with Q_ENUMS() so it can be registered as a QML type and accessible via QML, and there is + # no need to remember what those Enum integer values mean. + ConnectionType = ConnectionType + Q_ENUMS(ConnectionType) + printersChanged = pyqtSignal() connectionStateChanged = pyqtSignal(str) acceptsCommandsChanged = pyqtSignal() diff --git a/resources/qml/PrinterSelector/MachineSelectorList.qml b/resources/qml/PrinterSelector/MachineSelectorList.qml index 3324b9948b..bc3fe105a2 100644 --- a/resources/qml/PrinterSelector/MachineSelectorList.qml +++ b/resources/qml/PrinterSelector/MachineSelectorList.qml @@ -30,9 +30,16 @@ Column model: UM.ContainerStacksModel { id: networkedPrintersModel + property var umConnectionTypes: [Cura.PrinterOutputDevice.NetworkConnection, + Cura.PrinterOutputDevice.ClusterConnection, + Cura.PrinterOutputDevice.CloudConnection + ] filter: { - "type": "machine", "um_network_key": "*", "hidden": "False", "um_connection_type": "[2,3,4]" + "type": "machine", + "um_network_key": "*", + "hidden": "False", + "um_connection_type": "[" + umConnectionTypes.join(",") + "]" } } From 15cd2a926975403ad0e225ffa0b2e63beadcab1b Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 14 Dec 2018 11:36:40 +0100 Subject: [PATCH 0943/1292] Changed textColor of recommended infill slider text to be themed. This is required to make the dark theme work correctly --- .../Recommended/RecommendedInfillDensitySelector.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml index 2971415948..0da53cc1c1 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml @@ -144,6 +144,7 @@ Item anchors.horizontalCenter: parent.horizontalCenter y: UM.Theme.getSize("thin_margin").height renderType: Text.NativeRendering + color: UM.Theme.getColor("quality_slider_available") } } } From a18203b2864358dfcde1206bf51250e523e6af91 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 14 Dec 2018 11:37:30 +0100 Subject: [PATCH 0944/1292] Fix typing CURA-6011 --- cura/PrinterOutputDevice.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index 298c690b01..ed65d5d700 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -57,7 +57,6 @@ class PrinterOutputDevice(QObject, OutputDevice): # Put ConnectionType here with Q_ENUMS() so it can be registered as a QML type and accessible via QML, and there is # no need to remember what those Enum integer values mean. - ConnectionType = ConnectionType Q_ENUMS(ConnectionType) printersChanged = pyqtSignal() From 6a3ac9955162885c81859354d366d82cad40e42f Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 14 Dec 2018 11:59:22 +0100 Subject: [PATCH 0945/1292] Ensure that all icons use the same color from theme. Also added some fixes for the dark theme --- plugins/PrepareStage/PrepareMenu.qml | 2 +- resources/qml/ActionPanel/PrintInformationWidget.qml | 2 +- resources/qml/IconWithText.qml | 4 ++-- resources/qml/Toolbar.qml | 2 +- resources/themes/cura-dark/theme.json | 6 ++++++ resources/themes/cura-light/theme.json | 2 ++ 6 files changed, 13 insertions(+), 5 deletions(-) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index b7980bc30b..b62d65254d 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -100,7 +100,7 @@ Item source: UM.Theme.getIcon("load") width: UM.Theme.getSize("button_icon").width height: UM.Theme.getSize("button_icon").height - color: UM.Theme.getColor("toolbar_button_text") + color: UM.Theme.getColor("icon") sourceSize.height: height } diff --git a/resources/qml/ActionPanel/PrintInformationWidget.qml b/resources/qml/ActionPanel/PrintInformationWidget.qml index 554273a818..0826e2c715 100644 --- a/resources/qml/ActionPanel/PrintInformationWidget.qml +++ b/resources/qml/ActionPanel/PrintInformationWidget.qml @@ -15,7 +15,7 @@ UM.RecolorImage width: UM.Theme.getSize("section_icon").width height: UM.Theme.getSize("section_icon").height - color: popup.opened ? UM.Theme.getColor("primary") : UM.Theme.getColor("text_medium") + color: UM.Theme.getColor("icon") MouseArea { diff --git a/resources/qml/IconWithText.qml b/resources/qml/IconWithText.qml index 5530740040..f9220380f2 100644 --- a/resources/qml/IconWithText.qml +++ b/resources/qml/IconWithText.qml @@ -18,7 +18,7 @@ Item property alias color: label.color property alias text: label.text property alias font: label.font - + property alias iconColor: icon.color property real margin: UM.Theme.getSize("narrow_margin").width // These properties can be used in combination with layouts. @@ -39,7 +39,7 @@ Item width: UM.Theme.getSize("section_icon").width height: UM.Theme.getSize("section_icon").height - color: label.color + color: UM.Theme.getColor("icon") anchors { diff --git a/resources/qml/Toolbar.qml b/resources/qml/Toolbar.qml index 1e335472d4..c3c4c1cd6d 100644 --- a/resources/qml/Toolbar.qml +++ b/resources/qml/Toolbar.qml @@ -67,7 +67,7 @@ Item toolItem: UM.RecolorImage { source: UM.Theme.getIcon(model.icon) != "" ? UM.Theme.getIcon(model.icon) : "file:///" + model.location + "/" + model.icon - color: UM.Theme.getColor("toolbar_button_text") + color: UM.Theme.getColor("icon") sourceSize: UM.Theme.getSize("button_icon") } diff --git a/resources/themes/cura-dark/theme.json b/resources/themes/cura-dark/theme.json index 8540abf61a..2fa96c8897 100644 --- a/resources/themes/cura-dark/theme.json +++ b/resources/themes/cura-dark/theme.json @@ -17,6 +17,12 @@ "border": [127, 127, 127, 255], "secondary": [95, 95, 95, 255], + "icon": [204, 204, 204, 255], + "toolbar_background": [39, 44, 48, 255], + "toolbar_button_active": [95, 95, 95, 255], + "toolbar_button_hover": [95, 95, 95, 255], + "toolbar_button_active_hover": [95, 95, 95, 255], + "main_window_header_button_text_inactive": [128, 128, 128, 255], "main_window_header_button_text_hovered": [255, 255, 255, 255], diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 6d76004739..b64190dd23 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -83,6 +83,8 @@ "secondary": [240, 240, 240, 255], "secondary_shadow": [216, 216, 216, 255], + "icon": [8, 7, 63, 255], + "primary_button": [38, 113, 231, 255], "primary_button_shadow": [27, 95, 202, 255], "primary_button_hover": [81, 145, 247, 255], From c3aca8907cdfe83439b863912dcf3291142980dc Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 14 Dec 2018 12:02:52 +0100 Subject: [PATCH 0946/1292] Fix extruder number not being visible in dark theme --- resources/qml/ExtruderIcon.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/qml/ExtruderIcon.qml b/resources/qml/ExtruderIcon.qml index bb0b347b7e..c44b6e0fa3 100644 --- a/resources/qml/ExtruderIcon.qml +++ b/resources/qml/ExtruderIcon.qml @@ -49,6 +49,7 @@ Item anchors.centerIn: parent text: index + 1 font: UM.Theme.getFont("very_small") + color: UM.Theme.getColor("text") width: contentWidth height: contentHeight visible: extruderEnabled From 4dc8edb99625de2c4b1efbe96eb3170e034b795b Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 14 Dec 2018 12:48:40 +0100 Subject: [PATCH 0947/1292] STAR-322: Fixing the multipart upload --- cura/NetworkClient.py | 82 +++++++------------ cura/OAuth2/AuthorizationService.py | 2 + .../src/Cloud/CloudOutputDevice.py | 12 +-- .../src/Cloud/CloudOutputDeviceManager.py | 34 ++++++-- .../src/Cloud/ResumableUpload.py | 53 ++++++++---- .../src/UM3OutputDevicePlugin.py | 2 + 6 files changed, 105 insertions(+), 80 deletions(-) diff --git a/cura/NetworkClient.py b/cura/NetworkClient.py index 6abf4f3d47..b455d03db0 100644 --- a/cura/NetworkClient.py +++ b/cura/NetworkClient.py @@ -1,7 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. from time import time -from typing import Optional, Dict, Callable, List, Union +from typing import Optional, Dict, Callable, List, Union, Tuple from PyQt5.QtCore import QUrl from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkReply, QHttpMultiPart, QNetworkRequest, QHttpPart, \ @@ -16,50 +16,63 @@ from UM.Logger import Logger class NetworkClient: def __init__(self) -> None: - + # Network manager instance to use for this client. self._manager = None # type: Optional[QNetworkAccessManager] - + # Timings. self._last_manager_create_time = None # type: Optional[float] self._last_response_time = None # type: Optional[float] self._last_request_time = None # type: Optional[float] - + # The user agent of Cura. application = Application.getInstance() self._user_agent = "%s/%s " % (application.getApplicationName(), application.getVersion()) # Uses to store callback methods for finished network requests. # This allows us to register network calls with a callback directly instead of having to dissect the reply. - self._on_finished_callbacks = {} # type: Dict[str, Callable[[QNetworkReply], None]] + # The key is created out of a tuple (operation, url) + self._on_finished_callbacks = {} # type: Dict[Tuple[int, str], Callable[[QNetworkReply], None]] # QHttpMultiPart objects need to be kept alive and not garbage collected during the # HTTP which uses them. We hold references to these QHttpMultiPart objects here. self._kept_alive_multiparts = {} # type: Dict[QNetworkReply, QHttpMultiPart] - ## Creates a network manager with all the required properties and event bindings. - def _createNetworkManager(self) -> None: + ## Creates a network manager if needed, with all the required properties and event bindings. + def start(self) -> None: if self._manager: - self._manager.finished.disconnect(self.__handleOnFinished) - self._manager.authenticationRequired.disconnect(self._onAuthenticationRequired) + return self._manager = QNetworkAccessManager() - self._manager.finished.connect(self.__handleOnFinished) + self._manager.finished.connect(self._handleOnFinished) self._last_manager_create_time = time() self._manager.authenticationRequired.connect(self._onAuthenticationRequired) + ## Destroys the network manager and event bindings. + def stop(self) -> None: + if not self._manager: + return + self._manager.finished.disconnect(self._handleOnFinished) + self._manager.authenticationRequired.disconnect(self._onAuthenticationRequired) + self._manager = None + ## Create a new empty network request. # Automatically adds the required HTTP headers. # \param url: The URL to request # \param content_type: The type of the body contents. def _createEmptyRequest(self, url: str, content_type: Optional[str] = "application/json") -> QNetworkRequest: + if not self._manager: + self.start() # make sure the manager is created request = QNetworkRequest(QUrl(url)) if content_type: request.setHeader(QNetworkRequest.ContentTypeHeader, content_type) request.setHeader(QNetworkRequest.UserAgentHeader, self._user_agent) + self._last_request_time = time() return request ## Executes the correct callback method when a network request finishes. - def __handleOnFinished(self, reply: QNetworkReply) -> None: + def _handleOnFinished(self, reply: QNetworkReply) -> None: + + Logger.log("i", "On finished %s %s", reply.attribute(QNetworkRequest.HttpStatusCodeAttribute), reply.url().toString()) # Due to garbage collection, we need to cache certain bits of post operations. # As we don't want to keep them around forever, delete them if we get a reply. @@ -76,7 +89,7 @@ class NetworkClient: # Find the right callback and execute it. # It always takes the full reply as single parameter. - callback_key = reply.url().toString() + str(reply.operation()) + callback_key = reply.operation(), reply.url().toString() if callback_key in self._on_finished_callbacks: self._on_finished_callbacks[callback_key](reply) else: @@ -87,12 +100,6 @@ class NetworkClient: if reply in self._kept_alive_multiparts: del self._kept_alive_multiparts[reply] - ## Makes sure the network manager is created. - def _validateManager(self) -> None: - if self._manager is None: - self._createNetworkManager() - assert self._manager is not None - ## Callback for when the network manager detects that authentication is required but was not given. @staticmethod def _onAuthenticationRequired(reply: QNetworkReply, authenticator: QAuthenticator) -> None: @@ -102,7 +109,7 @@ class NetworkClient: def _registerOnFinishedCallback(self, reply: QNetworkReply, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: if on_finished is not None: - self._on_finished_callbacks[reply.url().toString() + str(reply.operation())] = on_finished + self._on_finished_callbacks[reply.operation(), reply.url().toString()] = on_finished ## Add a part to a Multi-Part form. @staticmethod @@ -133,33 +140,23 @@ class NetworkClient: def put(self, url: str, data: Union[str, bytes], content_type: Optional[str] = None, on_finished: Optional[Callable[[QNetworkReply], None]] = None, on_progress: Optional[Callable[[int, int], None]] = None) -> None: - self._validateManager() - request = self._createEmptyRequest(url, content_type = content_type) - self._last_request_time = time() - - if not self._manager: - return Logger.log("e", "No network manager was created to execute the PUT call with.") body = data if isinstance(data, bytes) else data.encode() # type: bytes reply = self._manager.put(request, body) self._registerOnFinishedCallback(reply, on_finished) if on_progress is not None: + # TODO: Do we need to disconnect() as well? reply.uploadProgress.connect(on_progress) + reply.finished.connect(lambda r: Logger.log("i", "On finished %s %s", url, r)) + reply.error.connect(lambda r: Logger.log("i", "On error %s %s", url, r)) ## Sends a delete request to the given path. # url: The path after the API prefix. # on_finished: The function to be call when the response is received. def delete(self, url: str, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: - self._validateManager() - request = self._createEmptyRequest(url) - self._last_request_time = time() - - if not self._manager: - return Logger.log("e", "No network manager was created to execute the DELETE call with.") - reply = self._manager.deleteResource(request) self._registerOnFinishedCallback(reply, on_finished) @@ -167,14 +164,7 @@ class NetworkClient: # \param url: The path after the API prefix. # \param on_finished: The function to be call when the response is received. def get(self, url: str, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: - self._validateManager() - request = self._createEmptyRequest(url) - self._last_request_time = time() - - if not self._manager: - return Logger.log("e", "No network manager was created to execute the GET call with.") - reply = self._manager.get(request) self._registerOnFinishedCallback(reply, on_finished) @@ -186,13 +176,7 @@ class NetworkClient: def post(self, url: str, data: Union[str, bytes], on_finished: Optional[Callable[[QNetworkReply], None]], on_progress: Optional[Callable[[int, int], None]] = None) -> None: - self._validateManager() - request = self._createEmptyRequest(url) - self._last_request_time = time() - - if not self._manager: - return Logger.log("e", "Could not find manager.") body = data if isinstance(data, bytes) else data.encode() # type: bytes reply = self._manager.post(request, body) @@ -213,20 +197,12 @@ class NetworkClient: def postFormWithParts(self, target: str, parts: List[QHttpPart], on_finished: Optional[Callable[[QNetworkReply], None]], on_progress: Optional[Callable[[int, int], None]] = None) -> Optional[QNetworkReply]: - self._validateManager() - request = self._createEmptyRequest(target, content_type = None) multi_post_part = QHttpMultiPart(QHttpMultiPart.FormDataType) for part in parts: multi_post_part.append(part) - self._last_request_time = time() - - if not self._manager: - Logger.log("e", "No network manager was created to execute the POST call with.") - return None - reply = self._manager.post(request, multi_post_part) self._kept_alive_multiparts[reply] = multi_post_part diff --git a/cura/OAuth2/AuthorizationService.py b/cura/OAuth2/AuthorizationService.py index 4355891139..21dbbe8248 100644 --- a/cura/OAuth2/AuthorizationService.py +++ b/cura/OAuth2/AuthorizationService.py @@ -54,6 +54,8 @@ class AuthorizationService: self._user_profile = self._parseJWT() if not self._user_profile: # If there is still no user profile from the JWT, we have to log in again. + Logger.log("w", "The user profile could not be loaded. The user must log in again!") + self.deleteAuthData() return None return self._user_profile diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index e75989a6a8..83b5bed16b 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -66,7 +66,7 @@ class T: class CloudOutputDevice(NetworkedPrinterOutputDevice): # The interval with which the remote clusters are checked - CHECK_CLUSTER_INTERVAL = 5.0 # seconds + CHECK_CLUSTER_INTERVAL = 50.0 # seconds # Signal triggered when the print jobs in the queue were changed. printJobsChanged = pyqtSignal() @@ -150,7 +150,6 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): return # Indicate we have started sending a job. - self._sending_job = True self.writeStarted.emit(self) mesh_format = MeshFormatHandler(file_handler, self.firmwareVersion) @@ -173,6 +172,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): if self._last_response_time and time() - self._last_response_time < self.CHECK_CLUSTER_INTERVAL: return # avoid calling the cloud too often + Logger.log("i", "Requesting update for %s after %s", self._device_id, + self._last_response_time and time() - self._last_response_time) if self._account.isLoggedIn: self.setAuthenticationState(AuthState.Authenticated) self._api.getClusterStatus(self._device_id, self._onStatusCallFinished) @@ -183,6 +184,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # Contains both printers and print jobs statuses in a single response. def _onStatusCallFinished(self, status: CloudClusterStatus) -> None: # Update all data from the cluster. + self._last_response_time = time() if self._received_printers != status.printers: self._received_printers = status.printers self._updatePrinters(status.printers) @@ -289,7 +291,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## Requests the print to be sent to the printer when we finished uploading the mesh. # \param job_id: The ID of the job. def _onPrintJobUploaded(self, job_id: str) -> None: - self._api.requestPrint(self._device_id, job_id, self._onUploadSuccess) + self._progress.update(100) + self._api.requestPrint(self._device_id, job_id, self._onPrintRequested) ## Displays the given message if uploading the mesh has failed # \param message: The message to display. @@ -304,7 +307,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## Shows a message when the upload has succeeded # \param response: The response from the cloud API. - def _onUploadSuccess(self, response: CloudPrintResponse) -> None: + def _onPrintRequested(self, response: CloudPrintResponse) -> None: Logger.log("i", "The cluster will be printing this print job with the ID %s", response.cluster_job_id) self._progress.hide() Message( @@ -312,7 +315,6 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): title = T.UPLOAD_SUCCESS_TITLE, lifetime = 5 ).show() - self._sending_job = False # the upload has finished so we're not sending a job anymore self.writeFinished.emit() ## Gets the remote printers. diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index c9b30d7c79..68b5f99bba 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -26,7 +26,7 @@ class CloudOutputDeviceManager: META_CLUSTER_ID = "um_cloud_cluster_id" # The interval with which the remote clusters are checked - CHECK_CLUSTER_INTERVAL = 5.0 # seconds + CHECK_CLUSTER_INTERVAL = 50.0 # seconds # The translation catalog for this device. I18N_CATALOG = i18nCatalog("cura") @@ -39,26 +39,22 @@ class CloudOutputDeviceManager: self._output_device_manager = application.getOutputDeviceManager() self._account = application.getCuraAPI().account # type: Account - self._account.loginStateChanged.connect(self._onLoginStateChanged) self._api = CloudApiClient(self._account, self._onApiError) - # When switching machines we check if we have to activate a remote cluster. - application.globalContainerStackChanged.connect(self._connectToActiveMachine) - # create a timer to update the remote cluster list self._update_timer = QTimer(application) self._update_timer.setInterval(int(self.CHECK_CLUSTER_INTERVAL * 1000)) self._update_timer.setSingleShot(False) - self._update_timer.timeout.connect(self._getRemoteClusters) - # Make sure the timer is started in case we missed the loginChanged signal - self._onLoginStateChanged(self._account.isLoggedIn) + self._running = False # Called when the uses logs in or out def _onLoginStateChanged(self, is_logged_in: bool) -> None: + Logger.log("i", "Log in state changed to %s", is_logged_in) if is_logged_in: if not self._update_timer.isActive(): self._update_timer.start() + self._getRemoteClusters() else: if self._update_timer.isActive(): self._update_timer.stop() @@ -136,3 +132,25 @@ class CloudOutputDeviceManager: lifetime = 10, dismissable = True ).show() + + def start(self): + if self._running: + return + application = CuraApplication.getInstance() + self._account.loginStateChanged.connect(self._onLoginStateChanged) + # When switching machines we check if we have to activate a remote cluster. + application.globalContainerStackChanged.connect(self._connectToActiveMachine) + self._update_timer.timeout.connect(self._getRemoteClusters) + self._api.start() + self._onLoginStateChanged(is_logged_in = self._account.isLoggedIn) + + def stop(self): + if not self._running: + return + application = CuraApplication.getInstance() + self._account.loginStateChanged.disconnect(self._onLoginStateChanged) + # When switching machines we check if we have to activate a remote cluster. + application.globalContainerStackChanged.disconnect(self._connectToActiveMachine) + self._update_timer.timeout.disconnect(self._getRemoteClusters) + self._api.stop() + self._onLoginStateChanged(is_logged_in = False) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/ResumableUpload.py b/plugins/UM3NetworkPrinting/src/Cloud/ResumableUpload.py index 52b8e5c2d7..e2052c33c8 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/ResumableUpload.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/ResumableUpload.py @@ -51,44 +51,69 @@ class ResumableUpload(NetworkClient): return self._sent_bytes, last_byte def start(self) -> None: + super().start() + if self._finished: + self._sent_bytes = 0 + self._retries = 0 + self._finished = False self._uploadChunk() + def stop(self): + super().stop() + Logger.log("i", "Stopped uploading") + self._finished = True + def _uploadChunk(self) -> None: if self._finished: raise ValueError("The upload is already finished") first_byte, last_byte = self._chunkRange() - Logger.log("i", "PUT %s - %s", first_byte, last_byte) - self.put(self._url, data = self._data[first_byte:last_byte], content_type = self._content_type, - on_finished = self.finishedCallback, on_progress = self.progressCallback) + # self.put(self._url, data = self._data[first_byte:last_byte], content_type = self._content_type, + # on_finished = self.finishedCallback, on_progress = self._progressCallback) + request = self._createEmptyRequest(self._url, content_type=self._content_type) - def progressCallback(self, bytes_sent: int, bytes_total: int) -> None: + reply = self._manager.put(request, self._data[first_byte:last_byte]) + reply.finished.connect(lambda: self._finishedCallback(reply)) + reply.uploadProgress.connect(self._progressCallback) + reply.error.connect(self._errorCallback) + if reply.isFinished(): + self._finishedCallback(reply) + + def _progressCallback(self, bytes_sent: int, bytes_total: int) -> None: + Logger.log("i", "Progress callback %s / %s", bytes_sent, bytes_total) if bytes_total: self._on_progress(int((self._sent_bytes + bytes_sent) / len(self._data) * 100)) - def finishedCallback(self, reply: QNetworkReply) -> None: + def _errorCallback(self, reply: QNetworkReply) -> None: + body = bytes(reply.readAll()).decode() + Logger.log("e", "Received error while uploading: %s", body) + self.stop() + self._on_error() + + def _finishedCallback(self, reply: QNetworkReply) -> None: + Logger.log("i", "Finished callback %s %s", + reply.attribute(QNetworkRequest.HttpStatusCodeAttribute), reply.url().toString()) + status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) if self._retries < self.MAX_RETRIES and status_code in self.RETRY_HTTP_CODES: self._retries += 1 - Logger.log("i", "Retrying %s/%s request %s", tries, self.MAX_RETRIES, request.url) + Logger.log("i", "Retrying %s/%s request %s", self._retries, self.MAX_RETRIES, reply.url().toString()) self._uploadChunk() return + if status_code > 308: + self._errorCallback(reply) + return + body = bytes(reply.readAll()).decode() Logger.log("w", "status_code: %s, Headers: %s, body: %s", status_code, [bytes(header).decode() for header in reply.rawHeaderList()], body) - if status_code > 308: - self._finished = True - Logger.log("e", "Received error while uploading: %s", body) - self._on_error() - return - first_byte, last_byte = self._chunkRange() self._sent_bytes += last_byte - first_byte - self._finished = self._sent_bytes >= len(self._data) - if self._finished: + if self._sent_bytes >= len(self._data): + self.stop() self._on_finished() else: self._uploadChunk() diff --git a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py index 6a80ae046e..52fbf31e3c 100644 --- a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py +++ b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py @@ -86,6 +86,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): ## Start looking for devices on network. def start(self): self.startDiscovery() + self._cloud_output_device_manager.start() def startDiscovery(self): self.stop() @@ -142,6 +143,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): if self._zero_conf is not None: Logger.log("d", "zeroconf close...") self._zero_conf.close() + self._cloud_output_device_manager.stop() def removeManualDevice(self, key, address = None): if key in self._discovered_devices: From a02bccf74d587793796c1737de455e74856cdff8 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 14 Dec 2018 13:00:03 +0100 Subject: [PATCH 0948/1292] Fix NozzleModel to work with new ListModel data update CURA-6015 ListModels should not modify items directly. All ListModels should use setItems() and the insertions/removals/modifications will be done in setItems() itself. --- cura/Machines/Models/NozzleModel.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/cura/Machines/Models/NozzleModel.py b/cura/Machines/Models/NozzleModel.py index 9d97106d6b..785ff5b9b9 100644 --- a/cura/Machines/Models/NozzleModel.py +++ b/cura/Machines/Models/NozzleModel.py @@ -33,8 +33,6 @@ class NozzleModel(ListModel): def _update(self): Logger.log("d", "Updating {model_class_name}.".format(model_class_name = self.__class__.__name__)) - self.items.clear() - global_stack = self._machine_manager.activeMachine if global_stack is None: self.setItems([]) From 8a4a1c9d49ab684a8bfdadfd87166fb494463277 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 14 Dec 2018 13:18:00 +0100 Subject: [PATCH 0949/1292] Don't let print info take space if invisible This way there is a little bit more space for the text 'No time estimation available', which was previously abbreviated to 'No time estimation availa...'. --- resources/qml/ActionPanel/OutputProcessWidget.qml | 2 +- resources/qml/ActionPanel/PrintInformationWidget.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/ActionPanel/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml index 3f53abf28f..ad5a708898 100644 --- a/resources/qml/ActionPanel/OutputProcessWidget.qml +++ b/resources/qml/ActionPanel/OutputProcessWidget.qml @@ -41,7 +41,7 @@ Column { left: parent.left right: printInformationPanel.left - rightMargin: UM.Theme.getSize("thin_margin").height + rightMargin: printInformationPanel.visible ? UM.Theme.getSize("thin_margin").width : 0 } Cura.IconWithText diff --git a/resources/qml/ActionPanel/PrintInformationWidget.qml b/resources/qml/ActionPanel/PrintInformationWidget.qml index 0826e2c715..2e108b05d7 100644 --- a/resources/qml/ActionPanel/PrintInformationWidget.qml +++ b/resources/qml/ActionPanel/PrintInformationWidget.qml @@ -12,7 +12,7 @@ UM.RecolorImage id: widget source: UM.Theme.getIcon("info") - width: UM.Theme.getSize("section_icon").width + width: visible ? UM.Theme.getSize("section_icon").width : 0 height: UM.Theme.getSize("section_icon").height color: UM.Theme.getColor("icon") From a010823a4e39902d0bfadb807edeb180e649b108 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 14 Dec 2018 13:20:43 +0100 Subject: [PATCH 0950/1292] Fix warning when active stage is not yet instantiated Edit: Originally this was more or less the same fix as what Diego just did at the same time, which caused a merge conflict, but I think my solution is more elegant than the ternary operator that was originally there so I'm keeping mine. --- resources/qml/MainWindow/MainWindowHeader.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/MainWindow/MainWindowHeader.qml b/resources/qml/MainWindow/MainWindowHeader.qml index 8f6957d9cd..eecf2a1e73 100644 --- a/resources/qml/MainWindow/MainWindowHeader.qml +++ b/resources/qml/MainWindow/MainWindowHeader.qml @@ -54,7 +54,7 @@ Item { text: model.name.toUpperCase() checkable: true - checked: UM.Controller.activeStage != null ? model.id == UM.Controller.activeStage.stageId : false + checked: UM.Controller.activeStage !== null && model.id == UM.Controller.activeStage.stageId anchors.verticalCenter: parent.verticalCenter exclusiveGroup: mainWindowHeaderMenuGroup From d379f9477508ad1c248ba308d551e5f3bb97909b Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 14 Dec 2018 13:23:28 +0100 Subject: [PATCH 0951/1292] Make the dark theme a bit more readable --- resources/qml/ExtruderIcon.qml | 2 +- .../qml/PrintSetupSelector/Custom/CustomPrintSetup.qml | 2 ++ resources/themes/cura-dark/theme.json | 10 +++++----- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/resources/qml/ExtruderIcon.qml b/resources/qml/ExtruderIcon.qml index c44b6e0fa3..fcc49c9040 100644 --- a/resources/qml/ExtruderIcon.qml +++ b/resources/qml/ExtruderIcon.qml @@ -49,7 +49,7 @@ Item anchors.centerIn: parent text: index + 1 font: UM.Theme.getFont("very_small") - color: UM.Theme.getColor("text") + color: UM.Theme.getColor("text") width: contentWidth height: contentHeight visible: extruderEnabled diff --git a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml index b28c9ceb46..26ca4deec6 100644 --- a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml +++ b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml @@ -113,9 +113,11 @@ Item } z: tabBar.z - 1 // Don't show the border when only one extruder + border.color: tabBar.visible ? UM.Theme.getColor("lining") : "transparent" border.width: UM.Theme.getSize("default_lining").width + color: UM.Theme.getColor("main_background") Cura.SettingView { anchors diff --git a/resources/themes/cura-dark/theme.json b/resources/themes/cura-dark/theme.json index 2fa96c8897..cade342488 100644 --- a/resources/themes/cura-dark/theme.json +++ b/resources/themes/cura-dark/theme.json @@ -99,11 +99,11 @@ "scrollbar_handle_hover": [255, 255, 255, 255], "scrollbar_handle_down": [255, 255, 255, 255], - "setting_category": [39, 44, 48, 255], - "setting_category_disabled": [39, 44, 48, 255], - "setting_category_hover": [39, 44, 48, 255], - "setting_category_active": [39, 44, 48, 255], - "setting_category_active_hover": [39, 44, 48, 255], + "setting_category": [75, 80, 83, 255], + "setting_category_disabled": [75, 80, 83, 255], + "setting_category_hover": [75, 80, 83, 255], + "setting_category_active": [75, 80, 83, 255], + "setting_category_active_hover": [75, 80, 83, 255], "setting_category_text": [255, 255, 255, 152], "setting_category_disabled_text": [255, 255, 255, 101], "setting_category_hover_text": [255, 255, 255, 204], From 475b008310376d0e26fe7649aef870baa0a366e1 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 14 Dec 2018 13:27:26 +0100 Subject: [PATCH 0952/1292] Reduce minimum window size slightly This way it just fits on the screen of a 13 inch MacBook Air. --- resources/themes/cura-light/theme.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index b64190dd23..965fe63179 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -349,7 +349,7 @@ }, "sizes": { - "window_minimum_size": [106, 66], + "window_minimum_size": [100, 60], "main_window_header": [0.0, 4.0], "main_window_header_button": [8, 2.35], From 2f08854097dcf3895e2d320752c8afa6a67296f1 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 14 Dec 2018 14:50:15 +0100 Subject: [PATCH 0953/1292] STAR-322: Using QNetworkReply.finished signal instead of QNetworkAccessManager.finished --- cura/NetworkClient.py | 73 ++++++------------- .../src/Cloud/CloudApiClient.py | 32 +++++--- .../src/Cloud/CloudOutputDevice.py | 2 - .../src/Cloud/CloudOutputDeviceManager.py | 11 ++- .../src/Cloud/ResumableUpload.py | 54 +++++++------- .../tests/Cloud/NetworkManagerMock.py | 23 +++++- .../tests/Cloud/TestCloudApiClient.py | 55 ++++++-------- .../tests/Cloud/TestCloudOutputDevice.py | 21 +++--- .../Cloud/TestCloudOutputDeviceManager.py | 45 ++++++------ 9 files changed, 152 insertions(+), 164 deletions(-) diff --git a/cura/NetworkClient.py b/cura/NetworkClient.py index b455d03db0..4c43e58c4f 100644 --- a/cura/NetworkClient.py +++ b/cura/NetworkClient.py @@ -1,9 +1,9 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. from time import time -from typing import Optional, Dict, Callable, List, Union, Tuple +from typing import Optional, Dict, Callable, List, Union -from PyQt5.QtCore import QUrl +from PyQt5.QtCore import QUrl, QObject from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkReply, QHttpMultiPart, QNetworkRequest, QHttpPart, \ QAuthenticator @@ -13,9 +13,10 @@ from UM.Logger import Logger ## Abstraction of QNetworkAccessManager for easier networking in Cura. # This was originally part of NetworkedPrinterOutputDevice but was moved out for re-use in other classes. -class NetworkClient: +class NetworkClient(QObject): def __init__(self) -> None: + super().__init__() # Network manager instance to use for this client. self._manager = None # type: Optional[QNetworkAccessManager] @@ -29,11 +30,6 @@ class NetworkClient: application = Application.getInstance() self._user_agent = "%s/%s " % (application.getApplicationName(), application.getVersion()) - # Uses to store callback methods for finished network requests. - # This allows us to register network calls with a callback directly instead of having to dissect the reply. - # The key is created out of a tuple (operation, url) - self._on_finished_callbacks = {} # type: Dict[Tuple[int, str], Callable[[QNetworkReply], None]] - # QHttpMultiPart objects need to be kept alive and not garbage collected during the # HTTP which uses them. We hold references to these QHttpMultiPart objects here. self._kept_alive_multiparts = {} # type: Dict[QNetworkReply, QHttpMultiPart] @@ -43,7 +39,6 @@ class NetworkClient: if self._manager: return self._manager = QNetworkAccessManager() - self._manager.finished.connect(self._handleOnFinished) self._last_manager_create_time = time() self._manager.authenticationRequired.connect(self._onAuthenticationRequired) @@ -51,7 +46,6 @@ class NetworkClient: def stop(self) -> None: if not self._manager: return - self._manager.finished.disconnect(self._handleOnFinished) self._manager.authenticationRequired.disconnect(self._onAuthenticationRequired) self._manager = None @@ -69,32 +63,6 @@ class NetworkClient: self._last_request_time = time() return request - ## Executes the correct callback method when a network request finishes. - def _handleOnFinished(self, reply: QNetworkReply) -> None: - - Logger.log("i", "On finished %s %s", reply.attribute(QNetworkRequest.HttpStatusCodeAttribute), reply.url().toString()) - - # Due to garbage collection, we need to cache certain bits of post operations. - # As we don't want to keep them around forever, delete them if we get a reply. - if reply.operation() == QNetworkAccessManager.PostOperation: - self._clearCachedMultiPart(reply) - - # No status code means it never even reached remote. - if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) is None: - return - - # Not used by this class itself, but children might need it for better network handling. - # An example of this is the _update method in the NetworkedPrinterOutputDevice. - self._last_response_time = time() - - # Find the right callback and execute it. - # It always takes the full reply as single parameter. - callback_key = reply.operation(), reply.url().toString() - if callback_key in self._on_finished_callbacks: - self._on_finished_callbacks[callback_key](reply) - else: - Logger.log("w", "Received reply to URL %s but no callbacks are registered", reply.url()) - ## Removes all cached Multi-Part items. def _clearCachedMultiPart(self, reply: QNetworkReply) -> None: if reply in self._kept_alive_multiparts: @@ -105,12 +73,6 @@ class NetworkClient: def _onAuthenticationRequired(reply: QNetworkReply, authenticator: QAuthenticator) -> None: Logger.log("w", "Request to {} required authentication but was not given".format(reply.url().toString())) - ## Register a method to be executed when the associated network request finishes. - def _registerOnFinishedCallback(self, reply: QNetworkReply, - on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: - if on_finished is not None: - self._on_finished_callbacks[reply.operation(), reply.url().toString()] = on_finished - ## Add a part to a Multi-Part form. @staticmethod def _createFormPart(content_header: str, data: bytes, content_type: Optional[str] = None) -> QHttpPart: @@ -144,13 +106,10 @@ class NetworkClient: body = data if isinstance(data, bytes) else data.encode() # type: bytes reply = self._manager.put(request, body) - self._registerOnFinishedCallback(reply, on_finished) - + callback = self._createCallback(reply, on_finished) + reply.finished.connect(callback) if on_progress is not None: - # TODO: Do we need to disconnect() as well? reply.uploadProgress.connect(on_progress) - reply.finished.connect(lambda r: Logger.log("i", "On finished %s %s", url, r)) - reply.error.connect(lambda r: Logger.log("i", "On error %s %s", url, r)) ## Sends a delete request to the given path. # url: The path after the API prefix. @@ -158,7 +117,8 @@ class NetworkClient: def delete(self, url: str, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: request = self._createEmptyRequest(url) reply = self._manager.deleteResource(request) - self._registerOnFinishedCallback(reply, on_finished) + callback = self._createCallback(reply, on_finished) + reply.finished.connect(callback) ## Sends a get request to the given path. # \param url: The path after the API prefix. @@ -166,7 +126,8 @@ class NetworkClient: def get(self, url: str, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: request = self._createEmptyRequest(url) reply = self._manager.get(request) - self._registerOnFinishedCallback(reply, on_finished) + callback = self._createCallback(reply, on_finished) + reply.finished.connect(callback) ## Sends a post request to the given path. # \param url: The path after the API prefix. @@ -180,9 +141,10 @@ class NetworkClient: body = data if isinstance(data, bytes) else data.encode() # type: bytes reply = self._manager.post(request, body) + callback = self._createCallback(reply, on_finished) + reply.finished.connect(callback) if on_progress is not None: reply.uploadProgress.connect(on_progress) - self._registerOnFinishedCallback(reply, on_finished) ## Does a POST request with form data to the given URL. def postForm(self, url: str, header_data: str, body_data: bytes, @@ -205,10 +167,19 @@ class NetworkClient: reply = self._manager.post(request, multi_post_part) + def callback(): + on_finished(reply) + self._clearCachedMultiPart(reply) + + reply.finished.connect(callback) + self._kept_alive_multiparts[reply] = multi_post_part if on_progress is not None: reply.uploadProgress.connect(on_progress) - self._registerOnFinishedCallback(reply, on_finished) return reply + + @staticmethod + def _createCallback(reply: QNetworkReply, on_finished: Optional[Callable[[QNetworkReply], None]] = None): + return lambda: on_finished(reply) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py index 2637f17010..7c3c08e044 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py @@ -4,11 +4,11 @@ import json from json import JSONDecodeError from typing import Callable, List, Type, TypeVar, Union, Optional, Tuple, Dict, Any -from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply +from PyQt5.QtCore import QObject, QUrl +from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply, QNetworkAccessManager from UM.Logger import Logger from cura.API import Account -from cura.NetworkClient import NetworkClient from .ResumableUpload import ResumableUpload from ..Models import BaseModel from .Models.CloudClusterResponse import CloudClusterResponse @@ -21,7 +21,7 @@ from .Models.CloudPrintJobResponse import CloudPrintJobResponse ## The cloud API client is responsible for handling the requests and responses from the cloud. # Each method should only handle models instead of exposing Any HTTP details. -class CloudApiClient(NetworkClient): +class CloudApiClient: # The cloud URL to use for this remote cluster. # TODO: Make sure that this URL goes to the live api before release @@ -34,6 +34,7 @@ class CloudApiClient(NetworkClient): # \param on_error: The callback to be called whenever we receive errors from the server. def __init__(self, account: Account, on_error: Callable[[List[CloudErrorObject]], None]) -> None: super().__init__() + self._manager = QNetworkAccessManager() self._account = account self._on_error = on_error @@ -46,14 +47,18 @@ class CloudApiClient(NetworkClient): # \param on_finished: The function to be called after the result is parsed. def getClusters(self, on_finished: Callable[[List[CloudClusterResponse]], Any]) -> None: url = "{}/clusters".format(self.CLUSTER_API_ROOT) - self.get(url, on_finished=self._wrapCallback(on_finished, CloudClusterResponse)) + reply = self._manager.get(self._createEmptyRequest(url)) + callback = self._wrapCallback(reply, on_finished, CloudClusterResponse) + reply.finished.connect(callback) ## Retrieves the status of the given cluster. # \param cluster_id: The ID of the cluster. # \param on_finished: The function to be called after the result is parsed. def getClusterStatus(self, cluster_id: str, on_finished: Callable[[CloudClusterStatus], Any]) -> None: url = "{}/clusters/{}/status".format(self.CLUSTER_API_ROOT, cluster_id) - self.get(url, on_finished=self._wrapCallback(on_finished, CloudClusterStatus)) + reply = self._manager.get(self._createEmptyRequest(url)) + callback = self._wrapCallback(reply, on_finished, CloudClusterStatus) + reply.finished.connect(callback) ## Requests the cloud to register the upload of a print job mesh. # \param request: The request object. @@ -62,7 +67,9 @@ class CloudApiClient(NetworkClient): ) -> None: url = "{}/jobs/upload".format(self.CURA_API_ROOT) body = json.dumps({"data": request.toDict()}) - self.put(url, body, on_finished=self._wrapCallback(on_finished, CloudPrintJobResponse)) + reply = self._manager.put(self._createEmptyRequest(url), body.encode()) + callback = self._wrapCallback(reply, on_finished, CloudPrintJobResponse) + reply.finished.connect(callback) ## Requests the cloud to register the upload of a print job mesh. # \param upload_response: The object received after requesting an upload with `self.requestUpload`. @@ -72,7 +79,7 @@ class CloudApiClient(NetworkClient): # \param on_error: A function to be called if the upload fails. It receives a dict with the error. def uploadMesh(self, upload_response: CloudPrintJobResponse, mesh: bytes, on_finished: Callable[[], Any], on_progress: Callable[[int], Any], on_error: Callable[[], Any]): - ResumableUpload(upload_response.upload_url, upload_response.content_type, mesh, on_finished, + ResumableUpload(self._manager, upload_response.upload_url, upload_response.content_type, mesh, on_finished, on_progress, on_error).start() # Requests a cluster to print the given print job. @@ -81,13 +88,17 @@ class CloudApiClient(NetworkClient): # \param on_finished: The function to be called after the result is parsed. def requestPrint(self, cluster_id: str, job_id: str, on_finished: Callable[[CloudPrintResponse], Any]) -> None: url = "{}/clusters/{}/print/{}".format(self.CLUSTER_API_ROOT, cluster_id, job_id) - self.post(url, data = "", on_finished=self._wrapCallback(on_finished, CloudPrintResponse)) + reply = self._manager.post(self._createEmptyRequest(url), b"") + callback = self._wrapCallback(reply, on_finished, CloudPrintResponse) + reply.finished.connect(callback) ## We override _createEmptyRequest in order to add the user credentials. # \param url: The URL to request # \param content_type: The type of the body contents. def _createEmptyRequest(self, path: str, content_type: Optional[str] = "application/json") -> QNetworkRequest: - request = super()._createEmptyRequest(path, content_type) + request = QNetworkRequest(QUrl(path)) + if content_type: + request.setHeader(QNetworkRequest.ContentTypeHeader, content_type) if self._account.isLoggedIn: request.setRawHeader(b"Authorization", "Bearer {}".format(self._account.accessToken).encode()) Logger.log("i", "Created request for URL %s. Logged in = %s", path, self._account.isLoggedIn) @@ -132,10 +143,11 @@ class CloudApiClient(NetworkClient): # \param model: The type of the model to convert the response to. It may either be a single record or a list. # \return: A function that can be passed to the def _wrapCallback(self, + reply: QNetworkReply, on_finished: Callable[[Union[Model, List[Model]]], Any], model: Type[Model], ) -> Callable[[QNetworkReply], None]: - def parse(reply: QNetworkReply) -> None: + def parse() -> None: status_code, response = self._parseReply(reply) return self._parseModels(response, on_finished, model) return parse diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 83b5bed16b..09677d5e48 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -172,8 +172,6 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): if self._last_response_time and time() - self._last_response_time < self.CHECK_CLUSTER_INTERVAL: return # avoid calling the cloud too often - Logger.log("i", "Requesting update for %s after %s", self._device_id, - self._last_response_time and time() - self._last_response_time) if self._account.isLoggedIn: self.setAuthenticationState(AuthState.Authenticated) self._api.getClusterStatus(self._device_id, self._onStatusCallFinished) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 68b5f99bba..af80907f01 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -125,13 +125,14 @@ class CloudOutputDeviceManager: ## Handles an API error received from the cloud. # \param errors: The errors received def _onApiError(self, errors: List[CloudErrorObject]) -> None: - message = ". ".join(e.title for e in errors) # TODO: translate errors - Message( - text = message, + text = ". ".join(e.title for e in errors) # TODO: translate errors + message = Message( + text = text, title = self.I18N_CATALOG.i18nc("@info:title", "Error"), lifetime = 10, dismissable = True - ).show() + ) + message.show() def start(self): if self._running: @@ -141,7 +142,6 @@ class CloudOutputDeviceManager: # When switching machines we check if we have to activate a remote cluster. application.globalContainerStackChanged.connect(self._connectToActiveMachine) self._update_timer.timeout.connect(self._getRemoteClusters) - self._api.start() self._onLoginStateChanged(is_logged_in = self._account.isLoggedIn) def stop(self): @@ -152,5 +152,4 @@ class CloudOutputDeviceManager: # When switching machines we check if we have to activate a remote cluster. application.globalContainerStackChanged.disconnect(self._connectToActiveMachine) self._update_timer.timeout.disconnect(self._getRemoteClusters) - self._api.stop() self._onLoginStateChanged(is_logged_in = False) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/ResumableUpload.py b/plugins/UM3NetworkPrinting/src/Cloud/ResumableUpload.py index e2052c33c8..5e3bc9545e 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/ResumableUpload.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/ResumableUpload.py @@ -1,14 +1,14 @@ # Copyright (c) 2018 Ultimaker B.V. # !/usr/bin/env python # -*- coding: utf-8 -*- -from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply +from PyQt5.QtCore import QUrl +from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply, QNetworkAccessManager from typing import Optional, Callable, Any, Tuple from UM.Logger import Logger -from cura.NetworkClient import NetworkClient -class ResumableUpload(NetworkClient): +class ResumableUpload: MAX_RETRIES = 10 BYTES_PER_REQUEST = 256 * 1024 RETRY_HTTP_CODES = {500, 502, 503, 504} @@ -18,9 +18,9 @@ class ResumableUpload(NetworkClient): # \param content_length: The total content length of the file, in bytes. # \param http_method: The HTTP method to be used, e.g. "POST" or "PUT". # \param timeout: The timeout for each chunk upload. Important: If None, no timeout is applied at all. - def __init__(self, url: str, content_type: str, data: bytes, + def __init__(self, manager: QNetworkAccessManager, url: str, content_type: str, data: bytes, on_finished: Callable[[], Any], on_progress: Callable[[int], Any], on_error: Callable[[], Any]): - super().__init__() + self._manager = manager self._url = url self._content_type = content_type self._data = data @@ -32,13 +32,15 @@ class ResumableUpload(NetworkClient): self._sent_bytes = 0 self._retries = 0 self._finished = False + self._reply = None # type: Optional[QNetworkReply] - ## We override _createEmptyRequest in order to add the user credentials. + ## We override _createRequest in order to add the user credentials. # \param url: The URL to request # \param content_type: The type of the body contents. - def _createEmptyRequest(self, path: str, content_type: Optional[str] = "application/json") -> QNetworkRequest: - request = super()._createEmptyRequest(path, content_type = self._content_type) - + def _createRequest(self) -> QNetworkRequest: + request = QNetworkRequest(QUrl(self._url)) + request.setHeader(QNetworkRequest.ContentTypeHeader, self._content_type) + first_byte, last_byte = self._chunkRange() content_range = "bytes {}-{}/{}".format(first_byte, last_byte - 1, len(self._data)) request.setRawHeader(b"Content-Range", content_range.encode()) @@ -51,7 +53,6 @@ class ResumableUpload(NetworkClient): return self._sent_bytes, last_byte def start(self) -> None: - super().start() if self._finished: self._sent_bytes = 0 self._retries = 0 @@ -59,7 +60,6 @@ class ResumableUpload(NetworkClient): self._uploadChunk() def stop(self): - super().stop() Logger.log("i", "Stopped uploading") self._finished = True @@ -68,47 +68,43 @@ class ResumableUpload(NetworkClient): raise ValueError("The upload is already finished") first_byte, last_byte = self._chunkRange() - # self.put(self._url, data = self._data[first_byte:last_byte], content_type = self._content_type, - # on_finished = self.finishedCallback, on_progress = self._progressCallback) - request = self._createEmptyRequest(self._url, content_type=self._content_type) + request = self._createRequest() - reply = self._manager.put(request, self._data[first_byte:last_byte]) - reply.finished.connect(lambda: self._finishedCallback(reply)) - reply.uploadProgress.connect(self._progressCallback) - reply.error.connect(self._errorCallback) - if reply.isFinished(): - self._finishedCallback(reply) + self._reply = self._manager.put(request, self._data[first_byte:last_byte]) + self._reply.finished.connect(self._finishedCallback) + self._reply.uploadProgress.connect(self._progressCallback) + self._reply.error.connect(self._errorCallback) def _progressCallback(self, bytes_sent: int, bytes_total: int) -> None: Logger.log("i", "Progress callback %s / %s", bytes_sent, bytes_total) if bytes_total: self._on_progress(int((self._sent_bytes + bytes_sent) / len(self._data) * 100)) - def _errorCallback(self, reply: QNetworkReply) -> None: - body = bytes(reply.readAll()).decode() + def _errorCallback(self) -> None: + body = bytes(self._reply.readAll()).decode() Logger.log("e", "Received error while uploading: %s", body) self.stop() self._on_error() - def _finishedCallback(self, reply: QNetworkReply) -> None: + def _finishedCallback(self) -> None: Logger.log("i", "Finished callback %s %s", - reply.attribute(QNetworkRequest.HttpStatusCodeAttribute), reply.url().toString()) + self._reply.attribute(QNetworkRequest.HttpStatusCodeAttribute), self._reply.url().toString()) - status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) + status_code = self._reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) if self._retries < self.MAX_RETRIES and status_code in self.RETRY_HTTP_CODES: self._retries += 1 - Logger.log("i", "Retrying %s/%s request %s", self._retries, self.MAX_RETRIES, reply.url().toString()) + Logger.log("i", "Retrying %s/%s request %s", self._retries, self.MAX_RETRIES, self._reply.url().toString()) self._uploadChunk() return if status_code > 308: - self._errorCallback(reply) + self._errorCallback() return - body = bytes(reply.readAll()).decode() + body = bytes(self._reply.readAll()).decode() Logger.log("w", "status_code: %s, Headers: %s, body: %s", status_code, - [bytes(header).decode() for header in reply.rawHeaderList()], body) + [bytes(header).decode() for header in self._reply.rawHeaderList()], body) first_byte, last_byte = self._chunkRange() self._sent_bytes += last_byte - first_byte diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py b/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py index 60627cbe7c..59b79fdfa6 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py @@ -4,12 +4,27 @@ import json from typing import Dict, Tuple, Union, Optional from unittest.mock import MagicMock -from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkReply, QNetworkRequest +from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest from UM.Logger import Logger from UM.Signal import Signal +class FakeSignal: + def __init__(self): + self._callbacks = [] + + def connect(self, callback): + self._callbacks.append(callback) + + def disconnect(self, callback): + self._callbacks.remove(callback) + + def emit(self, *args, **kwargs): + for callback in self._callbacks: + callback(*args, **kwargs) + + ## This class can be used to mock the QNetworkManager class and test the code using it. # After patching the QNetworkManager class, requests are prepared before they can be executed. # Any requests not prepared beforehand will cause KeyErrors. @@ -27,7 +42,7 @@ class NetworkManagerMock: ## Initializes the network manager mock. def __init__(self) -> None: # a dict with the prepared replies, using the format {(http_method, url): reply} - self.replies = {} # type: Dict[Tuple[str, str], QNetworkReply] + self.replies = {} # type: Dict[Tuple[str, str], MagicMock] self.request_bodies = {} # type: Dict[Tuple[str, str], bytes] # signals used in the network manager. @@ -64,6 +79,8 @@ class NetworkManagerMock: reply_mock.url().toString.return_value = url reply_mock.operation.return_value = self._OPERATIONS[method] reply_mock.attribute.return_value = status_code + reply_mock.finished = FakeSignal() + reply_mock.isFinished.return_value = False reply_mock.readAll.return_value = response if isinstance(response, bytes) else json.dumps(response).encode() self.replies[method, url] = reply_mock Logger.log("i", "Prepared mock {}-response to {} {}", status_code, method, url) @@ -78,6 +95,8 @@ class NetworkManagerMock: def flushReplies(self) -> None: for key, reply in self.replies.items(): Logger.log("i", "Flushing reply to {} {}", *key) + reply.isFinished.return_value = True + reply.finished.emit() self.finished.emit(reply) self.reset() diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py index e377627465..d4044726a3 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py @@ -8,6 +8,8 @@ from unittest.mock import patch, MagicMock from cura.CuraApplication import CuraApplication from src.Cloud.CloudApiClient import CloudApiClient +from src.Cloud.Models.CloudClusterResponse import CloudClusterResponse +from src.Cloud.Models.CloudClusterStatus import CloudClusterStatus from src.Cloud.Models.CloudPrintJobResponse import CloudPrintJobResponse from src.Cloud.Models.CloudPrintJobUploadRequest import CloudPrintJobUploadRequest from src.Cloud.Models.CloudErrorObject import CloudErrorObject @@ -15,7 +17,6 @@ from tests.Cloud.Fixtures import readFixture, parseFixture from .NetworkManagerMock import NetworkManagerMock -@patch("cura.NetworkClient.QNetworkAccessManager") class TestCloudApiClient(TestCase): def _errorHandler(self, errors: List[CloudErrorObject]): raise Exception("Received unexpected error: {}".format(errors)) @@ -27,15 +28,14 @@ class TestCloudApiClient(TestCase): self.app = CuraApplication.getInstance() self.network = NetworkManagerMock() - self.api = CloudApiClient(self.account, self._errorHandler) - - def test_GetClusters(self, network_mock): - network_mock.return_value = self.network + with patch("src.Cloud.CloudApiClient.QNetworkAccessManager", return_value = self.network): + self.api = CloudApiClient(self.account, self._errorHandler) + def test_getClusters(self): result = [] - with open("{}/Fixtures/getClusters.json".format(os.path.dirname(__file__)), "rb") as f: - response = f.read() + response = readFixture("getClusters") + data = parseFixture("getClusters")["data"] self.network.prepareReply("GET", "https://api-staging.ultimaker.com/connect/v1/clusters", 200, response) # the callback is a function that adds the result of the call to getClusters to the result list @@ -43,32 +43,26 @@ class TestCloudApiClient(TestCase): self.network.flushReplies() - self.assertEqual(2, len(result)) - - def test_getClusterStatus(self, network_mock): - network_mock.return_value = self.network + self.assertEqual([CloudClusterResponse(**data[0]), CloudClusterResponse(**data[1])], result) + def test_getClusterStatus(self): result = [] - with open("{}/Fixtures/getClusterStatusResponse.json".format(os.path.dirname(__file__)), "rb") as f: - response = f.read() + response = readFixture("getClusterStatusResponse") + data = parseFixture("getClusterStatusResponse")["data"] self.network.prepareReply("GET", "https://api-staging.ultimaker.com/connect/v1/clusters/R0YcLJwar1ugh0ikEZsZs8NWKV6vJP_LdYsXgXqAcaNC/status", 200, response ) - self.api.getClusterStatus("R0YcLJwar1ugh0ikEZsZs8NWKV6vJP_LdYsXgXqAcaNC", lambda status: result.append(status)) + self.api.getClusterStatus("R0YcLJwar1ugh0ikEZsZs8NWKV6vJP_LdYsXgXqAcaNC", lambda s: result.append(s)) self.network.flushReplies() - self.assertEqual(len(result), 1) - status = result[0] + self.assertEqual([CloudClusterStatus(**data)], result) - self.assertEqual(len(status.printers), 2) - self.assertEqual(len(status.print_jobs), 1) - - def test_requestUpload(self, network_mock): - network_mock.return_value = self.network + def test_requestUpload(self): + results = [] response = readFixture("putJobUploadResponse") @@ -78,11 +72,11 @@ class TestCloudApiClient(TestCase): self.api.requestUpload(request, lambda r: results.append(r)) self.network.flushReplies() - self.assertEqual(results[0].content_type, "text/plain") - self.assertEqual(results[0].status, "uploading") + self.assertEqual(["text/plain"], [r.content_type for r in results]) + self.assertEqual(["uploading"], [r.status for r in results]) - def test_uploadMesh(self, network_mock): - network_mock.return_value = self.network + def test_uploadMesh(self): + results = [] progress = MagicMock() @@ -101,8 +95,8 @@ class TestCloudApiClient(TestCase): self.assertEqual(["sent"], results) - def test_requestPrint(self, network_mock): - network_mock.return_value = self.network + def test_requestPrint(self): + results = [] response = readFixture("postJobPrintResponse") @@ -120,7 +114,6 @@ class TestCloudApiClient(TestCase): self.network.flushReplies() - self.assertEqual(len(results), 1) - self.assertEqual(results[0].job_id, job_id) - self.assertEqual(results[0].cluster_job_id, cluster_job_id) - self.assertEqual(results[0].status, "queued") + self.assertEqual([job_id], [r.job_id for r in results]) + self.assertEqual([cluster_job_id], [r.cluster_job_id for r in results]) + self.assertEqual(["queued"], [r.status for r in results]) diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py index 287f2dda98..c391dc75dd 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py @@ -13,7 +13,6 @@ from tests.Cloud.Fixtures import readFixture, parseFixture from .NetworkManagerMock import NetworkManagerMock -@patch("cura.NetworkClient.QNetworkAccessManager") class TestCloudOutputDevice(TestCase): CLUSTER_ID = "RIZ6cZbWA_Ua7RZVJhrdVfVpf0z-MqaSHQE4v8aRTtYq" JOB_ID = "ABCDefGHIjKlMNOpQrSTUvYxWZ0-1234567890abcDE=" @@ -30,7 +29,9 @@ class TestCloudOutputDevice(TestCase): self.network = NetworkManagerMock() self.account = MagicMock(isLoggedIn=True, accessToken="TestAccessToken") self.onError = MagicMock() - self.device = CloudOutputDevice(CloudApiClient(self.account, self.onError), self.CLUSTER_ID, self.HOST_NAME) + with patch("src.Cloud.CloudApiClient.QNetworkAccessManager", return_value = self.network): + self._api = CloudApiClient(self.account, self.onError) + self.device = CloudOutputDevice(self._api, self.CLUSTER_ID, self.HOST_NAME) self.cluster_status = parseFixture("getClusterStatusResponse") self.network.prepareReply("GET", self.STATUS_URL, 200, readFixture("getClusterStatusResponse")) @@ -38,8 +39,7 @@ class TestCloudOutputDevice(TestCase): super().tearDown() self.network.flushReplies() - def test_status(self, network_mock): - network_mock.return_value = self.network + def test_status(self): self.device._update() self.network.flushReplies() @@ -69,32 +69,34 @@ class TestCloudOutputDevice(TestCase): self.assertEqual({job["name"] for job in self.cluster_status["data"]["print_jobs"]}, {job.name for job in self.device.printJobs}) - def test_remove_print_job(self, network_mock): - network_mock.return_value = self.network + def test_remove_print_job(self): self.device._update() self.network.flushReplies() self.assertEqual(1, len(self.device.printJobs)) self.cluster_status["data"]["print_jobs"].clear() self.network.prepareReply("GET", self.STATUS_URL, 200, self.cluster_status) + + self.device._last_response_time = None self.device._update() self.network.flushReplies() self.assertEqual([], self.device.printJobs) - def test_remove_printers(self, network_mock): - network_mock.return_value = self.network + def test_remove_printers(self): self.device._update() self.network.flushReplies() self.assertEqual(2, len(self.device.printers)) self.cluster_status["data"]["printers"].clear() self.network.prepareReply("GET", self.STATUS_URL, 200, self.cluster_status) + + self.device._last_response_time = None self.device._update() self.network.flushReplies() self.assertEqual([], self.device.printers) @patch("cura.CuraApplication.CuraApplication.getGlobalContainerStack") - def test_print_to_cloud(self, global_container_stack_mock, network_mock): + def test_print_to_cloud(self, global_container_stack_mock): active_machine_mock = global_container_stack_mock.return_value active_machine_mock.getMetaDataEntry.side_effect = {"file_formats": "application/gzip"}.get @@ -104,7 +106,6 @@ class TestCloudOutputDevice(TestCase): self.network.prepareReply("PUT", request_upload_response["data"]["upload_url"], 201, b"{}") self.network.prepareReply("POST", self.PRINT_URL, 200, request_print_response) - network_mock.return_value = self.network file_handler = MagicMock() file_handler.getSupportedFileTypesWrite.return_value = [{ "extension": "gcode.gz", diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py index b6bcde6e55..80dd2c7990 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py @@ -10,7 +10,6 @@ from tests.Cloud.Fixtures import parseFixture, readFixture from .NetworkManagerMock import NetworkManagerMock -@patch("cura.NetworkClient.QNetworkAccessManager") class TestCloudOutputDeviceManager(TestCase): URL = "https://api-staging.ultimaker.com/connect/v1/clusters" @@ -18,13 +17,15 @@ class TestCloudOutputDeviceManager(TestCase): super().setUp() self.app = CuraApplication.getInstance() self.network = NetworkManagerMock() - self.manager = CloudOutputDeviceManager() + with patch("src.Cloud.CloudApiClient.QNetworkAccessManager", return_value = self.network): + self.manager = CloudOutputDeviceManager() self.clusters_response = parseFixture("getClusters") self.network.prepareReply("GET", self.URL, 200, readFixture("getClusters")) def tearDown(self): try: self._beforeTearDown() + self.manager.stop() finally: super().tearDown() @@ -47,17 +48,17 @@ class TestCloudOutputDeviceManager(TestCase): device_manager.removeOutputDevice(device["cluster_id"]) ## Runs the initial request to retrieve the clusters. - def _loadData(self, network_mock): - network_mock.return_value = self.network - self.manager._account.loginStateChanged.emit(True) - self.manager._update_timer.timeout.emit() + def _loadData(self): + self.manager.start() + self.manager._onLoginStateChanged(is_logged_in = True) + self.network.flushReplies() - def test_device_is_created(self, network_mock): + def test_device_is_created(self): # just create the cluster, it is checked at tearDown - self._loadData(network_mock) + self._loadData() - def test_device_is_updated(self, network_mock): - self._loadData(network_mock) + def test_device_is_updated(self): + self._loadData() # update the cluster from member variable, which is checked at tearDown self.clusters_response["data"][0]["host_name"] = "New host name" @@ -65,8 +66,8 @@ class TestCloudOutputDeviceManager(TestCase): self.manager._update_timer.timeout.emit() - def test_device_is_removed(self, network_mock): - self._loadData(network_mock) + def test_device_is_removed(self): + self._loadData() # delete the cluster from member variable, which is checked at tearDown del self.clusters_response["data"][1] @@ -75,41 +76,39 @@ class TestCloudOutputDeviceManager(TestCase): self.manager._update_timer.timeout.emit() @patch("cura.CuraApplication.CuraApplication.getGlobalContainerStack") - def test_device_connects_by_cluster_id(self, global_container_stack_mock, network_mock): + def test_device_connects_by_cluster_id(self, global_container_stack_mock): active_machine_mock = global_container_stack_mock.return_value cluster1, cluster2 = self.clusters_response["data"] cluster_id = cluster1["cluster_id"] active_machine_mock.getMetaDataEntry.side_effect = {"um_cloud_cluster_id": cluster_id}.get - self._loadData(network_mock) - self.network.flushReplies() + self._loadData() self.assertTrue(self.app.getOutputDeviceManager().getOutputDevice(cluster1["cluster_id"]).isConnected()) self.assertFalse(self.app.getOutputDeviceManager().getOutputDevice(cluster2["cluster_id"]).isConnected()) self.assertEquals([], active_machine_mock.setMetaDataEntry.mock_calls) @patch("cura.CuraApplication.CuraApplication.getGlobalContainerStack") - def test_device_connects_by_network_key(self, global_container_stack_mock, network_mock): + def test_device_connects_by_network_key(self, global_container_stack_mock): active_machine_mock = global_container_stack_mock.return_value cluster1, cluster2 = self.clusters_response["data"] network_key = cluster2["host_name"] + ".ultimaker.local" active_machine_mock.getMetaDataEntry.side_effect = {"um_network_key": network_key}.get - self._loadData(network_mock) - self.network.flushReplies() + self._loadData() self.assertFalse(self.app.getOutputDeviceManager().getOutputDevice(cluster1["cluster_id"]).isConnected()) self.assertTrue(self.app.getOutputDeviceManager().getOutputDevice(cluster2["cluster_id"]).isConnected()) active_machine_mock.setMetaDataEntry.assert_called_with("um_cloud_cluster_id", cluster2["cluster_id"]) - @patch("UM.Message.Message.show") - def test_api_error(self, message_mock, network_mock): + @patch("src.Cloud.CloudOutputDeviceManager.Message") + def test_api_error(self, message_mock): self.clusters_response = { "errors": [{"id": "notFound", "title": "Not found!", "http_status": "404", "code": "notFound"}] } self.network.prepareReply("GET", self.URL, 200, self.clusters_response) - self._loadData(network_mock) - self.network.flushReplies() - message_mock.assert_called_once_with() + self._loadData() + message_mock.assert_called_once_with(text='Not found!', title='Error', lifetime=10, dismissable=True) + message_mock.return_value.show.assert_called_once_with() From 7fc5742b7f328b0a46b1708526eaf8bf3f5aba33 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Fri, 14 Dec 2018 15:01:40 +0100 Subject: [PATCH 0954/1292] Add monitor carousel Contributes to CL-1151 --- .../resources/qml/MonitorCarousel.qml | 231 ++++++++++++++++++ .../resources/qml/MonitorPrinterCard.qml | 2 +- .../resources/qml/MonitorStage.qml | 21 +- 3 files changed, 235 insertions(+), 19 deletions(-) create mode 100644 plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml new file mode 100644 index 0000000000..7d56b2f294 --- /dev/null +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml @@ -0,0 +1,231 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.3 +import QtQuick.Controls 2.0 +import QtGraphicalEffects 1.0 +import UM 1.3 as UM + +Item +{ + id: base + + property var currentIndex: 0 + property var tileWidth: 834 * screenScaleFactor // TODO: Theme! + property var tileHeight: 216 * screenScaleFactor // TODO: Theme! + property var tileSpacing: 60 * screenScaleFactor // TODO: Theme! + property var maxOffset: (OutputDevice.printers.length - 1) * (tileWidth + tileSpacing) + + height: centerSection.height + width: maximumWidth + + Item + { + id: leftHint + anchors + { + right: leftButton.left + rightMargin: 12 * screenScaleFactor + left: parent.left + } + height: parent.height + z: 10 + LinearGradient + { + anchors.fill: parent + start: Qt.point(0, 0) + end: Qt.point(leftHint.width, 0) + gradient: Gradient + { + GradientStop + { + position: 0.0 + color: "#fff6f6f6" + } + GradientStop + { + position: 1.0 + color: "#00f6f6f6" + } + } + } + } + + Button + { + id: leftButton + anchors + { + verticalCenter: parent.verticalCenter + right: centerSection.left + rightMargin: 12 * screenScaleFactor + } + width: 36 * screenScaleFactor // TODO: Theme! + height: 72 * screenScaleFactor // TODO: Theme! + visible: currentIndex > 0 + z: 10 + onClicked: navigateTo(currentIndex - 1) + background: Rectangle + { + color: "#ffffff" // TODO: Theme! + border.width: 1 * screenScaleFactor // TODO: Theme! + border.color: "#cccccc" // TODO: Theme! + radius: 2 * screenScaleFactor // TODO: Theme! + } + contentItem: Item + { + anchors.fill: parent + UM.RecolorImage + { + anchors.centerIn: parent + width: 18 + height: 18 + sourceSize.width: 18 + sourceSize.height: 18 + color: "#666666" // TODO: Theme! + source: UM.Theme.getIcon("arrow_left") + } + } + } + + Item + { + id: centerSection + anchors + { + verticalCenter: parent.verticalCenter + horizontalCenter: parent.horizontalCenter + } + width: tileWidth + height: tiles.height + z: 1 + + Row + { + id: tiles + height: childrenRect.height + width: 5 * tileWidth + 4 * tileSpacing + x: 0 + z: 0 + Behavior on x { NumberAnimation { duration: 100 } } + spacing: 60 * screenScaleFactor // TODO: Theme! + + Repeater + { + model: OutputDevice.printers + MonitorPrinterCard + { + printer: modelData + } + } + } + } + + Button + { + id: rightButton + anchors + { + verticalCenter: parent.verticalCenter + left: centerSection.right + leftMargin: 12 * screenScaleFactor + } + width: 36 * screenScaleFactor // TODO: Theme! + height: 72 * screenScaleFactor // TODO: Theme! + z: 10 + visible: currentIndex < OutputDevice.printers.length - 1 + onClicked: navigateTo(currentIndex + 1) + background: Rectangle + { + color: "#ffffff" // TODO: Theme! + border.width: 1 * screenScaleFactor // TODO: Theme! + border.color: "#cccccc" // TODO: Theme! + radius: 2 * screenScaleFactor // TODO: Theme! + } + contentItem: Item + { + anchors.fill: parent + UM.RecolorImage + { + anchors.centerIn: parent + width: 18 + height: 18 + sourceSize.width: 18 + sourceSize.height: 18 + color: "#666666" // TODO: Theme! + source: UM.Theme.getIcon("arrow_right") + } + } + } + + Item + { + id: rightHint + anchors + { + left: rightButton.right + leftMargin: 12 * screenScaleFactor + right: parent.right + } + height: centerSection.height + z: 10 + + LinearGradient + { + anchors.fill: parent + start: Qt.point(0, 0) + end: Qt.point(rightHint.width, 0) + gradient: Gradient + { + GradientStop + { + position: 0.0 + color: "#00f6f6f6" + } + GradientStop + { + position: 1.0 + color: "#fff6f6f6" + } + } + } + } + + Item + { + id: navigationDots + anchors + { + horizontalCenter: centerSection.horizontalCenter + top: centerSection.bottom + topMargin: 36 * screenScaleFactor // TODO: Theme! + } + Row + { + spacing: 8 * screenScaleFactor // TODO: Theme! + Repeater + { + model: OutputDevice.printers + Button + { + background: Rectangle + { + color: model.index == currentIndex ? "#777777" : "#d8d8d8" // TODO: Theme! + radius: Math.floor(width / 2) + width: 12 * screenScaleFactor // TODO: Theme! + height: width + } + onClicked: navigateTo(model.index) + } + } + } + } + + function navigateTo( i ) { + if (i >= 0 && i < OutputDevice.printers.length) + { + tiles.x = -1 * i * (tileWidth + tileSpacing) + currentIndex = i + } + } +} \ No newline at end of file diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml index 1676c51edf..cfeb77cc89 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml @@ -26,7 +26,7 @@ Item property var borderSize: 1 * screenScaleFactor // TODO: Theme, and remove from here width: 834 * screenScaleFactor // TODO: Theme! - height: 216 * screenScaleFactor // TODO: Theme! + height: childrenRect.height // Printer portion Rectangle diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml index 4d59e0eb6b..f77cfee1ef 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml @@ -48,32 +48,17 @@ Component } } - ScrollView + Item { id: printers anchors { - left: queue.left - right: queue.right top: parent.top topMargin: 48 * screenScaleFactor // TODO: Theme! } + width: parent.width height: 264 * screenScaleFactor // TODO: Theme! - - Row - { - spacing: 60 * screenScaleFactor // TODO: Theme! - - Repeater - { - model: OutputDevice.printers - - MonitorPrinterCard - { - printer: modelData - } - } - } + MonitorCarousel {} } Item From 3a74511d231d573e7ed910fb8d51080265740ac4 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 14 Dec 2018 15:01:56 +0100 Subject: [PATCH 0955/1292] Remove padding from views selector This padding made it break the height of the item for some reason. I guess that is a Qt bug. In any case, the padding shouldn't be there either since the lining is on the inside of the child buttons so the padding only causes a gap to appear on the left and right sides, which looks weird. Contributes to issue CURA-6029. --- resources/qml/ViewsSelector.qml | 2 -- 1 file changed, 2 deletions(-) diff --git a/resources/qml/ViewsSelector.qml b/resources/qml/ViewsSelector.qml index 06d2e662b5..acde7d1f71 100644 --- a/resources/qml/ViewsSelector.qml +++ b/resources/qml/ViewsSelector.qml @@ -78,8 +78,6 @@ Cura.ExpandablePopup { id: viewSelectorPopup width: viewSelector.width - 2 * viewSelector.contentPadding - leftPadding: UM.Theme.getSize("default_lining").width - rightPadding: UM.Theme.getSize("default_lining").width // For some reason the height/width of the column gets set to 0 if this is not set... Component.onCompleted: From 5d0da580b9a65c76b9bf21c4d7bcf4470133c1dd Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Fri, 14 Dec 2018 15:04:22 +0100 Subject: [PATCH 0956/1292] Fix border colors --- plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml | 2 +- .../UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml | 2 +- .../UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml b/plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml index 0877a15f00..7778c4e1a2 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml @@ -16,7 +16,7 @@ Item property bool expanded: false property var borderWidth: 1 - property color borderColor: "#EAEAEC" + property color borderColor: "#CCCCCC" property color headerBackgroundColor: "white" property color headerHoverColor: "#f5f5f5" property color drawerBackgroundColor: "white" diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml index d8c5d1ec28..f431ef1c52 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml @@ -26,7 +26,7 @@ Item ExpandableCard { - borderColor: printJob.configurationChanges.length !== 0 ? "#f5a623" : "#EAEAEC" // TODO: Theme! + borderColor: printJob.configurationChanges.length !== 0 ? "#f5a623" : "#CCCCCC" // TODO: Theme! headerItem: Row { height: 48 * screenScaleFactor // TODO: Theme! diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml index cfeb77cc89..038f0535f0 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml @@ -34,7 +34,7 @@ Item id: printerInfo border { - color: "#EAEAEC" // TODO: Theme! + color: "#CCCCCC" // TODO: Theme! width: borderSize // TODO: Remove once themed } color: "white" // TODO: Theme! @@ -151,7 +151,7 @@ Item } border { - color: printer.activePrintJob && printer.activePrintJob.configurationChanges.length > 0 ? "#f5a623" : "#EAEAEC" // TODO: Theme! + color: printer.activePrintJob && printer.activePrintJob.configurationChanges.length > 0 ? "#f5a623" : "#CCCCCC" // TODO: Theme! width: borderSize // TODO: Remove once themed } color: "white" // TODO: Theme! From b2ea597543f58db9e447167f38389e58425237f9 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Fri, 14 Dec 2018 15:10:34 +0100 Subject: [PATCH 0957/1292] Fix button color Contributes to CL-1151 --- plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml index 7d56b2f294..49d35f794f 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml @@ -82,7 +82,7 @@ Item height: 18 sourceSize.width: 18 sourceSize.height: 18 - color: "#666666" // TODO: Theme! + color: "#152950" // TODO: Theme! source: UM.Theme.getIcon("arrow_left") } } @@ -152,7 +152,7 @@ Item height: 18 sourceSize.width: 18 sourceSize.height: 18 - color: "#666666" // TODO: Theme! + color: "#152950" // TODO: Theme! source: UM.Theme.getIcon("arrow_right") } } From ae695b77e6ad8e9ea882c2b20e6ec4922fa6603a Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 14 Dec 2018 15:23:56 +0100 Subject: [PATCH 0958/1292] Add native rendering for QML Label CURA-6013 --- plugins/Toolbox/resources/qml/SmallRatingWidget.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/Toolbox/resources/qml/SmallRatingWidget.qml b/plugins/Toolbox/resources/qml/SmallRatingWidget.qml index bab219d294..686058f4e8 100644 --- a/plugins/Toolbox/resources/qml/SmallRatingWidget.qml +++ b/plugins/Toolbox/resources/qml/SmallRatingWidget.qml @@ -29,5 +29,6 @@ Row anchors.verticalCenter: starIcon.verticalCenter color: starIcon.color font: UM.Theme.getFont("small") + renderType: Text.NativeRendering } } \ No newline at end of file From 2f6a274c0e2b78064fb9ae8a3c6f7766f8623e1a Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Fri, 14 Dec 2018 15:27:55 +0100 Subject: [PATCH 0959/1292] Small style improvements Contributes to CL-1151 --- .../resources/qml/ExpandableCard.qml | 2 +- .../resources/qml/MonitorCarousel.qml | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml b/plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml index 7778c4e1a2..f86135ae62 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml @@ -18,7 +18,7 @@ Item property var borderWidth: 1 property color borderColor: "#CCCCCC" property color headerBackgroundColor: "white" - property color headerHoverColor: "#f5f5f5" + property color headerHoverColor: "#e8f2fc" property color drawerBackgroundColor: "white" property alias headerItem: header.children property alias drawerItem: drawer.children diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml index 49d35f794f..cd7c6f177f 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml @@ -63,11 +63,12 @@ Item width: 36 * screenScaleFactor // TODO: Theme! height: 72 * screenScaleFactor // TODO: Theme! visible: currentIndex > 0 + hoverEnabled: true z: 10 onClicked: navigateTo(currentIndex - 1) background: Rectangle { - color: "#ffffff" // TODO: Theme! + color: leftButton.hovered ? "#e8f2fc" : "#ffffff" // TODO: Theme! border.width: 1 * screenScaleFactor // TODO: Theme! border.color: "#cccccc" // TODO: Theme! radius: 2 * screenScaleFactor // TODO: Theme! @@ -79,9 +80,9 @@ Item { anchors.centerIn: parent width: 18 - height: 18 - sourceSize.width: 18 - sourceSize.height: 18 + height: width + sourceSize.width: width + sourceSize.height: width color: "#152950" // TODO: Theme! source: UM.Theme.getIcon("arrow_left") } @@ -135,9 +136,10 @@ Item z: 10 visible: currentIndex < OutputDevice.printers.length - 1 onClicked: navigateTo(currentIndex + 1) + hoverEnabled: true background: Rectangle { - color: "#ffffff" // TODO: Theme! + color: rightButton.hovered ? "#e8f2fc" : "#ffffff" // TODO: Theme! border.width: 1 * screenScaleFactor // TODO: Theme! border.color: "#cccccc" // TODO: Theme! radius: 2 * screenScaleFactor // TODO: Theme! @@ -149,9 +151,9 @@ Item { anchors.centerIn: parent width: 18 - height: 18 - sourceSize.width: 18 - sourceSize.height: 18 + height: width + sourceSize.width: width + sourceSize.height: width color: "#152950" // TODO: Theme! source: UM.Theme.getIcon("arrow_right") } From 3bd5d141ab74b9e41f85510add3168604c13f5a8 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Fri, 14 Dec 2018 15:39:17 +0100 Subject: [PATCH 0960/1292] Add easing and make animation less snappy and awesome Contributes to CL-1151 --- .../UM3NetworkPrinting/resources/qml/MonitorCarousel.qml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml index cd7c6f177f..988008dc31 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml @@ -108,7 +108,14 @@ Item width: 5 * tileWidth + 4 * tileSpacing x: 0 z: 0 - Behavior on x { NumberAnimation { duration: 100 } } + Behavior on x + { + NumberAnimation + { + duration: 200 + easing.type: Easing.InOutCubic + } + } spacing: 60 * screenScaleFactor // TODO: Theme! Repeater From 30168103b726fb2d49d7d4cc1d563b9a302757a6 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Fri, 14 Dec 2018 15:47:36 +0100 Subject: [PATCH 0961/1292] Update MonitorStage.qml --- plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml index f77cfee1ef..22badfc8ac 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml @@ -15,9 +15,6 @@ Component { id: monitorFrame - property var emphasisColor: UM.Theme.getColor("setting_control_border_highlight") - property var cornerRadius: UM.Theme.getSize("monitor_corner_radius").width - height: maximumHeight onVisibleChanged: { @@ -39,11 +36,11 @@ Component gradient: Gradient { GradientStop { position: 0.0 - color: "#f6f6f6" + color: "#f6f6f6" // TODO: Theme! } GradientStop { position: 1.0 - color: "#ffffff" + color: "#ffffff" // TODO: Theme! } } } From e815d5da8f73a939cd4a1e028fea44c65f987cc8 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 14 Dec 2018 16:02:28 +0100 Subject: [PATCH 0962/1292] STAR-322: Avoiding lambdas and direct callbacks to avoid gc --- cura/NetworkClient.py | 4 +- .../src/Cloud/CloudApiClient.py | 11 +++-- .../src/Cloud/CloudOutputDevice.py | 46 +++++++++++++++---- .../{ResumableUpload.py => MeshUploader.py} | 18 +++++--- .../tests/Cloud/TestCloudOutputDevice.py | 4 ++ 5 files changed, 59 insertions(+), 24 deletions(-) rename plugins/UM3NetworkPrinting/src/Cloud/{ResumableUpload.py => MeshUploader.py} (91%) diff --git a/cura/NetworkClient.py b/cura/NetworkClient.py index 4c43e58c4f..878158542a 100644 --- a/cura/NetworkClient.py +++ b/cura/NetworkClient.py @@ -3,7 +3,7 @@ from time import time from typing import Optional, Dict, Callable, List, Union -from PyQt5.QtCore import QUrl, QObject +from PyQt5.QtCore import QUrl from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkReply, QHttpMultiPart, QNetworkRequest, QHttpPart, \ QAuthenticator @@ -13,7 +13,7 @@ from UM.Logger import Logger ## Abstraction of QNetworkAccessManager for easier networking in Cura. # This was originally part of NetworkedPrinterOutputDevice but was moved out for re-use in other classes. -class NetworkClient(QObject): +class NetworkClient: def __init__(self) -> None: super().__init__() diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py index 7c3c08e044..8cdedd1229 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py @@ -4,12 +4,12 @@ import json from json import JSONDecodeError from typing import Callable, List, Type, TypeVar, Union, Optional, Tuple, Dict, Any -from PyQt5.QtCore import QObject, QUrl +from PyQt5.QtCore import QUrl from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply, QNetworkAccessManager from UM.Logger import Logger from cura.API import Account -from .ResumableUpload import ResumableUpload +from .MeshUploader import MeshUploader from ..Models import BaseModel from .Models.CloudClusterResponse import CloudClusterResponse from .Models.CloudErrorObject import CloudErrorObject @@ -37,6 +37,7 @@ class CloudApiClient: self._manager = QNetworkAccessManager() self._account = account self._on_error = on_error + self._upload = None # type: Optional[MeshUploader] ## Gets the account used for the API. @property @@ -77,10 +78,10 @@ class CloudApiClient: # \param on_finished: The function to be called after the result is parsed. It receives the print job ID. # \param on_progress: A function to be called during upload progress. It receives a percentage (0-100). # \param on_error: A function to be called if the upload fails. It receives a dict with the error. - def uploadMesh(self, upload_response: CloudPrintJobResponse, mesh: bytes, on_finished: Callable[[], Any], + def uploadMesh(self, print_job: CloudPrintJobResponse, mesh: bytes, on_finished: Callable[[], Any], on_progress: Callable[[int], Any], on_error: Callable[[], Any]): - ResumableUpload(self._manager, upload_response.upload_url, upload_response.content_type, mesh, on_finished, - on_progress, on_error).start() + self._upload = MeshUploader(self._manager, print_job, mesh, on_finished, on_progress, on_error) + self._upload.start() # Requests a cluster to print the given print job. # \param cluster_id: The ID of the cluster. diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 09677d5e48..88c2f8da1d 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -8,11 +8,13 @@ from typing import Dict, List, Optional, Set from PyQt5.QtCore import QObject, QUrl, pyqtProperty, pyqtSignal, pyqtSlot from UM import i18nCatalog +from UM.Backend.Backend import BackendState from UM.FileHandler.FileHandler import FileHandler from UM.Logger import Logger from UM.Message import Message from UM.Qt.Duration import Duration, DurationFormat from UM.Scene.SceneNode import SceneNode +from cura.CuraApplication import CuraApplication from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState, NetworkedPrinterOutputDevice from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputController import CloudOutputController @@ -92,6 +94,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self._device_id = device_id self._account = api_client.account + CuraApplication.getInstance().getBackend().backendStateChange.connect(self._onBackendStateChange) + # We use the Cura Connect monitor tab to get most functionality right away. self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../resources/qml/MonitorStage.qml") @@ -116,6 +120,17 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # A set of the user's job IDs that have finished self._finished_jobs = set() # type: Set[str] + # Reference to the uploaded print job + self._mesh = None # type: Optional[bytes] + self._uploaded_print_job = None # type: Optional[CloudPrintJobResponse] + + def disconnect(self) -> None: + CuraApplication.getInstance().getBackend().backendStateChange.disconnect(self._onBackendStateChange) + + def _onBackendStateChange(self, _: BackendState) -> None: + self._mesh = None + self._uploaded_print_job = None + ## Gets the host name of this device @property def host_name(self) -> str: @@ -146,7 +161,16 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # Show an error message if we're already sending a job. if self._progress.visible: - self._onUploadError(T.BLOCKED_UPLOADING) + Message( + text = T.BLOCKED_UPLOADING, + title = T.ERROR, + lifetime = 10, + ).show() + return + + if self._uploaded_print_job: + # the mesh didn't change, let's not upload it again + self._api.requestPrint(self._device_id, self._uploaded_print_job.job_id, self._onPrintRequested) return # Indicate we have started sending a job. @@ -157,14 +181,15 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): Logger.log("e", "Missing file or mesh writer!") return self._onUploadError(T.COULD_NOT_EXPORT) - mesh_bytes = mesh_format.getBytes(nodes) + mesh = mesh_format.getBytes(nodes) + self._mesh = mesh request = CloudPrintJobUploadRequest( job_name = file_name, - file_size = len(mesh_bytes), + file_size = len(mesh), content_type = mesh_format.mime_type, ) - self._api.requestUpload(request, lambda response: self._onPrintJobCreated(mesh_bytes, response)) + self._api.requestUpload(request, self._onPrintJobCreated) ## Called when the network data should be updated. def _update(self) -> None: @@ -281,21 +306,22 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## Uploads the mesh when the print job was registered with the cloud API. # \param mesh: The bytes to upload. # \param job_response: The response received from the cloud API. - def _onPrintJobCreated(self, mesh: bytes, job_response: CloudPrintJobResponse) -> None: + def _onPrintJobCreated(self, job_response: CloudPrintJobResponse) -> None: self._progress.show() - self._api.uploadMesh(job_response, mesh, lambda: self._onPrintJobUploaded(job_response.job_id), - self._progress.update, self._onUploadError) + self._uploaded_print_job = job_response + self._api.uploadMesh(job_response, self._mesh, self._onPrintJobUploaded, self._progress.update, + self._onUploadError) ## Requests the print to be sent to the printer when we finished uploading the mesh. - # \param job_id: The ID of the job. - def _onPrintJobUploaded(self, job_id: str) -> None: + def _onPrintJobUploaded(self) -> None: self._progress.update(100) - self._api.requestPrint(self._device_id, job_id, self._onPrintRequested) + self._api.requestPrint(self._device_id, self._uploaded_print_job.job_id, self._onPrintRequested) ## Displays the given message if uploading the mesh has failed # \param message: The message to display. def _onUploadError(self, message = None) -> None: self._progress.hide() + self._uploaded_print_job = None Message( text = message or T.UPLOAD_ERROR, title = T.ERROR, diff --git a/plugins/UM3NetworkPrinting/src/Cloud/ResumableUpload.py b/plugins/UM3NetworkPrinting/src/Cloud/MeshUploader.py similarity index 91% rename from plugins/UM3NetworkPrinting/src/Cloud/ResumableUpload.py rename to plugins/UM3NetworkPrinting/src/Cloud/MeshUploader.py index 5e3bc9545e..4f0d6f2e81 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/ResumableUpload.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/MeshUploader.py @@ -6,9 +6,10 @@ from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply, QNetworkAccessManage from typing import Optional, Callable, Any, Tuple from UM.Logger import Logger +from src.Cloud.Models.CloudPrintJobResponse import CloudPrintJobResponse -class ResumableUpload: +class MeshUploader: MAX_RETRIES = 10 BYTES_PER_REQUEST = 256 * 1024 RETRY_HTTP_CODES = {500, 502, 503, 504} @@ -18,11 +19,10 @@ class ResumableUpload: # \param content_length: The total content length of the file, in bytes. # \param http_method: The HTTP method to be used, e.g. "POST" or "PUT". # \param timeout: The timeout for each chunk upload. Important: If None, no timeout is applied at all. - def __init__(self, manager: QNetworkAccessManager, url: str, content_type: str, data: bytes, + def __init__(self, manager: QNetworkAccessManager, print_job: CloudPrintJobResponse, data: bytes, on_finished: Callable[[], Any], on_progress: Callable[[int], Any], on_error: Callable[[], Any]): self._manager = manager - self._url = url - self._content_type = content_type + self._print_job = print_job self._data = data self._on_finished = on_finished @@ -34,17 +34,21 @@ class ResumableUpload: self._finished = False self._reply = None # type: Optional[QNetworkReply] + @property + def printJob(self): + return self._print_job + ## We override _createRequest in order to add the user credentials. # \param url: The URL to request # \param content_type: The type of the body contents. def _createRequest(self) -> QNetworkRequest: - request = QNetworkRequest(QUrl(self._url)) - request.setHeader(QNetworkRequest.ContentTypeHeader, self._content_type) + request = QNetworkRequest(QUrl(self._print_job.upload_url)) + request.setHeader(QNetworkRequest.ContentTypeHeader, self._print_job.content_type) first_byte, last_byte = self._chunkRange() content_range = "bytes {}-{}/{}".format(first_byte, last_byte - 1, len(self._data)) request.setRawHeader(b"Content-Range", content_range.encode()) - Logger.log("i", "Uploading %s to %s", content_range, self._url) + Logger.log("i", "Uploading %s to %s", content_range, self._print_job.upload_url) return request diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py index c391dc75dd..d31f59f85a 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py @@ -5,6 +5,7 @@ from unittest import TestCase from unittest.mock import patch, MagicMock from UM.Scene.SceneNode import SceneNode +from UM.Signal import Signal from cura.CuraApplication import CuraApplication from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from src.Cloud.CloudApiClient import CloudApiClient @@ -26,6 +27,9 @@ class TestCloudOutputDevice(TestCase): def setUp(self): super().setUp() self.app = CuraApplication.getInstance() + self.backend = MagicMock(backendStateChange = Signal()) + self.app.setBackend(self.backend) + self.network = NetworkManagerMock() self.account = MagicMock(isLoggedIn=True, accessToken="TestAccessToken") self.onError = MagicMock() From 3766effa81dc111d70c0d7ff4563936ec92fc5c4 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Fri, 14 Dec 2018 16:04:31 +0100 Subject: [PATCH 0963/1292] Quick fix to prevent monitor stage from overlapping header --- plugins/MonitorStage/MonitorMain.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/MonitorStage/MonitorMain.qml b/plugins/MonitorStage/MonitorMain.qml index 1f287fc0fa..1f52ceea51 100644 --- a/plugins/MonitorStage/MonitorMain.qml +++ b/plugins/MonitorStage/MonitorMain.qml @@ -16,6 +16,7 @@ Item color: UM.Theme.getColor("viewport_overlay") anchors.fill: parent + anchors.topMargin: Math.round(stageMenu.height / 2) MouseArea { anchors.fill: parent @@ -29,8 +30,7 @@ Item id: monitorViewComponent anchors.fill: parent - - height: parent.height + anchors.topMargin: Math.round(stageMenu.height / 2) property real maximumWidth: parent.width property real maximumHeight: parent.height From 2789a0fdc43a2eb4c32f2c434ac23b22a83eef1f Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Fri, 14 Dec 2018 16:13:35 +0100 Subject: [PATCH 0964/1292] Revert "Quick fix to prevent monitor stage from overlapping header" This reverts commit 3766effa81dc111d70c0d7ff4563936ec92fc5c4. --- plugins/MonitorStage/MonitorMain.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/MonitorStage/MonitorMain.qml b/plugins/MonitorStage/MonitorMain.qml index 1f52ceea51..1f287fc0fa 100644 --- a/plugins/MonitorStage/MonitorMain.qml +++ b/plugins/MonitorStage/MonitorMain.qml @@ -16,7 +16,6 @@ Item color: UM.Theme.getColor("viewport_overlay") anchors.fill: parent - anchors.topMargin: Math.round(stageMenu.height / 2) MouseArea { anchors.fill: parent @@ -30,7 +29,8 @@ Item id: monitorViewComponent anchors.fill: parent - anchors.topMargin: Math.round(stageMenu.height / 2) + + height: parent.height property real maximumWidth: parent.width property real maximumHeight: parent.height From ffccbcea2fbe91bef2becc71a90b5d09bf840203 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Fri, 14 Dec 2018 16:13:49 +0100 Subject: [PATCH 0965/1292] Anchor to bottom of header background --- resources/qml/Cura.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 2b6f989e0b..573d75e5fa 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -252,7 +252,7 @@ UM.MainWindow anchors { // Align to the top of the stageMenu since the stageMenu may not exist - top: parent.top + top: headerBackground.top left: parent.left right: parent.right bottom: parent.bottom From 9146a775a4c3ae4b83cd7f62d2bf0d945e9caab1 Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Fri, 14 Dec 2018 16:17:05 +0100 Subject: [PATCH 0966/1292] After resetting the custom settings the quality slider did not update selected value CURA-6028 --- cura/Settings/SimpleModeSettingsManager.py | 11 ++++++----- .../RecommendedQualityProfileSelector.qml | 12 +++++++++++- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/cura/Settings/SimpleModeSettingsManager.py b/cura/Settings/SimpleModeSettingsManager.py index fce43243bd..210a5794d4 100644 --- a/cura/Settings/SimpleModeSettingsManager.py +++ b/cura/Settings/SimpleModeSettingsManager.py @@ -1,7 +1,7 @@ # Copyright (c) 2017 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty +from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty, pyqtSlot from UM.Application import Application @@ -16,12 +16,12 @@ class SimpleModeSettingsManager(QObject): self._is_profile_user_created = False # True when profile was custom created by user self._machine_manager.activeStackValueChanged.connect(self._updateIsProfileCustomized) - self._machine_manager.activeQualityGroupChanged.connect(self._updateIsProfileUserCreated) - self._machine_manager.activeQualityChangesGroupChanged.connect(self._updateIsProfileUserCreated) + self._machine_manager.activeQualityGroupChanged.connect(self.updateIsProfileUserCreated) + self._machine_manager.activeQualityChangesGroupChanged.connect(self.updateIsProfileUserCreated) # update on create as the activeQualityChanged signal is emitted before this manager is created when Cura starts self._updateIsProfileCustomized() - self._updateIsProfileUserCreated() + self.updateIsProfileUserCreated() isProfileCustomizedChanged = pyqtSignal() isProfileUserCreatedChanged = pyqtSignal() @@ -61,7 +61,8 @@ class SimpleModeSettingsManager(QObject): def isProfileUserCreated(self): return self._is_profile_user_created - def _updateIsProfileUserCreated(self): + @pyqtSlot() + def updateIsProfileUserCreated(self) -> None: quality_changes_keys = set() if not self._machine_manager.activeMachine: diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml index 349c6dbb57..e6b3f1b9eb 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml @@ -39,7 +39,17 @@ Item { target: Cura.QualityProfilesDropDownMenuModel onItemsChanged: qualityModel.update() - onDataChanged: qualityModel.update() + onDataChanged: + { + // If a custom profile is selected and then a user decides to change any of setting the slider should show + // the reset button. After clicking the reset button the QualityProfilesDropDownMenuModel(ListModel) is + // updated before the property isProfileCustomized is called to update. + if (Cura.SimpleModeSettingsManager.isProfileCustomized) + { + Cura.SimpleModeSettingsManager.updateIsProfileUserCreated() + } + qualityModel.update() + } } Connections { From 74af11d609f7e927f14de92af619a06121cc35ed Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Fri, 14 Dec 2018 16:20:08 +0100 Subject: [PATCH 0967/1292] Anchor loader to stage menu vertical center --- resources/qml/Cura.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 573d75e5fa..8ab943b93b 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -252,7 +252,7 @@ UM.MainWindow anchors { // Align to the top of the stageMenu since the stageMenu may not exist - top: headerBackground.top + top: stageMenu.source ? stageMenu.verticalCenter : parent.top left: parent.left right: parent.right bottom: parent.bottom From ef6f666c3e07b0b9c5fd4ab85023d2a9d29433c2 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 14 Dec 2018 16:41:07 +0100 Subject: [PATCH 0968/1292] Remove duplicate alias definition Yay. Merges. --- resources/qml/IconWithText.qml | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/qml/IconWithText.qml b/resources/qml/IconWithText.qml index dd522031c1..24b6dc7fe2 100644 --- a/resources/qml/IconWithText.qml +++ b/resources/qml/IconWithText.qml @@ -19,7 +19,6 @@ Item property alias color: label.color property alias text: label.text property alias font: label.font - property alias iconColor: icon.color property real margin: UM.Theme.getSize("narrow_margin").width // These properties can be used in combination with layouts. From e877b47e22cb95b2534a7121db73914d4a321d93 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Fri, 14 Dec 2018 16:55:48 +0100 Subject: [PATCH 0969/1292] Disable printer cards which are not in focus Contributes to CL-1151 --- .../resources/qml/CameraButton.qml | 18 +++++++++++++----- .../resources/qml/MonitorCarousel.qml | 1 + .../resources/qml/MonitorPrinterCard.qml | 9 ++++++++- .../resources/qml/PrintJobContextMenu.qml | 5 +++-- 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/CameraButton.qml b/plugins/UM3NetworkPrinting/resources/qml/CameraButton.qml index 618dbed81c..6f054f9c19 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/CameraButton.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/CameraButton.qml @@ -8,11 +8,13 @@ import UM 1.3 as UM import Cura 1.0 as Cura Rectangle { + id: base property var iconSource: null; color: "#0a0850" // TODO: Theme! height: width; radius: Math.round(0.5 * width); width: 24 * screenScaleFactor; + property var enabled: true UM.RecolorImage { id: icon; @@ -29,12 +31,18 @@ Rectangle { MouseArea { id: clickArea; anchors.fill: parent; - hoverEnabled: true; + hoverEnabled: base.enabled onClicked: { - if (OutputDevice.activeCameraUrl != "") { - OutputDevice.setActiveCameraUrl(""); - } else { - OutputDevice.setActiveCameraUrl(modelData.cameraUrl); + if (base.enabled) + { + if (OutputDevice.activeCameraUrl != "") + { + OutputDevice.setActiveCameraUrl("") + } + else + { + OutputDevice.setActiveCameraUrl(modelData.cameraUrl) + } } } } diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml index 988008dc31..952ec1e162 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml @@ -124,6 +124,7 @@ Item MonitorPrinterCard { printer: modelData + enabled: model.index == currentIndex } } } diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml index 038f0535f0..2ca37a7e13 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml @@ -25,6 +25,11 @@ Item property var borderSize: 1 * screenScaleFactor // TODO: Theme, and remove from here + // If the printer card's controls are enabled. This is used by the carousel + // to prevent opening the context menu or camera while the printer card is not + // "in focus" + property var enabled: true + width: 834 * screenScaleFactor // TODO: Theme! height: childrenRect.height @@ -124,6 +129,7 @@ Item printJob: printer.activePrintJob width: 36 * screenScaleFactor // TODO: Theme! height: 36 * screenScaleFactor // TODO: Theme! + enabled: base.enabled } CameraButton { @@ -136,6 +142,7 @@ Item bottomMargin: 20 * screenScaleFactor // TODO: Theme! } iconSource: "../svg/icons/camera.svg" + enabled: base.enabled } } @@ -320,7 +327,7 @@ Item implicitHeight: 32 * screenScaleFactor // TODO: Theme! implicitWidth: 96 * screenScaleFactor // TODO: Theme! visible: printer.activePrintJob && printer.activePrintJob.configurationChanges.length > 0 - onClicked: overrideConfirmationDialog.open() + onClicked: base.enabled ? overrideConfirmationDialog.open() : {} } } diff --git a/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml b/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml index 1edbf9f6a2..5c5c892dad 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml @@ -13,6 +13,7 @@ Item { property var printJob: null; property var started: isStarted(printJob); property var assigned: isAssigned(printJob); + property var enabled: true Button { id: button; @@ -31,8 +32,8 @@ Item { verticalAlignment: Text.AlignVCenter; } height: width; - hoverEnabled: true; - onClicked: parent.switchPopupState(); + hoverEnabled: base.enabled + onClicked: base.enabled ? parent.switchPopupState() : {} text: "\u22EE"; //Unicode; Three stacked points. visible: { if (!printJob) { From 331cd730f11c4b5a486fe7a5e1474c54b0d054fd Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Fri, 14 Dec 2018 16:56:20 +0100 Subject: [PATCH 0970/1292] Improve visual hint that side cards are not in focus Contributes to CL-1151 --- plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml index 952ec1e162..ea1449ac8d 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml @@ -45,7 +45,7 @@ Item GradientStop { position: 1.0 - color: "#00f6f6f6" + color: "#66f6f6f6" } } } @@ -190,7 +190,7 @@ Item GradientStop { position: 0.0 - color: "#00f6f6f6" + color: "#66f6f6f6" } GradientStop { From 226d05246877a95c46c0799160cbd0015bff714c Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 14 Dec 2018 17:10:58 +0100 Subject: [PATCH 0971/1292] Move the machines from machinelist into their own model CURA-6011 --- cura/CuraApplication.py | 2 + cura/PrintersModel.py | 65 ++++++++++++++++ .../src/UM3OutputDevicePlugin.py | 1 + .../qml/PrinterSelector/MachineSelector.qml | 6 ++ .../PrinterSelector/MachineSelectorList.qml | 76 ++++++------------- 5 files changed, 97 insertions(+), 53 deletions(-) create mode 100644 cura/PrintersModel.py diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index a50d7d55c8..c773dae998 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -51,6 +51,7 @@ from cura.Arranging.ArrangeObjectsJob import ArrangeObjectsJob from cura.Arranging.ArrangeObjectsAllBuildPlatesJob import ArrangeObjectsAllBuildPlatesJob from cura.Arranging.ShapeArray import ShapeArray from cura.MultiplyObjectsJob import MultiplyObjectsJob +from cura.PrintersModel import PrintersModel from cura.Scene.ConvexHullDecorator import ConvexHullDecorator from cura.Operations.SetParentOperation import SetParentOperation from cura.Scene.SliceableObjectDecorator import SliceableObjectDecorator @@ -955,6 +956,7 @@ class CuraApplication(QtApplication): qmlRegisterType(MultiBuildPlateModel, "Cura", 1, 0, "MultiBuildPlateModel") qmlRegisterType(InstanceContainer, "Cura", 1, 0, "InstanceContainer") qmlRegisterType(ExtrudersModel, "Cura", 1, 0, "ExtrudersModel") + qmlRegisterType(PrintersModel, "Cura", 1, 0, "PrintersModel") qmlRegisterType(FavoriteMaterialsModel, "Cura", 1, 0, "FavoriteMaterialsModel") qmlRegisterType(GenericMaterialsModel, "Cura", 1, 0, "GenericMaterialsModel") diff --git a/cura/PrintersModel.py b/cura/PrintersModel.py new file mode 100644 index 0000000000..83471a2e2a --- /dev/null +++ b/cura/PrintersModel.py @@ -0,0 +1,65 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from UM.Qt.ListModel import ListModel + +from PyQt5.QtCore import pyqtProperty, Qt, pyqtSignal + +from UM.Settings.ContainerRegistry import ContainerRegistry +from UM.Settings.ContainerStack import ContainerStack + +from cura.PrinterOutputDevice import ConnectionType + +from cura.Settings.GlobalStack import GlobalStack + +class PrintersModel(ListModel): + NameRole = Qt.UserRole + 1 + IdRole = Qt.UserRole + 2 + HasRemoteConnectionRole = Qt.UserRole + 3 + ConnectionTypeRole = Qt.UserRole + 4 + MetaDataRole = Qt.UserRole + 5 + + def __init__(self, parent = None): + super().__init__(parent) + self.addRoleName(self.NameRole, "name") + self.addRoleName(self.IdRole, "id") + self.addRoleName(self.HasRemoteConnectionRole, "hasRemoteConnection") + self.addRoleName(self.ConnectionTypeRole, "connectionType") + self.addRoleName(self.MetaDataRole, "metadata") + self._container_stacks = [] + + # Listen to changes + ContainerRegistry.getInstance().containerAdded.connect(self._onContainerChanged) + ContainerRegistry.getInstance().containerMetaDataChanged.connect(self._onContainerChanged) + ContainerRegistry.getInstance().containerRemoved.connect(self._onContainerChanged) + self._filter_dict = {} + self._update() + + ## Handler for container added/removed events from registry + def _onContainerChanged(self, container): + # We only need to update when the added / removed container GlobalStack + if isinstance(container, GlobalStack): + self._update() + + ## Handler for container name change events. + def _onContainerNameChanged(self): + self._update() + + def _update(self) -> None: + items = [] + for container in self._container_stacks: + container.nameChanged.disconnect(self._onContainerNameChanged) + + container_stacks = ContainerRegistry.getInstance().findContainerStacks(type = "machine") + + for container_stack in container_stacks: + connection_type = container_stack.getMetaDataEntry("connection_type") + has_remote_connection = connection_type in [str(ConnectionType.NetworkConnection), str(ConnectionType.CloudConnection), str(ConnectionType.ClusterConnection)] + + # TODO: Remove reference to connect group name. + items.append({"name": container_stack.getMetaDataEntry("connect_group_name", container_stack.getName()), + "id": container_stack.getId(), + "hasRemoteConnection": has_remote_connection, + "connectionType": connection_type}) + items.sort(key=lambda i: not i["hasRemoteConnection"]) + self.setItems(items) \ No newline at end of file diff --git a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py index b96c508d70..43290c8e44 100644 --- a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py +++ b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py @@ -283,6 +283,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): global_container_stack = Application.getInstance().getGlobalContainerStack() if global_container_stack and device.getId() == global_container_stack.getMetaDataEntry("um_network_key"): + global_container_stack.setMetaDataEntry("connection_type", str(device.getConnectionType())) device.connect() device.connectionStateChanged.connect(self._onDeviceConnectionStateChanged) diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index 7cda4f1d2e..6e120e89c7 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -123,6 +123,12 @@ Cura.ExpandablePopup scroll.height = Math.min(height, maximumHeight) popup.height = scroll.height + buttonRow.height } + Component.onCompleted: + { + scroll.height = Math.min(height, maximumHeight) + popup.height = scroll.height + buttonRow.height + } + } } diff --git a/resources/qml/PrinterSelector/MachineSelectorList.qml b/resources/qml/PrinterSelector/MachineSelectorList.qml index bc3fe105a2..b157f9a4f6 100644 --- a/resources/qml/PrinterSelector/MachineSelectorList.qml +++ b/resources/qml/PrinterSelector/MachineSelectorList.qml @@ -7,46 +7,48 @@ import QtQuick.Controls 2.3 import UM 1.2 as UM import Cura 1.0 as Cura -Column +ListView { - id: machineSelectorList + id: listView + height: childrenRect.height + width: 200 + model: Cura.PrintersModel {} + section.property: "hasRemoteConnection" - Label + section.delegate: Label { - text: catalog.i18nc("@label", "Connected printers") - visible: networkedPrintersModel.items.length > 0 + text: section == "true" ? catalog.i18nc("@label", "Connected printers") : catalog.i18nc("@label", "Preset printers") + width: parent.width leftPadding: UM.Theme.getSize("default_margin").width - height: visible ? contentHeight + 2 * UM.Theme.getSize("default_margin").height : 0 renderType: Text.NativeRendering font: UM.Theme.getFont("medium") color: UM.Theme.getColor("text_medium") verticalAlignment: Text.AlignVCenter } + delegate: MachineSelectorButton + { + text: model.name + width: listView.width + } +} + /* + + + Repeater { id: networkedPrinters - model: UM.ContainerStacksModel + model: Cura.PrintersModel { id: networkedPrintersModel - property var umConnectionTypes: [Cura.PrinterOutputDevice.NetworkConnection, - Cura.PrinterOutputDevice.ClusterConnection, - Cura.PrinterOutputDevice.CloudConnection - ] - filter: - { - "type": "machine", - "um_network_key": "*", - "hidden": "False", - "um_connection_type": "[" + umConnectionTypes.join(",") + "]" - } } delegate: MachineSelectorButton { - text: model.metadata["connect_group_name"] - checked: Cura.MachineManager.activeMachineNetworkGroupName == model.metadata["connect_group_name"] + text: model.name //model.metadata["connect_group_name"] + //checked: Cura.MachineManager.activeMachineNetworkGroupName == model.metadata["connect_group_name"] outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null Connections @@ -55,37 +57,5 @@ Column onActiveMachineNetworkGroupNameChanged: checked = Cura.MachineManager.activeMachineNetworkGroupName == model.metadata["connect_group_name"] } } - } + }*/ - Label - { - text: catalog.i18nc("@label", "Preset printers") - visible: virtualPrintersModel.items.length > 0 - leftPadding: UM.Theme.getSize("default_margin").width - height: visible ? contentHeight + 2 * UM.Theme.getSize("default_margin").height : 0 - renderType: Text.NativeRendering - font: UM.Theme.getFont("medium") - color: UM.Theme.getColor("text_medium") - verticalAlignment: Text.AlignVCenter - } - - Repeater - { - id: virtualPrinters - - model: UM.ContainerStacksModel - { - id: virtualPrintersModel - filter: - { - "type": "machine", "um_network_key": null - } - } - - delegate: MachineSelectorButton - { - text: model.name - checked: Cura.MachineManager.activeMachineId == model.id - } - } -} \ No newline at end of file From b8a4d8e80d39c81dbb2670e3236709a3ad4df4ba Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 14 Dec 2018 17:14:56 +0100 Subject: [PATCH 0972/1292] Remove the cluster connection type CURA-6011 --- cura/PrinterOutputDevice.py | 3 +-- cura/PrintersModel.py | 2 +- plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index ed65d5d700..b33993f150 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -39,8 +39,7 @@ class ConnectionType(IntEnum): Unknown = 0 UsbConnection = 1 NetworkConnection = 2 - ClusterConnection = 3 - CloudConnection = 4 + CloudConnection = 3 ## Printer output device adds extra interface options on top of output device. diff --git a/cura/PrintersModel.py b/cura/PrintersModel.py index 83471a2e2a..26b65409c5 100644 --- a/cura/PrintersModel.py +++ b/cura/PrintersModel.py @@ -54,7 +54,7 @@ class PrintersModel(ListModel): for container_stack in container_stacks: connection_type = container_stack.getMetaDataEntry("connection_type") - has_remote_connection = connection_type in [str(ConnectionType.NetworkConnection), str(ConnectionType.CloudConnection), str(ConnectionType.ClusterConnection)] + has_remote_connection = connection_type in [str(ConnectionType.NetworkConnection), str(ConnectionType.CloudConnection)] # TODO: Remove reference to connect group name. items.append({"name": container_stack.getMetaDataEntry("connect_group_name", container_stack.getName()), diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index d85cbeb27b..bebccc54e3 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -55,7 +55,7 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): clusterPrintersChanged = pyqtSignal() def __init__(self, device_id, address, properties, parent = None) -> None: - super().__init__(device_id = device_id, address = address, properties=properties, connection_type = ConnectionType.ClusterConnection, parent = parent) + super().__init__(device_id = device_id, address = address, properties=properties, connection_type = ConnectionType.NetworkConnection, parent = parent) self._api_prefix = "/cluster-api/v1/" self._number_of_extruders = 2 From c235f339ae9e59b2c54a9054028a456658c306f1 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 14 Dec 2018 17:29:02 +0100 Subject: [PATCH 0973/1292] Increment API version to 6 All plug-ins now have to re-check whether they are still compatible with the current version of Cura. Contributes to issue CURA-6019. --- cura/CuraApplication.py | 2 +- plugins/3MFReader/plugin.json | 2 +- plugins/3MFWriter/plugin.json | 2 +- plugins/ChangeLogPlugin/plugin.json | 2 +- plugins/CuraEngineBackend/plugin.json | 2 +- plugins/CuraProfileReader/plugin.json | 2 +- plugins/CuraProfileWriter/plugin.json | 2 +- plugins/FirmwareUpdateChecker/plugin.json | 2 +- plugins/FirmwareUpdater/plugin.json | 2 +- plugins/GCodeGzReader/plugin.json | 2 +- plugins/GCodeGzWriter/plugin.json | 2 +- plugins/GCodeProfileReader/plugin.json | 2 +- plugins/GCodeReader/plugin.json | 4 ++-- plugins/GCodeWriter/plugin.json | 2 +- plugins/ImageReader/plugin.json | 2 +- plugins/LegacyProfileReader/plugin.json | 2 +- plugins/MachineSettingsAction/plugin.json | 2 +- plugins/ModelChecker/plugin.json | 2 +- plugins/MonitorStage/plugin.json | 2 +- plugins/PerObjectSettingsTool/plugin.json | 2 +- plugins/PostProcessingPlugin/plugin.json | 2 +- plugins/PrepareStage/plugin.json | 2 +- plugins/PreviewStage/plugin.json | 2 +- plugins/RemovableDriveOutputDevice/plugin.json | 2 +- plugins/SimulationView/plugin.json | 2 +- plugins/SliceInfoPlugin/plugin.json | 2 +- plugins/SolidView/plugin.json | 2 +- plugins/SupportEraser/plugin.json | 2 +- plugins/Toolbox/plugin.json | 2 +- plugins/UFPWriter/plugin.json | 2 +- plugins/UM3NetworkPrinting/plugin.json | 2 +- plugins/USBPrinting/plugin.json | 2 +- plugins/UltimakerMachineActions/plugin.json | 2 +- plugins/UserAgreement/plugin.json | 2 +- plugins/VersionUpgrade/VersionUpgrade21to22/plugin.json | 2 +- plugins/VersionUpgrade/VersionUpgrade22to24/plugin.json | 2 +- plugins/VersionUpgrade/VersionUpgrade25to26/plugin.json | 2 +- plugins/VersionUpgrade/VersionUpgrade26to27/plugin.json | 2 +- plugins/VersionUpgrade/VersionUpgrade27to30/plugin.json | 2 +- plugins/VersionUpgrade/VersionUpgrade30to31/plugin.json | 2 +- plugins/VersionUpgrade/VersionUpgrade32to33/plugin.json | 2 +- plugins/VersionUpgrade/VersionUpgrade33to34/plugin.json | 2 +- plugins/VersionUpgrade/VersionUpgrade34to35/plugin.json | 2 +- plugins/X3DReader/plugin.json | 2 +- plugins/XRayView/plugin.json | 2 +- plugins/XmlMaterialProfile/plugin.json | 2 +- 46 files changed, 47 insertions(+), 47 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 55e37617d5..726197de10 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -134,7 +134,7 @@ except ImportError: CuraVersion = "master" # [CodeStyle: Reflecting imported value] CuraBuildType = "" CuraDebugMode = False - CuraSDKVersion = "5.0.0" + CuraSDKVersion = "6.0.0" class CuraApplication(QtApplication): diff --git a/plugins/3MFReader/plugin.json b/plugins/3MFReader/plugin.json index 5e41975752..d7160e166a 100644 --- a/plugins/3MFReader/plugin.json +++ b/plugins/3MFReader/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Provides support for reading 3MF files.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/3MFWriter/plugin.json b/plugins/3MFWriter/plugin.json index 9ec4fb0c20..865c3bf026 100644 --- a/plugins/3MFWriter/plugin.json +++ b/plugins/3MFWriter/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Provides support for writing 3MF files.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/ChangeLogPlugin/plugin.json b/plugins/ChangeLogPlugin/plugin.json index e09a08564a..04d5ce7c51 100644 --- a/plugins/ChangeLogPlugin/plugin.json +++ b/plugins/ChangeLogPlugin/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Shows changes since latest checked version.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/CuraEngineBackend/plugin.json b/plugins/CuraEngineBackend/plugin.json index 111698d8d1..25db9abefd 100644 --- a/plugins/CuraEngineBackend/plugin.json +++ b/plugins/CuraEngineBackend/plugin.json @@ -2,7 +2,7 @@ "name": "CuraEngine Backend", "author": "Ultimaker B.V.", "description": "Provides the link to the CuraEngine slicing backend.", - "api": 5, + "api": "6.0", "version": "1.0.0", "i18n-catalog": "cura" } diff --git a/plugins/CuraProfileReader/plugin.json b/plugins/CuraProfileReader/plugin.json index 66a2a6a56b..adbf376b72 100644 --- a/plugins/CuraProfileReader/plugin.json +++ b/plugins/CuraProfileReader/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Provides support for importing Cura profiles.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/CuraProfileWriter/plugin.json b/plugins/CuraProfileWriter/plugin.json index 16c8c34152..d576f517de 100644 --- a/plugins/CuraProfileWriter/plugin.json +++ b/plugins/CuraProfileWriter/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Provides support for exporting Cura profiles.", - "api": 5, + "api": "6.0", "i18n-catalog":"cura" } diff --git a/plugins/FirmwareUpdateChecker/plugin.json b/plugins/FirmwareUpdateChecker/plugin.json index cbbd41e420..4b77a53a62 100644 --- a/plugins/FirmwareUpdateChecker/plugin.json +++ b/plugins/FirmwareUpdateChecker/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Checks for firmware updates.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/FirmwareUpdater/plugin.json b/plugins/FirmwareUpdater/plugin.json index 3e09eab2b5..4098759630 100644 --- a/plugins/FirmwareUpdater/plugin.json +++ b/plugins/FirmwareUpdater/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Provides a machine actions for updating firmware.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/GCodeGzReader/plugin.json b/plugins/GCodeGzReader/plugin.json index 3bd6a4097d..cea1d0f55c 100644 --- a/plugins/GCodeGzReader/plugin.json +++ b/plugins/GCodeGzReader/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Reads g-code from a compressed archive.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/GCodeGzWriter/plugin.json b/plugins/GCodeGzWriter/plugin.json index 4c6497317b..d725b2649d 100644 --- a/plugins/GCodeGzWriter/plugin.json +++ b/plugins/GCodeGzWriter/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Writes g-code to a compressed archive.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/GCodeProfileReader/plugin.json b/plugins/GCodeProfileReader/plugin.json index 9677628c85..12d8a276da 100644 --- a/plugins/GCodeProfileReader/plugin.json +++ b/plugins/GCodeProfileReader/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Provides support for importing profiles from g-code files.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/GCodeReader/plugin.json b/plugins/GCodeReader/plugin.json index 75b4d0cd4f..351d6cbc31 100644 --- a/plugins/GCodeReader/plugin.json +++ b/plugins/GCodeReader/plugin.json @@ -1,8 +1,8 @@ { "name": "G-code Reader", - "author": "Victor Larchenko", + "author": "Victor Larchenko, Ultimaker", "version": "1.0.0", "description": "Allows loading and displaying G-code files.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/GCodeWriter/plugin.json b/plugins/GCodeWriter/plugin.json index 3bbbab8b95..78b63a582f 100644 --- a/plugins/GCodeWriter/plugin.json +++ b/plugins/GCodeWriter/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Writes g-code to a file.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/ImageReader/plugin.json b/plugins/ImageReader/plugin.json index 08195863e8..001da0822b 100644 --- a/plugins/ImageReader/plugin.json +++ b/plugins/ImageReader/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Enables ability to generate printable geometry from 2D image files.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/LegacyProfileReader/plugin.json b/plugins/LegacyProfileReader/plugin.json index 179f5444e0..2cd1e9ca2c 100644 --- a/plugins/LegacyProfileReader/plugin.json +++ b/plugins/LegacyProfileReader/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Provides support for importing profiles from legacy Cura versions.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/MachineSettingsAction/plugin.json b/plugins/MachineSettingsAction/plugin.json index 571658e40a..4587729a9a 100644 --- a/plugins/MachineSettingsAction/plugin.json +++ b/plugins/MachineSettingsAction/plugin.json @@ -3,6 +3,6 @@ "author": "fieldOfView", "version": "1.0.0", "description": "Provides a way to change machine settings (such as build volume, nozzle size, etc.).", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/ModelChecker/plugin.json b/plugins/ModelChecker/plugin.json index 3753c0cc88..a210c3bf9f 100644 --- a/plugins/ModelChecker/plugin.json +++ b/plugins/ModelChecker/plugin.json @@ -2,7 +2,7 @@ "name": "Model Checker", "author": "Ultimaker B.V.", "version": "0.1", - "api": 5, + "api": "6.0", "description": "Checks models and print configuration for possible printing issues and give suggestions.", "i18n-catalog": "cura" } diff --git a/plugins/MonitorStage/plugin.json b/plugins/MonitorStage/plugin.json index 88b53840e0..71fc10c5ce 100644 --- a/plugins/MonitorStage/plugin.json +++ b/plugins/MonitorStage/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Provides a monitor stage in Cura.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } \ No newline at end of file diff --git a/plugins/PerObjectSettingsTool/plugin.json b/plugins/PerObjectSettingsTool/plugin.json index 15fde63387..e5bdc5d3da 100644 --- a/plugins/PerObjectSettingsTool/plugin.json +++ b/plugins/PerObjectSettingsTool/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Provides the Per Model Settings.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/PostProcessingPlugin/plugin.json b/plugins/PostProcessingPlugin/plugin.json index fea061e93b..ad60312af0 100644 --- a/plugins/PostProcessingPlugin/plugin.json +++ b/plugins/PostProcessingPlugin/plugin.json @@ -2,7 +2,7 @@ "name": "Post Processing", "author": "Ultimaker", "version": "2.2", - "api": 5, + "api": "6.0", "description": "Extension that allows for user created scripts for post processing", "catalog": "cura" } \ No newline at end of file diff --git a/plugins/PrepareStage/plugin.json b/plugins/PrepareStage/plugin.json index f0464313c7..e948b96f6f 100644 --- a/plugins/PrepareStage/plugin.json +++ b/plugins/PrepareStage/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Provides a prepare stage in Cura.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } \ No newline at end of file diff --git a/plugins/PreviewStage/plugin.json b/plugins/PreviewStage/plugin.json index 9349da2b0e..c9c13fe341 100644 --- a/plugins/PreviewStage/plugin.json +++ b/plugins/PreviewStage/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Provides a preview stage in Cura.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } \ No newline at end of file diff --git a/plugins/RemovableDriveOutputDevice/plugin.json b/plugins/RemovableDriveOutputDevice/plugin.json index 36bb9ae186..48cd60596c 100644 --- a/plugins/RemovableDriveOutputDevice/plugin.json +++ b/plugins/RemovableDriveOutputDevice/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "description": "Provides removable drive hotplugging and writing support.", "version": "1.0.0", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/SimulationView/plugin.json b/plugins/SimulationView/plugin.json index 93df98068f..dcfbeb305e 100644 --- a/plugins/SimulationView/plugin.json +++ b/plugins/SimulationView/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Provides the Simulation view.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/SliceInfoPlugin/plugin.json b/plugins/SliceInfoPlugin/plugin.json index 939e5ff235..c2d78e8d78 100644 --- a/plugins/SliceInfoPlugin/plugin.json +++ b/plugins/SliceInfoPlugin/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Submits anonymous slice info. Can be disabled through preferences.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/SolidView/plugin.json b/plugins/SolidView/plugin.json index e70ec224dd..c66e41a7aa 100644 --- a/plugins/SolidView/plugin.json +++ b/plugins/SolidView/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Provides a normal solid mesh view.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } \ No newline at end of file diff --git a/plugins/SupportEraser/plugin.json b/plugins/SupportEraser/plugin.json index 7af35e0fb5..dc624ecd77 100644 --- a/plugins/SupportEraser/plugin.json +++ b/plugins/SupportEraser/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Creates an eraser mesh to block the printing of support in certain places", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/Toolbox/plugin.json b/plugins/Toolbox/plugin.json index 2557185524..91e9561327 100644 --- a/plugins/Toolbox/plugin.json +++ b/plugins/Toolbox/plugin.json @@ -2,6 +2,6 @@ "name": "Toolbox", "author": "Ultimaker B.V.", "version": "1.0.0", - "api": 5, + "api": "6.0", "description": "Find, manage and install new Cura packages." } diff --git a/plugins/UFPWriter/plugin.json b/plugins/UFPWriter/plugin.json index ab590353e0..b4e05d9346 100644 --- a/plugins/UFPWriter/plugin.json +++ b/plugins/UFPWriter/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Provides support for writing Ultimaker Format Packages.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } \ No newline at end of file diff --git a/plugins/UM3NetworkPrinting/plugin.json b/plugins/UM3NetworkPrinting/plugin.json index d415338374..def02562db 100644 --- a/plugins/UM3NetworkPrinting/plugin.json +++ b/plugins/UM3NetworkPrinting/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "description": "Manages network connections to Ultimaker 3 printers.", "version": "1.0.0", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/USBPrinting/plugin.json b/plugins/USBPrinting/plugin.json index 5d3cba8415..3a58abe7e7 100644 --- a/plugins/USBPrinting/plugin.json +++ b/plugins/USBPrinting/plugin.json @@ -2,7 +2,7 @@ "name": "USB printing", "author": "Ultimaker B.V.", "version": "1.0.1", - "api": 5, + "api": "6.0", "description": "Accepts G-Code and sends them to a printer. Plugin can also update firmware.", "i18n-catalog": "cura" } diff --git a/plugins/UltimakerMachineActions/plugin.json b/plugins/UltimakerMachineActions/plugin.json index b60c7df88e..fc1eb242fe 100644 --- a/plugins/UltimakerMachineActions/plugin.json +++ b/plugins/UltimakerMachineActions/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Provides machine actions for Ultimaker machines (such as bed leveling wizard, selecting upgrades, etc.).", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/UserAgreement/plugin.json b/plugins/UserAgreement/plugin.json index 50a2aa0441..7781e383d6 100644 --- a/plugins/UserAgreement/plugin.json +++ b/plugins/UserAgreement/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Ask the user once if he/she agrees with our license.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/plugin.json b/plugins/VersionUpgrade/VersionUpgrade21to22/plugin.json index 463fcdc941..e732c43813 100644 --- a/plugins/VersionUpgrade/VersionUpgrade21to22/plugin.json +++ b/plugins/VersionUpgrade/VersionUpgrade21to22/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Upgrades configurations from Cura 2.1 to Cura 2.2.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/VersionUpgrade/VersionUpgrade22to24/plugin.json b/plugins/VersionUpgrade/VersionUpgrade22to24/plugin.json index e7a0b1c559..2b344ce5d3 100644 --- a/plugins/VersionUpgrade/VersionUpgrade22to24/plugin.json +++ b/plugins/VersionUpgrade/VersionUpgrade22to24/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Upgrades configurations from Cura 2.2 to Cura 2.4.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/VersionUpgrade/VersionUpgrade25to26/plugin.json b/plugins/VersionUpgrade/VersionUpgrade25to26/plugin.json index 3029539887..8691ebfc67 100644 --- a/plugins/VersionUpgrade/VersionUpgrade25to26/plugin.json +++ b/plugins/VersionUpgrade/VersionUpgrade25to26/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Upgrades configurations from Cura 2.5 to Cura 2.6.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/VersionUpgrade/VersionUpgrade26to27/plugin.json b/plugins/VersionUpgrade/VersionUpgrade26to27/plugin.json index 225da67235..c7124eada6 100644 --- a/plugins/VersionUpgrade/VersionUpgrade26to27/plugin.json +++ b/plugins/VersionUpgrade/VersionUpgrade26to27/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Upgrades configurations from Cura 2.6 to Cura 2.7.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/VersionUpgrade/VersionUpgrade27to30/plugin.json b/plugins/VersionUpgrade/VersionUpgrade27to30/plugin.json index 9a139851ec..ce8f4a6d44 100644 --- a/plugins/VersionUpgrade/VersionUpgrade27to30/plugin.json +++ b/plugins/VersionUpgrade/VersionUpgrade27to30/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Upgrades configurations from Cura 2.7 to Cura 3.0.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/VersionUpgrade/VersionUpgrade30to31/plugin.json b/plugins/VersionUpgrade/VersionUpgrade30to31/plugin.json index cf42b3f6cd..f94f3dfe30 100644 --- a/plugins/VersionUpgrade/VersionUpgrade30to31/plugin.json +++ b/plugins/VersionUpgrade/VersionUpgrade30to31/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Upgrades configurations from Cura 3.0 to Cura 3.1.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/VersionUpgrade/VersionUpgrade32to33/plugin.json b/plugins/VersionUpgrade/VersionUpgrade32to33/plugin.json index f9cc968dae..0bbc237436 100644 --- a/plugins/VersionUpgrade/VersionUpgrade32to33/plugin.json +++ b/plugins/VersionUpgrade/VersionUpgrade32to33/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Upgrades configurations from Cura 3.2 to Cura 3.3.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/VersionUpgrade/VersionUpgrade33to34/plugin.json b/plugins/VersionUpgrade/VersionUpgrade33to34/plugin.json index f5ba7235d1..5f83695245 100644 --- a/plugins/VersionUpgrade/VersionUpgrade33to34/plugin.json +++ b/plugins/VersionUpgrade/VersionUpgrade33to34/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Upgrades configurations from Cura 3.3 to Cura 3.4.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/VersionUpgrade/VersionUpgrade34to35/plugin.json b/plugins/VersionUpgrade/VersionUpgrade34to35/plugin.json index b73001b683..f95cb7be87 100644 --- a/plugins/VersionUpgrade/VersionUpgrade34to35/plugin.json +++ b/plugins/VersionUpgrade/VersionUpgrade34to35/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Upgrades configurations from Cura 3.4 to Cura 3.5.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/X3DReader/plugin.json b/plugins/X3DReader/plugin.json index 9ee09e43df..4052ac6605 100644 --- a/plugins/X3DReader/plugin.json +++ b/plugins/X3DReader/plugin.json @@ -3,6 +3,6 @@ "author": "Seva Alekseyev", "version": "0.5.0", "description": "Provides support for reading X3D files.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/XRayView/plugin.json b/plugins/XRayView/plugin.json index 576dec4656..4d8e42bae3 100644 --- a/plugins/XRayView/plugin.json +++ b/plugins/XRayView/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Provides the X-Ray view.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/XmlMaterialProfile/plugin.json b/plugins/XmlMaterialProfile/plugin.json index 4b2901c375..d172d49f87 100644 --- a/plugins/XmlMaterialProfile/plugin.json +++ b/plugins/XmlMaterialProfile/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "description": "Provides capabilities to read and write XML-based material profiles.", - "api": 5, + "api": "6.0", "i18n-catalog": "cura" } From 46c950a5b9afa7b2805924da7f5811f84e60c7ba Mon Sep 17 00:00:00 2001 From: Danny Tuppeny Date: Sun, 16 Dec 2018 19:57:43 +0000 Subject: [PATCH 0974/1292] Add Monoprice Ultimate based on Wanhao D6 The default values on my Monoprice Ultimate are way different to what Cura has the Wanhao Duplicator 6 as. I'm guessing that Monoprice have changed these (if not, then maybe the Duplicator 6 file is wrong?). Without this profile, I had a 4hr print estimate for a piece that's only 55% through after 4hours. With this profile, it estimates 7:22 (which seems very accurate). I got the default values from the printer when I connected Octoprint to it: ``` 21:20:56: Attempting to connect to printer 21:20:56: Connection opened < 21:20:57: start > 21:20:57: N1 M110 *2 < 21:20:57: echo:Marlin 1.0.0 > 21:20:57: N2 M110 *1 < 21:20:57: echo: Last Updated: Jun 26 2016 12:14:19 | Author: Version DEV 3.01 > 21:20:57: N3 M115 *5 < 21:20:57: Compiled: Jun 26 2016 < 21:20:57: echo: Free Memory: 1961 PlannerBufferBytes: 1232 < 21:20:57: echo:Stored settings retrieved < 21:20:57: echo:Steps per unit: < 21:20:57: echo: M92 X80.04 Y80.04 Z400.48 E94.30 < 21:20:57: echo:Maximum feedrates (mm/s): < 21:20:57: echo: M203 X300.00 Y300.00 Z5.00 E25.00 < 21:20:57: echo:Maximum Acceleration (mm/s2): < 21:20:57: echo: M201 X3000 Y3000 Z100 E500 < 21:20:57: echo:Acceleration: S=acceleration, T=retract acceleration < 21:20:57: echo: M204 S800.00 T800.00 < 21:20:57: echo:Advanced variables: S=Min feedrate (mm/s), T=Min travel feedrate (mm/s), B=minimum segment time (ms), X=maximum XY jerk (mm/s), Z=maximum Z jerk (mm/s), E=maximum E jerk (mm/s) < 21:20:57: echo: M205 S0.00 T0.00 B20000 X10.00 Z0.40 E1.00 < 21:20:57: echo:Home offset (mm): < 21:20:57: echo: M206 X0.00 Y0.00 Z0.40 ``` --- .../definitions/monoprice_ultimate.def.json | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 resources/definitions/monoprice_ultimate.def.json diff --git a/resources/definitions/monoprice_ultimate.def.json b/resources/definitions/monoprice_ultimate.def.json new file mode 100644 index 0000000000..48290f0941 --- /dev/null +++ b/resources/definitions/monoprice_ultimate.def.json @@ -0,0 +1,52 @@ +{ + "version": 2, + "name": "Monoprice Ultimate", + "inherits": "wanhao_d6", + "metadata": { + "visible": true, + "author": "Danny Tuppeny", + "manufacturer": "monoprice", + "file_formats": "text/x-gcode", + "icon": "wanhao-icon.png", + "has_materials": true, + "platform": "wanhao_200_200_platform.obj", + "platform_texture": "Wanhaobackplate.png", + "machine_extruder_trains": { + "0": "wanhao_d6_extruder_0" + }, + "platform_offset": [ + 0, + -28, + 0 + ] + }, + "overrides": { + "machine_name": { + "default_value": "Monoprice Ultimate" + }, + "machine_max_acceleration_x": { + "default_value": 3000 + }, + "machine_max_acceleration_y": { + "default_value": 3000 + }, + "machine_max_acceleration_z": { + "default_value": 100 + }, + "machine_max_acceleration_e": { + "default_value": 500 + }, + "machine_acceleration": { + "default_value": 800 + }, + "machine_max_jerk_xy": { + "default_value": 10.0 + }, + "machine_max_jerk_z": { + "default_value": 0.4 + }, + "machine_max_jerk_e": { + "default_value": 1.0 + } + } +} From 36ccef420926b0bc38b94c701e5e92405747071d Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 17 Dec 2018 09:08:32 +0100 Subject: [PATCH 0975/1292] Remove duplicate iconColor property in the IconWithText component Probably it was a mistake in a merge conflict --- resources/qml/IconWithText.qml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/resources/qml/IconWithText.qml b/resources/qml/IconWithText.qml index dd522031c1..97983dd7ce 100644 --- a/resources/qml/IconWithText.qml +++ b/resources/qml/IconWithText.qml @@ -19,7 +19,6 @@ Item property alias color: label.color property alias text: label.text property alias font: label.font - property alias iconColor: icon.color property real margin: UM.Theme.getSize("narrow_margin").width // These properties can be used in combination with layouts. @@ -40,7 +39,7 @@ Item width: UM.Theme.getSize("section_icon").width height: width - color: UM.Theme.getColor("icon") + color: label.color anchors { From 328f32615369f0a5e0bd2c4729fb5fe9dfc7c4ae Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 17 Dec 2018 09:15:47 +0100 Subject: [PATCH 0976/1292] Use a specific color for the icons --- resources/qml/IconWithText.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/IconWithText.qml b/resources/qml/IconWithText.qml index 97983dd7ce..24b6dc7fe2 100644 --- a/resources/qml/IconWithText.qml +++ b/resources/qml/IconWithText.qml @@ -39,7 +39,7 @@ Item width: UM.Theme.getSize("section_icon").width height: width - color: label.color + color: UM.Theme.getColor("icon") anchors { From 77deabf6d4d2f6ceee9bb536c53b8516acb08f7c Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 17 Dec 2018 09:43:24 +0100 Subject: [PATCH 0977/1292] Code style --- .../resources/qml/MonitorStage.qml | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml index 4d59e0eb6b..150bc49254 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml @@ -34,14 +34,18 @@ Component name: "cura" } - LinearGradient { + LinearGradient + { anchors.fill: parent - gradient: Gradient { - GradientStop { + gradient: Gradient + { + GradientStop + { position: 0.0 color: "#f6f6f6" } - GradientStop { + GradientStop + { position: 1.0 color: "#ffffff" } @@ -81,7 +85,8 @@ Component id: queue width: Math.min(834 * screenScaleFactor, maximumWidth) - anchors { + anchors + { bottom: parent.bottom horizontalCenter: parent.horizontalCenter top: printers.bottom @@ -210,7 +215,8 @@ Component ScrollView { id: queuedPrintJobs - anchors { + anchors + { bottom: parent.bottom horizontalCenter: parent.horizontalCenter top: printJobQueueHeadings.bottom @@ -239,7 +245,8 @@ Component } } - PrinterVideoStream { + PrinterVideoStream + { anchors.fill: parent cameraUrl: OutputDevice.activeCameraUrl visible: OutputDevice.activeCameraUrl != "" From 8d6a281070e1fb222324edaa2a99230c347aa540 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 17 Dec 2018 09:58:38 +0100 Subject: [PATCH 0978/1292] Increment SDK version in bundled packages file And increment the version number of every package. Contributes to issue CURA-6019. --- resources/bundled_packages/cura.json | 364 +++++++++++++-------------- 1 file changed, 182 insertions(+), 182 deletions(-) diff --git a/resources/bundled_packages/cura.json b/resources/bundled_packages/cura.json index 384b7d0412..c32b94af3f 100644 --- a/resources/bundled_packages/cura.json +++ b/resources/bundled_packages/cura.json @@ -5,8 +5,8 @@ "package_type": "plugin", "display_name": "3MF Reader", "description": "Provides support for reading 3MF files.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -22,8 +22,8 @@ "package_type": "plugin", "display_name": "3MF Writer", "description": "Provides support for writing 3MF files.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -39,8 +39,8 @@ "package_type": "plugin", "display_name": "Change Log", "description": "Shows changes since latest checked version.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -56,8 +56,8 @@ "package_type": "plugin", "display_name": "CuraEngine Backend", "description": "Provides the link to the CuraEngine slicing backend.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -73,8 +73,8 @@ "package_type": "plugin", "display_name": "Cura Profile Reader", "description": "Provides support for importing Cura profiles.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -90,8 +90,8 @@ "package_type": "plugin", "display_name": "Cura Profile Writer", "description": "Provides support for exporting Cura profiles.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -107,8 +107,8 @@ "package_type": "plugin", "display_name": "Firmware Update Checker", "description": "Checks for firmware updates.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -124,8 +124,8 @@ "package_type": "plugin", "display_name": "Firmware Updater", "description": "Provides a machine actions for updating firmware.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -141,8 +141,8 @@ "package_type": "plugin", "display_name": "Compressed G-code Reader", "description": "Reads g-code from a compressed archive.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -158,8 +158,8 @@ "package_type": "plugin", "display_name": "Compressed G-code Writer", "description": "Writes g-code to a compressed archive.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -175,8 +175,8 @@ "package_type": "plugin", "display_name": "G-Code Profile Reader", "description": "Provides support for importing profiles from g-code files.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -192,8 +192,8 @@ "package_type": "plugin", "display_name": "G-Code Reader", "description": "Allows loading and displaying G-code files.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "VictorLarchenko", @@ -209,8 +209,8 @@ "package_type": "plugin", "display_name": "G-Code Writer", "description": "Writes g-code to a file.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -226,8 +226,8 @@ "package_type": "plugin", "display_name": "Image Reader", "description": "Enables ability to generate printable geometry from 2D image files.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -243,8 +243,8 @@ "package_type": "plugin", "display_name": "Legacy Cura Profile Reader", "description": "Provides support for importing profiles from legacy Cura versions.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -260,8 +260,8 @@ "package_type": "plugin", "display_name": "Machine Settings Action", "description": "Provides a way to change machine settings (such as build volume, nozzle size, etc.).", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "fieldOfView", @@ -277,8 +277,8 @@ "package_type": "plugin", "display_name": "Model Checker", "description": "Checks models and print configuration for possible printing issues and give suggestions.", - "package_version": "0.1.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -294,8 +294,8 @@ "package_type": "plugin", "display_name": "Monitor Stage", "description": "Provides a monitor stage in Cura.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -311,8 +311,8 @@ "package_type": "plugin", "display_name": "Per-Object Settings Tool", "description": "Provides the per-model settings.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -328,8 +328,8 @@ "package_type": "plugin", "display_name": "Post Processing", "description": "Extension that allows for user created scripts for post processing.", - "package_version": "2.2.0", - "sdk_version": 5, + "package_version": "2.2.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -345,8 +345,8 @@ "package_type": "plugin", "display_name": "Prepare Stage", "description": "Provides a prepare stage in Cura.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -362,8 +362,8 @@ "package_type": "plugin", "display_name": "Preview Stage", "description": "Provides a preview stage in Cura.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -379,8 +379,8 @@ "package_type": "plugin", "display_name": "Removable Drive Output Device", "description": "Provides removable drive hotplugging and writing support.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -396,8 +396,8 @@ "package_type": "plugin", "display_name": "Simulation View", "description": "Provides the Simulation view.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -413,8 +413,8 @@ "package_type": "plugin", "display_name": "Slice Info", "description": "Submits anonymous slice info. Can be disabled through preferences.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -430,8 +430,8 @@ "package_type": "plugin", "display_name": "Solid View", "description": "Provides a normal solid mesh view.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -447,8 +447,8 @@ "package_type": "plugin", "display_name": "Support Eraser Tool", "description": "Creates an eraser mesh to block the printing of support in certain places.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -464,8 +464,8 @@ "package_type": "plugin", "display_name": "Toolbox", "description": "Find, manage and install new Cura packages.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -481,8 +481,8 @@ "package_type": "plugin", "display_name": "UFP Writer", "description": "Provides support for writing Ultimaker Format Packages.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -498,8 +498,8 @@ "package_type": "plugin", "display_name": "Ultimaker Machine Actions", "description": "Provides machine actions for Ultimaker machines (such as bed leveling wizard, selecting upgrades, etc.).", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -515,8 +515,8 @@ "package_type": "plugin", "display_name": "UM3 Network Printing", "description": "Manages network connections to Ultimaker 3 printers.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -532,8 +532,8 @@ "package_type": "plugin", "display_name": "USB Printing", "description": "Accepts G-Code and sends them to a printer. Plugin can also update firmware.", - "package_version": "1.0.1", - "sdk_version": 5, + "package_version": "1.0.2", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -549,8 +549,8 @@ "package_type": "plugin", "display_name": "User Agreement", "description": "Ask the user once if he/she agrees with our license.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -566,8 +566,8 @@ "package_type": "plugin", "display_name": "Version Upgrade 2.1 to 2.2", "description": "Upgrades configurations from Cura 2.1 to Cura 2.2.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -583,8 +583,8 @@ "package_type": "plugin", "display_name": "Version Upgrade 2.2 to 2.4", "description": "Upgrades configurations from Cura 2.2 to Cura 2.4.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -600,8 +600,8 @@ "package_type": "plugin", "display_name": "Version Upgrade 2.5 to 2.6", "description": "Upgrades configurations from Cura 2.5 to Cura 2.6.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -617,8 +617,8 @@ "package_type": "plugin", "display_name": "Version Upgrade 2.6 to 2.7", "description": "Upgrades configurations from Cura 2.6 to Cura 2.7.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -634,8 +634,8 @@ "package_type": "plugin", "display_name": "Version Upgrade 2.7 to 3.0", "description": "Upgrades configurations from Cura 2.7 to Cura 3.0.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -651,8 +651,8 @@ "package_type": "plugin", "display_name": "Version Upgrade 3.0 to 3.1", "description": "Upgrades configurations from Cura 3.0 to Cura 3.1.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -668,8 +668,8 @@ "package_type": "plugin", "display_name": "Version Upgrade 3.2 to 3.3", "description": "Upgrades configurations from Cura 3.2 to Cura 3.3.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -685,8 +685,8 @@ "package_type": "plugin", "display_name": "Version Upgrade 3.3 to 3.4", "description": "Upgrades configurations from Cura 3.3 to Cura 3.4.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -702,8 +702,8 @@ "package_type": "plugin", "display_name": "Version Upgrade 3.4 to 3.5", "description": "Upgrades configurations from Cura 3.4 to Cura 3.5.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -719,8 +719,8 @@ "package_type": "plugin", "display_name": "X3D Reader", "description": "Provides support for reading X3D files.", - "package_version": "0.5.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "SevaAlekseyev", @@ -736,8 +736,8 @@ "package_type": "plugin", "display_name": "XML Material Profiles", "description": "Provides capabilities to read and write XML-based material profiles.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -753,8 +753,8 @@ "package_type": "plugin", "display_name": "X-Ray View", "description": "Provides the X-Ray view.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", @@ -770,8 +770,8 @@ "package_type": "material", "display_name": "Generic ABS", "description": "The generic ABS profile which other profiles can be based upon.", - "package_version": "1.2.0", - "sdk_version": 5, + "package_version": "1.2.1", + "sdk_version": "6.0", "website": "https://github.com/Ultimaker/fdm_materials", "author": { "author_id": "Generic", @@ -788,8 +788,8 @@ "package_type": "material", "display_name": "Generic BAM", "description": "The generic BAM profile which other profiles can be based upon.", - "package_version": "1.2.0", - "sdk_version": 5, + "package_version": "1.2.1", + "sdk_version": "6.0", "website": "https://github.com/Ultimaker/fdm_materials", "author": { "author_id": "Generic", @@ -806,8 +806,8 @@ "package_type": "material", "display_name": "Generic CFF CPE", "description": "The generic CFF CPE profile which other profiles can be based upon.", - "package_version": "1.1.0", - "sdk_version": 5, + "package_version": "1.1.1", + "sdk_version": "6.0", "website": "https://github.com/Ultimaker/fdm_materials", "author": { "author_id": "Generic", @@ -824,8 +824,8 @@ "package_type": "material", "display_name": "Generic CFF PA", "description": "The generic CFF PA profile which other profiles can be based upon.", - "package_version": "1.1.0", - "sdk_version": 5, + "package_version": "1.1.1", + "sdk_version": "6.0", "website": "https://github.com/Ultimaker/fdm_materials", "author": { "author_id": "Generic", @@ -842,8 +842,8 @@ "package_type": "material", "display_name": "Generic CPE", "description": "The generic CPE profile which other profiles can be based upon.", - "package_version": "1.2.0", - "sdk_version": 5, + "package_version": "1.2.1", + "sdk_version": "6.0", "website": "https://github.com/Ultimaker/fdm_materials", "author": { "author_id": "Generic", @@ -860,8 +860,8 @@ "package_type": "material", "display_name": "Generic CPE+", "description": "The generic CPE+ profile which other profiles can be based upon.", - "package_version": "1.2.0", - "sdk_version": 5, + "package_version": "1.2.1", + "sdk_version": "6.0", "website": "https://github.com/Ultimaker/fdm_materials", "author": { "author_id": "Generic", @@ -878,8 +878,8 @@ "package_type": "material", "display_name": "Generic GFF CPE", "description": "The generic GFF CPE profile which other profiles can be based upon.", - "package_version": "1.1.0", - "sdk_version": 5, + "package_version": "1.1.1", + "sdk_version": "6.0", "website": "https://github.com/Ultimaker/fdm_materials", "author": { "author_id": "Generic", @@ -896,8 +896,8 @@ "package_type": "material", "display_name": "Generic GFF PA", "description": "The generic GFF PA profile which other profiles can be based upon.", - "package_version": "1.1.0", - "sdk_version": 5, + "package_version": "1.1.1", + "sdk_version": "6.0", "website": "https://github.com/Ultimaker/fdm_materials", "author": { "author_id": "Generic", @@ -914,8 +914,8 @@ "package_type": "material", "display_name": "Generic HIPS", "description": "The generic HIPS profile which other profiles can be based upon.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://github.com/Ultimaker/fdm_materials", "author": { "author_id": "Generic", @@ -932,8 +932,8 @@ "package_type": "material", "display_name": "Generic Nylon", "description": "The generic Nylon profile which other profiles can be based upon.", - "package_version": "1.2.0", - "sdk_version": 5, + "package_version": "1.2.1", + "sdk_version": "6.0", "website": "https://github.com/Ultimaker/fdm_materials", "author": { "author_id": "Generic", @@ -950,8 +950,8 @@ "package_type": "material", "display_name": "Generic PC", "description": "The generic PC profile which other profiles can be based upon.", - "package_version": "1.2.0", - "sdk_version": 5, + "package_version": "1.2.1", + "sdk_version": "6.0", "website": "https://github.com/Ultimaker/fdm_materials", "author": { "author_id": "Generic", @@ -968,8 +968,8 @@ "package_type": "material", "display_name": "Generic PETG", "description": "The generic PETG profile which other profiles can be based upon.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://github.com/Ultimaker/fdm_materials", "author": { "author_id": "Generic", @@ -986,8 +986,8 @@ "package_type": "material", "display_name": "Generic PLA", "description": "The generic PLA profile which other profiles can be based upon.", - "package_version": "1.2.0", - "sdk_version": 5, + "package_version": "1.2.1", + "sdk_version": "6.0", "website": "https://github.com/Ultimaker/fdm_materials", "author": { "author_id": "Generic", @@ -1004,8 +1004,8 @@ "package_type": "material", "display_name": "Generic PP", "description": "The generic PP profile which other profiles can be based upon.", - "package_version": "1.2.0", - "sdk_version": 5, + "package_version": "1.2.1", + "sdk_version": "6.0", "website": "https://github.com/Ultimaker/fdm_materials", "author": { "author_id": "Generic", @@ -1022,8 +1022,8 @@ "package_type": "material", "display_name": "Generic PVA", "description": "The generic PVA profile which other profiles can be based upon.", - "package_version": "1.2.0", - "sdk_version": 5, + "package_version": "1.2.1", + "sdk_version": "6.0", "website": "https://github.com/Ultimaker/fdm_materials", "author": { "author_id": "Generic", @@ -1040,8 +1040,8 @@ "package_type": "material", "display_name": "Generic Tough PLA", "description": "The generic Tough PLA profile which other profiles can be based upon.", - "package_version": "1.0.1", - "sdk_version": 5, + "package_version": "1.0.2", + "sdk_version": "6.0", "website": "https://github.com/Ultimaker/fdm_materials", "author": { "author_id": "Generic", @@ -1058,8 +1058,8 @@ "package_type": "material", "display_name": "Generic TPU", "description": "The generic TPU profile which other profiles can be based upon.", - "package_version": "1.2.0", - "sdk_version": 5, + "package_version": "1.2.1", + "sdk_version": "6.0", "website": "https://github.com/Ultimaker/fdm_materials", "author": { "author_id": "Generic", @@ -1076,8 +1076,8 @@ "package_type": "material", "display_name": "Dagoma Chromatik PLA", "description": "Filament testé et approuvé pour les imprimantes 3D Dagoma. Chromatik est l'idéal pour débuter et suivre les tutoriels premiers pas. Il vous offre qualité et résistance pour chacune de vos impressions.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://dagoma.fr/boutique/filaments.html", "author": { "author_id": "Dagoma", @@ -1093,8 +1093,8 @@ "package_type": "material", "display_name": "FABtotum ABS", "description": "This material is easy to be extruded but it is not the simplest to use. It is one of the most used in 3D printing to get very well finished objects. It is not sustainable and its smoke can be dangerous if inhaled. The reason to prefer this filament to PLA is mainly because of its precision and mechanical specs. ABS (for plastic) stands for Acrylonitrile Butadiene Styrene and it is a thermoplastic which is widely used in everyday objects. It can be printed with any FFF 3D printer which can get to high temperatures as it must be extruded in a range between 220° and 245°, so it’s compatible with all versions of the FABtotum Personal fabricator.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://store.fabtotum.com/eu/products/filaments.html?filament_type=40", "author": { "author_id": "FABtotum", @@ -1110,8 +1110,8 @@ "package_type": "material", "display_name": "FABtotum Nylon", "description": "When 3D printing started this material was not listed among the extrudable filaments. It is flexible as well as resistant to tractions. It is well known for its uses in textile but also in industries which require a strong and flexible material. There are different kinds of Nylon: 3D printing mostly uses Nylon 6 and Nylon 6.6, which are the most common. It requires higher temperatures to be printed, so a 3D printer must be able to reach them (around 240°C): the FABtotum, of course, can.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://store.fabtotum.com/eu/products/filaments.html?filament_type=53", "author": { "author_id": "FABtotum", @@ -1127,8 +1127,8 @@ "package_type": "material", "display_name": "FABtotum PLA", "description": "It is the most common filament used for 3D printing. It is studied to be bio-degradable as it comes from corn starch’s sugar mainly. It is completely made of renewable sources and has no footprint on polluting. PLA stands for PolyLactic Acid and it is a thermoplastic that today is still considered the easiest material to be 3D printed. It can be extruded at lower temperatures: the standard range of FABtotum’s one is between 185° and 195°.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://store.fabtotum.com/eu/products/filaments.html?filament_type=39", "author": { "author_id": "FABtotum", @@ -1144,8 +1144,8 @@ "package_type": "material", "display_name": "FABtotum TPU Shore 98A", "description": "", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://store.fabtotum.com/eu/products/filaments.html?filament_type=66", "author": { "author_id": "FABtotum", @@ -1161,8 +1161,8 @@ "package_type": "material", "display_name": "Fiberlogy HD PLA", "description": "With our HD PLA you have many more options. You can use this material in two ways. Choose the one you like best. You can use it as a normal PLA and get prints characterized by a very good adhesion between the layers and high precision. You can also make your prints acquire similar properties to that of ABS – better impact resistance and high temperature resistance. All you need is an oven. Yes, an oven! By annealing our HD PLA in an oven, in accordance with the manual, you will avoid all the inconveniences of printing with ABS, such as unpleasant odour or hazardous fumes.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "http://fiberlogy.com/en/fiberlogy-filaments/filament-hd-pla/", "author": { "author_id": "Fiberlogy", @@ -1178,8 +1178,8 @@ "package_type": "material", "display_name": "Filo3D PLA", "description": "Fast, safe and reliable printing. PLA is ideal for the fast and reliable printing of parts and prototypes with a great surface quality.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://dagoma.fr", "author": { "author_id": "Dagoma", @@ -1195,8 +1195,8 @@ "package_type": "material", "display_name": "IMADE3D JellyBOX PETG", "description": "", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "http://shop.imade3d.com/filament.html", "author": { "author_id": "IMADE3D", @@ -1212,8 +1212,8 @@ "package_type": "material", "display_name": "IMADE3D JellyBOX PLA", "description": "", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "http://shop.imade3d.com/filament.html", "author": { "author_id": "IMADE3D", @@ -1229,8 +1229,8 @@ "package_type": "material", "display_name": "Octofiber PLA", "description": "PLA material from Octofiber.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://nl.octofiber.com/3d-printing-filament/pla.html", "author": { "author_id": "Octofiber", @@ -1246,8 +1246,8 @@ "package_type": "material", "display_name": "PolyFlex™ PLA", "description": "PolyFlex™ is a highly flexible yet easy to print 3D printing material. Featuring good elasticity and a large strain-to- failure, PolyFlex™ opens up a completely new realm of applications.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "http://www.polymaker.com/shop/polyflex/", "author": { "author_id": "Polymaker", @@ -1263,8 +1263,8 @@ "package_type": "material", "display_name": "PolyMax™ PLA", "description": "PolyMax™ PLA is a 3D printing material with excellent mechanical properties and printing quality. PolyMax™ PLA has an impact resistance of up to nine times that of regular PLA, and better overall mechanical properties than ABS.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "http://www.polymaker.com/shop/polymax/", "author": { "author_id": "Polymaker", @@ -1280,8 +1280,8 @@ "package_type": "material", "display_name": "PolyPlus™ PLA True Colour", "description": "PolyPlus™ PLA is a premium PLA designed for all desktop FDM/FFF 3D printers. It is produced with our patented Jam-Free™ technology that ensures consistent extrusion and prevents jams.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "http://www.polymaker.com/shop/polyplus-true-colour/", "author": { "author_id": "Polymaker", @@ -1297,8 +1297,8 @@ "package_type": "material", "display_name": "PolyWood™ PLA", "description": "PolyWood™ is a wood mimic printing material that contains no actual wood ensuring a clean Jam-Free™ printing experience.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "http://www.polymaker.com/shop/polywood/", "author": { "author_id": "Polymaker", @@ -1314,8 +1314,8 @@ "package_type": "material", "display_name": "Ultimaker ABS", "description": "Example package for material and quality profiles for Ultimaker materials.", - "package_version": "1.2.0", - "sdk_version": 5, + "package_version": "1.2.1", + "sdk_version": "6.0", "website": "https://ultimaker.com/products/materials/abs", "author": { "author_id": "UltimakerPackages", @@ -1333,8 +1333,8 @@ "package_type": "material", "display_name": "Ultimaker Breakaway", "description": "Example package for material and quality profiles for Ultimaker materials.", - "package_version": "1.2.0", - "sdk_version": 5, + "package_version": "1.2.1", + "sdk_version": "6.0", "website": "https://ultimaker.com/products/materials/breakaway", "author": { "author_id": "UltimakerPackages", @@ -1352,8 +1352,8 @@ "package_type": "material", "display_name": "Ultimaker CPE", "description": "Example package for material and quality profiles for Ultimaker materials.", - "package_version": "1.2.0", - "sdk_version": 5, + "package_version": "1.2.1", + "sdk_version": "6.0", "website": "https://ultimaker.com/products/materials/abs", "author": { "author_id": "UltimakerPackages", @@ -1371,8 +1371,8 @@ "package_type": "material", "display_name": "Ultimaker CPE+", "description": "Example package for material and quality profiles for Ultimaker materials.", - "package_version": "1.2.0", - "sdk_version": 5, + "package_version": "1.2.1", + "sdk_version": "6.0", "website": "https://ultimaker.com/products/materials/cpe", "author": { "author_id": "UltimakerPackages", @@ -1390,8 +1390,8 @@ "package_type": "material", "display_name": "Ultimaker Nylon", "description": "Example package for material and quality profiles for Ultimaker materials.", - "package_version": "1.2.0", - "sdk_version": 5, + "package_version": "1.2.1", + "sdk_version": "6.0", "website": "https://ultimaker.com/products/materials/abs", "author": { "author_id": "UltimakerPackages", @@ -1409,8 +1409,8 @@ "package_type": "material", "display_name": "Ultimaker PC", "description": "Example package for material and quality profiles for Ultimaker materials.", - "package_version": "1.2.0", - "sdk_version": 5, + "package_version": "1.2.1", + "sdk_version": "6.0", "website": "https://ultimaker.com/products/materials/pc", "author": { "author_id": "UltimakerPackages", @@ -1428,8 +1428,8 @@ "package_type": "material", "display_name": "Ultimaker PLA", "description": "Example package for material and quality profiles for Ultimaker materials.", - "package_version": "1.2.0", - "sdk_version": 5, + "package_version": "1.2.1", + "sdk_version": "6.0", "website": "https://ultimaker.com/products/materials/abs", "author": { "author_id": "UltimakerPackages", @@ -1447,8 +1447,8 @@ "package_type": "material", "display_name": "Ultimaker PP", "description": "Example package for material and quality profiles for Ultimaker materials.", - "package_version": "1.2.0", - "sdk_version": 5, + "package_version": "1.2.1", + "sdk_version": "6.0", "website": "https://ultimaker.com/products/materials/pp", "author": { "author_id": "UltimakerPackages", @@ -1466,8 +1466,8 @@ "package_type": "material", "display_name": "Ultimaker PVA", "description": "Example package for material and quality profiles for Ultimaker materials.", - "package_version": "1.2.0", - "sdk_version": 5, + "package_version": "1.2.1", + "sdk_version": "6.0", "website": "https://ultimaker.com/products/materials/abs", "author": { "author_id": "UltimakerPackages", @@ -1485,8 +1485,8 @@ "package_type": "material", "display_name": "Ultimaker TPU 95A", "description": "Example package for material and quality profiles for Ultimaker materials.", - "package_version": "1.2.0", - "sdk_version": 5, + "package_version": "1.2.1", + "sdk_version": "6.0", "website": "https://ultimaker.com/products/materials/tpu-95a", "author": { "author_id": "UltimakerPackages", @@ -1504,8 +1504,8 @@ "package_type": "material", "display_name": "Ultimaker Tough PLA", "description": "Example package for material and quality profiles for Ultimaker materials.", - "package_version": "1.0.2", - "sdk_version": 5, + "package_version": "1.0.3", + "sdk_version": "6.0", "website": "https://ultimaker.com/products/materials/tough-pla", "author": { "author_id": "UltimakerPackages", @@ -1523,8 +1523,8 @@ "package_type": "material", "display_name": "Vertex Delta ABS", "description": "ABS material and quality files for the Delta Vertex K8800.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://vertex3dprinter.eu", "author": { "author_id": "Velleman", @@ -1540,8 +1540,8 @@ "package_type": "material", "display_name": "Vertex Delta PET", "description": "ABS material and quality files for the Delta Vertex K8800.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://vertex3dprinter.eu", "author": { "author_id": "Velleman", @@ -1557,8 +1557,8 @@ "package_type": "material", "display_name": "Vertex Delta PLA", "description": "ABS material and quality files for the Delta Vertex K8800.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://vertex3dprinter.eu", "author": { "author_id": "Velleman", @@ -1574,8 +1574,8 @@ "package_type": "material", "display_name": "Vertex Delta TPU", "description": "ABS material and quality files for the Delta Vertex K8800.", - "package_version": "1.0.0", - "sdk_version": 5, + "package_version": "1.0.1", + "sdk_version": "6.0", "website": "https://vertex3dprinter.eu", "author": { "author_id": "Velleman", From ff1a0e30f6f9dbebad72e90079df1ee23c42c437 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 17 Dec 2018 10:42:41 +0100 Subject: [PATCH 0979/1292] Code style & comments --- plugins/MonitorStage/MonitorMain.qml | 2 +- plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/MonitorStage/MonitorMain.qml b/plugins/MonitorStage/MonitorMain.qml index 1f287fc0fa..8f113735ee 100644 --- a/plugins/MonitorStage/MonitorMain.qml +++ b/plugins/MonitorStage/MonitorMain.qml @@ -35,6 +35,6 @@ Item property real maximumWidth: parent.width property real maximumHeight: parent.height - sourceComponent: Cura.MachineManager.printerOutputDevices.length > 0 ? Cura.MachineManager.printerOutputDevices[0].monitorItem: null + sourceComponent: Cura.MachineManager.printerOutputDevices.length > 0 ? Cura.MachineManager.printerOutputDevices[0].monitorItem : null } } diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml index 150bc49254..98ca715108 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml @@ -42,12 +42,12 @@ Component GradientStop { position: 0.0 - color: "#f6f6f6" + color: "#f6f6f6" // TODO: Theme! } GradientStop { position: 1.0 - color: "#ffffff" + color: "#ffffff" // TODO: Theme! } } } From cbd8e72bd5061547573bad6c847110268b5ec64a Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 17 Dec 2018 10:42:52 +0100 Subject: [PATCH 0980/1292] Add fixed width to the preview button Doing that, the elide will work. Also increase the size of the panel a bit so it will fit better in other languages. Adding also the tooltip in case the text is too long in other languages. --- resources/qml/ActionPanel/OutputProcessWidget.qml | 2 ++ resources/themes/cura-light/theme.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/resources/qml/ActionPanel/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml index b6aa9289f5..eb6dc5b417 100644 --- a/resources/qml/ActionPanel/OutputProcessWidget.qml +++ b/resources/qml/ActionPanel/OutputProcessWidget.qml @@ -120,6 +120,8 @@ Column height: UM.Theme.getSize("action_button").height text: catalog.i18nc("@button", "Preview") + tooltip: text + fixedWidthMode: true onClicked: UM.Controller.setActiveStage("PreviewStage") visible: UM.Controller.activeStage != null && UM.Controller.activeStage.stageId != "PreviewStage" diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 2ff014bd31..ea6c92b479 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -361,7 +361,7 @@ "configuration_selector": [35.0, 4.0], "configuration_selector_mode_tabs": [0.0, 3.0], - "action_panel_widget": [25.0, 0.0], + "action_panel_widget": [26.0, 0.0], "action_panel_information_widget": [20.0, 0.0], "machine_selector_widget": [20.0, 4.0], From 938287095f3c2705b97df881feba30924733f291 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 17 Dec 2018 10:47:14 +0100 Subject: [PATCH 0981/1292] Use connection type instead of um_network_key to see if a printer has a network connection CURA-6011 --- cura/Settings/MachineManager.py | 9 ++++++++- .../qml/Menus/ConfigurationMenu/ConfigurationMenu.qml | 2 +- resources/qml/MonitorSidebar.qml | 4 ++-- resources/qml/PrinterSelector/MachineSelector.qml | 2 +- resources/qml/PrinterSelector/MachineSelectorList.qml | 1 + 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index c375ce01d1..342f53aac6 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -23,7 +23,7 @@ from UM.Settings.SettingFunction import SettingFunction from UM.Signal import postponeSignals, CompressTechnique from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch -from cura.PrinterOutputDevice import PrinterOutputDevice +from cura.PrinterOutputDevice import PrinterOutputDevice, ConnectionType from cura.PrinterOutput.ConfigurationModel import ConfigurationModel from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel @@ -521,6 +521,13 @@ class MachineManager(QObject): def printerConnected(self): return bool(self._printer_output_devices) + @pyqtProperty(bool, notify=printerConnectedStatusChanged) + def activeMachineHasRemoteConnection(self) -> bool: + if self._global_container_stack: + connection_type = self._global_container_stack.getMetaDataEntry("connection_type") + return connection_type in [ConnectionType.NetworkConnection, ConnectionType.CloudConnection] + return False + @pyqtProperty(str, notify = printerConnectedStatusChanged) def activeMachineNetworkKey(self) -> str: if self._global_container_stack: diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index 33a317b42b..8e9c276c0d 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -134,7 +134,7 @@ Cura.ExpandablePopup property bool is_connected: false //If current machine is connected to a printer. Only evaluated upon making popup visible. onVisibleChanged: { - is_connected = Cura.MachineManager.activeMachineNetworkKey !== "" && Cura.MachineManager.printerConnected //Re-evaluate. + is_connected = Cura.MachineManager.activeMachineHasRemoteConnection && Cura.MachineManager.printerConnected //Re-evaluate. } property int configuration_method: is_connected ? ConfigurationMenu.ConfigurationMethod.Auto : ConfigurationMenu.ConfigurationMethod.Custom //Auto if connected to a printer at start-up, or Custom if not. diff --git a/resources/qml/MonitorSidebar.qml b/resources/qml/MonitorSidebar.qml index 669bdbfb8f..70ee60377d 100644 --- a/resources/qml/MonitorSidebar.qml +++ b/resources/qml/MonitorSidebar.qml @@ -21,7 +21,7 @@ Rectangle property bool hideView: Cura.MachineManager.activeMachineName == "" // Is there an output device for this printer? - property bool isNetworkPrinter: Cura.MachineManager.activeMachineNetworkKey != "" + property bool isNetworkPrinter: Cura.MachineManager.activeMachineHasRemoteConnection property bool printerConnected: Cura.MachineManager.printerConnected property bool printerAcceptsCommands: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands property var connectedPrinter: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null @@ -205,7 +205,7 @@ Rectangle target: Cura.MachineManager onGlobalContainerChanged: { - base.isNetworkPrinter = Cura.MachineManager.activeMachineNetworkKey != "" + base.isNetworkPrinter = Cura.MachineManager.activeMachineHasRemoteConnection base.printerConnected = Cura.MachineManager.printerOutputDevices.length != 0 } } diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index 6e120e89c7..8a7b87f409 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -11,7 +11,7 @@ Cura.ExpandablePopup { id: machineSelector - property bool isNetworkPrinter: Cura.MachineManager.activeMachineNetworkKey != "" + property bool isNetworkPrinter: Cura.MachineManager.activeMachineHasRemoteConnection property bool isPrinterConnected: Cura.MachineManager.printerConnected property var outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null diff --git a/resources/qml/PrinterSelector/MachineSelectorList.qml b/resources/qml/PrinterSelector/MachineSelectorList.qml index b157f9a4f6..e0dc6f5e44 100644 --- a/resources/qml/PrinterSelector/MachineSelectorList.qml +++ b/resources/qml/PrinterSelector/MachineSelectorList.qml @@ -30,6 +30,7 @@ ListView { text: model.name width: listView.width + outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null } } /* From ed4d339deec699098ac70971edbd44d3d56a269d Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 17 Dec 2018 11:00:49 +0100 Subject: [PATCH 0982/1292] Change the margin in the view orientation buttons to aling the pixels correctly --- resources/qml/ViewOrientationButton.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/ViewOrientationButton.qml b/resources/qml/ViewOrientationButton.qml index 5371f8549b..5d72de9a8d 100644 --- a/resources/qml/ViewOrientationButton.qml +++ b/resources/qml/ViewOrientationButton.qml @@ -11,5 +11,5 @@ UM.SimpleButton height: UM.Theme.getSize("small_button").height hoverColor: UM.Theme.getColor("small_button_text_hover") color: UM.Theme.getColor("small_button_text") - iconMargin: 0.5 * UM.Theme.getSize("wide_lining").width + iconMargin: UM.Theme.getSize("thick_lining").width } \ No newline at end of file From 9f4b7bd70362a3f7c77ebda0ee77d52ee68ca945 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 17 Dec 2018 11:28:16 +0100 Subject: [PATCH 0983/1292] STAR-322: Improving logging and cluster connection --- cura/OAuth2/AuthorizationService.py | 3 +- .../src/Cloud/CloudApiClient.py | 29 ++++++++------ .../src/Cloud/CloudOutputDevice.py | 40 +++++++++++-------- .../src/Cloud/CloudOutputDeviceManager.py | 11 +++-- .../src/ClusterUM3OutputDevice.py | 2 +- .../src/ClusterUM3PrinterOutputController.py | 1 - 6 files changed, 51 insertions(+), 35 deletions(-) diff --git a/cura/OAuth2/AuthorizationService.py b/cura/OAuth2/AuthorizationService.py index 21dbbe8248..0c3074f3d5 100644 --- a/cura/OAuth2/AuthorizationService.py +++ b/cura/OAuth2/AuthorizationService.py @@ -52,7 +52,8 @@ class AuthorizationService: if not self._user_profile: # If no user profile was stored locally, we try to get it from JWT. self._user_profile = self._parseJWT() - if not self._user_profile: + + if not self._user_profile and self._auth_data: # If there is still no user profile from the JWT, we have to log in again. Logger.log("w", "The user profile could not be loaded. The user must log in again!") self.deleteAuthData() diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py index b54c9e97d6..5fd14efc9c 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py @@ -2,6 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. import json from json import JSONDecodeError +from time import time from typing import Callable, List, Type, TypeVar, Union, Optional, Tuple, Dict, Any from PyQt5.QtCore import QUrl @@ -38,6 +39,8 @@ class CloudApiClient: self._account = account self._on_error = on_error self._upload = None # type: Optional[MeshUploader] + # in order to avoid garbage collection we keep the callbacks in this list. + self._anti_gc_callbacks = [] # type: List[Callable[[QNetworkReply], None]] ## Gets the account used for the API. @property @@ -49,8 +52,7 @@ class CloudApiClient: def getClusters(self, on_finished: Callable[[List[CloudClusterResponse]], Any]) -> None: url = "{}/clusters".format(self.CLUSTER_API_ROOT) reply = self._manager.get(self._createEmptyRequest(url)) - callback = self._wrapCallback(reply, on_finished, CloudClusterResponse) - reply.finished.connect(callback) + self._addCallbacks(reply, on_finished, CloudClusterResponse) ## Retrieves the status of the given cluster. # \param cluster_id: The ID of the cluster. @@ -58,8 +60,7 @@ class CloudApiClient: def getClusterStatus(self, cluster_id: str, on_finished: Callable[[CloudClusterStatus], Any]) -> None: url = "{}/clusters/{}/status".format(self.CLUSTER_API_ROOT, cluster_id) reply = self._manager.get(self._createEmptyRequest(url)) - callback = self._wrapCallback(reply, on_finished, CloudClusterStatus) - reply.finished.connect(callback) + self._addCallbacks(reply, on_finished, CloudClusterStatus) ## Requests the cloud to register the upload of a print job mesh. # \param request: The request object. @@ -69,8 +70,7 @@ class CloudApiClient: url = "{}/jobs/upload".format(self.CURA_API_ROOT) body = json.dumps({"data": request.toDict()}) reply = self._manager.put(self._createEmptyRequest(url), body.encode()) - callback = self._wrapCallback(reply, on_finished, CloudPrintJobResponse) - reply.finished.connect(callback) + self._addCallbacks(reply, on_finished, CloudPrintJobResponse) ## Requests the cloud to register the upload of a print job mesh. # \param upload_response: The object received after requesting an upload with `self.requestUpload`. @@ -90,8 +90,7 @@ class CloudApiClient: def requestPrint(self, cluster_id: str, job_id: str, on_finished: Callable[[CloudPrintResponse], Any]) -> None: url = "{}/clusters/{}/print/{}".format(self.CLUSTER_API_ROOT, cluster_id, job_id) reply = self._manager.post(self._createEmptyRequest(url), b"") - callback = self._wrapCallback(reply, on_finished, CloudPrintResponse) - reply.finished.connect(callback) + self._addCallbacks(reply, on_finished, CloudPrintResponse) ## We override _createEmptyRequest in order to add the user credentials. # \param url: The URL to request @@ -116,9 +115,10 @@ class CloudApiClient: Logger.log("i", "Received a reply %s from %s with %s", status_code, reply.url().toString(), response) return status_code, json.loads(response) except (UnicodeDecodeError, JSONDecodeError, ValueError) as err: - error = {"code": type(err).__name__, "title": str(err), "http_code": str(status_code)} + error = CloudErrorObject(code=type(err).__name__, title=str(err), http_code=str(status_code), + id=str(time()), http_status="500") Logger.logException("e", "Could not parse the stardust response: %s", error) - return status_code, {"errors": [error]} + return status_code, {"errors": [error.toDict()]} ## The generic type variable used to document the methods below. Model = TypeVar("Model", bound=BaseModel) @@ -143,12 +143,15 @@ class CloudApiClient: # \param on_finished: The callback in case the response is successful. # \param model: The type of the model to convert the response to. It may either be a single record or a list. # \return: A function that can be passed to the - def _wrapCallback(self, + def _addCallbacks(self, reply: QNetworkReply, on_finished: Callable[[Union[Model, List[Model]]], Any], model: Type[Model], - ) -> Callable[[QNetworkReply], None]: + ) -> None: def parse() -> None: status_code, response = self._parseReply(reply) + self._anti_gc_callbacks.remove(parse) return self._parseModels(response, on_finished, model) - return parse + + self._anti_gc_callbacks.append(parse) + reply.finished.connect(parse) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 88c2f8da1d..3890e7cee2 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -18,6 +18,7 @@ from cura.CuraApplication import CuraApplication from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState, NetworkedPrinterOutputDevice from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputController import CloudOutputController +from src.Cloud.Models.CloudClusterResponse import CloudClusterResponse from ..MeshFormatHandler import MeshFormatHandler from ..UM3PrintJobOutputModel import UM3PrintJobOutputModel from .CloudProgressMessage import CloudProgressMessage @@ -84,18 +85,15 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # \param api_client: The client that will run the API calls # \param device_id: The ID of the device (i.e. the cluster_id for the cloud API) # \param parent: The optional parent of this output device. - def __init__(self, api_client: CloudApiClient, device_id: str, host_name: str, parent: QObject = None) -> None: - super().__init__(device_id = device_id, address = "", properties = {}, parent = parent) + def __init__(self, api_client: CloudApiClient, cluster: CloudClusterResponse, parent: QObject = None) -> None: + super().__init__(device_id = cluster.cluster_id, address = "", properties = {}, parent = parent) self._api = api_client - self._host_name = host_name + self._cluster = cluster self._setInterfaceElements() - self._device_id = device_id self._account = api_client.account - CuraApplication.getInstance().getBackend().backendStateChange.connect(self._onBackendStateChange) - # We use the Cura Connect monitor tab to get most functionality right away. self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../resources/qml/MonitorStage.qml") @@ -124,7 +122,14 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self._mesh = None # type: Optional[bytes] self._uploaded_print_job = None # type: Optional[CloudPrintJobResponse] + def connect(self) -> None: + super().connect() + Logger.log("i", "Connected to cluster %s", self.key) + CuraApplication.getInstance().getBackend().backendStateChange.connect(self._onBackendStateChange) + def disconnect(self) -> None: + super().disconnect() + Logger.log("i", "Disconnected to cluster %s", self.key) CuraApplication.getInstance().getBackend().backendStateChange.disconnect(self._onBackendStateChange) def _onBackendStateChange(self, _: BackendState) -> None: @@ -133,19 +138,19 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## Gets the host name of this device @property - def host_name(self) -> str: - return self._host_name + def clusterData(self) -> CloudClusterResponse: + return self._cluster ## Updates the host name of the output device - @host_name.setter - def host_name(self, value: str) -> None: - self._host_name = value + @clusterData.setter + def clusterData(self, value: CloudClusterResponse) -> None: + self._cluster = value ## Checks whether the given network key is found in the cloud's host name def matchesNetworkKey(self, network_key: str) -> bool: # A network key looks like "ultimakersystem-aabbccdd0011._ultimaker._tcp.local." # the host name should then be "ultimakersystem-aabbccdd0011" - return network_key.startswith(self._host_name) + return network_key.startswith(self.clusterData.host_name) ## Set all the interface elements and texts for this output device. def _setInterfaceElements(self) -> None: @@ -170,7 +175,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): if self._uploaded_print_job: # the mesh didn't change, let's not upload it again - self._api.requestPrint(self._device_id, self._uploaded_print_job.job_id, self._onPrintRequested) + self._api.requestPrint(self.key, self._uploaded_print_job.job_id, self._onPrintRequested) return # Indicate we have started sending a job. @@ -194,12 +199,15 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## Called when the network data should be updated. def _update(self) -> None: super()._update() - if self._last_response_time and time() - self._last_response_time < self.CHECK_CLUSTER_INTERVAL: + if self._last_request_time and time() - self._last_request_time < self.CHECK_CLUSTER_INTERVAL: + Logger.log("i", "Not updating: %s - %s < %s", time(), self._last_request_time, self.CHECK_CLUSTER_INTERVAL) return # avoid calling the cloud too often + Logger.log("i", "Updating: %s - %s >= %s", time(), self._last_request_time, self.CHECK_CLUSTER_INTERVAL) if self._account.isLoggedIn: self.setAuthenticationState(AuthState.Authenticated) - self._api.getClusterStatus(self._device_id, self._onStatusCallFinished) + self._last_request_time = time() + self._api.getClusterStatus(self.key, self._onStatusCallFinished) else: self.setAuthenticationState(AuthState.NotAuthenticated) @@ -315,7 +323,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## Requests the print to be sent to the printer when we finished uploading the mesh. def _onPrintJobUploaded(self) -> None: self._progress.update(100) - self._api.requestPrint(self._device_id, self._uploaded_print_job.job_id, self._onPrintRequested) + self._api.requestPrint(self.key, self._uploaded_print_job.job_id, self._onPrintRequested) ## Displays the given message if uploading the mesh has failed # \param message: The message to display. diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index af80907f01..29c60fd14a 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -73,7 +73,8 @@ class CloudOutputDeviceManager: removed_devices, added_clusters, updates = findChanges(self._remote_clusters, online_clusters) - Logger.log("i", "Parsed remote clusters to %s", online_clusters) + Logger.log("i", "Parsed remote clusters to %s", [cluster.toDict() for cluster in online_clusters.values()]) + Logger.log("i", "Removed: %s, added: %s, updates: %s", len(removed_devices), len(added_clusters), len(updates)) # Remove output devices that are gone for removed_cluster in removed_devices: @@ -86,12 +87,12 @@ class CloudOutputDeviceManager: # Add an output device for each new remote cluster. # We only add when is_online as we don't want the option in the drop down if the cluster is not online. for added_cluster in added_clusters: - device = CloudOutputDevice(self._api, added_cluster.cluster_id, added_cluster.host_name) + device = CloudOutputDevice(self._api, added_cluster) self._output_device_manager.addOutputDevice(device) self._remote_clusters[added_cluster.cluster_id] = device for device, cluster in updates: - device.host_name = cluster.host_name + device.clusterData = cluster self._connectToActiveMachine() @@ -99,6 +100,7 @@ class CloudOutputDeviceManager: def _connectToActiveMachine(self) -> None: active_machine = CuraApplication.getInstance().getGlobalContainerStack() if not active_machine: + Logger.log("i", "no active machine") return # Check if the stored cluster_id for the active machine is in our list of remote clusters. @@ -107,6 +109,7 @@ class CloudOutputDeviceManager: device = self._remote_clusters[stored_cluster_id] if not device.isConnected(): device.connect() + Logger.log("i", "Device connected by metadata %s", stored_cluster_id) else: self._connectByNetworkKey(active_machine) @@ -122,6 +125,8 @@ class CloudOutputDeviceManager: active_machine.setMetaDataEntry(self.META_CLUSTER_ID, device.key) device.connect() + Logger.log("i", "Found cluster %s with network key %s", device, local_network_key) + ## Handles an API error received from the cloud. # \param errors: The errors received def _onApiError(self, errors: List[CloudErrorObject]) -> None: diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index 96fee0d96d..1896ffac9c 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -390,10 +390,10 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): ## Called when the connection to the cluster changes. def connect(self) -> None: - pass # TODO: uncomment this once cloud implementation works for testing # super().connect() # self.sendMaterialProfiles() + pass def _onGetPreviewImageFinished(self, reply: QNetworkReply) -> None: reply_url = reply.url().toString() diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3PrinterOutputController.py b/plugins/UM3NetworkPrinting/src/ClusterUM3PrinterOutputController.py index fcced0b883..fc6798386a 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3PrinterOutputController.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3PrinterOutputController.py @@ -18,4 +18,3 @@ class ClusterUM3PrinterOutputController(PrinterOutputController): def setJobState(self, job: "PrintJobOutputModel", state: str): data = "{\"action\": \"%s\"}" % state self._output_device.put("print_jobs/%s/action" % job.key, data, on_finished=None) - From 6178f9ddf62e193865558f7ac8e4e2975c57a316 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 17 Dec 2018 11:49:09 +0100 Subject: [PATCH 0984/1292] Improve code style and line lengths --- .../resources/qml/UM3InfoComponents.qml | 40 +++++++++++++++++-- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml b/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml index 42e3b7d160..320201e165 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml @@ -13,8 +13,40 @@ Item { property string activeQualityDefinitionId: Cura.MachineManager.activeQualityDefinitionId; property bool isUM3: activeQualityDefinitionId == "ultimaker3" || activeQualityDefinitionId.match("ultimaker_") != null; property bool printerConnected: Cura.MachineManager.printerConnected; - property bool printerAcceptsCommands: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands; - property bool authenticationRequested: printerConnected && (Cura.MachineManager.printerOutputDevices[0].authenticationState == 2 || Cura.MachineManager.printerOutputDevices[0].authenticationState == 5); // AuthState.AuthenticationRequested or AuthenticationReceived. + property bool printerAcceptsCommands: + { + if (printerConnected && Cura.MachineManager.printerOutputDevices[0]) + { + return Cura.MachineManager.printerOutputDevices[0].acceptsCommands + } + return false + } + property bool authenticationRequested: + { + if (printerConnected && Cura.MachineManager.printerOutputDevices[0]) + { + var device = Cura.MachineManager.printerOutputDevices[0] + // AuthState.AuthenticationRequested or AuthState.AuthenticationReceived + return device.authenticationState == 2 || device.authenticationState == 5 + } + return false + } + property var materialNames: + { + if (printerConnected && Cura.MachineManager.printerOutputDevices[0]) + { + return Cura.MachineManager.printerOutputDevices[0].materialNames + } + return null + } + property var hotendIds: + { + if (printerConnected && Cura.MachineManager.printerOutputDevices[0]) + { + return Cura.MachineManager.printerOutputDevices[0].hotendIds + } + return null + } UM.I18nCatalog { id: catalog; @@ -94,7 +126,7 @@ Item { Column { Repeater { id: nozzleColumn; - model: printerConnected ? Cura.MachineManager.printerOutputDevices[0].hotendIds : null; + model: hotendIds Label { text: nozzleColumn.model[index]; @@ -105,7 +137,7 @@ Item { Column { Repeater { id: materialColumn; - model: printerConnected ? Cura.MachineManager.printerOutputDevices[0].materialNames : null; + model: materialNames Label { text: materialColumn.model[index]; From 9eb743bcb8b1619769f0c6679bb3378b9c813231 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 17 Dec 2018 12:01:10 +0100 Subject: [PATCH 0985/1292] STAR-322: Making mypy happy --- cura/NetworkClient.py | 57 +++++++++++-------- cura/Settings/SimpleModeSettingsManager.py | 5 +- .../src/Cloud/CloudApiClient.py | 16 ++++-- .../src/Cloud/CloudOutputDevice.py | 13 +++-- .../src/Cloud/MeshUploader.py | 19 ++++--- 5 files changed, 64 insertions(+), 46 deletions(-) diff --git a/cura/NetworkClient.py b/cura/NetworkClient.py index 878158542a..fabaaed95e 100644 --- a/cura/NetworkClient.py +++ b/cura/NetworkClient.py @@ -1,7 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. from time import time -from typing import Optional, Dict, Callable, List, Union +from typing import Optional, Dict, Callable, List, Union, cast from PyQt5.QtCore import QUrl from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkReply, QHttpMultiPart, QNetworkRequest, QHttpPart, \ @@ -19,7 +19,7 @@ class NetworkClient: super().__init__() # Network manager instance to use for this client. - self._manager = None # type: Optional[QNetworkAccessManager] + self.__manager = None # type: Optional[QNetworkAccessManager] # Timings. self._last_manager_create_time = None # type: Optional[float] @@ -34,20 +34,26 @@ class NetworkClient: # HTTP which uses them. We hold references to these QHttpMultiPart objects here. self._kept_alive_multiparts = {} # type: Dict[QNetworkReply, QHttpMultiPart] + # in order to avoid garbage collection we keep the callbacks in this list. + self._anti_gc_callbacks = [] # type: List[Callable[[], None]] + ## Creates a network manager if needed, with all the required properties and event bindings. def start(self) -> None: - if self._manager: - return - self._manager = QNetworkAccessManager() - self._last_manager_create_time = time() - self._manager.authenticationRequired.connect(self._onAuthenticationRequired) + if not self.__manager: + self.__manager = QNetworkAccessManager() + self._last_manager_create_time = time() + self.__manager.authenticationRequired.connect(self._onAuthenticationRequired) ## Destroys the network manager and event bindings. def stop(self) -> None: - if not self._manager: - return - self._manager.authenticationRequired.disconnect(self._onAuthenticationRequired) - self._manager = None + if self.__manager: + self.__manager.authenticationRequired.disconnect(self._onAuthenticationRequired) + self.__manager = None + + @property + def _manager(self) -> QNetworkAccessManager: + self.start() + return cast(QNetworkAccessManager, self.__manager) ## Create a new empty network request. # Automatically adds the required HTTP headers. @@ -94,13 +100,13 @@ class NetworkClient: return self._createFormPart(content_header, data, content_type) ## Sends a put request to the given path. - # url: The path after the API prefix. - # data: The data to be sent in the body - # content_type: The content type of the body data. - # on_finished: The function to call when the response is received. - # on_progress: The function to call when the progress changes. Parameters are bytes_sent / bytes_total. - def put(self, url: str, data: Union[str, bytes], content_type: Optional[str] = None, - on_finished: Optional[Callable[[QNetworkReply], None]] = None, + # \param url: The path after the API prefix. + # \param data: The data to be sent in the body + # \param content_type: The content type of the body data. + # \param on_finished: The function to call when the response is received. + # \param on_progress: The function to call when the progress changes. Parameters are bytes_sent / bytes_total. + def put(self, url: str, data: Union[str, bytes], content_type: str, + on_finished: Callable[[QNetworkReply], None], on_progress: Optional[Callable[[int, int], None]] = None) -> None: request = self._createEmptyRequest(url, content_type = content_type) @@ -114,7 +120,7 @@ class NetworkClient: ## Sends a delete request to the given path. # url: The path after the API prefix. # on_finished: The function to be call when the response is received. - def delete(self, url: str, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: + def delete(self, url: str, on_finished: Callable[[QNetworkReply], None]) -> None: request = self._createEmptyRequest(url) reply = self._manager.deleteResource(request) callback = self._createCallback(reply, on_finished) @@ -123,7 +129,7 @@ class NetworkClient: ## Sends a get request to the given path. # \param url: The path after the API prefix. # \param on_finished: The function to be call when the response is received. - def get(self, url: str, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: + def get(self, url: str, on_finished: Callable[[QNetworkReply], None]) -> None: request = self._createEmptyRequest(url) reply = self._manager.get(request) callback = self._createCallback(reply, on_finished) @@ -135,7 +141,7 @@ class NetworkClient: # \param on_finished: The function to call when the response is received. # \param on_progress: The function to call when the progress changes. Parameters are bytes_sent / bytes_total. def post(self, url: str, data: Union[str, bytes], - on_finished: Optional[Callable[[QNetworkReply], None]], + on_finished: Callable[[QNetworkReply], None], on_progress: Optional[Callable[[int, int], None]] = None) -> None: request = self._createEmptyRequest(url) @@ -180,6 +186,9 @@ class NetworkClient: return reply - @staticmethod - def _createCallback(reply: QNetworkReply, on_finished: Optional[Callable[[QNetworkReply], None]] = None): - return lambda: on_finished(reply) + def _createCallback(self, reply: QNetworkReply, on_finished: Callable[[QNetworkReply], None]) -> Callable[[], None]: + def callback(): + on_finished(reply) + self._anti_gc_callbacks.remove(callback) + self._anti_gc_callbacks.append(callback) + return callback diff --git a/cura/Settings/SimpleModeSettingsManager.py b/cura/Settings/SimpleModeSettingsManager.py index 210a5794d4..b22aea15ea 100644 --- a/cura/Settings/SimpleModeSettingsManager.py +++ b/cura/Settings/SimpleModeSettingsManager.py @@ -1,5 +1,6 @@ # Copyright (c) 2017 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +from typing import Set from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty, pyqtSlot @@ -63,10 +64,10 @@ class SimpleModeSettingsManager(QObject): @pyqtSlot() def updateIsProfileUserCreated(self) -> None: - quality_changes_keys = set() + quality_changes_keys = set() # type: Set[str] if not self._machine_manager.activeMachine: - return False + return global_stack = self._machine_manager.activeMachine diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py index 5fd14efc9c..d58def4545 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py @@ -3,7 +3,7 @@ import json from json import JSONDecodeError from time import time -from typing import Callable, List, Type, TypeVar, Union, Optional, Tuple, Dict, Any +from typing import Callable, List, Type, TypeVar, Union, Optional, Tuple, Dict, Any, cast from PyQt5.QtCore import QUrl from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply, QNetworkAccessManager @@ -40,7 +40,7 @@ class CloudApiClient: self._on_error = on_error self._upload = None # type: Optional[MeshUploader] # in order to avoid garbage collection we keep the callbacks in this list. - self._anti_gc_callbacks = [] # type: List[Callable[[QNetworkReply], None]] + self._anti_gc_callbacks = [] # type: List[Callable[[], None]] ## Gets the account used for the API. @property @@ -128,12 +128,16 @@ class CloudApiClient: # \param on_finished: The callback in case the response is successful. # \param model_class: The type of the model to convert the response to. It may either be a single record or a list. def _parseModels(self, response: Dict[str, Any], - on_finished: Callable[[Union[Model, List[Model]]], Any], + on_finished: Union[Callable[[Model], Any], Callable[[List[Model]], Any]], model_class: Type[Model]) -> None: if "data" in response: data = response["data"] - result = [model_class(**c) for c in data] if isinstance(data, list) else model_class(**data) - on_finished(result) + if isinstance(data, list): + results = [model_class(**c) for c in data] # type: List[CloudApiClient.Model] + cast(Callable[[List[CloudApiClient.Model]], Any], on_finished)(results) + else: + result = model_class(**data) # type: CloudApiClient.Model + cast(Callable[[CloudApiClient.Model], Any], on_finished)(result) elif "errors" in response: self._on_error([CloudErrorObject(**error) for error in response["errors"]]) else: @@ -145,7 +149,7 @@ class CloudApiClient: # \return: A function that can be passed to the def _addCallbacks(self, reply: QNetworkReply, - on_finished: Callable[[Union[Model, List[Model]]], Any], + on_finished: Union[Callable[[Model], Any], Callable[[List[Model]], Any]], model: Type[Model], ) -> None: def parse() -> None: diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 3890e7cee2..54f0dc20b6 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -3,7 +3,7 @@ import os from time import time -from typing import Dict, List, Optional, Set +from typing import Dict, List, Optional, Set, cast from PyQt5.QtCore import QObject, QUrl, pyqtProperty, pyqtSignal, pyqtSlot @@ -161,7 +161,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self.setConnectionText(T.CONNECTED_VIA_CLOUD) ## Called when Cura requests an output device to receive a (G-code) file. - def requestWrite(self, nodes: List[SceneNode], file_name: Optional[str] = None, limit_mime_types: bool = False, + def requestWrite(self, nodes: List[SceneNode], file_name: Optional[str] = None, limit_mimetypes: bool = False, file_handler: Optional[FileHandler] = None, **kwargs: str) -> None: # Show an error message if we're already sending a job. @@ -190,7 +190,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self._mesh = mesh request = CloudPrintJobUploadRequest( - job_name = file_name, + job_name = file_name or mesh_format.file_extension, file_size = len(mesh), content_type = mesh_format.mime_type, ) @@ -317,13 +317,14 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def _onPrintJobCreated(self, job_response: CloudPrintJobResponse) -> None: self._progress.show() self._uploaded_print_job = job_response - self._api.uploadMesh(job_response, self._mesh, self._onPrintJobUploaded, self._progress.update, - self._onUploadError) + mesh = cast(bytes, self._mesh) + self._api.uploadMesh(job_response, mesh, self._onPrintJobUploaded, self._progress.update, self._onUploadError) ## Requests the print to be sent to the printer when we finished uploading the mesh. def _onPrintJobUploaded(self) -> None: self._progress.update(100) - self._api.requestPrint(self.key, self._uploaded_print_job.job_id, self._onPrintRequested) + print_job = cast(CloudPrintJobResponse, self._uploaded_print_job) + self._api.requestPrint(self.key, print_job.job_id, self._onPrintRequested) ## Displays the given message if uploading the mesh has failed # \param message: The message to display. diff --git a/plugins/UM3NetworkPrinting/src/Cloud/MeshUploader.py b/plugins/UM3NetworkPrinting/src/Cloud/MeshUploader.py index 4f0d6f2e81..f0360b83e3 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/MeshUploader.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/MeshUploader.py @@ -3,7 +3,7 @@ # -*- coding: utf-8 -*- from PyQt5.QtCore import QUrl from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply, QNetworkAccessManager -from typing import Optional, Callable, Any, Tuple +from typing import Optional, Callable, Any, Tuple, cast from UM.Logger import Logger from src.Cloud.Models.CloudPrintJobResponse import CloudPrintJobResponse @@ -20,7 +20,8 @@ class MeshUploader: # \param http_method: The HTTP method to be used, e.g. "POST" or "PUT". # \param timeout: The timeout for each chunk upload. Important: If None, no timeout is applied at all. def __init__(self, manager: QNetworkAccessManager, print_job: CloudPrintJobResponse, data: bytes, - on_finished: Callable[[], Any], on_progress: Callable[[int], Any], on_error: Callable[[], Any]): + on_finished: Callable[[], Any], on_progress: Callable[[int], Any], on_error: Callable[[], Any] + ) -> None: self._manager = manager self._print_job = print_job self._data = data @@ -85,20 +86,22 @@ class MeshUploader: self._on_progress(int((self._sent_bytes + bytes_sent) / len(self._data) * 100)) def _errorCallback(self) -> None: - body = bytes(self._reply.readAll()).decode() + reply = cast(QNetworkReply, self._reply) + body = bytes(reply.readAll()).decode() Logger.log("e", "Received error while uploading: %s", body) self.stop() self._on_error() def _finishedCallback(self) -> None: + reply = cast(QNetworkReply, self._reply) Logger.log("i", "Finished callback %s %s", - self._reply.attribute(QNetworkRequest.HttpStatusCodeAttribute), self._reply.url().toString()) + reply.attribute(QNetworkRequest.HttpStatusCodeAttribute), reply.url().toString()) - status_code = self._reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) + status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) if self._retries < self.MAX_RETRIES and status_code in self.RETRY_HTTP_CODES: self._retries += 1 - Logger.log("i", "Retrying %s/%s request %s", self._retries, self.MAX_RETRIES, self._reply.url().toString()) + Logger.log("i", "Retrying %s/%s request %s", self._retries, self.MAX_RETRIES, reply.url().toString()) self._uploadChunk() return @@ -106,9 +109,9 @@ class MeshUploader: self._errorCallback() return - body = bytes(self._reply.readAll()).decode() + body = bytes(reply.readAll()).decode() Logger.log("w", "status_code: %s, Headers: %s, body: %s", status_code, - [bytes(header).decode() for header in self._reply.rawHeaderList()], body) + [bytes(header).decode() for header in reply.rawHeaderList()], body) first_byte, last_byte = self._chunkRange() self._sent_bytes += last_byte - first_byte From 87c1392173ce05785f9e4c981bb1cae86dcbacce Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 17 Dec 2018 12:05:25 +0100 Subject: [PATCH 0986/1292] STAR-322: Fixing tests --- .../tests/Cloud/TestCloudOutputDevice.py | 10 +++++++--- .../tests/Cloud/TestCloudOutputDeviceManager.py | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py index d31f59f85a..c42a208ece 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py @@ -10,6 +10,7 @@ from cura.CuraApplication import CuraApplication from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from src.Cloud.CloudApiClient import CloudApiClient from src.Cloud.CloudOutputDevice import CloudOutputDevice +from src.Cloud.Models.CloudClusterResponse import CloudClusterResponse from tests.Cloud.Fixtures import readFixture, parseFixture from .NetworkManagerMock import NetworkManagerMock @@ -18,6 +19,7 @@ class TestCloudOutputDevice(TestCase): CLUSTER_ID = "RIZ6cZbWA_Ua7RZVJhrdVfVpf0z-MqaSHQE4v8aRTtYq" JOB_ID = "ABCDefGHIjKlMNOpQrSTUvYxWZ0-1234567890abcDE=" HOST_NAME = "ultimakersystem-ccbdd30044ec" + HOST_GUID = "e90ae0ac-1257-4403-91ee-a44c9b7e8050" BASE_URL = "https://api-staging.ultimaker.com" STATUS_URL = "{}/connect/v1/clusters/{}/status".format(BASE_URL, CLUSTER_ID) @@ -29,13 +31,15 @@ class TestCloudOutputDevice(TestCase): self.app = CuraApplication.getInstance() self.backend = MagicMock(backendStateChange = Signal()) self.app.setBackend(self.backend) + self.cluster = CloudClusterResponse(self.CLUSTER_ID, self.HOST_GUID, self.HOST_NAME, is_online=True, + status="active") self.network = NetworkManagerMock() self.account = MagicMock(isLoggedIn=True, accessToken="TestAccessToken") self.onError = MagicMock() with patch("src.Cloud.CloudApiClient.QNetworkAccessManager", return_value = self.network): self._api = CloudApiClient(self.account, self.onError) - self.device = CloudOutputDevice(self._api, self.CLUSTER_ID, self.HOST_NAME) + self.device = CloudOutputDevice(self._api, self.cluster) self.cluster_status = parseFixture("getClusterStatusResponse") self.network.prepareReply("GET", self.STATUS_URL, 200, readFixture("getClusterStatusResponse")) @@ -81,7 +85,7 @@ class TestCloudOutputDevice(TestCase): self.cluster_status["data"]["print_jobs"].clear() self.network.prepareReply("GET", self.STATUS_URL, 200, self.cluster_status) - self.device._last_response_time = None + self.device._last_request_time = None self.device._update() self.network.flushReplies() self.assertEqual([], self.device.printJobs) @@ -94,7 +98,7 @@ class TestCloudOutputDevice(TestCase): self.cluster_status["data"]["printers"].clear() self.network.prepareReply("GET", self.STATUS_URL, 200, self.cluster_status) - self.device._last_response_time = None + self.device._last_request_time = None self.device._update() self.network.flushReplies() self.assertEqual([], self.device.printers) diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py index 80dd2c7990..f98e954274 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py @@ -41,7 +41,7 @@ class TestCloudOutputDeviceManager(TestCase): clusters = self.clusters_response.get("data", []) self.assertEqual([CloudOutputDevice] * len(clusters), [type(d) for d in devices]) self.assertEqual({cluster["cluster_id"] for cluster in clusters}, {device.key for device in devices}) - self.assertEqual({cluster["host_name"] for cluster in clusters}, {device.host_name for device in devices}) + self.assertEqual(clusters, [device.clusterData.toDict() for device in devices]) for device in clusters: device_manager.getOutputDevice(device["cluster_id"]).close() From ab83af3a0353bc308a5d417ebbaa7d0bc24b446a Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 17 Dec 2018 12:20:30 +0100 Subject: [PATCH 0987/1292] Fix code-style --- cura/Settings/SimpleModeSettingsManager.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cura/Settings/SimpleModeSettingsManager.py b/cura/Settings/SimpleModeSettingsManager.py index 210a5794d4..b22aea15ea 100644 --- a/cura/Settings/SimpleModeSettingsManager.py +++ b/cura/Settings/SimpleModeSettingsManager.py @@ -1,5 +1,6 @@ # Copyright (c) 2017 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +from typing import Set from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty, pyqtSlot @@ -63,10 +64,10 @@ class SimpleModeSettingsManager(QObject): @pyqtSlot() def updateIsProfileUserCreated(self) -> None: - quality_changes_keys = set() + quality_changes_keys = set() # type: Set[str] if not self._machine_manager.activeMachine: - return False + return global_stack = self._machine_manager.activeMachine From 6992fd299159dd7775a3406c5c798f5e00bbda62 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 17 Dec 2018 13:03:17 +0100 Subject: [PATCH 0988/1292] Update plugin versions to match package versions CURA-6019 --- plugins/3MFReader/plugin.json | 2 +- plugins/3MFWriter/plugin.json | 2 +- plugins/ChangeLogPlugin/plugin.json | 2 +- plugins/CuraEngineBackend/plugin.json | 2 +- plugins/CuraProfileReader/plugin.json | 2 +- plugins/CuraProfileWriter/plugin.json | 2 +- plugins/FirmwareUpdateChecker/plugin.json | 2 +- plugins/FirmwareUpdater/plugin.json | 2 +- plugins/GCodeGzReader/plugin.json | 2 +- plugins/GCodeGzWriter/plugin.json | 2 +- plugins/GCodeProfileReader/plugin.json | 2 +- plugins/GCodeReader/plugin.json | 2 +- plugins/GCodeWriter/plugin.json | 2 +- plugins/ImageReader/plugin.json | 2 +- plugins/LegacyProfileReader/plugin.json | 2 +- plugins/MachineSettingsAction/plugin.json | 2 +- plugins/ModelChecker/plugin.json | 2 +- plugins/MonitorStage/plugin.json | 2 +- plugins/PerObjectSettingsTool/plugin.json | 2 +- plugins/PostProcessingPlugin/plugin.json | 2 +- plugins/PrepareStage/plugin.json | 2 +- plugins/PreviewStage/plugin.json | 2 +- plugins/RemovableDriveOutputDevice/plugin.json | 2 +- plugins/SimulationView/plugin.json | 2 +- plugins/SliceInfoPlugin/plugin.json | 2 +- plugins/SolidView/plugin.json | 2 +- plugins/SupportEraser/plugin.json | 2 +- plugins/Toolbox/plugin.json | 2 +- plugins/UFPWriter/plugin.json | 2 +- plugins/UM3NetworkPrinting/plugin.json | 2 +- plugins/USBPrinting/plugin.json | 2 +- plugins/UltimakerMachineActions/plugin.json | 2 +- plugins/UserAgreement/plugin.json | 2 +- plugins/VersionUpgrade/VersionUpgrade21to22/plugin.json | 2 +- plugins/VersionUpgrade/VersionUpgrade22to24/plugin.json | 2 +- plugins/VersionUpgrade/VersionUpgrade25to26/plugin.json | 2 +- plugins/VersionUpgrade/VersionUpgrade26to27/plugin.json | 2 +- plugins/VersionUpgrade/VersionUpgrade27to30/plugin.json | 2 +- plugins/VersionUpgrade/VersionUpgrade30to31/plugin.json | 2 +- plugins/VersionUpgrade/VersionUpgrade32to33/plugin.json | 2 +- plugins/VersionUpgrade/VersionUpgrade33to34/plugin.json | 2 +- plugins/VersionUpgrade/VersionUpgrade34to35/plugin.json | 2 +- plugins/X3DReader/plugin.json | 2 +- plugins/XRayView/plugin.json | 2 +- plugins/XmlMaterialProfile/plugin.json | 2 +- 45 files changed, 45 insertions(+), 45 deletions(-) diff --git a/plugins/3MFReader/plugin.json b/plugins/3MFReader/plugin.json index d7160e166a..5af21a7033 100644 --- a/plugins/3MFReader/plugin.json +++ b/plugins/3MFReader/plugin.json @@ -1,7 +1,7 @@ { "name": "3MF Reader", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Provides support for reading 3MF files.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/3MFWriter/plugin.json b/plugins/3MFWriter/plugin.json index 865c3bf026..3820ebd2e7 100644 --- a/plugins/3MFWriter/plugin.json +++ b/plugins/3MFWriter/plugin.json @@ -1,7 +1,7 @@ { "name": "3MF Writer", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Provides support for writing 3MF files.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/ChangeLogPlugin/plugin.json b/plugins/ChangeLogPlugin/plugin.json index 04d5ce7c51..92041d1543 100644 --- a/plugins/ChangeLogPlugin/plugin.json +++ b/plugins/ChangeLogPlugin/plugin.json @@ -1,7 +1,7 @@ { "name": "Changelog", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Shows changes since latest checked version.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/CuraEngineBackend/plugin.json b/plugins/CuraEngineBackend/plugin.json index 25db9abefd..28f0e294e7 100644 --- a/plugins/CuraEngineBackend/plugin.json +++ b/plugins/CuraEngineBackend/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "description": "Provides the link to the CuraEngine slicing backend.", "api": "6.0", - "version": "1.0.0", + "version": "1.0.1", "i18n-catalog": "cura" } diff --git a/plugins/CuraProfileReader/plugin.json b/plugins/CuraProfileReader/plugin.json index adbf376b72..169fb43360 100644 --- a/plugins/CuraProfileReader/plugin.json +++ b/plugins/CuraProfileReader/plugin.json @@ -1,7 +1,7 @@ { "name": "Cura Profile Reader", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Provides support for importing Cura profiles.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/CuraProfileWriter/plugin.json b/plugins/CuraProfileWriter/plugin.json index d576f517de..9627c754d7 100644 --- a/plugins/CuraProfileWriter/plugin.json +++ b/plugins/CuraProfileWriter/plugin.json @@ -1,7 +1,7 @@ { "name": "Cura Profile Writer", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Provides support for exporting Cura profiles.", "api": "6.0", "i18n-catalog":"cura" diff --git a/plugins/FirmwareUpdateChecker/plugin.json b/plugins/FirmwareUpdateChecker/plugin.json index 4b77a53a62..6c55d77fd8 100644 --- a/plugins/FirmwareUpdateChecker/plugin.json +++ b/plugins/FirmwareUpdateChecker/plugin.json @@ -1,7 +1,7 @@ { "name": "Firmware Update Checker", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Checks for firmware updates.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/FirmwareUpdater/plugin.json b/plugins/FirmwareUpdater/plugin.json index 4098759630..c1034e5e42 100644 --- a/plugins/FirmwareUpdater/plugin.json +++ b/plugins/FirmwareUpdater/plugin.json @@ -1,7 +1,7 @@ { "name": "Firmware Updater", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Provides a machine actions for updating firmware.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/GCodeGzReader/plugin.json b/plugins/GCodeGzReader/plugin.json index cea1d0f55c..d4f281682f 100644 --- a/plugins/GCodeGzReader/plugin.json +++ b/plugins/GCodeGzReader/plugin.json @@ -1,7 +1,7 @@ { "name": "Compressed G-code Reader", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Reads g-code from a compressed archive.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/GCodeGzWriter/plugin.json b/plugins/GCodeGzWriter/plugin.json index d725b2649d..b0e6f8d605 100644 --- a/plugins/GCodeGzWriter/plugin.json +++ b/plugins/GCodeGzWriter/plugin.json @@ -1,7 +1,7 @@ { "name": "Compressed G-code Writer", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Writes g-code to a compressed archive.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/GCodeProfileReader/plugin.json b/plugins/GCodeProfileReader/plugin.json index 12d8a276da..af1c2d1827 100644 --- a/plugins/GCodeProfileReader/plugin.json +++ b/plugins/GCodeProfileReader/plugin.json @@ -1,7 +1,7 @@ { "name": "G-code Profile Reader", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Provides support for importing profiles from g-code files.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/GCodeReader/plugin.json b/plugins/GCodeReader/plugin.json index 351d6cbc31..bbc94fa917 100644 --- a/plugins/GCodeReader/plugin.json +++ b/plugins/GCodeReader/plugin.json @@ -1,7 +1,7 @@ { "name": "G-code Reader", "author": "Victor Larchenko, Ultimaker", - "version": "1.0.0", + "version": "1.0.1", "description": "Allows loading and displaying G-code files.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/GCodeWriter/plugin.json b/plugins/GCodeWriter/plugin.json index 78b63a582f..f3a95ddb78 100644 --- a/plugins/GCodeWriter/plugin.json +++ b/plugins/GCodeWriter/plugin.json @@ -1,7 +1,7 @@ { "name": "G-code Writer", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Writes g-code to a file.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/ImageReader/plugin.json b/plugins/ImageReader/plugin.json index 001da0822b..d966537d99 100644 --- a/plugins/ImageReader/plugin.json +++ b/plugins/ImageReader/plugin.json @@ -1,7 +1,7 @@ { "name": "Image Reader", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Enables ability to generate printable geometry from 2D image files.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/LegacyProfileReader/plugin.json b/plugins/LegacyProfileReader/plugin.json index 2cd1e9ca2c..2f5264ad37 100644 --- a/plugins/LegacyProfileReader/plugin.json +++ b/plugins/LegacyProfileReader/plugin.json @@ -1,7 +1,7 @@ { "name": "Legacy Cura Profile Reader", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Provides support for importing profiles from legacy Cura versions.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/MachineSettingsAction/plugin.json b/plugins/MachineSettingsAction/plugin.json index 4587729a9a..d734c1adf5 100644 --- a/plugins/MachineSettingsAction/plugin.json +++ b/plugins/MachineSettingsAction/plugin.json @@ -1,7 +1,7 @@ { "name": "Machine Settings action", "author": "fieldOfView", - "version": "1.0.0", + "version": "1.0.1", "description": "Provides a way to change machine settings (such as build volume, nozzle size, etc.).", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/ModelChecker/plugin.json b/plugins/ModelChecker/plugin.json index a210c3bf9f..59be5bbf0a 100644 --- a/plugins/ModelChecker/plugin.json +++ b/plugins/ModelChecker/plugin.json @@ -1,7 +1,7 @@ { "name": "Model Checker", "author": "Ultimaker B.V.", - "version": "0.1", + "version": "1.0.1", "api": "6.0", "description": "Checks models and print configuration for possible printing issues and give suggestions.", "i18n-catalog": "cura" diff --git a/plugins/MonitorStage/plugin.json b/plugins/MonitorStage/plugin.json index 71fc10c5ce..95e4b86f36 100644 --- a/plugins/MonitorStage/plugin.json +++ b/plugins/MonitorStage/plugin.json @@ -1,7 +1,7 @@ { "name": "Monitor Stage", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Provides a monitor stage in Cura.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/PerObjectSettingsTool/plugin.json b/plugins/PerObjectSettingsTool/plugin.json index e5bdc5d3da..f272abf06a 100644 --- a/plugins/PerObjectSettingsTool/plugin.json +++ b/plugins/PerObjectSettingsTool/plugin.json @@ -1,7 +1,7 @@ { "name": "Per Model Settings Tool", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Provides the Per Model Settings.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/PostProcessingPlugin/plugin.json b/plugins/PostProcessingPlugin/plugin.json index ad60312af0..1e73133c53 100644 --- a/plugins/PostProcessingPlugin/plugin.json +++ b/plugins/PostProcessingPlugin/plugin.json @@ -1,7 +1,7 @@ { "name": "Post Processing", "author": "Ultimaker", - "version": "2.2", + "version": "2.2.1", "api": "6.0", "description": "Extension that allows for user created scripts for post processing", "catalog": "cura" diff --git a/plugins/PrepareStage/plugin.json b/plugins/PrepareStage/plugin.json index e948b96f6f..dc5c68ce16 100644 --- a/plugins/PrepareStage/plugin.json +++ b/plugins/PrepareStage/plugin.json @@ -1,7 +1,7 @@ { "name": "Prepare Stage", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Provides a prepare stage in Cura.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/PreviewStage/plugin.json b/plugins/PreviewStage/plugin.json index c9c13fe341..e1e4288bae 100644 --- a/plugins/PreviewStage/plugin.json +++ b/plugins/PreviewStage/plugin.json @@ -1,7 +1,7 @@ { "name": "Preview Stage", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Provides a preview stage in Cura.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/RemovableDriveOutputDevice/plugin.json b/plugins/RemovableDriveOutputDevice/plugin.json index 48cd60596c..5523d6b1c1 100644 --- a/plugins/RemovableDriveOutputDevice/plugin.json +++ b/plugins/RemovableDriveOutputDevice/plugin.json @@ -2,7 +2,7 @@ "name": "Removable Drive Output Device Plugin", "author": "Ultimaker B.V.", "description": "Provides removable drive hotplugging and writing support.", - "version": "1.0.0", + "version": "1.0.1", "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/SimulationView/plugin.json b/plugins/SimulationView/plugin.json index dcfbeb305e..3ccf91b9e6 100644 --- a/plugins/SimulationView/plugin.json +++ b/plugins/SimulationView/plugin.json @@ -1,7 +1,7 @@ { "name": "Simulation View", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Provides the Simulation view.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/SliceInfoPlugin/plugin.json b/plugins/SliceInfoPlugin/plugin.json index c2d78e8d78..8ff0e194fb 100644 --- a/plugins/SliceInfoPlugin/plugin.json +++ b/plugins/SliceInfoPlugin/plugin.json @@ -1,7 +1,7 @@ { "name": "Slice info", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Submits anonymous slice info. Can be disabled through preferences.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/SolidView/plugin.json b/plugins/SolidView/plugin.json index c66e41a7aa..b3f62221c5 100644 --- a/plugins/SolidView/plugin.json +++ b/plugins/SolidView/plugin.json @@ -1,7 +1,7 @@ { "name": "Solid View", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Provides a normal solid mesh view.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/SupportEraser/plugin.json b/plugins/SupportEraser/plugin.json index dc624ecd77..fa6d6d230e 100644 --- a/plugins/SupportEraser/plugin.json +++ b/plugins/SupportEraser/plugin.json @@ -1,7 +1,7 @@ { "name": "Support Eraser", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Creates an eraser mesh to block the printing of support in certain places", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/Toolbox/plugin.json b/plugins/Toolbox/plugin.json index 91e9561327..61dc0429f5 100644 --- a/plugins/Toolbox/plugin.json +++ b/plugins/Toolbox/plugin.json @@ -1,7 +1,7 @@ { "name": "Toolbox", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "api": "6.0", "description": "Find, manage and install new Cura packages." } diff --git a/plugins/UFPWriter/plugin.json b/plugins/UFPWriter/plugin.json index b4e05d9346..288d6acf77 100644 --- a/plugins/UFPWriter/plugin.json +++ b/plugins/UFPWriter/plugin.json @@ -1,7 +1,7 @@ { "name": "UFP Writer", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Provides support for writing Ultimaker Format Packages.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/UM3NetworkPrinting/plugin.json b/plugins/UM3NetworkPrinting/plugin.json index def02562db..088b4dae6a 100644 --- a/plugins/UM3NetworkPrinting/plugin.json +++ b/plugins/UM3NetworkPrinting/plugin.json @@ -2,7 +2,7 @@ "name": "UM3 Network Connection", "author": "Ultimaker B.V.", "description": "Manages network connections to Ultimaker 3 printers.", - "version": "1.0.0", + "version": "1.0.1", "api": "6.0", "i18n-catalog": "cura" } diff --git a/plugins/USBPrinting/plugin.json b/plugins/USBPrinting/plugin.json index 3a58abe7e7..45971d858b 100644 --- a/plugins/USBPrinting/plugin.json +++ b/plugins/USBPrinting/plugin.json @@ -1,7 +1,7 @@ { "name": "USB printing", "author": "Ultimaker B.V.", - "version": "1.0.1", + "version": "1.0.2", "api": "6.0", "description": "Accepts G-Code and sends them to a printer. Plugin can also update firmware.", "i18n-catalog": "cura" diff --git a/plugins/UltimakerMachineActions/plugin.json b/plugins/UltimakerMachineActions/plugin.json index fc1eb242fe..3e3e0af9b0 100644 --- a/plugins/UltimakerMachineActions/plugin.json +++ b/plugins/UltimakerMachineActions/plugin.json @@ -1,7 +1,7 @@ { "name": "Ultimaker machine actions", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Provides machine actions for Ultimaker machines (such as bed leveling wizard, selecting upgrades, etc.).", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/UserAgreement/plugin.json b/plugins/UserAgreement/plugin.json index 7781e383d6..b172d1f9a2 100644 --- a/plugins/UserAgreement/plugin.json +++ b/plugins/UserAgreement/plugin.json @@ -1,7 +1,7 @@ { "name": "UserAgreement", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Ask the user once if he/she agrees with our license.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/plugin.json b/plugins/VersionUpgrade/VersionUpgrade21to22/plugin.json index e732c43813..cad94c2eb5 100644 --- a/plugins/VersionUpgrade/VersionUpgrade21to22/plugin.json +++ b/plugins/VersionUpgrade/VersionUpgrade21to22/plugin.json @@ -1,7 +1,7 @@ { "name": "Version Upgrade 2.1 to 2.2", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Upgrades configurations from Cura 2.1 to Cura 2.2.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/VersionUpgrade/VersionUpgrade22to24/plugin.json b/plugins/VersionUpgrade/VersionUpgrade22to24/plugin.json index 2b344ce5d3..7da1e7a56d 100644 --- a/plugins/VersionUpgrade/VersionUpgrade22to24/plugin.json +++ b/plugins/VersionUpgrade/VersionUpgrade22to24/plugin.json @@ -1,7 +1,7 @@ { "name": "Version Upgrade 2.2 to 2.4", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Upgrades configurations from Cura 2.2 to Cura 2.4.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/VersionUpgrade/VersionUpgrade25to26/plugin.json b/plugins/VersionUpgrade/VersionUpgrade25to26/plugin.json index 8691ebfc67..e1f0a47685 100644 --- a/plugins/VersionUpgrade/VersionUpgrade25to26/plugin.json +++ b/plugins/VersionUpgrade/VersionUpgrade25to26/plugin.json @@ -1,7 +1,7 @@ { "name": "Version Upgrade 2.5 to 2.6", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Upgrades configurations from Cura 2.5 to Cura 2.6.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/VersionUpgrade/VersionUpgrade26to27/plugin.json b/plugins/VersionUpgrade/VersionUpgrade26to27/plugin.json index c7124eada6..6cdbd64cbb 100644 --- a/plugins/VersionUpgrade/VersionUpgrade26to27/plugin.json +++ b/plugins/VersionUpgrade/VersionUpgrade26to27/plugin.json @@ -1,7 +1,7 @@ { "name": "Version Upgrade 2.6 to 2.7", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Upgrades configurations from Cura 2.6 to Cura 2.7.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/VersionUpgrade/VersionUpgrade27to30/plugin.json b/plugins/VersionUpgrade/VersionUpgrade27to30/plugin.json index ce8f4a6d44..885d741a8c 100644 --- a/plugins/VersionUpgrade/VersionUpgrade27to30/plugin.json +++ b/plugins/VersionUpgrade/VersionUpgrade27to30/plugin.json @@ -1,7 +1,7 @@ { "name": "Version Upgrade 2.7 to 3.0", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Upgrades configurations from Cura 2.7 to Cura 3.0.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/VersionUpgrade/VersionUpgrade30to31/plugin.json b/plugins/VersionUpgrade/VersionUpgrade30to31/plugin.json index f94f3dfe30..d5f22649c1 100644 --- a/plugins/VersionUpgrade/VersionUpgrade30to31/plugin.json +++ b/plugins/VersionUpgrade/VersionUpgrade30to31/plugin.json @@ -1,7 +1,7 @@ { "name": "Version Upgrade 3.0 to 3.1", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Upgrades configurations from Cura 3.0 to Cura 3.1.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/VersionUpgrade/VersionUpgrade32to33/plugin.json b/plugins/VersionUpgrade/VersionUpgrade32to33/plugin.json index 0bbc237436..eb489169e0 100644 --- a/plugins/VersionUpgrade/VersionUpgrade32to33/plugin.json +++ b/plugins/VersionUpgrade/VersionUpgrade32to33/plugin.json @@ -1,7 +1,7 @@ { "name": "Version Upgrade 3.2 to 3.3", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Upgrades configurations from Cura 3.2 to Cura 3.3.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/VersionUpgrade/VersionUpgrade33to34/plugin.json b/plugins/VersionUpgrade/VersionUpgrade33to34/plugin.json index 5f83695245..9649010643 100644 --- a/plugins/VersionUpgrade/VersionUpgrade33to34/plugin.json +++ b/plugins/VersionUpgrade/VersionUpgrade33to34/plugin.json @@ -1,7 +1,7 @@ { "name": "Version Upgrade 3.3 to 3.4", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Upgrades configurations from Cura 3.3 to Cura 3.4.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/VersionUpgrade/VersionUpgrade34to35/plugin.json b/plugins/VersionUpgrade/VersionUpgrade34to35/plugin.json index f95cb7be87..02635ec606 100644 --- a/plugins/VersionUpgrade/VersionUpgrade34to35/plugin.json +++ b/plugins/VersionUpgrade/VersionUpgrade34to35/plugin.json @@ -1,7 +1,7 @@ { "name": "Version Upgrade 3.4 to 3.5", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Upgrades configurations from Cura 3.4 to Cura 3.5.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/X3DReader/plugin.json b/plugins/X3DReader/plugin.json index 4052ac6605..1fc14104ed 100644 --- a/plugins/X3DReader/plugin.json +++ b/plugins/X3DReader/plugin.json @@ -1,7 +1,7 @@ { "name": "X3D Reader", "author": "Seva Alekseyev", - "version": "0.5.0", + "version": "1.0.1", "description": "Provides support for reading X3D files.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/XRayView/plugin.json b/plugins/XRayView/plugin.json index 4d8e42bae3..71cc165b6c 100644 --- a/plugins/XRayView/plugin.json +++ b/plugins/XRayView/plugin.json @@ -1,7 +1,7 @@ { "name": "X-Ray View", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Provides the X-Ray view.", "api": "6.0", "i18n-catalog": "cura" diff --git a/plugins/XmlMaterialProfile/plugin.json b/plugins/XmlMaterialProfile/plugin.json index d172d49f87..bb1db82fa4 100644 --- a/plugins/XmlMaterialProfile/plugin.json +++ b/plugins/XmlMaterialProfile/plugin.json @@ -1,7 +1,7 @@ { "name": "Material Profiles", "author": "Ultimaker B.V.", - "version": "1.0.0", + "version": "1.0.1", "description": "Provides capabilities to read and write XML-based material profiles.", "api": "6.0", "i18n-catalog": "cura" From b7904d6e056b1edbac2ac8b75755704d4ad47f75 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 17 Dec 2018 13:04:23 +0100 Subject: [PATCH 0989/1292] Unify the CuraDrive plugin with the rest of the items in Cura For instance, the buttons were converted to either primary buttons or secondary buttons. A new CheckBox component was created in Cura in order to reuse it in the future. Contributes to CURA-6005. --- .../src/qml/components/ActionButton.qml | 67 ------------------- .../src/qml/components/ActionCheckBox.qml | 49 -------------- .../src/qml/components/ActionToolTip.qml | 4 +- .../src/qml/components/BackupListFooter.qml | 10 +-- .../src/qml/components/BackupListItem.qml | 15 +++-- plugins/CuraDrive/src/qml/main.qml | 6 +- .../CuraDrive/src/qml/pages/WelcomePage.qml | 9 ++- resources/qml/ActionButton.qml | 15 +++++ resources/qml/CheckBox.qml | 61 +++++++++++++++++ resources/qml/Cura.qml | 11 +++ resources/qml/qmldir | 3 +- resources/themes/cura-light/styles.qml | 2 +- 12 files changed, 115 insertions(+), 137 deletions(-) delete mode 100644 plugins/CuraDrive/src/qml/components/ActionButton.qml delete mode 100644 plugins/CuraDrive/src/qml/components/ActionCheckBox.qml create mode 100644 resources/qml/CheckBox.qml diff --git a/plugins/CuraDrive/src/qml/components/ActionButton.qml b/plugins/CuraDrive/src/qml/components/ActionButton.qml deleted file mode 100644 index 843079ed88..0000000000 --- a/plugins/CuraDrive/src/qml/components/ActionButton.qml +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -import QtQuick 2.7 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.3 - -import UM 1.1 as UM - -Button -{ - id: button - property alias cursorShape: mouseArea.cursorShape - property var iconSource: "" - property var busy: false - property var color: UM.Theme.getColor("primary") - property var hoverColor: UM.Theme.getColor("primary_hover") - property var disabledColor: color - property var textColor: UM.Theme.getColor("button_text") - property var textHoverColor: UM.Theme.getColor("button_text_hover") - property var textDisabledColor: textColor - property var textFont: UM.Theme.getFont("action_button") - - contentItem: RowLayout - { - Icon - { - id: buttonIcon - iconSource: button.iconSource - width: 16 * screenScaleFactor - color: button.hovered ? button.textHoverColor : button.textColor - visible: button.iconSource != "" && !loader.visible - } - - Icon - { - id: loader - iconSource: "../images/loading.gif" - width: 16 * screenScaleFactor - color: button.hovered ? button.textHoverColor : button.textColor - visible: button.busy - animated: true - } - - Label - { - id: buttonText - text: button.text - color: button.enabled ? (button.hovered ? button.textHoverColor : button.textColor): button.textDisabledColor - font: button.textFont - visible: button.text != "" - renderType: Text.NativeRendering - } - } - - background: Rectangle - { - color: button.enabled ? (button.hovered ? button.hoverColor : button.color) : button.disabledColor - } - - MouseArea - { - id: mouseArea - anchors.fill: parent - onPressed: mouse.accepted = false - hoverEnabled: true - cursorShape: button.enabled ? (hovered ? Qt.PointingHandCursor : Qt.ArrowCursor) : Qt.ForbiddenCursor - } -} diff --git a/plugins/CuraDrive/src/qml/components/ActionCheckBox.qml b/plugins/CuraDrive/src/qml/components/ActionCheckBox.qml deleted file mode 100644 index 71f5e6035d..0000000000 --- a/plugins/CuraDrive/src/qml/components/ActionCheckBox.qml +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -import QtQuick 2.7 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.3 - -import UM 1.3 as UM - -CheckBox -{ - id: checkbox - hoverEnabled: true - - property var label: "" - - indicator: Rectangle { - implicitWidth: 30 * screenScaleFactor - implicitHeight: 30 * screenScaleFactor - x: 0 - y: Math.round(parent.height / 2 - height / 2) - color: UM.Theme.getColor("sidebar") - border.color: UM.Theme.getColor("text") - - Rectangle { - width: 14 * screenScaleFactor - height: 14 * screenScaleFactor - x: 8 * screenScaleFactor - y: 8 * screenScaleFactor - color: UM.Theme.getColor("primary") - visible: checkbox.checked - } - } - - contentItem: Label { - anchors - { - left: checkbox.indicator.right - leftMargin: 5 * screenScaleFactor - } - text: catalog.i18nc("@checkbox:description", "Auto Backup") - color: UM.Theme.getColor("text") - renderType: Text.NativeRendering - verticalAlignment: Text.AlignVCenter - } - - ActionToolTip - { - text: checkbox.label - } -} diff --git a/plugins/CuraDrive/src/qml/components/ActionToolTip.qml b/plugins/CuraDrive/src/qml/components/ActionToolTip.qml index 93b92bc2df..7401221328 100644 --- a/plugins/CuraDrive/src/qml/components/ActionToolTip.qml +++ b/plugins/CuraDrive/src/qml/components/ActionToolTip.qml @@ -14,7 +14,7 @@ ToolTip background: Rectangle { - color: UM.Theme.getColor("sidebar") + color: UM.Theme.getColor("main_background") border.color: UM.Theme.getColor("primary") border.width: 1 * screenScaleFactor } @@ -23,7 +23,7 @@ ToolTip { text: tooltip.text color: UM.Theme.getColor("text") - font: UM.Theme.getFont("very_small") + font: UM.Theme.getFont("default") renderType: Text.NativeRendering } } diff --git a/plugins/CuraDrive/src/qml/components/BackupListFooter.qml b/plugins/CuraDrive/src/qml/components/BackupListFooter.qml index 80f47d6cba..1e7fc16801 100644 --- a/plugins/CuraDrive/src/qml/components/BackupListFooter.qml +++ b/plugins/CuraDrive/src/qml/components/BackupListFooter.qml @@ -4,6 +4,7 @@ import QtQuick.Controls 2.1 import QtQuick.Layouts 1.3 import UM 1.3 as UM +import Cura 1.0 as Cura import "../components" @@ -13,7 +14,7 @@ RowLayout width: parent.width property bool showInfoButton: false - ActionButton + Cura.PrimaryButton { id: infoButton text: catalog.i18nc("@button", "Want more?") @@ -22,7 +23,7 @@ RowLayout visible: backupListFooter.showInfoButton } - ActionButton + Cura.PrimaryButton { id: createBackupButton text: catalog.i18nc("@button", "Backup Now") @@ -32,11 +33,12 @@ RowLayout busy: CuraDrive.isCreatingBackup } - ActionCheckBox + Cura.CheckBox { id: autoBackupEnabled checked: CuraDrive.autoBackupEnabled onClicked: CuraDrive.toggleAutoBackup(autoBackupEnabled.checked) - label: catalog.i18nc("@checkbox:description", "Automatically create a backup each day that Cura is started.") + text: catalog.i18nc("@checkbox:description", "Auto Backup") + tooltip: catalog.i18nc("@checkbox:description", "Automatically create a backup each day that Cura is started.") } } diff --git a/plugins/CuraDrive/src/qml/components/BackupListItem.qml b/plugins/CuraDrive/src/qml/components/BackupListItem.qml index abe9a1acf9..ad1ce5f9df 100644 --- a/plugins/CuraDrive/src/qml/components/BackupListItem.qml +++ b/plugins/CuraDrive/src/qml/components/BackupListItem.qml @@ -5,6 +5,7 @@ import QtQuick.Layouts 1.3 import QtQuick.Dialogs 1.1 import UM 1.1 as UM +import Cura 1.0 as Cura Item { @@ -29,7 +30,7 @@ Item width: parent.width height: 50 * screenScaleFactor - ActionButton + Cura.ActionButton { color: "transparent" hoverColor: "transparent" @@ -61,18 +62,18 @@ Item renderType: Text.NativeRendering } - ActionButton + Cura.SecondaryButton { text: catalog.i18nc("@button", "Restore") - color: "transparent" - hoverColor: "transparent" - textColor: UM.Theme.getColor("text") - textHoverColor: UM.Theme.getColor("text_link") +// color: "transparent" +// hoverColor: "transparent" +// textColor: UM.Theme.getColor("text") +// textHoverColor: UM.Theme.getColor("text_link") enabled: !CuraDrive.isCreatingBackup && !CuraDrive.isRestoringBackup onClicked: confirmRestoreDialog.visible = true } - ActionButton + Cura.ActionButton { color: "transparent" hoverColor: "transparent" diff --git a/plugins/CuraDrive/src/qml/main.qml b/plugins/CuraDrive/src/qml/main.qml index 4a2219cf1f..359f8dd725 100644 --- a/plugins/CuraDrive/src/qml/main.qml +++ b/plugins/CuraDrive/src/qml/main.qml @@ -14,11 +14,11 @@ Window id: curaDriveDialog minimumWidth: Math.round(UM.Theme.getSize("modal_window_minimum").width) minimumHeight: Math.round(UM.Theme.getSize("modal_window_minimum").height) - maximumWidth: minimumWidth * 1.2 - maximumHeight: minimumHeight * 1.2 + maximumWidth: Math.round(minimumWidth * 1.2) + maximumHeight: Math.round(minimumHeight * 1.2) width: minimumWidth height: minimumHeight - color: UM.Theme.getColor("sidebar") + color: UM.Theme.getColor("main_background") title: catalog.i18nc("@title:window", "Cura Backups") // Globally available. diff --git a/plugins/CuraDrive/src/qml/pages/WelcomePage.qml b/plugins/CuraDrive/src/qml/pages/WelcomePage.qml index 882656dc4a..b7f96d162a 100644 --- a/plugins/CuraDrive/src/qml/pages/WelcomePage.qml +++ b/plugins/CuraDrive/src/qml/pages/WelcomePage.qml @@ -38,11 +38,14 @@ Column renderType: Text.NativeRendering } - ActionButton + Cura.PrimaryButton { id: loginButton - onClicked: Cura.API.account.login() - text: catalog.i18nc("@button", "Sign In") + width: UM.Theme.getSize("account_button").width + height: UM.Theme.getSize("account_button").height anchors.horizontalCenter: parent.horizontalCenter + text: catalog.i18nc("@button", "Sign in") + onClicked: Cura.API.account.login() + fixedWidthMode: true } } diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index 3a9552cd9c..573ead2910 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -4,6 +4,7 @@ import QtQuick 2.7 import QtQuick.Controls 2.1 import QtGraphicalEffects 1.0 // For the dropshadow + import UM 1.1 as UM import Cura 1.0 as Cura @@ -30,6 +31,7 @@ Button property color outlineDisabledColor: outlineColor property alias shadowColor: shadow.color property alias shadowEnabled: shadow.visible + property alias busy: busyIndicator.visible // This property is used to indicate whether the button has a fixed width or the width would depend on the contents // Be careful when using fixedWidthMode, the translated texts can be too long that they won't fit. In any case, @@ -117,4 +119,17 @@ Button delay: 500 visible: text != "" && button.hovered } + + BusyIndicator { + id: busyIndicator + + anchors { + centerIn: parent + } + + width: height + height: parent.height + + visible: false + } } \ No newline at end of file diff --git a/resources/qml/CheckBox.qml b/resources/qml/CheckBox.qml new file mode 100644 index 0000000000..7a79182a4b --- /dev/null +++ b/resources/qml/CheckBox.qml @@ -0,0 +1,61 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.1 + +import UM 1.3 as UM + +CheckBox +{ + id: checkbox + hoverEnabled: true + + property alias tooltip: tooltip.text + + indicator: Rectangle { + implicitWidth: UM.Theme.getSize("checkbox").width + implicitHeight: UM.Theme.getSize("checkbox").height + x: 0 + y: Math.round(parent.height / 2 - height / 2) + color: UM.Theme.getColor("main_background") + radius: UM.Theme.getSize("checkbox_radius").width + border.width: UM.Theme.getSize("default_lining").width + border.color: checkbox.hovered ? UM.Theme.getColor("checkbox_border_hover") : UM.Theme.getColor("checkbox_border") + + UM.RecolorImage + { + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + width: Math.round(parent.width / 2.5) + height: Math.round(parent.height / 2.5) + sourceSize.height: width + color: UM.Theme.getColor("checkbox_mark") + source: UM.Theme.getIcon("check") + opacity: checkbox.checked + Behavior on opacity { NumberAnimation { duration: 100; } } + } + } + + contentItem: Label { + anchors + { + left: checkbox.indicator.right + leftMargin: UM.Theme.getSize("narrow_margin").width + } + text: checkbox.text + color: UM.Theme.getColor("checkbox_text") + font: UM.Theme.getFont("default") + renderType: Text.NativeRendering + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } + + ToolTip + { + id: tooltip + text: "" + delay: 500 + visible: text != "" && checkbox.hovered + } +} diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 8ab943b93b..71b97fa6f4 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -123,6 +123,17 @@ UM.MainWindow } } } + + // This is a placehoder for adding a pattern in the header + Image + { + id: backgroundPattern + anchors.fill: parent + fillMode: Image.Tile + source: UM.Theme.getImage("header_pattern") + horizontalAlignment: Image.AlignLeft + verticalAlignment: Image.AlignTop + } } MainWindowHeader diff --git a/resources/qml/qmldir b/resources/qml/qmldir index 1dc21150ce..4e28e12f62 100644 --- a/resources/qml/qmldir +++ b/resources/qml/qmldir @@ -14,4 +14,5 @@ PrinterTypeLabel 1.0 PrinterTypeLabel.qml ViewsSelector 1.0 ViewsSelector.qml ToolbarButton 1.0 ToolbarButton.qml SettingView 1.0 SettingView.qml -ProfileMenu 1.0 ProfileMenu.qml \ No newline at end of file +ProfileMenu 1.0 ProfileMenu.qml +CheckBox 1.0 CheckBox.qml \ No newline at end of file diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index 89729fc08c..95f811c3aa 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -478,7 +478,7 @@ QtObject color: (control.hovered || control._hovered) ? Theme.getColor("checkbox_hover") : (control.enabled ? Theme.getColor("checkbox") : Theme.getColor("checkbox_disabled")) Behavior on color { ColorAnimation { duration: 50; } } - radius: control.exclusiveGroup ? Math.round(Theme.getSize("checkbox").width / 2) : UM.Theme.getSize("checkbox_radius").width + radius: control.exclusiveGroup ? Math.round(Theme.getSize("checkbox").width / 2) : Theme.getSize("checkbox_radius").width border.width: Theme.getSize("default_lining").width border.color: (control.hovered || control._hovered) ? Theme.getColor("checkbox_border_hover") : Theme.getColor("checkbox_border") From ee74b9f89f04f8bfaaf71ab852a2abea8b9be250 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 17 Dec 2018 13:09:01 +0100 Subject: [PATCH 0990/1292] Once the connectiontype is recovered, it's converted to a string So we need to check if that's the case. CURA-6011 --- cura/Settings/MachineManager.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 342f53aac6..db43207cc9 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -525,10 +525,9 @@ class MachineManager(QObject): def activeMachineHasRemoteConnection(self) -> bool: if self._global_container_stack: connection_type = self._global_container_stack.getMetaDataEntry("connection_type") - return connection_type in [ConnectionType.NetworkConnection, ConnectionType.CloudConnection] + return connection_type in [str(ConnectionType.NetworkConnection), str(ConnectionType.CloudConnection)] return False - @pyqtProperty(str, notify = printerConnectedStatusChanged) def activeMachineNetworkKey(self) -> str: if self._global_container_stack: return self._global_container_stack.getMetaDataEntry("um_network_key", "") @@ -756,7 +755,7 @@ class MachineManager(QObject): self.setActiveMachine(other_machine_stacks[0]["id"]) metadata = CuraContainerRegistry.getInstance().findContainerStacksMetadata(id = machine_id)[0] - network_key = metadata["um_network_key"] if "um_network_key" in metadata else None + network_key = metadata.get("um_network_key", None) ExtruderManager.getInstance().removeMachineExtruders(machine_id) containers = CuraContainerRegistry.getInstance().findInstanceContainersMetadata(type = "user", machine = machine_id) for container in containers: From 34f56b046aeb562c8d8e8d52a1dd89d35474c176 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 17 Dec 2018 13:13:44 +0100 Subject: [PATCH 0991/1292] STAR-322: Review comments --- cura/NetworkClient.py | 194 ------------------ .../src/Cloud/CloudOutputDevice.py | 2 +- 2 files changed, 1 insertion(+), 195 deletions(-) delete mode 100644 cura/NetworkClient.py diff --git a/cura/NetworkClient.py b/cura/NetworkClient.py deleted file mode 100644 index fabaaed95e..0000000000 --- a/cura/NetworkClient.py +++ /dev/null @@ -1,194 +0,0 @@ -# Copyright (c) 2018 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. -from time import time -from typing import Optional, Dict, Callable, List, Union, cast - -from PyQt5.QtCore import QUrl -from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkReply, QHttpMultiPart, QNetworkRequest, QHttpPart, \ - QAuthenticator - -from UM.Application import Application -from UM.Logger import Logger - - -## Abstraction of QNetworkAccessManager for easier networking in Cura. -# This was originally part of NetworkedPrinterOutputDevice but was moved out for re-use in other classes. -class NetworkClient: - - def __init__(self) -> None: - super().__init__() - - # Network manager instance to use for this client. - self.__manager = None # type: Optional[QNetworkAccessManager] - - # Timings. - self._last_manager_create_time = None # type: Optional[float] - self._last_response_time = None # type: Optional[float] - self._last_request_time = None # type: Optional[float] - - # The user agent of Cura. - application = Application.getInstance() - self._user_agent = "%s/%s " % (application.getApplicationName(), application.getVersion()) - - # QHttpMultiPart objects need to be kept alive and not garbage collected during the - # HTTP which uses them. We hold references to these QHttpMultiPart objects here. - self._kept_alive_multiparts = {} # type: Dict[QNetworkReply, QHttpMultiPart] - - # in order to avoid garbage collection we keep the callbacks in this list. - self._anti_gc_callbacks = [] # type: List[Callable[[], None]] - - ## Creates a network manager if needed, with all the required properties and event bindings. - def start(self) -> None: - if not self.__manager: - self.__manager = QNetworkAccessManager() - self._last_manager_create_time = time() - self.__manager.authenticationRequired.connect(self._onAuthenticationRequired) - - ## Destroys the network manager and event bindings. - def stop(self) -> None: - if self.__manager: - self.__manager.authenticationRequired.disconnect(self._onAuthenticationRequired) - self.__manager = None - - @property - def _manager(self) -> QNetworkAccessManager: - self.start() - return cast(QNetworkAccessManager, self.__manager) - - ## Create a new empty network request. - # Automatically adds the required HTTP headers. - # \param url: The URL to request - # \param content_type: The type of the body contents. - def _createEmptyRequest(self, url: str, content_type: Optional[str] = "application/json") -> QNetworkRequest: - if not self._manager: - self.start() # make sure the manager is created - request = QNetworkRequest(QUrl(url)) - if content_type: - request.setHeader(QNetworkRequest.ContentTypeHeader, content_type) - request.setHeader(QNetworkRequest.UserAgentHeader, self._user_agent) - self._last_request_time = time() - return request - - ## Removes all cached Multi-Part items. - def _clearCachedMultiPart(self, reply: QNetworkReply) -> None: - if reply in self._kept_alive_multiparts: - del self._kept_alive_multiparts[reply] - - ## Callback for when the network manager detects that authentication is required but was not given. - @staticmethod - def _onAuthenticationRequired(reply: QNetworkReply, authenticator: QAuthenticator) -> None: - Logger.log("w", "Request to {} required authentication but was not given".format(reply.url().toString())) - - ## Add a part to a Multi-Part form. - @staticmethod - def _createFormPart(content_header: str, data: bytes, content_type: Optional[str] = None) -> QHttpPart: - part = QHttpPart() - - if not content_header.startswith("form-data;"): - content_header = "form_data; " + content_header - - part.setHeader(QNetworkRequest.ContentDispositionHeader, content_header) - - if content_type is not None: - part.setHeader(QNetworkRequest.ContentTypeHeader, content_type) - - part.setBody(data) - return part - - ## Public version of _createFormPart. Both are needed for backward compatibility with 3rd party plugins. - def createFormPart(self, content_header: str, data: bytes, content_type: Optional[str] = None) -> QHttpPart: - return self._createFormPart(content_header, data, content_type) - - ## Sends a put request to the given path. - # \param url: The path after the API prefix. - # \param data: The data to be sent in the body - # \param content_type: The content type of the body data. - # \param on_finished: The function to call when the response is received. - # \param on_progress: The function to call when the progress changes. Parameters are bytes_sent / bytes_total. - def put(self, url: str, data: Union[str, bytes], content_type: str, - on_finished: Callable[[QNetworkReply], None], - on_progress: Optional[Callable[[int, int], None]] = None) -> None: - request = self._createEmptyRequest(url, content_type = content_type) - - body = data if isinstance(data, bytes) else data.encode() # type: bytes - reply = self._manager.put(request, body) - callback = self._createCallback(reply, on_finished) - reply.finished.connect(callback) - if on_progress is not None: - reply.uploadProgress.connect(on_progress) - - ## Sends a delete request to the given path. - # url: The path after the API prefix. - # on_finished: The function to be call when the response is received. - def delete(self, url: str, on_finished: Callable[[QNetworkReply], None]) -> None: - request = self._createEmptyRequest(url) - reply = self._manager.deleteResource(request) - callback = self._createCallback(reply, on_finished) - reply.finished.connect(callback) - - ## Sends a get request to the given path. - # \param url: The path after the API prefix. - # \param on_finished: The function to be call when the response is received. - def get(self, url: str, on_finished: Callable[[QNetworkReply], None]) -> None: - request = self._createEmptyRequest(url) - reply = self._manager.get(request) - callback = self._createCallback(reply, on_finished) - reply.finished.connect(callback) - - ## Sends a post request to the given path. - # \param url: The path after the API prefix. - # \param data: The data to be sent in the body - # \param on_finished: The function to call when the response is received. - # \param on_progress: The function to call when the progress changes. Parameters are bytes_sent / bytes_total. - def post(self, url: str, data: Union[str, bytes], - on_finished: Callable[[QNetworkReply], None], - on_progress: Optional[Callable[[int, int], None]] = None) -> None: - request = self._createEmptyRequest(url) - - body = data if isinstance(data, bytes) else data.encode() # type: bytes - reply = self._manager.post(request, body) - callback = self._createCallback(reply, on_finished) - reply.finished.connect(callback) - if on_progress is not None: - reply.uploadProgress.connect(on_progress) - - ## Does a POST request with form data to the given URL. - def postForm(self, url: str, header_data: str, body_data: bytes, - on_finished: Optional[Callable[[QNetworkReply], None]], - on_progress: Optional[Callable[[int, int], None]] = None) -> None: - post_part = QHttpPart() - post_part.setHeader(QNetworkRequest.ContentDispositionHeader, header_data) - post_part.setBody(body_data) - self.postFormWithParts(url, [post_part], on_finished, on_progress) - - ## Does a POST request with form parts to the given URL. - def postFormWithParts(self, target: str, parts: List[QHttpPart], - on_finished: Optional[Callable[[QNetworkReply], None]], - on_progress: Optional[Callable[[int, int], None]] = None) -> Optional[QNetworkReply]: - request = self._createEmptyRequest(target, content_type = None) - multi_post_part = QHttpMultiPart(QHttpMultiPart.FormDataType) - - for part in parts: - multi_post_part.append(part) - - reply = self._manager.post(request, multi_post_part) - - def callback(): - on_finished(reply) - self._clearCachedMultiPart(reply) - - reply.finished.connect(callback) - - self._kept_alive_multiparts[reply] = multi_post_part - - if on_progress is not None: - reply.uploadProgress.connect(on_progress) - - return reply - - def _createCallback(self, reply: QNetworkReply, on_finished: Callable[[QNetworkReply], None]) -> Callable[[], None]: - def callback(): - on_finished(reply) - self._anti_gc_callbacks.remove(callback) - self._anti_gc_callbacks.append(callback) - return callback diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 54f0dc20b6..f29e29c40b 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -18,11 +18,11 @@ from cura.CuraApplication import CuraApplication from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState, NetworkedPrinterOutputDevice from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputController import CloudOutputController -from src.Cloud.Models.CloudClusterResponse import CloudClusterResponse from ..MeshFormatHandler import MeshFormatHandler from ..UM3PrintJobOutputModel import UM3PrintJobOutputModel from .CloudProgressMessage import CloudProgressMessage from .CloudApiClient import CloudApiClient +from .Models.CloudClusterResponse import CloudClusterResponse from .Models.CloudClusterStatus import CloudClusterStatus from .Models.CloudPrintJobUploadRequest import CloudPrintJobUploadRequest from .Models.CloudPrintResponse import CloudPrintResponse From a1cb09f73fe4403090c4857c35910ba92e74e411 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 17 Dec 2018 13:24:07 +0100 Subject: [PATCH 0992/1292] STAR-322: Sorting clusters --- plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py | 2 ++ .../UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py | 2 ++ .../tests/Cloud/TestCloudOutputDeviceManager.py | 5 ++++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py index d4044726a3..c7d58cea78 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py @@ -18,6 +18,8 @@ from .NetworkManagerMock import NetworkManagerMock class TestCloudApiClient(TestCase): + maxDiff = None + def _errorHandler(self, errors: List[CloudErrorObject]): raise Exception("Received unexpected error: {}".format(errors)) diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py index c42a208ece..fded79e15b 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py @@ -16,6 +16,8 @@ from .NetworkManagerMock import NetworkManagerMock class TestCloudOutputDevice(TestCase): + maxDiff = None + CLUSTER_ID = "RIZ6cZbWA_Ua7RZVJhrdVfVpf0z-MqaSHQE4v8aRTtYq" JOB_ID = "ABCDefGHIjKlMNOpQrSTUvYxWZ0-1234567890abcDE=" HOST_NAME = "ultimakersystem-ccbdd30044ec" diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py index f98e954274..f62d92e9db 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py @@ -11,6 +11,8 @@ from .NetworkManagerMock import NetworkManagerMock class TestCloudOutputDeviceManager(TestCase): + maxDiff = None + URL = "https://api-staging.ultimaker.com/connect/v1/clusters" def setUp(self): @@ -41,7 +43,8 @@ class TestCloudOutputDeviceManager(TestCase): clusters = self.clusters_response.get("data", []) self.assertEqual([CloudOutputDevice] * len(clusters), [type(d) for d in devices]) self.assertEqual({cluster["cluster_id"] for cluster in clusters}, {device.key for device in devices}) - self.assertEqual(clusters, [device.clusterData.toDict() for device in devices]) + self.assertEqual(clusters, sorted((device.clusterData.toDict() for device in devices), + key=lambda device_dict: device_dict["host_version"])) for device in clusters: device_manager.getOutputDevice(device["cluster_id"]).close() From b6f90f1ab2caa1be9a1974f680970997dd8e72b3 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 17 Dec 2018 13:29:20 +0100 Subject: [PATCH 0993/1292] STAR-322: Using cura constants --- .../UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py | 9 +++++---- .../tests/Cloud/TestCloudOutputDevice.py | 8 ++++---- .../tests/Cloud/TestCloudOutputDeviceManager.py | 3 ++- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py index c7d58cea78..a09894deb0 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py @@ -7,6 +7,7 @@ from unittest import TestCase from unittest.mock import patch, MagicMock from cura.CuraApplication import CuraApplication +from cura.CuraConstants import CuraCloudAPIRoot from src.Cloud.CloudApiClient import CloudApiClient from src.Cloud.Models.CloudClusterResponse import CloudClusterResponse from src.Cloud.Models.CloudClusterStatus import CloudClusterStatus @@ -39,7 +40,7 @@ class TestCloudApiClient(TestCase): response = readFixture("getClusters") data = parseFixture("getClusters")["data"] - self.network.prepareReply("GET", "https://api-staging.ultimaker.com/connect/v1/clusters", 200, response) + self.network.prepareReply("GET", CuraCloudAPIRoot + "/connect/v1/clusters", 200, response) # the callback is a function that adds the result of the call to getClusters to the result list self.api.getClusters(lambda clusters: result.extend(clusters)) @@ -54,7 +55,7 @@ class TestCloudApiClient(TestCase): data = parseFixture("getClusterStatusResponse")["data"] self.network.prepareReply("GET", - "https://api-staging.ultimaker.com/connect/v1/clusters/R0YcLJwar1ugh0ikEZsZs8NWKV6vJP_LdYsXgXqAcaNC/status", + CuraCloudAPIRoot + "/connect/v1/clusters/R0YcLJwar1ugh0ikEZsZs8NWKV6vJP_LdYsXgXqAcaNC/status", 200, response ) self.api.getClusterStatus("R0YcLJwar1ugh0ikEZsZs8NWKV6vJP_LdYsXgXqAcaNC", lambda s: result.append(s)) @@ -69,7 +70,7 @@ class TestCloudApiClient(TestCase): response = readFixture("putJobUploadResponse") - self.network.prepareReply("PUT", "https://api-staging.ultimaker.com/cura/v1/jobs/upload", 200, response) + self.network.prepareReply("PUT", CuraCloudAPIRoot + "/cura/v1/jobs/upload", 200, response) request = CloudPrintJobUploadRequest(job_name = "job name", file_size = 143234, content_type = "text/plain") self.api.requestUpload(request, lambda r: results.append(r)) self.network.flushReplies() @@ -108,7 +109,7 @@ class TestCloudApiClient(TestCase): job_id = "ABCDefGHIjKlMNOpQrSTUvYxWZ0-1234567890abcDE=" self.network.prepareReply("POST", - "https://api-staging.ultimaker.com/connect/v1/clusters/{}/print/{}" + CuraCloudAPIRoot + "/connect/v1/clusters/{}/print/{}" .format(cluster_id, job_id), 200, response) diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py index fded79e15b..90a1b2fa96 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py @@ -7,6 +7,7 @@ from unittest.mock import patch, MagicMock from UM.Scene.SceneNode import SceneNode from UM.Signal import Signal from cura.CuraApplication import CuraApplication +from cura.CuraConstants import CuraCloudAPIRoot from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from src.Cloud.CloudApiClient import CloudApiClient from src.Cloud.CloudOutputDevice import CloudOutputDevice @@ -23,10 +24,9 @@ class TestCloudOutputDevice(TestCase): HOST_NAME = "ultimakersystem-ccbdd30044ec" HOST_GUID = "e90ae0ac-1257-4403-91ee-a44c9b7e8050" - BASE_URL = "https://api-staging.ultimaker.com" - STATUS_URL = "{}/connect/v1/clusters/{}/status".format(BASE_URL, CLUSTER_ID) - PRINT_URL = "{}/connect/v1/clusters/{}/print/{}".format(BASE_URL, CLUSTER_ID, JOB_ID) - REQUEST_UPLOAD_URL = "{}/cura/v1/jobs/upload".format(BASE_URL) + STATUS_URL = "{}/connect/v1/clusters/{}/status".format(CuraCloudAPIRoot, CLUSTER_ID) + PRINT_URL = "{}/connect/v1/clusters/{}/print/{}".format(CuraCloudAPIRoot, CLUSTER_ID, JOB_ID) + REQUEST_UPLOAD_URL = "{}/cura/v1/jobs/upload".format(CuraCloudAPIRoot) def setUp(self): super().setUp() diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py index f62d92e9db..01b1b18ff1 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py @@ -4,6 +4,7 @@ from unittest import TestCase from unittest.mock import patch from cura.CuraApplication import CuraApplication +from cura.CuraConstants import CuraCloudAPIRoot from src.Cloud.CloudOutputDevice import CloudOutputDevice from src.Cloud.CloudOutputDeviceManager import CloudOutputDeviceManager from tests.Cloud.Fixtures import parseFixture, readFixture @@ -13,7 +14,7 @@ from .NetworkManagerMock import NetworkManagerMock class TestCloudOutputDeviceManager(TestCase): maxDiff = None - URL = "https://api-staging.ultimaker.com/connect/v1/clusters" + URL = CuraCloudAPIRoot + "/connect/v1/clusters" def setUp(self): super().setUp() From aad7540366e6b7b71619574f77961499493fd4f8 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 17 Dec 2018 13:31:38 +0100 Subject: [PATCH 0994/1292] Fix situation where multiple connect configurations would cause issues CURA-6011 --- cura/PrintersModel.py | 6 +++- cura/Settings/MachineManager.py | 11 ++++--- .../PrinterSelector/MachineSelectorList.qml | 32 +++++-------------- 3 files changed, 19 insertions(+), 30 deletions(-) diff --git a/cura/PrintersModel.py b/cura/PrintersModel.py index 26b65409c5..0c58d9bf8c 100644 --- a/cura/PrintersModel.py +++ b/cura/PrintersModel.py @@ -56,10 +56,14 @@ class PrintersModel(ListModel): connection_type = container_stack.getMetaDataEntry("connection_type") has_remote_connection = connection_type in [str(ConnectionType.NetworkConnection), str(ConnectionType.CloudConnection)] + if container_stack.getMetaDataEntry("hidden", False) in ["True", True]: + continue + # TODO: Remove reference to connect group name. items.append({"name": container_stack.getMetaDataEntry("connect_group_name", container_stack.getName()), "id": container_stack.getId(), "hasRemoteConnection": has_remote_connection, - "connectionType": connection_type}) + "connectionType": connection_type, + "metadata": container_stack.getMetaData().copy()}) items.sort(key=lambda i: not i["hasRemoteConnection"]) self.setItems(items) \ No newline at end of file diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index db43207cc9..c51c26f1b9 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1321,17 +1321,18 @@ class MachineManager(QObject): # Get the definition id corresponding to this machine name machine_definition_id = CuraContainerRegistry.getInstance().findDefinitionContainers(name = machine_name)[0].getId() # Try to find a machine with the same network key - new_machine = self.getMachine(machine_definition_id, metadata_filter = {"um_network_key": self.activeMachineNetworkKey}) + new_machine = self.getMachine(machine_definition_id, metadata_filter = {"um_network_key": self.activeMachineNetworkKey()}) # If there is no machine, then create a new one and set it to the non-hidden instance if not new_machine: new_machine = CuraStackBuilder.createMachine(machine_definition_id + "_sync", machine_definition_id) if not new_machine: return - new_machine.setMetaDataEntry("um_network_key", self.activeMachineNetworkKey) + new_machine.setMetaDataEntry("um_network_key", self.activeMachineNetworkKey()) new_machine.setMetaDataEntry("connect_group_name", self.activeMachineNetworkGroupName) new_machine.setMetaDataEntry("hidden", False) + new_machine.setMetaDataEntry("connection_type", self._global_container_stack.getMetaDataEntry("connection_type")) else: - Logger.log("i", "Found a %s with the key %s. Let's use it!", machine_name, self.activeMachineNetworkKey) + Logger.log("i", "Found a %s with the key %s. Let's use it!", machine_name, self.activeMachineNetworkKey()) new_machine.setMetaDataEntry("hidden", False) # Set the current printer instance to hidden (the metadata entry must exist) @@ -1391,10 +1392,10 @@ class MachineManager(QObject): # After updating from 3.2 to 3.3 some group names may be temporary. If there is a mismatch in the name of the group # then all the container stacks are updated, both the current and the hidden ones. def checkCorrectGroupName(self, device_id: str, group_name: str) -> None: - if self._global_container_stack and device_id == self.activeMachineNetworkKey: + if self._global_container_stack and device_id == self.activeMachineNetworkKey(): # Check if the connect_group_name is correct. If not, update all the containers connected to the same printer if self.activeMachineNetworkGroupName != group_name: - metadata_filter = {"um_network_key": self.activeMachineNetworkKey} + metadata_filter = {"um_network_key": self.activeMachineNetworkKey()} containers = CuraContainerRegistry.getInstance().findContainerStacks(type = "machine", **metadata_filter) for container in containers: container.setMetaDataEntry("connect_group_name", group_name) diff --git a/resources/qml/PrinterSelector/MachineSelectorList.qml b/resources/qml/PrinterSelector/MachineSelectorList.qml index e0dc6f5e44..52cea0ea80 100644 --- a/resources/qml/PrinterSelector/MachineSelectorList.qml +++ b/resources/qml/PrinterSelector/MachineSelectorList.qml @@ -31,32 +31,16 @@ ListView text: model.name width: listView.width outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null - } -} - /* - - - Repeater - { - id: networkedPrinters - - model: Cura.PrintersModel + checked: { - id: networkedPrintersModel - } - - delegate: MachineSelectorButton - { - text: model.name //model.metadata["connect_group_name"] - //checked: Cura.MachineManager.activeMachineNetworkGroupName == model.metadata["connect_group_name"] - outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null - - Connections + // If the machine has a remote connection + var result = Cura.MachineManager.activeMachineId == model.id + if (Cura.MachineManager.activeMachineHasRemoteConnection) { - target: Cura.MachineManager - onActiveMachineNetworkGroupNameChanged: checked = Cura.MachineManager.activeMachineNetworkGroupName == model.metadata["connect_group_name"] + result |= Cura.MachineManager.activeMachineNetworkGroupName == model.metadata["connect_group_name"] } + return result } - }*/ - + } +} \ No newline at end of file From 02825a062fd4e2413938fb8eee3969d7c3cbdc06 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 17 Dec 2018 13:38:41 +0100 Subject: [PATCH 0995/1292] Change the remove and the info buttons Contributes to CURA-6005. --- .../src/qml/components/ActionToolTip.qml | 29 ------------------ .../src/qml/components/BackupList.qml | 2 +- .../src/qml/components/BackupListFooter.qml | 4 +-- .../src/qml/components/BackupListItem.qml | 30 ++++++++----------- plugins/CuraDrive/src/qml/images/delete.svg | 7 ----- plugins/CuraDrive/src/qml/images/info.svg | 4 --- resources/qml/ActionButton.qml | 2 +- 7 files changed, 17 insertions(+), 61 deletions(-) delete mode 100644 plugins/CuraDrive/src/qml/components/ActionToolTip.qml delete mode 100644 plugins/CuraDrive/src/qml/images/delete.svg delete mode 100644 plugins/CuraDrive/src/qml/images/info.svg diff --git a/plugins/CuraDrive/src/qml/components/ActionToolTip.qml b/plugins/CuraDrive/src/qml/components/ActionToolTip.qml deleted file mode 100644 index 7401221328..0000000000 --- a/plugins/CuraDrive/src/qml/components/ActionToolTip.qml +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -import QtQuick 2.7 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.3 - -import UM 1.1 as UM - -ToolTip -{ - id: tooltip - visible: parent.hovered - opacity: 0.9 - delay: 500 - - background: Rectangle - { - color: UM.Theme.getColor("main_background") - border.color: UM.Theme.getColor("primary") - border.width: 1 * screenScaleFactor - } - - contentItem: Label - { - text: tooltip.text - color: UM.Theme.getColor("text") - font: UM.Theme.getFont("default") - renderType: Text.NativeRendering - } -} diff --git a/plugins/CuraDrive/src/qml/components/BackupList.qml b/plugins/CuraDrive/src/qml/components/BackupList.qml index 231f25afc8..a19d1f0ae7 100644 --- a/plugins/CuraDrive/src/qml/components/BackupList.qml +++ b/plugins/CuraDrive/src/qml/components/BackupList.qml @@ -18,7 +18,7 @@ ListView BackupListItem { id: backupListItem - width: parent.width + width: parent.width - UM.Theme.getSize("default_margin").width // Add a margin, otherwise the scrollbar is be on top of the right most component } Divider diff --git a/plugins/CuraDrive/src/qml/components/BackupListFooter.qml b/plugins/CuraDrive/src/qml/components/BackupListFooter.qml index 1e7fc16801..72dc3df044 100644 --- a/plugins/CuraDrive/src/qml/components/BackupListFooter.qml +++ b/plugins/CuraDrive/src/qml/components/BackupListFooter.qml @@ -18,7 +18,7 @@ RowLayout { id: infoButton text: catalog.i18nc("@button", "Want more?") - iconSource: "../images/info.svg" + iconSource: UM.Theme.getIcon("info") onClicked: Qt.openUrlExternally("https://goo.gl/forms/QACEP8pP3RV60QYG2") visible: backupListFooter.showInfoButton } @@ -28,7 +28,7 @@ RowLayout id: createBackupButton text: catalog.i18nc("@button", "Backup Now") iconSource: "../images/backup.svg" - enabled: !CuraDrive.isCreatingBackup && !CuraDrive.isRestoringBackup + enabled: !CuraDrive.isCreatingBackup && !CuraDrive.isRestoringBackup && !backupListFooter.showInfoButton onClicked: CuraDrive.createBackup() busy: CuraDrive.isCreatingBackup } diff --git a/plugins/CuraDrive/src/qml/components/BackupListItem.qml b/plugins/CuraDrive/src/qml/components/BackupListItem.qml index ad1ce5f9df..a84caeb6ab 100644 --- a/plugins/CuraDrive/src/qml/components/BackupListItem.qml +++ b/plugins/CuraDrive/src/qml/components/BackupListItem.qml @@ -26,17 +26,17 @@ Item RowLayout { id: dataRow - spacing: UM.Theme.getSize("default_margin").width * 2 + spacing: UM.Theme.getSize("wide_margin").width width: parent.width height: 50 * screenScaleFactor - Cura.ActionButton + UM.SimpleButton { - color: "transparent" - hoverColor: "transparent" - textColor: UM.Theme.getColor("text") - textHoverColor: UM.Theme.getColor("primary") - iconSource: "../images/info.svg" + width: UM.Theme.getSize("section_icon").width + height: UM.Theme.getSize("section_icon").height + color: UM.Theme.getColor("small_button_text") + hoverColor: UM.Theme.getColor("small_button_text_hover") + iconSource: UM.Theme.getIcon("info") onClicked: backupListItem.showDetails = !backupListItem.showDetails } @@ -65,21 +65,17 @@ Item Cura.SecondaryButton { text: catalog.i18nc("@button", "Restore") -// color: "transparent" -// hoverColor: "transparent" -// textColor: UM.Theme.getColor("text") -// textHoverColor: UM.Theme.getColor("text_link") enabled: !CuraDrive.isCreatingBackup && !CuraDrive.isRestoringBackup onClicked: confirmRestoreDialog.visible = true } - Cura.ActionButton + UM.SimpleButton { - color: "transparent" - hoverColor: "transparent" - textColor: UM.Theme.getColor("setting_validation_error") - textHoverColor: UM.Theme.getColor("setting_validation_error") - iconSource: "../images/delete.svg" + width: UM.Theme.getSize("message_close").width + height: UM.Theme.getSize("message_close").height + color: UM.Theme.getColor("small_button_text") + hoverColor: UM.Theme.getColor("small_button_text_hover") + iconSource: UM.Theme.getIcon("cross1") onClicked: confirmDeleteDialog.visible = true } } diff --git a/plugins/CuraDrive/src/qml/images/delete.svg b/plugins/CuraDrive/src/qml/images/delete.svg deleted file mode 100644 index 2f6190ad43..0000000000 --- a/plugins/CuraDrive/src/qml/images/delete.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/plugins/CuraDrive/src/qml/images/info.svg b/plugins/CuraDrive/src/qml/images/info.svg deleted file mode 100644 index 36154d6729..0000000000 --- a/plugins/CuraDrive/src/qml/images/info.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index 573ead2910..2448b9a551 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -55,7 +55,7 @@ Button width: visible ? height : 0 sourceSize.width: width sourceSize.height: height - color: button.hovered ? button.textHoverColor : button.textColor + color: button.enabled ? (button.hovered ? button.textHoverColor : button.textColor) : button.textDisabledColor visible: source != "" && !button.isIconOnRightSide anchors.verticalCenter: parent.verticalCenter } From 3b367938de9600a94829bfaa8ac29e069cb49552 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 17 Dec 2018 13:53:31 +0100 Subject: [PATCH 0996/1292] STAR-322: Removing TestSendMaterialJob temporarily --- .../tests/Cloud/TestCloudApiClient.py | 6 +- .../tests/TestSendMaterialJob.py | 190 ------------------ plugins/UM3NetworkPrinting/tests/__init__.py | 2 + run_mypy.py | 1 + 4 files changed, 5 insertions(+), 194 deletions(-) delete mode 100644 plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py create mode 100644 plugins/UM3NetworkPrinting/tests/__init__.py diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py index a09894deb0..49d2b1b34b 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py @@ -54,10 +54,8 @@ class TestCloudApiClient(TestCase): response = readFixture("getClusterStatusResponse") data = parseFixture("getClusterStatusResponse")["data"] - self.network.prepareReply("GET", - CuraCloudAPIRoot + "/connect/v1/clusters/R0YcLJwar1ugh0ikEZsZs8NWKV6vJP_LdYsXgXqAcaNC/status", - 200, response - ) + url = CuraCloudAPIRoot + "/connect/v1/clusters/R0YcLJwar1ugh0ikEZsZs8NWKV6vJP_LdYsXgXqAcaNC/status" + self.network.prepareReply("GET", url, 200, response) self.api.getClusterStatus("R0YcLJwar1ugh0ikEZsZs8NWKV6vJP_LdYsXgXqAcaNC", lambda s: result.append(s)) self.network.flushReplies() diff --git a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py deleted file mode 100644 index 7db5ebdedf..0000000000 --- a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py +++ /dev/null @@ -1,190 +0,0 @@ -# Copyright (c) 2018 Ultimaker B.V. -# Copyright (c) 2018 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. -import io -import json -from unittest import TestCase, mock -from unittest.mock import patch, call - -from PyQt5.QtCore import QByteArray - -from UM.MimeTypeDatabase import MimeType -from UM.Application import Application -from src.SendMaterialJob import SendMaterialJob - - -@patch("builtins.open", lambda _, __: io.StringIO("")) -@patch("UM.MimeTypeDatabase.MimeTypeDatabase.getMimeTypeForFile", - lambda _: MimeType(name = "application/x-ultimaker-material-profile", comment = "Ultimaker Material Profile", - suffixes = ["xml.fdm_material"])) -@patch("UM.Resources.Resources.getAllResourcesOfType", lambda _: ["/materials/generic_pla_white.xml.fdm_material"]) -@patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") -@patch("PyQt5.QtNetwork.QNetworkReply") -class TestSendMaterialJob(TestCase): - _LOCAL_MATERIAL_WHITE = {"type": "material", "status": "unknown", "id": "generic_pla_white", - "base_file": "generic_pla_white", "setting_version": "5", "name": "White PLA", - "brand": "Generic", "material": "PLA", "color_name": "White", - "GUID": "badb0ee7-87c8-4f3f-9398-938587b67dce", "version": "1", "color_code": "#ffffff", - "description": "Test PLA White", "adhesion_info": "Use glue.", "approximate_diameter": "3", - "properties": {"density": "1.00", "diameter": "2.85", "weight": "750"}, - "definition": "fdmprinter", "compatible": True} - - _LOCAL_MATERIAL_BLACK = {"type": "material", "status": "unknown", "id": "generic_pla_black", - "base_file": "generic_pla_black", "setting_version": "5", "name": "Yellow CPE", - "brand": "Ultimaker", "material": "CPE", "color_name": "Black", - "GUID": "5fbb362a-41f9-4818-bb43-15ea6df34aa4", "version": "1", "color_code": "#000000", - "description": "Test PLA Black", "adhesion_info": "Use glue.", "approximate_diameter": "3", - "properties": {"density": "1.01", "diameter": "2.85", "weight": "750"}, - "definition": "fdmprinter", "compatible": True} - - _REMOTE_MATERIAL_WHITE = { - "guid": "badb0ee7-87c8-4f3f-9398-938587b67dce", - "material": "PLA", - "brand": "Generic", - "version": 1, - "color": "White", - "density": 1.00 - } - - _REMOTE_MATERIAL_BLACK = { - "guid": "5fbb362a-41f9-4818-bb43-15ea6df34aa4", - "material": "PLA", - "brand": "Generic", - "version": 2, - "color": "Black", - "density": 1.00 - } - - def test_run(self, device_mock, reply_mock): - job = SendMaterialJob(device_mock) - job.run() - - # We expect the materials endpoint to be called when the job runs. - device_mock.get.assert_called_with("materials/", on_finished = job._onGetRemoteMaterials) - - def test__onGetRemoteMaterials_withFailedRequest(self, reply_mock, device_mock): - reply_mock.attribute.return_value = 404 - job = SendMaterialJob(device_mock) - job._onGetRemoteMaterials(reply_mock) - - # We expect the device not to be called for any follow up. - self.assertEqual(0, device_mock.createFormPart.call_count) - - def test__onGetRemoteMaterials_withWrongEncoding(self, reply_mock, device_mock): - reply_mock.attribute.return_value = 200 - reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTE_MATERIAL_WHITE]).encode("cp500")) - job = SendMaterialJob(device_mock) - job._onGetRemoteMaterials(reply_mock) - - # Given that the parsing fails we do no expect the device to be called for any follow up. - self.assertEqual(0, device_mock.createFormPart.call_count) - - def test__onGetRemoteMaterials_withBadJsonAnswer(self, reply_mock, device_mock): - reply_mock.attribute.return_value = 200 - reply_mock.readAll.return_value = QByteArray(b"Six sick hicks nick six slick bricks with picks and sticks.") - job = SendMaterialJob(device_mock) - job._onGetRemoteMaterials(reply_mock) - - # Given that the parsing fails we do no expect the device to be called for any follow up. - self.assertEqual(0, device_mock.createFormPart.call_count) - - def test__onGetRemoteMaterials_withMissingGuidInRemoteMaterial(self, reply_mock, device_mock): - reply_mock.attribute.return_value = 200 - remote_material_without_guid = self._REMOTE_MATERIAL_WHITE.copy() - del remote_material_without_guid["guid"] - reply_mock.readAll.return_value = QByteArray(json.dumps([remote_material_without_guid]).encode("ascii")) - job = SendMaterialJob(device_mock) - job._onGetRemoteMaterials(reply_mock) - - # Given that parsing fails we do not expect the device to be called for any follow up. - self.assertEqual(0, device_mock.createFormPart.call_count) - - @patch("cura.Settings.CuraContainerRegistry") - @patch("UM.Application") - def test__onGetRemoteMaterials_withInvalidVersionInLocalMaterial(self, application_mock, container_registry_mock, - reply_mock, device_mock): - reply_mock.attribute.return_value = 200 - reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTE_MATERIAL_WHITE]).encode("ascii")) - - localMaterialWhiteWithInvalidVersion = self._LOCAL_MATERIAL_WHITE.copy() - localMaterialWhiteWithInvalidVersion["version"] = "one" - container_registry_mock.findContainersMetadata.return_value = [localMaterialWhiteWithInvalidVersion] - - application_mock.getContainerRegistry.return_value = container_registry_mock - - with mock.patch.object(Application, "getInstance", new = lambda: application_mock): - job = SendMaterialJob(device_mock) - job._onGetRemoteMaterials(reply_mock) - - self.assertEqual(0, device_mock.createFormPart.call_count) - - @patch("cura.Settings.CuraContainerRegistry") - @patch("UM.Application") - def test__onGetRemoteMaterials_withNoUpdate(self, application_mock, container_registry_mock, reply_mock, - device_mock): - application_mock.getContainerRegistry.return_value = container_registry_mock - - device_mock.createFormPart.return_value = "_xXx_" - - container_registry_mock.findContainersMetadata.return_value = [self._LOCAL_MATERIAL_WHITE] - - reply_mock.attribute.return_value = 200 - reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTE_MATERIAL_WHITE]).encode("ascii")) - - with mock.patch.object(Application, "getInstance", new = lambda: application_mock): - job = SendMaterialJob(device_mock) - job._onGetRemoteMaterials(reply_mock) - - self.assertEqual(0, device_mock.createFormPart.call_count) - self.assertEqual(0, device_mock.postFormWithParts.call_count) - - @patch("cura.Settings.CuraContainerRegistry") - @patch("UM.Application") - def test__onGetRemoteMaterials_withUpdatedMaterial(self, application_mock, container_registry_mock, reply_mock, - device_mock): - application_mock.getContainerRegistry.return_value = container_registry_mock - - device_mock.createFormPart.return_value = "_xXx_" - - localMaterialWhiteWithHigherVersion = self._LOCAL_MATERIAL_WHITE.copy() - localMaterialWhiteWithHigherVersion["version"] = "2" - container_registry_mock.findContainersMetadata.return_value = [localMaterialWhiteWithHigherVersion] - - reply_mock.attribute.return_value = 200 - reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTE_MATERIAL_WHITE]).encode("ascii")) - - with mock.patch.object(Application, "getInstance", new = lambda: application_mock): - job = SendMaterialJob(device_mock) - job._onGetRemoteMaterials(reply_mock) - - self.assertEqual(1, device_mock.createFormPart.call_count) - self.assertEqual(1, device_mock.postFormWithParts.call_count) - self.assertEquals( - [call.createFormPart("name=\"file\"; filename=\"generic_pla_white.xml.fdm_material\"", ""), - call.postFormWithParts(target = "materials/", parts = ["_xXx_"], on_finished = job.sendingFinished)], - device_mock.method_calls) - - @patch("cura.Settings.CuraContainerRegistry") - @patch("UM.Application") - def test__onGetRemoteMaterials_withNewMaterial(self, application_mock, container_registry_mock, reply_mock, - device_mock): - application_mock.getContainerRegistry.return_value = container_registry_mock - - device_mock.createFormPart.return_value = "_xXx_" - - container_registry_mock.findContainersMetadata.return_value = [self._LOCAL_MATERIAL_WHITE, - self._LOCAL_MATERIAL_BLACK] - - reply_mock.attribute.return_value = 200 - reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTE_MATERIAL_BLACK]).encode("ascii")) - - with mock.patch.object(Application, "getInstance", new = lambda: application_mock): - job = SendMaterialJob(device_mock) - job._onGetRemoteMaterials(reply_mock) - - self.assertEqual(1, device_mock.createFormPart.call_count) - self.assertEqual(1, device_mock.postFormWithParts.call_count) - self.assertEquals( - [call.createFormPart("name=\"file\"; filename=\"generic_pla_white.xml.fdm_material\"", ""), - call.postFormWithParts(target = "materials/", parts = ["_xXx_"], on_finished = job.sendingFinished)], - device_mock.method_calls) diff --git a/plugins/UM3NetworkPrinting/tests/__init__.py b/plugins/UM3NetworkPrinting/tests/__init__.py new file mode 100644 index 0000000000..f3f6970c54 --- /dev/null +++ b/plugins/UM3NetworkPrinting/tests/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. diff --git a/run_mypy.py b/run_mypy.py index 27f07cd281..2073f0e9a7 100644 --- a/run_mypy.py +++ b/run_mypy.py @@ -29,6 +29,7 @@ def where(exe_name: str, search_path: str = os.getenv("PATH")) -> str: def findModules(path): + return ["UM3NetworkPrinting"] result = [] for entry in os.scandir(path): if entry.is_dir() and os.path.exists(os.path.join(path, entry.name, "__init__.py")): From cb6e4ff2d1a0f26ed8849c45cd97b0f15d8dab36 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 17 Dec 2018 14:05:28 +0100 Subject: [PATCH 0997/1292] Organize MonitorStage.qml better --- .../resources/qml/MonitorQueue.qml | 167 ++++++++++++++++++ .../resources/qml/MonitorStage.qml | 159 +---------------- 2 files changed, 169 insertions(+), 157 deletions(-) create mode 100644 plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml new file mode 100644 index 0000000000..884dbabc2f --- /dev/null +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml @@ -0,0 +1,167 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import UM 1.3 as UM +import Cura 1.0 as Cura + +/** + * This component contains the print job queue, extracted from the primary + * MonitorStage.qml file not for reusability but simply to keep it lean and more + * readable. + */ +Item +{ + Label + { + id: queuedLabel + anchors + { + left: queuedPrintJobs.left + top: parent.top + } + color: UM.Theme.getColor("text") + font: UM.Theme.getFont("large_nonbold") + text: catalog.i18nc("@label", "Queued") + } + + Item + { + id: manageQueueLabel + anchors + { + right: queuedPrintJobs.right + verticalCenter: queuedLabel.verticalCenter + } + height: 18 * screenScaleFactor // TODO: Theme! + width: childrenRect.width + + UM.RecolorImage + { + id: externalLinkIcon + anchors.verticalCenter: manageQueueLabel.verticalCenter + color: UM.Theme.getColor("primary") + source: "../svg/icons/external_link.svg" + width: 16 * screenScaleFactor // TODO: Theme! (Y U NO USE 18 LIKE ALL OTHER ICONS?!) + height: 16 * screenScaleFactor // TODO: Theme! (Y U NO USE 18 LIKE ALL OTHER ICONS?!) + } + Label + { + id: manageQueueText + anchors + { + left: externalLinkIcon.right + leftMargin: 6 * screenScaleFactor // TODO: Theme! + verticalCenter: externalLinkIcon.verticalCenter + } + color: UM.Theme.getColor("primary") + font: UM.Theme.getFont("default") // 12pt, regular + linkColor: UM.Theme.getColor("primary") + text: catalog.i18nc("@label link to connect manager", "Manage queue in Cura Connect") + } + } + + MouseArea + { + anchors.fill: manageQueueLabel + hoverEnabled: true + onClicked: Cura.MachineManager.printerOutputDevices[0].openPrintJobControlPanel() + onEntered: + { + manageQueueText.font.underline = true + } + onExited: + { + manageQueueText.font.underline = false + } + } + + Row + { + id: printJobQueueHeadings + anchors + { + left: queuedPrintJobs.left + leftMargin: 6 * screenScaleFactor // TODO: Theme! + top: queuedLabel.bottom + topMargin: 24 * screenScaleFactor // TODO: Theme! + } + spacing: 18 * screenScaleFactor // TODO: Theme! + + Label + { + text: catalog.i18nc("@label", "Print jobs") + color: "#666666" + elide: Text.ElideRight + font: UM.Theme.getFont("medium") // 14pt, regular + anchors.verticalCenter: parent.verticalCenter + width: 284 * screenScaleFactor // TODO: Theme! (Should match column size) + + // FIXED-LINE-HEIGHT: + height: 18 * screenScaleFactor // TODO: Theme! + verticalAlignment: Text.AlignVCenter + } + + Label + { + text: catalog.i18nc("@label", "Total print time") + color: "#666666" + elide: Text.ElideRight + font: UM.Theme.getFont("medium") // 14pt, regular + anchors.verticalCenter: parent.verticalCenter + width: 216 * screenScaleFactor // TODO: Theme! (Should match column size) + + // FIXED-LINE-HEIGHT: + height: 18 * screenScaleFactor // TODO: Theme! + verticalAlignment: Text.AlignVCenter + } + + Label + { + text: catalog.i18nc("@label", "Waiting for") + color: "#666666" + elide: Text.ElideRight + font: UM.Theme.getFont("medium") // 14pt, regular + anchors.verticalCenter: parent.verticalCenter + width: 216 * screenScaleFactor // TODO: Theme! (Should match column size) + + // FIXED-LINE-HEIGHT: + height: 18 * screenScaleFactor // TODO: Theme! + verticalAlignment: Text.AlignVCenter + } + } + + ScrollView + { + id: queuedPrintJobs + anchors + { + bottom: parent.bottom + horizontalCenter: parent.horizontalCenter + top: printJobQueueHeadings.bottom + topMargin: 12 * screenScaleFactor // TODO: Theme! + } + style: UM.Theme.styles.scrollview + visible: OutputDevice.receivedPrintJobs + width: parent.width + + ListView + { + id: printJobList + anchors.fill: parent + delegate: MonitorPrintJobCard + { + anchors + { + left: parent.left + right: parent.right + } + printJob: modelData + } + model: OutputDevice.queuedPrintJobs + spacing: 6 // TODO: Theme! + } + } +} \ No newline at end of file diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml index 98ca715108..0333e1447c 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml @@ -8,16 +8,13 @@ import UM 1.3 as UM import Cura 1.0 as Cura import QtGraphicalEffects 1.0 -// Root component for the monitor tab (stage) +// This is the root component for the monitor stage. Component { Item { id: monitorFrame - property var emphasisColor: UM.Theme.getColor("setting_control_border_highlight") - property var cornerRadius: UM.Theme.getSize("monitor_corner_radius").width - height: maximumHeight onVisibleChanged: { @@ -80,11 +77,10 @@ Component } } - Item + MonitorQueue { id: queue width: Math.min(834 * screenScaleFactor, maximumWidth) - anchors { bottom: parent.bottom @@ -92,157 +88,6 @@ Component top: printers.bottom topMargin: 48 * screenScaleFactor // TODO: Theme! } - - Label - { - id: queuedLabel - anchors - { - left: queuedPrintJobs.left - top: parent.top - } - color: UM.Theme.getColor("text") - font: UM.Theme.getFont("large_nonbold") - text: catalog.i18nc("@label", "Queued") - } - - Item - { - id: manageQueueLabel - anchors - { - right: queuedPrintJobs.right - verticalCenter: queuedLabel.verticalCenter - } - height: 18 * screenScaleFactor // TODO: Theme! - width: childrenRect.width - - UM.RecolorImage - { - id: externalLinkIcon - anchors.verticalCenter: manageQueueLabel.verticalCenter - color: UM.Theme.getColor("primary") - source: "../svg/icons/external_link.svg" - width: 16 * screenScaleFactor // TODO: Theme! (Y U NO USE 18 LIKE ALL OTHER ICONS?!) - height: 16 * screenScaleFactor // TODO: Theme! (Y U NO USE 18 LIKE ALL OTHER ICONS?!) - } - Label - { - id: manageQueueText - anchors - { - left: externalLinkIcon.right - leftMargin: 6 * screenScaleFactor // TODO: Theme! - verticalCenter: externalLinkIcon.verticalCenter - } - color: UM.Theme.getColor("primary") - font: UM.Theme.getFont("default") // 12pt, regular - linkColor: UM.Theme.getColor("primary") - text: catalog.i18nc("@label link to connect manager", "Manage queue in Cura Connect") - } - } - - MouseArea - { - anchors.fill: manageQueueLabel - hoverEnabled: true - onClicked: Cura.MachineManager.printerOutputDevices[0].openPrintJobControlPanel() - onEntered: - { - manageQueueText.font.underline = true - } - onExited: - { - manageQueueText.font.underline = false - } - } - - Row - { - id: printJobQueueHeadings - anchors - { - left: queuedPrintJobs.left - leftMargin: 6 * screenScaleFactor // TODO: Theme! - top: queuedLabel.bottom - topMargin: 24 * screenScaleFactor // TODO: Theme! - } - spacing: 18 * screenScaleFactor // TODO: Theme! - - Label - { - text: catalog.i18nc("@label", "Print jobs") - color: "#666666" - elide: Text.ElideRight - font: UM.Theme.getFont("medium") // 14pt, regular - anchors.verticalCenter: parent.verticalCenter - width: 284 * screenScaleFactor // TODO: Theme! (Should match column size) - - // FIXED-LINE-HEIGHT: - height: 18 * screenScaleFactor // TODO: Theme! - verticalAlignment: Text.AlignVCenter - } - - Label - { - text: catalog.i18nc("@label", "Total print time") - color: "#666666" - elide: Text.ElideRight - font: UM.Theme.getFont("medium") // 14pt, regular - anchors.verticalCenter: parent.verticalCenter - width: 216 * screenScaleFactor // TODO: Theme! (Should match column size) - - // FIXED-LINE-HEIGHT: - height: 18 * screenScaleFactor // TODO: Theme! - verticalAlignment: Text.AlignVCenter - } - - Label - { - text: catalog.i18nc("@label", "Waiting for") - color: "#666666" - elide: Text.ElideRight - font: UM.Theme.getFont("medium") // 14pt, regular - anchors.verticalCenter: parent.verticalCenter - width: 216 * screenScaleFactor // TODO: Theme! (Should match column size) - - // FIXED-LINE-HEIGHT: - height: 18 * screenScaleFactor // TODO: Theme! - verticalAlignment: Text.AlignVCenter - } - } - - ScrollView - { - id: queuedPrintJobs - anchors - { - bottom: parent.bottom - horizontalCenter: parent.horizontalCenter - top: printJobQueueHeadings.bottom - topMargin: 12 * screenScaleFactor // TODO: Theme! - } - style: UM.Theme.styles.scrollview - visible: OutputDevice.receivedPrintJobs - width: parent.width - - ListView - { - id: printJobList - anchors.fill: parent - delegate: MonitorPrintJobCard - { - anchors - { - left: parent.left - right: parent.right - } - printJob: modelData - } - model: OutputDevice.queuedPrintJobs - spacing: 6 - } - } } PrinterVideoStream From 75d7d493499b4594166c8a7adf9d4be719065ff4 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 17 Dec 2018 14:41:28 +0100 Subject: [PATCH 0998/1292] STAR-322: Mocking the CuraApp --- .../src/Cloud/CloudApiClient.py | 10 +- .../tests/Cloud/TestCloudApiClient.py | 2 - .../tests/Cloud/TestCloudOutputDevice.py | 18 +- .../Cloud/TestCloudOutputDeviceManager.py | 51 +++-- .../tests/TestSendMaterialJob.py | 190 ++++++++++++++++++ plugins/UM3NetworkPrinting/tests/conftest.py | 40 ---- 6 files changed, 238 insertions(+), 73 deletions(-) create mode 100644 plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py delete mode 100644 plugins/UM3NetworkPrinting/tests/conftest.py diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py index d58def4545..c6fb02753f 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py @@ -52,7 +52,7 @@ class CloudApiClient: def getClusters(self, on_finished: Callable[[List[CloudClusterResponse]], Any]) -> None: url = "{}/clusters".format(self.CLUSTER_API_ROOT) reply = self._manager.get(self._createEmptyRequest(url)) - self._addCallbacks(reply, on_finished, CloudClusterResponse) + self._addCallback(reply, on_finished, CloudClusterResponse) ## Retrieves the status of the given cluster. # \param cluster_id: The ID of the cluster. @@ -60,7 +60,7 @@ class CloudApiClient: def getClusterStatus(self, cluster_id: str, on_finished: Callable[[CloudClusterStatus], Any]) -> None: url = "{}/clusters/{}/status".format(self.CLUSTER_API_ROOT, cluster_id) reply = self._manager.get(self._createEmptyRequest(url)) - self._addCallbacks(reply, on_finished, CloudClusterStatus) + self._addCallback(reply, on_finished, CloudClusterStatus) ## Requests the cloud to register the upload of a print job mesh. # \param request: The request object. @@ -70,7 +70,7 @@ class CloudApiClient: url = "{}/jobs/upload".format(self.CURA_API_ROOT) body = json.dumps({"data": request.toDict()}) reply = self._manager.put(self._createEmptyRequest(url), body.encode()) - self._addCallbacks(reply, on_finished, CloudPrintJobResponse) + self._addCallback(reply, on_finished, CloudPrintJobResponse) ## Requests the cloud to register the upload of a print job mesh. # \param upload_response: The object received after requesting an upload with `self.requestUpload`. @@ -90,7 +90,7 @@ class CloudApiClient: def requestPrint(self, cluster_id: str, job_id: str, on_finished: Callable[[CloudPrintResponse], Any]) -> None: url = "{}/clusters/{}/print/{}".format(self.CLUSTER_API_ROOT, cluster_id, job_id) reply = self._manager.post(self._createEmptyRequest(url), b"") - self._addCallbacks(reply, on_finished, CloudPrintResponse) + self._addCallback(reply, on_finished, CloudPrintResponse) ## We override _createEmptyRequest in order to add the user credentials. # \param url: The URL to request @@ -147,7 +147,7 @@ class CloudApiClient: # \param on_finished: The callback in case the response is successful. # \param model: The type of the model to convert the response to. It may either be a single record or a list. # \return: A function that can be passed to the - def _addCallbacks(self, + def _addCallback(self, reply: QNetworkReply, on_finished: Union[Callable[[Model], Any], Callable[[List[Model]], Any]], model: Type[Model], diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py index 49d2b1b34b..0c0c8cffdf 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py @@ -6,7 +6,6 @@ from typing import List from unittest import TestCase from unittest.mock import patch, MagicMock -from cura.CuraApplication import CuraApplication from cura.CuraConstants import CuraCloudAPIRoot from src.Cloud.CloudApiClient import CloudApiClient from src.Cloud.Models.CloudClusterResponse import CloudClusterResponse @@ -29,7 +28,6 @@ class TestCloudApiClient(TestCase): self.account = MagicMock() self.account.isLoggedIn.return_value = True - self.app = CuraApplication.getInstance() self.network = NetworkManagerMock() with patch("src.Cloud.CloudApiClient.QNetworkAccessManager", return_value = self.network): self.api = CloudApiClient(self.account, self._errorHandler) diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py index 90a1b2fa96..34e04689c2 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py @@ -30,9 +30,13 @@ class TestCloudOutputDevice(TestCase): def setUp(self): super().setUp() - self.app = CuraApplication.getInstance() - self.backend = MagicMock(backendStateChange = Signal()) - self.app.setBackend(self.backend) + self.app = MagicMock() + + self.patches = [patch("UM.Qt.QtApplication.QtApplication.getInstance", return_value=self.app), + patch("UM.Application.Application.getInstance", return_value=self.app)] + for patched_method in self.patches: + patched_method.start() + self.cluster = CloudClusterResponse(self.CLUSTER_ID, self.HOST_GUID, self.HOST_NAME, is_online=True, status="active") @@ -41,6 +45,7 @@ class TestCloudOutputDevice(TestCase): self.onError = MagicMock() with patch("src.Cloud.CloudApiClient.QNetworkAccessManager", return_value = self.network): self._api = CloudApiClient(self.account, self.onError) + self.device = CloudOutputDevice(self._api, self.cluster) self.cluster_status = parseFixture("getClusterStatusResponse") self.network.prepareReply("GET", self.STATUS_URL, 200, readFixture("getClusterStatusResponse")) @@ -48,6 +53,8 @@ class TestCloudOutputDevice(TestCase): def tearDown(self): super().tearDown() self.network.flushReplies() + for patched_method in self.patches: + patched_method.stop() def test_status(self): self.device._update() @@ -105,9 +112,8 @@ class TestCloudOutputDevice(TestCase): self.network.flushReplies() self.assertEqual([], self.device.printers) - @patch("cura.CuraApplication.CuraApplication.getGlobalContainerStack") - def test_print_to_cloud(self, global_container_stack_mock): - active_machine_mock = global_container_stack_mock.return_value + def test_print_to_cloud(self): + active_machine_mock = self.app.getGlobalContainerStack.return_value active_machine_mock.getMetaDataEntry.side_effect = {"file_formats": "application/gzip"}.get request_upload_response = parseFixture("putJobUploadResponse") diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py index 01b1b18ff1..96137a3edb 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py @@ -1,14 +1,14 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. from unittest import TestCase -from unittest.mock import patch +from unittest.mock import patch, MagicMock -from cura.CuraApplication import CuraApplication +from UM.OutputDevice.OutputDeviceManager import OutputDeviceManager from cura.CuraConstants import CuraCloudAPIRoot from src.Cloud.CloudOutputDevice import CloudOutputDevice from src.Cloud.CloudOutputDeviceManager import CloudOutputDeviceManager from tests.Cloud.Fixtures import parseFixture, readFixture -from .NetworkManagerMock import NetworkManagerMock +from .NetworkManagerMock import NetworkManagerMock, FakeSignal class TestCloudOutputDeviceManager(TestCase): @@ -18,9 +18,19 @@ class TestCloudOutputDeviceManager(TestCase): def setUp(self): super().setUp() - self.app = CuraApplication.getInstance() + self.app = MagicMock() + self.device_manager = OutputDeviceManager() + self.app.getOutputDeviceManager.return_value = self.device_manager + + self.patches = [patch("UM.Qt.QtApplication.QtApplication.getInstance", return_value=self.app), + patch("UM.Application.Application.getInstance", return_value=self.app)] + for patched_method in self.patches: + patched_method.start() + self.network = NetworkManagerMock() - with patch("src.Cloud.CloudApiClient.QNetworkAccessManager", return_value = self.network): + self.timer = MagicMock(timeout = FakeSignal()) + with patch("src.Cloud.CloudApiClient.QNetworkAccessManager", return_value = self.network), \ + patch("src.Cloud.CloudOutputDeviceManager.QTimer", return_value = self.timer): self.manager = CloudOutputDeviceManager() self.clusters_response = parseFixture("getClusters") self.network.prepareReply("GET", self.URL, 200, readFixture("getClusters")) @@ -28,7 +38,11 @@ class TestCloudOutputDeviceManager(TestCase): def tearDown(self): try: self._beforeTearDown() + + self.network.flushReplies() self.manager.stop() + for patched_method in self.patches: + patched_method.stop() finally: super().tearDown() @@ -38,8 +52,7 @@ class TestCloudOutputDeviceManager(TestCase): # let the network send replies self.network.flushReplies() # get the created devices - device_manager = self.app.getOutputDeviceManager() - devices = device_manager.getOutputDevices() + devices = self.device_manager.getOutputDevices() # get the server data clusters = self.clusters_response.get("data", []) self.assertEqual([CloudOutputDevice] * len(clusters), [type(d) for d in devices]) @@ -48,13 +61,12 @@ class TestCloudOutputDeviceManager(TestCase): key=lambda device_dict: device_dict["host_version"])) for device in clusters: - device_manager.getOutputDevice(device["cluster_id"]).close() - device_manager.removeOutputDevice(device["cluster_id"]) + self.device_manager.getOutputDevice(device["cluster_id"]).close() + self.device_manager.removeOutputDevice(device["cluster_id"]) ## Runs the initial request to retrieve the clusters. def _loadData(self): self.manager.start() - self.manager._onLoginStateChanged(is_logged_in = True) self.network.flushReplies() def test_device_is_created(self): @@ -79,22 +91,20 @@ class TestCloudOutputDeviceManager(TestCase): self.manager._update_timer.timeout.emit() - @patch("cura.CuraApplication.CuraApplication.getGlobalContainerStack") - def test_device_connects_by_cluster_id(self, global_container_stack_mock): - active_machine_mock = global_container_stack_mock.return_value + def test_device_connects_by_cluster_id(self): + active_machine_mock = self.app.getGlobalContainerStack.return_value cluster1, cluster2 = self.clusters_response["data"] cluster_id = cluster1["cluster_id"] active_machine_mock.getMetaDataEntry.side_effect = {"um_cloud_cluster_id": cluster_id}.get self._loadData() - self.assertTrue(self.app.getOutputDeviceManager().getOutputDevice(cluster1["cluster_id"]).isConnected()) - self.assertFalse(self.app.getOutputDeviceManager().getOutputDevice(cluster2["cluster_id"]).isConnected()) + self.assertTrue(self.device_manager.getOutputDevice(cluster1["cluster_id"]).isConnected()) + self.assertFalse(self.device_manager.getOutputDevice(cluster2["cluster_id"]).isConnected()) self.assertEquals([], active_machine_mock.setMetaDataEntry.mock_calls) - @patch("cura.CuraApplication.CuraApplication.getGlobalContainerStack") - def test_device_connects_by_network_key(self, global_container_stack_mock): - active_machine_mock = global_container_stack_mock.return_value + def test_device_connects_by_network_key(self): + active_machine_mock = self.app.getGlobalContainerStack.return_value cluster1, cluster2 = self.clusters_response["data"] network_key = cluster2["host_name"] + ".ultimaker.local" @@ -102,8 +112,9 @@ class TestCloudOutputDeviceManager(TestCase): self._loadData() - self.assertFalse(self.app.getOutputDeviceManager().getOutputDevice(cluster1["cluster_id"]).isConnected()) - self.assertTrue(self.app.getOutputDeviceManager().getOutputDevice(cluster2["cluster_id"]).isConnected()) + self.assertEqual([False, True], + [self.device_manager.getOutputDevice(cluster["cluster_id"]).isConnected() + for cluster in (cluster1, cluster2)]) active_machine_mock.setMetaDataEntry.assert_called_with("um_cloud_cluster_id", cluster2["cluster_id"]) diff --git a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py new file mode 100644 index 0000000000..b669eb192a --- /dev/null +++ b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py @@ -0,0 +1,190 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +import io +import json +from unittest import TestCase, mock +from unittest.mock import patch, call + +from PyQt5.QtCore import QByteArray + +from UM.MimeTypeDatabase import MimeType +from UM.Application import Application +from plugins.UM3NetworkPrinting.src.SendMaterialJob import SendMaterialJob + + +@patch("builtins.open", lambda _, __: io.StringIO("")) +@patch("UM.MimeTypeDatabase.MimeTypeDatabase.getMimeTypeForFile", + lambda _: MimeType(name = "application/x-ultimaker-material-profile", comment = "Ultimaker Material Profile", + suffixes = ["xml.fdm_material"])) +@patch("UM.Resources.Resources.getAllResourcesOfType", lambda _: ["/materials/generic_pla_white.xml.fdm_material"]) +@patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") +@patch("PyQt5.QtNetwork.QNetworkReply") +class TestSendMaterialJob(TestCase): + _LOCAL_MATERIAL_WHITE = {"type": "material", "status": "unknown", "id": "generic_pla_white", + "base_file": "generic_pla_white", "setting_version": "5", "name": "White PLA", + "brand": "Generic", "material": "PLA", "color_name": "White", + "GUID": "badb0ee7-87c8-4f3f-9398-938587b67dce", "version": "1", "color_code": "#ffffff", + "description": "Test PLA White", "adhesion_info": "Use glue.", "approximate_diameter": "3", + "properties": {"density": "1.00", "diameter": "2.85", "weight": "750"}, + "definition": "fdmprinter", "compatible": True} + + _LOCAL_MATERIAL_BLACK = {"type": "material", "status": "unknown", "id": "generic_pla_black", + "base_file": "generic_pla_black", "setting_version": "5", "name": "Yellow CPE", + "brand": "Ultimaker", "material": "CPE", "color_name": "Black", + "GUID": "5fbb362a-41f9-4818-bb43-15ea6df34aa4", "version": "1", "color_code": "#000000", + "description": "Test PLA Black", "adhesion_info": "Use glue.", "approximate_diameter": "3", + "properties": {"density": "1.01", "diameter": "2.85", "weight": "750"}, + "definition": "fdmprinter", "compatible": True} + + _REMOTE_MATERIAL_WHITE = { + "guid": "badb0ee7-87c8-4f3f-9398-938587b67dce", + "material": "PLA", + "brand": "Generic", + "version": 1, + "color": "White", + "density": 1.00 + } + + _REMOTE_MATERIAL_BLACK = { + "guid": "5fbb362a-41f9-4818-bb43-15ea6df34aa4", + "material": "PLA", + "brand": "Generic", + "version": 2, + "color": "Black", + "density": 1.00 + } + + def test_run(self, device_mock, reply_mock): + job = SendMaterialJob(device_mock) + job.run() + + # We expect the materials endpoint to be called when the job runs. + device_mock.get.assert_called_with("materials/", on_finished = job._onGetRemoteMaterials) + + def test__onGetRemoteMaterials_withFailedRequest(self, reply_mock, device_mock): + reply_mock.attribute.return_value = 404 + job = SendMaterialJob(device_mock) + job._onGetRemoteMaterials(reply_mock) + + # We expect the device not to be called for any follow up. + self.assertEqual(0, device_mock.createFormPart.call_count) + + def test__onGetRemoteMaterials_withWrongEncoding(self, reply_mock, device_mock): + reply_mock.attribute.return_value = 200 + reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTE_MATERIAL_WHITE]).encode("cp500")) + job = SendMaterialJob(device_mock) + job._onGetRemoteMaterials(reply_mock) + + # Given that the parsing fails we do no expect the device to be called for any follow up. + self.assertEqual(0, device_mock.createFormPart.call_count) + + def test__onGetRemoteMaterials_withBadJsonAnswer(self, reply_mock, device_mock): + reply_mock.attribute.return_value = 200 + reply_mock.readAll.return_value = QByteArray(b"Six sick hicks nick six slick bricks with picks and sticks.") + job = SendMaterialJob(device_mock) + job._onGetRemoteMaterials(reply_mock) + + # Given that the parsing fails we do no expect the device to be called for any follow up. + self.assertEqual(0, device_mock.createFormPart.call_count) + + def test__onGetRemoteMaterials_withMissingGuidInRemoteMaterial(self, reply_mock, device_mock): + reply_mock.attribute.return_value = 200 + remote_material_without_guid = self._REMOTE_MATERIAL_WHITE.copy() + del remote_material_without_guid["guid"] + reply_mock.readAll.return_value = QByteArray(json.dumps([remote_material_without_guid]).encode("ascii")) + job = SendMaterialJob(device_mock) + job._onGetRemoteMaterials(reply_mock) + + # Given that parsing fails we do not expect the device to be called for any follow up. + self.assertEqual(0, device_mock.createFormPart.call_count) + + @patch("cura.Settings.CuraContainerRegistry") + @patch("UM.Application") + def test__onGetRemoteMaterials_withInvalidVersionInLocalMaterial(self, application_mock, container_registry_mock, + reply_mock, device_mock): + reply_mock.attribute.return_value = 200 + reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTE_MATERIAL_WHITE]).encode("ascii")) + + localMaterialWhiteWithInvalidVersion = self._LOCAL_MATERIAL_WHITE.copy() + localMaterialWhiteWithInvalidVersion["version"] = "one" + container_registry_mock.findContainersMetadata.return_value = [localMaterialWhiteWithInvalidVersion] + + application_mock.getContainerRegistry.return_value = container_registry_mock + + with mock.patch.object(Application, "getInstance", new = lambda: application_mock): + job = SendMaterialJob(device_mock) + job._onGetRemoteMaterials(reply_mock) + + self.assertEqual(0, device_mock.createFormPart.call_count) + + @patch("cura.Settings.CuraContainerRegistry") + @patch("UM.Application") + def test__onGetRemoteMaterials_withNoUpdate(self, application_mock, container_registry_mock, reply_mock, + device_mock): + application_mock.getContainerRegistry.return_value = container_registry_mock + + device_mock.createFormPart.return_value = "_xXx_" + + container_registry_mock.findContainersMetadata.return_value = [self._LOCAL_MATERIAL_WHITE] + + reply_mock.attribute.return_value = 200 + reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTE_MATERIAL_WHITE]).encode("ascii")) + + with mock.patch.object(Application, "getInstance", new = lambda: application_mock): + job = SendMaterialJob(device_mock) + job._onGetRemoteMaterials(reply_mock) + + self.assertEqual(0, device_mock.createFormPart.call_count) + self.assertEqual(0, device_mock.postFormWithParts.call_count) + + @patch("cura.Settings.CuraContainerRegistry") + @patch("UM.Application") + def test__onGetRemoteMaterials_withUpdatedMaterial(self, application_mock, container_registry_mock, reply_mock, + device_mock): + application_mock.getContainerRegistry.return_value = container_registry_mock + + device_mock.createFormPart.return_value = "_xXx_" + + localMaterialWhiteWithHigherVersion = self._LOCAL_MATERIAL_WHITE.copy() + localMaterialWhiteWithHigherVersion["version"] = "2" + container_registry_mock.findContainersMetadata.return_value = [localMaterialWhiteWithHigherVersion] + + reply_mock.attribute.return_value = 200 + reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTE_MATERIAL_WHITE]).encode("ascii")) + + with mock.patch.object(Application, "getInstance", new = lambda: application_mock): + job = SendMaterialJob(device_mock) + job._onGetRemoteMaterials(reply_mock) + + self.assertEqual(1, device_mock.createFormPart.call_count) + self.assertEqual(1, device_mock.postFormWithParts.call_count) + self.assertEquals( + [call.createFormPart("name=\"file\"; filename=\"generic_pla_white.xml.fdm_material\"", ""), + call.postFormWithParts(target = "materials/", parts = ["_xXx_"], on_finished = job.sendingFinished)], + device_mock.method_calls) + + @patch("cura.Settings.CuraContainerRegistry") + @patch("UM.Application") + def test__onGetRemoteMaterials_withNewMaterial(self, application_mock, container_registry_mock, reply_mock, + device_mock): + application_mock.getContainerRegistry.return_value = container_registry_mock + + device_mock.createFormPart.return_value = "_xXx_" + + container_registry_mock.findContainersMetadata.return_value = [self._LOCAL_MATERIAL_WHITE, + self._LOCAL_MATERIAL_BLACK] + + reply_mock.attribute.return_value = 200 + reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTE_MATERIAL_BLACK]).encode("ascii")) + + with mock.patch.object(Application, "getInstance", new = lambda: application_mock): + job = SendMaterialJob(device_mock) + job._onGetRemoteMaterials(reply_mock) + + self.assertEqual(1, device_mock.createFormPart.call_count) + self.assertEqual(1, device_mock.postFormWithParts.call_count) + self.assertEquals( + [call.createFormPart("name=\"file\"; filename=\"generic_pla_white.xml.fdm_material\"", ""), + call.postFormWithParts(target = "materials/", parts = ["_xXx_"], on_finished = job.sendingFinished)], + device_mock.method_calls) diff --git a/plugins/UM3NetworkPrinting/tests/conftest.py b/plugins/UM3NetworkPrinting/tests/conftest.py deleted file mode 100644 index ce49bd3cb7..0000000000 --- a/plugins/UM3NetworkPrinting/tests/conftest.py +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright (c) 2018 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. - -import pytest -from UM.Signal import Signal - -from cura.CuraApplication import CuraApplication -from cura.Machines.MaterialManager import MaterialManager - - -# This mock application must extend from Application and not QtApplication otherwise some QObjects are created and -# a segfault is raised. -class FixtureApplication(CuraApplication): - def __init__(self): - super().__init__() - super().initialize() - Signal._signalQueue = self - - self.getPreferences().addPreference("cura/favorite_materials", "") - - self._material_manager = MaterialManager(self._container_registry, parent = self) - self._material_manager.initialize() - - def functionEvent(self, event): - event.call() - - def parseCommandLine(self): - pass - - def processEvents(self): - pass - - -@pytest.fixture(autouse=True) -def application(): - # Since we need to use it more that once, we create the application the first time and use its instance the second - application = FixtureApplication.getInstance() - if application is None: - application = FixtureApplication() - return application From 42ae9faeb4df483be003b6f45c7f91605402d54f Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 17 Dec 2018 14:42:16 +0100 Subject: [PATCH 0999/1292] STAR-322: Reverting change to run mypy --- run_mypy.py | 1 - 1 file changed, 1 deletion(-) diff --git a/run_mypy.py b/run_mypy.py index 2073f0e9a7..27f07cd281 100644 --- a/run_mypy.py +++ b/run_mypy.py @@ -29,7 +29,6 @@ def where(exe_name: str, search_path: str = os.getenv("PATH")) -> str: def findModules(path): - return ["UM3NetworkPrinting"] result = [] for entry in os.scandir(path): if entry.is_dir() and os.path.exists(os.path.join(path, entry.name, "__init__.py")): From da974d98686356eee9a39335334841d02fe68555 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 17 Dec 2018 14:51:57 +0100 Subject: [PATCH 1000/1292] STAR-322: Improving documentation --- .../src/Cloud/CloudApiClient.py | 32 +++++++++++-------- .../tests/Cloud/NetworkManagerMock.py | 4 +-- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py index c6fb02753f..29a9f48c3f 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py @@ -72,12 +72,12 @@ class CloudApiClient: reply = self._manager.put(self._createEmptyRequest(url), body.encode()) self._addCallback(reply, on_finished, CloudPrintJobResponse) - ## Requests the cloud to register the upload of a print job mesh. - # \param upload_response: The object received after requesting an upload with `self.requestUpload`. + ## Uploads a print job mesh to the cloud. + # \param print_job: The object received after requesting an upload with `self.requestUpload`. # \param mesh: The mesh data to be uploaded. - # \param on_finished: The function to be called after the result is parsed. It receives the print job ID. + # \param on_finished: The function to be called after the upload is successful. # \param on_progress: A function to be called during upload progress. It receives a percentage (0-100). - # \param on_error: A function to be called if the upload fails. It receives a dict with the error. + # \param on_error: A function to be called if the upload fails. def uploadMesh(self, print_job: CloudPrintJobResponse, mesh: bytes, on_finished: Callable[[], Any], on_progress: Callable[[int], Any], on_error: Callable[[], Any]): self._upload = MeshUploader(self._manager, print_job, mesh, on_finished, on_progress, on_error) @@ -134,24 +134,28 @@ class CloudApiClient: data = response["data"] if isinstance(data, list): results = [model_class(**c) for c in data] # type: List[CloudApiClient.Model] - cast(Callable[[List[CloudApiClient.Model]], Any], on_finished)(results) + on_finished_list = cast(Callable[[List[CloudApiClient.Model]], Any], on_finished) + on_finished_list(results) else: result = model_class(**data) # type: CloudApiClient.Model - cast(Callable[[CloudApiClient.Model], Any], on_finished)(result) + on_finished_item = cast(Callable[[CloudApiClient.Model], Any], on_finished) + on_finished_item(result) elif "errors" in response: self._on_error([CloudErrorObject(**error) for error in response["errors"]]) else: Logger.log("e", "Cannot find data or errors in the cloud response: %s", response) - ## Wraps a callback function so that it includes the parsing of the response into the correct model. - # \param on_finished: The callback in case the response is successful. - # \param model: The type of the model to convert the response to. It may either be a single record or a list. - # \return: A function that can be passed to the + ## Creates a callback function so that it includes the parsing of the response into the correct model. + # The callback is added to the 'finished' signal of the reply. + # \param reply: The reply that should be listened to. + # \param on_finished: The callback in case the response is successful. Depending on the endpoint it will be either + # a list or a single item. + # \param model: The type of the model to convert the response to. def _addCallback(self, - reply: QNetworkReply, - on_finished: Union[Callable[[Model], Any], Callable[[List[Model]], Any]], - model: Type[Model], - ) -> None: + reply: QNetworkReply, + on_finished: Union[Callable[[Model], Any], Callable[[List[Model]], Any]], + model: Type[Model], + ) -> None: def parse() -> None: status_code, response = self._parseReply(reply) self._anti_gc_callbacks.remove(parse) diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py b/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py index 59b79fdfa6..5b5d89ca54 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py @@ -1,7 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import json -from typing import Dict, Tuple, Union, Optional +from typing import Dict, Tuple, Union, Optional, Any from unittest.mock import MagicMock from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest @@ -53,7 +53,7 @@ class NetworkManagerMock: # Since the methods are very simple and the same it didn't make sense to repeat the code. # \param method: The method being called. # \return The mocked function, if the method name is known. Defaults to the standard getattr function. - def __getattr__(self, method: str) -> any: + def __getattr__(self, method: str) -> Any: ## This mock implementation will simply return the reply from the prepared ones. # it raises a KeyError if requests are done without being prepared. def doRequest(request: QNetworkRequest, body: Optional[bytes] = None, *_): From d28ac5e1205f8b5d3083807c2975925c78052e9b Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 17 Dec 2018 14:57:57 +0100 Subject: [PATCH 1001/1292] STAR-322: Improving documentation --- .../src/Cloud/CloudOutputDevice.py | 19 +++++++++---------- .../src/Cloud/CloudOutputDeviceManager.py | 2 ++ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index f29e29c40b..fed8cb040a 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -83,7 +83,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## Creates a new cloud output device # \param api_client: The client that will run the API calls - # \param device_id: The ID of the device (i.e. the cluster_id for the cloud API) + # \param cluster: The device response received from the cloud API. # \param parent: The optional parent of this output device. def __init__(self, api_client: CloudApiClient, cluster: CloudClusterResponse, parent: QObject = None) -> None: super().__init__(device_id = cluster.cluster_id, address = "", properties = {}, parent = parent) @@ -118,30 +118,33 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # A set of the user's job IDs that have finished self._finished_jobs = set() # type: Set[str] - # Reference to the uploaded print job + # Reference to the uploaded print job / mesh self._mesh = None # type: Optional[bytes] self._uploaded_print_job = None # type: Optional[CloudPrintJobResponse] + ## Connects this device. def connect(self) -> None: super().connect() Logger.log("i", "Connected to cluster %s", self.key) CuraApplication.getInstance().getBackend().backendStateChange.connect(self._onBackendStateChange) + ## Disconnects the device def disconnect(self) -> None: super().disconnect() Logger.log("i", "Disconnected to cluster %s", self.key) CuraApplication.getInstance().getBackend().backendStateChange.disconnect(self._onBackendStateChange) + ## Resets the print job that was uploaded to force a new upload, runs whenever the user re-slices. def _onBackendStateChange(self, _: BackendState) -> None: self._mesh = None self._uploaded_print_job = None - ## Gets the host name of this device + ## Gets the cluster response from which this device was created. @property def clusterData(self) -> CloudClusterResponse: return self._cluster - ## Updates the host name of the output device + ## Updates the cluster data from the cloud. @clusterData.setter def clusterData(self, value: CloudClusterResponse) -> None: self._cluster = value @@ -166,11 +169,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # Show an error message if we're already sending a job. if self._progress.visible: - Message( - text = T.BLOCKED_UPLOADING, - title = T.ERROR, - lifetime = 10, - ).show() + message = Message(text = T.BLOCKED_UPLOADING, title = T.ERROR, lifetime = 10) + message.show() return if self._uploaded_print_job: @@ -312,7 +312,6 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): model.updateAssignedPrinter(printer) ## Uploads the mesh when the print job was registered with the cloud API. - # \param mesh: The bytes to upload. # \param job_response: The response received from the cloud API. def _onPrintJobCreated(self, job_response: CloudPrintJobResponse) -> None: self._progress.show() diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 29c60fd14a..07051f15fd 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -139,6 +139,7 @@ class CloudOutputDeviceManager: ) message.show() + ## Starts running the cloud output device manager, thus periodically requesting cloud data. def start(self): if self._running: return @@ -149,6 +150,7 @@ class CloudOutputDeviceManager: self._update_timer.timeout.connect(self._getRemoteClusters) self._onLoginStateChanged(is_logged_in = self._account.isLoggedIn) + ## Stops running the cloud output device manager. def stop(self): if not self._running: return From c5f438819a60c547b9d416696a6fc4665b539aa3 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 17 Dec 2018 15:11:01 +0100 Subject: [PATCH 1002/1292] STAR-322: Improving documentation --- .../src/Cloud/CloudProgressMessage.py | 5 ++ .../src/Cloud/MeshUploader.py | 54 ++++++++++++++----- 2 files changed, 45 insertions(+), 14 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudProgressMessage.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudProgressMessage.py index e3e0cefc0c..aefe59cc85 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudProgressMessage.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudProgressMessage.py @@ -12,6 +12,7 @@ class T: SENDING_DATA_TITLE = _I18N_CATALOG.i18nc("@info:status", "Sending data to remote cluster") +## Class responsible for showing a progress message while a mesh is being uploaded to the cloud. class CloudProgressMessage(Message): def __init__(self): super().__init__( @@ -23,15 +24,19 @@ class CloudProgressMessage(Message): use_inactivity_timer = False ) + ## Shows the progress message. def show(self): self.setProgress(0) super().show() + ## Updates the percentage of the uploaded. + # \param percentage: The percentage amount (0-100). def update(self, percentage: int) -> None: if not self._visible: super().show() self.setProgress(percentage) + ## Returns a boolean indicating whether the message is currently visible. @property def visible(self) -> bool: return self._visible diff --git a/plugins/UM3NetworkPrinting/src/Cloud/MeshUploader.py b/plugins/UM3NetworkPrinting/src/Cloud/MeshUploader.py index f0360b83e3..9d9662a82a 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/MeshUploader.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/MeshUploader.py @@ -9,16 +9,25 @@ from UM.Logger import Logger from src.Cloud.Models.CloudPrintJobResponse import CloudPrintJobResponse +## Class responsible for uploading meshes to the cloud in separate requests. class MeshUploader: + + # The maximum amount of times to retry if the server returns one of the RETRY_HTTP_CODES MAX_RETRIES = 10 - BYTES_PER_REQUEST = 256 * 1024 + + # The HTTP codes that should trigger a retry. RETRY_HTTP_CODES = {500, 502, 503, 504} - ## Creates a resumable upload - # \param url: The URL to which we shall upload. - # \param content_length: The total content length of the file, in bytes. - # \param http_method: The HTTP method to be used, e.g. "POST" or "PUT". - # \param timeout: The timeout for each chunk upload. Important: If None, no timeout is applied at all. + # The amount of bytes to send per request + BYTES_PER_REQUEST = 256 * 1024 + + ## Creates a mesh upload object. + # \param manager: The network access manager that will handle the HTTP requests. + # \param print_job: The print job response that was returned by the cloud after registering the upload. + # \param data: The mesh bytes to be uploaded. + # \param on_finished: The method to be called when done. + # \param on_progress: The method to be called when the progress changes (receives a percentage 0-100). + # \param on_error: The method to be called when an error occurs. def __init__(self, manager: QNetworkAccessManager, print_job: CloudPrintJobResponse, data: bytes, on_finished: Callable[[], Any], on_progress: Callable[[int], Any], on_error: Callable[[], Any] ) -> None: @@ -35,13 +44,12 @@ class MeshUploader: self._finished = False self._reply = None # type: Optional[QNetworkReply] + ## Returns the print job for which this object was created. @property def printJob(self): return self._print_job - ## We override _createRequest in order to add the user credentials. - # \param url: The URL to request - # \param content_type: The type of the body contents. + ## Creates a network request to the print job upload URL, adding the needed content range header. def _createRequest(self) -> QNetworkRequest: request = QNetworkRequest(QUrl(self._print_job.upload_url)) request.setHeader(QNetworkRequest.ContentTypeHeader, self._print_job.content_type) @@ -53,21 +61,27 @@ class MeshUploader: return request + ## Determines the bytes that should be uploaded next. + # \return: A tuple with the first and the last byte to upload. def _chunkRange(self) -> Tuple[int, int]: last_byte = min(len(self._data), self._sent_bytes + self.BYTES_PER_REQUEST) return self._sent_bytes, last_byte + ## Starts uploading the mesh. def start(self) -> None: if self._finished: + # reset state. self._sent_bytes = 0 self._retries = 0 self._finished = False self._uploadChunk() + ## Stops uploading the mesh, marking it as finished. def stop(self): Logger.log("i", "Stopped uploading") self._finished = True + ## Uploads a chunk of the mesh to the cloud. def _uploadChunk(self) -> None: if self._finished: raise ValueError("The upload is already finished") @@ -75,16 +89,22 @@ class MeshUploader: first_byte, last_byte = self._chunkRange() request = self._createRequest() + # now send the reply and subscribe to the results self._reply = self._manager.put(request, self._data[first_byte:last_byte]) self._reply.finished.connect(self._finishedCallback) self._reply.uploadProgress.connect(self._progressCallback) self._reply.error.connect(self._errorCallback) + ## Handles an update to the upload progress + # \param bytes_sent: The amount of bytes sent in the current request. + # \param bytes_total: The amount of bytes to send in the current request. def _progressCallback(self, bytes_sent: int, bytes_total: int) -> None: Logger.log("i", "Progress callback %s / %s", bytes_sent, bytes_total) if bytes_total: - self._on_progress(int((self._sent_bytes + bytes_sent) / len(self._data) * 100)) + total_sent = self._sent_bytes + bytes_sent + self._on_progress(int(total_sent / len(self._data) * 100)) + ## Handles an error uploading. def _errorCallback(self) -> None: reply = cast(QNetworkReply, self._reply) body = bytes(reply.readAll()).decode() @@ -92,27 +112,33 @@ class MeshUploader: self.stop() self._on_error() + ## Checks whether a chunk of data was uploaded successfully, starting the next chunk if needed. def _finishedCallback(self) -> None: reply = cast(QNetworkReply, self._reply) Logger.log("i", "Finished callback %s %s", reply.attribute(QNetworkRequest.HttpStatusCodeAttribute), reply.url().toString()) - status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) + status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) # type: int + # check if we should retry the last chunk if self._retries < self.MAX_RETRIES and status_code in self.RETRY_HTTP_CODES: self._retries += 1 Logger.log("i", "Retrying %s/%s request %s", self._retries, self.MAX_RETRIES, reply.url().toString()) self._uploadChunk() return + # Http codes that are not to be retried are assumed to be errors. if status_code > 308: self._errorCallback() return - body = bytes(reply.readAll()).decode() - Logger.log("w", "status_code: %s, Headers: %s, body: %s", status_code, - [bytes(header).decode() for header in reply.rawHeaderList()], body) + Logger.log("d", "status_code: %s, Headers: %s, body: %s", status_code, + [bytes(header).decode() for header in reply.rawHeaderList()], bytes(reply.readAll()).decode()) + self._chunkUploaded() + ## Handles a chunk of data being uploaded, starting the next chunk if needed. + def _chunkUploaded(self) -> None: + # We got a successful response. Let's start the next chunk or report the upload is finished. first_byte, last_byte = self._chunkRange() self._sent_bytes += last_byte - first_byte if self._sent_bytes >= len(self._data): From 53da111617d9363784e3363659653496ebd4c734 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 17 Dec 2018 15:21:48 +0100 Subject: [PATCH 1003/1292] Change "Rating" to "Your rating" --- plugins/Toolbox/resources/qml/ToolboxDetailPage.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 92b9fb1198..b9b36cd878 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -88,7 +88,7 @@ Item height: childrenRect.height Label { - text: catalog.i18nc("@label", "Rating") + ":" + text: catalog.i18nc("@label", "Your rating") + ":" font: UM.Theme.getFont("default") color: UM.Theme.getColor("text_medium") renderType: Text.NativeRendering From 135219365423e588303c5bf30e6e94c851bfd4cd Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 17 Dec 2018 15:26:10 +0100 Subject: [PATCH 1004/1292] Ensure that the sourceSize is set correctly --- plugins/Toolbox/resources/qml/RatingWidget.qml | 2 ++ plugins/Toolbox/resources/qml/SmallRatingWidget.qml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/plugins/Toolbox/resources/qml/RatingWidget.qml b/plugins/Toolbox/resources/qml/RatingWidget.qml index 3dcae6d602..441cf238f7 100644 --- a/plugins/Toolbox/resources/qml/RatingWidget.qml +++ b/plugins/Toolbox/resources/qml/RatingWidget.qml @@ -75,6 +75,8 @@ Item background: UM.RecolorImage { source: UM.Theme.getIcon(control.isStarFilled ? "star_filled" : "star_empty") + sourceSize.width: width + sourceSize.height: height // Unfilled stars should always have the default color. Only filled stars should change on hover color: diff --git a/plugins/Toolbox/resources/qml/SmallRatingWidget.qml b/plugins/Toolbox/resources/qml/SmallRatingWidget.qml index 686058f4e8..4950ea9242 100644 --- a/plugins/Toolbox/resources/qml/SmallRatingWidget.qml +++ b/plugins/Toolbox/resources/qml/SmallRatingWidget.qml @@ -17,6 +17,8 @@ Row color: model.user_rating == 0 ? UM.Theme.getColor("rating_star") : UM.Theme.getColor("primary") height: UM.Theme.getSize("rating_star").height width: UM.Theme.getSize("rating_star").width + sourceSize.height: height + sourceSize.width: width } Label From 4d135c13bb8dc5f6971d07eb6682962433826b55 Mon Sep 17 00:00:00 2001 From: alekseisasin Date: Mon, 17 Dec 2018 16:46:02 +0100 Subject: [PATCH 1005/1292] Cura used wrong firmware version for UMO+. The firmware was from UMO. The reason of this issue because it used a heated firmware from his parent(UMO) printer. To avoid this case we need to define externally the firmware_hbk_file property in umo+ defintion file CURA-5994 --- resources/definitions/ultimaker_original_plus.def.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/definitions/ultimaker_original_plus.def.json b/resources/definitions/ultimaker_original_plus.def.json index 5ad7ae66e8..bdb8a3d788 100644 --- a/resources/definitions/ultimaker_original_plus.def.json +++ b/resources/definitions/ultimaker_original_plus.def.json @@ -16,7 +16,8 @@ { "0": "ultimaker_original_plus_extruder_0" }, - "firmware_file": "MarlinUltimaker-UMOP-{baudrate}.hex" + "firmware_file": "MarlinUltimaker-UMOP-{baudrate}.hex", + "firmware_hbk_file": "MarlinUltimaker-UMOP-{baudrate}.hex" }, "overrides": { From 5c697ab5bed61ad4169db31ac676cdd2f056d9c8 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 17 Dec 2018 16:58:51 +0100 Subject: [PATCH 1006/1292] Make hints clickable Contributes to CL-1151 --- .../resources/qml/MonitorCarousel.qml | 46 +++++++++++-------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml index ea1449ac8d..476e3c2aa1 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml @@ -25,7 +25,7 @@ Item anchors { right: leftButton.left - rightMargin: 12 * screenScaleFactor + rightMargin: 12 * screenScaleFactor // TODO: Theme! left: parent.left } height: parent.height @@ -40,15 +40,20 @@ Item GradientStop { position: 0.0 - color: "#fff6f6f6" + color: "#fff6f6f6" // TODO: Theme! } GradientStop { position: 1.0 - color: "#66f6f6f6" + color: "#66f6f6f6" // TODO: Theme! } } } + MouseArea + { + anchors.fill: parent + onClicked: navigateTo(currentIndex - 1) + } } Button @@ -58,7 +63,7 @@ Item { verticalCenter: parent.verticalCenter right: centerSection.left - rightMargin: 12 * screenScaleFactor + rightMargin: 12 * screenScaleFactor // TODO: Theme! } width: 36 * screenScaleFactor // TODO: Theme! height: 72 * screenScaleFactor // TODO: Theme! @@ -79,10 +84,10 @@ Item UM.RecolorImage { anchors.centerIn: parent - width: 18 - height: width - sourceSize.width: width - sourceSize.height: width + width: 18 // TODO: Theme! + height: width // TODO: Theme! + sourceSize.width: width // TODO: Theme! + sourceSize.height: width // TODO: Theme! color: "#152950" // TODO: Theme! source: UM.Theme.getIcon("arrow_left") } @@ -105,7 +110,7 @@ Item { id: tiles height: childrenRect.height - width: 5 * tileWidth + 4 * tileSpacing + width: 5 * tileWidth + 4 * tileSpacing // TODO: Theme! x: 0 z: 0 Behavior on x @@ -137,7 +142,7 @@ Item { verticalCenter: parent.verticalCenter left: centerSection.right - leftMargin: 12 * screenScaleFactor + leftMargin: 12 * screenScaleFactor // TODO: Theme! } width: 36 * screenScaleFactor // TODO: Theme! height: 72 * screenScaleFactor // TODO: Theme! @@ -158,10 +163,10 @@ Item UM.RecolorImage { anchors.centerIn: parent - width: 18 - height: width - sourceSize.width: width - sourceSize.height: width + width: 18 // TODO: Theme! + height: width // TODO: Theme! + sourceSize.width: width // TODO: Theme! + sourceSize.height: width // TODO: Theme! color: "#152950" // TODO: Theme! source: UM.Theme.getIcon("arrow_right") } @@ -174,7 +179,7 @@ Item anchors { left: rightButton.right - leftMargin: 12 * screenScaleFactor + leftMargin: 12 * screenScaleFactor // TODO: Theme! right: parent.right } height: centerSection.height @@ -190,15 +195,20 @@ Item GradientStop { position: 0.0 - color: "#66f6f6f6" + color: "#66f6f6f6" // TODO: Theme! } GradientStop { position: 1.0 - color: "#fff6f6f6" + color: "#fff6f6f6" // TODO: Theme! } } } + MouseArea + { + anchors.fill: parent + onClicked: navigateTo(currentIndex + 1) + } } Item @@ -223,7 +233,7 @@ Item color: model.index == currentIndex ? "#777777" : "#d8d8d8" // TODO: Theme! radius: Math.floor(width / 2) width: 12 * screenScaleFactor // TODO: Theme! - height: width + height: width // TODO: Theme! } onClicked: navigateTo(model.index) } From d6212d5a398d19bf72d9a718b316270629dcef52 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 17 Dec 2018 17:29:24 +0100 Subject: [PATCH 1007/1292] Add elide in the showcase title and reduce the height a bit so there are only 2 lines for the title. --- plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml | 1 + resources/themes/cura-light/theme.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml index bb4f34163d..c8c1e56c82 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml @@ -47,6 +47,7 @@ Rectangle height: UM.Theme.getSize("toolbox_heading_label").height width: parent.width - UM.Theme.getSize("default_margin").width wrapMode: Text.WordWrap + elide: Text.ElideRight font: UM.Theme.getFont("medium_bold") } UM.RecolorImage diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index ea6c92b479..83a51e5431 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -495,7 +495,7 @@ "toolbox_back_button": [4.0, 2.0], "toolbox_installed_tile": [1.0, 8.0], "toolbox_property_label": [1.0, 2.0], - "toolbox_heading_label": [1.0, 4.0], + "toolbox_heading_label": [1.0, 3.8], "toolbox_header": [1.0, 4.0], "toolbox_header_highlight": [0.25, 0.25], "toolbox_progress_bar": [8.0, 0.5], From 0e294481ff9e2ffa4e2dbe24dda5b527a74a0fcc Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 17 Dec 2018 17:32:11 +0100 Subject: [PATCH 1008/1292] Improve readability of printer_type_label for dark theme --- resources/themes/cura-dark/theme.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/resources/themes/cura-dark/theme.json b/resources/themes/cura-dark/theme.json index cade342488..537fccbc5c 100644 --- a/resources/themes/cura-dark/theme.json +++ b/resources/themes/cura-dark/theme.json @@ -40,6 +40,8 @@ "text_scene": [255, 255, 255, 162], "text_scene_hover": [255, 255, 255, 204], + "printer_type_label_background": [95, 95, 95, 255], + "error": [212, 31, 53, 255], "disabled": [32, 32, 32, 255], From 3f7c9227340a57f1d031910a34ff6e23221c9fb8 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 17 Dec 2018 17:37:12 +0100 Subject: [PATCH 1009/1292] Add missing type for g-code reader --- plugins/GCodeReader/FlavorParser.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/GCodeReader/FlavorParser.py b/plugins/GCodeReader/FlavorParser.py index 6fe2cb5260..baf21d47ce 100644 --- a/plugins/GCodeReader/FlavorParser.py +++ b/plugins/GCodeReader/FlavorParser.py @@ -364,6 +364,8 @@ class FlavorParser: self._layer_type = LayerPolygon.SupportType elif type == "FILL": self._layer_type = LayerPolygon.InfillType + elif type == "SUPPORT-INTERFACE": + self._layer_type = LayerPolygon.SupportInterfaceType else: Logger.log("w", "Encountered a unknown type (%s) while parsing g-code.", type) From 7d6e698f431c24126d0521b408bd2dafb79788ec Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 17 Dec 2018 17:37:21 +0100 Subject: [PATCH 1010/1292] Fix (USB) print monitor in dark theme --- plugins/USBPrinting/MonitorItem.qml | 2 ++ resources/qml/PrintMonitor.qml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/USBPrinting/MonitorItem.qml b/plugins/USBPrinting/MonitorItem.qml index 8041698ef0..c86353f814 100644 --- a/plugins/USBPrinting/MonitorItem.qml +++ b/plugins/USBPrinting/MonitorItem.qml @@ -13,6 +13,8 @@ Component { Rectangle { + color: UM.Theme.getColor("main_background") + anchors.right: parent.right width: parent.width * 0.3 anchors.top: parent.top diff --git a/resources/qml/PrintMonitor.qml b/resources/qml/PrintMonitor.qml index 6d8edf0deb..d44acf0adb 100644 --- a/resources/qml/PrintMonitor.qml +++ b/resources/qml/PrintMonitor.qml @@ -12,7 +12,7 @@ import Cura 1.0 as Cura import "PrinterOutput" -Rectangle +Item { id: base UM.I18nCatalog { id: catalog; name: "cura"} From 74bec96ce810a569b02161dd0b14f7032194341f Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 17 Dec 2018 17:41:02 +0100 Subject: [PATCH 1011/1292] Fix a relative import --- plugins/UM3NetworkPrinting/src/Cloud/MeshUploader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/MeshUploader.py b/plugins/UM3NetworkPrinting/src/Cloud/MeshUploader.py index 9d9662a82a..cb721b872e 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/MeshUploader.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/MeshUploader.py @@ -6,7 +6,7 @@ from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply, QNetworkAccessManage from typing import Optional, Callable, Any, Tuple, cast from UM.Logger import Logger -from src.Cloud.Models.CloudPrintJobResponse import CloudPrintJobResponse +from .Models.CloudPrintJobResponse import CloudPrintJobResponse ## Class responsible for uploading meshes to the cloud in separate requests. From d395c38436712979639747c202741f788dbd388d Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 17 Dec 2018 17:47:33 +0100 Subject: [PATCH 1012/1292] Removed collapse / expand all I don't think it ever worked. --- resources/qml/Settings/SettingView.qml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index c1b4b28d1d..972cbcdbb1 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -558,17 +558,6 @@ Item onTriggered: Cura.Actions.configureSettingVisibility.trigger(contextMenu); } - MenuSeparator {} - MenuItem - { - text: catalog.i18nc("@action:inmenu", "Collapse All") - onTriggered: definitionsModel.collapseAll() - } - MenuItem - { - text: catalog.i18nc("@action:inmenu", "Expand All") - onTriggered: definitionsModel.expandRecursive() - } } UM.SettingPropertyProvider From 62d20ac773b617e1ed0fe0a43ce05913ca59b789 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 17 Dec 2018 17:55:40 +0100 Subject: [PATCH 1013/1292] Change the base color of the tooltips to align with the designs Contributes to CURA-6004. --- resources/themes/cura-light/theme.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 83a51e5431..2b9ce3d218 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -229,7 +229,7 @@ "checkbox_disabled": [223, 223, 223, 255], "checkbox_text": [35, 35, 35, 255], - "tooltip": [68, 192, 255, 255], + "tooltip": [25, 25, 25, 255], "tooltip_text": [255, 255, 255, 255], "message_background": [255, 255, 255, 255], From 6017c2b4d2cd52110856e3cb835638a40458a6b6 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 18 Dec 2018 08:55:55 +0100 Subject: [PATCH 1014/1292] Replace isProfileUserCreated with hasCustomQuality CURA-6028 --- cura/Settings/MachineManager.py | 4 +++ cura/Settings/SimpleModeSettingsManager.py | 32 ------------------- .../RecommendedQualityProfileSelector.qml | 23 ++++--------- 3 files changed, 10 insertions(+), 49 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index e26b82e487..5e0bbea1ee 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1529,6 +1529,10 @@ class MachineManager(QObject): def activeQualityChangesGroup(self) -> Optional["QualityChangesGroup"]: return self._current_quality_changes_group + @pyqtProperty(bool, notify = activeQualityChangesGroupChanged) + def hasCustomQuality(self) -> bool: + return self._current_quality_changes_group is not None + @pyqtProperty(str, notify = activeQualityGroupChanged) def activeQualityOrQualityChangesName(self) -> str: name = empty_quality_container.getName() diff --git a/cura/Settings/SimpleModeSettingsManager.py b/cura/Settings/SimpleModeSettingsManager.py index b22aea15ea..b1896a9205 100644 --- a/cura/Settings/SimpleModeSettingsManager.py +++ b/cura/Settings/SimpleModeSettingsManager.py @@ -17,15 +17,11 @@ class SimpleModeSettingsManager(QObject): self._is_profile_user_created = False # True when profile was custom created by user self._machine_manager.activeStackValueChanged.connect(self._updateIsProfileCustomized) - self._machine_manager.activeQualityGroupChanged.connect(self.updateIsProfileUserCreated) - self._machine_manager.activeQualityChangesGroupChanged.connect(self.updateIsProfileUserCreated) # update on create as the activeQualityChanged signal is emitted before this manager is created when Cura starts self._updateIsProfileCustomized() - self.updateIsProfileUserCreated() isProfileCustomizedChanged = pyqtSignal() - isProfileUserCreatedChanged = pyqtSignal() @pyqtProperty(bool, notify = isProfileCustomizedChanged) def isProfileCustomized(self): @@ -58,34 +54,6 @@ class SimpleModeSettingsManager(QObject): self._is_profile_customized = has_customized_user_settings self.isProfileCustomizedChanged.emit() - @pyqtProperty(bool, notify = isProfileUserCreatedChanged) - def isProfileUserCreated(self): - return self._is_profile_user_created - - @pyqtSlot() - def updateIsProfileUserCreated(self) -> None: - quality_changes_keys = set() # type: Set[str] - - if not self._machine_manager.activeMachine: - return - - global_stack = self._machine_manager.activeMachine - - # check quality changes settings in the global stack - quality_changes_keys.update(global_stack.qualityChanges.getAllKeys()) - - # check quality changes settings in the extruder stacks - if global_stack.extruders: - for extruder_stack in global_stack.extruders.values(): - quality_changes_keys.update(extruder_stack.qualityChanges.getAllKeys()) - - # check if the qualityChanges container is not empty (meaning it is a user created profile) - has_quality_changes = len(quality_changes_keys) > 0 - - if has_quality_changes != self._is_profile_user_created: - self._is_profile_user_created = has_quality_changes - self.isProfileUserCreatedChanged.emit() - # These are the settings included in the Simple ("Recommended") Mode, so only when the other settings have been # changed, we consider it as a user customized profile in the Simple ("Recommended") Mode. __ignored_custom_setting_keys = ["support_enable", diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml index e6b3f1b9eb..1e71134404 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml @@ -39,17 +39,6 @@ Item { target: Cura.QualityProfilesDropDownMenuModel onItemsChanged: qualityModel.update() - onDataChanged: - { - // If a custom profile is selected and then a user decides to change any of setting the slider should show - // the reset button. After clicking the reset button the QualityProfilesDropDownMenuModel(ListModel) is - // updated before the property isProfileCustomized is called to update. - if (Cura.SimpleModeSettingsManager.isProfileCustomized) - { - Cura.SimpleModeSettingsManager.updateIsProfileUserCreated() - } - qualityModel.update() - } } Connections { @@ -97,7 +86,7 @@ Item if (Cura.MachineManager.activeQualityType == qualityItem.quality_type) { // set to -1 when switching to user created profile so all ticks are clickable - if (Cura.SimpleModeSettingsManager.isProfileUserCreated) + if (Cura.MachineManager.hasCustomQuality) { qualityModel.qualitySliderActiveIndex = -1 } @@ -192,7 +181,7 @@ Item { id: customisedSettings - visible: Cura.SimpleModeSettingsManager.isProfileCustomized || Cura.SimpleModeSettingsManager.isProfileUserCreated + visible: Cura.SimpleModeSettingsManager.isProfileCustomized || Cura.MachineManager.hasCustomQuality height: visible ? UM.Theme.getSize("print_setup_icon").height : 0 width: height anchors @@ -358,7 +347,7 @@ Item { anchors.fill: parent hoverEnabled: true - enabled: !Cura.SimpleModeSettingsManager.isProfileUserCreated + enabled: !Cura.MachineManager.hasCustomQuality onEntered: { var tooltipContent = catalog.i18nc("@tooltip", "This quality profile is not available for your current material and nozzle configuration. Please change these to enable this quality profile") @@ -417,7 +406,7 @@ Item implicitWidth: UM.Theme.getSize("print_setup_slider_handle").width implicitHeight: implicitWidth radius: Math.round(implicitWidth / 2) - visible: !Cura.SimpleModeSettingsManager.isProfileCustomized && !Cura.SimpleModeSettingsManager.isProfileUserCreated && qualityModel.existingQualityProfile + visible: !Cura.SimpleModeSettingsManager.isProfileCustomized && !Cura.MachineManager.hasCustomQuality && qualityModel.existingQualityProfile } } @@ -441,7 +430,7 @@ Item anchors.fill: parent hoverEnabled: true acceptedButtons: Qt.NoButton - enabled: !Cura.SimpleModeSettingsManager.isProfileUserCreated + enabled: !Cura.MachineManager.hasCustomQuality } } @@ -451,7 +440,7 @@ Item { anchors.fill: parent hoverEnabled: true - visible: Cura.SimpleModeSettingsManager.isProfileUserCreated + visible: Cura.MachineManager.hasCustomQuality onEntered: { From 9f52a52ea3ee9e497c8b7dc220a9077ad7c64c59 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 18 Dec 2018 09:32:11 +0100 Subject: [PATCH 1015/1292] Fix ExtruderModel reference in machine settings dialog --- .../MachineSettingsAction.qml | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index d8efe6f8b8..a9900070a8 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -14,20 +14,9 @@ Cura.MachineAction { id: base property var extrudersModel: CuraApplication.getExtrudersModel() - property int extruderTabsCount: 0 property var activeMachineId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.id : "" - Connections - { - target: base.extrudersModel - onModelChanged: - { - var extruderCount = base.extrudersModel.count; - base.extruderTabsCount = extruderCount; - } - } - Connections { target: dialog ? dialog : null @@ -357,11 +346,11 @@ Cura.MachineAction Repeater { id: extruderTabsRepeater - model: base.extruderTabsCount + model: base.extrudersModel Tab { - title: base.extrudersModel.getItem(index).name + title: model.name anchors.margins: UM.Theme.getSize("default_margin").width Column From 84a7f2e5a2d1ec96f74ffb15b9b08f053af44198 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 18 Dec 2018 09:40:08 +0100 Subject: [PATCH 1016/1292] Fix review comments CURA-6011 --- cura/PrintersModel.py | 2 +- cura/Settings/MachineManager.py | 4 ++-- plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py | 10 +++++----- .../UM3NetworkPrinting/src/UM3OutputDevicePlugin.py | 2 +- plugins/USBPrinting/USBPrinterOutputDevice.py | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/cura/PrintersModel.py b/cura/PrintersModel.py index 0c58d9bf8c..8b5d2f6cc9 100644 --- a/cura/PrintersModel.py +++ b/cura/PrintersModel.py @@ -54,7 +54,7 @@ class PrintersModel(ListModel): for container_stack in container_stacks: connection_type = container_stack.getMetaDataEntry("connection_type") - has_remote_connection = connection_type in [str(ConnectionType.NetworkConnection), str(ConnectionType.CloudConnection)] + has_remote_connection = connection_type in [ConnectionType.NetworkConnection.value, ConnectionType.CloudConnection.value] if container_stack.getMetaDataEntry("hidden", False) in ["True", True]: continue diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index c51c26f1b9..e1ae0d761c 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -521,11 +521,11 @@ class MachineManager(QObject): def printerConnected(self): return bool(self._printer_output_devices) - @pyqtProperty(bool, notify=printerConnectedStatusChanged) + @pyqtProperty(bool, notify = printerConnectedStatusChanged) def activeMachineHasRemoteConnection(self) -> bool: if self._global_container_stack: connection_type = self._global_container_stack.getMetaDataEntry("connection_type") - return connection_type in [str(ConnectionType.NetworkConnection), str(ConnectionType.CloudConnection)] + return connection_type in [ConnectionType.NetworkConnection.value, ConnectionType.CloudConnection.value] return False def activeMachineNetworkKey(self) -> str: diff --git a/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py b/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py index 2e59810317..6ce99e4891 100644 --- a/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py +++ b/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py @@ -136,13 +136,13 @@ class DiscoverUM3Action(MachineAction): global_container_stack.removeMetaDataEntry("network_authentication_key") CuraApplication.getInstance().getMachineManager().replaceContainersMetadata(key = "um_network_key", value = previous_network_key, new_value = printer_device.key) - if "um_connection_type" in meta_data: - previous_connection_type = meta_data["um_connection_type"] - global_container_stack.setMetaDataEntry("um_connection_type", printer_device.getConnectionType().value) - CuraApplication.getInstance().getMachineManager().replaceContainersMetadata(key = "um_connection_type", value = previous_connection_type, new_value = printer_device.getConnectionType().value) + if "connection_type" in meta_data: + previous_connection_type = meta_data["connection_type"] + global_container_stack.setMetaDataEntry("connection_type", printer_device.getConnectionType().value) + CuraApplication.getInstance().getMachineManager().replaceContainersMetadata(key = "connection_type", value = previous_connection_type, new_value = printer_device.getConnectionType().value) else: global_container_stack.setMetaDataEntry("um_network_key", printer_device.key) - global_container_stack.setMetaDataEntry("um_connection_type", printer_device.getConnectionType().value) + global_container_stack.setMetaDataEntry("connection_type", printer_device.getConnectionType().value) if self._network_plugin: # Ensure that the connection states are refreshed. diff --git a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py index 43290c8e44..80212fcf00 100644 --- a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py +++ b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py @@ -283,7 +283,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): global_container_stack = Application.getInstance().getGlobalContainerStack() if global_container_stack and device.getId() == global_container_stack.getMetaDataEntry("um_network_key"): - global_container_stack.setMetaDataEntry("connection_type", str(device.getConnectionType())) + global_container_stack.setMetaDataEntry("connection_type", device.getConnectionType().value) device.connect() device.connectionStateChanged.connect(self._onDeviceConnectionStateChanged) diff --git a/plugins/USBPrinting/USBPrinterOutputDevice.py b/plugins/USBPrinting/USBPrinterOutputDevice.py index 08cf29baf4..19a703e605 100644 --- a/plugins/USBPrinting/USBPrinterOutputDevice.py +++ b/plugins/USBPrinting/USBPrinterOutputDevice.py @@ -29,7 +29,7 @@ catalog = i18nCatalog("cura") class USBPrinterOutputDevice(PrinterOutputDevice): def __init__(self, serial_port: str, baud_rate: Optional[int] = None) -> None: - super().__init__(serial_port, connection_type=ConnectionType.UsbConnection) + super().__init__(serial_port, connection_type = ConnectionType.UsbConnection) self.setName(catalog.i18nc("@item:inmenu", "USB printing")) self.setShortDescription(catalog.i18nc("@action:button Preceded by 'Ready to'.", "Print via USB")) self.setDescription(catalog.i18nc("@info:tooltip", "Print via USB")) From aa0c8c75ee40373b1b2faac4055b72b06164d3ee Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 18 Dec 2018 09:45:26 +0100 Subject: [PATCH 1017/1292] Add a sane default to connection type CURA-6011 --- cura/PrinterOutputDevice.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index b33993f150..3102d73bb0 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -74,7 +74,7 @@ class PrinterOutputDevice(QObject, OutputDevice): # Signal to indicate that the configuration of one of the printers has changed. uniqueConfigurationsChanged = pyqtSignal() - def __init__(self, device_id: str, connection_type: "ConnectionType", parent: QObject = None) -> None: + def __init__(self, device_id: str, connection_type: "ConnectionType" = ConnectionType.Unknown, parent: QObject = None) -> None: super().__init__(device_id = device_id, parent = parent) # type: ignore # MyPy complains with the multiple inheritance self._printers = [] # type: List[PrinterOutputModel] From be9d35d45f63d5a3c6896abcfca1a74165ec0f1b Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 18 Dec 2018 09:47:51 +0100 Subject: [PATCH 1018/1292] Fix some minor layout issues CURA-6011 --- resources/qml/PrinterSelector/MachineSelectorList.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/PrinterSelector/MachineSelectorList.qml b/resources/qml/PrinterSelector/MachineSelectorList.qml index 52cea0ea80..ea8068fa95 100644 --- a/resources/qml/PrinterSelector/MachineSelectorList.qml +++ b/resources/qml/PrinterSelector/MachineSelectorList.qml @@ -11,7 +11,6 @@ ListView { id: listView height: childrenRect.height - width: 200 model: Cura.PrintersModel {} section.property: "hasRemoteConnection" @@ -19,6 +18,7 @@ ListView { text: section == "true" ? catalog.i18nc("@label", "Connected printers") : catalog.i18nc("@label", "Preset printers") width: parent.width + height: visible ? contentHeight + 2 * UM.Theme.getSize("default_margin").height : 0 leftPadding: UM.Theme.getSize("default_margin").width renderType: Text.NativeRendering font: UM.Theme.getFont("medium") From cc462ef3a609be1df9ee0fb9d94ce4a541db2183 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 18 Dec 2018 10:29:44 +0100 Subject: [PATCH 1019/1292] Add a placeholder for a pattern in the header, if the theme wants to add one. --- resources/qml/Cura.qml | 11 + .../cura-light/images/header_pattern.svg | 1901 ----------------- 2 files changed, 11 insertions(+), 1901 deletions(-) delete mode 100644 resources/themes/cura-light/images/header_pattern.svg diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 8ab943b93b..8a34c7e219 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -123,6 +123,17 @@ UM.MainWindow } } } + + // This is a placehoder for adding a pattern in the header + Image + { + id: backgroundPattern + anchors.fill: parent + fillMode: Image.Tile + source: UM.Theme.getImage("header_pattern") + horizontalAlignment: Image.AlignLeft + verticalAlignment: Image.AlignTop + } } MainWindowHeader diff --git a/resources/themes/cura-light/images/header_pattern.svg b/resources/themes/cura-light/images/header_pattern.svg deleted file mode 100644 index eff5f01cfa..0000000000 --- a/resources/themes/cura-light/images/header_pattern.svg +++ /dev/null @@ -1,1901 +0,0 @@ - - - - Desktop HD - Created with Sketch. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file From dff9a3dfb24301d27e6ef53365bd4786d9d926a9 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 18 Dec 2018 10:52:11 +0100 Subject: [PATCH 1020/1292] Fix None problem in project loading --- plugins/3MFReader/ThreeMFWorkspaceReader.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py index 9ee2ef0dd4..55296979b5 100755 --- a/plugins/3MFReader/ThreeMFWorkspaceReader.py +++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py @@ -794,7 +794,8 @@ class ThreeMFWorkspaceReader(WorkspaceReader): # Clear all existing containers quality_changes_info.global_info.container.clear() for container_info in quality_changes_info.extruder_info_dict.values(): - container_info.container.clear() + if container_info.container: + container_info.container.clear() # Loop over everything and override the existing containers global_info = quality_changes_info.global_info From 9b6e52a5be95471b96baa4fe53f674c719f37b00 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 18 Dec 2018 13:08:18 +0100 Subject: [PATCH 1021/1292] Make monitor item background themable --- plugins/USBPrinting/MonitorItem.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/USBPrinting/MonitorItem.qml b/plugins/USBPrinting/MonitorItem.qml index 8041698ef0..14b1402e50 100644 --- a/plugins/USBPrinting/MonitorItem.qml +++ b/plugins/USBPrinting/MonitorItem.qml @@ -17,6 +17,7 @@ Component width: parent.width * 0.3 anchors.top: parent.top anchors.bottom: parent.bottom + color: UM.Theme.getColor("main_background") Cura.PrintMonitor { From 627c647fbcca9555807770fa640fa69b47c9877c Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 18 Dec 2018 13:17:25 +0100 Subject: [PATCH 1022/1292] Center navigation dots Contributes to CL-1151 --- .../resources/qml/MonitorCarousel.qml | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml index 476e3c2aa1..a3e2517b45 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml @@ -211,7 +211,7 @@ Item } } - Item + Row { id: navigationDots anchors @@ -220,23 +220,20 @@ Item top: centerSection.bottom topMargin: 36 * screenScaleFactor // TODO: Theme! } - Row + spacing: 8 * screenScaleFactor // TODO: Theme! + Repeater { - spacing: 8 * screenScaleFactor // TODO: Theme! - Repeater + model: OutputDevice.printers + Button { - model: OutputDevice.printers - Button + background: Rectangle { - background: Rectangle - { - color: model.index == currentIndex ? "#777777" : "#d8d8d8" // TODO: Theme! - radius: Math.floor(width / 2) - width: 12 * screenScaleFactor // TODO: Theme! - height: width // TODO: Theme! - } - onClicked: navigateTo(model.index) + color: model.index == currentIndex ? "#777777" : "#d8d8d8" // TODO: Theme! + radius: Math.floor(width / 2) + width: 12 * screenScaleFactor // TODO: Theme! + height: width // TODO: Theme! } + onClicked: navigateTo(model.index) } } } From e885b527370a84d0399962b436e3da472d8ac85a Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 18 Dec 2018 13:42:23 +0100 Subject: [PATCH 1023/1292] Add time prime tower into Cura.proto --- plugins/CuraEngineBackend/Cura.proto | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/CuraEngineBackend/Cura.proto b/plugins/CuraEngineBackend/Cura.proto index 292330576b..c4f934bc00 100644 --- a/plugins/CuraEngineBackend/Cura.proto +++ b/plugins/CuraEngineBackend/Cura.proto @@ -29,7 +29,7 @@ message Object bytes normals = 3; //An array of 3 floats. bytes indices = 4; //An array of ints. repeated Setting settings = 5; // Setting override per object, overruling the global settings. - string name = 6; + string name = 6; //Mesh name } message Progress @@ -108,8 +108,9 @@ message PrintTimeMaterialEstimates { // The print time for each feature and mate float time_travel = 9; float time_retract = 10; float time_support_interface = 11; + float time_prime_tower = 12; - repeated MaterialEstimates materialEstimates = 12; // materialEstimates data + repeated MaterialEstimates materialEstimates = 13; // materialEstimates data } message MaterialEstimates { From 279812e4ff356170463dbf0e693e86689a063945 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 18 Dec 2018 13:55:12 +0100 Subject: [PATCH 1024/1292] Round width of buttons They were getting rendered a bit weird if your pixel scale was not an integer (for me it's 1.25). --- resources/qml/Preferences/MachinesPage.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Preferences/MachinesPage.qml b/resources/qml/Preferences/MachinesPage.qml index bc75b9bc72..4acefdb493 100644 --- a/resources/qml/Preferences/MachinesPage.qml +++ b/resources/qml/Preferences/MachinesPage.qml @@ -1,4 +1,4 @@ -// Copyright (c) 2016 Ultimaker B.V. +// Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 @@ -91,7 +91,7 @@ UM.ManagementPage Item { - width: childrenRect.width + 2 * screenScaleFactor + width: Math.round(childrenRect.width + 2 * screenScaleFactor) height: childrenRect.height Button { From 1ac5403c21a6b55f372f19329328ef618ecf03fb Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Tue, 18 Dec 2018 15:52:26 +0100 Subject: [PATCH 1025/1292] Remove extruder tabs from tabView CURA-6036 --- .../MachineSettingsAction/MachineSettingsAction.qml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index a9900070a8..60dd31dcae 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -348,6 +348,17 @@ Cura.MachineAction id: extruderTabsRepeater model: base.extrudersModel + + onItemAdded: + { + settingsTabs.addTab(index + 1, item) + } + + onItemRemoved: + { + settingsTabs.removeTab(index + 1) + } + Tab { title: model.name From 1b11164340d93ee6f955a6b710dd2dbe3865489a Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 18 Dec 2018 16:09:19 +0100 Subject: [PATCH 1026/1292] Remove unused import and add documentation --- cura/Machines/Models/FavoriteMaterialsModel.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cura/Machines/Models/FavoriteMaterialsModel.py b/cura/Machines/Models/FavoriteMaterialsModel.py index cc273e55ce..98a2a01597 100644 --- a/cura/Machines/Models/FavoriteMaterialsModel.py +++ b/cura/Machines/Models/FavoriteMaterialsModel.py @@ -1,10 +1,9 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from UM.Logger import Logger from cura.Machines.Models.BaseMaterialsModel import BaseMaterialsModel - +## Model that shows the list of favorite materials. class FavoriteMaterialsModel(BaseMaterialsModel): def __init__(self, parent = None): super().__init__(parent) From da69c16e0962231b2d8ae14cc5684d5788f57bf8 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 18 Dec 2018 16:14:13 +0100 Subject: [PATCH 1027/1292] Split the constants in to files, indicating which constants each file stores. Contributes to CURA-6005. --- cura/API/Account.py | 4 +- ...uraConstants.py => ApplicationMetadata.py} | 96 +++++++------------ cura/CuraApplication.py | 14 +-- cura/UltimakerCloudAuthentication.py | 24 +++++ plugins/CuraDrive/src/Settings.py | 4 +- plugins/Toolbox/src/Toolbox.py | 10 +- 6 files changed, 76 insertions(+), 76 deletions(-) rename cura/{CuraConstants.py => ApplicationMetadata.py} (50%) create mode 100644 cura/UltimakerCloudAuthentication.py diff --git a/cura/API/Account.py b/cura/API/Account.py index 7b4bc32e99..47f67af8ce 100644 --- a/cura/API/Account.py +++ b/cura/API/Account.py @@ -6,7 +6,7 @@ from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot, pyqtProperty from UM.i18n import i18nCatalog from UM.Message import Message -from cura import CuraConstants +from cura import UltimakerCloudAuthentication from cura.OAuth2.AuthorizationService import AuthorizationService from cura.OAuth2.Models import OAuth2Settings @@ -38,7 +38,7 @@ class Account(QObject): self._logged_in = False self._callback_port = 32118 - self._oauth_root = CuraConstants.CuraCloudAccountAPIRoot + self._oauth_root = UltimakerCloudAuthentication.CuraCloudAccountAPIRoot self._oauth_settings = OAuth2Settings( OAUTH_SERVER_URL= self._oauth_root, diff --git a/cura/CuraConstants.py b/cura/ApplicationMetadata.py similarity index 50% rename from cura/CuraConstants.py rename to cura/ApplicationMetadata.py index 7ca8ea865b..e2ac4453eb 100644 --- a/cura/CuraConstants.py +++ b/cura/ApplicationMetadata.py @@ -1,60 +1,36 @@ -# -# This file contains all constant values in Cura -# - -# ------------- -# Cura Versions -# ------------- -DEFAULT_CURA_DISPLAY_NAME = "Ultimaker Cura" -DEFAULT_CURA_VERSION = "master" -DEFAULT_CURA_BUILD_TYPE = "" -DEFAULT_CURA_DEBUG_MODE = False -DEFAULT_CURA_SDK_VERSION = "5.0.0" - -try: - from cura.CuraVersion import CuraAppDisplayName # type: ignore -except ImportError: - CuraAppDisplayName = DEFAULT_CURA_DISPLAY_NAME - -try: - from cura.CuraVersion import CuraVersion # type: ignore -except ImportError: - CuraVersion = DEFAULT_CURA_VERSION # [CodeStyle: Reflecting imported value] - -try: - from cura.CuraVersion import CuraBuildType # type: ignore -except ImportError: - CuraBuildType = DEFAULT_CURA_BUILD_TYPE - -try: - from cura.CuraVersion import CuraDebugMode # type: ignore -except ImportError: - CuraDebugMode = DEFAULT_CURA_DEBUG_MODE - -try: - from cura.CuraVersion import CuraSDKVersion # type: ignore -except ImportError: - CuraSDKVersion = DEFAULT_CURA_SDK_VERSION - - -# --------- -# Cloud API -# --------- -DEFAULT_CLOUD_API_ROOT = "https://api.ultimaker.com" # type: str -DEFAULT_CLOUD_API_VERSION = "1" # type: str -DEFAULT_CLOUD_ACCOUNT_API_ROOT = "https://account.ultimaker.com" # type: str - -try: - from cura.CuraVersion import CuraCloudAPIRoot # type: ignore -except ImportError: - CuraCloudAPIRoot = DEFAULT_CLOUD_API_ROOT - -try: - from cura.CuraVersion import CuraCloudAPIVersion # type: ignore -except ImportError: - CuraCloudAPIVersion = DEFAULT_CLOUD_API_VERSION - -try: - from cura.CuraVersion import CuraCloudAccountAPIRoot # type: ignore -except ImportError: - CuraCloudAccountAPIRoot = DEFAULT_CLOUD_ACCOUNT_API_ROOT +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +# --------- +# Genearl constants used in Cura +# --------- +DEFAULT_CURA_DISPLAY_NAME = "Ultimaker Cura" +DEFAULT_CURA_VERSION = "master" +DEFAULT_CURA_BUILD_TYPE = "" +DEFAULT_CURA_DEBUG_MODE = False +DEFAULT_CURA_SDK_VERSION = "6.0.0" + +try: + from cura.CuraVersion import CuraAppDisplayName # type: ignore +except ImportError: + CuraAppDisplayName = DEFAULT_CURA_DISPLAY_NAME + +try: + from cura.CuraVersion import CuraVersion # type: ignore +except ImportError: + CuraVersion = DEFAULT_CURA_VERSION # [CodeStyle: Reflecting imported value] + +try: + from cura.CuraVersion import CuraBuildType # type: ignore +except ImportError: + CuraBuildType = DEFAULT_CURA_BUILD_TYPE + +try: + from cura.CuraVersion import CuraDebugMode # type: ignore +except ImportError: + CuraDebugMode = DEFAULT_CURA_DEBUG_MODE + +try: + from cura.CuraVersion import CuraSDKVersion # type: ignore +except ImportError: + CuraSDKVersion = DEFAULT_CURA_SDK_VERSION diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index a7845708e4..748c5c2fc4 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -115,7 +115,7 @@ from cura.ObjectsModel import ObjectsModel from cura.PrinterOutput.NetworkMJPGImage import NetworkMJPGImage -from cura import CuraConstants +from cura import ApplicationMetadata from UM.FlameProfiler import pyqtSlot from UM.Decorators import override @@ -164,11 +164,11 @@ class CuraApplication(QtApplication): def __init__(self, *args, **kwargs): super().__init__(name = "cura", - app_display_name = CuraConstants.CuraAppDisplayName, - version = CuraConstants.CuraVersion, - api_version = CuraConstants.CuraSDKVersion, - buildtype = CuraConstants.CuraBuildType, - is_debug_mode = CuraConstants.CuraDebugMode, + app_display_name = ApplicationMetadata.CuraAppDisplayName, + version = ApplicationMetadata.CuraVersion, + api_version = ApplicationMetadata.CuraSDKVersion, + buildtype = ApplicationMetadata.CuraBuildType, + is_debug_mode = ApplicationMetadata.CuraDebugMode, tray_icon_name = "cura-icon-32.png", **kwargs) @@ -953,7 +953,7 @@ class CuraApplication(QtApplication): engine.rootContext().setContextProperty("CuraApplication", self) engine.rootContext().setContextProperty("PrintInformation", self._print_information) engine.rootContext().setContextProperty("CuraActions", self._cura_actions) - engine.rootContext().setContextProperty("CuraSDKVersion", CuraConstants.CuraSDKVersion) + engine.rootContext().setContextProperty("CuraSDKVersion", ApplicationMetadata.CuraSDKVersion) qmlRegisterUncreatableType(CuraApplication, "Cura", 1, 0, "ResourceTypes", "Just an Enum type") diff --git a/cura/UltimakerCloudAuthentication.py b/cura/UltimakerCloudAuthentication.py new file mode 100644 index 0000000000..7ebdfd054b --- /dev/null +++ b/cura/UltimakerCloudAuthentication.py @@ -0,0 +1,24 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +# --------- +# Constants used for the Cloud API +# --------- +DEFAULT_CLOUD_API_ROOT = "https://api.ultimaker.com" # type: str +DEFAULT_CLOUD_API_VERSION = "1" # type: str +DEFAULT_CLOUD_ACCOUNT_API_ROOT = "https://account.ultimaker.com" # type: str + +try: + from cura.CuraVersion import CuraCloudAPIRoot # type: ignore +except ImportError: + CuraCloudAPIRoot = DEFAULT_CLOUD_API_ROOT + +try: + from cura.CuraVersion import CuraCloudAPIVersion # type: ignore +except ImportError: + CuraCloudAPIVersion = DEFAULT_CLOUD_API_VERSION + +try: + from cura.CuraVersion import CuraCloudAccountAPIRoot # type: ignore +except ImportError: + CuraCloudAccountAPIRoot = DEFAULT_CLOUD_ACCOUNT_API_ROOT diff --git a/plugins/CuraDrive/src/Settings.py b/plugins/CuraDrive/src/Settings.py index c0df66b950..4ee73ad149 100644 --- a/plugins/CuraDrive/src/Settings.py +++ b/plugins/CuraDrive/src/Settings.py @@ -1,7 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. from UM import i18nCatalog -from cura import CuraConstants +from cura import UltimakerCloudAuthentication class Settings: @@ -9,7 +9,7 @@ class Settings: Keeps the application settings. """ DRIVE_API_VERSION = 1 - DRIVE_API_URL = "{}/cura-drive/v{}".format(CuraConstants.CuraCloudAPIRoot, str(DRIVE_API_VERSION)) + DRIVE_API_URL = "{}/cura-drive/v{}".format(UltimakerCloudAuthentication.CuraCloudAPIRoot, str(DRIVE_API_VERSION)) AUTO_BACKUP_ENABLED_PREFERENCE_KEY = "cura_drive/auto_backup_enabled" AUTO_BACKUP_LAST_DATE_PREFERENCE_KEY = "cura_drive/auto_backup_date" diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 2229ab1f67..e7e849f1d2 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -16,8 +16,8 @@ from UM.Extension import Extension from UM.i18n import i18nCatalog from UM.Version import Version -import cura -from cura import CuraConstants +from cura import ApplicationMetadata +from cura import UltimakerCloudAuthentication from cura.CuraApplication import CuraApplication from .AuthorsModel import AuthorsModel @@ -39,9 +39,9 @@ class Toolbox(QObject, Extension): self._application = application # type: CuraApplication - self._sdk_version = CuraConstants.CuraSDKVersion # type: Union[str, int] - self._cloud_api_version = CuraConstants.CuraCloudAPIVersion # type: int - self._cloud_api_root = CuraConstants.CuraCloudAPIRoot # type: str + self._sdk_version = ApplicationMetadata.CuraSDKVersion # type: Union[str, int] + self._cloud_api_version = UltimakerCloudAuthentication.CuraCloudAPIVersion # type: int + self._cloud_api_root = UltimakerCloudAuthentication.CuraCloudAPIRoot # type: str self._api_url = None # type: Optional[str] # Network: From 8e78582b619e9e2511f57dd00162c800fcf4c43d Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 18 Dec 2018 16:17:37 +0100 Subject: [PATCH 1028/1292] Add correct copyright and license header to all the files in the plugin Contributes to CURA-6005. --- plugins/CuraDrive/__init__.py | 4 +++- plugins/CuraDrive/plugin.json | 2 +- plugins/CuraDrive/src/DriveApiService.py | 4 +++- plugins/CuraDrive/src/DrivePluginExtension.py | 4 +++- plugins/CuraDrive/src/Settings.py | 2 ++ plugins/CuraDrive/src/UploadBackupJob.py | 2 ++ plugins/CuraDrive/src/models/BackupListModel.py | 2 ++ plugins/CuraDrive/src/qml/components/BackupList.qml | 2 ++ plugins/CuraDrive/src/qml/components/BackupListFooter.qml | 2 ++ plugins/CuraDrive/src/qml/components/BackupListItem.qml | 2 ++ .../CuraDrive/src/qml/components/BackupListItemDetails.qml | 2 ++ .../CuraDrive/src/qml/components/BackupListItemDetailsRow.qml | 2 ++ plugins/CuraDrive/src/qml/components/Divider.qml | 2 ++ plugins/CuraDrive/src/qml/components/Icon.qml | 2 ++ plugins/CuraDrive/src/qml/components/RightSideScrollBar.qml | 2 ++ plugins/CuraDrive/src/qml/main.qml | 2 ++ plugins/CuraDrive/src/qml/pages/BackupsPage.qml | 2 ++ plugins/CuraDrive/src/qml/pages/WelcomePage.qml | 2 ++ 18 files changed, 38 insertions(+), 4 deletions(-) diff --git a/plugins/CuraDrive/__init__.py b/plugins/CuraDrive/__init__.py index 6612a5d614..4103b0cf2e 100644 --- a/plugins/CuraDrive/__init__.py +++ b/plugins/CuraDrive/__init__.py @@ -1,4 +1,6 @@ -# 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 is_testing = os.getenv('ENV_NAME', "development") == "testing" diff --git a/plugins/CuraDrive/plugin.json b/plugins/CuraDrive/plugin.json index 6cf1fa273c..d1cab39ca5 100644 --- a/plugins/CuraDrive/plugin.json +++ b/plugins/CuraDrive/plugin.json @@ -3,6 +3,6 @@ "author": "Ultimaker B.V.", "description": "Backup and restore your configuration.", "version": "1.2.0", - "api": 5, + "api": 6, "i18n-catalog": "cura" } diff --git a/plugins/CuraDrive/src/DriveApiService.py b/plugins/CuraDrive/src/DriveApiService.py index 98199c91cf..7c3e7b7026 100644 --- a/plugins/CuraDrive/src/DriveApiService.py +++ b/plugins/CuraDrive/src/DriveApiService.py @@ -1,4 +1,6 @@ -# Copyright (c) 2017 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + import base64 import hashlib from datetime import datetime diff --git a/plugins/CuraDrive/src/DrivePluginExtension.py b/plugins/CuraDrive/src/DrivePluginExtension.py index 7e1472b988..a76c623fe8 100644 --- a/plugins/CuraDrive/src/DrivePluginExtension.py +++ b/plugins/CuraDrive/src/DrivePluginExtension.py @@ -1,4 +1,6 @@ -# 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 from datetime import datetime from typing import Optional diff --git a/plugins/CuraDrive/src/Settings.py b/plugins/CuraDrive/src/Settings.py index 4ee73ad149..04ace8af95 100644 --- a/plugins/CuraDrive/src/Settings.py +++ b/plugins/CuraDrive/src/Settings.py @@ -1,4 +1,6 @@ # Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + from UM import i18nCatalog from cura import UltimakerCloudAuthentication diff --git a/plugins/CuraDrive/src/UploadBackupJob.py b/plugins/CuraDrive/src/UploadBackupJob.py index bcecce554a..ae6cb13f2e 100644 --- a/plugins/CuraDrive/src/UploadBackupJob.py +++ b/plugins/CuraDrive/src/UploadBackupJob.py @@ -1,4 +1,6 @@ # Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + import requests from UM.Job import Job diff --git a/plugins/CuraDrive/src/models/BackupListModel.py b/plugins/CuraDrive/src/models/BackupListModel.py index 93b0c4c48c..06b256b22c 100644 --- a/plugins/CuraDrive/src/models/BackupListModel.py +++ b/plugins/CuraDrive/src/models/BackupListModel.py @@ -1,4 +1,6 @@ # Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + from typing import Any, List, Dict from UM.Qt.ListModel import ListModel diff --git a/plugins/CuraDrive/src/qml/components/BackupList.qml b/plugins/CuraDrive/src/qml/components/BackupList.qml index a19d1f0ae7..af7e72b6e6 100644 --- a/plugins/CuraDrive/src/qml/components/BackupList.qml +++ b/plugins/CuraDrive/src/qml/components/BackupList.qml @@ -1,4 +1,6 @@ // Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + import QtQuick 2.7 import QtQuick.Controls 2.1 import QtQuick.Layouts 1.3 diff --git a/plugins/CuraDrive/src/qml/components/BackupListFooter.qml b/plugins/CuraDrive/src/qml/components/BackupListFooter.qml index 72dc3df044..2a6d82bc74 100644 --- a/plugins/CuraDrive/src/qml/components/BackupListFooter.qml +++ b/plugins/CuraDrive/src/qml/components/BackupListFooter.qml @@ -1,4 +1,6 @@ // Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + import QtQuick 2.7 import QtQuick.Controls 2.1 import QtQuick.Layouts 1.3 diff --git a/plugins/CuraDrive/src/qml/components/BackupListItem.qml b/plugins/CuraDrive/src/qml/components/BackupListItem.qml index a84caeb6ab..ba4f1a32a4 100644 --- a/plugins/CuraDrive/src/qml/components/BackupListItem.qml +++ b/plugins/CuraDrive/src/qml/components/BackupListItem.qml @@ -1,4 +1,6 @@ // Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + import QtQuick 2.7 import QtQuick.Controls 2.1 import QtQuick.Layouts 1.3 diff --git a/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml b/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml index 74d4c5ab57..38a2557c47 100644 --- a/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml +++ b/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml @@ -1,4 +1,6 @@ // Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + import QtQuick 2.7 import QtQuick.Controls 2.1 import QtQuick.Layouts 1.3 diff --git a/plugins/CuraDrive/src/qml/components/BackupListItemDetailsRow.qml b/plugins/CuraDrive/src/qml/components/BackupListItemDetailsRow.qml index dad1674fe7..d1c8dd33d2 100644 --- a/plugins/CuraDrive/src/qml/components/BackupListItemDetailsRow.qml +++ b/plugins/CuraDrive/src/qml/components/BackupListItemDetailsRow.qml @@ -1,4 +1,6 @@ // Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + import QtQuick 2.7 import QtQuick.Controls 2.1 import QtQuick.Layouts 1.3 diff --git a/plugins/CuraDrive/src/qml/components/Divider.qml b/plugins/CuraDrive/src/qml/components/Divider.qml index bba2f2f29c..202794fe23 100644 --- a/plugins/CuraDrive/src/qml/components/Divider.qml +++ b/plugins/CuraDrive/src/qml/components/Divider.qml @@ -1,4 +1,6 @@ // Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + import QtQuick 2.7 import UM 1.3 as UM diff --git a/plugins/CuraDrive/src/qml/components/Icon.qml b/plugins/CuraDrive/src/qml/components/Icon.qml index 3cb822bf82..8d559bc2b4 100644 --- a/plugins/CuraDrive/src/qml/components/Icon.qml +++ b/plugins/CuraDrive/src/qml/components/Icon.qml @@ -1,4 +1,6 @@ // Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + import QtQuick 2.7 import QtQuick.Controls 2.1 import QtGraphicalEffects 1.0 diff --git a/plugins/CuraDrive/src/qml/components/RightSideScrollBar.qml b/plugins/CuraDrive/src/qml/components/RightSideScrollBar.qml index 5ac5df15ff..5ef8558ee7 100644 --- a/plugins/CuraDrive/src/qml/components/RightSideScrollBar.qml +++ b/plugins/CuraDrive/src/qml/components/RightSideScrollBar.qml @@ -1,4 +1,6 @@ // Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + import QtQuick 2.7 import QtQuick.Controls 2.1 import QtQuick.Layouts 1.3 diff --git a/plugins/CuraDrive/src/qml/main.qml b/plugins/CuraDrive/src/qml/main.qml index 359f8dd725..e8a49a49e5 100644 --- a/plugins/CuraDrive/src/qml/main.qml +++ b/plugins/CuraDrive/src/qml/main.qml @@ -1,4 +1,6 @@ // Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + import QtQuick 2.7 import QtQuick.Controls 2.1 import QtQuick.Window 2.2 diff --git a/plugins/CuraDrive/src/qml/pages/BackupsPage.qml b/plugins/CuraDrive/src/qml/pages/BackupsPage.qml index 88ce766383..0a7b00d2cb 100644 --- a/plugins/CuraDrive/src/qml/pages/BackupsPage.qml +++ b/plugins/CuraDrive/src/qml/pages/BackupsPage.qml @@ -1,4 +1,6 @@ // Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + import QtQuick 2.7 import QtQuick.Controls 2.1 import QtQuick.Layouts 1.3 diff --git a/plugins/CuraDrive/src/qml/pages/WelcomePage.qml b/plugins/CuraDrive/src/qml/pages/WelcomePage.qml index b7f96d162a..19eecedf28 100644 --- a/plugins/CuraDrive/src/qml/pages/WelcomePage.qml +++ b/plugins/CuraDrive/src/qml/pages/WelcomePage.qml @@ -1,4 +1,6 @@ // Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + import QtQuick 2.7 import QtQuick.Controls 2.1 import QtQuick.Window 2.2 From c66257bf4d42c5649606de352cf41496bd7a90dd Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 18 Dec 2018 16:18:01 +0100 Subject: [PATCH 1029/1292] Use item instead of transparent rectangle This is faster to render. Contributes to issue CURA-6032. --- .../qml/Preferences/Materials/MaterialsBrandSection.qml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/resources/qml/Preferences/Materials/MaterialsBrandSection.qml b/resources/qml/Preferences/Materials/MaterialsBrandSection.qml index a3a0e4708f..c40693e343 100644 --- a/resources/qml/Preferences/Materials/MaterialsBrandSection.qml +++ b/resources/qml/Preferences/Materials/MaterialsBrandSection.qml @@ -1,5 +1,5 @@ // Copyright (c) 2018 Ultimaker B.V. -// Uranium is released under the terms of the LGPLv3 or higher. +// Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 import QtQuick.Controls 1.4 @@ -69,11 +69,7 @@ Rectangle } style: ButtonStyle { - background: Rectangle - { - anchors.fill: parent - color: "transparent" - } + background: Item { } } } } From 7cf1df74354022c5cceba84ae8ab304ad0d16b1e Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Tue, 18 Dec 2018 16:19:21 +0100 Subject: [PATCH 1030/1292] Remove back Cura.ExtrudersModel{}, because if retrieve the model from backend the tabs cannot be removed after model update. The QML bug CURA-6036 --- .../MachineSettingsAction.qml | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index 60dd31dcae..ef8fda224a 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -13,10 +13,22 @@ import Cura 1.0 as Cura Cura.MachineAction { id: base - property var extrudersModel: CuraApplication.getExtrudersModel() + property var extrudersModel: Cura.ExtrudersModel{} // Do not retrieve the Model from a backend. Otherwise the tabs + // in tabView will not removed/updated. Probably QML bug + property int extruderTabsCount: 0 property var activeMachineId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.id : "" + Connections + { + target: base.extrudersModel + onModelChanged: + { + var extruderCount = base.extrudersModel.count; + base.extruderTabsCount = extruderCount; + } + } + Connections { target: dialog ? dialog : null @@ -346,22 +358,11 @@ Cura.MachineAction Repeater { id: extruderTabsRepeater - model: base.extrudersModel - - - onItemAdded: - { - settingsTabs.addTab(index + 1, item) - } - - onItemRemoved: - { - settingsTabs.removeTab(index + 1) - } + model: base.extruderTabsCount Tab { - title: model.name + title: base.extrudersModel.getItem(index).name anchors.margins: UM.Theme.getSize("default_margin").width Column From 8206fde2237930de5347a711ae6539055952888f Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 18 Dec 2018 16:24:13 +0100 Subject: [PATCH 1031/1292] Remove the non-load-only-when-testing check Contributes to CURA-6005. --- plugins/CuraDrive/__init__.py | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/plugins/CuraDrive/__init__.py b/plugins/CuraDrive/__init__.py index 4103b0cf2e..766d94752f 100644 --- a/plugins/CuraDrive/__init__.py +++ b/plugins/CuraDrive/__init__.py @@ -1,16 +1,10 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -import os +from .src.DrivePluginExtension import DrivePluginExtension -is_testing = os.getenv('ENV_NAME', "development") == "testing" +def getMetaData(): + return {} -# Only load the whole plugin when not running tests as __init__.py is automatically loaded by PyTest -if not is_testing: - from .src.DrivePluginExtension import DrivePluginExtension - - def getMetaData(): - return {} - - def register(app): - return {"extension": DrivePluginExtension(app)} +def register(app): + return {"extension": DrivePluginExtension(app)} From 0588c54035441d536f6afce236563e957a5b5114 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 18 Dec 2018 16:29:13 +0100 Subject: [PATCH 1032/1292] Start work on cloud icon --- cura/PrinterOutputDevice.py | 7 ++++++- .../UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py | 4 +++- resources/qml/PrinterSelector/MachineSelector.qml | 7 ++++--- .../cura-light/icons/printer_cloud_connected.svg | 10 ++++++++++ 4 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 resources/themes/cura-light/icons/printer_cloud_connected.svg diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index d16242d9c2..44c564d03a 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -56,6 +56,7 @@ class PrinterOutputDevice(QObject, OutputDevice): # Put ConnectionType here with Q_ENUMS() so it can be registered as a QML type and accessible via QML, and there is # no need to remember what those Enum integer values mean. + ConnectionType = ConnectionType Q_ENUMS(ConnectionType) printersChanged = pyqtSignal() @@ -133,7 +134,11 @@ class PrinterOutputDevice(QObject, OutputDevice): def getConnectionType(self) -> "ConnectionType": return self._connection_type - @pyqtProperty(str, notify = connectionStateChanged) + @pyqtProperty(int, constant = True) + def connectionType(self) -> "ConnectionType": + return self._connection_type + + @pyqtProperty(int, notify = connectionStateChanged) def connectionState(self) -> "ConnectionState": return self._connection_state diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index fed8cb040a..7e9608dc8b 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -17,6 +17,7 @@ from UM.Scene.SceneNode import SceneNode from cura.CuraApplication import CuraApplication from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState, NetworkedPrinterOutputDevice from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel +from cura.PrinterOutputDevice import ConnectionType from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputController import CloudOutputController from ..MeshFormatHandler import MeshFormatHandler from ..UM3PrintJobOutputModel import UM3PrintJobOutputModel @@ -86,7 +87,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # \param cluster: The device response received from the cloud API. # \param parent: The optional parent of this output device. def __init__(self, api_client: CloudApiClient, cluster: CloudClusterResponse, parent: QObject = None) -> None: - super().__init__(device_id = cluster.cluster_id, address = "", properties = {}, parent = parent) + super().__init__(device_id = cluster.cluster_id, address = "", + connection_type = ConnectionType.CloudConnection, properties = {}, parent = parent) self._api = api_client self._cluster = cluster diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index 28e01c7ae9..3804c04025 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -11,9 +11,10 @@ Cura.ExpandablePopup { id: machineSelector - property bool isNetworkPrinter: Cura.MachineManager.activeMachineHasRemoteConnection - property bool isPrinterConnected: Cura.MachineManager.printerConnected property var outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null + property bool isNetworkPrinter: Cura.MachineManager.activeMachineHasRemoteConnection + property bool isCloudPrinter: machineSelector.outputDevice.connectionType == Cura.PrinterOutputDevice.CloudConnection + property bool isPrinterConnected: Cura.MachineManager.printerConnected contentPadding: UM.Theme.getSize("default_lining").width contentAlignment: Cura.ExpandablePopup.ContentAlignment.AlignLeft @@ -52,7 +53,7 @@ Cura.ExpandablePopup leftMargin: UM.Theme.getSize("thick_margin").width } - source: UM.Theme.getIcon("printer_connected") + source: machineSelector.isCloudPrinter ? UM.Theme.getIcon("printer_connected") : UM.Theme.getIcon("printer_connected") width: UM.Theme.getSize("printer_status_icon").width height: UM.Theme.getSize("printer_status_icon").height diff --git a/resources/themes/cura-light/icons/printer_cloud_connected.svg b/resources/themes/cura-light/icons/printer_cloud_connected.svg new file mode 100644 index 0000000000..6b2c814786 --- /dev/null +++ b/resources/themes/cura-light/icons/printer_cloud_connected.svg @@ -0,0 +1,10 @@ + + + + Artboard Copy 2 + Created with Sketch. + + + + + \ No newline at end of file From 4bf24671a21d3b17ed55548200198180eb71e52c Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 18 Dec 2018 16:33:39 +0100 Subject: [PATCH 1033/1292] Use the (not final) cloud icon when cloud connected --- resources/qml/PrinterSelector/MachineSelector.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index 3804c04025..13ebae4ac5 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -53,7 +53,7 @@ Cura.ExpandablePopup leftMargin: UM.Theme.getSize("thick_margin").width } - source: machineSelector.isCloudPrinter ? UM.Theme.getIcon("printer_connected") : UM.Theme.getIcon("printer_connected") + source: machineSelector.isCloudPrinter ? UM.Theme.getIcon("printer_cloud_connected") : UM.Theme.getIcon("printer_connected") width: UM.Theme.getSize("printer_status_icon").width height: UM.Theme.getSize("printer_status_icon").height From c0c45519a06847d49a745dd2d23537350b937710 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 18 Dec 2018 16:49:41 +0100 Subject: [PATCH 1034/1292] Change another useless rectangle into an item It's more efficient to render. Also changed some code style. Contributes to issue CURA-6032. --- .../qml/Preferences/Materials/MaterialsSlot.qml | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/resources/qml/Preferences/Materials/MaterialsSlot.qml b/resources/qml/Preferences/Materials/MaterialsSlot.qml index a706aaf2b9..fb3cb9607d 100644 --- a/resources/qml/Preferences/Materials/MaterialsSlot.qml +++ b/resources/qml/Preferences/Materials/MaterialsSlot.qml @@ -1,5 +1,5 @@ // Copyright (c) 2018 Ultimaker B.V. -// Uranium is released under the terms of the LGPLv3 or higher. +// Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 import QtQuick.Controls 1.4 @@ -70,7 +70,8 @@ Rectangle } onClicked: { - if (materialSlot.is_favorite) { + if (materialSlot.is_favorite) + { base.materialManager.removeFavorite(material.root_material_id) materialSlot.is_favorite = false return @@ -81,13 +82,10 @@ Rectangle } style: ButtonStyle { - background: Rectangle - { - anchors.fill: parent - color: "transparent" - } + background: Item { } } - UM.RecolorImage { + UM.RecolorImage + { anchors { verticalCenter: favorite_button.verticalCenter From 6600cea632c9e3cdb925407ff4c7eecf745b40e3 Mon Sep 17 00:00:00 2001 From: susisstrolch Date: Tue, 18 Dec 2018 16:51:16 +0100 Subject: [PATCH 1035/1292] Add missing baudrate to USB connection. Extend the baudrate list by 500.000bd to also detect Vertex Delta 3D (K8800). Fixes #4952 --- plugins/USBPrinting/AutoDetectBaudJob.py | 2 +- plugins/USBPrinting/USBPrinterOutputDevice.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/USBPrinting/AutoDetectBaudJob.py b/plugins/USBPrinting/AutoDetectBaudJob.py index 78de864e57..2fa0af1795 100644 --- a/plugins/USBPrinting/AutoDetectBaudJob.py +++ b/plugins/USBPrinting/AutoDetectBaudJob.py @@ -18,7 +18,7 @@ class AutoDetectBaudJob(Job): def __init__(self, serial_port: int) -> None: super().__init__() self._serial_port = serial_port - self._all_baud_rates = [115200, 250000, 230400, 57600, 38400, 19200, 9600] + self._all_baud_rates = [115200, 250000, 500000, 230400, 57600, 38400, 19200, 9600] def run(self) -> None: Logger.log("d", "Auto detect baud rate started.") diff --git a/plugins/USBPrinting/USBPrinterOutputDevice.py b/plugins/USBPrinting/USBPrinterOutputDevice.py index 19a703e605..89903b06f4 100644 --- a/plugins/USBPrinting/USBPrinterOutputDevice.py +++ b/plugins/USBPrinting/USBPrinterOutputDevice.py @@ -49,7 +49,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice): self._baud_rate = baud_rate - self._all_baud_rates = [115200, 250000, 230400, 57600, 38400, 19200, 9600] + self._all_baud_rates = [115200, 250000, 500000, 230400, 57600, 38400, 19200, 9600] # Instead of using a timer, we really need the update to be as a thread, as reading from serial can block. self._update_thread = Thread(target = self._update, daemon = True) From 66ed9ed201dd3873c98fda46508243e4902a41ce Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 18 Dec 2018 16:52:04 +0100 Subject: [PATCH 1036/1292] Remove optimisation that broke updates of models upon metadata change If the metadata changed, such as whether a material was favourite or not, then the materials models were not updating any more because the actual list of available materials was still the same. I've removed this optimisation and tested performance locally. It seems to be slightly slower (though that might be placebo or measurement error). However most of the performance boost of cura-6016 was resulting from different changes there so the interface still seems to be quite a lot faster than what it used to be. Contributes to issue CURA-6032. --- cura/Machines/Models/BaseMaterialsModel.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/cura/Machines/Models/BaseMaterialsModel.py b/cura/Machines/Models/BaseMaterialsModel.py index 629e5c2b48..212e4fcf1e 100644 --- a/cura/Machines/Models/BaseMaterialsModel.py +++ b/cura/Machines/Models/BaseMaterialsModel.py @@ -106,10 +106,7 @@ class BaseMaterialsModel(ListModel): return False extruder_stack = global_stack.extruders[extruder_position] - available_materials = self._material_manager.getAvailableMaterialsForMachineExtruder(global_stack, extruder_stack) - if available_materials == self._available_materials: - return False - self._available_materials = available_materials + self._available_materials = self._material_manager.getAvailableMaterialsForMachineExtruder(global_stack, extruder_stack) if self._available_materials is None: return False From 6987d5ff782c53253c1b85b9f280ee4b9b328b59 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 19 Dec 2018 09:33:46 +0100 Subject: [PATCH 1037/1292] Add a radius to the printer type label --- resources/qml/PrinterTypeLabel.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/qml/PrinterTypeLabel.qml b/resources/qml/PrinterTypeLabel.qml index 7feae32e16..cfc9e56513 100644 --- a/resources/qml/PrinterTypeLabel.qml +++ b/resources/qml/PrinterTypeLabel.qml @@ -19,6 +19,7 @@ Item { anchors.fill: parent color: UM.Theme.getColor("printer_type_label_background") + radius: UM.Theme.getSize("checkbox_radius").width } Label From 382286509f6cc5b1af6093b7e3b003965e955958 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 19 Dec 2018 09:49:12 +0100 Subject: [PATCH 1038/1292] Change the buildplate information to use a reusable component Boy scouting. Contributes to CURA-6025. --- .../ConfigurationMenu/ConfigurationItem.qml | 22 +++++-------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 728a0cbe9a..7e1b7e5af7 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -90,25 +90,13 @@ Button height: childrenRect.height visible: configuration.buildplateConfiguration != "" - UM.RecolorImage - { - id: buildplateIcon - anchors.left: parent.left - width: UM.Theme.getSize("main_window_header_button_icon").width - height: UM.Theme.getSize("main_window_header_button_icon").height - source: UM.Theme.getIcon("buildplate") - color: UM.Theme.getColor("text") - } - - Label + // Show the type of buildplate. The first letter is capitalized + Cura.IconWithText { id: buildplateLabel - anchors.left: buildplateIcon.right - anchors.verticalCenter: buildplateIcon.verticalCenter - anchors.leftMargin: Math.round(UM.Theme.getSize("default_margin").height / 2) - text: configuration.buildplateConfiguration - renderType: Text.NativeRendering - color: UM.Theme.getColor("text") + source: UM.Theme.getIcon("buildplate") + text: configuration.buildplateConfiguration.charAt(0).toUpperCase() + configuration.buildplateConfiguration.substr(1) + anchors.left: parent.left } } } From f1c28498a67aa73f93ada591bfdcb01c7ec14e59 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 19 Dec 2018 11:00:00 +0100 Subject: [PATCH 1039/1292] Display 0 if there are no measurements for minimum values Don't display max float then. --- plugins/SimulationView/SimulationView.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/SimulationView/SimulationView.py b/plugins/SimulationView/SimulationView.py index 6a0ffc1666..ae01b7cdb0 100644 --- a/plugins/SimulationView/SimulationView.py +++ b/plugins/SimulationView/SimulationView.py @@ -342,12 +342,16 @@ class SimulationView(CuraView): return self._extruder_count def getMinFeedrate(self) -> float: + if abs(self._min_feedrate - sys.float_info.max) < 10: # Some lenience due to floating point rounding. + return 0.0 # If it's still max-float, there are no measurements. Use 0 then. return self._min_feedrate def getMaxFeedrate(self) -> float: return self._max_feedrate def getMinThickness(self) -> float: + if abs(self._min_thickness - sys.float_info.max) < 10: # Some lenience due to floating point rounding. + return 0.0 # If it's still max-float, there are no measurements. Use 0 then. return self._min_thickness def getMaxThickness(self) -> float: From 5e9fe3fe500f7dca38139672fb58cdb6a28014d2 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Wed, 19 Dec 2018 11:21:50 +0100 Subject: [PATCH 1040/1292] Fix some codestyle, make connectionType a property as it's needed in QML --- cura/PrinterOutputDevice.py | 31 +++++++++---------- .../src/DiscoverUM3Action.py | 6 ++-- .../src/UM3OutputDevicePlugin.py | 2 +- 3 files changed, 18 insertions(+), 21 deletions(-) diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index 44c564d03a..54fbf3a7f2 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -81,28 +81,28 @@ class PrinterOutputDevice(QObject, OutputDevice): self._printers = [] # type: List[PrinterOutputModel] self._unique_configurations = [] # type: List[ConfigurationModel] - self._monitor_view_qml_path = "" #type: str - self._monitor_component = None #type: Optional[QObject] - self._monitor_item = None #type: Optional[QObject] + self._monitor_view_qml_path = "" # type: str + self._monitor_component = None # type: Optional[QObject] + self._monitor_item = None # type: Optional[QObject] - self._control_view_qml_path = "" #type: str - self._control_component = None #type: Optional[QObject] - self._control_item = None #type: Optional[QObject] + self._control_view_qml_path = "" # type: str + self._control_component = None # type: Optional[QObject] + self._control_item = None # type: Optional[QObject] - self._accepts_commands = False #type: bool + self._accepts_commands = False # type: bool - self._update_timer = QTimer() #type: QTimer + self._update_timer = QTimer() # type: QTimer self._update_timer.setInterval(2000) # TODO; Add preference for update interval self._update_timer.setSingleShot(False) self._update_timer.timeout.connect(self._update) - self._connection_state = ConnectionState.Closed #type: ConnectionState - self._connection_type = connection_type + self._connection_state = ConnectionState.Closed # type: ConnectionState + self._connection_type = connection_type # type: ConnectionType - self._firmware_updater = None #type: Optional[FirmwareUpdater] - self._firmware_name = None #type: Optional[str] - self._address = "" #type: str - self._connection_text = "" #type: str + self._firmware_updater = None # type: Optional[FirmwareUpdater] + self._firmware_name = None # type: Optional[str] + self._address = "" # type: str + self._connection_text = "" # type: str self.printersChanged.connect(self._onPrintersChanged) QtApplication.getInstance().getOutputDeviceManager().outputDevicesChanged.connect(self._updateUniqueConfigurations) @@ -131,9 +131,6 @@ class PrinterOutputDevice(QObject, OutputDevice): self._connection_state = connection_state self.connectionStateChanged.emit(self._id) - def getConnectionType(self) -> "ConnectionType": - return self._connection_type - @pyqtProperty(int, constant = True) def connectionType(self) -> "ConnectionType": return self._connection_type diff --git a/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py b/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py index 6ce99e4891..6b016c4f42 100644 --- a/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py +++ b/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py @@ -138,11 +138,11 @@ class DiscoverUM3Action(MachineAction): if "connection_type" in meta_data: previous_connection_type = meta_data["connection_type"] - global_container_stack.setMetaDataEntry("connection_type", printer_device.getConnectionType().value) - CuraApplication.getInstance().getMachineManager().replaceContainersMetadata(key = "connection_type", value = previous_connection_type, new_value = printer_device.getConnectionType().value) + global_container_stack.setMetaDataEntry("connection_type", printer_device.connectionType.value) + CuraApplication.getInstance().getMachineManager().replaceContainersMetadata(key = "connection_type", value = previous_connection_type, new_value = printer_device.connectionType.value) else: global_container_stack.setMetaDataEntry("um_network_key", printer_device.key) - global_container_stack.setMetaDataEntry("connection_type", printer_device.getConnectionType().value) + global_container_stack.setMetaDataEntry("connection_type", printer_device.connectionType.value) if self._network_plugin: # Ensure that the connection states are refreshed. diff --git a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py index 4642811f39..e7e6b35978 100644 --- a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py +++ b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py @@ -288,7 +288,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): global_container_stack = Application.getInstance().getGlobalContainerStack() if global_container_stack and device.getId() == global_container_stack.getMetaDataEntry("um_network_key"): - global_container_stack.setMetaDataEntry("connection_type", device.getConnectionType().value) + global_container_stack.setMetaDataEntry("connection_type", device.connectionType.value) device.connect() device.connectionStateChanged.connect(self._onDeviceConnectionStateChanged) From 142ac56d78e2bcb91eff8fffb0341be736d3461f Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Wed, 19 Dec 2018 11:26:38 +0100 Subject: [PATCH 1041/1292] Add keyboard navigation for printer carousel --- .../UM3NetworkPrinting/resources/qml/MonitorCarousel.qml | 4 ++++ .../UM3NetworkPrinting/resources/qml/MonitorStage.qml | 9 ++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml index a3e2517b45..eccd93c578 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml @@ -18,6 +18,10 @@ Item height: centerSection.height width: maximumWidth + + // Enable keyboard navigation + Keys.onLeftPressed: navigateTo(currentIndex - 1) + Keys.onRightPressed: navigateTo(currentIndex + 1) Item { diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml index b80c6a3661..8b1a11cb4d 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml @@ -24,6 +24,11 @@ Component } } width: maximumWidth + + // Enable keyboard navigation. NOTE: This is done here so that we can also potentially + // forward to the queue items in the future. (Deleting selected print job, etc.) + Keys.forwardTo: carousel + Component.onCompleted: forceActiveFocus() UM.I18nCatalog { @@ -59,7 +64,9 @@ Component } width: parent.width height: 264 * screenScaleFactor // TODO: Theme! - MonitorCarousel {} + MonitorCarousel { + id: carousel + } } MonitorQueue From 1b356a321958437c2781a475800ee9bb12f67c44 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Wed, 19 Dec 2018 11:41:22 +0100 Subject: [PATCH 1042/1292] Move cloud connection check logic to Python --- cura/Settings/MachineManager.py | 9 +++++++++ resources/qml/PrinterSelector/MachineSelector.qml | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index cd8ca09447..669a5a7cf7 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -530,6 +530,15 @@ class MachineManager(QObject): return connection_type in [ConnectionType.NetworkConnection.value, ConnectionType.CloudConnection.value] return False + @pyqtProperty(bool, notify = printerConnectedStatusChanged) + def activeMachineHasCloudConnection(self) -> bool: + if not self.activeMachineHasRemoteConnection: + return False + output_device = next(iter(self.printerOutputDevices), None) # type: PrinterOutputDevice + if not output_device: + return False + return output_device.connectionType == ConnectionType.CloudConnection + def activeMachineNetworkKey(self) -> str: if self._global_container_stack: return self._global_container_stack.getMetaDataEntry("um_network_key", "") diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index 13ebae4ac5..bb8934f620 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -13,7 +13,7 @@ Cura.ExpandablePopup property var outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null property bool isNetworkPrinter: Cura.MachineManager.activeMachineHasRemoteConnection - property bool isCloudPrinter: machineSelector.outputDevice.connectionType == Cura.PrinterOutputDevice.CloudConnection + property bool isCloudPrinter: Cura.MachineManager.activeMachineHasCloudConnection property bool isPrinterConnected: Cura.MachineManager.printerConnected contentPadding: UM.Theme.getSize("default_lining").width From eb1bde05166a64ac860e4c07ca056448826bab82 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Wed, 19 Dec 2018 11:42:17 +0100 Subject: [PATCH 1043/1292] Remove Q_ENUMS for connection type, not used in QML anymore --- cura/PrinterOutputDevice.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index 54fbf3a7f2..2d95b21c8a 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -54,11 +54,6 @@ class ConnectionType(IntEnum): @signalemitter class PrinterOutputDevice(QObject, OutputDevice): - # Put ConnectionType here with Q_ENUMS() so it can be registered as a QML type and accessible via QML, and there is - # no need to remember what those Enum integer values mean. - ConnectionType = ConnectionType - Q_ENUMS(ConnectionType) - printersChanged = pyqtSignal() connectionStateChanged = pyqtSignal(str) acceptsCommandsChanged = pyqtSignal() From 112950f00319b69c09f0d532b4edc556178ee212 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Wed, 19 Dec 2018 11:45:36 +0100 Subject: [PATCH 1044/1292] Remove unused import --- cura/PrinterOutputDevice.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index 2d95b21c8a..723a255133 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -1,10 +1,12 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +from enum import IntEnum +from typing import Callable, List, Optional, Union from UM.Decorators import deprecated from UM.i18n import i18nCatalog from UM.OutputDevice.OutputDevice import OutputDevice -from PyQt5.QtCore import pyqtProperty, pyqtSignal, QObject, QTimer, QUrl, Q_ENUMS +from PyQt5.QtCore import pyqtProperty, pyqtSignal, QObject, QTimer, QUrl from PyQt5.QtWidgets import QMessageBox from UM.Logger import Logger @@ -12,9 +14,6 @@ from UM.Signal import signalemitter from UM.Qt.QtApplication import QtApplication from UM.FlameProfiler import pyqtSlot -from enum import IntEnum # For the connection state tracking. -from typing import Callable, List, Optional, Union - MYPY = False if MYPY: from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel From 80d2a784634f74039594fdf17be92ee7263f6e2b Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Wed, 19 Dec 2018 11:47:41 +0100 Subject: [PATCH 1045/1292] Fix optional type for output device --- cura/Settings/MachineManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 669a5a7cf7..f47724372f 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -534,7 +534,7 @@ class MachineManager(QObject): def activeMachineHasCloudConnection(self) -> bool: if not self.activeMachineHasRemoteConnection: return False - output_device = next(iter(self.printerOutputDevices), None) # type: PrinterOutputDevice + output_device = next(iter(self.printerOutputDevices), None) # type: Optional[PrinterOutputDevice] if not output_device: return False return output_device.connectionType == ConnectionType.CloudConnection From 56d0a52faccb3cc0cd5ecd8701b342a530395ed3 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 19 Dec 2018 11:51:46 +0100 Subject: [PATCH 1046/1292] Documentation and code style --- plugins/SimulationView/SimulationViewMenuComponent.qml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/plugins/SimulationView/SimulationViewMenuComponent.qml b/plugins/SimulationView/SimulationViewMenuComponent.qml index eec254c0dd..fe32fe9eb1 100644 --- a/plugins/SimulationView/SimulationViewMenuComponent.qml +++ b/plugins/SimulationView/SimulationViewMenuComponent.qml @@ -358,7 +358,7 @@ Cura.ExpandableComponent width: parent.width height: UM.Theme.getSize("layerview_row").height - Label + Label //Minimum value. { text: { @@ -383,9 +383,10 @@ Cura.ExpandableComponent renderType: Text.NativeRendering } - Label + Label //Unit in the middle. { - text: { + text: + { if (UM.SimulationView.layerActivity && CuraApplication.platformActivity) { // Feedrate selected @@ -407,7 +408,7 @@ Cura.ExpandableComponent font: UM.Theme.getFont("default") } - Label + Label //Maximum value. { text: { if (UM.SimulationView.layerActivity && CuraApplication.platformActivity) From d2746d03c1a5786b0d1fef1d41d2abfff79939c7 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Wed, 19 Dec 2018 11:56:43 +0100 Subject: [PATCH 1047/1292] Fix type checking for DiscoverUM3Action --- .../src/DiscoverUM3Action.py | 40 +++++++++++-------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py b/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py index 6b016c4f42..c02c18e942 100644 --- a/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py +++ b/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py @@ -124,25 +124,31 @@ class DiscoverUM3Action(MachineAction): @pyqtSlot(QObject) def associateActiveMachineWithPrinterDevice(self, printer_device: Optional["PrinterOutputDevice"]) -> None: Logger.log("d", "Attempting to set the network key of the active machine to %s", printer_device.key) - global_container_stack = CuraApplication.getInstance().getGlobalContainerStack() - if global_container_stack: - meta_data = global_container_stack.getMetaData() - if "um_network_key" in meta_data: - previous_network_key= meta_data["um_network_key"] - global_container_stack.setMetaDataEntry("um_network_key", printer_device.key) - # Delete old authentication data. - Logger.log("d", "Removing old authentication id %s for device %s", global_container_stack.getMetaDataEntry("network_authentication_id", None), printer_device.key) - global_container_stack.removeMetaDataEntry("network_authentication_id") - global_container_stack.removeMetaDataEntry("network_authentication_key") - CuraApplication.getInstance().getMachineManager().replaceContainersMetadata(key = "um_network_key", value = previous_network_key, new_value = printer_device.key) + if not printer_device: + return - if "connection_type" in meta_data: - previous_connection_type = meta_data["connection_type"] - global_container_stack.setMetaDataEntry("connection_type", printer_device.connectionType.value) - CuraApplication.getInstance().getMachineManager().replaceContainersMetadata(key = "connection_type", value = previous_connection_type, new_value = printer_device.connectionType.value) - else: - global_container_stack.setMetaDataEntry("um_network_key", printer_device.key) + global_container_stack = CuraApplication.getInstance().getGlobalContainerStack() + if not global_container_stack: + return + + meta_data = global_container_stack.getMetaData() + if "um_network_key" in meta_data: + previous_network_key = meta_data["um_network_key"] + global_container_stack.setMetaDataEntry("um_network_key", printer_device.key) + # Delete old authentication data. + Logger.log("d", "Removing old authentication id %s for device %s", + global_container_stack.getMetaDataEntry("network_authentication_id", None), printer_device.key) + global_container_stack.removeMetaDataEntry("network_authentication_id") + global_container_stack.removeMetaDataEntry("network_authentication_key") + CuraApplication.getInstance().getMachineManager().replaceContainersMetadata(key = "um_network_key", value = previous_network_key, new_value = printer_device.key) + + if "connection_type" in meta_data: + previous_connection_type = meta_data["connection_type"] global_container_stack.setMetaDataEntry("connection_type", printer_device.connectionType.value) + CuraApplication.getInstance().getMachineManager().replaceContainersMetadata(key = "connection_type", value = previous_connection_type, new_value = printer_device.connectionType.value) + else: + global_container_stack.setMetaDataEntry("um_network_key", printer_device.key) + global_container_stack.setMetaDataEntry("connection_type", printer_device.connectionType.value) if self._network_plugin: # Ensure that the connection states are refreshed. From c4a8545c45717547449c0c03c39c3cd25acb9bc2 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Wed, 19 Dec 2018 12:05:07 +0100 Subject: [PATCH 1048/1292] Add final cloud connected icon to printer selector --- .../themes/cura-light/icons/printer_cloud_connected.svg | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/resources/themes/cura-light/icons/printer_cloud_connected.svg b/resources/themes/cura-light/icons/printer_cloud_connected.svg index 6b2c814786..3bc94a05e7 100644 --- a/resources/themes/cura-light/icons/printer_cloud_connected.svg +++ b/resources/themes/cura-light/icons/printer_cloud_connected.svg @@ -1,10 +1,11 @@ - + Artboard Copy 2 Created with Sketch. - - + + + \ No newline at end of file From cf06cb5351f7ec3c08ac1bd811334822406bfb1a Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Wed, 19 Dec 2018 12:10:24 +0100 Subject: [PATCH 1049/1292] Do not call printer_device.key before checking if it exists --- plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py b/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py index c02c18e942..c88848317a 100644 --- a/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py +++ b/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py @@ -123,10 +123,11 @@ class DiscoverUM3Action(MachineAction): # stored into the metadata of the currently active machine. @pyqtSlot(QObject) def associateActiveMachineWithPrinterDevice(self, printer_device: Optional["PrinterOutputDevice"]) -> None: - Logger.log("d", "Attempting to set the network key of the active machine to %s", printer_device.key) if not printer_device: return + Logger.log("d", "Attempting to set the network key of the active machine to %s", printer_device.key) + global_container_stack = CuraApplication.getInstance().getGlobalContainerStack() if not global_container_stack: return From acabd06542ea4907d503055bba6174c19a5ab89e Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 19 Dec 2018 12:32:18 +0100 Subject: [PATCH 1050/1292] Change the large_nonbold to large in one remaining component Contributes to CURA-6025. --- plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml index 884dbabc2f..f2a0e785b8 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml @@ -23,7 +23,7 @@ Item top: parent.top } color: UM.Theme.getColor("text") - font: UM.Theme.getFont("large_nonbold") + font: UM.Theme.getFont("large") text: catalog.i18nc("@label", "Queued") } From 773190bee18dd7e18fefacfe2aca0104a0762897 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 19 Dec 2018 12:53:41 +0100 Subject: [PATCH 1051/1292] Fix code style Add space between binary operator. Contributes to CURA-6005. --- plugins/CuraDrive/src/DriveApiService.py | 30 ++++++++++++------------ 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/plugins/CuraDrive/src/DriveApiService.py b/plugins/CuraDrive/src/DriveApiService.py index 7c3e7b7026..a542ac439e 100644 --- a/plugins/CuraDrive/src/DriveApiService.py +++ b/plugins/CuraDrive/src/DriveApiService.py @@ -43,7 +43,7 @@ class DriveApiService: Logger.log("w", "Could not get access token.") return [] - backup_list_request = requests.get(self.GET_BACKUPS_URL, headers={ + backup_list_request = requests.get(self.GET_BACKUPS_URL, headers = { "Authorization": "Bearer {}".format(access_token) }) if backup_list_request.status_code > 299: @@ -55,12 +55,12 @@ class DriveApiService: def createBackup(self) -> None: """Create a backup and upload it to CuraDrive cloud storage.""" - self.onCreatingStateChanged.emit(is_creating=True) + self.onCreatingStateChanged.emit(is_creating = True) # Create the backup. backup_zip_file, backup_meta_data = self._cura_api.backups.createBackup() if not backup_zip_file or not backup_meta_data: - self.onCreatingStateChanged.emit(is_creating=False, error_message="Could not create backup.") + self.onCreatingStateChanged.emit(is_creating = False, error_message = "Could not create backup.") return # Create an upload entry for the backup. @@ -68,7 +68,7 @@ class DriveApiService: backup_meta_data["description"] = "{}.backup.{}.cura.zip".format(timestamp, backup_meta_data["cura_release"]) backup_upload_url = self._requestBackupUpload(backup_meta_data, len(backup_zip_file)) if not backup_upload_url: - self.onCreatingStateChanged.emit(is_creating=False, error_message="Could not upload backup.") + self.onCreatingStateChanged.emit(is_creating = False, error_message = "Could not upload backup.") return # Upload the backup to storage. @@ -83,29 +83,29 @@ class DriveApiService: """ if job.backup_upload_error_message != "": # If the job contains an error message we pass it along so the UI can display it. - self.onCreatingStateChanged.emit(is_creating=False, error_message=job.backup_upload_error_message) + self.onCreatingStateChanged.emit(is_creating = False, error_message = job.backup_upload_error_message) else: - self.onCreatingStateChanged.emit(is_creating=False) + self.onCreatingStateChanged.emit(is_creating = False) def restoreBackup(self, backup: Dict[str, Any]) -> None: """ Restore a previously exported backup from cloud storage. :param backup: A dict containing an entry from the API list response. """ - self.onRestoringStateChanged.emit(is_restoring=True) + self.onRestoringStateChanged.emit(is_restoring = True) download_url = backup.get("download_url") if not download_url: # If there is no download URL, we can't restore the backup. return self._emitRestoreError() - download_package = requests.get(download_url, stream=True) + download_package = requests.get(download_url, stream = True) if download_package.status_code != 200: # Something went wrong when attempting to download the backup. Logger.log("w", "Could not download backup from url %s: %s", download_url, download_package.text) return self._emitRestoreError() # We store the file in a temporary path fist to ensure integrity. - temporary_backup_file = NamedTemporaryFile(delete=False) + temporary_backup_file = NamedTemporaryFile(delete = False) with open(temporary_backup_file.name, "wb") as write_backup: for chunk in download_package: write_backup.write(chunk) @@ -119,13 +119,13 @@ class DriveApiService: # Tell Cura to place the backup back in the user data folder. with open(temporary_backup_file.name, "rb") as read_backup: self._cura_api.backups.restoreBackup(read_backup.read(), backup.get("data")) - self.onRestoringStateChanged.emit(is_restoring=False) + self.onRestoringStateChanged.emit(is_restoring = False) def _emitRestoreError(self, error_message: str = Settings.translatable_messages["backup_restore_error_message"]): """Helper method for emitting a signal when restoring failed.""" self.onRestoringStateChanged.emit( - is_restoring=False, - error_message=error_message + is_restoring = False, + error_message = error_message ) @staticmethod @@ -137,7 +137,7 @@ class DriveApiService: :return: Success or not. """ with open(file_path, "rb") as read_backup: - local_md5_hash = base64.b64encode(hashlib.md5(read_backup.read()).digest(), altchars=b"_-").decode("utf-8") + local_md5_hash = base64.b64encode(hashlib.md5(read_backup.read()).digest(), altchars = b"_-").decode("utf-8") return known_hash == local_md5_hash def deleteBackup(self, backup_id: str) -> bool: @@ -171,12 +171,12 @@ class DriveApiService: Logger.log("w", "Could not get access token.") return None - backup_upload_request = requests.put(self.PUT_BACKUP_URL, json={ + backup_upload_request = requests.put(self.PUT_BACKUP_URL, json = { "data": { "backup_size": backup_size, "metadata": backup_metadata } - }, headers={ + }, headers = { "Authorization": "Bearer {}".format(access_token) }) From e62ce0e4ca3f7af27282e246cc103c5804f1047c Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Wed, 19 Dec 2018 13:18:53 +0100 Subject: [PATCH 1052/1292] Make printer carousel more flexible/robust Contributes to CL-1157 --- .../resources/qml/MonitorCarousel.qml | 15 ++++++++++----- .../resources/qml/MonitorStage.qml | 4 +++- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml index eccd93c578..7c0d9b95b6 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml @@ -14,7 +14,12 @@ Item property var tileWidth: 834 * screenScaleFactor // TODO: Theme! property var tileHeight: 216 * screenScaleFactor // TODO: Theme! property var tileSpacing: 60 * screenScaleFactor // TODO: Theme! - property var maxOffset: (OutputDevice.printers.length - 1) * (tileWidth + tileSpacing) + + // Array/model of printers to populate the carousel with + property var printers: [] + + // Maximum distance the carousel can be shifted + property var maxOffset: (printers.length - 1) * (tileWidth + tileSpacing) height: centerSection.height width: maximumWidth @@ -129,7 +134,7 @@ Item Repeater { - model: OutputDevice.printers + model: printers MonitorPrinterCard { printer: modelData @@ -151,7 +156,7 @@ Item width: 36 * screenScaleFactor // TODO: Theme! height: 72 * screenScaleFactor // TODO: Theme! z: 10 - visible: currentIndex < OutputDevice.printers.length - 1 + visible: currentIndex < printers.length - 1 onClicked: navigateTo(currentIndex + 1) hoverEnabled: true background: Rectangle @@ -227,7 +232,7 @@ Item spacing: 8 * screenScaleFactor // TODO: Theme! Repeater { - model: OutputDevice.printers + model: printers Button { background: Rectangle @@ -243,7 +248,7 @@ Item } function navigateTo( i ) { - if (i >= 0 && i < OutputDevice.printers.length) + if (i >= 0 && i < printers.length) { tiles.x = -1 * i * (tileWidth + tileSpacing) currentIndex = i diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml index 8b1a11cb4d..d20c2247b4 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml @@ -64,8 +64,10 @@ Component } width: parent.width height: 264 * screenScaleFactor // TODO: Theme! - MonitorCarousel { + MonitorCarousel + { id: carousel + printers: OutputDevice.printers } } From 9acaf9abd772643de75a51d4a8c47878c8ee2079 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 19 Dec 2018 13:30:25 +0100 Subject: [PATCH 1053/1292] Disable dropping of files into cura when monitor stage is active. CURA-6038 --- plugins/MonitorStage/MonitorMain.qml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plugins/MonitorStage/MonitorMain.qml b/plugins/MonitorStage/MonitorMain.qml index 8f113735ee..34cf4ad801 100644 --- a/plugins/MonitorStage/MonitorMain.qml +++ b/plugins/MonitorStage/MonitorMain.qml @@ -16,12 +16,20 @@ Item color: UM.Theme.getColor("viewport_overlay") anchors.fill: parent + + // This mouse area is to prevent mouse clicks to be passed onto the scene. MouseArea { anchors.fill: parent acceptedButtons: Qt.AllButtons onWheel: wheel.accepted = true } + + // Disable dropping files into Cura when the monitor page is active + DropArea + { + anchors.fill: parent + } } Loader From 9e867f8077e95bec3fe15567983813433e42e5ef Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 19 Dec 2018 13:53:34 +0100 Subject: [PATCH 1054/1292] Fix the codestyle and cleanup the QML a bit CURA-6043 --- .../PostProcessingPlugin.qml | 103 +++++++++++------- 1 file changed, 63 insertions(+), 40 deletions(-) diff --git a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml index b962f4d53b..5862259be5 100644 --- a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml +++ b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml @@ -25,7 +25,7 @@ UM.Dialog { if(!visible) //Whenever the window is closed (either via the "Close" button or the X on the window frame), we want to update it in the stack. { - manager.writeScriptsToStack(); + manager.writeScriptsToStack() } } @@ -67,12 +67,17 @@ UM.Dialog ListView { id: activeScriptsList - anchors.top: activeScriptsHeader.bottom - anchors.topMargin: base.textMargin - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("default_margin").width - anchors.right: parent.right - anchors.rightMargin: base.textMargin + + anchors + { + top: activeScriptsHeader.bottom + left: parent.left + right: parent.right + rightMargin: base.textMargin + topMargin: base.textMargin + leftMargin: UM.Theme.getSize("default_margin").width + } + height: childrenRect.height model: manager.scriptList delegate: Item @@ -84,8 +89,12 @@ UM.Dialog id: activeScriptButton text: manager.getScriptLabelByKey(modelData.toString()) exclusiveGroup: selectedScriptGroup + width: parent.width + height: UM.Theme.getSize("setting").height checkable: true - checked: { + + checked: + { if (manager.selectedScriptIndex == index) { base.activeScriptName = manager.getScriptLabelByKey(modelData.toString()) @@ -102,8 +111,7 @@ UM.Dialog manager.setSelectedScriptIndex(index) base.activeScriptName = manager.getScriptLabelByKey(modelData.toString()) } - width: parent.width - height: UM.Theme.getSize("setting").height + style: ButtonStyle { background: Rectangle @@ -121,6 +129,7 @@ UM.Dialog } } } + Button { id: removeButton @@ -249,8 +258,8 @@ UM.Dialog onTriggered: manager.addScriptToList(modelData.toString()) } - onObjectAdded: scriptsMenu.insertItem(index, object); - onObjectRemoved: scriptsMenu.removeItem(object); + onObjectAdded: scriptsMenu.insertItem(index, object) + onObjectRemoved: scriptsMenu.removeItem(object) } } } @@ -268,12 +277,16 @@ UM.Dialog { id: scriptSpecsHeader text: manager.selectedScriptIndex == -1 ? catalog.i18nc("@label", "Settings") : base.activeScriptName - anchors.top: parent.top - anchors.topMargin: base.textMargin - anchors.left: parent.left - anchors.leftMargin: base.textMargin - anchors.right: parent.right - anchors.rightMargin: base.textMargin + anchors + { + top: parent.top + topMargin: base.textMargin + left: parent.left + leftMargin: base.textMargin + right: parent.right + rightMargin: base.textMargin + } + elide: Text.ElideRight height: 20 * screenScaleFactor font: UM.Theme.getFont("large") @@ -283,11 +296,15 @@ UM.Dialog ScrollView { id: scrollView - anchors.top: scriptSpecsHeader.bottom - anchors.topMargin: settingsPanel.textMargin - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom + anchors + { + top: scriptSpecsHeader.bottom + topMargin: settingsPanel.textMargin + left: parent.left + right: parent.right + bottom: parent.bottom + } + visible: manager.selectedScriptDefinitionId != "" style: UM.Theme.styles.scrollview; @@ -297,7 +314,7 @@ UM.Dialog spacing: UM.Theme.getSize("default_lining").height model: UM.SettingDefinitionsModel { - id: definitionsModel; + id: definitionsModel containerId: manager.selectedScriptDefinitionId showAll: true } @@ -327,8 +344,10 @@ UM.Dialog } Behavior on height { NumberAnimation { duration: 100 } } opacity: provider.properties.enabled == "True" ? 1 : 0 + Behavior on opacity { NumberAnimation { duration: 100 } } enabled: opacity > 0 + property var definition: model property var settingDefinitionsModel: definitionsModel property var propertyProvider: provider @@ -339,7 +358,8 @@ UM.Dialog //causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely. asynchronous: model.type != "enum" && model.type != "extruder" - onLoaded: { + onLoaded: + { settingLoader.item.showRevertButton = false settingLoader.item.showInheritButton = false settingLoader.item.showLinkedSettingIcon = false @@ -395,18 +415,14 @@ UM.Dialog onShowTooltip: { - tooltip.text = text; - var position = settingLoader.mapToItem(settingsPanel, settingsPanel.x, 0); - tooltip.show(position); + tooltip.text = text + var position = settingLoader.mapToItem(settingsPanel, settingsPanel.x, 0) + tooltip.show(position) tooltip.target.x = position.x + 1 } - onHideTooltip: - { - tooltip.hide(); - } + onHideTooltip: tooltip.hide() } - } } } @@ -459,6 +475,7 @@ UM.Dialog Cura.SettingUnknown { } } } + rightButtons: Button { text: catalog.i18nc("@action:button", "Close") @@ -466,7 +483,8 @@ UM.Dialog onClicked: dialog.accept() } - Button { + Button + { objectName: "postProcessingSaveAreaButton" visible: activeScriptsList.count > 0 height: UM.Theme.getSize("save_button_save_to_button").height @@ -474,8 +492,10 @@ UM.Dialog tooltip: catalog.i18nc("@info:tooltip", "Change active post-processing scripts") onClicked: dialog.show() - style: ButtonStyle { - background: Rectangle { + style: ButtonStyle + { + background: Rectangle + { id: deviceSelectionIcon border.width: UM.Theme.getSize("default_lining").width border.color: !control.enabled ? UM.Theme.getColor("action_button_disabled_border") : @@ -485,12 +505,15 @@ UM.Dialog control.pressed ? UM.Theme.getColor("action_button_active") : control.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") Behavior on color { ColorAnimation { duration: 50; } } + anchors.left: parent.left - anchors.leftMargin: Math.round(UM.Theme.getSize("save_button_text_margin").width / 2); + anchors.leftMargin: Math.round(UM.Theme.getSize("save_button_text_margin").width / 2) + width: parent.height height: parent.height - UM.RecolorImage { + UM.RecolorImage + { anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter width: Math.round(parent.width / 2) @@ -498,11 +521,11 @@ UM.Dialog sourceSize.height: height color: !control.enabled ? UM.Theme.getColor("action_button_disabled_text") : control.pressed ? UM.Theme.getColor("action_button_active_text") : - control.hovered ? UM.Theme.getColor("action_button_hovered_text") : UM.Theme.getColor("action_button_text"); + control.hovered ? UM.Theme.getColor("action_button_hovered_text") : UM.Theme.getColor("action_button_text") source: "postprocessing.svg" } } - label: Label{ } + label: Label { } } } } \ No newline at end of file From a5134001e98934576969eb1815b228ed92f885f9 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 19 Dec 2018 13:03:59 +0100 Subject: [PATCH 1055/1292] Sort unique printer types So that they appear in a consistent order everywhere. --- cura/PrinterOutputDevice.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index 3102d73bb0..aeeb0381b2 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -230,7 +230,7 @@ class PrinterOutputDevice(QObject, OutputDevice): # Returns the unique configurations of the printers within this output device @pyqtProperty("QStringList", notify = uniqueConfigurationsChanged) def uniquePrinterTypes(self) -> List[str]: - return list(set([configuration.printerType for configuration in self._unique_configurations])) + return list(sorted(set([configuration.printerType for configuration in self._unique_configurations]))) def _onPrintersChanged(self) -> None: for printer in self._printers: From c0835f3a2fa8541de9b74fe715882e5e2993076f Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 19 Dec 2018 13:04:37 +0100 Subject: [PATCH 1056/1292] Code style Just something I boyscouted while working on something else. --- resources/qml/Menus/NetworkPrinterMenu.qml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/resources/qml/Menus/NetworkPrinterMenu.qml b/resources/qml/Menus/NetworkPrinterMenu.qml index 07a22202e4..166e45f3b9 100644 --- a/resources/qml/Menus/NetworkPrinterMenu.qml +++ b/resources/qml/Menus/NetworkPrinterMenu.qml @@ -7,11 +7,14 @@ import QtQuick.Controls 1.4 import UM 1.2 as UM import Cura 1.0 as Cura -Instantiator { - model: UM.ContainerStacksModel { +Instantiator +{ + model: UM.ContainerStacksModel + { filter: {"type": "machine", "um_network_key": "*", "hidden": "False"} } - MenuItem { + MenuItem + { // TODO: Use printer_group icon when it's a cluster. Not use it for now since it doesn't look as expected // iconSource: UM.Theme.getIcon("printer_single") text: model.metadata["connect_group_name"] From f2719ef582093f857e171678052507409f8958c0 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 19 Dec 2018 14:09:07 +0100 Subject: [PATCH 1057/1292] Fix identation for postProcessing plugin settings CURA-6043 --- .../PostProcessingPlugin/PostProcessingPlugin.qml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml index 5862259be5..09fda8d454 100644 --- a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml +++ b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml @@ -301,6 +301,7 @@ UM.Dialog top: scriptSpecsHeader.bottom topMargin: settingsPanel.textMargin left: parent.left + leftMargin: UM.Theme.getSize("default_margin").width right: parent.right bottom: parent.bottom } @@ -318,7 +319,8 @@ UM.Dialog containerId: manager.selectedScriptDefinitionId showAll: true } - delegate:Loader + + delegate: Loader { id: settingLoader @@ -329,18 +331,17 @@ UM.Dialog { if(model.type != undefined) { - return UM.Theme.getSize("section").height; + return UM.Theme.getSize("section").height } else { - return 0; + return 0 } } else { - return 0; + return 0 } - } Behavior on height { NumberAnimation { duration: 100 } } opacity: provider.properties.enabled == "True" ? 1 : 0 @@ -363,7 +364,7 @@ UM.Dialog settingLoader.item.showRevertButton = false settingLoader.item.showInheritButton = false settingLoader.item.showLinkedSettingIcon = false - settingLoader.item.doDepthIndentation = true + settingLoader.item.doDepthIndentation = false settingLoader.item.doQualityUserSettingEmphasis = false } From beb68213f403eb6f2f3318ce2fb058d3aa83bdc5 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Wed, 19 Dec 2018 14:14:44 +0100 Subject: [PATCH 1058/1292] Remove much logging or use debug level, fix cloud icon not appearing right away --- cura/Settings/MachineManager.py | 10 ++++++---- .../UM3NetworkPrinting/src/Cloud/CloudApiClient.py | 4 ++-- .../src/Cloud/CloudOutputDevice.py | 7 ++----- .../src/Cloud/CloudOutputDeviceManager.py | 12 ++++++------ 4 files changed, 16 insertions(+), 17 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index f47724372f..bdb0f10082 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -178,6 +178,7 @@ class MachineManager(QObject): self._printer_output_devices.append(printer_output_device) self.outputDevicesChanged.emit() + self.printerConnectedStatusChanged.emit() @pyqtProperty(QObject, notify = currentConfigurationChanged) def currentConfiguration(self) -> ConfigurationModel: @@ -520,7 +521,7 @@ class MachineManager(QObject): return "" @pyqtProperty(bool, notify = printerConnectedStatusChanged) - def printerConnected(self): + def printerConnected(self) -> bool: return bool(self._printer_output_devices) @pyqtProperty(bool, notify = printerConnectedStatusChanged) @@ -532,9 +533,10 @@ class MachineManager(QObject): @pyqtProperty(bool, notify = printerConnectedStatusChanged) def activeMachineHasCloudConnection(self) -> bool: - if not self.activeMachineHasRemoteConnection: - return False - output_device = next(iter(self.printerOutputDevices), None) # type: Optional[PrinterOutputDevice] + # A cloud connection is only available if the active output device actually is a cloud connected device. + # We cannot simply use the connection_type metadata entry as that's always set to 'NetworkConnection' + # if there was a network connection during setup, which is always the case. + output_device = next(iter(self._printer_output_devices), None) # type: Optional[PrinterOutputDevice] if not output_device: return False return output_device.connectionType == ConnectionType.CloudConnection diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py index 29a9f48c3f..302ca86d32 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py @@ -101,7 +101,7 @@ class CloudApiClient: request.setHeader(QNetworkRequest.ContentTypeHeader, content_type) if self._account.isLoggedIn: request.setRawHeader(b"Authorization", "Bearer {}".format(self._account.accessToken).encode()) - Logger.log("i", "Created request for URL %s. Logged in = %s", path, self._account.isLoggedIn) + # Logger.log("i", "Created request for URL %s. Logged in = %s", path, self._account.isLoggedIn) return request ## Parses the given JSON network reply into a status code and a dictionary, handling unexpected errors as well. @@ -112,7 +112,7 @@ class CloudApiClient: status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) try: response = bytes(reply.readAll()).decode() - Logger.log("i", "Received a reply %s from %s with %s", status_code, reply.url().toString(), response) + # Logger.log("i", "Received a reply %s from %s with %s", status_code, reply.url().toString(), response) return status_code, json.loads(response) except (UnicodeDecodeError, JSONDecodeError, ValueError) as err: error = CloudErrorObject(code=type(err).__name__, title=str(err), http_code=str(status_code), diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 7e9608dc8b..c436418f5e 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -65,8 +65,6 @@ class T: # Currently it only supports viewing the printer and print job status and adding a new job to the queue. # As such, those methods have been implemented here. # Note that this device represents a single remote cluster, not a list of multiple clusters. -# -# TODO: figure our how the QML interface for the cluster networking should operate with this limited functionality. class CloudOutputDevice(NetworkedPrinterOutputDevice): # The interval with which the remote clusters are checked @@ -202,10 +200,9 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def _update(self) -> None: super()._update() if self._last_request_time and time() - self._last_request_time < self.CHECK_CLUSTER_INTERVAL: - Logger.log("i", "Not updating: %s - %s < %s", time(), self._last_request_time, self.CHECK_CLUSTER_INTERVAL) return # avoid calling the cloud too often - Logger.log("i", "Updating: %s - %s >= %s", time(), self._last_request_time, self.CHECK_CLUSTER_INTERVAL) + Logger.log("d", "Updating: %s - %s >= %s", time(), self._last_request_time, self.CHECK_CLUSTER_INTERVAL) if self._account.isLoggedIn: self.setAuthenticationState(AuthState.Authenticated) self._last_request_time = time() @@ -342,7 +339,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## Shows a message when the upload has succeeded # \param response: The response from the cloud API. def _onPrintRequested(self, response: CloudPrintResponse) -> None: - Logger.log("i", "The cluster will be printing this print job with the ID %s", response.cluster_job_id) + Logger.log("d", "The cluster will be printing this print job with the ID %s", response.cluster_job_id) self._progress.hide() Message( text = T.UPLOAD_SUCCESS_TEXT, diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 07051f15fd..af45f06394 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -50,7 +50,7 @@ class CloudOutputDeviceManager: # Called when the uses logs in or out def _onLoginStateChanged(self, is_logged_in: bool) -> None: - Logger.log("i", "Log in state changed to %s", is_logged_in) + Logger.log("d", "Log in state changed to %s", is_logged_in) if is_logged_in: if not self._update_timer.isActive(): self._update_timer.start() @@ -64,7 +64,7 @@ class CloudOutputDeviceManager: ## Gets all remote clusters from the API. def _getRemoteClusters(self) -> None: - Logger.log("i", "Retrieving remote clusters") + Logger.log("d", "Retrieving remote clusters") self._api.getClusters(self._onGetRemoteClustersFinished) ## Callback for when the request for getting the clusters. is finished. @@ -73,8 +73,8 @@ class CloudOutputDeviceManager: removed_devices, added_clusters, updates = findChanges(self._remote_clusters, online_clusters) - Logger.log("i", "Parsed remote clusters to %s", [cluster.toDict() for cluster in online_clusters.values()]) - Logger.log("i", "Removed: %s, added: %s, updates: %s", len(removed_devices), len(added_clusters), len(updates)) + Logger.log("d", "Parsed remote clusters to %s", [cluster.toDict() for cluster in online_clusters.values()]) + Logger.log("d", "Removed: %s, added: %s, updates: %s", len(removed_devices), len(added_clusters), len(updates)) # Remove output devices that are gone for removed_cluster in removed_devices: @@ -100,7 +100,7 @@ class CloudOutputDeviceManager: def _connectToActiveMachine(self) -> None: active_machine = CuraApplication.getInstance().getGlobalContainerStack() if not active_machine: - Logger.log("i", "no active machine") + Logger.log("d", "no active machine") return # Check if the stored cluster_id for the active machine is in our list of remote clusters. @@ -109,7 +109,7 @@ class CloudOutputDeviceManager: device = self._remote_clusters[stored_cluster_id] if not device.isConnected(): device.connect() - Logger.log("i", "Device connected by metadata %s", stored_cluster_id) + Logger.log("d", "Device connected by metadata %s", stored_cluster_id) else: self._connectByNetworkKey(active_machine) From 3953c7bb3a4400f7e49fe3ee53052e317b341f62 Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Wed, 19 Dec 2018 14:24:02 +0100 Subject: [PATCH 1059/1292] Added Tooltip alignment CURA-6004 --- resources/qml/ActionButton.qml | 2 ++ .../qml/ActionPanel/OutputProcessWidget.qml | 2 ++ resources/qml/ToolTip.qml | 29 +++++++++++++++++-- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index 675cbb588e..9ceade6a57 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -31,6 +31,8 @@ Button property alias shadowColor: shadow.color property alias shadowEnabled: shadow.visible + property alias toolTipContentAlignment: tooltip.contentAlignment + // This property is used to indicate whether the button has a fixed width or the width would depend on the contents // Be careful when using fixedWidthMode, the translated texts can be too long that they won't fit. In any case, // we elide the text to the right so the text will be cut off with the three dots at the end. diff --git a/resources/qml/ActionPanel/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml index eb6dc5b417..03fa00d504 100644 --- a/resources/qml/ActionPanel/OutputProcessWidget.qml +++ b/resources/qml/ActionPanel/OutputProcessWidget.qml @@ -123,6 +123,8 @@ Column tooltip: text fixedWidthMode: true + toolTipContentAlignment: Cura.ToolTip.ContentAlignment.AlignLeft + onClicked: UM.Controller.setActiveStage("PreviewStage") visible: UM.Controller.activeStage != null && UM.Controller.activeStage.stageId != "PreviewStage" diff --git a/resources/qml/ToolTip.qml b/resources/qml/ToolTip.qml index ed71d3983b..5e7d436d70 100644 --- a/resources/qml/ToolTip.qml +++ b/resources/qml/ToolTip.qml @@ -5,14 +5,26 @@ import QtQuick 2.7 import QtQuick.Controls 2.3 import UM 1.0 as UM +import Cura 1.0 as Cura ToolTip { + + enum ContentAlignment + { + AlignLeft, + AlignRight + } + // This property indicates when the tooltip has to show, for instance when a button is hovered property bool show: false + // Defines the alignment of the content, by default to the left + property int contentAlignment: Cura.ToolTip.ContentAlignment.AlignRight + property alias tooltipText: tooltip.text - property var targetPoint: Qt.point(0, 0) + property var targetPoint: Qt.point(parent.x, y + Math.round(height/2)) + id: tooltip text: "" @@ -20,13 +32,24 @@ ToolTip visible: text != "" && show font: UM.Theme.getFont("default") + x: + { + if (contentAlignment == Cura.ToolTip.ContentAlignment.AlignLeft) + { + return (label.width + Math.round(UM.Theme.getSize("default_arrow").width * 1.2) + padding * 2) * -1 + } + return parent.width + Math.round(UM.Theme.getSize("default_arrow").width * 1.2 + padding) + } + + y: Math.round(parent.height / 2 - label.height / 2 ) - padding + + padding: 2 + background: UM.PointingRectangle { id: backgroundRect color: UM.Theme.getColor("tooltip") - target: Qt.point(targetPoint.x - tooltip.x, targetPoint.y - tooltip.y) - arrowSize: UM.Theme.getSize("default_arrow").width } From d891d30ab8df3b528902102b12dba6de7298eacc Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Wed, 19 Dec 2018 15:51:32 +0100 Subject: [PATCH 1060/1292] The Cura logo in left top corner is not displayed properly. CURA-6044 --- resources/qml/MainWindow/MainWindowHeader.qml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/resources/qml/MainWindow/MainWindowHeader.qml b/resources/qml/MainWindow/MainWindowHeader.qml index eecf2a1e73..971b275bd8 100644 --- a/resources/qml/MainWindow/MainWindowHeader.qml +++ b/resources/qml/MainWindow/MainWindowHeader.qml @@ -29,6 +29,8 @@ Item source: UM.Theme.getImage("logo") width: UM.Theme.getSize("logo").width height: UM.Theme.getSize("logo").height + + mipmap: true } Row From 9dbc6429674cf13f9f763a0a5dd76f0dae6f6446 Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Wed, 19 Dec 2018 17:34:31 +0100 Subject: [PATCH 1061/1292] SendMaterials: Make sure the base-material is compared to and make case insensitive. [CURA-6035] --- plugins/UM3NetworkPrinting/src/SendMaterialJob.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py index f536fad49a..a1ddf37461 100644 --- a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py @@ -101,11 +101,10 @@ class SendMaterialJob(Job): continue file_name = os.path.basename(file_path) - material_id = urllib.parse.unquote_plus(mime_type.stripExtension(file_name)) + material_id = urllib.parse.unquote_plus(mime_type.stripExtension(file_name)).lower() if material_id not in materials_to_send: # If the material does not have to be sent we skip it. continue - self._sendMaterialFile(file_path, file_name, material_id) ## Send a single material file to the printer. @@ -182,6 +181,7 @@ class SendMaterialJob(Job): # Create a new local material local_material = LocalMaterial(**material) + local_material.id = material["base_file"].lower() # Don't compare each profile, only base materials. if local_material.GUID not in result or \ local_material.version > result.get(local_material.GUID).version: From 8bff0d17e8b2b15e67d5da8f02bda41ea0fe3576 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 20 Dec 2018 09:43:01 +0100 Subject: [PATCH 1062/1292] Prevent the backend attempting to reslice everytime a preference changed --- plugins/CuraEngineBackend/CuraEngineBackend.py | 1 + resources/qml/ActionPanel/SliceProcessWidget.qml | 10 +++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 7ede6b6736..1830a30b30 100755 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -229,6 +229,7 @@ class CuraEngineBackend(QObject, Backend): if not self._build_plates_to_be_sliced: self.processingProgress.emit(1.0) Logger.log("w", "Slice unnecessary, nothing has changed that needs reslicing.") + self.setState(BackendState.Done) return if self._process_layers_job: diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index 3756d0d452..b80c24e7b7 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -134,10 +134,14 @@ Column onPreferenceChanged: { var autoSlice = UM.Preferences.getValue("general/auto_slice") - prepareButtons.autoSlice = autoSlice - if(autoSlice) + print(prepareButtons.autoSlice, autoSlice) + if(prepareButtons.autoSlice != autoSlice) { - CuraApplication.backend.forceSlice() + prepareButtons.autoSlice = autoSlice + if(autoSlice) + { + CuraApplication.backend.forceSlice() + } } } } From a9f4b70b5cf35be3b8dec8f99178a73d12ebd571 Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Thu, 20 Dec 2018 09:53:58 +0100 Subject: [PATCH 1063/1292] Emit 'number of extruders changed' signal after add machine. [CURA-6045] --- cura/Settings/MachineManager.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index cd8ca09447..2185bbce9d 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -299,6 +299,7 @@ class MachineManager(QObject): self.activeMaterialChanged.emit() self.rootMaterialChanged.emit() + self.numberExtrudersEnabledChanged.emit() def _onContainersChanged(self, container: ContainerInterface) -> None: self._instance_container_timer.start() From d93e19d530e93b0fb02c79a591b49aa6b8593967 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 20 Dec 2018 10:45:03 +0100 Subject: [PATCH 1064/1292] Add getAllMaterialGroups() CURA-6035 --- cura/Machines/MaterialManager.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index aee96f3153..4d9574bf38 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -302,6 +302,10 @@ class MaterialManager(QObject): def getMaterialGroupListByGUID(self, guid: str) -> Optional[List[MaterialGroup]]: return self._guid_material_groups_map.get(guid) + # Returns a dict of all material groups organized by root_material_id. + def getAllMaterialGroups(self) -> Dict[str, "MaterialGroup"]: + return self._material_group_map + # # Return a dict with all root material IDs (k) and ContainerNodes (v) that's suitable for the given setup. # From 68372aff6038064892becda076e6c642a36e92b7 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 20 Dec 2018 10:45:38 +0100 Subject: [PATCH 1065/1292] Use MaterialManager in SendMaterialJob CURA-6035 --- .../UM3NetworkPrinting/src/SendMaterialJob.py | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py index a1ddf37461..7a0da24098 100644 --- a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py @@ -2,17 +2,14 @@ # Cura is released under the terms of the LGPLv3 or higher. import json import os -import urllib.parse from typing import Dict, TYPE_CHECKING, Set from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest -from UM.Application import Application from UM.Job import Job from UM.Logger import Logger -from UM.MimeTypeDatabase import MimeTypeDatabase -from UM.Resources import Resources from cura.CuraApplication import CuraApplication + # Absolute imports don't work in plugins from .Models import ClusterMaterial, LocalMaterial @@ -91,21 +88,22 @@ class SendMaterialJob(Job): # # \param materials_to_send A set with id's of materials that must be sent. def _sendMaterials(self, materials_to_send: Set[str]) -> None: - file_paths = Resources.getAllResourcesOfType(CuraApplication.ResourceTypes.MaterialInstanceContainer) + container_registry = CuraApplication.getInstance().getContainerRegistry() + material_manager = CuraApplication.getInstance().getMaterialManager() + material_group_dict = material_manager.getAllMaterialGroups() - # Find all local material files and send them if needed. - for file_path in file_paths: - try: - mime_type = MimeTypeDatabase.getMimeTypeForFile(file_path) - except MimeTypeDatabase.MimeTypeNotFoundError: + for root_material_id in material_group_dict: + if root_material_id not in materials_to_send: + # If the material does not have to be sent we skip it. + continue + + file_path = container_registry.getContainerFilePathById(root_material_id) + if not file_path: + Logger.log("e", "Cannot get file path for material container [%s]", root_material_id) continue file_name = os.path.basename(file_path) - material_id = urllib.parse.unquote_plus(mime_type.stripExtension(file_name)).lower() - if material_id not in materials_to_send: - # If the material does not have to be sent we skip it. - continue - self._sendMaterialFile(file_path, file_name, material_id) + self._sendMaterialFile(file_path, file_name, root_material_id) ## Send a single material file to the printer. # @@ -115,7 +113,6 @@ class SendMaterialJob(Job): # \param file_name The name of the material file. # \param material_id The ID of the material in the file. def _sendMaterialFile(self, file_path: str, file_name: str, material_id: str) -> None: - parts = [] # Add the material file. @@ -170,28 +167,31 @@ class SendMaterialJob(Job): # \return a dictionary of LocalMaterial objects by GUID def _getLocalMaterials(self) -> Dict[str, LocalMaterial]: result = {} # type: Dict[str, LocalMaterial] - container_registry = Application.getInstance().getContainerRegistry() - material_containers = container_registry.findContainersMetadata(type = "material") + material_manager = CuraApplication.getInstance().getMaterialManager() + + material_group_dict = material_manager.getAllMaterialGroups() # Find the latest version of all material containers in the registry. - for material in material_containers: + for root_material_id, material_group in material_group_dict.items(): + material_metadata = material_group.root_material_node.getMetadata() + try: # material version must be an int - material["version"] = int(material["version"]) + material_metadata["version"] = int(material_metadata["version"]) # Create a new local material - local_material = LocalMaterial(**material) - local_material.id = material["base_file"].lower() # Don't compare each profile, only base materials. + local_material = LocalMaterial(**material_metadata) + local_material.id = root_material_id if local_material.GUID not in result or \ local_material.version > result.get(local_material.GUID).version: result[local_material.GUID] = local_material except KeyError: - Logger.logException("w", "Local material {} has missing values.".format(material["id"])) + Logger.logException("w", "Local material {} has missing values.".format(material_metadata["id"])) except ValueError: - Logger.logException("w", "Local material {} has invalid values.".format(material["id"])) + Logger.logException("w", "Local material {} has invalid values.".format(material_metadata["id"])) except TypeError: - Logger.logException("w", "Local material {} has invalid values.".format(material["id"])) + Logger.logException("w", "Local material {} has invalid values.".format(material_metadata["id"])) return result From dc473dc78d63c15a62dfd5a197162f43b0780b8f Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 20 Dec 2018 11:09:02 +0100 Subject: [PATCH 1066/1292] Add missing typing for setting visibility preset model --- .../Models/SettingVisibilityPresetsModel.py | 35 +++++++++++++------ .../qml/ActionPanel/SliceProcessWidget.qml | 1 - 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/cura/Machines/Models/SettingVisibilityPresetsModel.py b/cura/Machines/Models/SettingVisibilityPresetsModel.py index 79131521f2..baa8e3ed29 100644 --- a/cura/Machines/Models/SettingVisibilityPresetsModel.py +++ b/cura/Machines/Models/SettingVisibilityPresetsModel.py @@ -6,6 +6,7 @@ from typing import Optional, List from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject from UM.Logger import Logger +from UM.Preferences import Preferences from UM.Resources import Resources from UM.i18n import i18nCatalog @@ -18,14 +19,20 @@ class SettingVisibilityPresetsModel(QObject): onItemsChanged = pyqtSignal() activePresetChanged = pyqtSignal() - def __init__(self, preferences, parent = None): + def __init__(self, preferences: Preferences, parent = None) -> None: super().__init__(parent) self._items = [] # type: List[SettingVisibilityPreset] + self._custom_preset = SettingVisibilityPreset(preset_id = "custom", name = "Custom selection", weight = -100) + self._populate() basic_item = self.getVisibilityPresetById("basic") - basic_visibile_settings = ";".join(basic_item.settings) + if basic_item is not None: + basic_visibile_settings = ";".join(basic_item.settings) + else: + Logger.log("w", "Unable to find the basic visiblity preset.") + basic_visibile_settings = "" self._preferences = preferences @@ -42,7 +49,8 @@ class SettingVisibilityPresetsModel(QObject): visible_settings = self._preferences.getValue("general/visible_settings") if not visible_settings: - self._preferences.setValue("general/visible_settings", ";".join(self._active_preset_item.settings)) + new_visible_settings = self._active_preset_item.settings if self._active_preset_item is not None else [] + self._preferences.setValue("general/visible_settings", ";".join(new_visible_settings)) else: self._onPreferencesChanged("general/visible_settings") @@ -59,9 +67,7 @@ class SettingVisibilityPresetsModel(QObject): def _populate(self) -> None: from cura.CuraApplication import CuraApplication items = [] # type: List[SettingVisibilityPreset] - - custom_preset = SettingVisibilityPreset(preset_id="custom", name ="Custom selection", weight = -100) - items.append(custom_preset) + items.append(self._custom_preset) for file_path in Resources.getAllResourcesOfType(CuraApplication.ResourceTypes.SettingVisibilityPreset): setting_visibility_preset = SettingVisibilityPreset() try: @@ -77,7 +83,7 @@ class SettingVisibilityPresetsModel(QObject): self.setItems(items) @pyqtProperty("QVariantList", notify = onItemsChanged) - def items(self): + def items(self) -> List[SettingVisibilityPreset]: return self._items def setItems(self, items: List[SettingVisibilityPreset]) -> None: @@ -87,7 +93,7 @@ class SettingVisibilityPresetsModel(QObject): @pyqtSlot(str) def setActivePreset(self, preset_id: str) -> None: - if preset_id == self._active_preset_item.presetId: + if self._active_preset_item is not None and preset_id == self._active_preset_item.presetId: Logger.log("d", "Same setting visibility preset [%s] selected, do nothing.", preset_id) return @@ -96,7 +102,7 @@ class SettingVisibilityPresetsModel(QObject): Logger.log("w", "Tried to set active preset to unknown id [%s]", preset_id) return - need_to_save_to_custom = self._active_preset_item.presetId == "custom" and preset_id != "custom" + need_to_save_to_custom = self._active_preset_item is None or (self._active_preset_item.presetId == "custom" and preset_id != "custom") if need_to_save_to_custom: # Save the current visibility settings to custom current_visibility_string = self._preferences.getValue("general/visible_settings") @@ -117,7 +123,9 @@ class SettingVisibilityPresetsModel(QObject): @pyqtProperty(str, notify = activePresetChanged) def activePreset(self) -> str: - return self._active_preset_item.presetId + if self._active_preset_item is not None: + return self._active_preset_item.presetId + return "" def _onPreferencesChanged(self, name: str) -> None: if name != "general/visible_settings": @@ -149,7 +157,12 @@ class SettingVisibilityPresetsModel(QObject): else: item_to_set = matching_preset_item + # If we didn't find a matching preset, fallback to custom. + if item_to_set is None: + item_to_set = self._custom_preset + if self._active_preset_item is None or self._active_preset_item.presetId != item_to_set.presetId: self._active_preset_item = item_to_set - self._preferences.setValue("cura/active_setting_visibility_preset", self._active_preset_item.presetId) + if self._active_preset_item is not None: + self._preferences.setValue("cura/active_setting_visibility_preset", self._active_preset_item.presetId) self.activePresetChanged.emit() diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index b80c24e7b7..462d685fd4 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -134,7 +134,6 @@ Column onPreferenceChanged: { var autoSlice = UM.Preferences.getValue("general/auto_slice") - print(prepareButtons.autoSlice, autoSlice) if(prepareButtons.autoSlice != autoSlice) { prepareButtons.autoSlice = autoSlice From 36efa171c68dd7b0beb5771b1f29be1680127a99 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 20 Dec 2018 11:31:01 +0100 Subject: [PATCH 1067/1292] Add a bit more logging to the authorization service --- cura/OAuth2/AuthorizationService.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cura/OAuth2/AuthorizationService.py b/cura/OAuth2/AuthorizationService.py index 4355891139..a055254891 100644 --- a/cura/OAuth2/AuthorizationService.py +++ b/cura/OAuth2/AuthorizationService.py @@ -83,9 +83,11 @@ class AuthorizationService: if not self.getUserProfile(): # We check if we can get the user profile. # If we can't get it, that means the access token (JWT) was invalid or expired. + Logger.log("w", "Unable to get the user profile.") return None if self._auth_data is None: + Logger.log("d", "No auth data to retrieve the access_token from") return None return self._auth_data.access_token From 2f92f6ef50faba4b8c3875481b60e446bc6bc83b Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Thu, 20 Dec 2018 13:45:59 +0100 Subject: [PATCH 1068/1292] Simplify checking if cloud or network printer, small fixes --- .../NetworkedPrinterOutputDevice.py | 5 +++++ cura/Settings/MachineManager.py | 16 +++++++------- .../src/Cloud/CloudOutputDevice.py | 21 +++++++------------ .../src/ClusterUM3OutputDevice.py | 6 ++---- .../qml/PrinterSelector/MachineSelector.qml | 4 ++-- 5 files changed, 24 insertions(+), 28 deletions(-) diff --git a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py index d0a0b5076a..3dcc43dd00 100644 --- a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py +++ b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py @@ -150,6 +150,11 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): request.setHeader(QNetworkRequest.UserAgentHeader, self._user_agent) return request + ## This method was only available privately before, but it was actually called from SendMaterialJob.py. + # We now have a public equivalent as well. We did not remove the private one as plugins might be using that. + def createFormPart(self, content_header: str, data: bytes, content_type: Optional[str] = None) -> QHttpPart: + return self._createFormPart(content_header, data, content_type) + def _createFormPart(self, content_header: str, data: bytes, content_type: Optional[str] = None) -> QHttpPart: part = QHttpPart() diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 8d42ee59a2..66ee7f9543 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -533,14 +533,14 @@ class MachineManager(QObject): return False @pyqtProperty(bool, notify = printerConnectedStatusChanged) - def activeMachineHasCloudConnection(self) -> bool: - # A cloud connection is only available if the active output device actually is a cloud connected device. - # We cannot simply use the connection_type metadata entry as that's always set to 'NetworkConnection' - # if there was a network connection during setup, which is always the case. - output_device = next(iter(self._printer_output_devices), None) # type: Optional[PrinterOutputDevice] - if not output_device: - return False - return output_device.connectionType == ConnectionType.CloudConnection + def activeMachineHasActiveNetworkConnection(self) -> bool: + # A network connection is only available if any output device is actually a network connected device. + return any(d.connectionType == ConnectionType.NetworkConnection for d in self._printer_output_devices) + + @pyqtProperty(bool, notify = printerConnectedStatusChanged) + def activeMachineHasActiveCloudConnection(self) -> bool: + # A cloud connection is only available if any output device actually is a cloud connected device. + return any(d.connectionType == ConnectionType.CloudConnection for d in self._printer_output_devices) def activeMachineNetworkKey(self) -> str: if self._global_container_stack: diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index c436418f5e..093aa05ea9 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -246,7 +246,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): if self._printers and not self._active_printer: self.setActivePrinter(self._printers[0]) - self.printersChanged.emit() # TODO: Make this more efficient by not updating every request + if added_printers or removed_printers or updated_printers: + self.printersChanged.emit() ## Updates the local list of print jobs with the list received from the cloud. # \param jobs: The print jobs received from the cloud. @@ -302,10 +303,10 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## Updates the printer assignment for the given print job model. def _updateAssignedPrinter(self, model: UM3PrintJobOutputModel, printer_uuid: str) -> None: printer = next((p for p in self._printers if printer_uuid == p.key), None) - if not printer: - return Logger.log("w", "Missing printer %s for job %s in %s", model.assignedPrinter, model.key, - [p.key for p in self._printers]) + Logger.log("w", "Missing printer %s for job %s in %s", model.assignedPrinter, model.key, + [p.key for p in self._printers]) + return printer.updateActivePrintJob(model) model.updateAssignedPrinter(printer) @@ -329,11 +330,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def _onUploadError(self, message = None) -> None: self._progress.hide() self._uploaded_print_job = None - Message( - text = message or T.UPLOAD_ERROR, - title = T.ERROR, - lifetime = 10 - ).show() + Message(text = message or T.UPLOAD_ERROR, title = T.ERROR, lifetime = 10).show() self.writeError.emit() ## Shows a message when the upload has succeeded @@ -341,11 +338,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def _onPrintRequested(self, response: CloudPrintResponse) -> None: Logger.log("d", "The cluster will be printing this print job with the ID %s", response.cluster_job_id) self._progress.hide() - Message( - text = T.UPLOAD_SUCCESS_TEXT, - title = T.UPLOAD_SUCCESS_TITLE, - lifetime = 5 - ).show() + Message(text = T.UPLOAD_SUCCESS_TEXT, title = T.UPLOAD_SUCCESS_TITLE, lifetime = 5).show() self.writeFinished.emit() ## Gets the remote printers. diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index a9a002aed7..75fd1e0f9e 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -389,10 +389,8 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): ## Called when the connection to the cluster changes. def connect(self) -> None: - # TODO: uncomment this once cloud implementation works for testing - # super().connect() - # self.sendMaterialProfiles() - pass + super().connect() + self.sendMaterialProfiles() def _onGetPreviewImageFinished(self, reply: QNetworkReply) -> None: reply_url = reply.url().toString() diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index bb8934f620..64cf3e6005 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -12,9 +12,9 @@ Cura.ExpandablePopup id: machineSelector property var outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null - property bool isNetworkPrinter: Cura.MachineManager.activeMachineHasRemoteConnection - property bool isCloudPrinter: Cura.MachineManager.activeMachineHasCloudConnection property bool isPrinterConnected: Cura.MachineManager.printerConnected + property bool isNetworkPrinter: Cura.MachineManager.activeMachineHasActiveNetworkConnection + property bool isCloudPrinter: Cura.MachineManager.activeMachineHasActiveCloudConnection contentPadding: UM.Theme.getSize("default_lining").width contentAlignment: Cura.ExpandablePopup.ContentAlignment.AlignLeft From 9ffc03925469aaaebceebd7d7931ab377e2f5d95 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 20 Dec 2018 14:01:12 +0100 Subject: [PATCH 1069/1292] Fix logo aliasing CURA-6044 --- plugins/VersionUpgrade/VersionUpgrade32to33/__init__.py | 2 +- resources/qml/MainWindow/MainWindowHeader.qml | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/VersionUpgrade/VersionUpgrade32to33/__init__.py b/plugins/VersionUpgrade/VersionUpgrade32to33/__init__.py index 006b21bc48..b55ea5ebaf 100644 --- a/plugins/VersionUpgrade/VersionUpgrade32to33/__init__.py +++ b/plugins/VersionUpgrade/VersionUpgrade32to33/__init__.py @@ -47,7 +47,7 @@ def getMetaData() -> Dict[str, Any]: }, "user": { "get_version": upgrade.getCfgVersion, - "location": {"./user"} + "location": {"./user", "./materials/*"} }, "variant": { "get_version": upgrade.getCfgVersion, diff --git a/resources/qml/MainWindow/MainWindowHeader.qml b/resources/qml/MainWindow/MainWindowHeader.qml index 971b275bd8..e3b7e199fa 100644 --- a/resources/qml/MainWindow/MainWindowHeader.qml +++ b/resources/qml/MainWindow/MainWindowHeader.qml @@ -30,7 +30,8 @@ Item width: UM.Theme.getSize("logo").width height: UM.Theme.getSize("logo").height - mipmap: true + sourceSize.width: width + sourceSize.height: height } Row From e79f312fa0fa3e35bfc407e4c7d59a572d044686 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 20 Dec 2018 14:20:31 +0100 Subject: [PATCH 1070/1292] Fix unit tests for SendMaterialJob CURA-6035 --- .../UM3NetworkPrinting/src/SendMaterialJob.py | 10 +- .../tests/TestSendMaterialJob.py | 135 +++++++++++++----- 2 files changed, 102 insertions(+), 43 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py index 7a0da24098..ab6ebfef2e 100644 --- a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py @@ -6,9 +6,9 @@ from typing import Dict, TYPE_CHECKING, Set from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest +from UM.Application import Application from UM.Job import Job from UM.Logger import Logger -from cura.CuraApplication import CuraApplication # Absolute imports don't work in plugins from .Models import ClusterMaterial, LocalMaterial @@ -34,7 +34,6 @@ class SendMaterialJob(Job): # # \param reply The reply from the printer, a json file. def _onGetRemoteMaterials(self, reply: QNetworkReply) -> None: - # Got an error from the HTTP request. If we did not receive a 200 something happened. if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) != 200: Logger.log("e", "Error fetching materials from printer: %s", reply.errorString()) @@ -49,7 +48,6 @@ class SendMaterialJob(Job): # # \param remote_materials_by_guid The remote materials by GUID. def _sendMissingMaterials(self, remote_materials_by_guid: Dict[str, ClusterMaterial]) -> None: - # Collect local materials local_materials_by_guid = self._getLocalMaterials() if len(local_materials_by_guid) == 0: @@ -88,8 +86,8 @@ class SendMaterialJob(Job): # # \param materials_to_send A set with id's of materials that must be sent. def _sendMaterials(self, materials_to_send: Set[str]) -> None: - container_registry = CuraApplication.getInstance().getContainerRegistry() - material_manager = CuraApplication.getInstance().getMaterialManager() + container_registry = Application.getInstance().getContainerRegistry() + material_manager = Application.getInstance().getMaterialManager() material_group_dict = material_manager.getAllMaterialGroups() for root_material_id in material_group_dict: @@ -167,7 +165,7 @@ class SendMaterialJob(Job): # \return a dictionary of LocalMaterial objects by GUID def _getLocalMaterials(self) -> Dict[str, LocalMaterial]: result = {} # type: Dict[str, LocalMaterial] - material_manager = CuraApplication.getInstance().getMaterialManager() + material_manager = Application.getInstance().getMaterialManager() material_group_dict = material_manager.getAllMaterialGroups() diff --git a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py index b669eb192a..4303f89c20 100644 --- a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py @@ -1,26 +1,29 @@ # Copyright (c) 2018 Ultimaker B.V. # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +import copy import io import json from unittest import TestCase, mock -from unittest.mock import patch, call +from unittest.mock import patch, call, MagicMock from PyQt5.QtCore import QByteArray -from UM.MimeTypeDatabase import MimeType from UM.Application import Application + +from cura.Machines.MaterialGroup import MaterialGroup +from cura.Machines.MaterialNode import MaterialNode + from plugins.UM3NetworkPrinting.src.SendMaterialJob import SendMaterialJob +_FILES_MAP = {"generic_pla_white": "/materials/generic_pla_white.xml.fdm_material", + "generic_pla_black": "/materials/generic_pla_black.xml.fdm_material", + } + @patch("builtins.open", lambda _, __: io.StringIO("")) -@patch("UM.MimeTypeDatabase.MimeTypeDatabase.getMimeTypeForFile", - lambda _: MimeType(name = "application/x-ultimaker-material-profile", comment = "Ultimaker Material Profile", - suffixes = ["xml.fdm_material"])) -@patch("UM.Resources.Resources.getAllResourcesOfType", lambda _: ["/materials/generic_pla_white.xml.fdm_material"]) -@patch("plugins.UM3NetworkPrinting.src.ClusterUM3OutputDevice") -@patch("PyQt5.QtNetwork.QNetworkReply") class TestSendMaterialJob(TestCase): + # version 1 _LOCAL_MATERIAL_WHITE = {"type": "material", "status": "unknown", "id": "generic_pla_white", "base_file": "generic_pla_white", "setting_version": "5", "name": "White PLA", "brand": "Generic", "material": "PLA", "color_name": "White", @@ -29,6 +32,37 @@ class TestSendMaterialJob(TestCase): "properties": {"density": "1.00", "diameter": "2.85", "weight": "750"}, "definition": "fdmprinter", "compatible": True} + # version 2 + _LOCAL_MATERIAL_WHITE_NEWER = {"type": "material", "status": "unknown", "id": "generic_pla_white", + "base_file": "generic_pla_white", "setting_version": "5", "name": "White PLA", + "brand": "Generic", "material": "PLA", "color_name": "White", + "GUID": "badb0ee7-87c8-4f3f-9398-938587b67dce", "version": "2", + "color_code": "#ffffff", + "description": "Test PLA White", "adhesion_info": "Use glue.", + "approximate_diameter": "3", + "properties": {"density": "1.00", "diameter": "2.85", "weight": "750"}, + "definition": "fdmprinter", "compatible": True} + + # invalid version: "one" + _LOCAL_MATERIAL_WHITE_INVALID_VERSION = {"type": "material", "status": "unknown", "id": "generic_pla_white", + "base_file": "generic_pla_white", "setting_version": "5", "name": "White PLA", + "brand": "Generic", "material": "PLA", "color_name": "White", + "GUID": "badb0ee7-87c8-4f3f-9398-938587b67dce", "version": "one", + "color_code": "#ffffff", + "description": "Test PLA White", "adhesion_info": "Use glue.", + "approximate_diameter": "3", + "properties": {"density": "1.00", "diameter": "2.85", "weight": "750"}, + "definition": "fdmprinter", "compatible": True} + + _LOCAL_MATERIAL_WHITE_ALL_RESULT = {"generic_pla_white": MaterialGroup("generic_pla_white", + MaterialNode(_LOCAL_MATERIAL_WHITE))} + + _LOCAL_MATERIAL_WHITE_NEWER_ALL_RESULT = {"generic_pla_white": MaterialGroup("generic_pla_white", + MaterialNode(_LOCAL_MATERIAL_WHITE_NEWER))} + + _LOCAL_MATERIAL_WHITE_INVALID_VERSION_ALL_RESULT = {"generic_pla_white": MaterialGroup("generic_pla_white", + MaterialNode(_LOCAL_MATERIAL_WHITE_INVALID_VERSION))} + _LOCAL_MATERIAL_BLACK = {"type": "material", "status": "unknown", "id": "generic_pla_black", "base_file": "generic_pla_black", "setting_version": "5", "name": "Yellow CPE", "brand": "Ultimaker", "material": "CPE", "color_name": "Black", @@ -37,6 +71,9 @@ class TestSendMaterialJob(TestCase): "properties": {"density": "1.01", "diameter": "2.85", "weight": "750"}, "definition": "fdmprinter", "compatible": True} + _LOCAL_MATERIAL_BLACK_ALL_RESULT = {"generic_pla_black": MaterialGroup("generic_pla_black", + MaterialNode(_LOCAL_MATERIAL_BLACK))} + _REMOTE_MATERIAL_WHITE = { "guid": "badb0ee7-87c8-4f3f-9398-938587b67dce", "material": "PLA", @@ -55,14 +92,17 @@ class TestSendMaterialJob(TestCase): "density": 1.00 } - def test_run(self, device_mock, reply_mock): + def test_run(self): + device_mock = MagicMock() job = SendMaterialJob(device_mock) job.run() # We expect the materials endpoint to be called when the job runs. device_mock.get.assert_called_with("materials/", on_finished = job._onGetRemoteMaterials) - def test__onGetRemoteMaterials_withFailedRequest(self, reply_mock, device_mock): + def test__onGetRemoteMaterials_withFailedRequest(self): + reply_mock = MagicMock() + device_mock = MagicMock() reply_mock.attribute.return_value = 404 job = SendMaterialJob(device_mock) job._onGetRemoteMaterials(reply_mock) @@ -70,7 +110,9 @@ class TestSendMaterialJob(TestCase): # We expect the device not to be called for any follow up. self.assertEqual(0, device_mock.createFormPart.call_count) - def test__onGetRemoteMaterials_withWrongEncoding(self, reply_mock, device_mock): + def test__onGetRemoteMaterials_withWrongEncoding(self): + reply_mock = MagicMock() + device_mock = MagicMock() reply_mock.attribute.return_value = 200 reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTE_MATERIAL_WHITE]).encode("cp500")) job = SendMaterialJob(device_mock) @@ -79,7 +121,9 @@ class TestSendMaterialJob(TestCase): # Given that the parsing fails we do no expect the device to be called for any follow up. self.assertEqual(0, device_mock.createFormPart.call_count) - def test__onGetRemoteMaterials_withBadJsonAnswer(self, reply_mock, device_mock): + def test__onGetRemoteMaterials_withBadJsonAnswer(self): + reply_mock = MagicMock() + device_mock = MagicMock() reply_mock.attribute.return_value = 200 reply_mock.readAll.return_value = QByteArray(b"Six sick hicks nick six slick bricks with picks and sticks.") job = SendMaterialJob(device_mock) @@ -88,7 +132,9 @@ class TestSendMaterialJob(TestCase): # Given that the parsing fails we do no expect the device to be called for any follow up. self.assertEqual(0, device_mock.createFormPart.call_count) - def test__onGetRemoteMaterials_withMissingGuidInRemoteMaterial(self, reply_mock, device_mock): + def test__onGetRemoteMaterials_withMissingGuidInRemoteMaterial(self): + reply_mock = MagicMock() + device_mock = MagicMock() reply_mock.attribute.return_value = 200 remote_material_without_guid = self._REMOTE_MATERIAL_WHITE.copy() del remote_material_without_guid["guid"] @@ -99,18 +145,20 @@ class TestSendMaterialJob(TestCase): # Given that parsing fails we do not expect the device to be called for any follow up. self.assertEqual(0, device_mock.createFormPart.call_count) + @patch("cura.Machines.MaterialManager.MaterialManager") @patch("cura.Settings.CuraContainerRegistry") @patch("UM.Application") def test__onGetRemoteMaterials_withInvalidVersionInLocalMaterial(self, application_mock, container_registry_mock, - reply_mock, device_mock): + material_manager_mock): + reply_mock = MagicMock() + device_mock = MagicMock() + application_mock.getContainerRegistry.return_value = container_registry_mock + application_mock.getMaterialManager.return_value = material_manager_mock + reply_mock.attribute.return_value = 200 reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTE_MATERIAL_WHITE]).encode("ascii")) - localMaterialWhiteWithInvalidVersion = self._LOCAL_MATERIAL_WHITE.copy() - localMaterialWhiteWithInvalidVersion["version"] = "one" - container_registry_mock.findContainersMetadata.return_value = [localMaterialWhiteWithInvalidVersion] - - application_mock.getContainerRegistry.return_value = container_registry_mock + material_manager_mock.getAllMaterialGroups.return_value = self._LOCAL_MATERIAL_WHITE_INVALID_VERSION_ALL_RESULT.copy() with mock.patch.object(Application, "getInstance", new = lambda: application_mock): job = SendMaterialJob(device_mock) @@ -118,15 +166,19 @@ class TestSendMaterialJob(TestCase): self.assertEqual(0, device_mock.createFormPart.call_count) + @patch("cura.Machines.MaterialManager") @patch("cura.Settings.CuraContainerRegistry") @patch("UM.Application") - def test__onGetRemoteMaterials_withNoUpdate(self, application_mock, container_registry_mock, reply_mock, - device_mock): + def test__onGetRemoteMaterials_withNoUpdate(self, application_mock, container_registry_mock, + material_manager_mock): + reply_mock = MagicMock() + device_mock = MagicMock() application_mock.getContainerRegistry.return_value = container_registry_mock + application_mock.getMaterialManager.return_value = material_manager_mock device_mock.createFormPart.return_value = "_xXx_" - container_registry_mock.findContainersMetadata.return_value = [self._LOCAL_MATERIAL_WHITE] + material_manager_mock.getAllMaterialGroups.return_value = self._LOCAL_MATERIAL_WHITE_ALL_RESULT.copy() reply_mock.attribute.return_value = 200 reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTE_MATERIAL_WHITE]).encode("ascii")) @@ -138,24 +190,25 @@ class TestSendMaterialJob(TestCase): self.assertEqual(0, device_mock.createFormPart.call_count) self.assertEqual(0, device_mock.postFormWithParts.call_count) - @patch("cura.Settings.CuraContainerRegistry") - @patch("UM.Application") - def test__onGetRemoteMaterials_withUpdatedMaterial(self, application_mock, container_registry_mock, reply_mock, - device_mock): - application_mock.getContainerRegistry.return_value = container_registry_mock + @patch("UM.Application.Application.getInstance") + def test__onGetRemoteMaterials_withUpdatedMaterial(self, get_instance_mock): + reply_mock = MagicMock() + device_mock = MagicMock() + application_mock = get_instance_mock.return_value + container_registry_mock = application_mock.getContainerRegistry.return_value + material_manager_mock = application_mock.getMaterialManager.return_value + + container_registry_mock.getContainerFilePathById = lambda x: _FILES_MAP.get(x) device_mock.createFormPart.return_value = "_xXx_" - localMaterialWhiteWithHigherVersion = self._LOCAL_MATERIAL_WHITE.copy() - localMaterialWhiteWithHigherVersion["version"] = "2" - container_registry_mock.findContainersMetadata.return_value = [localMaterialWhiteWithHigherVersion] + material_manager_mock.getAllMaterialGroups.return_value = self._LOCAL_MATERIAL_WHITE_NEWER_ALL_RESULT.copy() reply_mock.attribute.return_value = 200 reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTE_MATERIAL_WHITE]).encode("ascii")) - with mock.patch.object(Application, "getInstance", new = lambda: application_mock): - job = SendMaterialJob(device_mock) - job._onGetRemoteMaterials(reply_mock) + job = SendMaterialJob(device_mock) + job._onGetRemoteMaterials(reply_mock) self.assertEqual(1, device_mock.createFormPart.call_count) self.assertEqual(1, device_mock.postFormWithParts.call_count) @@ -164,16 +217,24 @@ class TestSendMaterialJob(TestCase): call.postFormWithParts(target = "materials/", parts = ["_xXx_"], on_finished = job.sendingFinished)], device_mock.method_calls) + @patch("cura.Machines.MaterialManager.MaterialManager") @patch("cura.Settings.CuraContainerRegistry") @patch("UM.Application") - def test__onGetRemoteMaterials_withNewMaterial(self, application_mock, container_registry_mock, reply_mock, - device_mock): + def test__onGetRemoteMaterials_withNewMaterial(self, application_mock, container_registry_mock, + material_manager_mock): + reply_mock = MagicMock() + device_mock = MagicMock() application_mock.getContainerRegistry.return_value = container_registry_mock + application_mock.getMaterialManager.return_value = material_manager_mock + + container_registry_mock.getContainerFilePathById = lambda x: _FILES_MAP.get(x) device_mock.createFormPart.return_value = "_xXx_" - container_registry_mock.findContainersMetadata.return_value = [self._LOCAL_MATERIAL_WHITE, - self._LOCAL_MATERIAL_BLACK] + all_results = self._LOCAL_MATERIAL_WHITE_ALL_RESULT.copy() + for key, value in self._LOCAL_MATERIAL_BLACK_ALL_RESULT.items(): + all_results[key] = value + material_manager_mock.getAllMaterialGroups.return_value = all_results reply_mock.attribute.return_value = 200 reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTE_MATERIAL_BLACK]).encode("ascii")) From 346d8d884e3f39e8aaae740ca1dcbf26022b3e0f Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 20 Dec 2018 14:23:37 +0100 Subject: [PATCH 1071/1292] Remove unnecessary patches in TestSendMaterialJob CURA-6035 --- .../tests/TestSendMaterialJob.py | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py index 4303f89c20..6eac892af6 100644 --- a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py @@ -166,15 +166,12 @@ class TestSendMaterialJob(TestCase): self.assertEqual(0, device_mock.createFormPart.call_count) - @patch("cura.Machines.MaterialManager") - @patch("cura.Settings.CuraContainerRegistry") - @patch("UM.Application") - def test__onGetRemoteMaterials_withNoUpdate(self, application_mock, container_registry_mock, - material_manager_mock): + @patch("UM.Application.Application.getInstance") + def test__onGetRemoteMaterials_withNoUpdate(self, application_mock): reply_mock = MagicMock() device_mock = MagicMock() - application_mock.getContainerRegistry.return_value = container_registry_mock - application_mock.getMaterialManager.return_value = material_manager_mock + container_registry_mock = application_mock.getContainerRegistry.return_value + material_manager_mock = application_mock.getMaterialManager.return_value device_mock.createFormPart.return_value = "_xXx_" @@ -217,15 +214,12 @@ class TestSendMaterialJob(TestCase): call.postFormWithParts(target = "materials/", parts = ["_xXx_"], on_finished = job.sendingFinished)], device_mock.method_calls) - @patch("cura.Machines.MaterialManager.MaterialManager") - @patch("cura.Settings.CuraContainerRegistry") - @patch("UM.Application") - def test__onGetRemoteMaterials_withNewMaterial(self, application_mock, container_registry_mock, - material_manager_mock): + @patch("UM.Application.Application.getInstance") + def test__onGetRemoteMaterials_withNewMaterial(self, application_mock): reply_mock = MagicMock() device_mock = MagicMock() - application_mock.getContainerRegistry.return_value = container_registry_mock - application_mock.getMaterialManager.return_value = material_manager_mock + container_registry_mock = application_mock.getContainerRegistry.return_value + material_manager_mock = application_mock.getMaterialManager.return_value container_registry_mock.getContainerFilePathById = lambda x: _FILES_MAP.get(x) From af2061cd52ec05cd9f25f07c6f858e2b81194fc8 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Thu, 20 Dec 2018 14:26:30 +0100 Subject: [PATCH 1072/1292] Simplify some checks for connection types and group size --- cura/Settings/MachineManager.py | 13 ++++++--- .../src/Cloud/CloudOutputDeviceManager.py | 7 +++-- .../qml/PrinterSelector/MachineSelector.qml | 29 ++++++++++++------- 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 66ee7f9543..b5f8420b97 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -527,10 +527,15 @@ class MachineManager(QObject): @pyqtProperty(bool, notify = printerConnectedStatusChanged) def activeMachineHasRemoteConnection(self) -> bool: - if self._global_container_stack: - connection_type = self._global_container_stack.getMetaDataEntry("connection_type") - return connection_type in [ConnectionType.NetworkConnection.value, ConnectionType.CloudConnection.value] - return False + return self.activeMachineHasActiveNetworkConnection or self.activeMachineHasActiveCloudConnection + # if self._global_container_stack: + # connection_type = self._global_container_stack.getMetaDataEntry("connection_type") + # return connection_type in [ConnectionType.NetworkConnection.value, ConnectionType.CloudConnection.value] + # return False + + @pyqtProperty(bool, notify = printerConnectedStatusChanged) + def activeMachineIsGroup(self) -> bool: + return self._printer_output_devices and self._printer_output_devices[0].clusterSize > 1 @pyqtProperty(bool, notify = printerConnectedStatusChanged) def activeMachineHasActiveNetworkConnection(self) -> bool: diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index af45f06394..c849ebfe4a 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -121,10 +121,11 @@ class CloudOutputDeviceManager: return device = next((c for c in self._remote_clusters.values() if c.matchesNetworkKey(local_network_key)), None) - if device: - active_machine.setMetaDataEntry(self.META_CLUSTER_ID, device.key) - device.connect() + if not device: + return + active_machine.setMetaDataEntry(self.META_CLUSTER_ID, device.key) + device.connect() Logger.log("i", "Found cluster %s with network key %s", device, local_network_key) ## Handles an API error received from the cloud. diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index 64cf3e6005..c39acb53e7 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -11,10 +11,9 @@ Cura.ExpandablePopup { id: machineSelector - property var outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null - property bool isPrinterConnected: Cura.MachineManager.printerConnected property bool isNetworkPrinter: Cura.MachineManager.activeMachineHasActiveNetworkConnection property bool isCloudPrinter: Cura.MachineManager.activeMachineHasActiveCloudConnection + property bool isGroup: Cura.MachineManager.activeMachineIsGroup contentPadding: UM.Theme.getSize("default_lining").width contentAlignment: Cura.ExpandablePopup.ContentAlignment.AlignLeft @@ -30,15 +29,13 @@ Cura.ExpandablePopup text: isNetworkPrinter ? Cura.MachineManager.activeMachineNetworkGroupName : Cura.MachineManager.activeMachineName source: { - if (isNetworkPrinter) - { - if (machineSelector.outputDevice != null && machineSelector.outputDevice.clusterSize > 1) - { - return UM.Theme.getIcon("printer_group") - } + if (isGroup) { + return UM.Theme.getIcon("printer_group") + } else if (isNetworkPrinter || isCloudPrinter) { return UM.Theme.getIcon("printer_single") + } else { + return "" } - return "" } font: UM.Theme.getFont("medium") iconColor: UM.Theme.getColor("machine_selector_printer_icon") @@ -53,12 +50,22 @@ Cura.ExpandablePopup leftMargin: UM.Theme.getSize("thick_margin").width } - source: machineSelector.isCloudPrinter ? UM.Theme.getIcon("printer_cloud_connected") : UM.Theme.getIcon("printer_connected") + source: + { + if (isNetworkPrinter) { + return UM.Theme.getIcon("printer_connected") + } else if (isCloudPrinter) { + return UM.Theme.getIcon("printer_cloud_connected") + } else { + return "" + } + } + width: UM.Theme.getSize("printer_status_icon").width height: UM.Theme.getSize("printer_status_icon").height color: UM.Theme.getColor("primary") - visible: isNetworkPrinter && isPrinterConnected + visible: isNetworkPrinter || isCloudPrinter // Make a themable circle in the background so we can change it in other themes Rectangle From bbddbcde9a780660c603d080ca903af1a9949654 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Thu, 20 Dec 2018 14:29:39 +0100 Subject: [PATCH 1073/1292] cleanup --- cura/Settings/MachineManager.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index b5f8420b97..1cb9af02d1 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -528,10 +528,6 @@ class MachineManager(QObject): @pyqtProperty(bool, notify = printerConnectedStatusChanged) def activeMachineHasRemoteConnection(self) -> bool: return self.activeMachineHasActiveNetworkConnection or self.activeMachineHasActiveCloudConnection - # if self._global_container_stack: - # connection_type = self._global_container_stack.getMetaDataEntry("connection_type") - # return connection_type in [ConnectionType.NetworkConnection.value, ConnectionType.CloudConnection.value] - # return False @pyqtProperty(bool, notify = printerConnectedStatusChanged) def activeMachineIsGroup(self) -> bool: From f3a0b44d5ebfb7a69d54cf1610a50eeec0285941 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 20 Dec 2018 14:24:00 +0100 Subject: [PATCH 1074/1292] Simplify is_favorite condition No stupid ternary operators necessary. Contributes to issue CURA-6032. --- resources/qml/Preferences/Materials/MaterialsSlot.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Preferences/Materials/MaterialsSlot.qml b/resources/qml/Preferences/Materials/MaterialsSlot.qml index fb3cb9607d..7c891dc65f 100644 --- a/resources/qml/Preferences/Materials/MaterialsSlot.qml +++ b/resources/qml/Preferences/Materials/MaterialsSlot.qml @@ -15,7 +15,7 @@ Rectangle id: materialSlot property var material: null property var hovered: false - property var is_favorite: material != null ? material.is_favorite : false + property var is_favorite: material != null && material.is_favorite height: UM.Theme.getSize("favorites_row").height width: parent.width From 5bf260f5247f1367d0bf100514d596f4b8d4cfee Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 20 Dec 2018 14:25:52 +0100 Subject: [PATCH 1075/1292] Don't break binding of is_favorite upon clicking star We shouldn't override it here because doing that causes the binding to break. Just remove the favourite and let the model update itself, thus removing the star. Contributes to issue CURA-6032. --- resources/qml/Preferences/Materials/MaterialsSlot.qml | 2 -- 1 file changed, 2 deletions(-) diff --git a/resources/qml/Preferences/Materials/MaterialsSlot.qml b/resources/qml/Preferences/Materials/MaterialsSlot.qml index 7c891dc65f..2f4847103b 100644 --- a/resources/qml/Preferences/Materials/MaterialsSlot.qml +++ b/resources/qml/Preferences/Materials/MaterialsSlot.qml @@ -73,11 +73,9 @@ Rectangle if (materialSlot.is_favorite) { base.materialManager.removeFavorite(material.root_material_id) - materialSlot.is_favorite = false return } base.materialManager.addFavorite(material.root_material_id) - materialSlot.is_favorite = true return } style: ButtonStyle From 1012eb7553db8f2246c0a94c21faa1012a9d2555 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Thu, 20 Dec 2018 14:48:56 +0100 Subject: [PATCH 1076/1292] Assure bool --- cura/Settings/MachineManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 1cb9af02d1..c87ddf2f80 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -531,7 +531,7 @@ class MachineManager(QObject): @pyqtProperty(bool, notify = printerConnectedStatusChanged) def activeMachineIsGroup(self) -> bool: - return self._printer_output_devices and self._printer_output_devices[0].clusterSize > 1 + return bool(self._printer_output_devices) and self._printer_output_devices[0].clusterSize > 1 @pyqtProperty(bool, notify = printerConnectedStatusChanged) def activeMachineHasActiveNetworkConnection(self) -> bool: From 119d3e9974780708516f88e760b4ea3d1dd3e665 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Thu, 20 Dec 2018 15:47:48 +0100 Subject: [PATCH 1077/1292] Fix printer selector sections --- cura/PrintersModel.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cura/PrintersModel.py b/cura/PrintersModel.py index 8b5d2f6cc9..77df73505d 100644 --- a/cura/PrintersModel.py +++ b/cura/PrintersModel.py @@ -53,9 +53,8 @@ class PrintersModel(ListModel): container_stacks = ContainerRegistry.getInstance().findContainerStacks(type = "machine") for container_stack in container_stacks: - connection_type = container_stack.getMetaDataEntry("connection_type") - has_remote_connection = connection_type in [ConnectionType.NetworkConnection.value, ConnectionType.CloudConnection.value] - + connection_type = container_stack.getMetaDataEntry("connection_type", 0) + has_remote_connection = int(connection_type) in [ConnectionType.NetworkConnection.value, ConnectionType.CloudConnection.value] if container_stack.getMetaDataEntry("hidden", False) in ["True", True]: continue From 3f82cd491697588c8ffcd58cf611fa9c845439ae Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Thu, 20 Dec 2018 15:55:04 +0100 Subject: [PATCH 1078/1292] Add missing new-line --- cura/PrintersModel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/PrintersModel.py b/cura/PrintersModel.py index 77df73505d..f05697d2b5 100644 --- a/cura/PrintersModel.py +++ b/cura/PrintersModel.py @@ -65,4 +65,4 @@ class PrintersModel(ListModel): "connectionType": connection_type, "metadata": container_stack.getMetaData().copy()}) items.sort(key=lambda i: not i["hasRemoteConnection"]) - self.setItems(items) \ No newline at end of file + self.setItems(items) From 3f599bd06f817ad39aaeb9d50b6939760e5505ea Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 20 Dec 2018 16:31:57 +0100 Subject: [PATCH 1079/1292] Ensure that the tooltip text is translated CURA-6004 --- resources/qml/ActionPanel/SliceProcessWidget.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index ab5e224c90..79c0186443 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -109,7 +109,7 @@ Column fixedWidthMode: true anchors.fill: parent text: catalog.i18nc("@button", "Slice") - tooltip: "Start slicing process" + tooltip: catalog.i18nc("@label", "Start the slicing process") enabled: widget.backendState != UM.Backend.Error visible: widget.backendState == UM.Backend.NotStarted || widget.backendState == UM.Backend.Error onClicked: sliceOrStopSlicing() From 403010aa90184a7977648d0d0701791ef5d33a1b Mon Sep 17 00:00:00 2001 From: Marijn Dee Date: Thu, 20 Dec 2018 16:32:00 +0100 Subject: [PATCH 1080/1292] Mirrored the changes made to the models in Commons --- .../Cloud/Models/CloudClusterBuildPlate.py | 13 +++++ ... => CloudClusterPrintCoreConfiguration.py} | 5 +- ...CloudClusterPrintJobConfigurationChange.py | 28 +++++++++ .../Models/CloudClusterPrintJobImpediment.py | 15 +++++ .../Models/CloudClusterPrintJobStatus.py | 58 ++++++++++++++++--- .../Cloud/Models/CloudClusterPrinterStatus.py | 20 +++++-- 6 files changed, 124 insertions(+), 15 deletions(-) create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterBuildPlate.py rename plugins/UM3NetworkPrinting/src/Cloud/Models/{CloudClusterPrinterConfiguration.py => CloudClusterPrintCoreConfiguration.py} (92%) create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobConfigurationChange.py create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobImpediment.py diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterBuildPlate.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterBuildPlate.py new file mode 100644 index 0000000000..4386bbb435 --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterBuildPlate.py @@ -0,0 +1,13 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +from .BaseCloudModel import BaseCloudModel + + +## Class representing a cluster printer +# Spec: https://api-staging.ultimaker.com/connect/v1/spec +class CloudClusterBuildPlate(BaseCloudModel): + ## Create a new build plate + # \param type: The type of buildplate glass or aluminium + def __init__(self, type: str = "glass", **kwargs) -> None: + self.type = type + super().__init__(**kwargs) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintCoreConfiguration.py similarity index 92% rename from plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py rename to plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintCoreConfiguration.py index 3e06d0e2e7..7454401d09 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintCoreConfiguration.py @@ -10,7 +10,7 @@ from .BaseCloudModel import BaseCloudModel ## Class representing a cloud cluster printer configuration # Spec: https://api-staging.ultimaker.com/connect/v1/spec -class CloudClusterPrinterConfiguration(BaseCloudModel): +class CloudClusterPrintCoreConfiguration(BaseCloudModel): ## Creates a new cloud cluster printer configuration object # \param extruder_index: The position of the extruder on the machine as list index. Numbered from left to right. # \param material: The material of a configuration object in a cluster printer. May be in a dict or an object. @@ -18,10 +18,9 @@ class CloudClusterPrinterConfiguration(BaseCloudModel): # \param print_core_id: The type of print core inserted at this position, e.g. 'AA 0.4'. def __init__(self, extruder_index: int, material: Union[None, Dict[str, Any], CloudClusterPrinterConfigurationMaterial], - nozzle_diameter: Optional[str] = None, print_core_id: Optional[str] = None, **kwargs) -> None: + print_core_id: Optional[str] = None, **kwargs) -> None: self.extruder_index = extruder_index self.material = self.parseModel(CloudClusterPrinterConfigurationMaterial, material) if material else None - self.nozzle_diameter = nozzle_diameter self.print_core_id = print_core_id super().__init__(**kwargs) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobConfigurationChange.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobConfigurationChange.py new file mode 100644 index 0000000000..6c02972757 --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobConfigurationChange.py @@ -0,0 +1,28 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +from typing import Optional + +from .BaseCloudModel import BaseCloudModel + + +## Model for the types of changes that are needed before a print job can start +# Spec: https://api-staging.ultimaker.com/connect/v1/spec +class CloudClusterPrintJobConfigurationChange(BaseCloudModel): + ## Creates a new print job constraint. + # \param type_of_change: The type of configuration change, one of: "material", "print_core_change" + # \param index: The hotend slot or extruder index to change + # \param target_id: Target material guid or hotend id + # \param origin_id: Original/current material guid or hotend id + # \param target_name: Target material name or hotend id + # \param origin_name: Original/current material name or hotend id + def __init__(self, type_of_change: Optional[str] = None, index: Optional[int] = None, + target_id: Optional[str] = None,origin_id: Optional[str] = None, + target_name: Optional[str] = None,origin_name: Optional[str] = None, + **kwargs) -> None: + self.type_of_change = type_of_change + self.index = index + self.target_id = target_id + self.origin_id = origin_id + self.target_name = target_name + self.origin_name = origin_name + super().__init__(**kwargs) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobImpediment.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobImpediment.py new file mode 100644 index 0000000000..12b67996c1 --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobImpediment.py @@ -0,0 +1,15 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +from .BaseCloudModel import BaseCloudModel + + +## Class representing the reasons that prevent this job from being printed on the associated printer +# Spec: https://api-staging.ultimaker.com/connect/v1/spec +class CloudClusterPrintJobImpediment(BaseCloudModel): + ## Creates a new print job constraint. + # \param translation_key: A string indicating a reason the print cannot be printed, such as 'does_not_fit_in_build_volume' + # \param severity: A number indicating the severity of the problem, with higher being more severe + def __init__(self, translation_key: str, severity: int, **kwargs) -> None: + self.translation_key = translation_key + self.severity = severity + super().__init__(**kwargs) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py index f451665a4f..4b70d191e4 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py @@ -4,11 +4,14 @@ from typing import List, Optional, Union, Dict, Any from cura.PrinterOutput.ConfigurationModel import ConfigurationModel from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputController import CloudOutputController -from .CloudClusterPrinterConfiguration import CloudClusterPrinterConfiguration +from src.ConfigurationChangeModel import ConfigurationChangeModel +from .CloudClusterBuildPlate import CloudClusterBuildPlate +from .CloudClusterPrintJobConfigurationChange import CloudClusterPrintJobConfigurationChange +from .CloudClusterPrintJobImpediment import CloudClusterPrintJobImpediment +from .CloudClusterPrintCoreConfiguration import CloudClusterPrintCoreConfiguration from .CloudClusterPrintJobConstraint import CloudClusterPrintJobConstraints from .BaseCloudModel import BaseCloudModel - ## Class representing a print job from plugins.UM3NetworkPrinting.src.UM3PrintJobOutputModel import UM3PrintJobOutputModel @@ -34,15 +37,29 @@ class CloudClusterPrintJobStatus(BaseCloudModel): # \param time_elapsed: The remaining printing time in seconds. # \param time_total: The total printing time in seconds. # \param uuid: UUID of this print job. Should be used for identification purposes. + # \param deleted_at: The time when this print job was deleted. + # \param printed_on_uuid: UUID of the printer used to print this job. + # \param configuration_changes_required: List of configuration changes the printer this job is associated with + # needs to make in order to be able to print this job + # \param build_plate: The build plate (type) this job needs to be printed on. + # \param compatible_machine_families: Family names of machines suitable for this print job + # \param impediments_to_printing: A list of reasons that prevent this job from being printed on the associated + # printer def __init__(self, created_at: str, force: bool, machine_variant: str, name: str, started: bool, status: str, time_total: int, uuid: str, - configuration: List[Union[Dict[str, Any], CloudClusterPrinterConfiguration]], + configuration: List[Union[Dict[str, Any], CloudClusterPrintCoreConfiguration]], constraints: List[Union[Dict[str, Any], CloudClusterPrintJobConstraints]], last_seen: Optional[float] = None, network_error_count: Optional[int] = None, owner: Optional[str] = None, printer_uuid: Optional[str] = None, time_elapsed: Optional[int] = None, - assigned_to: Optional[str] = None, **kwargs) -> None: + assigned_to: Optional[str] = None, deleted_at: Optional[str] = None, + printed_on_uuid: Optional[str] = None, + configuration_changes_required: List[ + Union[Dict[str, Any], CloudClusterPrintJobConfigurationChange]] = None, + build_plate: Optional[str] = None, compatible_machine_families: List[str] = None, + impediments_to_printing: List[Union[Dict[str, Any], CloudClusterPrintJobImpediment]] = None, + **kwargs) -> None: self.assigned_to = assigned_to - self.configuration = self.parseModels(CloudClusterPrinterConfiguration, configuration) + self.configuration = self.parseModels(CloudClusterPrintCoreConfiguration, configuration) self.constraints = self.parseModels(CloudClusterPrintJobConstraints, constraints) self.created_at = created_at self.force = force @@ -57,6 +74,14 @@ class CloudClusterPrintJobStatus(BaseCloudModel): self.time_elapsed = time_elapsed self.time_total = time_total self.uuid = uuid + self.deleted_at = deleted_at + self.printed_on_uuid = printed_on_uuid + self.configuration_changes_required = self.parseModels(CloudClusterPrintJobConfigurationChange, + configuration_changes_required) + self.build_plate = self.parseModel(CloudClusterBuildPlate, build_plate) + self.compatible_machine_families = compatible_machine_families + self.impediments_to_printing = self.parseModels(CloudClusterPrintJobImpediment, impediments_to_printing) + super().__init__(**kwargs) ## Creates an UM3 print job output model based on this cloud cluster print job. @@ -77,11 +102,28 @@ class CloudClusterPrintJobStatus(BaseCloudModel): ## Updates an UM3 print job output model based on this cloud cluster print job. # \param model: The model to update. def updateOutputModel(self, model: UM3PrintJobOutputModel) -> None: - # TODO: Add `compatible_machine_families` to the cloud, than add model.setCompatibleMachineFamilies() - # TODO: Add `impediments_to_printing` to the cloud, see ClusterUM3OutputDevice._updatePrintJob - # TODO: Use model.updateConfigurationChanges, see ClusterUM3OutputDevice#_createConfigurationChanges model.updateConfiguration(self._createConfigurationModel()) model.updateTimeTotal(self.time_total) model.updateTimeElapsed(self.time_elapsed) model.updateOwner(self.owner) model.updateState(self.status) + model.setCompatibleMachineFamilies(self.compatible_machine_families) + model.updateTimeTotal(self.time_total) + model.updateTimeElapsed(self.time_elapsed) + model.updateOwner(self.owner) + + status_set_by_impediment = False + for impediment in self.impediments_to_printing: + if impediment.severity == "UNFIXABLE": # TODO: impediment.severity is defined as int, this will not work, is there a translation? + status_set_by_impediment = True + model.updateState("error") + break + + if not status_set_by_impediment: + model.updateState(self.status) + + model.updateConfigurationChanges([ConfigurationChangeModel(type_of_change=change.type_of_change, + index=change.index, + target_name=change.target_name, + origin_name=change.origin_name) + for change in self.configuration_changes_required]) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterStatus.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterStatus.py index cd3b6bbdca..23409a761d 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterStatus.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterStatus.py @@ -4,7 +4,8 @@ from typing import List, Union, Dict, Optional, Any from cura.PrinterOutput.PrinterOutputController import PrinterOutputController from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel -from .CloudClusterPrinterConfiguration import CloudClusterPrinterConfiguration +from .CloudClusterBuildPlate import CloudClusterBuildPlate +from .CloudClusterPrintCoreConfiguration import CloudClusterPrintCoreConfiguration from .BaseCloudModel import BaseCloudModel @@ -22,12 +23,19 @@ class CloudClusterPrinterStatus(BaseCloudModel): # \param uuid: The unique ID of the printer, also known as GUID. # \param configuration: The active print core configurations of this printer. # \param reserved_by: A printer can be claimed by a specific print job. + # \param maintenance_required: Indicates if maintenance is necessary + # \param firmware_update_status: Whether the printer's firmware is up-to-date, value is one of: "up_to_date", + # "pending_update", "update_available", "update_in_progress", "update_failed", "update_impossible" + # \param latest_available_firmware: The version of the latest firmware that is available + # \param build_plate: The build plate that is on the printer def __init__(self, enabled: bool, firmware_version: str, friendly_name: str, ip_address: str, machine_variant: str, status: str, unique_name: str, uuid: str, - configuration: List[Union[Dict[str, Any], CloudClusterPrinterConfiguration]], - reserved_by: Optional[str] = None, **kwargs) -> None: + configuration: List[Union[Dict[str, Any], CloudClusterPrintCoreConfiguration]], + reserved_by: Optional[str] = None, maintenance_required: Optional[bool] = None, + firmware_update_status: Optional[str] = None, latest_available_firmware: Optional[str] = None, + build_plate: Optional[str] = None, **kwargs) -> None: - self.configuration = self.parseModels(CloudClusterPrinterConfiguration, configuration) + self.configuration = self.parseModels(CloudClusterPrintCoreConfiguration, configuration) self.enabled = enabled self.firmware_version = firmware_version self.friendly_name = friendly_name @@ -37,6 +45,10 @@ class CloudClusterPrinterStatus(BaseCloudModel): self.unique_name = unique_name self.uuid = uuid self.reserved_by = reserved_by + self.maintenance_required = maintenance_required + self.firmware_update_status = firmware_update_status + self.latest_available_firmware = latest_available_firmware + self.build_plate = self.parseModel(CloudClusterBuildPlate, build_plate) super().__init__(**kwargs) ## Creates a new output model. From 0965d909c09bdc27acb6c04084f35a7d5fac6ed5 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 20 Dec 2018 16:41:26 +0100 Subject: [PATCH 1081/1292] Remove the show property from the tooltip This was a bit of a weird setup, so i removed it. This way the tooltip can be used in the same way as the regular tooltip (by simply setting the visibility) CURA-6004 --- resources/qml/ActionButton.qml | 2 +- resources/qml/ToolTip.qml | 11 ++++------- resources/qml/ToolbarButton.qml | 2 +- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index 9ceade6a57..6cab04e5ec 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -115,6 +115,6 @@ Button Cura.ToolTip { id: tooltip - show: button.hovered + visible: button.hovered } } \ No newline at end of file diff --git a/resources/qml/ToolTip.qml b/resources/qml/ToolTip.qml index 5e7d436d70..87586f76d8 100644 --- a/resources/qml/ToolTip.qml +++ b/resources/qml/ToolTip.qml @@ -9,28 +9,25 @@ import Cura 1.0 as Cura ToolTip { - enum ContentAlignment { AlignLeft, AlignRight } - // This property indicates when the tooltip has to show, for instance when a button is hovered - property bool show: false - // Defines the alignment of the content, by default to the left property int contentAlignment: Cura.ToolTip.ContentAlignment.AlignRight property alias tooltipText: tooltip.text property var targetPoint: Qt.point(parent.x, y + Math.round(height/2)) - id: tooltip text: "" delay: 500 - visible: text != "" && show font: UM.Theme.getFont("default") + + // If the text is not set, just set the height to 0 to prevent it from showing + height: text != "" ? label.contentHeight + 2 * UM.Theme.getSize("thin_margin").width: 0 x: { @@ -43,7 +40,7 @@ ToolTip y: Math.round(parent.height / 2 - label.height / 2 ) - padding - padding: 2 + padding: UM.Theme.getSize("thin_margin").width background: UM.PointingRectangle { diff --git a/resources/qml/ToolbarButton.qml b/resources/qml/ToolbarButton.qml index 307d49302c..b3f84bba1d 100644 --- a/resources/qml/ToolbarButton.qml +++ b/resources/qml/ToolbarButton.qml @@ -101,6 +101,6 @@ Button { id: tooltip tooltipText: base.text - show: base.hovered + visible: base.hovered } } From 9d27c29c8ccd5bc09d54dd9f0a90f474cf643c18 Mon Sep 17 00:00:00 2001 From: Marijn Dee Date: Thu, 20 Dec 2018 17:04:17 +0100 Subject: [PATCH 1082/1292] Fixed indentation and relative import, tests still fail though --- .../src/Cloud/Models/CloudClusterPrintJobStatus.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py index 4b70d191e4..5b7ef7c18a 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py @@ -4,7 +4,7 @@ from typing import List, Optional, Union, Dict, Any from cura.PrinterOutput.ConfigurationModel import ConfigurationModel from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputController import CloudOutputController -from src.ConfigurationChangeModel import ConfigurationChangeModel +from plugins.UM3NetworkPrinting.src.ConfigurationChangeModel import ConfigurationChangeModel from .CloudClusterBuildPlate import CloudClusterBuildPlate from .CloudClusterPrintJobConfigurationChange import CloudClusterPrintJobConfigurationChange from .CloudClusterPrintJobImpediment import CloudClusterPrintJobImpediment @@ -122,8 +122,10 @@ class CloudClusterPrintJobStatus(BaseCloudModel): if not status_set_by_impediment: model.updateState(self.status) - model.updateConfigurationChanges([ConfigurationChangeModel(type_of_change=change.type_of_change, - index=change.index, - target_name=change.target_name, - origin_name=change.origin_name) - for change in self.configuration_changes_required]) + model.updateConfigurationChanges( + [ConfigurationChangeModel( + type_of_change=change.type_of_change, + index=change.index, + target_name=change.target_name, + origin_name=change.origin_name) + for change in self.configuration_changes_required]) From 5403f5241b44684ec6b857fa86c97f8d593a7527 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Thu, 20 Dec 2018 17:21:07 +0100 Subject: [PATCH 1083/1292] Fix not registering cloud output device for every machine --- .../src/Cloud/CloudOutputDeviceManager.py | 22 +++++++++++++------ .../src/ClusterUM3OutputDevice.py | 5 +++-- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index c849ebfe4a..b1dc13e34f 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -88,7 +88,6 @@ class CloudOutputDeviceManager: # We only add when is_online as we don't want the option in the drop down if the cluster is not online. for added_cluster in added_clusters: device = CloudOutputDevice(self._api, added_cluster) - self._output_device_manager.addOutputDevice(device) self._remote_clusters[added_cluster.cluster_id] = device for device, cluster in updates: @@ -103,17 +102,20 @@ class CloudOutputDeviceManager: Logger.log("d", "no active machine") return + # Remove all output devices that we have registered. + for stored_cluster_id in self._remote_clusters: + self._output_device_manager.removeOutputDevice(stored_cluster_id) + # Check if the stored cluster_id for the active machine is in our list of remote clusters. stored_cluster_id = active_machine.getMetaDataEntry(self.META_CLUSTER_ID) if stored_cluster_id in self._remote_clusters: device = self._remote_clusters[stored_cluster_id] - if not device.isConnected(): - device.connect() - Logger.log("d", "Device connected by metadata %s", stored_cluster_id) + self._connectToOutputDevice(device) + Logger.log("d", "Device connected by metadata cluster ID %s", stored_cluster_id) else: self._connectByNetworkKey(active_machine) - ## Tries to match the + ## Tries to match the local network key to the cloud cluster host name. def _connectByNetworkKey(self, active_machine: GlobalStack) -> None: # Check if the active printer has a local network connection and match this key to the remote cluster. local_network_key = active_machine.getMetaDataEntry("um_network_key") @@ -124,9 +126,15 @@ class CloudOutputDeviceManager: if not device: return - active_machine.setMetaDataEntry(self.META_CLUSTER_ID, device.key) - device.connect() Logger.log("i", "Found cluster %s with network key %s", device, local_network_key) + active_machine.setMetaDataEntry(self.META_CLUSTER_ID, device.key) + self._connectToOutputDevice(device) + + ## Connects to an output device and makes sure it is registered in the output device manager. + def _connectToOutputDevice(self, device: CloudOutputDevice) -> None: + if not device.isConnected(): + device.connect() + self._output_device_manager.addOutputDevice(device) ## Handles an API error received from the cloud. # \param errors: The errors received diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index 75fd1e0f9e..a1931c428a 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -389,8 +389,9 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): ## Called when the connection to the cluster changes. def connect(self) -> None: - super().connect() - self.sendMaterialProfiles() + # super().connect() + # self.sendMaterialProfiles() + pass def _onGetPreviewImageFinished(self, reply: QNetworkReply) -> None: reply_url = reply.url().toString() From 7cfb29e337ae47884c0faf80be7394ea19ddb604 Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Thu, 20 Dec 2018 18:12:40 +0100 Subject: [PATCH 1084/1292] If a connected printer has a selected material which is unknown for Cura then show a message for downloading it from Marketplace CURA-6033 --- .../ConfigurationMenu/ConfigurationItem.qml | 104 +++++++++++++++++- 1 file changed, 102 insertions(+), 2 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 862e1475a9..16d683adca 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -14,6 +14,23 @@ Button property var configuration: null hoverEnabled: true + property bool isValidMaterial: + { + var extruderConfigurations = configuration.extruderConfigurations + + for (var index = 0; index < extruderConfigurations.length; index++) + { + var name = extruderConfigurations[index].material.brand ? extruderConfigurations[index].material.name : "" + + if (name == "" || name == "Unknown") + { + hoverEnabled = false + return false + } + } + return true + } + background: Rectangle { color: parent.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") @@ -40,19 +57,102 @@ Button right: parent.right rightMargin: UM.Theme.getSize("wide_margin").width } - + height: childrenRect.height spacing: UM.Theme.getSize("default_margin").width Repeater { id: repeater - model: configuration.extruderConfigurations + model: + { + if (configurationItem.isValidMaterial) + { + return configuration.extruderConfigurations + } + return [] + } + delegate: PrintCoreConfiguration { width: Math.round(parent.width / 2) printCoreConfiguration: modelData } } + + // Unknown material + Rectangle + { + id: unknownMaterial + height: unknownMaterialMessage.height + UM.Theme.getSize("thin_margin").width / 2 + width: parent.width + + anchors.top: parent.top + anchors.topMargin: + { + return UM.Theme.getSize("thin_margin").width / 2 + } + + visible: !configurationItem.isValidMaterial + + UM.RecolorImage + { + id: icon + anchors.verticalCenter: unknownMaterialMessage.verticalCenter + + source: UM.Theme.getIcon("warning") + color: UM.Theme.getColor("warning") + width: UM.Theme.getSize("section_icon").width + height: width + } + + Label + { + id: unknownMaterialMessage + text: + { + var extruderConfigurations = configuration.extruderConfigurations + var unknownMaterials = [] + for (var index = 0; index < extruderConfigurations.length; index++) + { + var name = extruderConfigurations[index].material.brand ? extruderConfigurations[index].material.name : "" + + if (name == "" || name == "Unknown") + { + unknownMaterials.push(extruderConfigurations[index].material.brand ? extruderConfigurations[index].material.brand : "Unknown Brand") + } + } + + unknownMaterials = "" + unknownMaterials + "" + var draftResult = catalog.i18nc("@label", "This configuration is not available because %1 is not recognized. Please visit %2 to download the correct material profile."); + var result = draftResult.arg(unknownMaterials).arg("" + catalog.i18nc("@label","Marketplace") + " ") + + return result + } + width: extruderRow.width + + anchors.left: icon.right + anchors.right: unknownMaterial.right + anchors.leftMargin: UM.Theme.getSize("wide_margin").height + anchors.top: unknownMaterial.top + + wrapMode: Text.WordWrap + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + verticalAlignment: Text.AlignVCenter + linkColor: UM.Theme.getColor("text_link") + + onLinkActivated: + { + Cura.Actions.browsePackages.trigger() + } + } + + MouseArea { + anchors.fill: parent + cursorShape: unknownMaterialMessage.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor + acceptedButtons: Qt.NoButton + } + } } //Buildplate row separator From 9430c421ebcf202caca4c6dda40af920678e396d Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Thu, 20 Dec 2018 18:19:59 +0100 Subject: [PATCH 1085/1292] Code refactor CURA-6033 --- resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 16d683adca..4cf0437098 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -87,10 +87,7 @@ Button width: parent.width anchors.top: parent.top - anchors.topMargin: - { - return UM.Theme.getSize("thin_margin").width / 2 - } + anchors.topMargin: UM.Theme.getSize("thin_margin").width / 2 visible: !configurationItem.isValidMaterial From 81a6531f47f3b7356146827f27a8bf430b93a94e Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Thu, 20 Dec 2018 20:37:48 +0100 Subject: [PATCH 1086/1292] Fix range slider label position in LayerSlider.qml. --- plugins/SimulationView/LayerSlider.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/SimulationView/LayerSlider.qml b/plugins/SimulationView/LayerSlider.qml index 42b8cf0ba0..88f298d1f5 100644 --- a/plugins/SimulationView/LayerSlider.qml +++ b/plugins/SimulationView/LayerSlider.qml @@ -163,9 +163,9 @@ Item id: rangleHandleLabel height: sliderRoot.handleSize + UM.Theme.getSize("default_margin").height - x: parent.x + parent.width + UM.Theme.getSize("default_margin").width + x: parent.x - width - UM.Theme.getSize("default_margin").width anchors.verticalCenter: parent.verticalCenter - target: Qt.point(sliderRoot.width + width, y + height / 2) + target: Qt.point(sliderRoot.width, y + height / 2) visible: sliderRoot.activeHandle == parent // custom properties From e51b5993d334e424fe97278d317f7dce37a76d83 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 20 Dec 2018 21:56:27 +0100 Subject: [PATCH 1087/1292] Don't create system tray icon in headless mode --- cura/CuraApplication.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 9ec2435f0b..4e02be87f5 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -434,7 +434,8 @@ class CuraApplication(QtApplication): def startSplashWindowPhase(self) -> None: super().startSplashWindowPhase() - self.setWindowIcon(QIcon(Resources.getPath(Resources.Images, "cura-icon.png"))) + if not self.getIsHeadLess(): + self.setWindowIcon(QIcon(Resources.getPath(Resources.Images, "cura-icon.png"))) self.setRequiredPlugins([ # Misc.: From 131211e604bed58b719f6f017d44d0fbb68d15b8 Mon Sep 17 00:00:00 2001 From: Marijn Dee Date: Fri, 21 Dec 2018 09:42:28 +0100 Subject: [PATCH 1088/1292] Fixed the unit tests --- .../src/Cloud/Models/CloudClusterPrintJobStatus.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py index 5b7ef7c18a..b1672f362e 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py @@ -76,11 +76,17 @@ class CloudClusterPrintJobStatus(BaseCloudModel): self.uuid = uuid self.deleted_at = deleted_at self.printed_on_uuid = printed_on_uuid - self.configuration_changes_required = self.parseModels(CloudClusterPrintJobConfigurationChange, - configuration_changes_required) + if configuration_changes_required: + self.configuration_changes_required = self.parseModels(CloudClusterPrintJobConfigurationChange, + configuration_changes_required) + else: + self.configuration_changes_required = [] self.build_plate = self.parseModel(CloudClusterBuildPlate, build_plate) self.compatible_machine_families = compatible_machine_families - self.impediments_to_printing = self.parseModels(CloudClusterPrintJobImpediment, impediments_to_printing) + if impediments_to_printing: + self.impediments_to_printing = self.parseModels(CloudClusterPrintJobImpediment, impediments_to_printing) + else: + self.impediments_to_printing = [] super().__init__(**kwargs) From 75fbdf2c94a5e0f004dbecaba71447cb491a87e0 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 21 Dec 2018 10:40:37 +0100 Subject: [PATCH 1089/1292] Expand error message for cases when extruders are disabled It is also unable to slice models that are on extruders that are disabled. --- plugins/CuraEngineBackend/CuraEngineBackend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 1830a30b30..cf00035e3b 100755 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -411,7 +411,7 @@ class CuraEngineBackend(QObject, Backend): if job.getResult() == StartJobResult.NothingToSlice: if self._application.platformActivity: - self._error_message = Message(catalog.i18nc("@info:status", "Nothing to slice because none of the models fit the build volume. Please scale or rotate models to fit."), + self._error_message = Message(catalog.i18nc("@info:status", "Nothing to slice because none of the models fit the build volume or are assigned to a disabled extruder. Please scale or rotate models to fit, or enable an extruder."), title = catalog.i18nc("@info:title", "Unable to slice")) self._error_message.show() self.setState(BackendState.Error) From 81e356ea1b3ce7e19b0ec211f337e75038369d53 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 21 Dec 2018 11:20:09 +0100 Subject: [PATCH 1090/1292] Switch out the containersModel for the more specific printersModel --- resources/qml/Menus/LocalPrinterMenu.qml | 20 +++++++++++--------- resources/qml/Menus/NetworkPrinterMenu.qml | 14 +++++--------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/resources/qml/Menus/LocalPrinterMenu.qml b/resources/qml/Menus/LocalPrinterMenu.qml index 0bdd4f33b9..e7c5037814 100644 --- a/resources/qml/Menus/LocalPrinterMenu.qml +++ b/resources/qml/Menus/LocalPrinterMenu.qml @@ -7,16 +7,18 @@ import QtQuick.Controls 1.4 import UM 1.2 as UM import Cura 1.0 as Cura -Instantiator { - model: UM.ContainerStacksModel { - filter: {"type": "machine", "um_network_key": null} - } - MenuItem { - text: model.name; - checkable: true; +Instantiator +{ + model: Cura.PrintersModel {} + + MenuItem + { + text: model.name + checkable: true checked: Cura.MachineManager.activeMachineId == model.id - exclusiveGroup: group; - onTriggered: Cura.MachineManager.setActiveMachine(model.id); + exclusiveGroup: group + visible: !model.hasRemoteConnection + onTriggered: Cura.MachineManager.setActiveMachine(model.id) } onObjectAdded: menu.insertItem(index, object) onObjectRemoved: menu.removeItem(object) diff --git a/resources/qml/Menus/NetworkPrinterMenu.qml b/resources/qml/Menus/NetworkPrinterMenu.qml index 166e45f3b9..8c607bc5ae 100644 --- a/resources/qml/Menus/NetworkPrinterMenu.qml +++ b/resources/qml/Menus/NetworkPrinterMenu.qml @@ -9,19 +9,15 @@ import Cura 1.0 as Cura Instantiator { - model: UM.ContainerStacksModel - { - filter: {"type": "machine", "um_network_key": "*", "hidden": "False"} - } + model: Cura.PrintersModel {} MenuItem { - // TODO: Use printer_group icon when it's a cluster. Not use it for now since it doesn't look as expected -// iconSource: UM.Theme.getIcon("printer_single") text: model.metadata["connect_group_name"] - checkable: true; + checkable: true + visible: model.hasRemoteConnection checked: Cura.MachineManager.activeMachineNetworkGroupName == model.metadata["connect_group_name"] - exclusiveGroup: group; - onTriggered: Cura.MachineManager.setActiveMachine(model.id); + exclusiveGroup: group + onTriggered: Cura.MachineManager.setActiveMachine(model.id) } onObjectAdded: menu.insertItem(index, object) onObjectRemoved: menu.removeItem(object) From a5500b028f9d5f43688822d1ba8427868baeb833 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 21 Dec 2018 11:50:30 +0100 Subject: [PATCH 1091/1292] Use HTTPS for Help links The Ultimaker website doesn't even accept anything else any more. --- cura/CuraActions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/CuraActions.py b/cura/CuraActions.py index 49f7e740a9..ebb1523f13 100644 --- a/cura/CuraActions.py +++ b/cura/CuraActions.py @@ -36,12 +36,12 @@ class CuraActions(QObject): # Starting a web browser from a signal handler connected to a menu will crash on windows. # So instead, defer the call to the next run of the event loop, since that does work. # Note that weirdly enough, only signal handlers that open a web browser fail like that. - event = CallFunctionEvent(self._openUrl, [QUrl("http://ultimaker.com/en/support/software")], {}) + event = CallFunctionEvent(self._openUrl, [QUrl("https://ultimaker.com/en/support/software")], {}) cura.CuraApplication.CuraApplication.getInstance().functionEvent(event) @pyqtSlot() def openBugReportPage(self) -> None: - event = CallFunctionEvent(self._openUrl, [QUrl("http://github.com/Ultimaker/Cura/issues")], {}) + event = CallFunctionEvent(self._openUrl, [QUrl("https://github.com/Ultimaker/Cura/issues")], {}) cura.CuraApplication.CuraApplication.getInstance().functionEvent(event) ## Reset camera position and direction to default From 7269065cca3bcd16bb4689095d2d6e54dbe80544 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 21 Dec 2018 11:54:11 +0100 Subject: [PATCH 1092/1292] Only clear the stored optimized layer data if the slice started --- plugins/CuraEngineBackend/CuraEngineBackend.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index cf00035e3b..f12a5b1222 100755 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -86,8 +86,8 @@ class CuraEngineBackend(QObject, Backend): self._layer_view_active = False #type: bool self._onActiveViewChanged() - self._stored_layer_data = [] #type: List[Arcus.PythonMessage] - self._stored_optimized_layer_data = {} #type: Dict[int, List[Arcus.PythonMessage]] # key is build plate number, then arrays are stored until they go to the ProcessSlicesLayersJob + self._stored_layer_data = [] # type: List[Arcus.PythonMessage] + self._stored_optimized_layer_data = {} # type: Dict[int, List[Arcus.PythonMessage]] # key is build plate number, then arrays are stored until they go to the ProcessSlicesLayersJob self._scene = self._application.getController().getScene() #type: Scene self._scene.sceneChanged.connect(self._onSceneChanged) @@ -246,7 +246,7 @@ class CuraEngineBackend(QObject, Backend): num_objects = self._numObjectsPerBuildPlate() self._stored_layer_data = [] - self._stored_optimized_layer_data[build_plate_to_be_sliced] = [] + if build_plate_to_be_sliced not in num_objects or num_objects[build_plate_to_be_sliced] == 0: self._scene.gcode_dict[build_plate_to_be_sliced] = [] #type: ignore #Because we created this attribute above. @@ -254,7 +254,7 @@ class CuraEngineBackend(QObject, Backend): if self._build_plates_to_be_sliced: self.slice() return - + self._stored_optimized_layer_data[build_plate_to_be_sliced] = [] if self._application.getPrintInformation() and build_plate_to_be_sliced == active_build_plate: self._application.getPrintInformation().setToZeroPrintInformation(build_plate_to_be_sliced) From 07f0433751ad9f97e4169c60b46ce57f6010d671 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 21 Dec 2018 11:58:57 +0100 Subject: [PATCH 1093/1292] Correct link to manual They changed this on the website, breaking all previous releases of Cura in the process. --- cura/CuraActions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/CuraActions.py b/cura/CuraActions.py index ebb1523f13..91e0966fed 100644 --- a/cura/CuraActions.py +++ b/cura/CuraActions.py @@ -36,7 +36,7 @@ class CuraActions(QObject): # Starting a web browser from a signal handler connected to a menu will crash on windows. # So instead, defer the call to the next run of the event loop, since that does work. # Note that weirdly enough, only signal handlers that open a web browser fail like that. - event = CallFunctionEvent(self._openUrl, [QUrl("https://ultimaker.com/en/support/software")], {}) + event = CallFunctionEvent(self._openUrl, [QUrl("https://ultimaker.com/en/resources/manuals/software")], {}) cura.CuraApplication.CuraApplication.getInstance().functionEvent(event) @pyqtSlot() From 01783e7f685cda2a24ce6a0de846ab7cca79d17d Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Fri, 21 Dec 2018 13:54:01 +0100 Subject: [PATCH 1094/1292] Check material name instead of material brand CURA-6033 --- resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 4cf0437098..9e2fed0767 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -20,7 +20,7 @@ Button for (var index = 0; index < extruderConfigurations.length; index++) { - var name = extruderConfigurations[index].material.brand ? extruderConfigurations[index].material.name : "" + var name = extruderConfigurations[index].material ? extruderConfigurations[index].material.name : "" if (name == "" || name == "Unknown") { @@ -111,7 +111,7 @@ Button var unknownMaterials = [] for (var index = 0; index < extruderConfigurations.length; index++) { - var name = extruderConfigurations[index].material.brand ? extruderConfigurations[index].material.name : "" + var name = extruderConfigurations[index].material ? extruderConfigurations[index].material.name : "" if (name == "" || name == "Unknown") { From 766fc2293e1e5e635fdf0d5b2b5fbb75071df816 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 21 Dec 2018 14:35:41 +0100 Subject: [PATCH 1095/1292] Fix visibility for machine icon in dark theme --- resources/themes/cura-dark/theme.json | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/themes/cura-dark/theme.json b/resources/themes/cura-dark/theme.json index 537fccbc5c..6b29073475 100644 --- a/resources/themes/cura-dark/theme.json +++ b/resources/themes/cura-dark/theme.json @@ -28,6 +28,7 @@ "machine_selector_bar": [39, 44, 48, 255], "machine_selector_active": [39, 44, 48, 255], + "machine_selector_printer_icon": [204, 204, 204, 255], "text": [255, 255, 255, 204], "text_detail": [255, 255, 255, 172], From c8994102da49ac08f3fcd041df12c7ffaa12eb88 Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Fri, 21 Dec 2018 14:44:25 +0100 Subject: [PATCH 1096/1292] Use short for each javascript function CURA-6033 --- .../qml/Menus/ConfigurationMenu/ConfigurationItem.qml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 9e2fed0767..b23bcc4b8c 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -18,7 +18,7 @@ Button { var extruderConfigurations = configuration.extruderConfigurations - for (var index = 0; index < extruderConfigurations.length; index++) + for (var index in extruderConfigurations) { var name = extruderConfigurations[index].material ? extruderConfigurations[index].material.name : "" @@ -109,7 +109,7 @@ Button { var extruderConfigurations = configuration.extruderConfigurations var unknownMaterials = [] - for (var index = 0; index < extruderConfigurations.length; index++) + for (var index in extruderConfigurations) { var name = extruderConfigurations[index].material ? extruderConfigurations[index].material.name : "" @@ -144,7 +144,8 @@ Button } } - MouseArea { + MouseArea + { anchors.fill: parent cursorShape: unknownMaterialMessage.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor acceptedButtons: Qt.NoButton From 12a4a5e9f54ba62b6c2eb1f6df8e1a28c8441506 Mon Sep 17 00:00:00 2001 From: Marijn Dee Date: Fri, 21 Dec 2018 15:06:02 +0100 Subject: [PATCH 1097/1292] Fixing the rest of the automatic test failures --- ...CloudClusterPrintJobConfigurationChange.py | 5 ++- .../Models/CloudClusterPrintJobStatus.py | 35 +++++++++---------- .../Cloud/Models/CloudClusterPrinterStatus.py | 4 +-- 3 files changed, 21 insertions(+), 23 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobConfigurationChange.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobConfigurationChange.py index 6c02972757..9ff4154666 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobConfigurationChange.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobConfigurationChange.py @@ -15,9 +15,8 @@ class CloudClusterPrintJobConfigurationChange(BaseCloudModel): # \param origin_id: Original/current material guid or hotend id # \param target_name: Target material name or hotend id # \param origin_name: Original/current material name or hotend id - def __init__(self, type_of_change: Optional[str] = None, index: Optional[int] = None, - target_id: Optional[str] = None,origin_id: Optional[str] = None, - target_name: Optional[str] = None,origin_name: Optional[str] = None, + def __init__(self, type_of_change: str, target_id: str, origin_id: str, + index: Optional[int] = None, target_name: Optional[str] = None, origin_name: Optional[str] = None, **kwargs) -> None: self.type_of_change = type_of_change self.index = index diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py index b1672f362e..5d62471710 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py @@ -55,7 +55,8 @@ class CloudClusterPrintJobStatus(BaseCloudModel): printed_on_uuid: Optional[str] = None, configuration_changes_required: List[ Union[Dict[str, Any], CloudClusterPrintJobConfigurationChange]] = None, - build_plate: Optional[str] = None, compatible_machine_families: List[str] = None, + build_plate: Union[Dict[str, Any], CloudClusterBuildPlate] = None, + compatible_machine_families: List[str] = None, impediments_to_printing: List[Union[Dict[str, Any], CloudClusterPrintJobImpediment]] = None, **kwargs) -> None: self.assigned_to = assigned_to @@ -76,17 +77,14 @@ class CloudClusterPrintJobStatus(BaseCloudModel): self.uuid = uuid self.deleted_at = deleted_at self.printed_on_uuid = printed_on_uuid - if configuration_changes_required: - self.configuration_changes_required = self.parseModels(CloudClusterPrintJobConfigurationChange, - configuration_changes_required) - else: - self.configuration_changes_required = [] - self.build_plate = self.parseModel(CloudClusterBuildPlate, build_plate) - self.compatible_machine_families = compatible_machine_families - if impediments_to_printing: - self.impediments_to_printing = self.parseModels(CloudClusterPrintJobImpediment, impediments_to_printing) - else: - self.impediments_to_printing = [] + + self.configuration_changes_required = self.parseModels(CloudClusterPrintJobConfigurationChange, + configuration_changes_required) \ + if configuration_changes_required else [] + self.build_plate = self.parseModel(CloudClusterBuildPlate, build_plate) if build_plate else None + self.compatible_machine_families = compatible_machine_families if compatible_machine_families else [] + self.impediments_to_printing = self.parseModels(CloudClusterPrintJobImpediment, impediments_to_printing) \ + if impediments_to_printing else [] super().__init__(**kwargs) @@ -120,7 +118,8 @@ class CloudClusterPrintJobStatus(BaseCloudModel): status_set_by_impediment = False for impediment in self.impediments_to_printing: - if impediment.severity == "UNFIXABLE": # TODO: impediment.severity is defined as int, this will not work, is there a translation? + # TODO: impediment.severity is defined as int, this will not work, is there a translation? + if impediment.severity == "UNFIXABLE": status_set_by_impediment = True model.updateState("error") break @@ -130,8 +129,8 @@ class CloudClusterPrintJobStatus(BaseCloudModel): model.updateConfigurationChanges( [ConfigurationChangeModel( - type_of_change=change.type_of_change, - index=change.index, - target_name=change.target_name, - origin_name=change.origin_name) - for change in self.configuration_changes_required]) + type_of_change = change.type_of_change, + index = change.index if change.index else 0, + target_name = change.target_name if change.target_name else "", + origin_name = change.origin_name if change.origin_name else "") + for change in self.configuration_changes_required]) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterStatus.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterStatus.py index 23409a761d..a8165ff69c 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterStatus.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterStatus.py @@ -33,7 +33,7 @@ class CloudClusterPrinterStatus(BaseCloudModel): configuration: List[Union[Dict[str, Any], CloudClusterPrintCoreConfiguration]], reserved_by: Optional[str] = None, maintenance_required: Optional[bool] = None, firmware_update_status: Optional[str] = None, latest_available_firmware: Optional[str] = None, - build_plate: Optional[str] = None, **kwargs) -> None: + build_plate: Union[Dict[str, Any], CloudClusterBuildPlate] = None, **kwargs) -> None: self.configuration = self.parseModels(CloudClusterPrintCoreConfiguration, configuration) self.enabled = enabled @@ -48,7 +48,7 @@ class CloudClusterPrinterStatus(BaseCloudModel): self.maintenance_required = maintenance_required self.firmware_update_status = firmware_update_status self.latest_available_firmware = latest_available_firmware - self.build_plate = self.parseModel(CloudClusterBuildPlate, build_plate) + self.build_plate = self.parseModel(CloudClusterBuildPlate, build_plate) if build_plate else None super().__init__(**kwargs) ## Creates a new output model. From 33c97fcf4a5c7958dd3d899811dde6d52bcde114 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 21 Dec 2018 15:09:09 +0100 Subject: [PATCH 1098/1292] Updated typing --- cura/CuraApplication.py | 89 +++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 44 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 4e02be87f5..49b0026b39 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -4,7 +4,7 @@ import os import sys import time -from typing import cast, TYPE_CHECKING, Optional, Callable +from typing import cast, TYPE_CHECKING, Optional, Callable, List import numpy @@ -665,12 +665,12 @@ class CuraApplication(QtApplication): ## Handle loading of all plugin types (and the backend explicitly) # \sa PluginRegistry - def _loadPlugins(self): + def _loadPlugins(self) -> None: self._plugin_registry.addType("profile_reader", self._addProfileReader) self._plugin_registry.addType("profile_writer", self._addProfileWriter) if Platform.isLinux(): - lib_suffixes = {"", "64", "32", "x32"} #A few common ones on different distributions. + lib_suffixes = {"", "64", "32", "x32"} # A few common ones on different distributions. else: lib_suffixes = {""} for suffix in lib_suffixes: @@ -1267,62 +1267,75 @@ class CuraApplication(QtApplication): ## Arrange all objects. @pyqtSlot() - def arrangeObjectsToAllBuildPlates(self): - nodes = [] - for node in DepthFirstIterator(self.getController().getScene().getRoot()): + def arrangeObjectsToAllBuildPlates(self) -> None: + nodes_to_arrange = [] + for node in DepthFirstIterator(self.getController().getScene().getRoot()): # type: ignore if not isinstance(node, SceneNode): continue + if not node.getMeshData() and not node.callDecoration("isGroup"): continue # Node that doesnt have a mesh and is not a group. - if node.getParent() and node.getParent().callDecoration("isGroup"): - continue # Grouped nodes don't need resetting as their parent (the group) is resetted) + + parent_node = node.getParent() + if parent_node and parent_node.callDecoration("isGroup"): + continue # Grouped nodes don't need resetting as their parent (the group) is reset) + if not node.callDecoration("isSliceable") and not node.callDecoration("isGroup"): continue # i.e. node with layer data + + bounding_box = node.getBoundingBox() # Skip nodes that are too big - if node.getBoundingBox().width < self._volume.getBoundingBox().width or node.getBoundingBox().depth < self._volume.getBoundingBox().depth: - nodes.append(node) - job = ArrangeObjectsAllBuildPlatesJob(nodes) + if bounding_box is None or bounding_box.width < self._volume.getBoundingBox().width or bounding_box.depth < self._volume.getBoundingBox().depth: + nodes_to_arrange.append(node) + job = ArrangeObjectsAllBuildPlatesJob(nodes_to_arrange) job.start() self.getCuraSceneController().setActiveBuildPlate(0) # Select first build plate # Single build plate @pyqtSlot() - def arrangeAll(self): - nodes = [] + def arrangeAll(self) -> None: + nodes_to_arrange = [] active_build_plate = self.getMultiBuildPlateModel().activeBuildPlate - for node in DepthFirstIterator(self.getController().getScene().getRoot()): + for node in DepthFirstIterator(self.getController().getScene().getRoot()): # type: ignore if not isinstance(node, SceneNode): continue + if not node.getMeshData() and not node.callDecoration("isGroup"): continue # Node that doesnt have a mesh and is not a group. - if node.getParent() and node.getParent().callDecoration("isGroup"): + + parent_node = node.getParent() + if parent_node and parent_node.callDecoration("isGroup"): continue # Grouped nodes don't need resetting as their parent (the group) is resetted) + if not node.isSelectable(): continue # i.e. node with layer data + if not node.callDecoration("isSliceable") and not node.callDecoration("isGroup"): continue # i.e. node with layer data + if node.callDecoration("getBuildPlateNumber") == active_build_plate: # Skip nodes that are too big - if node.getBoundingBox().width < self._volume.getBoundingBox().width or node.getBoundingBox().depth < self._volume.getBoundingBox().depth: - nodes.append(node) - self.arrange(nodes, fixed_nodes = []) + bounding_box = node.getBoundingBox() + if bounding_box is None or bounding_box.width < self._volume.getBoundingBox().width or bounding_box.depth < self._volume.getBoundingBox().depth: + nodes_to_arrange.append(node) + self.arrange(nodes_to_arrange, fixed_nodes = []) ## Arrange a set of nodes given a set of fixed nodes # \param nodes nodes that we have to place # \param fixed_nodes nodes that are placed in the arranger before finding spots for nodes - def arrange(self, nodes, fixed_nodes): + def arrange(self, nodes: List[SceneNode], fixed_nodes: List[SceneNode]) -> None: min_offset = self.getBuildVolume().getEdgeDisallowedSize() + 2 # Allow for some rounding errors job = ArrangeObjectsJob(nodes, fixed_nodes, min_offset = max(min_offset, 8)) job.start() ## Reload all mesh data on the screen from file. @pyqtSlot() - def reloadAll(self): + def reloadAll(self) -> None: Logger.log("i", "Reloading all loaded mesh data.") nodes = [] has_merged_nodes = False - for node in DepthFirstIterator(self.getController().getScene().getRoot()): - if not isinstance(node, CuraSceneNode) or not node.getMeshData() : + for node in DepthFirstIterator(self.getController().getScene().getRoot()): # type: ignore + if not isinstance(node, CuraSceneNode) or not node.getMeshData(): if node.getName() == "MergedMesh": has_merged_nodes = True continue @@ -1336,7 +1349,7 @@ class CuraApplication(QtApplication): file_name = node.getMeshData().getFileName() if file_name: job = ReadMeshJob(file_name) - job._node = node + job._node = node # type: ignore job.finished.connect(self._reloadMeshFinished) if has_merged_nodes: job.finished.connect(self.updateOriginOfMergedMeshes) @@ -1345,20 +1358,8 @@ class CuraApplication(QtApplication): else: Logger.log("w", "Unable to reload data because we don't have a filename.") - - ## Get logging data of the backend engine - # \returns \type{string} Logging data - @pyqtSlot(result = str) - def getEngineLog(self): - log = "" - - for entry in self.getBackend().getLog(): - log += entry.decode() - - return log - @pyqtSlot("QStringList") - def setExpandedCategories(self, categories): + def setExpandedCategories(self, categories: List[str]) -> None: categories = list(set(categories)) categories.sort() joined = ";".join(categories) @@ -1369,7 +1370,7 @@ class CuraApplication(QtApplication): expandedCategoriesChanged = pyqtSignal() @pyqtProperty("QStringList", notify = expandedCategoriesChanged) - def expandedCategories(self): + def expandedCategories(self) -> List[str]: return self.getPreferences().getValue("cura/categories_expanded").split(";") @pyqtSlot() @@ -1419,13 +1420,12 @@ class CuraApplication(QtApplication): ## Updates origin position of all merged meshes - # \param jobNode \type{Job} empty object which passed which is required by JobQueue - def updateOriginOfMergedMeshes(self, jobNode): + def updateOriginOfMergedMeshes(self, _): group_nodes = [] for node in DepthFirstIterator(self.getController().getScene().getRoot()): if isinstance(node, CuraSceneNode) and node.getName() == "MergedMesh": - #checking by name might be not enough, the merged mesh should has "GroupDecorator" decorator + # Checking by name might be not enough, the merged mesh should has "GroupDecorator" decorator for decorator in node.getDecorators(): if isinstance(decorator, GroupDecorator): group_nodes.append(node) @@ -1469,7 +1469,7 @@ class CuraApplication(QtApplication): @pyqtSlot() - def groupSelected(self): + def groupSelected(self) -> None: # Create a group-node group_node = CuraSceneNode() group_decorator = GroupDecorator() @@ -1485,7 +1485,8 @@ class CuraApplication(QtApplication): # Remove nodes that are directly parented to another selected node from the selection so they remain parented selected_nodes = Selection.getAllSelectedObjects().copy() for node in selected_nodes: - if node.getParent() in selected_nodes and not node.getParent().callDecoration("isGroup"): + parent = node.getParent() + if parent is not None and node in selected_nodes and not node.callDecoration("isGroup"): Selection.remove(node) # Move selected nodes into the group-node @@ -1497,7 +1498,7 @@ class CuraApplication(QtApplication): Selection.add(group_node) @pyqtSlot() - def ungroupSelected(self): + def ungroupSelected(self) -> None: selected_objects = Selection.getAllSelectedObjects().copy() for node in selected_objects: if node.callDecoration("isGroup"): @@ -1520,7 +1521,7 @@ class CuraApplication(QtApplication): # Note: The group removes itself from the scene once all its children have left it, # see GroupDecorator._onChildrenChanged - def _createSplashScreen(self): + def _createSplashScreen(self) -> Optional[CuraSplashScreen.CuraSplashScreen]: if self._is_headless: return None return CuraSplashScreen.CuraSplashScreen() From 4ab79f963ab8e38096cb53b1c11c3c7b1db17edc Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 21 Dec 2018 15:10:14 +0100 Subject: [PATCH 1099/1292] Remove deprecated functions --- cura/CuraApplication.py | 82 ----------------------------------------- 1 file changed, 82 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 49b0026b39..4a1023f69e 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -1106,88 +1106,6 @@ class CuraApplication(QtApplication): self._platform_activity = True if count > 0 else False self.activityChanged.emit() - # Remove all selected objects from the scene. - @pyqtSlot() - @deprecated("Moved to CuraActions", "2.6") - def deleteSelection(self): - if not self.getController().getToolsEnabled(): - return - removed_group_nodes = [] - op = GroupedOperation() - nodes = Selection.getAllSelectedObjects() - for node in nodes: - op.addOperation(RemoveSceneNodeOperation(node)) - group_node = node.getParent() - if group_node and group_node.callDecoration("isGroup") and group_node not in removed_group_nodes: - remaining_nodes_in_group = list(set(group_node.getChildren()) - set(nodes)) - if len(remaining_nodes_in_group) == 1: - removed_group_nodes.append(group_node) - op.addOperation(SetParentOperation(remaining_nodes_in_group[0], group_node.getParent())) - op.addOperation(RemoveSceneNodeOperation(group_node)) - op.push() - - ## Remove an object from the scene. - # Note that this only removes an object if it is selected. - @pyqtSlot("quint64") - @deprecated("Use deleteSelection instead", "2.6") - def deleteObject(self, object_id): - if not self.getController().getToolsEnabled(): - return - - node = self.getController().getScene().findObject(object_id) - - if not node and object_id != 0: # Workaround for tool handles overlapping the selected object - node = Selection.getSelectedObject(0) - - if node: - op = GroupedOperation() - op.addOperation(RemoveSceneNodeOperation(node)) - - group_node = node.getParent() - if group_node: - # Note that at this point the node has not yet been deleted - if len(group_node.getChildren()) <= 2 and group_node.callDecoration("isGroup"): - op.addOperation(SetParentOperation(group_node.getChildren()[0], group_node.getParent())) - op.addOperation(RemoveSceneNodeOperation(group_node)) - - op.push() - - ## Create a number of copies of existing object. - # \param object_id - # \param count number of copies - # \param min_offset minimum offset to other objects. - @pyqtSlot("quint64", int) - @deprecated("Use CuraActions::multiplySelection", "2.6") - def multiplyObject(self, object_id, count, min_offset = 8): - node = self.getController().getScene().findObject(object_id) - if not node: - node = Selection.getSelectedObject(0) - - while node.getParent() and node.getParent().callDecoration("isGroup"): - node = node.getParent() - - job = MultiplyObjectsJob([node], count, min_offset) - job.start() - return - - ## Center object on platform. - @pyqtSlot("quint64") - @deprecated("Use CuraActions::centerSelection", "2.6") - def centerObject(self, object_id): - node = self.getController().getScene().findObject(object_id) - if not node and object_id != 0: # Workaround for tool handles overlapping the selected object - node = Selection.getSelectedObject(0) - - if not node: - return - - if node.getParent() and node.getParent().callDecoration("isGroup"): - node = node.getParent() - - if node: - op = SetTransformOperation(node, Vector()) - op.push() - ## Select all nodes containing mesh data in the scene. @pyqtSlot() def selectAll(self): From e8ea742cf6c9cb533604fd7741a94381a33b27d7 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 21 Dec 2018 16:27:38 +0100 Subject: [PATCH 1100/1292] Retain binding with isValidMaterial on hover So that if a material becomes valid, it updates this property. Contributes to issue CURA-6033. --- resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index b23bcc4b8c..31569c58d2 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -12,7 +12,7 @@ Button id: configurationItem property var configuration: null - hoverEnabled: true + hoverEnabled: isValidMaterial property bool isValidMaterial: { @@ -24,7 +24,6 @@ Button if (name == "" || name == "Unknown") { - hoverEnabled = false return false } } From 5e9854454185fee9490b0d9aa996d36f65b7e2fd Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 21 Dec 2018 16:33:16 +0100 Subject: [PATCH 1101/1292] Don't change the model depending on isValidMaterial That would cause a circular dependency in a way. Contributes to issue CURA-6033. --- .../qml/Menus/ConfigurationMenu/ConfigurationItem.qml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 31569c58d2..6a17353459 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -62,19 +62,13 @@ Button Repeater { id: repeater - model: - { - if (configurationItem.isValidMaterial) - { - return configuration.extruderConfigurations - } - return [] - } + model: configuration.extruderConfigurations delegate: PrintCoreConfiguration { width: Math.round(parent.width / 2) printCoreConfiguration: modelData + visible: configurationItem.isValidMaterial } } From a720cca5b6f279696e398e96abe919491c12775e Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 21 Dec 2018 16:40:24 +0100 Subject: [PATCH 1102/1292] Fix background colour for dark theme The default colour for Rectangle is white. So this Rectangle, not defining a colour, became white. Instead we should use an Item, which cannot have a background colour and thus becomes transparent, making the background colour the same as the button below, which was intended. It's also slightly faster to render. Contributes to issue CURA-6033. --- resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 6a17353459..81f2183488 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -73,7 +73,7 @@ Button } // Unknown material - Rectangle + Item { id: unknownMaterial height: unknownMaterialMessage.height + UM.Theme.getSize("thin_margin").width / 2 From 2277a3d316ae2ded6c8f6df18e43de9277181e38 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 21 Dec 2018 16:43:45 +0100 Subject: [PATCH 1103/1292] Prevent syncing with invalid configurations Contributes to issue CURA-6033. --- resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 81f2183488..75a1b21186 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -216,6 +216,9 @@ Button onClicked: { - Cura.MachineManager.applyRemoteConfiguration(configuration) + if(isValidMaterial) + { + Cura.MachineManager.applyRemoteConfiguration(configuration); + } } } From 85f10e7c4f9bc48afd2fe43903e565b128e03189 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 21 Dec 2018 16:57:52 +0100 Subject: [PATCH 1104/1292] Prevent some unneeded calling of signals --- cura/Settings/ExtruderManager.py | 4 +++- cura/Settings/MachineManager.py | 1 - cura/Settings/SettingInheritanceManager.py | 1 - 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index 8fa0172305..6e462031dc 100755 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -344,7 +344,9 @@ class ExtruderManager(QObject): self._fixSingleExtrusionMachineExtruderDefinition(global_stack) if extruders_changed: self.extrudersChanged.emit(global_stack_id) - self.setActiveExtruderIndex(0) + + # Set it directly instead of using setActiveExtruder, since we want to force the signal to emitted. + self._active_extruder_index = 0 self.activeExtruderChanged.emit() # After 3.4, all single-extrusion machines have their own extruder definition files instead of reusing diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 2185bbce9d..755d05d71e 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -385,7 +385,6 @@ class MachineManager(QObject): self._application.setGlobalContainerStack(global_stack) ExtruderManager.getInstance()._globalContainerStackChanged() self._initMachineState(global_stack) - self._onGlobalContainerChanged() self.__emitChangedSignals() diff --git a/cura/Settings/SettingInheritanceManager.py b/cura/Settings/SettingInheritanceManager.py index 12b541c3d8..3815d85e81 100644 --- a/cura/Settings/SettingInheritanceManager.py +++ b/cura/Settings/SettingInheritanceManager.py @@ -249,7 +249,6 @@ class SettingInheritanceManager(QObject): if self._global_container_stack: self._global_container_stack.containersChanged.connect(self._onContainersChanged) self._global_container_stack.propertyChanged.connect(self._onPropertyChanged) - self._onActiveExtruderChanged() def _onContainersChanged(self, container): self._update_timer.start() From f627560751761f25b75733412b91a14cd2357e1e Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 21 Dec 2018 17:12:07 +0100 Subject: [PATCH 1105/1292] Add timer to QualityProfilesDropdownMenuModel to prevent unneeded updates It's the same old trick we've pulled off quite often, so this should be pretty safe --- .../Models/QualityProfilesDropDownMenuModel.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/cura/Machines/Models/QualityProfilesDropDownMenuModel.py b/cura/Machines/Models/QualityProfilesDropDownMenuModel.py index 747882b041..7ccc886bfe 100644 --- a/cura/Machines/Models/QualityProfilesDropDownMenuModel.py +++ b/cura/Machines/Models/QualityProfilesDropDownMenuModel.py @@ -1,7 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from PyQt5.QtCore import Qt +from PyQt5.QtCore import Qt, QTimer from UM.Application import Application from UM.Logger import Logger @@ -39,15 +39,23 @@ class QualityProfilesDropDownMenuModel(ListModel): self._machine_manager = self._application.getMachineManager() self._quality_manager = Application.getInstance().getQualityManager() - self._application.globalContainerStackChanged.connect(self._update) - self._machine_manager.activeQualityGroupChanged.connect(self._update) - self._machine_manager.extruderChanged.connect(self._update) - self._quality_manager.qualitiesUpdated.connect(self._update) + self._application.globalContainerStackChanged.connect(self._onChange) + self._machine_manager.activeQualityGroupChanged.connect(self._onChange) + self._machine_manager.extruderChanged.connect(self._onChange) + self._quality_manager.qualitiesUpdated.connect(self._onChange) self._layer_height_unit = "" # This is cached + self._update_timer = QTimer() # type: QTimer + self._update_timer.setInterval(100) + self._update_timer.setSingleShot(True) + self._update_timer.timeout.connect(self._update) + self._update() + def _onChange(self) -> None: + self._update_timer.start() + def _update(self): Logger.log("d", "Updating {model_class_name}.".format(model_class_name = self.__class__.__name__)) From e4af883f251ee8e0e6be9db6ab9d5afa18a5652a Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 21 Dec 2018 18:19:34 +0100 Subject: [PATCH 1106/1292] Add missing signal --- cura/Settings/GlobalStack.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cura/Settings/GlobalStack.py b/cura/Settings/GlobalStack.py index 44ceee9511..8dba0f5204 100755 --- a/cura/Settings/GlobalStack.py +++ b/cura/Settings/GlobalStack.py @@ -97,6 +97,7 @@ class GlobalStack(CuraContainerStack): return self._extruders[position] = extruder + self.extrudersChanged.emit() Logger.log("i", "Extruder[%s] added to [%s] at position [%s]", extruder.id, self.id, position) ## Overridden from ContainerStack From 42058a2e8ff8d35c3adb89fbf324fbe353b3576d Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 24 Dec 2018 09:37:17 +0100 Subject: [PATCH 1107/1292] Revert "Prevent some unneeded calling of signals" This reverts commit 85f10e7c4f9bc48afd2fe43903e565b128e03189. The second time you start Cura, it won't slice due to the number of extruders being wrong. --- cura/Settings/ExtruderManager.py | 4 +--- cura/Settings/MachineManager.py | 1 + cura/Settings/SettingInheritanceManager.py | 1 + 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index 6e462031dc..8fa0172305 100755 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -344,9 +344,7 @@ class ExtruderManager(QObject): self._fixSingleExtrusionMachineExtruderDefinition(global_stack) if extruders_changed: self.extrudersChanged.emit(global_stack_id) - - # Set it directly instead of using setActiveExtruder, since we want to force the signal to emitted. - self._active_extruder_index = 0 + self.setActiveExtruderIndex(0) self.activeExtruderChanged.emit() # After 3.4, all single-extrusion machines have their own extruder definition files instead of reusing diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 755d05d71e..2185bbce9d 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -385,6 +385,7 @@ class MachineManager(QObject): self._application.setGlobalContainerStack(global_stack) ExtruderManager.getInstance()._globalContainerStackChanged() self._initMachineState(global_stack) + self._onGlobalContainerChanged() self.__emitChangedSignals() diff --git a/cura/Settings/SettingInheritanceManager.py b/cura/Settings/SettingInheritanceManager.py index 3815d85e81..12b541c3d8 100644 --- a/cura/Settings/SettingInheritanceManager.py +++ b/cura/Settings/SettingInheritanceManager.py @@ -249,6 +249,7 @@ class SettingInheritanceManager(QObject): if self._global_container_stack: self._global_container_stack.containersChanged.connect(self._onContainersChanged) self._global_container_stack.propertyChanged.connect(self._onPropertyChanged) + self._onActiveExtruderChanged() def _onContainersChanged(self, container): self._update_timer.start() From c6f4cb492761f1b80e71021d322ed78852e8af5f Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 24 Dec 2018 15:31:47 +0100 Subject: [PATCH 1108/1292] Make the settings panel resizable You can now drag the bottom side of the panel to make it bigger or smaller. Contributes to issue CURA-6054. --- cura/CuraApplication.py | 2 +- .../Custom/CustomPrintSetup.qml | 5 +- .../PrintSetupSelectorContents.qml | 48 ++++++++++++++++++- 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 9ec2435f0b..905c367cd1 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -499,7 +499,7 @@ class CuraApplication(QtApplication): preferences.addPreference("cura/choice_on_profile_override", "always_ask") preferences.addPreference("cura/choice_on_open_project", "always_ask") preferences.addPreference("cura/use_multi_build_plate", False) - + preferences.addPreference("view/settings_list_height", 600) preferences.addPreference("cura/currency", "€") preferences.addPreference("cura/material_settings", "{}") diff --git a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml index 51eb14a441..98bb5c0405 100644 --- a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml +++ b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml @@ -11,7 +11,6 @@ import Cura 1.0 as Cura Item { id: customPrintSetup - height: childrenRect.height + padding property real padding: UM.Theme.getSize("default_margin").width property bool multipleExtruders: extrudersModel.count > 1 @@ -98,15 +97,15 @@ Item Rectangle { - height: UM.Theme.getSize("print_setup_widget").height anchors { top: tabBar.visible ? tabBar.bottom : globalProfileRow.bottom + topMargin: -UM.Theme.getSize("default_lining").width left: parent.left leftMargin: parent.padding right: parent.right rightMargin: parent.padding - topMargin: -UM.Theme.getSize("default_lining").width + bottom: parent.bottom } z: tabBar.z - 1 // Don't show the border when only one extruder diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml index 6c678f7ce5..52c2807b81 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml @@ -15,7 +15,7 @@ Item id: content width: UM.Theme.getSize("print_setup_widget").width - 2 * UM.Theme.getSize("default_margin").width - height: childrenRect.height + height: contents.height + buttonRow.height enum Mode { @@ -71,6 +71,15 @@ Item right: parent.right top: parent.top } + height: UM.Preferences.getValue("view/settings_list_height") - UM.Theme.getSize("default_margin").height + Connections + { + target: UM.Preferences + onPreferenceChanged: + { + customPrintSetup.height = UM.Preferences.getValue("view/settings_list_height"); + } + } visible: currentModeIndex == PrintSetupSelectorContents.Mode.Custom } } @@ -94,13 +103,14 @@ Item anchors { - top: buttonsSeparator.bottom + bottom: parent.bottom left: parent.left right: parent.right } Cura.SecondaryButton { + id: recommendedButton anchors.top: parent.top anchors.left: parent.left anchors.margins: parent.padding @@ -125,5 +135,39 @@ Item visible: currentModeIndex == PrintSetupSelectorContents.Mode.Recommended onClicked: currentModeIndex = PrintSetupSelectorContents.Mode.Custom } + + //Invisible area at the bottom with which you can resize the panel. + MouseArea + { + anchors + { + left: parent.left + right: parent.right + bottom: parent.bottom + top: recommendedButton.bottom + topMargin: UM.Theme.getSize("default_lining").height + } + cursorShape: Qt.SplitVCursor + visible: currentModeIndex == PrintSetupSelectorContents.Mode.Custom + drag + { + target: parent + axis: Drag.YAxis + } + onMouseYChanged: + { + if(drag.active) + { + // position of mouse relative to dropdown align vertical centre of mouse area to cursor + // v------------------------------v v------------v + var h = mouseY + buttonRow.y + content.y - height / 2 | 0; + if(h < 200 * screenScaleFactor) //Enforce a minimum size. + { + h = 200 * screenScaleFactor; + } + UM.Preferences.setValue("view/settings_list_height", h); + } + } + } } } \ No newline at end of file From b7a23399f5bac16e0275647b23564558ada9185e Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 24 Dec 2018 15:37:48 +0100 Subject: [PATCH 1109/1292] Move action panel in front of settings panel The settings panel can now be so long that they overlap (if the user so chooses). This causes the action panel to be hidden behind the settings. We'd prefer to show the action panel in front, always. Contributes to issue CURA-6054. --- resources/qml/ActionPanel/ActionPanelWidget.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/qml/ActionPanel/ActionPanelWidget.qml b/resources/qml/ActionPanel/ActionPanelWidget.qml index a1cd81e9e9..1d9ee95548 100644 --- a/resources/qml/ActionPanel/ActionPanelWidget.qml +++ b/resources/qml/ActionPanel/ActionPanelWidget.qml @@ -23,6 +23,7 @@ Rectangle border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") radius: UM.Theme.getSize("default_radius").width + z: 10 property bool outputAvailable: UM.Backend.state == UM.Backend.Done || UM.Backend.state == UM.Backend.Disabled From c6c09a83271d368e68afec1ce106b246b770f1f4 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 24 Dec 2018 16:16:23 +0100 Subject: [PATCH 1110/1292] Limit height of settings drop-down to window size It seems to be very hard to limit it to not overlap with the action panel. Well, going out of the window is a bigger problem so at least we can fix that. Contributes to issue CURA-6054. --- .../qml/PrintSetupSelector/PrintSetupSelectorContents.qml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml index 52c2807b81..35c5f008b6 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml @@ -165,6 +165,14 @@ Item { h = 200 * screenScaleFactor; } + + //Absolute mouse Y position in the window, to prevent it from going outside the window. + var mouse_absolute_y = mapToGlobal(mouseX, mouseY).y - UM.Preferences.getValue("general/window_top"); + if(mouse_absolute_y > base.height) + { + h -= mouse_absolute_y - base.height; + } + UM.Preferences.setValue("view/settings_list_height", h); } } From f2a32e62fc8ab19b1dad9352a3a8e9aca965e149 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 27 Dec 2018 11:06:09 +0100 Subject: [PATCH 1111/1292] Rename 'Protected profiles' to 'Default profiles' We agreed that it looks better, especially when listed right above 'Custom profiles'. --- resources/qml/Preferences/ProfilesPage.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 7fb17b7aa1..d20519b361 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -408,7 +408,7 @@ Item { anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("default_lining").width - text: section == "true" ? catalog.i18nc("@label", "Protected profiles") : catalog.i18nc("@label", "Custom profiles") + text: section == "true" ? catalog.i18nc("@label", "Default profiles") : catalog.i18nc("@label", "Custom profiles") font.bold: true } } From 02f7a1476524dd39d2ac775ff1139a509a1bf856 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 27 Dec 2018 11:28:02 +0100 Subject: [PATCH 1112/1292] Fix ordering of a bunch of profiles --- resources/bundled_packages/cura.json | 4 ++-- resources/quality/abax_pri3/apri3_pla_fast.inst.cfg | 2 +- resources/quality/abax_pri5/apri5_pla_fast.inst.cfg | 2 +- resources/quality/abax_titan/atitan_pla_fast.inst.cfg | 2 +- .../anycubic_4max/abs/anycubic_4max_abs_draft.inst.cfg | 2 +- .../quality/anycubic_4max/abs/anycubic_4max_abs_high.inst.cfg | 2 +- .../anycubic_4max/abs/anycubic_4max_abs_normal.inst.cfg | 2 +- resources/quality/anycubic_4max/anycubic_4max_draft.inst.cfg | 2 +- resources/quality/anycubic_4max/anycubic_4max_high.inst.cfg | 2 +- resources/quality/anycubic_4max/anycubic_4max_normal.inst.cfg | 2 +- .../anycubic_4max/hips/anycubic_4max_hips_draft.inst.cfg | 2 +- .../anycubic_4max/hips/anycubic_4max_hips_high.inst.cfg | 2 +- .../anycubic_4max/hips/anycubic_4max_hips_normal.inst.cfg | 2 +- .../anycubic_4max/petg/anycubic_4max_petg_draft.inst.cfg | 2 +- .../anycubic_4max/petg/anycubic_4max_petg_high.inst.cfg | 2 +- .../anycubic_4max/petg/anycubic_4max_petg_normal.inst.cfg | 2 +- .../anycubic_4max/pla/anycubic_4max_pla_draft.inst.cfg | 2 +- .../quality/anycubic_4max/pla/anycubic_4max_pla_high.inst.cfg | 2 +- .../anycubic_4max/pla/anycubic_4max_pla_normal.inst.cfg | 2 +- .../quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg | 2 +- .../quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg | 2 +- .../quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg | 2 +- .../quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg | 2 +- .../quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg | 2 +- .../quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg | 2 +- .../cartesio/arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg | 2 +- .../quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg | 2 +- .../quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg | 2 +- .../quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg | 2 +- .../cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg | 2 +- .../quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg | 2 +- .../quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg | 2 +- .../quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg | 2 +- resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg | 2 +- resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg | 2 +- .../quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg | 2 +- .../quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg | 2 +- .../quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg | 2 +- .../quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg | 2 +- .../quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg | 2 +- .../quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg | 2 +- .../quality/deltacomb/deltacomb_abs_High_Quality.inst.cfg | 2 +- .../quality/deltacomb/deltacomb_global_High_Quality.inst.cfg | 2 +- .../quality/deltacomb/deltacomb_pla_High_Quality.inst.cfg | 2 +- .../quality/gmax15plus/gmax15plus_pla_dual_normal.inst.cfg | 2 +- .../quality/gmax15plus/gmax15plus_pla_dual_thin.inst.cfg | 2 +- resources/quality/gmax15plus/gmax15plus_pla_normal.inst.cfg | 2 +- resources/quality/gmax15plus/gmax15plus_pla_thin.inst.cfg | 2 +- .../malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg | 2 +- .../malyan_m200/malyan_m200_global_VeryDraft_Quality.inst.cfg | 2 +- .../malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg | 2 +- .../malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg | 2 +- .../abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg | 2 +- ...monoprice_select_mini_v2_global_VeryDraft_Quality.inst.cfg | 2 +- .../nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg | 2 +- .../pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg | 2 +- .../petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg | 2 +- .../pla/monoprice_select_mini_v2_pla_high.inst.cfg | 2 +- resources/quality/peopoly_moai/peopoly_moai_draft.inst.cfg | 2 +- resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg | 2 +- .../quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg | 2 +- .../quality/ultimaker2_plus/um2p_global_High_Quality.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg | 2 +- .../quality/ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.8_PC_Fast_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.8_PC_Superdraft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.8_PC_Verydraft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.8_aluminum_PC_Fast_Print.inst.cfg | 2 +- .../um_s5_aa0.8_aluminum_PC_Superdraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_aluminum_PC_Verydraft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_cc0.6_CFFCPE_Draft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_cc0.6_CFFPA_Draft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_cc0.6_GFFCPE_Draft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_cc0.6_GFFPA_Draft_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_global_High_Quality.inst.cfg | 2 +- resources/quality/zyyx/zyyx_agile_global_fine.inst.cfg | 2 +- resources/quality/zyyx/zyyx_agile_global_normal.inst.cfg | 2 +- resources/quality/zyyx/zyyx_agile_pro_flex_fine.inst.cfg | 2 +- resources/quality/zyyx/zyyx_agile_pro_flex_normal.inst.cfg | 2 +- resources/quality/zyyx/zyyx_agile_pro_pla_fine.inst.cfg | 2 +- resources/quality/zyyx/zyyx_agile_pro_pla_normal.inst.cfg | 2 +- 85 files changed, 86 insertions(+), 86 deletions(-) diff --git a/resources/bundled_packages/cura.json b/resources/bundled_packages/cura.json index c32b94af3f..99b8cd35a0 100644 --- a/resources/bundled_packages/cura.json +++ b/resources/bundled_packages/cura.json @@ -356,7 +356,7 @@ } } }, - "PreviewStage": { + "PreviewStage": { "package_info": { "package_id": "PreviewStage", "package_type": "plugin", @@ -1409,7 +1409,7 @@ "package_type": "material", "display_name": "Ultimaker PC", "description": "Example package for material and quality profiles for Ultimaker materials.", - "package_version": "1.2.1", + "package_version": "1.2.2", "sdk_version": "6.0", "website": "https://ultimaker.com/products/materials/pc", "author": { diff --git a/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg b/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg index 1d406e4387..ebb506a222 100644 --- a/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg +++ b/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg @@ -7,7 +7,7 @@ definition = abax_pri3 setting_version = 5 type = quality quality_type = normal -weight = -1 +weight = 0 material = generic_pla [values] diff --git a/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg b/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg index 6d0fdd40d2..f278788c68 100644 --- a/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg +++ b/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg @@ -7,7 +7,7 @@ definition = abax_pri5 setting_version = 5 type = quality quality_type = normal -weight = -1 +weight = 0 material = generic_pla [values] diff --git a/resources/quality/abax_titan/atitan_pla_fast.inst.cfg b/resources/quality/abax_titan/atitan_pla_fast.inst.cfg index 71740ede84..997e77041d 100644 --- a/resources/quality/abax_titan/atitan_pla_fast.inst.cfg +++ b/resources/quality/abax_titan/atitan_pla_fast.inst.cfg @@ -7,7 +7,7 @@ definition = abax_titan setting_version = 5 type = quality quality_type = normal -weight = -1 +weight = 0 material = generic_pla [values] diff --git a/resources/quality/anycubic_4max/abs/anycubic_4max_abs_draft.inst.cfg b/resources/quality/anycubic_4max/abs/anycubic_4max_abs_draft.inst.cfg index f5baa55029..9bb11389d2 100644 --- a/resources/quality/anycubic_4max/abs/anycubic_4max_abs_draft.inst.cfg +++ b/resources/quality/anycubic_4max/abs/anycubic_4max_abs_draft.inst.cfg @@ -7,7 +7,7 @@ definition = anycubic_4max setting_version = 5 type = quality quality_type = draft -weight = 0 +weight = -2 material = generic_abs [values] diff --git a/resources/quality/anycubic_4max/abs/anycubic_4max_abs_high.inst.cfg b/resources/quality/anycubic_4max/abs/anycubic_4max_abs_high.inst.cfg index bd613c6aad..4a09e0ee7c 100644 --- a/resources/quality/anycubic_4max/abs/anycubic_4max_abs_high.inst.cfg +++ b/resources/quality/anycubic_4max/abs/anycubic_4max_abs_high.inst.cfg @@ -7,7 +7,7 @@ definition = anycubic_4max setting_version = 5 type = quality quality_type = high -weight = 2 +weight = 1 material = generic_abs [values] diff --git a/resources/quality/anycubic_4max/abs/anycubic_4max_abs_normal.inst.cfg b/resources/quality/anycubic_4max/abs/anycubic_4max_abs_normal.inst.cfg index 7cff1db4d2..f415cb379f 100644 --- a/resources/quality/anycubic_4max/abs/anycubic_4max_abs_normal.inst.cfg +++ b/resources/quality/anycubic_4max/abs/anycubic_4max_abs_normal.inst.cfg @@ -7,7 +7,7 @@ definition = anycubic_4max setting_version = 5 type = quality quality_type = normal -weight = 1 +weight = 0 material = generic_abs [values] diff --git a/resources/quality/anycubic_4max/anycubic_4max_draft.inst.cfg b/resources/quality/anycubic_4max/anycubic_4max_draft.inst.cfg index c0114e3d6c..56810934c7 100644 --- a/resources/quality/anycubic_4max/anycubic_4max_draft.inst.cfg +++ b/resources/quality/anycubic_4max/anycubic_4max_draft.inst.cfg @@ -7,7 +7,7 @@ definition = anycubic_4max setting_version = 5 type = quality quality_type = draft -weight = 0 +weight = -2 global_quality = True [values] diff --git a/resources/quality/anycubic_4max/anycubic_4max_high.inst.cfg b/resources/quality/anycubic_4max/anycubic_4max_high.inst.cfg index 4a0993412a..4f35669ae2 100644 --- a/resources/quality/anycubic_4max/anycubic_4max_high.inst.cfg +++ b/resources/quality/anycubic_4max/anycubic_4max_high.inst.cfg @@ -7,7 +7,7 @@ definition = anycubic_4max setting_version = 5 type = quality quality_type = high -weight = 2 +weight = 1 global_quality = True [values] diff --git a/resources/quality/anycubic_4max/anycubic_4max_normal.inst.cfg b/resources/quality/anycubic_4max/anycubic_4max_normal.inst.cfg index eeb1d699e4..778764f005 100644 --- a/resources/quality/anycubic_4max/anycubic_4max_normal.inst.cfg +++ b/resources/quality/anycubic_4max/anycubic_4max_normal.inst.cfg @@ -7,7 +7,7 @@ definition = anycubic_4max setting_version = 5 type = quality quality_type = normal -weight = 1 +weight = 0 global_quality = True [values] diff --git a/resources/quality/anycubic_4max/hips/anycubic_4max_hips_draft.inst.cfg b/resources/quality/anycubic_4max/hips/anycubic_4max_hips_draft.inst.cfg index 3cd0226bd4..59b727e7be 100644 --- a/resources/quality/anycubic_4max/hips/anycubic_4max_hips_draft.inst.cfg +++ b/resources/quality/anycubic_4max/hips/anycubic_4max_hips_draft.inst.cfg @@ -7,7 +7,7 @@ definition = anycubic_4max setting_version = 5 type = quality quality_type = draft -weight = 0 +weight = -2 material = generic_hips [values] diff --git a/resources/quality/anycubic_4max/hips/anycubic_4max_hips_high.inst.cfg b/resources/quality/anycubic_4max/hips/anycubic_4max_hips_high.inst.cfg index ff5c6bee2f..1ddfe9ee4b 100644 --- a/resources/quality/anycubic_4max/hips/anycubic_4max_hips_high.inst.cfg +++ b/resources/quality/anycubic_4max/hips/anycubic_4max_hips_high.inst.cfg @@ -7,7 +7,7 @@ definition = anycubic_4max setting_version = 5 type = quality quality_type = high -weight = 2 +weight = 1 material = generic_hips [values] diff --git a/resources/quality/anycubic_4max/hips/anycubic_4max_hips_normal.inst.cfg b/resources/quality/anycubic_4max/hips/anycubic_4max_hips_normal.inst.cfg index c4701ae246..829392ad1f 100644 --- a/resources/quality/anycubic_4max/hips/anycubic_4max_hips_normal.inst.cfg +++ b/resources/quality/anycubic_4max/hips/anycubic_4max_hips_normal.inst.cfg @@ -7,7 +7,7 @@ definition = anycubic_4max setting_version = 5 type = quality quality_type = normal -weight = 1 +weight = 0 material = generic_hips [values] diff --git a/resources/quality/anycubic_4max/petg/anycubic_4max_petg_draft.inst.cfg b/resources/quality/anycubic_4max/petg/anycubic_4max_petg_draft.inst.cfg index 5e0c3e204a..028fe5d8a7 100644 --- a/resources/quality/anycubic_4max/petg/anycubic_4max_petg_draft.inst.cfg +++ b/resources/quality/anycubic_4max/petg/anycubic_4max_petg_draft.inst.cfg @@ -7,7 +7,7 @@ definition = anycubic_4max setting_version = 5 type = quality quality_type = draft -weight = 0 +weight = -2 material = generic_petg [values] diff --git a/resources/quality/anycubic_4max/petg/anycubic_4max_petg_high.inst.cfg b/resources/quality/anycubic_4max/petg/anycubic_4max_petg_high.inst.cfg index 57a89c4ec2..73eb73fe16 100644 --- a/resources/quality/anycubic_4max/petg/anycubic_4max_petg_high.inst.cfg +++ b/resources/quality/anycubic_4max/petg/anycubic_4max_petg_high.inst.cfg @@ -7,7 +7,7 @@ definition = anycubic_4max setting_version = 5 type = quality quality_type = high -weight = 2 +weight = 1 material = generic_petg [values] diff --git a/resources/quality/anycubic_4max/petg/anycubic_4max_petg_normal.inst.cfg b/resources/quality/anycubic_4max/petg/anycubic_4max_petg_normal.inst.cfg index 14a4607ceb..3ed9e5e707 100644 --- a/resources/quality/anycubic_4max/petg/anycubic_4max_petg_normal.inst.cfg +++ b/resources/quality/anycubic_4max/petg/anycubic_4max_petg_normal.inst.cfg @@ -7,7 +7,7 @@ definition = anycubic_4max setting_version = 5 type = quality quality_type = normal -weight = 1 +weight = 0 material = generic_petg [values] diff --git a/resources/quality/anycubic_4max/pla/anycubic_4max_pla_draft.inst.cfg b/resources/quality/anycubic_4max/pla/anycubic_4max_pla_draft.inst.cfg index eae9e3b5ef..fef5f88f97 100644 --- a/resources/quality/anycubic_4max/pla/anycubic_4max_pla_draft.inst.cfg +++ b/resources/quality/anycubic_4max/pla/anycubic_4max_pla_draft.inst.cfg @@ -7,7 +7,7 @@ definition = anycubic_4max setting_version = 5 type = quality quality_type = draft -weight = 0 +weight = -2 material = generic_pla [values] diff --git a/resources/quality/anycubic_4max/pla/anycubic_4max_pla_high.inst.cfg b/resources/quality/anycubic_4max/pla/anycubic_4max_pla_high.inst.cfg index c856fc66a7..edfa07067b 100644 --- a/resources/quality/anycubic_4max/pla/anycubic_4max_pla_high.inst.cfg +++ b/resources/quality/anycubic_4max/pla/anycubic_4max_pla_high.inst.cfg @@ -7,7 +7,7 @@ definition = anycubic_4max setting_version = 5 type = quality quality_type = high -weight = 2 +weight = 1 material = generic_pla [values] diff --git a/resources/quality/anycubic_4max/pla/anycubic_4max_pla_normal.inst.cfg b/resources/quality/anycubic_4max/pla/anycubic_4max_pla_normal.inst.cfg index be33bfe53a..e90bac1a0b 100644 --- a/resources/quality/anycubic_4max/pla/anycubic_4max_pla_normal.inst.cfg +++ b/resources/quality/anycubic_4max/pla/anycubic_4max_pla_normal.inst.cfg @@ -7,7 +7,7 @@ definition = anycubic_4max setting_version = 5 type = quality quality_type = normal -weight = 1 +weight = 0 material = generic_pla [values] diff --git a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg index e94b9f01d1..b4f8ba78ed 100644 --- a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg +++ b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg @@ -7,7 +7,7 @@ definition = anycubic_i3_mega setting_version = 5 type = quality quality_type = draft -weight = 0 +weight = -2 global_quality = True [values] diff --git a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg index c8c4bf9a81..c727764c5d 100644 --- a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg +++ b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg @@ -7,7 +7,7 @@ definition = anycubic_i3_mega setting_version = 5 type = quality quality_type = high -weight = 2 +weight = 1 global_quality = True [values] diff --git a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg index 399c3ebc55..beb7d98b8e 100644 --- a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg +++ b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg @@ -7,7 +7,7 @@ definition = anycubic_i3_mega setting_version = 5 type = quality quality_type = normal -weight = 1 +weight = 0 global_quality = True [values] diff --git a/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg index f74918ef4f..f0b4581b90 100644 --- a/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg @@ -7,7 +7,7 @@ definition = cartesio setting_version = 5 type = quality quality_type = normal -weight = 2 +weight = 0 material = generic_abs variant = 0.25mm thermoplastic extruder diff --git a/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg index ab72092035..5ee76e8e2b 100644 --- a/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg @@ -7,7 +7,7 @@ definition = cartesio setting_version = 5 type = quality quality_type = normal -weight = 2 +weight = 0 material = generic_abs variant = 0.4mm thermoplastic extruder diff --git a/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg index 9eea2177a8..82a980538c 100644 --- a/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg @@ -7,7 +7,7 @@ definition = cartesio setting_version = 5 type = quality quality_type = normal -weight = 2 +weight = 0 material = generic_abs variant = 0.8mm thermoplastic extruder diff --git a/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg b/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg index 8215eb2f50..50dc4d42a0 100644 --- a/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg +++ b/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg @@ -7,7 +7,7 @@ definition = cartesio setting_version = 5 type = quality quality_type = normal -weight = 2 +weight = 0 material = dsm_arnitel2045_175 variant = 0.4mm thermoplastic extruder diff --git a/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg index 0cf82847a0..08d1cf709e 100644 --- a/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg @@ -7,7 +7,7 @@ definition = cartesio setting_version = 5 type = quality quality_type = normal -weight = 2 +weight = 0 material = generic_hips variant = 0.25mm thermoplastic extruder diff --git a/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg index 8101fb6dd8..18daa16d97 100644 --- a/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg @@ -7,7 +7,7 @@ definition = cartesio setting_version = 5 type = quality quality_type = normal -weight = 2 +weight = 0 material = generic_hips variant = 0.4mm thermoplastic extruder diff --git a/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg index 0b019d555f..5afc358d51 100644 --- a/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg @@ -7,7 +7,7 @@ definition = cartesio setting_version = 5 type = quality quality_type = normal -weight = 2 +weight = 0 material = generic_hips variant = 0.8mm thermoplastic extruder diff --git a/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg index e0100d37ec..b8d17bcc8f 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg @@ -7,7 +7,7 @@ definition = cartesio setting_version = 5 type = quality quality_type = normal -weight = 2 +weight = 0 material = generic_nylon variant = 0.25mm thermoplastic extruder diff --git a/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg index 7d899ae927..b208462ed7 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg @@ -7,7 +7,7 @@ definition = cartesio setting_version = 5 type = quality quality_type = normal -weight = 2 +weight = 0 material = generic_nylon variant = 0.4mm thermoplastic extruder diff --git a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg index 95be159ff2..3c51389cc8 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg @@ -7,7 +7,7 @@ definition = cartesio setting_version = 5 type = quality quality_type = normal -weight = 2 +weight = 0 material = generic_nylon variant = 0.8mm thermoplastic extruder diff --git a/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg index 248517d769..cca1922fa1 100644 --- a/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg @@ -7,7 +7,7 @@ definition = cartesio setting_version = 5 type = quality quality_type = normal -weight = 2 +weight = 0 material = generic_pc variant = 0.25mm thermoplastic extruder diff --git a/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg index a0b71f1f0a..6dc8225f82 100644 --- a/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg @@ -7,7 +7,7 @@ definition = cartesio setting_version = 5 type = quality quality_type = normal -weight = 2 +weight = 0 material = generic_pc variant = 0.4mm thermoplastic extruder diff --git a/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg index 173ad406f3..b47f7f1ded 100644 --- a/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg @@ -7,7 +7,7 @@ definition = cartesio setting_version = 5 type = quality quality_type = normal -weight = 2 +weight = 0 material = generic_pc variant = 0.8mm thermoplastic extruder diff --git a/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg index 019af9d905..d9f358360d 100644 --- a/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg @@ -7,7 +7,7 @@ definition = cartesio setting_version = 5 type = quality quality_type = normal -weight = 2 +weight = 0 material = generic_petg variant = 0.25mm thermoplastic extruder diff --git a/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg index ed17ccce31..f5269d4e88 100644 --- a/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg @@ -7,7 +7,7 @@ definition = cartesio setting_version = 5 type = quality quality_type = normal -weight = 2 +weight = 0 material = generic_petg variant = 0.4mm thermoplastic extruder diff --git a/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg index 08f918f59b..ef4b5428c0 100644 --- a/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg @@ -7,7 +7,7 @@ definition = cartesio setting_version = 5 type = quality quality_type = normal -weight = 2 +weight = 0 material = generic_petg variant = 0.8mm thermoplastic extruder diff --git a/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg index 6525991986..940432e07e 100644 --- a/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg @@ -7,7 +7,7 @@ definition = cartesio setting_version = 5 type = quality quality_type = normal -weight = 2 +weight = 0 material = generic_pva variant = 0.25mm thermoplastic extruder diff --git a/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg index e7267735e4..9a0e279e6a 100644 --- a/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg @@ -7,7 +7,7 @@ definition = cartesio setting_version = 5 type = quality quality_type = normal -weight = 2 +weight = 0 material = generic_pva variant = 0.4mm thermoplastic extruder diff --git a/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg index a6c0a89fcc..1d8cd52d0d 100644 --- a/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg @@ -7,7 +7,7 @@ definition = cartesio setting_version = 5 type = quality quality_type = normal -weight = 2 +weight = 0 material = generic_pva variant = 0.8mm thermoplastic extruder diff --git a/resources/quality/deltacomb/deltacomb_abs_High_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_abs_High_Quality.inst.cfg index c196209553..d407b66762 100644 --- a/resources/quality/deltacomb/deltacomb_abs_High_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_abs_High_Quality.inst.cfg @@ -7,7 +7,7 @@ definition = deltacomb setting_version = 5 type = quality quality_type = high -weight = 0 +weight = 1 material = generic_abs [values] diff --git a/resources/quality/deltacomb/deltacomb_global_High_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_global_High_Quality.inst.cfg index d6d853466a..b56b222eb1 100755 --- a/resources/quality/deltacomb/deltacomb_global_High_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_global_High_Quality.inst.cfg @@ -7,7 +7,7 @@ definition = deltacomb setting_version = 5 type = quality quality_type = high -weight = 0 +weight = 1 global_quality = True [values] diff --git a/resources/quality/deltacomb/deltacomb_pla_High_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_pla_High_Quality.inst.cfg index 774b8969c0..440bac36e9 100644 --- a/resources/quality/deltacomb/deltacomb_pla_High_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_pla_High_Quality.inst.cfg @@ -7,7 +7,7 @@ definition = deltacomb setting_version = 5 type = quality quality_type = high -weight = 0 +weight = 1 material = generic_pla [values] diff --git a/resources/quality/gmax15plus/gmax15plus_pla_dual_normal.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_dual_normal.inst.cfg index 7fd2ab2296..4bd83d5950 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_dual_normal.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_dual_normal.inst.cfg @@ -7,7 +7,7 @@ definition = gmax15plus_dual setting_version = 5 type = quality quality_type = normal -weight = -1 +weight = 0 [values] layer_height = 0.2 diff --git a/resources/quality/gmax15plus/gmax15plus_pla_dual_thin.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_dual_thin.inst.cfg index decafac241..e85a70d069 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_dual_thin.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_dual_thin.inst.cfg @@ -7,7 +7,7 @@ definition = gmax15plus_dual setting_version = 5 type = quality quality_type = high -weight = 0 +weight = 1 [values] layer_height = 0.16 diff --git a/resources/quality/gmax15plus/gmax15plus_pla_normal.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_normal.inst.cfg index ddf5a4c491..afecc2ef58 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_normal.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_normal.inst.cfg @@ -7,7 +7,7 @@ definition = gmax15plus setting_version = 5 type = quality quality_type = normal -weight = -1 +weight = 0 [values] layer_height = 0.2 diff --git a/resources/quality/gmax15plus/gmax15plus_pla_thin.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_thin.inst.cfg index d119539d32..41d32cb6b9 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_thin.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_thin.inst.cfg @@ -7,7 +7,7 @@ definition = gmax15plus setting_version = 5 type = quality quality_type = high -weight = 0 +weight = 1 [values] layer_height = 0.16 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg index 373908b2bd..a3d8bd4579 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg @@ -7,7 +7,7 @@ definition = malyan_m200 setting_version = 5 type = quality quality_type = verydraft -weight = -4 +weight = -3 material = generic_abs [values] diff --git a/resources/quality/malyan_m200/malyan_m200_global_VeryDraft_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_VeryDraft_Quality.inst.cfg index 42c670920f..a3013a68fb 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_VeryDraft_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_VeryDraft_Quality.inst.cfg @@ -7,7 +7,7 @@ definition = malyan_m200 setting_version = 5 type = quality quality_type = verydraft -weight = -4 +weight = -3 global_quality = True [values] diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg index 2f33760afa..e0305105af 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg @@ -7,5 +7,5 @@ definition = malyan_m200 setting_version = 5 type = quality quality_type = verydraft -weight = -4 +weight = -3 material = generic_petg diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg index 7d96a9f56d..a79d253e49 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg @@ -7,7 +7,7 @@ definition = malyan_m200 setting_version = 5 type = quality quality_type = verydraft -weight = -4 +weight = -3 material = generic_pla [values] diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg index 279f58d64f..21d1215dca 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg @@ -7,7 +7,7 @@ definition = monoprice_select_mini_v2 setting_version = 5 type = quality quality_type = verydraft -weight = -4 +weight = -3 material = generic_abs [values] diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_VeryDraft_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_VeryDraft_Quality.inst.cfg index 79d9c8abb9..36aa5a9a37 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_VeryDraft_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_VeryDraft_Quality.inst.cfg @@ -7,7 +7,7 @@ definition = monoprice_select_mini_v2 setting_version = 5 type = quality quality_type = verydraft -weight = -4 +weight = -3 global_quality = True [values] diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg index 8f568d3948..40f6a9f53d 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg @@ -7,5 +7,5 @@ definition = monoprice_select_mini_v2 setting_version = 5 type = quality quality_type = verydraft -weight = -4 +weight = -3 material = generic_nylon diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg index 23b72a3a3b..5202565894 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg @@ -7,7 +7,7 @@ definition = monoprice_select_mini_v2 setting_version = 5 type = quality quality_type = verydraft -weight = -4 +weight = -3 material = generic_pc [values] diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg index 99874f0571..a9f891692a 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg @@ -7,5 +7,5 @@ definition = monoprice_select_mini_v2 setting_version = 5 type = quality quality_type = verydraft -weight = -4 +weight = -3 material = generic_petg diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg index 9f64ce57f0..f8458ce63b 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg @@ -7,5 +7,5 @@ definition = monoprice_select_mini_v2 setting_version = 5 type = quality quality_type = high -weight = 0 +weight = 1 material = generic_pla diff --git a/resources/quality/peopoly_moai/peopoly_moai_draft.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_draft.inst.cfg index 2d21b1f7e0..53abc477ae 100644 --- a/resources/quality/peopoly_moai/peopoly_moai_draft.inst.cfg +++ b/resources/quality/peopoly_moai/peopoly_moai_draft.inst.cfg @@ -7,7 +7,7 @@ definition = peopoly_moai setting_version = 5 type = quality quality_type = draft -weight = 4 +weight = -2 [values] layer_height = 0.1 diff --git a/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg index cf67591ab2..89d0aa2980 100644 --- a/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg +++ b/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg @@ -7,7 +7,7 @@ definition = peopoly_moai setting_version = 5 type = quality quality_type = normal -weight = 2 +weight = 0 [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg index eca5070eb9..8f225271d6 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg @@ -7,7 +7,7 @@ definition = ultimaker2_plus setting_version = 5 type = quality quality_type = high -weight = -1 +weight = 1 material = generic_cpe variant = 0.25 mm diff --git a/resources/quality/ultimaker2_plus/um2p_global_High_Quality.inst.cfg b/resources/quality/ultimaker2_plus/um2p_global_High_Quality.inst.cfg index ade183d14a..c47efcfb7d 100644 --- a/resources/quality/ultimaker2_plus/um2p_global_High_Quality.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_global_High_Quality.inst.cfg @@ -7,7 +7,7 @@ definition = ultimaker2_plus setting_version = 5 type = quality quality_type = high -weight = 0 +weight = 1 global_quality = True [values] diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg index 2bba1be3d4..f0da3e678d 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg @@ -7,7 +7,7 @@ definition = ultimaker2_plus setting_version = 5 type = quality quality_type = fast -weight = -2 +weight = -1 material = generic_pp variant = 0.8 mm diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg index 15f7577bdb..586eb04dd8 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg @@ -7,7 +7,7 @@ definition = ultimaker2_plus setting_version = 5 type = quality quality_type = draft -weight = -3 +weight = -2 material = generic_pp variant = 0.8 mm diff --git a/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg index c2bb6d4988..80be29ed85 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg @@ -7,7 +7,7 @@ definition = ultimaker3 setting_version = 5 type = quality quality_type = draft -weight = 0 +weight = -2 material = generic_pc variant = AA 0.8 is_experimental = True diff --git a/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg index e815b673d1..149712dde9 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg @@ -7,7 +7,7 @@ definition = ultimaker3 setting_version = 5 type = quality quality_type = superdraft -weight = -2 +weight = -4 material = generic_pc variant = AA 0.8 is_experimental = True diff --git a/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg index c50cee576d..7311cc43a6 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg @@ -7,7 +7,7 @@ definition = ultimaker3 setting_version = 5 type = quality quality_type = verydraft -weight = -1 +weight = -3 material = generic_pc variant = AA 0.8 is_experimental = True diff --git a/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg index ce5497bd39..a1fa758163 100644 --- a/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg @@ -7,7 +7,7 @@ definition = ultimaker3 setting_version = 5 type = quality quality_type = high -weight = 0 +weight = 1 global_quality = True [values] diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Fast_Print.inst.cfg index c24aa9a98d..378028694b 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Fast_Print.inst.cfg @@ -7,7 +7,7 @@ definition = ultimaker_s5 setting_version = 5 type = quality quality_type = draft -weight = 0 +weight = -2 material = generic_pc variant = AA 0.8 is_experimental = True diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Superdraft_Print.inst.cfg index 5fc306b1f1..a179d6b7c9 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Superdraft_Print.inst.cfg @@ -7,7 +7,7 @@ definition = ultimaker_s5 setting_version = 5 type = quality quality_type = superdraft -weight = -2 +weight = -4 material = generic_pc variant = AA 0.8 is_experimental = True diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Verydraft_Print.inst.cfg index 996adf5be7..b474cb23d9 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Verydraft_Print.inst.cfg @@ -7,7 +7,7 @@ definition = ultimaker_s5 setting_version = 5 type = quality quality_type = verydraft -weight = -1 +weight = -3 material = generic_pc variant = AA 0.8 is_experimental = True diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Fast_Print.inst.cfg index 6fdd22c6b0..a313ac56fc 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Fast_Print.inst.cfg @@ -7,7 +7,7 @@ definition = ultimaker_s5 setting_version = 5 type = quality quality_type = draft -weight = 0 +weight = -2 material = generic_pc variant = AA 0.8 buildplate = Aluminum diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Superdraft_Print.inst.cfg index 689652dc06..f1c1762d2c 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Superdraft_Print.inst.cfg @@ -7,7 +7,7 @@ definition = ultimaker_s5 setting_version = 5 type = quality quality_type = superdraft -weight = -2 +weight = -4 material = generic_pc variant = AA 0.8 buildplate = Aluminum diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Verydraft_Print.inst.cfg index 0480ee5620..399c139412 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Verydraft_Print.inst.cfg @@ -7,7 +7,7 @@ definition = ultimaker_s5 setting_version = 5 type = quality quality_type = verydraft -weight = -1 +weight = -3 material = generic_pc variant = AA 0.8 buildplate = Aluminum diff --git a/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFCPE_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFCPE_Draft_Print.inst.cfg index 99b4b142fa..feb8891d26 100644 --- a/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFCPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFCPE_Draft_Print.inst.cfg @@ -7,7 +7,7 @@ definition = ultimaker_s5 setting_version = 5 type = quality quality_type = draft -weight = -3 +weight = -2 material = generic_cffcpe variant = CC 0.6 diff --git a/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFPA_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFPA_Draft_Print.inst.cfg index 80c383aa8d..980ded99e9 100644 --- a/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFPA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFPA_Draft_Print.inst.cfg @@ -7,7 +7,7 @@ definition = ultimaker_s5 setting_version = 5 type = quality quality_type = draft -weight = -3 +weight = -2 material = generic_cffpa variant = CC 0.6 diff --git a/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFCPE_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFCPE_Draft_Print.inst.cfg index c94d239c81..331c5e6d73 100644 --- a/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFCPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFCPE_Draft_Print.inst.cfg @@ -7,7 +7,7 @@ definition = ultimaker_s5 setting_version = 5 type = quality quality_type = draft -weight = -3 +weight = -2 material = generic_gffcpe variant = CC 0.6 diff --git a/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFPA_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFPA_Draft_Print.inst.cfg index e7d4d1955b..0e90d6df78 100644 --- a/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFPA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFPA_Draft_Print.inst.cfg @@ -7,7 +7,7 @@ definition = ultimaker_s5 setting_version = 5 type = quality quality_type = draft -weight = -3 +weight = -2 material = generic_gffpa variant = CC 0.6 diff --git a/resources/quality/ultimaker_s5/um_s5_global_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_global_High_Quality.inst.cfg index cd1c269b1d..96005a48da 100644 --- a/resources/quality/ultimaker_s5/um_s5_global_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_global_High_Quality.inst.cfg @@ -7,7 +7,7 @@ definition = ultimaker_s5 setting_version = 5 type = quality quality_type = high -weight = 0 +weight = 1 global_quality = True [values] diff --git a/resources/quality/zyyx/zyyx_agile_global_fine.inst.cfg b/resources/quality/zyyx/zyyx_agile_global_fine.inst.cfg index 58e13b22c5..b8bc7eb628 100644 --- a/resources/quality/zyyx/zyyx_agile_global_fine.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_global_fine.inst.cfg @@ -7,7 +7,7 @@ definition = zyyx_agile setting_version = 5 type = quality quality_type = fine -weight = 3 +weight = 1 global_quality = True [values] diff --git a/resources/quality/zyyx/zyyx_agile_global_normal.inst.cfg b/resources/quality/zyyx/zyyx_agile_global_normal.inst.cfg index cb4e042e7b..3f934b0114 100644 --- a/resources/quality/zyyx/zyyx_agile_global_normal.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_global_normal.inst.cfg @@ -7,7 +7,7 @@ definition = zyyx_agile setting_version = 5 type = quality quality_type = normal -weight = 2 +weight = 0 global_quality = True [values] diff --git a/resources/quality/zyyx/zyyx_agile_pro_flex_fine.inst.cfg b/resources/quality/zyyx/zyyx_agile_pro_flex_fine.inst.cfg index 6654889c10..d69bc930e9 100644 --- a/resources/quality/zyyx/zyyx_agile_pro_flex_fine.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_pro_flex_fine.inst.cfg @@ -7,7 +7,7 @@ definition = zyyx_agile setting_version = 5 type = quality quality_type = fine -weight = 3 +weight = 1 material = generic_tpu [values] diff --git a/resources/quality/zyyx/zyyx_agile_pro_flex_normal.inst.cfg b/resources/quality/zyyx/zyyx_agile_pro_flex_normal.inst.cfg index f56355100c..d717f11528 100644 --- a/resources/quality/zyyx/zyyx_agile_pro_flex_normal.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_pro_flex_normal.inst.cfg @@ -7,7 +7,7 @@ definition = zyyx_agile setting_version = 5 type = quality quality_type = normal -weight = 2 +weight = 0 material = generic_tpu [values] diff --git a/resources/quality/zyyx/zyyx_agile_pro_pla_fine.inst.cfg b/resources/quality/zyyx/zyyx_agile_pro_pla_fine.inst.cfg index 64c7d4afc8..44b722ac32 100644 --- a/resources/quality/zyyx/zyyx_agile_pro_pla_fine.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_pro_pla_fine.inst.cfg @@ -7,7 +7,7 @@ definition = zyyx_agile setting_version = 5 type = quality quality_type = fine -weight = 3 +weight = 1 material = generic_pla [values] diff --git a/resources/quality/zyyx/zyyx_agile_pro_pla_normal.inst.cfg b/resources/quality/zyyx/zyyx_agile_pro_pla_normal.inst.cfg index dbdd600ece..01424a9422 100644 --- a/resources/quality/zyyx/zyyx_agile_pro_pla_normal.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_pro_pla_normal.inst.cfg @@ -7,7 +7,7 @@ definition = zyyx_agile setting_version = 5 type = quality quality_type = normal -weight = 2 +weight = 0 material = generic_pla [values] From abe684c1bda37bb1ca7c7f82dd07b6720a5d22c1 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 27 Dec 2018 13:08:25 +0100 Subject: [PATCH 1113/1292] Use Item instead of rectangle without defined colour Item should be faster to render. Contributes to issue CURA-6056. --- resources/qml/Preferences/Materials/MaterialsBrandSection.qml | 2 +- resources/qml/Preferences/Materials/MaterialsTypeSection.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Preferences/Materials/MaterialsBrandSection.qml b/resources/qml/Preferences/Materials/MaterialsBrandSection.qml index c40693e343..c976233805 100644 --- a/resources/qml/Preferences/Materials/MaterialsBrandSection.qml +++ b/resources/qml/Preferences/Materials/MaterialsBrandSection.qml @@ -10,7 +10,7 @@ import QtQuick.Dialogs 1.2 import UM 1.2 as UM import Cura 1.0 as Cura -Rectangle +Item { id: brand_section diff --git a/resources/qml/Preferences/Materials/MaterialsTypeSection.qml b/resources/qml/Preferences/Materials/MaterialsTypeSection.qml index f98c19e0b3..8f34217cce 100644 --- a/resources/qml/Preferences/Materials/MaterialsTypeSection.qml +++ b/resources/qml/Preferences/Materials/MaterialsTypeSection.qml @@ -10,7 +10,7 @@ import QtQuick.Dialogs 1.2 import UM 1.2 as UM import Cura 1.0 as Cura -Rectangle +Item { id: material_type_section property var materialType From 88d6e0bcaf29f14df298ce0b63224be56bbdc81a Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 27 Dec 2018 16:27:26 +0100 Subject: [PATCH 1114/1292] Correct inst.cfg version Contributes to issue CURA-5848. --- resources/variants/gmax15plus_025_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_dual_025_e3d.inst.cfg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/variants/gmax15plus_025_e3d.inst.cfg b/resources/variants/gmax15plus_025_e3d.inst.cfg index f106b13be1..8a6b37067d 100644 --- a/resources/variants/gmax15plus_025_e3d.inst.cfg +++ b/resources/variants/gmax15plus_025_e3d.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.25mm E3D (Difficult) -version = 2 +version = 4 definition = gmax15plus [metadata] diff --git a/resources/variants/gmax15plus_dual_025_e3d.inst.cfg b/resources/variants/gmax15plus_dual_025_e3d.inst.cfg index d5f6457902..750a5381b3 100644 --- a/resources/variants/gmax15plus_dual_025_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_025_e3d.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.25mm E3D (Difficult) -version = 2 +version = 4 definition = gmax15plus_dual [metadata] From 139ab2e0bb0bed3661d70a945105a2a75a5c1341 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 27 Dec 2018 16:39:05 +0100 Subject: [PATCH 1115/1292] Increment setting_version to 6 Because Cura 4.1 is going to have a version upgrade to change the stack files. Contributes to issue CURA-5848. --- cura/CuraApplication.py | 2 +- resources/quality/abax_pri3/apri3_pla_fast.inst.cfg | 2 +- resources/quality/abax_pri3/apri3_pla_high.inst.cfg | 2 +- resources/quality/abax_pri3/apri3_pla_normal.inst.cfg | 2 +- resources/quality/abax_pri5/apri5_pla_fast.inst.cfg | 2 +- resources/quality/abax_pri5/apri5_pla_high.inst.cfg | 2 +- resources/quality/abax_pri5/apri5_pla_normal.inst.cfg | 2 +- resources/quality/abax_titan/atitan_pla_fast.inst.cfg | 2 +- resources/quality/abax_titan/atitan_pla_high.inst.cfg | 2 +- resources/quality/abax_titan/atitan_pla_normal.inst.cfg | 2 +- .../quality/anycubic_4max/abs/anycubic_4max_abs_draft.inst.cfg | 2 +- .../quality/anycubic_4max/abs/anycubic_4max_abs_high.inst.cfg | 2 +- .../quality/anycubic_4max/abs/anycubic_4max_abs_normal.inst.cfg | 2 +- resources/quality/anycubic_4max/anycubic_4max_draft.inst.cfg | 2 +- resources/quality/anycubic_4max/anycubic_4max_high.inst.cfg | 2 +- resources/quality/anycubic_4max/anycubic_4max_normal.inst.cfg | 2 +- .../anycubic_4max/hips/anycubic_4max_hips_draft.inst.cfg | 2 +- .../quality/anycubic_4max/hips/anycubic_4max_hips_high.inst.cfg | 2 +- .../anycubic_4max/hips/anycubic_4max_hips_normal.inst.cfg | 2 +- .../anycubic_4max/petg/anycubic_4max_petg_draft.inst.cfg | 2 +- .../quality/anycubic_4max/petg/anycubic_4max_petg_high.inst.cfg | 2 +- .../anycubic_4max/petg/anycubic_4max_petg_normal.inst.cfg | 2 +- .../quality/anycubic_4max/pla/anycubic_4max_pla_draft.inst.cfg | 2 +- .../quality/anycubic_4max/pla/anycubic_4max_pla_high.inst.cfg | 2 +- .../quality/anycubic_4max/pla/anycubic_4max_pla_normal.inst.cfg | 2 +- .../quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg | 2 +- .../quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg | 2 +- .../quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg | 2 +- .../quality/builder_premium/bp_BVOH_Coarse_Quality.inst.cfg | 2 +- resources/quality/builder_premium/bp_BVOH_High_Quality.inst.cfg | 2 +- .../quality/builder_premium/bp_BVOH_Normal_Quality.inst.cfg | 2 +- .../builder_premium/bp_Innoflex60_Coarse_Quality.inst.cfg | 2 +- .../quality/builder_premium/bp_Innoflex60_High_Quality.inst.cfg | 2 +- .../builder_premium/bp_Innoflex60_Normal_Quality.inst.cfg | 2 +- .../quality/builder_premium/bp_PET_Coarse_Quality.inst.cfg | 2 +- resources/quality/builder_premium/bp_PET_High_Quality.inst.cfg | 2 +- .../quality/builder_premium/bp_PET_Normal_Quality.inst.cfg | 2 +- .../quality/builder_premium/bp_PLA_Coarse_Quality.inst.cfg | 2 +- resources/quality/builder_premium/bp_PLA_High_Quality.inst.cfg | 2 +- .../quality/builder_premium/bp_PLA_Normal_Quality.inst.cfg | 2 +- .../quality/builder_premium/bp_PVA_Coarse_Quality.inst.cfg | 2 +- resources/quality/builder_premium/bp_PVA_High_Quality.inst.cfg | 2 +- .../quality/builder_premium/bp_PVA_Normal_Quality.inst.cfg | 2 +- .../quality/builder_premium/bp_global_Coarse_Quality.inst.cfg | 2 +- .../quality/builder_premium/bp_global_High_Quality.inst.cfg | 2 +- .../quality/builder_premium/bp_global_Normal_Quality.inst.cfg | 2 +- resources/quality/cartesio/abs/cartesio_0.25_abs_high.inst.cfg | 2 +- .../quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg | 2 +- resources/quality/cartesio/abs/cartesio_0.4_abs_high.inst.cfg | 2 +- resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg | 2 +- resources/quality/cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg | 2 +- .../quality/cartesio/abs/cartesio_0.8_abs_extra_coarse.inst.cfg | 2 +- resources/quality/cartesio/abs/cartesio_0.8_abs_high.inst.cfg | 2 +- resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg | 2 +- .../cartesio/arnitel/cartesio_0.4_arnitel2045_high.inst.cfg | 2 +- .../cartesio/arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg | 2 +- .../quality/cartesio/cartesio_global_Coarse_Quality.inst.cfg | 2 +- .../cartesio/cartesio_global_Extra_Coarse_Quality.inst.cfg | 2 +- .../quality/cartesio/cartesio_global_High_Quality.inst.cfg | 2 +- .../quality/cartesio/cartesio_global_Normal_Quality.inst.cfg | 2 +- .../quality/cartesio/hips/cartesio_0.25_hips_high.inst.cfg | 2 +- .../quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg | 2 +- resources/quality/cartesio/hips/cartesio_0.4_hips_high.inst.cfg | 2 +- .../quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg | 2 +- .../quality/cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg | 2 +- .../cartesio/hips/cartesio_0.8_hips_extra_coarse.inst.cfg | 2 +- resources/quality/cartesio/hips/cartesio_0.8_hips_high.inst.cfg | 2 +- .../quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg | 2 +- .../quality/cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg | 2 +- .../quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg | 2 +- .../quality/cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg | 2 +- .../quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg | 2 +- .../quality/cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg | 2 +- .../cartesio/nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg | 2 +- .../quality/cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg | 2 +- .../quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg | 2 +- resources/quality/cartesio/pc/cartesio_0.25_pc_high.inst.cfg | 2 +- resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg | 2 +- resources/quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg | 2 +- resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg | 2 +- resources/quality/cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg | 2 +- .../quality/cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg | 2 +- resources/quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg | 2 +- resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg | 2 +- .../quality/cartesio/petg/cartesio_0.25_petg_high.inst.cfg | 2 +- .../quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg | 2 +- resources/quality/cartesio/petg/cartesio_0.4_petg_high.inst.cfg | 2 +- .../quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg | 2 +- .../quality/cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg | 2 +- .../cartesio/petg/cartesio_0.8_petg_extra_coarse.inst.cfg | 2 +- resources/quality/cartesio/petg/cartesio_0.8_petg_high.inst.cfg | 2 +- .../quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg | 2 +- resources/quality/cartesio/pla/cartesio_0.25_pla_high.inst.cfg | 2 +- .../quality/cartesio/pla/cartesio_0.25_pla_normal.inst.cfg | 2 +- resources/quality/cartesio/pla/cartesio_0.4_pla_high.inst.cfg | 2 +- resources/quality/cartesio/pla/cartesio_0.4_pla_normal.inst.cfg | 2 +- resources/quality/cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg | 2 +- .../quality/cartesio/pla/cartesio_0.8_pla_extra_coarse.inst.cfg | 2 +- resources/quality/cartesio/pla/cartesio_0.8_pla_high.inst.cfg | 2 +- resources/quality/cartesio/pla/cartesio_0.8_pla_normal.inst.cfg | 2 +- resources/quality/cartesio/pva/cartesio_0.25_pva_high.inst.cfg | 2 +- .../quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg | 2 +- resources/quality/cartesio/pva/cartesio_0.4_pva_high.inst.cfg | 2 +- resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg | 2 +- resources/quality/cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg | 2 +- .../quality/cartesio/pva/cartesio_0.8_pva_extra_coarse.inst.cfg | 2 +- resources/quality/cartesio/pva/cartesio_0.8_pva_high.inst.cfg | 2 +- resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg | 2 +- resources/quality/coarse.inst.cfg | 2 +- resources/quality/dagoma/dagoma_discoeasy200_pla_fast.inst.cfg | 2 +- resources/quality/dagoma/dagoma_discoeasy200_pla_fine.inst.cfg | 2 +- .../quality/dagoma/dagoma_discoeasy200_pla_standard.inst.cfg | 2 +- resources/quality/dagoma/dagoma_global_fast.inst.cfg | 2 +- resources/quality/dagoma/dagoma_global_fine.inst.cfg | 2 +- resources/quality/dagoma/dagoma_global_standard.inst.cfg | 2 +- resources/quality/dagoma/dagoma_magis_pla_fast.inst.cfg | 2 +- resources/quality/dagoma/dagoma_magis_pla_fine.inst.cfg | 2 +- resources/quality/dagoma/dagoma_magis_pla_standard.inst.cfg | 2 +- resources/quality/dagoma/dagoma_neva_pla_fast.inst.cfg | 2 +- resources/quality/dagoma/dagoma_neva_pla_fine.inst.cfg | 2 +- resources/quality/dagoma/dagoma_neva_pla_standard.inst.cfg | 2 +- .../quality/deltacomb/deltacomb_abs_Draft_Quality.inst.cfg | 2 +- resources/quality/deltacomb/deltacomb_abs_Fast_Quality.inst.cfg | 2 +- resources/quality/deltacomb/deltacomb_abs_High_Quality.inst.cfg | 2 +- .../quality/deltacomb/deltacomb_abs_Normal_Quality.inst.cfg | 2 +- .../quality/deltacomb/deltacomb_abs_Verydraft_Quality.inst.cfg | 2 +- .../quality/deltacomb/deltacomb_global_Draft_Quality.inst.cfg | 2 +- .../quality/deltacomb/deltacomb_global_Fast_Quality.inst.cfg | 2 +- .../quality/deltacomb/deltacomb_global_High_Quality.inst.cfg | 2 +- .../quality/deltacomb/deltacomb_global_Normal_Quality.inst.cfg | 2 +- .../deltacomb/deltacomb_global_Verydraft_Quality.inst.cfg | 2 +- .../quality/deltacomb/deltacomb_pla_Draft_Quality.inst.cfg | 2 +- resources/quality/deltacomb/deltacomb_pla_Fast_Quality.inst.cfg | 2 +- resources/quality/deltacomb/deltacomb_pla_High_Quality.inst.cfg | 2 +- .../quality/deltacomb/deltacomb_pla_Normal_Quality.inst.cfg | 2 +- .../quality/deltacomb/deltacomb_pla_Verydraft_Quality.inst.cfg | 2 +- resources/quality/draft.inst.cfg | 2 +- resources/quality/extra_coarse.inst.cfg | 2 +- resources/quality/extra_fast.inst.cfg | 2 +- resources/quality/fabtotum/fabtotum_abs_fast.inst.cfg | 2 +- resources/quality/fabtotum/fabtotum_abs_high.inst.cfg | 2 +- resources/quality/fabtotum/fabtotum_abs_normal.inst.cfg | 2 +- resources/quality/fabtotum/fabtotum_nylon_fast.inst.cfg | 2 +- resources/quality/fabtotum/fabtotum_nylon_high.inst.cfg | 2 +- resources/quality/fabtotum/fabtotum_nylon_normal.inst.cfg | 2 +- resources/quality/fabtotum/fabtotum_pla_fast.inst.cfg | 2 +- resources/quality/fabtotum/fabtotum_pla_high.inst.cfg | 2 +- resources/quality/fabtotum/fabtotum_pla_normal.inst.cfg | 2 +- resources/quality/fabtotum/fabtotum_tpu_fast.inst.cfg | 2 +- resources/quality/fabtotum/fabtotum_tpu_high.inst.cfg | 2 +- resources/quality/fabtotum/fabtotum_tpu_normal.inst.cfg | 2 +- resources/quality/fast.inst.cfg | 2 +- .../quality/gmax15plus/gmax15plus_global_dual_normal.inst.cfg | 2 +- .../quality/gmax15plus/gmax15plus_global_dual_thick.inst.cfg | 2 +- .../quality/gmax15plus/gmax15plus_global_dual_thin.inst.cfg | 2 +- .../gmax15plus/gmax15plus_global_dual_very_thick.inst.cfg | 2 +- resources/quality/gmax15plus/gmax15plus_global_normal.inst.cfg | 2 +- resources/quality/gmax15plus/gmax15plus_global_thick.inst.cfg | 2 +- resources/quality/gmax15plus/gmax15plus_global_thin.inst.cfg | 2 +- .../quality/gmax15plus/gmax15plus_global_very_thick.inst.cfg | 2 +- resources/quality/high.inst.cfg | 2 +- .../quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg | 2 +- .../imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg | 2 +- .../quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg | 2 +- .../imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg | 2 +- .../quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg | 2 +- .../imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg | 2 +- .../quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg | 2 +- .../imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg | 2 +- .../quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg | 2 +- .../imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg | 2 +- .../quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg | 2 +- .../imade3d_jellybox/generic_pla_0.4_ultrafine_2-fans.inst.cfg | 2 +- .../quality/imade3d_jellybox/imade3d_jellybox_coarse.inst.cfg | 2 +- .../quality/imade3d_jellybox/imade3d_jellybox_fine.inst.cfg | 2 +- .../quality/imade3d_jellybox/imade3d_jellybox_normal.inst.cfg | 2 +- .../imade3d_jellybox/imade3d_jellybox_ultrafine.inst.cfg | 2 +- resources/quality/kemiq_q2/kemiq_q2_beta_abs_draft.inst.cfg | 2 +- .../quality/kemiq_q2/kemiq_q2_beta_abs_extra_fine.inst.cfg | 2 +- resources/quality/kemiq_q2/kemiq_q2_beta_abs_fine.inst.cfg | 2 +- resources/quality/kemiq_q2/kemiq_q2_beta_abs_low.inst.cfg | 2 +- resources/quality/kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg | 2 +- resources/quality/kemiq_q2/kemiq_q2_beta_pla_draft.inst.cfg | 2 +- .../quality/kemiq_q2/kemiq_q2_beta_pla_extra_fine.inst.cfg | 2 +- resources/quality/kemiq_q2/kemiq_q2_beta_pla_fine.inst.cfg | 2 +- resources/quality/kemiq_q2/kemiq_q2_beta_pla_low.inst.cfg | 2 +- resources/quality/kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg | 2 +- resources/quality/kemiq_q2/kemiq_q2_gama_pla_draft.inst.cfg | 2 +- .../quality/kemiq_q2/kemiq_q2_gama_pla_extra_fine.inst.cfg | 2 +- resources/quality/kemiq_q2/kemiq_q2_gama_pla_fine.inst.cfg | 2 +- resources/quality/kemiq_q2/kemiq_q2_gama_pla_low.inst.cfg | 2 +- resources/quality/kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg | 2 +- .../quality/malyan_m200/abs/malyan_m200_abs_draft.inst.cfg | 2 +- resources/quality/malyan_m200/abs/malyan_m200_abs_fast.inst.cfg | 2 +- resources/quality/malyan_m200/abs/malyan_m200_abs_high.inst.cfg | 2 +- .../quality/malyan_m200/abs/malyan_m200_abs_normal.inst.cfg | 2 +- .../quality/malyan_m200/abs/malyan_m200_abs_superdraft.inst.cfg | 2 +- .../malyan_m200/abs/malyan_m200_abs_thickerdraft.inst.cfg | 2 +- .../quality/malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg | 2 +- .../quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg | 2 +- .../malyan_m200/malyan_m200_global_Draft_Quality.inst.cfg | 2 +- .../malyan_m200/malyan_m200_global_Fast_Quality.inst.cfg | 2 +- .../malyan_m200/malyan_m200_global_High_Quality.inst.cfg | 2 +- .../malyan_m200/malyan_m200_global_Normal_Quality.inst.cfg | 2 +- .../malyan_m200/malyan_m200_global_SuperDraft_Quality.inst.cfg | 2 +- .../malyan_m200_global_ThickerDraft_Quality.inst.cfg | 2 +- .../malyan_m200/malyan_m200_global_Ultra_Quality.inst.cfg | 2 +- .../malyan_m200/malyan_m200_global_VeryDraft_Quality.inst.cfg | 2 +- .../quality/malyan_m200/petg/malyan_m200_petg_draft.inst.cfg | 2 +- .../quality/malyan_m200/petg/malyan_m200_petg_fast.inst.cfg | 2 +- .../quality/malyan_m200/petg/malyan_m200_petg_high.inst.cfg | 2 +- .../quality/malyan_m200/petg/malyan_m200_petg_normal.inst.cfg | 2 +- .../malyan_m200/petg/malyan_m200_petg_superdraft.inst.cfg | 2 +- .../malyan_m200/petg/malyan_m200_petg_thickerdraft.inst.cfg | 2 +- .../quality/malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg | 2 +- .../malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg | 2 +- .../quality/malyan_m200/pla/malyan_m200_pla_draft.inst.cfg | 2 +- resources/quality/malyan_m200/pla/malyan_m200_pla_fast.inst.cfg | 2 +- resources/quality/malyan_m200/pla/malyan_m200_pla_high.inst.cfg | 2 +- .../quality/malyan_m200/pla/malyan_m200_pla_normal.inst.cfg | 2 +- .../quality/malyan_m200/pla/malyan_m200_pla_superdraft.inst.cfg | 2 +- .../malyan_m200/pla/malyan_m200_pla_thickerdraft.inst.cfg | 2 +- .../quality/malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg | 2 +- .../quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg | 2 +- .../abs/monoprice_select_mini_v2_abs_draft.inst.cfg | 2 +- .../abs/monoprice_select_mini_v2_abs_fast.inst.cfg | 2 +- .../abs/monoprice_select_mini_v2_abs_high.inst.cfg | 2 +- .../abs/monoprice_select_mini_v2_abs_normal.inst.cfg | 2 +- .../abs/monoprice_select_mini_v2_abs_superdraft.inst.cfg | 2 +- .../abs/monoprice_select_mini_v2_abs_thickerdraft.inst.cfg | 2 +- .../abs/monoprice_select_mini_v2_abs_ultra.inst.cfg | 2 +- .../abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg | 2 +- .../monoprice_select_mini_v2_global_Draft_Quality.inst.cfg | 2 +- .../monoprice_select_mini_v2_global_Fast_Quality.inst.cfg | 2 +- .../monoprice_select_mini_v2_global_High_Quality.inst.cfg | 2 +- .../monoprice_select_mini_v2_global_Normal_Quality.inst.cfg | 2 +- .../monoprice_select_mini_v2_global_SuperDraft_Quality.inst.cfg | 2 +- ...onoprice_select_mini_v2_global_ThickerDraft_Quality.inst.cfg | 2 +- .../monoprice_select_mini_v2_global_Ultra_Quality.inst.cfg | 2 +- .../monoprice_select_mini_v2_global_VeryDraft_Quality.inst.cfg | 2 +- .../nylon/monoprice_select_mini_v2_nylon_draft.inst.cfg | 2 +- .../nylon/monoprice_select_mini_v2_nylon_fast.inst.cfg | 2 +- .../nylon/monoprice_select_mini_v2_nylon_high.inst.cfg | 2 +- .../nylon/monoprice_select_mini_v2_nylon_normal.inst.cfg | 2 +- .../nylon/monoprice_select_mini_v2_nylon_superdraft.inst.cfg | 2 +- .../nylon/monoprice_select_mini_v2_nylon_thickerdraft.inst.cfg | 2 +- .../nylon/monoprice_select_mini_v2_nylon_ultra.inst.cfg | 2 +- .../nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg | 2 +- .../pc/monoprice_select_mini_v2_pc_draft.inst.cfg | 2 +- .../pc/monoprice_select_mini_v2_pc_fast.inst.cfg | 2 +- .../pc/monoprice_select_mini_v2_pc_high.inst.cfg | 2 +- .../pc/monoprice_select_mini_v2_pc_normal.inst.cfg | 2 +- .../pc/monoprice_select_mini_v2_pc_superdraft.inst.cfg | 2 +- .../pc/monoprice_select_mini_v2_pc_thickerdraft.inst.cfg | 2 +- .../pc/monoprice_select_mini_v2_pc_ultra.inst.cfg | 2 +- .../pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg | 2 +- .../petg/monoprice_select_mini_v2_petg_draft.inst.cfg | 2 +- .../petg/monoprice_select_mini_v2_petg_fast.inst.cfg | 2 +- .../petg/monoprice_select_mini_v2_petg_high.inst.cfg | 2 +- .../petg/monoprice_select_mini_v2_petg_normal.inst.cfg | 2 +- .../petg/monoprice_select_mini_v2_petg_superdraft.inst.cfg | 2 +- .../petg/monoprice_select_mini_v2_petg_thickerdraft.inst.cfg | 2 +- .../petg/monoprice_select_mini_v2_petg_ultra.inst.cfg | 2 +- .../petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg | 2 +- .../pla/monoprice_select_mini_v2_pla_draft.inst.cfg | 2 +- .../pla/monoprice_select_mini_v2_pla_fast.inst.cfg | 2 +- .../pla/monoprice_select_mini_v2_pla_high.inst.cfg | 2 +- .../pla/monoprice_select_mini_v2_pla_normal.inst.cfg | 2 +- .../pla/monoprice_select_mini_v2_pla_superdraft.inst.cfg | 2 +- .../pla/monoprice_select_mini_v2_pla_thickerdraft.inst.cfg | 2 +- .../pla/monoprice_select_mini_v2_pla_ultra.inst.cfg | 2 +- .../pla/monoprice_select_mini_v2_pla_verydraft.inst.cfg | 2 +- resources/quality/normal.inst.cfg | 2 +- resources/quality/peopoly_moai/peopoly_moai_coarse.inst.cfg | 2 +- resources/quality/peopoly_moai/peopoly_moai_draft.inst.cfg | 2 +- resources/quality/peopoly_moai/peopoly_moai_extra_high.inst.cfg | 2 +- resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg | 2 +- resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg | 2 +- .../quality/tevo_blackwidow/tevo_blackwidow_draft.inst.cfg | 2 +- resources/quality/tevo_blackwidow/tevo_blackwidow_high.inst.cfg | 2 +- .../quality/tevo_blackwidow/tevo_blackwidow_normal.inst.cfg | 2 +- resources/quality/tizyx_k25/tizyx_k25_normal.inst.cfg | 2 +- resources/quality/ultimaker2/um2_draft.inst.cfg | 2 +- resources/quality/ultimaker2/um2_fast.inst.cfg | 2 +- resources/quality/ultimaker2/um2_high.inst.cfg | 2 +- resources/quality/ultimaker2/um2_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg | 2 +- resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg | 2 +- resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_cpep_0.4_draft.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_cpep_0.4_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_cpep_0.6_draft.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_cpep_0.6_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_cpep_0.8_draft.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_cpep_0.8_normal.inst.cfg | 2 +- .../quality/ultimaker2_plus/um2p_global_Coarse_Quality.inst.cfg | 2 +- .../quality/ultimaker2_plus/um2p_global_Draft_Quality.inst.cfg | 2 +- .../ultimaker2_plus/um2p_global_Extra_Coarse_Quality.inst.cfg | 2 +- .../quality/ultimaker2_plus/um2p_global_Fast_Quality.inst.cfg | 2 +- .../quality/ultimaker2_plus/um2p_global_High_Quality.inst.cfg | 2 +- .../quality/ultimaker2_plus/um2p_global_Normal_Quality.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_nylon_0.25_high.inst.cfg | 2 +- .../quality/ultimaker2_plus/um2p_nylon_0.25_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_nylon_0.4_fast.inst.cfg | 2 +- .../quality/ultimaker2_plus/um2p_nylon_0.4_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_nylon_0.6_fast.inst.cfg | 2 +- .../quality/ultimaker2_plus/um2p_nylon_0.6_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_nylon_0.8_draft.inst.cfg | 2 +- .../quality/ultimaker2_plus/um2p_nylon_0.8_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_pc_0.25_high.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_pc_0.25_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_pc_0.4_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_pc_0.6_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_pc_0.8_draft.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_pc_0.8_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_pp_0.4_fast.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_pp_0.4_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_pp_0.6_draft.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_pp_0.6_fast.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg | 2 +- .../quality/ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_tpu_0.25_high.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_tpu_0.4_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_tpu_0.6_fast.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.25_ABS_Normal_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.25_CPE_Normal_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.25_Nylon_Normal_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.25_PLA_Normal_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.25_TPLA_Normal_Quality.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_ABS_Draft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_ABS_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_BAM_Draft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_BAM_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_BAM_Normal_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_CPEP_Draft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_CPEP_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_CPEP_High_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_CPEP_Normal_Quality.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_CPE_Draft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_CPE_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_CPE_High_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_CPE_Normal_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_Nylon_Draft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_Nylon_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_Nylon_High_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_Nylon_Normal_Quality.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_PC_Draft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_PC_Fast_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_PC_High_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_PC_Normal_Quality.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_PLA_Draft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_PLA_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_PLA_High_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_PLA_Normal_Quality.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_PP_Draft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_PP_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_PP_Normal_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_TPLA_Draft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_TPLA_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_TPLA_Normal_Quality.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_TPU_Draft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_TPU_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_TPU_Normal_Quality.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.8_ABS_Draft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_ABS_Superdraft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_ABS_Verydraft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_CPEP_Superdraft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_CPEP_Verydraft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.8_CPE_Draft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_CPE_Superdraft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_CPE_Verydraft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_Nylon_Draft_Print.inst.cfg | 2 +- .../ultimaker3/um3_aa0.8_Nylon_Superdraft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_Nylon_Verydraft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.8_PLA_Draft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_PLA_Superdraft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_PLA_Verydraft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.8_PP_Draft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_PP_Superdraft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_PP_Verydraft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_TPLA_Draft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_TPLA_Superdraft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_TPLA_Verydraft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.8_TPU_Draft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_TPU_Superdraft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_TPU_Verydraft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_bb0.4_PVA_Draft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_bb0.4_PVA_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_bb0.4_PVA_High_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_bb0.4_PVA_Normal_Quality.inst.cfg | 2 +- resources/quality/ultimaker3/um3_bb0.8_PVA_Draft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_bb0.8_PVA_Superdraft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_bb0.8_PVA_Verydraft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg | 2 +- resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg | 2 +- resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg | 2 +- resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_global_Superdraft_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_global_Verydraft_Quality.inst.cfg | 2 +- .../ultimaker_original/umo_global_Coarse_Quality.inst.cfg | 2 +- .../ultimaker_original/umo_global_Draft_Quality.inst.cfg | 2 +- .../ultimaker_original/umo_global_Extra_Coarse_Quality.inst.cfg | 2 +- .../quality/ultimaker_original/umo_global_Fast_Quality.inst.cfg | 2 +- .../quality/ultimaker_original/umo_global_High_Quality.inst.cfg | 2 +- .../ultimaker_original/umo_global_Normal_Quality.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.25_ABS_Normal_Quality.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.25_CPE_Normal_Quality.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.25_Nylon_Normal_Quality.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.25_PC_Normal_Quality.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.25_PLA_Normal_Quality.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.25_PP_Normal_Quality.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.25_TPLA_Normal_Quality.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.4_ABS_Draft_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.4_ABS_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.4_ABS_High_Quality.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.4_ABS_Normal_Quality.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.4_BAM_Draft_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.4_BAM_Fast_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.4_BAM_Normal_Quality.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.4_CPEP_Draft_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.4_CPEP_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.4_CPEP_High_Quality.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.4_CPEP_Normal_Quality.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.4_CPE_Draft_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.4_CPE_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.4_CPE_High_Quality.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.4_CPE_Normal_Quality.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.4_Nylon_Draft_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.4_Nylon_Fast_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.4_Nylon_High_Quality.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.4_Nylon_Normal_Quality.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.4_PC_Draft_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.4_PC_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.4_PC_High_Quality.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.4_PC_Normal_Quality.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.4_PLA_Draft_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.4_PLA_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.4_PLA_High_Quality.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.4_PLA_Normal_Quality.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.4_PP_Draft_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.4_PP_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.4_PP_Normal_Quality.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.4_TPLA_Draft_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.4_TPLA_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.4_TPLA_High_Quality.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.4_TPLA_Normal_Quality.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.4_TPU_Draft_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.4_TPU_Fast_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.4_TPU_Normal_Quality.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Draft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Fast_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.4_aluminum_ABS_High_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_aluminum_ABS_Normal_Quality.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Draft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Fast_Print.inst.cfg | 2 +- .../um_s5_aa0.4_aluminum_CPEP_High_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_aluminum_CPEP_Normal_Quality.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Draft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Fast_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.4_aluminum_CPE_High_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_aluminum_CPE_Normal_Quality.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.4_aluminum_PC_Draft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.4_aluminum_PC_Fast_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.4_aluminum_PC_High_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_aluminum_PC_Normal_Quality.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.4_aluminum_PP_Draft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.4_aluminum_PP_Fast_Print.inst.cfg | 2 +- .../um_s5_aa0.4_aluminum_PP_Normal_Quality.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.8_ABS_Draft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.8_ABS_Superdraft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.8_ABS_Verydraft_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.8_CPEP_Fast_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.8_CPEP_Superdraft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.8_CPEP_Verydraft_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.8_CPE_Draft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.8_CPE_Superdraft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.8_CPE_Verydraft_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.8_Nylon_Draft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.8_Nylon_Superdraft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.8_Nylon_Verydraft_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.8_PC_Fast_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.8_PC_Superdraft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.8_PC_Verydraft_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.8_PLA_Draft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.8_PLA_Superdraft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.8_PLA_Verydraft_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.8_PP_Draft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.8_PP_Superdraft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.8_PP_Verydraft_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.8_TPLA_Draft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.8_TPLA_Superdraft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.8_TPLA_Verydraft_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_aa0.8_TPU_Draft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.8_TPU_Superdraft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.8_TPU_Verydraft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_aluminum_ABS_Superdraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_aluminum_ABS_Verydraft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Fast_Print.inst.cfg | 2 +- .../um_s5_aa0.8_aluminum_CPEP_Superdraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_aluminum_CPEP_Verydraft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_aluminum_CPE_Superdraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_aluminum_CPE_Verydraft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.8_aluminum_PC_Fast_Print.inst.cfg | 2 +- .../um_s5_aa0.8_aluminum_PC_Superdraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_aluminum_PC_Verydraft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_aa0.8_aluminum_PP_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_aluminum_PP_Superdraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_aluminum_PP_Verydraft_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_bb0.4_PVA_Draft_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_bb0.4_PVA_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_bb0.4_PVA_High_Quality.inst.cfg | 2 +- .../ultimaker_s5/um_s5_bb0.4_PVA_Normal_Quality.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_bb0.8_PVA_Draft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_bb0.8_PVA_Superdraft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_bb0.8_PVA_Verydraft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_cc0.6_CFFCPE_Draft_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_cc0.6_CFFPA_Draft_Print.inst.cfg | 2 +- .../ultimaker_s5/um_s5_cc0.6_GFFCPE_Draft_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_cc0.6_GFFPA_Draft_Print.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_global_Draft_Quality.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_global_Fast_Quality.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_global_High_Quality.inst.cfg | 2 +- .../quality/ultimaker_s5/um_s5_global_Normal_Quality.inst.cfg | 2 +- .../ultimaker_s5/um_s5_global_Superdraft_Quality.inst.cfg | 2 +- .../ultimaker_s5/um_s5_global_Verydraft_Quality.inst.cfg | 2 +- .../vertex_delta_k8800/k8800_ABS_Extreme_Quality.inst.cfg | 2 +- .../quality/vertex_delta_k8800/k8800_ABS_High_Quality.inst.cfg | 2 +- .../vertex_delta_k8800/k8800_ABS_Normal_Quality.inst.cfg | 2 +- .../vertex_delta_k8800/k8800_Global_Extreme_Quality.inst.cfg | 2 +- .../vertex_delta_k8800/k8800_Global_High_Quality.inst.cfg | 2 +- .../vertex_delta_k8800/k8800_Global_Normal_Quality.inst.cfg | 2 +- .../vertex_delta_k8800/k8800_PET_Extreme_Quality.inst.cfg | 2 +- .../quality/vertex_delta_k8800/k8800_PET_High_Quality.inst.cfg | 2 +- .../vertex_delta_k8800/k8800_PET_Normal_Quality.inst.cfg | 2 +- .../vertex_delta_k8800/k8800_PLA_Extreme_Quality.inst.cfg | 2 +- .../quality/vertex_delta_k8800/k8800_PLA_High_Quality.inst.cfg | 2 +- .../vertex_delta_k8800/k8800_PLA_Normal_Quality.inst.cfg | 2 +- .../vertex_delta_k8800/k8800_TPU_Extreme_Quality.inst.cfg | 2 +- .../quality/vertex_delta_k8800/k8800_TPU_High_Quality.inst.cfg | 2 +- .../vertex_delta_k8800/k8800_TPU_Normal_Quality.inst.cfg | 2 +- resources/quality/zyyx/zyyx_agile_global_fast.inst.cfg | 2 +- resources/quality/zyyx/zyyx_agile_global_fine.inst.cfg | 2 +- resources/quality/zyyx/zyyx_agile_global_normal.inst.cfg | 2 +- resources/quality/zyyx/zyyx_agile_pro_flex_fast.inst.cfg | 2 +- resources/quality/zyyx/zyyx_agile_pro_flex_fine.inst.cfg | 2 +- resources/quality/zyyx/zyyx_agile_pro_flex_normal.inst.cfg | 2 +- resources/quality/zyyx/zyyx_agile_pro_pla_fast.inst.cfg | 2 +- resources/quality/zyyx/zyyx_agile_pro_pla_fine.inst.cfg | 2 +- resources/quality/zyyx/zyyx_agile_pro_pla_normal.inst.cfg | 2 +- resources/variants/cartesio_0.25.inst.cfg | 2 +- resources/variants/cartesio_0.4.inst.cfg | 2 +- resources/variants/cartesio_0.8.inst.cfg | 2 +- resources/variants/fabtotum_hyb35.inst.cfg | 2 +- resources/variants/fabtotum_lite04.inst.cfg | 2 +- resources/variants/fabtotum_lite06.inst.cfg | 2 +- resources/variants/fabtotum_pro02.inst.cfg | 2 +- resources/variants/fabtotum_pro04.inst.cfg | 2 +- resources/variants/fabtotum_pro06.inst.cfg | 2 +- resources/variants/fabtotum_pro08.inst.cfg | 2 +- resources/variants/felixtec4_0.25.inst.cfg | 2 +- resources/variants/felixtec4_0.35.inst.cfg | 2 +- resources/variants/felixtec4_0.50.inst.cfg | 2 +- resources/variants/felixtec4_0.70.inst.cfg | 2 +- resources/variants/gmax15plus_025_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_04_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_05_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_05_jhead.inst.cfg | 2 +- resources/variants/gmax15plus_06_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_08_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_10_jhead.inst.cfg | 2 +- resources/variants/gmax15plus_12_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_dual_025_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_dual_04_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_dual_05_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_dual_05_jhead.inst.cfg | 2 +- resources/variants/gmax15plus_dual_06_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_dual_08_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_dual_10_jhead.inst.cfg | 2 +- resources/variants/imade3d_jellybox_0.4.inst.cfg | 2 +- resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg | 2 +- resources/variants/tizyx_k25_0.2.inst.cfg | 2 +- resources/variants/tizyx_k25_0.3.inst.cfg | 2 +- resources/variants/tizyx_k25_0.4.inst.cfg | 2 +- resources/variants/tizyx_k25_0.5.inst.cfg | 2 +- resources/variants/tizyx_k25_0.6.inst.cfg | 2 +- resources/variants/tizyx_k25_0.8.inst.cfg | 2 +- resources/variants/tizyx_k25_1.0.inst.cfg | 2 +- resources/variants/ultimaker2_0.25.inst.cfg | 2 +- resources/variants/ultimaker2_0.4.inst.cfg | 2 +- resources/variants/ultimaker2_0.6.inst.cfg | 2 +- resources/variants/ultimaker2_0.8.inst.cfg | 2 +- resources/variants/ultimaker2_extended_0.25.inst.cfg | 2 +- resources/variants/ultimaker2_extended_0.4.inst.cfg | 2 +- resources/variants/ultimaker2_extended_0.6.inst.cfg | 2 +- resources/variants/ultimaker2_extended_0.8.inst.cfg | 2 +- resources/variants/ultimaker2_extended_plus_0.25.inst.cfg | 2 +- resources/variants/ultimaker2_extended_plus_0.4.inst.cfg | 2 +- resources/variants/ultimaker2_extended_plus_0.6.inst.cfg | 2 +- resources/variants/ultimaker2_extended_plus_0.8.inst.cfg | 2 +- resources/variants/ultimaker2_plus_0.25.inst.cfg | 2 +- resources/variants/ultimaker2_plus_0.4.inst.cfg | 2 +- resources/variants/ultimaker2_plus_0.6.inst.cfg | 2 +- resources/variants/ultimaker2_plus_0.8.inst.cfg | 2 +- resources/variants/ultimaker3_aa0.25.inst.cfg | 2 +- resources/variants/ultimaker3_aa0.8.inst.cfg | 2 +- resources/variants/ultimaker3_aa04.inst.cfg | 2 +- resources/variants/ultimaker3_bb0.8.inst.cfg | 2 +- resources/variants/ultimaker3_bb04.inst.cfg | 2 +- resources/variants/ultimaker3_extended_aa0.25.inst.cfg | 2 +- resources/variants/ultimaker3_extended_aa0.8.inst.cfg | 2 +- resources/variants/ultimaker3_extended_aa04.inst.cfg | 2 +- resources/variants/ultimaker3_extended_bb0.8.inst.cfg | 2 +- resources/variants/ultimaker3_extended_bb04.inst.cfg | 2 +- resources/variants/ultimaker_s5_aa0.25.inst.cfg | 2 +- resources/variants/ultimaker_s5_aa0.8.inst.cfg | 2 +- resources/variants/ultimaker_s5_aa04.inst.cfg | 2 +- resources/variants/ultimaker_s5_aluminum.inst.cfg | 2 +- resources/variants/ultimaker_s5_bb0.8.inst.cfg | 2 +- resources/variants/ultimaker_s5_bb04.inst.cfg | 2 +- resources/variants/ultimaker_s5_cc06.inst.cfg | 2 +- resources/variants/ultimaker_s5_glass.inst.cfg | 2 +- 648 files changed, 648 insertions(+), 648 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 4a1023f69e..032a56ae40 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -143,7 +143,7 @@ class CuraApplication(QtApplication): # SettingVersion represents the set of settings available in the machine/extruder definitions. # You need to make sure that this version number needs to be increased if there is any non-backwards-compatible # changes of the settings. - SettingVersion = 5 + SettingVersion = 6 Created = False diff --git a/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg b/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg index ebb506a222..1ca2674e1f 100644 --- a/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg +++ b/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = abax_pri3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/abax_pri3/apri3_pla_high.inst.cfg b/resources/quality/abax_pri3/apri3_pla_high.inst.cfg index 20d2c024aa..e9e8d53a03 100644 --- a/resources/quality/abax_pri3/apri3_pla_high.inst.cfg +++ b/resources/quality/abax_pri3/apri3_pla_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = abax_pri3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg b/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg index 0a4d1f1c62..40399c9548 100644 --- a/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg +++ b/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = abax_pri3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg b/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg index f278788c68..c6d20f70da 100644 --- a/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg +++ b/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = abax_pri5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/abax_pri5/apri5_pla_high.inst.cfg b/resources/quality/abax_pri5/apri5_pla_high.inst.cfg index 212c92e7d1..99bd10d654 100644 --- a/resources/quality/abax_pri5/apri5_pla_high.inst.cfg +++ b/resources/quality/abax_pri5/apri5_pla_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = abax_pri5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg b/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg index 8a1338f28c..55e0a7755a 100644 --- a/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg +++ b/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = abax_pri5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/abax_titan/atitan_pla_fast.inst.cfg b/resources/quality/abax_titan/atitan_pla_fast.inst.cfg index 997e77041d..6a2a49b555 100644 --- a/resources/quality/abax_titan/atitan_pla_fast.inst.cfg +++ b/resources/quality/abax_titan/atitan_pla_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = abax_titan [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/abax_titan/atitan_pla_high.inst.cfg b/resources/quality/abax_titan/atitan_pla_high.inst.cfg index 73cd31f3fd..7dd5833297 100644 --- a/resources/quality/abax_titan/atitan_pla_high.inst.cfg +++ b/resources/quality/abax_titan/atitan_pla_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = abax_titan [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/abax_titan/atitan_pla_normal.inst.cfg b/resources/quality/abax_titan/atitan_pla_normal.inst.cfg index c356e197ce..b6aae46c6d 100644 --- a/resources/quality/abax_titan/atitan_pla_normal.inst.cfg +++ b/resources/quality/abax_titan/atitan_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = abax_titan [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/anycubic_4max/abs/anycubic_4max_abs_draft.inst.cfg b/resources/quality/anycubic_4max/abs/anycubic_4max_abs_draft.inst.cfg index 9bb11389d2..e12954b6bc 100644 --- a/resources/quality/anycubic_4max/abs/anycubic_4max_abs_draft.inst.cfg +++ b/resources/quality/anycubic_4max/abs/anycubic_4max_abs_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = anycubic_4max [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/anycubic_4max/abs/anycubic_4max_abs_high.inst.cfg b/resources/quality/anycubic_4max/abs/anycubic_4max_abs_high.inst.cfg index 4a09e0ee7c..0218b87a63 100644 --- a/resources/quality/anycubic_4max/abs/anycubic_4max_abs_high.inst.cfg +++ b/resources/quality/anycubic_4max/abs/anycubic_4max_abs_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = anycubic_4max [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/anycubic_4max/abs/anycubic_4max_abs_normal.inst.cfg b/resources/quality/anycubic_4max/abs/anycubic_4max_abs_normal.inst.cfg index f415cb379f..f686855364 100644 --- a/resources/quality/anycubic_4max/abs/anycubic_4max_abs_normal.inst.cfg +++ b/resources/quality/anycubic_4max/abs/anycubic_4max_abs_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = anycubic_4max [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/anycubic_4max/anycubic_4max_draft.inst.cfg b/resources/quality/anycubic_4max/anycubic_4max_draft.inst.cfg index 56810934c7..d9dc632c16 100644 --- a/resources/quality/anycubic_4max/anycubic_4max_draft.inst.cfg +++ b/resources/quality/anycubic_4max/anycubic_4max_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = anycubic_4max [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/anycubic_4max/anycubic_4max_high.inst.cfg b/resources/quality/anycubic_4max/anycubic_4max_high.inst.cfg index 4f35669ae2..55b5833c3f 100644 --- a/resources/quality/anycubic_4max/anycubic_4max_high.inst.cfg +++ b/resources/quality/anycubic_4max/anycubic_4max_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = anycubic_4max [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/anycubic_4max/anycubic_4max_normal.inst.cfg b/resources/quality/anycubic_4max/anycubic_4max_normal.inst.cfg index 778764f005..45c6f19f8b 100644 --- a/resources/quality/anycubic_4max/anycubic_4max_normal.inst.cfg +++ b/resources/quality/anycubic_4max/anycubic_4max_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = anycubic_4max [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/anycubic_4max/hips/anycubic_4max_hips_draft.inst.cfg b/resources/quality/anycubic_4max/hips/anycubic_4max_hips_draft.inst.cfg index 59b727e7be..97c19b7083 100644 --- a/resources/quality/anycubic_4max/hips/anycubic_4max_hips_draft.inst.cfg +++ b/resources/quality/anycubic_4max/hips/anycubic_4max_hips_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = anycubic_4max [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/anycubic_4max/hips/anycubic_4max_hips_high.inst.cfg b/resources/quality/anycubic_4max/hips/anycubic_4max_hips_high.inst.cfg index 1ddfe9ee4b..cfa727bcb8 100644 --- a/resources/quality/anycubic_4max/hips/anycubic_4max_hips_high.inst.cfg +++ b/resources/quality/anycubic_4max/hips/anycubic_4max_hips_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = anycubic_4max [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/anycubic_4max/hips/anycubic_4max_hips_normal.inst.cfg b/resources/quality/anycubic_4max/hips/anycubic_4max_hips_normal.inst.cfg index 829392ad1f..f4372939f5 100644 --- a/resources/quality/anycubic_4max/hips/anycubic_4max_hips_normal.inst.cfg +++ b/resources/quality/anycubic_4max/hips/anycubic_4max_hips_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = anycubic_4max [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/anycubic_4max/petg/anycubic_4max_petg_draft.inst.cfg b/resources/quality/anycubic_4max/petg/anycubic_4max_petg_draft.inst.cfg index 028fe5d8a7..124bd487b0 100644 --- a/resources/quality/anycubic_4max/petg/anycubic_4max_petg_draft.inst.cfg +++ b/resources/quality/anycubic_4max/petg/anycubic_4max_petg_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = anycubic_4max [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/anycubic_4max/petg/anycubic_4max_petg_high.inst.cfg b/resources/quality/anycubic_4max/petg/anycubic_4max_petg_high.inst.cfg index 73eb73fe16..eeaaac6270 100644 --- a/resources/quality/anycubic_4max/petg/anycubic_4max_petg_high.inst.cfg +++ b/resources/quality/anycubic_4max/petg/anycubic_4max_petg_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = anycubic_4max [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/anycubic_4max/petg/anycubic_4max_petg_normal.inst.cfg b/resources/quality/anycubic_4max/petg/anycubic_4max_petg_normal.inst.cfg index 3ed9e5e707..ec0579015a 100644 --- a/resources/quality/anycubic_4max/petg/anycubic_4max_petg_normal.inst.cfg +++ b/resources/quality/anycubic_4max/petg/anycubic_4max_petg_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = anycubic_4max [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/anycubic_4max/pla/anycubic_4max_pla_draft.inst.cfg b/resources/quality/anycubic_4max/pla/anycubic_4max_pla_draft.inst.cfg index fef5f88f97..b72ce43e29 100644 --- a/resources/quality/anycubic_4max/pla/anycubic_4max_pla_draft.inst.cfg +++ b/resources/quality/anycubic_4max/pla/anycubic_4max_pla_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = anycubic_4max [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/anycubic_4max/pla/anycubic_4max_pla_high.inst.cfg b/resources/quality/anycubic_4max/pla/anycubic_4max_pla_high.inst.cfg index edfa07067b..4386159a66 100644 --- a/resources/quality/anycubic_4max/pla/anycubic_4max_pla_high.inst.cfg +++ b/resources/quality/anycubic_4max/pla/anycubic_4max_pla_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = anycubic_4max [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/anycubic_4max/pla/anycubic_4max_pla_normal.inst.cfg b/resources/quality/anycubic_4max/pla/anycubic_4max_pla_normal.inst.cfg index e90bac1a0b..9998fff2ad 100644 --- a/resources/quality/anycubic_4max/pla/anycubic_4max_pla_normal.inst.cfg +++ b/resources/quality/anycubic_4max/pla/anycubic_4max_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = anycubic_4max [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg index b4f8ba78ed..ba99d30de6 100644 --- a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg +++ b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = anycubic_i3_mega [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg index c727764c5d..b1092b115c 100644 --- a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg +++ b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = anycubic_i3_mega [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg index beb7d98b8e..d088d650a0 100644 --- a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg +++ b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = anycubic_i3_mega [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/builder_premium/bp_BVOH_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_BVOH_Coarse_Quality.inst.cfg index 10c8bc553f..491d24c919 100644 --- a/resources/quality/builder_premium/bp_BVOH_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_BVOH_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = -1 diff --git a/resources/quality/builder_premium/bp_BVOH_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_BVOH_High_Quality.inst.cfg index b09ceb8872..3ff0f07ac1 100644 --- a/resources/quality/builder_premium/bp_BVOH_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_BVOH_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High Quality definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/builder_premium/bp_BVOH_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_BVOH_Normal_Quality.inst.cfg index c2425a6d86..cf67185706 100644 --- a/resources/quality/builder_premium/bp_BVOH_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_BVOH_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/builder_premium/bp_Innoflex60_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_Innoflex60_Coarse_Quality.inst.cfg index 038fd02fff..aedb45a2b1 100644 --- a/resources/quality/builder_premium/bp_Innoflex60_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_Innoflex60_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = -1 diff --git a/resources/quality/builder_premium/bp_Innoflex60_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_Innoflex60_High_Quality.inst.cfg index e9512e30f8..08fb395a36 100644 --- a/resources/quality/builder_premium/bp_Innoflex60_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_Innoflex60_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High Quality definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/builder_premium/bp_Innoflex60_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_Innoflex60_Normal_Quality.inst.cfg index fb6ec6c89f..008de91758 100644 --- a/resources/quality/builder_premium/bp_Innoflex60_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_Innoflex60_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/builder_premium/bp_PET_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_PET_Coarse_Quality.inst.cfg index 572e83d4b3..0e2c26812b 100644 --- a/resources/quality/builder_premium/bp_PET_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PET_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = -1 diff --git a/resources/quality/builder_premium/bp_PET_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_PET_High_Quality.inst.cfg index f4a45dd43a..8217ca9156 100644 --- a/resources/quality/builder_premium/bp_PET_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PET_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High Quality definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/builder_premium/bp_PET_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_PET_Normal_Quality.inst.cfg index d927ab0851..48b2df0cae 100644 --- a/resources/quality/builder_premium/bp_PET_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PET_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/builder_premium/bp_PLA_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_PLA_Coarse_Quality.inst.cfg index fc877df05d..6834cbb2c4 100644 --- a/resources/quality/builder_premium/bp_PLA_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PLA_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = -1 diff --git a/resources/quality/builder_premium/bp_PLA_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_PLA_High_Quality.inst.cfg index 586133a500..9fc5426cf9 100644 --- a/resources/quality/builder_premium/bp_PLA_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PLA_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High Quality definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/builder_premium/bp_PLA_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_PLA_Normal_Quality.inst.cfg index e84b2eaa87..161bee24df 100644 --- a/resources/quality/builder_premium/bp_PLA_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PLA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/builder_premium/bp_PVA_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_PVA_Coarse_Quality.inst.cfg index f661e58b6d..149b938bac 100644 --- a/resources/quality/builder_premium/bp_PVA_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PVA_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = -1 diff --git a/resources/quality/builder_premium/bp_PVA_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_PVA_High_Quality.inst.cfg index 31b9c094df..ba310a0890 100644 --- a/resources/quality/builder_premium/bp_PVA_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PVA_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High Quality definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/builder_premium/bp_PVA_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_PVA_Normal_Quality.inst.cfg index 8c3ca85124..4ab949957f 100644 --- a/resources/quality/builder_premium/bp_PVA_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PVA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/builder_premium/bp_global_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_global_Coarse_Quality.inst.cfg index a1d80774a1..9a85c924ee 100644 --- a/resources/quality/builder_premium/bp_global_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_global_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = -1 diff --git a/resources/quality/builder_premium/bp_global_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_global_High_Quality.inst.cfg index 465ea6090a..ca2f8c843f 100644 --- a/resources/quality/builder_premium/bp_global_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_global_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High Quality definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/builder_premium/bp_global_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_global_Normal_Quality.inst.cfg index e872561b90..3b24f9963d 100644 --- a/resources/quality/builder_premium/bp_global_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_global_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/abs/cartesio_0.25_abs_high.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.25_abs_high.inst.cfg index 5626ed58de..f19635331d 100644 --- a/resources/quality/cartesio/abs/cartesio_0.25_abs_high.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.25_abs_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg index f0b4581b90..14babfa93d 100644 --- a/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/abs/cartesio_0.4_abs_high.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.4_abs_high.inst.cfg index d4dd85b09d..99e1290c77 100644 --- a/resources/quality/cartesio/abs/cartesio_0.4_abs_high.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.4_abs_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg index 5ee76e8e2b..32c306ba71 100644 --- a/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg index d15efb770f..5496468fd6 100644 --- a/resources/quality/cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = 3 diff --git a/resources/quality/cartesio/abs/cartesio_0.8_abs_extra_coarse.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.8_abs_extra_coarse.inst.cfg index 7467da765f..360397ddc9 100644 --- a/resources/quality/cartesio/abs/cartesio_0.8_abs_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.8_abs_extra_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extra coarse weight = 4 diff --git a/resources/quality/cartesio/abs/cartesio_0.8_abs_high.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.8_abs_high.inst.cfg index caa6b71a4a..82e0afa853 100644 --- a/resources/quality/cartesio/abs/cartesio_0.8_abs_high.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.8_abs_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg index 82a980538c..20ba9b777d 100644 --- a/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_high.inst.cfg b/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_high.inst.cfg index 17f2acd8d1..fa89b4c3aa 100644 --- a/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_high.inst.cfg +++ b/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg b/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg index 50dc4d42a0..63abbf1cc5 100644 --- a/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg +++ b/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/cartesio_global_Coarse_Quality.inst.cfg b/resources/quality/cartesio/cartesio_global_Coarse_Quality.inst.cfg index f92fc49981..7ce1111dd8 100644 --- a/resources/quality/cartesio/cartesio_global_Coarse_Quality.inst.cfg +++ b/resources/quality/cartesio/cartesio_global_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = -3 diff --git a/resources/quality/cartesio/cartesio_global_Extra_Coarse_Quality.inst.cfg b/resources/quality/cartesio/cartesio_global_Extra_Coarse_Quality.inst.cfg index 1681e83279..0369c74e2a 100644 --- a/resources/quality/cartesio/cartesio_global_Extra_Coarse_Quality.inst.cfg +++ b/resources/quality/cartesio/cartesio_global_Extra_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extra coarse weight = -4 diff --git a/resources/quality/cartesio/cartesio_global_High_Quality.inst.cfg b/resources/quality/cartesio/cartesio_global_High_Quality.inst.cfg index 95d1f3b37e..dafe5ef621 100644 --- a/resources/quality/cartesio/cartesio_global_High_Quality.inst.cfg +++ b/resources/quality/cartesio/cartesio_global_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/cartesio_global_Normal_Quality.inst.cfg b/resources/quality/cartesio/cartesio_global_Normal_Quality.inst.cfg index 6bb348282e..100da3c70a 100644 --- a/resources/quality/cartesio/cartesio_global_Normal_Quality.inst.cfg +++ b/resources/quality/cartesio/cartesio_global_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/hips/cartesio_0.25_hips_high.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.25_hips_high.inst.cfg index 3e212b2446..93e04e1514 100644 --- a/resources/quality/cartesio/hips/cartesio_0.25_hips_high.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.25_hips_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg index 08d1cf709e..ba3f88ce13 100644 --- a/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/hips/cartesio_0.4_hips_high.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.4_hips_high.inst.cfg index a9664cf9d1..91b1627650 100644 --- a/resources/quality/cartesio/hips/cartesio_0.4_hips_high.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.4_hips_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg index 18daa16d97..a2f817aef2 100644 --- a/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg index f009383ad8..6b84c5e864 100644 --- a/resources/quality/cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = 3 diff --git a/resources/quality/cartesio/hips/cartesio_0.8_hips_extra_coarse.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.8_hips_extra_coarse.inst.cfg index 1adbbb0fb9..16f299813b 100644 --- a/resources/quality/cartesio/hips/cartesio_0.8_hips_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.8_hips_extra_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extra coarse weight = 4 diff --git a/resources/quality/cartesio/hips/cartesio_0.8_hips_high.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.8_hips_high.inst.cfg index d3e6df227f..686759bc4d 100644 --- a/resources/quality/cartesio/hips/cartesio_0.8_hips_high.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.8_hips_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg index 5afc358d51..654564f291 100644 --- a/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg index 9eb5d5c4e9..bd2dca940f 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg index b8d17bcc8f..55d22623bb 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg index d4b261b99f..05e9abbe8f 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg index b208462ed7..51327c844a 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg index 21e6d357b0..279e2d98bf 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = 3 diff --git a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg index 15128584e1..69f9a8caad 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extra coarse weight = 4 diff --git a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg index 1d78bd0f1d..ff4d152ef2 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg index 3c51389cc8..f181244796 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/pc/cartesio_0.25_pc_high.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.25_pc_high.inst.cfg index c45194e18b..15c7f17451 100644 --- a/resources/quality/cartesio/pc/cartesio_0.25_pc_high.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.25_pc_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg index cca1922fa1..91676e65f0 100644 --- a/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg index 8c46693c91..73e1ff6bc5 100644 --- a/resources/quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg index 6dc8225f82..d217756cb4 100644 --- a/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg index 04f01db6ba..cba868e95e 100644 --- a/resources/quality/cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = 3 diff --git a/resources/quality/cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg index 53e21ec4d0..4aff24ed02 100644 --- a/resources/quality/cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extra coarse weight = 4 diff --git a/resources/quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg index 0b2b9dcb26..f00e83f63e 100644 --- a/resources/quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg index b47f7f1ded..2f8ed80751 100644 --- a/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/petg/cartesio_0.25_petg_high.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.25_petg_high.inst.cfg index 9dc7adfc88..3c8dcc7af6 100644 --- a/resources/quality/cartesio/petg/cartesio_0.25_petg_high.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.25_petg_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg index d9f358360d..7aedc76af9 100644 --- a/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/petg/cartesio_0.4_petg_high.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.4_petg_high.inst.cfg index 93388787e6..3788a4dd51 100644 --- a/resources/quality/cartesio/petg/cartesio_0.4_petg_high.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.4_petg_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg index f5269d4e88..4805ca55bb 100644 --- a/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg index 754c55caf5..d7d6e35a3c 100644 --- a/resources/quality/cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = 3 diff --git a/resources/quality/cartesio/petg/cartesio_0.8_petg_extra_coarse.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.8_petg_extra_coarse.inst.cfg index 81b1de32a2..784bd0d6af 100644 --- a/resources/quality/cartesio/petg/cartesio_0.8_petg_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.8_petg_extra_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extra coarse weight = 4 diff --git a/resources/quality/cartesio/petg/cartesio_0.8_petg_high.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.8_petg_high.inst.cfg index 86e93c8a32..bced328a9c 100644 --- a/resources/quality/cartesio/petg/cartesio_0.8_petg_high.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.8_petg_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg index ef4b5428c0..2a9da4f164 100644 --- a/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/pla/cartesio_0.25_pla_high.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.25_pla_high.inst.cfg index 4841f9f368..15456a0b78 100644 --- a/resources/quality/cartesio/pla/cartesio_0.25_pla_high.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.25_pla_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/pla/cartesio_0.25_pla_normal.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.25_pla_normal.inst.cfg index 3ba36f9436..bfa792f133 100644 --- a/resources/quality/cartesio/pla/cartesio_0.25_pla_normal.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.25_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/pla/cartesio_0.4_pla_high.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.4_pla_high.inst.cfg index 7c785a750a..e64b67b59b 100644 --- a/resources/quality/cartesio/pla/cartesio_0.4_pla_high.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.4_pla_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/pla/cartesio_0.4_pla_normal.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.4_pla_normal.inst.cfg index b24394daf0..704a974b63 100644 --- a/resources/quality/cartesio/pla/cartesio_0.4_pla_normal.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.4_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg index 6443f2d526..b8ff99c256 100644 --- a/resources/quality/cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = -3 diff --git a/resources/quality/cartesio/pla/cartesio_0.8_pla_extra_coarse.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.8_pla_extra_coarse.inst.cfg index 51a93f76d9..da613e6e1a 100644 --- a/resources/quality/cartesio/pla/cartesio_0.8_pla_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.8_pla_extra_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extra coarse weight = -4 diff --git a/resources/quality/cartesio/pla/cartesio_0.8_pla_high.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.8_pla_high.inst.cfg index 2f72d9d158..05c0f72686 100644 --- a/resources/quality/cartesio/pla/cartesio_0.8_pla_high.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.8_pla_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/pla/cartesio_0.8_pla_normal.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.8_pla_normal.inst.cfg index 431f7c0fff..8434f4abc6 100644 --- a/resources/quality/cartesio/pla/cartesio_0.8_pla_normal.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.8_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/pva/cartesio_0.25_pva_high.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.25_pva_high.inst.cfg index fe21c17e22..7df550917f 100644 --- a/resources/quality/cartesio/pva/cartesio_0.25_pva_high.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.25_pva_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg index 940432e07e..1f1d9549fb 100644 --- a/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/pva/cartesio_0.4_pva_high.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.4_pva_high.inst.cfg index cdf8f8cae7..faf1633ce2 100644 --- a/resources/quality/cartesio/pva/cartesio_0.4_pva_high.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.4_pva_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg index 9a0e279e6a..1dc24190c6 100644 --- a/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg index fc35e14fc6..35b2d1690d 100644 --- a/resources/quality/cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = 3 diff --git a/resources/quality/cartesio/pva/cartesio_0.8_pva_extra_coarse.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.8_pva_extra_coarse.inst.cfg index 0e1b8b1241..3d41308a5d 100644 --- a/resources/quality/cartesio/pva/cartesio_0.8_pva_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.8_pva_extra_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extra coarse weight = 4 diff --git a/resources/quality/cartesio/pva/cartesio_0.8_pva_high.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.8_pva_high.inst.cfg index 249cf6485e..0293ee9acb 100644 --- a/resources/quality/cartesio/pva/cartesio_0.8_pva_high.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.8_pva_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg index 1d8cd52d0d..ae3d51a03f 100644 --- a/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/coarse.inst.cfg b/resources/quality/coarse.inst.cfg index e9b8156a70..77b9004aa6 100644 --- a/resources/quality/coarse.inst.cfg +++ b/resources/quality/coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = fdmprinter [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = -3 diff --git a/resources/quality/dagoma/dagoma_discoeasy200_pla_fast.inst.cfg b/resources/quality/dagoma/dagoma_discoeasy200_pla_fast.inst.cfg index a302f5b513..b12a92dc1c 100644 --- a/resources/quality/dagoma/dagoma_discoeasy200_pla_fast.inst.cfg +++ b/resources/quality/dagoma/dagoma_discoeasy200_pla_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = dagoma_discoeasy200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/dagoma/dagoma_discoeasy200_pla_fine.inst.cfg b/resources/quality/dagoma/dagoma_discoeasy200_pla_fine.inst.cfg index b26eb1d910..055b3e30d6 100644 --- a/resources/quality/dagoma/dagoma_discoeasy200_pla_fine.inst.cfg +++ b/resources/quality/dagoma/dagoma_discoeasy200_pla_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = dagoma_discoeasy200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/dagoma/dagoma_discoeasy200_pla_standard.inst.cfg b/resources/quality/dagoma/dagoma_discoeasy200_pla_standard.inst.cfg index 9ec56f696a..7c244b3f18 100644 --- a/resources/quality/dagoma/dagoma_discoeasy200_pla_standard.inst.cfg +++ b/resources/quality/dagoma/dagoma_discoeasy200_pla_standard.inst.cfg @@ -4,7 +4,7 @@ name = Standard definition = dagoma_discoeasy200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/dagoma/dagoma_global_fast.inst.cfg b/resources/quality/dagoma/dagoma_global_fast.inst.cfg index 28569387f2..f0d312e0a7 100644 --- a/resources/quality/dagoma/dagoma_global_fast.inst.cfg +++ b/resources/quality/dagoma/dagoma_global_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = dagoma_discoeasy200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/dagoma/dagoma_global_fine.inst.cfg b/resources/quality/dagoma/dagoma_global_fine.inst.cfg index 1f7d577c1b..bf0a173ec3 100644 --- a/resources/quality/dagoma/dagoma_global_fine.inst.cfg +++ b/resources/quality/dagoma/dagoma_global_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = dagoma_discoeasy200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/dagoma/dagoma_global_standard.inst.cfg b/resources/quality/dagoma/dagoma_global_standard.inst.cfg index 167062c1d7..afeb925e96 100644 --- a/resources/quality/dagoma/dagoma_global_standard.inst.cfg +++ b/resources/quality/dagoma/dagoma_global_standard.inst.cfg @@ -4,7 +4,7 @@ name = Standard definition = dagoma_discoeasy200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/dagoma/dagoma_magis_pla_fast.inst.cfg b/resources/quality/dagoma/dagoma_magis_pla_fast.inst.cfg index d87c913eb6..8387ff2401 100644 --- a/resources/quality/dagoma/dagoma_magis_pla_fast.inst.cfg +++ b/resources/quality/dagoma/dagoma_magis_pla_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = dagoma_magis [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/dagoma/dagoma_magis_pla_fine.inst.cfg b/resources/quality/dagoma/dagoma_magis_pla_fine.inst.cfg index d046726e0e..60c0cae7ec 100644 --- a/resources/quality/dagoma/dagoma_magis_pla_fine.inst.cfg +++ b/resources/quality/dagoma/dagoma_magis_pla_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = dagoma_magis [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/dagoma/dagoma_magis_pla_standard.inst.cfg b/resources/quality/dagoma/dagoma_magis_pla_standard.inst.cfg index 39961ea93b..b406d43cb1 100644 --- a/resources/quality/dagoma/dagoma_magis_pla_standard.inst.cfg +++ b/resources/quality/dagoma/dagoma_magis_pla_standard.inst.cfg @@ -4,7 +4,7 @@ name = Standard definition = dagoma_magis [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/dagoma/dagoma_neva_pla_fast.inst.cfg b/resources/quality/dagoma/dagoma_neva_pla_fast.inst.cfg index efdf2f7d32..c0e8d7fe94 100644 --- a/resources/quality/dagoma/dagoma_neva_pla_fast.inst.cfg +++ b/resources/quality/dagoma/dagoma_neva_pla_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = dagoma_neva [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/dagoma/dagoma_neva_pla_fine.inst.cfg b/resources/quality/dagoma/dagoma_neva_pla_fine.inst.cfg index 50915db112..b6d6966c81 100644 --- a/resources/quality/dagoma/dagoma_neva_pla_fine.inst.cfg +++ b/resources/quality/dagoma/dagoma_neva_pla_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = dagoma_neva [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/dagoma/dagoma_neva_pla_standard.inst.cfg b/resources/quality/dagoma/dagoma_neva_pla_standard.inst.cfg index ed67800eac..eff587c908 100644 --- a/resources/quality/dagoma/dagoma_neva_pla_standard.inst.cfg +++ b/resources/quality/dagoma/dagoma_neva_pla_standard.inst.cfg @@ -4,7 +4,7 @@ name = Standard definition = dagoma_neva [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/deltacomb/deltacomb_abs_Draft_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_abs_Draft_Quality.inst.cfg index f540400575..9316a84175 100644 --- a/resources/quality/deltacomb/deltacomb_abs_Draft_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_abs_Draft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fast (beta) definition = deltacomb [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/deltacomb/deltacomb_abs_Fast_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_abs_Fast_Quality.inst.cfg index 2214813913..a2c67ff890 100644 --- a/resources/quality/deltacomb/deltacomb_abs_Fast_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_abs_Fast_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal (beta) definition = deltacomb [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/deltacomb/deltacomb_abs_High_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_abs_High_Quality.inst.cfg index d407b66762..be428bb8f4 100644 --- a/resources/quality/deltacomb/deltacomb_abs_High_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_abs_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine (beta) definition = deltacomb [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/deltacomb/deltacomb_abs_Normal_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_abs_Normal_Quality.inst.cfg index 332e1890c6..1f4184f3ad 100644 --- a/resources/quality/deltacomb/deltacomb_abs_Normal_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_abs_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine (beta) definition = deltacomb [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/deltacomb/deltacomb_abs_Verydraft_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_abs_Verydraft_Quality.inst.cfg index 674174c0bd..37925e0e4c 100644 --- a/resources/quality/deltacomb/deltacomb_abs_Verydraft_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_abs_Verydraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast (beta) definition = deltacomb [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/deltacomb/deltacomb_global_Draft_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_global_Draft_Quality.inst.cfg index f8887810d5..072f0435f6 100755 --- a/resources/quality/deltacomb/deltacomb_global_Draft_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_global_Draft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = deltacomb [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/deltacomb/deltacomb_global_Fast_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_global_Fast_Quality.inst.cfg index 99030a084b..eef96e35b8 100755 --- a/resources/quality/deltacomb/deltacomb_global_Fast_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_global_Fast_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = deltacomb [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/deltacomb/deltacomb_global_High_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_global_High_Quality.inst.cfg index b56b222eb1..becd10ea65 100755 --- a/resources/quality/deltacomb/deltacomb_global_High_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_global_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = deltacomb [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/deltacomb/deltacomb_global_Normal_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_global_Normal_Quality.inst.cfg index a3bafadeec..4c95c74cfa 100755 --- a/resources/quality/deltacomb/deltacomb_global_Normal_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_global_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = deltacomb [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/deltacomb/deltacomb_global_Verydraft_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_global_Verydraft_Quality.inst.cfg index 84c6e66f61..0ba6ca588f 100755 --- a/resources/quality/deltacomb/deltacomb_global_Verydraft_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_global_Verydraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = deltacomb [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/deltacomb/deltacomb_pla_Draft_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_pla_Draft_Quality.inst.cfg index c4f884486e..e0e695570d 100644 --- a/resources/quality/deltacomb/deltacomb_pla_Draft_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_pla_Draft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = deltacomb [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/deltacomb/deltacomb_pla_Fast_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_pla_Fast_Quality.inst.cfg index 714d4e3517..3f43871a8f 100644 --- a/resources/quality/deltacomb/deltacomb_pla_Fast_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_pla_Fast_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = deltacomb [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/deltacomb/deltacomb_pla_High_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_pla_High_Quality.inst.cfg index 440bac36e9..b3924431af 100644 --- a/resources/quality/deltacomb/deltacomb_pla_High_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_pla_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = deltacomb [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/deltacomb/deltacomb_pla_Normal_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_pla_Normal_Quality.inst.cfg index 58470ed650..98ec4f46cd 100644 --- a/resources/quality/deltacomb/deltacomb_pla_Normal_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_pla_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = deltacomb [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/deltacomb/deltacomb_pla_Verydraft_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_pla_Verydraft_Quality.inst.cfg index 9c00877c24..f67a2d8a26 100644 --- a/resources/quality/deltacomb/deltacomb_pla_Verydraft_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_pla_Verydraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = deltacomb [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/draft.inst.cfg b/resources/quality/draft.inst.cfg index ac1d9ec52f..a605b9c83c 100644 --- a/resources/quality/draft.inst.cfg +++ b/resources/quality/draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = fdmprinter [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/extra_coarse.inst.cfg b/resources/quality/extra_coarse.inst.cfg index 2a1a203d22..bf22b7ac3c 100644 --- a/resources/quality/extra_coarse.inst.cfg +++ b/resources/quality/extra_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse definition = fdmprinter [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extra coarse weight = -4 diff --git a/resources/quality/extra_fast.inst.cfg b/resources/quality/extra_fast.inst.cfg index da890f1653..eb1e7b3a42 100644 --- a/resources/quality/extra_fast.inst.cfg +++ b/resources/quality/extra_fast.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = fdmprinter [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/fabtotum/fabtotum_abs_fast.inst.cfg b/resources/quality/fabtotum/fabtotum_abs_fast.inst.cfg index 95e8b93b36..036d49a94f 100644 --- a/resources/quality/fabtotum/fabtotum_abs_fast.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_abs_fast.inst.cfg @@ -4,7 +4,7 @@ definition = fabtotum name = Fast Quality [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/fabtotum/fabtotum_abs_high.inst.cfg b/resources/quality/fabtotum/fabtotum_abs_high.inst.cfg index baedf0ed2b..f3d6f33952 100644 --- a/resources/quality/fabtotum/fabtotum_abs_high.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_abs_high.inst.cfg @@ -4,7 +4,7 @@ definition = fabtotum name = High Quality [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/fabtotum/fabtotum_abs_normal.inst.cfg b/resources/quality/fabtotum/fabtotum_abs_normal.inst.cfg index 58933486ee..d01599a392 100644 --- a/resources/quality/fabtotum/fabtotum_abs_normal.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_abs_normal.inst.cfg @@ -4,7 +4,7 @@ definition = fabtotum name = Normal Quality [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/fabtotum/fabtotum_nylon_fast.inst.cfg b/resources/quality/fabtotum/fabtotum_nylon_fast.inst.cfg index 00f0737227..1f0c050126 100644 --- a/resources/quality/fabtotum/fabtotum_nylon_fast.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_nylon_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fast Quality definition = fabtotum [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/fabtotum/fabtotum_nylon_high.inst.cfg b/resources/quality/fabtotum/fabtotum_nylon_high.inst.cfg index bd7f32c9ba..4e234f62f8 100644 --- a/resources/quality/fabtotum/fabtotum_nylon_high.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_nylon_high.inst.cfg @@ -4,7 +4,7 @@ name = High Quality definition = fabtotum [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/fabtotum/fabtotum_nylon_normal.inst.cfg b/resources/quality/fabtotum/fabtotum_nylon_normal.inst.cfg index 6a450e7ffe..67998dea38 100644 --- a/resources/quality/fabtotum/fabtotum_nylon_normal.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_nylon_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal Quality definition = fabtotum [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/fabtotum/fabtotum_pla_fast.inst.cfg b/resources/quality/fabtotum/fabtotum_pla_fast.inst.cfg index afac0b0884..e27477e8de 100644 --- a/resources/quality/fabtotum/fabtotum_pla_fast.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_pla_fast.inst.cfg @@ -4,7 +4,7 @@ definition = fabtotum name = Fast Quality [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/fabtotum/fabtotum_pla_high.inst.cfg b/resources/quality/fabtotum/fabtotum_pla_high.inst.cfg index 89dc6d9b33..bab6d5fc82 100644 --- a/resources/quality/fabtotum/fabtotum_pla_high.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_pla_high.inst.cfg @@ -4,7 +4,7 @@ definition = fabtotum name = High Quality [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/fabtotum/fabtotum_pla_normal.inst.cfg b/resources/quality/fabtotum/fabtotum_pla_normal.inst.cfg index e5496a13d4..7bd3bc024e 100644 --- a/resources/quality/fabtotum/fabtotum_pla_normal.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_pla_normal.inst.cfg @@ -4,7 +4,7 @@ definition = fabtotum name = Normal Quality [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/fabtotum/fabtotum_tpu_fast.inst.cfg b/resources/quality/fabtotum/fabtotum_tpu_fast.inst.cfg index 7917c92514..5668d4a5b9 100644 --- a/resources/quality/fabtotum/fabtotum_tpu_fast.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_tpu_fast.inst.cfg @@ -5,7 +5,7 @@ name = Fast Quality [metadata] type = quality -setting_version = 5 +setting_version = 6 material = generic_tpu quality_type = fast weight = -1 diff --git a/resources/quality/fabtotum/fabtotum_tpu_high.inst.cfg b/resources/quality/fabtotum/fabtotum_tpu_high.inst.cfg index 1c31967d79..6af9e88f00 100644 --- a/resources/quality/fabtotum/fabtotum_tpu_high.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_tpu_high.inst.cfg @@ -5,7 +5,7 @@ name = High Quality [metadata] type = quality -setting_version = 5 +setting_version = 6 material = generic_tpu quality_type = high weight = 1 diff --git a/resources/quality/fabtotum/fabtotum_tpu_normal.inst.cfg b/resources/quality/fabtotum/fabtotum_tpu_normal.inst.cfg index 0a3821f953..13faf5bc2f 100644 --- a/resources/quality/fabtotum/fabtotum_tpu_normal.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_tpu_normal.inst.cfg @@ -5,7 +5,7 @@ name = Normal Quality [metadata] type = quality -setting_version = 5 +setting_version = 6 material = generic_tpu quality_type = normal weight = 0 diff --git a/resources/quality/fast.inst.cfg b/resources/quality/fast.inst.cfg index 7568c42e8f..94a7961320 100644 --- a/resources/quality/fast.inst.cfg +++ b/resources/quality/fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = fdmprinter [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/gmax15plus/gmax15plus_global_dual_normal.inst.cfg b/resources/quality/gmax15plus/gmax15plus_global_dual_normal.inst.cfg index 63af72a6b1..3c9c9c0dfd 100644 --- a/resources/quality/gmax15plus/gmax15plus_global_dual_normal.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_global_dual_normal.inst.cfg @@ -4,7 +4,7 @@ name = gMax 1.5+ Dual Normal Layers definition = gmax15plus_dual [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/gmax15plus/gmax15plus_global_dual_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_global_dual_thick.inst.cfg index 94a15bfa2b..24740362af 100644 --- a/resources/quality/gmax15plus/gmax15plus_global_dual_thick.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_global_dual_thick.inst.cfg @@ -4,7 +4,7 @@ name = gMax 1.5+ Dual Thick Layers definition = gmax15plus_dual [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = course weight = -2 diff --git a/resources/quality/gmax15plus/gmax15plus_global_dual_thin.inst.cfg b/resources/quality/gmax15plus/gmax15plus_global_dual_thin.inst.cfg index 3a69778d89..845a1c2c39 100644 --- a/resources/quality/gmax15plus/gmax15plus_global_dual_thin.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_global_dual_thin.inst.cfg @@ -4,7 +4,7 @@ name = gMax 1.5+ Dual Thin Layers definition = gmax15plus_dual [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/gmax15plus/gmax15plus_global_dual_very_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_global_dual_very_thick.inst.cfg index a35e951c32..4dbd81255a 100644 --- a/resources/quality/gmax15plus/gmax15plus_global_dual_very_thick.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_global_dual_very_thick.inst.cfg @@ -4,7 +4,7 @@ name = gMax 1.5+ Dual Very Thick Layers definition = gmax15plus_dual [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extra_course weight = -3 diff --git a/resources/quality/gmax15plus/gmax15plus_global_normal.inst.cfg b/resources/quality/gmax15plus/gmax15plus_global_normal.inst.cfg index 5d52a8149e..8b91006184 100644 --- a/resources/quality/gmax15plus/gmax15plus_global_normal.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_global_normal.inst.cfg @@ -4,7 +4,7 @@ name = gMax 1.5+ Normal Layers definition = gmax15plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/gmax15plus/gmax15plus_global_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_global_thick.inst.cfg index 8b01d1a166..c5ef9fdf83 100644 --- a/resources/quality/gmax15plus/gmax15plus_global_thick.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_global_thick.inst.cfg @@ -4,7 +4,7 @@ name = gMax 1.5+ Thick Layers definition = gmax15plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = course weight = -2 diff --git a/resources/quality/gmax15plus/gmax15plus_global_thin.inst.cfg b/resources/quality/gmax15plus/gmax15plus_global_thin.inst.cfg index a097e9a981..b3a2ed8d82 100644 --- a/resources/quality/gmax15plus/gmax15plus_global_thin.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_global_thin.inst.cfg @@ -4,7 +4,7 @@ name = gMax 1.5+ Thin Layers definition = gmax15plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/gmax15plus/gmax15plus_global_very_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_global_very_thick.inst.cfg index 36f78673c2..5ebcf5e12d 100644 --- a/resources/quality/gmax15plus/gmax15plus_global_very_thick.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_global_very_thick.inst.cfg @@ -4,7 +4,7 @@ name = gMax 1.5+ Very Thick Layers definition = gmax15plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extra_course weight = -3 diff --git a/resources/quality/high.inst.cfg b/resources/quality/high.inst.cfg index 1b687bf5e4..2ef1aba9e1 100644 --- a/resources/quality/high.inst.cfg +++ b/resources/quality/high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = fdmprinter [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg index 6a50e24678..e299e675e0 100644 --- a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg index 2c8a43874a..7123c6440a 100644 --- a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg index 264c95c933..297531f989 100644 --- a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg @@ -4,7 +4,7 @@ name = Medium definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg index dfdfc2458c..d15c4a3b2d 100644 --- a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg @@ -4,7 +4,7 @@ name = Medium definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg index 68eec0c753..9ff4e6d49e 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg index 46f81d0c1a..88635bb56d 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg index f614b7cc3c..89dcca901c 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg index 5525899ea7..c7fd702eeb 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg index 28b4307cea..7f030b53e2 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg @@ -4,7 +4,7 @@ name = Medium definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg index 52a8594505..2759a24a8d 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg @@ -4,7 +4,7 @@ name = Medium definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg index bf3d409050..b74b9434b7 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg @@ -4,7 +4,7 @@ name = UltraFine definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = ultrahigh weight = 2 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine_2-fans.inst.cfg index 676ea84825..21df5445ab 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine_2-fans.inst.cfg @@ -4,7 +4,7 @@ name = UltraFine definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = ultrahigh weight = 2 diff --git a/resources/quality/imade3d_jellybox/imade3d_jellybox_coarse.inst.cfg b/resources/quality/imade3d_jellybox/imade3d_jellybox_coarse.inst.cfg index 819501c727..1c6ef69145 100644 --- a/resources/quality/imade3d_jellybox/imade3d_jellybox_coarse.inst.cfg +++ b/resources/quality/imade3d_jellybox/imade3d_jellybox_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/imade3d_jellybox/imade3d_jellybox_fine.inst.cfg b/resources/quality/imade3d_jellybox/imade3d_jellybox_fine.inst.cfg index 0f312aa62d..702c5182c9 100644 --- a/resources/quality/imade3d_jellybox/imade3d_jellybox_fine.inst.cfg +++ b/resources/quality/imade3d_jellybox/imade3d_jellybox_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/imade3d_jellybox/imade3d_jellybox_normal.inst.cfg b/resources/quality/imade3d_jellybox/imade3d_jellybox_normal.inst.cfg index 25d0e65d74..87256a9af7 100644 --- a/resources/quality/imade3d_jellybox/imade3d_jellybox_normal.inst.cfg +++ b/resources/quality/imade3d_jellybox/imade3d_jellybox_normal.inst.cfg @@ -4,7 +4,7 @@ name = Medium definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/imade3d_jellybox/imade3d_jellybox_ultrafine.inst.cfg b/resources/quality/imade3d_jellybox/imade3d_jellybox_ultrafine.inst.cfg index ebe5ab620c..ffa7ed4550 100644 --- a/resources/quality/imade3d_jellybox/imade3d_jellybox_ultrafine.inst.cfg +++ b/resources/quality/imade3d_jellybox/imade3d_jellybox_ultrafine.inst.cfg @@ -4,7 +4,7 @@ name = UltraFine definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = ultrahigh weight = 2 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_draft.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_draft.inst.cfg index edba5e79ce..e4b6411ef6 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_draft.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = kemiq_q2_beta [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = -3 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_extra_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_extra_fine.inst.cfg index 899af00b78..faeaee854d 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_extra_fine.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_extra_fine.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = kemiq_q2_beta [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_fine.inst.cfg index 9b7ae123df..1ee9821018 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_fine.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = kemiq_q2_beta [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_low.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_low.inst.cfg index 96888821e3..c47239ee4a 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_low.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_low.inst.cfg @@ -4,7 +4,7 @@ name = Low definition = kemiq_q2_beta [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg index c8f27f6a8f..8eac1515ca 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = kemiq_q2_beta [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_draft.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_draft.inst.cfg index a121d921cc..e51e3f6cd8 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_draft.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = kemiq_q2_beta [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = -3 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_extra_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_extra_fine.inst.cfg index 211da57f0c..f3d9aa9409 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_extra_fine.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_extra_fine.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = kemiq_q2_beta [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_fine.inst.cfg index 5879a76012..92d1a98e2b 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_fine.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = kemiq_q2_beta [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_low.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_low.inst.cfg index 0b437327d8..3fa48b32a6 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_low.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_low.inst.cfg @@ -4,7 +4,7 @@ name = Low definition = kemiq_q2_beta [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg index ca5ac5bd0e..277ddc7ec5 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = kemiq_q2_beta [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_draft.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_draft.inst.cfg index cd6ee5356e..e73ff9b982 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_draft.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = kemiq_q2_gama [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = -3 diff --git a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_extra_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_extra_fine.inst.cfg index 345fdc2f0d..0175eb8ffa 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_extra_fine.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_extra_fine.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = kemiq_q2_gama [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_fine.inst.cfg index bafc8f0016..415fbef684 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_fine.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = kemiq_q2_gama [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_low.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_low.inst.cfg index c8aa72def2..94aa963911 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_low.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_low.inst.cfg @@ -4,7 +4,7 @@ name = Low definition = kemiq_q2_gama [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg index 62c43104e1..cc69216ecd 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = kemiq_q2_gama [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_draft.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_draft.inst.cfg index 5bb967b78a..d54f0071cd 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_draft.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_fast.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_fast.inst.cfg index 30641b863a..bdd9a1ccb8 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_fast.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_high.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_high.inst.cfg index 746b579c70..7a4722d599 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_high.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_high.inst.cfg @@ -4,7 +4,7 @@ name = Finer definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_normal.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_normal.inst.cfg index e4ab115bc5..4cd3f34466 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_normal.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_superdraft.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_superdraft.inst.cfg index d8a7607c5c..bd349b6d72 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_superdraft.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_superdraft.inst.cfg @@ -4,7 +4,7 @@ name = Lowest Quality Draft definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -5 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_thickerdraft.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_thickerdraft.inst.cfg index 44cad5a198..a01282748b 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_thickerdraft.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_thickerdraft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = thickerdraft weight = -3 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg index 995074f330..ac82e263a7 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg @@ -4,7 +4,7 @@ name = Ultra Fine definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = ultra weight = 2 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg index a3d8bd4579..5e3afcb633 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg @@ -4,7 +4,7 @@ name = Low Detail Draft definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/malyan_m200/malyan_m200_global_Draft_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_Draft_Quality.inst.cfg index e53aa86a94..aa1f30d0b3 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_Draft_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_Draft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/malyan_m200/malyan_m200_global_Fast_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_Fast_Quality.inst.cfg index 4379d9fdcb..8cbbdac2e4 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_Fast_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_Fast_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/malyan_m200/malyan_m200_global_High_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_High_Quality.inst.cfg index a9a5720e14..a56a5771d8 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_High_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Finer definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/malyan_m200/malyan_m200_global_Normal_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_Normal_Quality.inst.cfg index 96b982e86a..f24faf98f0 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_Normal_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/malyan_m200/malyan_m200_global_SuperDraft_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_SuperDraft_Quality.inst.cfg index 0550efd603..ff0d97b1cc 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_SuperDraft_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_SuperDraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Lowest Quality Draft definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -5 diff --git a/resources/quality/malyan_m200/malyan_m200_global_ThickerDraft_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_ThickerDraft_Quality.inst.cfg index 9a0454fc75..623b48acff 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_ThickerDraft_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_ThickerDraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = thickerdraft weight = -3 diff --git a/resources/quality/malyan_m200/malyan_m200_global_Ultra_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_Ultra_Quality.inst.cfg index 76eaa3463f..ec04f9055b 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_Ultra_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_Ultra_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Ultra Fine definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = ultra weight = 2 diff --git a/resources/quality/malyan_m200/malyan_m200_global_VeryDraft_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_VeryDraft_Quality.inst.cfg index a3013a68fb..85b5d0df6b 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_VeryDraft_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_VeryDraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Low Detail Draft definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_draft.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_draft.inst.cfg index 96144c193f..6f36402470 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_draft.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_fast.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_fast.inst.cfg index f390034a1f..ff14d6a96e 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_fast.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_high.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_high.inst.cfg index 693c6efc08..74ab347def 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_high.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_high.inst.cfg @@ -4,7 +4,7 @@ name = Finer definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_normal.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_normal.inst.cfg index 09c5c2b14d..0862f96460 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_normal.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_superdraft.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_superdraft.inst.cfg index 0faec6b357..df50ebcc42 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_superdraft.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_superdraft.inst.cfg @@ -4,7 +4,7 @@ name = Lowest Quality Draft definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -5 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_thickerdraft.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_thickerdraft.inst.cfg index 988082f783..3697573e0e 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_thickerdraft.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_thickerdraft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = thickerdraft weight = -3 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg index 4eb84672e7..c9858b63c7 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg @@ -4,7 +4,7 @@ name = Ultra Fine definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = ultra weight = 2 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg index e0305105af..b88d57ab76 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg @@ -4,7 +4,7 @@ name = Low Detail Draft definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_draft.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_draft.inst.cfg index 9a26d1b2a1..7a3af8285a 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_draft.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_fast.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_fast.inst.cfg index ef4d002ce3..f813e062dd 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_fast.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_high.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_high.inst.cfg index 6ff347a7cc..5fe854ddab 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_high.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_high.inst.cfg @@ -4,7 +4,7 @@ name = Finer definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_normal.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_normal.inst.cfg index b6aa938b94..cce3508550 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_normal.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_superdraft.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_superdraft.inst.cfg index 8a4b63691f..477256a933 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_superdraft.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_superdraft.inst.cfg @@ -4,7 +4,7 @@ name = Lowest Quality Draft definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -5 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_thickerdraft.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_thickerdraft.inst.cfg index 98a8363c85..1841b91d3d 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_thickerdraft.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_thickerdraft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = thickerdraft weight = -3 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg index 5a334bd9c1..24717cda19 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg @@ -4,7 +4,7 @@ name = Ultra Fine definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = ultra weight = 2 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg index a79d253e49..9e638d67c5 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg @@ -4,7 +4,7 @@ name = Low Detail Draft definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_draft.inst.cfg index ef579a567e..e8959a1235 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_draft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_fast.inst.cfg index 33296bf677..256eea1976 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_fast.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_high.inst.cfg index e282847f14..6d0250121f 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_high.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_high.inst.cfg @@ -4,7 +4,7 @@ name = Finer definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_normal.inst.cfg index 2979f574a4..88c12a38f0 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_normal.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_superdraft.inst.cfg index 2d4d3c7461..2eacd312f4 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_superdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_superdraft.inst.cfg @@ -4,7 +4,7 @@ name = Lowest Quality Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -5 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_thickerdraft.inst.cfg index ed43dec3ae..4b311bcfed 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_thickerdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_thickerdraft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = thickerdraft weight = -3 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_ultra.inst.cfg index eb556fe862..e9857b76b3 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_ultra.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_ultra.inst.cfg @@ -4,7 +4,7 @@ name = Ultra Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = thickerdraft weight = 2 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg index 21d1215dca..aa29220d34 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg @@ -4,7 +4,7 @@ name = Low Detail Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Draft_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Draft_Quality.inst.cfg index 1d81d7535e..add2590cce 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Draft_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Draft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Fast_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Fast_Quality.inst.cfg index 6a5a041244..2feddbd32a 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Fast_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Fast_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_High_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_High_Quality.inst.cfg index 65925a1ea4..263bd8544c 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_High_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Finer definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Normal_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Normal_Quality.inst.cfg index 0ac150c117..52e2ec79f3 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Normal_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_SuperDraft_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_SuperDraft_Quality.inst.cfg index b02910cf12..dfbd2d4d3d 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_SuperDraft_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_SuperDraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Lowest Quality Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -5 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_ThickerDraft_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_ThickerDraft_Quality.inst.cfg index 46434555ad..f05617c4f0 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_ThickerDraft_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_ThickerDraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = thickerdraft weight = -3 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Ultra_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Ultra_Quality.inst.cfg index dfb4942b29..e6d835d683 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Ultra_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Ultra_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Ultra Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = ultra weight = 2 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_VeryDraft_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_VeryDraft_Quality.inst.cfg index 36aa5a9a37..f44b085be1 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_VeryDraft_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_VeryDraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Low Detail Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_draft.inst.cfg index 4d7d1cd848..c7701b56d3 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_draft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_fast.inst.cfg index 1a18df9651..dbe3b03148 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_fast.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_high.inst.cfg index ac0ca29caa..4612b19638 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_high.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_high.inst.cfg @@ -4,7 +4,7 @@ name = Finer definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_normal.inst.cfg index 32c5e33f0d..7b887afb8d 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_normal.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_superdraft.inst.cfg index 26f260f861..c696c71fd5 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_superdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_superdraft.inst.cfg @@ -4,7 +4,7 @@ name = Lowest Quality Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -5 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_thickerdraft.inst.cfg index b5bcc7d455..c561bcda04 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_thickerdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_thickerdraft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = thickerdraft weight = -3 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_ultra.inst.cfg index 6fc41e34b6..e16e044708 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_ultra.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_ultra.inst.cfg @@ -4,7 +4,7 @@ name = Ultra Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = ultra weight = 2 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg index 40f6a9f53d..9bf829c778 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg @@ -4,7 +4,7 @@ name = Low Detail Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_draft.inst.cfg index 76b210eba1..6cc27cd3e8 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_draft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_fast.inst.cfg index 53a099f42d..95ef667be9 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_fast.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_high.inst.cfg index 1a6193fbaf..c874fc5c42 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_high.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_high.inst.cfg @@ -4,7 +4,7 @@ name = Finer definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_normal.inst.cfg index 72e94d1828..62fb4046aa 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_normal.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_superdraft.inst.cfg index 13914d07e7..e1c88805e7 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_superdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_superdraft.inst.cfg @@ -4,7 +4,7 @@ name = Lowest Quality Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -5 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_thickerdraft.inst.cfg index d02a793b25..0cec8831bf 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_thickerdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_thickerdraft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = thickerdraft weight = -3 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_ultra.inst.cfg index 41b3821727..6aaf8680f5 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_ultra.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_ultra.inst.cfg @@ -4,7 +4,7 @@ name = Ultra Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = ultra weight = 2 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg index 5202565894..7a63b896c3 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg @@ -4,7 +4,7 @@ name = Low Detail Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_draft.inst.cfg index c2c8889127..4e31a46fbd 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_draft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_fast.inst.cfg index 881311d395..e0d7d393c5 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_fast.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_high.inst.cfg index f9f1e169cb..64451b0788 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_high.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_high.inst.cfg @@ -4,7 +4,7 @@ name = Finer definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_normal.inst.cfg index 026279f012..1f5b6c956c 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_normal.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_superdraft.inst.cfg index 3ff71bf416..9b269ee95b 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_superdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_superdraft.inst.cfg @@ -4,7 +4,7 @@ name = Lowest Quality Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -5 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_thickerdraft.inst.cfg index 5524ec59ea..e180b50a89 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_thickerdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_thickerdraft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = thickerdraft weight = -3 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_ultra.inst.cfg index 99d1da45c7..fe77254c56 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_ultra.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_ultra.inst.cfg @@ -4,7 +4,7 @@ name = Ultra Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = ultra weight = 2 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg index a9f891692a..9505b2b15b 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg @@ -4,7 +4,7 @@ name = Low Detail Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_draft.inst.cfg index a64020a89e..8333cd10ac 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_draft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_fast.inst.cfg index 994d6ff0fd..ab83dacbe8 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_fast.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = 0 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg index f8458ce63b..13f31a614e 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg @@ -4,7 +4,7 @@ name = Finer definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_normal.inst.cfg index afbc03d5af..57fb63fdea 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_normal.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_superdraft.inst.cfg index ec30cfe2b9..77c3a18b54 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_superdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_superdraft.inst.cfg @@ -4,7 +4,7 @@ name = Lowest Quality Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -5 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_thickerdraft.inst.cfg index 916285385d..52b871217b 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_thickerdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_thickerdraft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = thickerdraft weight = -3 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_ultra.inst.cfg index 5d627b6d35..36ef492905 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_ultra.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_ultra.inst.cfg @@ -4,7 +4,7 @@ name = Ultra Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = ultra weight = 2 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_verydraft.inst.cfg index 9f22fb3692..e1d636b2b1 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_verydraft.inst.cfg @@ -4,7 +4,7 @@ name = Low Detail Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality material = generic_pla weight = 0 diff --git a/resources/quality/normal.inst.cfg b/resources/quality/normal.inst.cfg index f32c87bc60..02b9ebf621 100644 --- a/resources/quality/normal.inst.cfg +++ b/resources/quality/normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = fdmprinter [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/peopoly_moai/peopoly_moai_coarse.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_coarse.inst.cfg index ac4f9ee81d..9ca6cec759 100644 --- a/resources/quality/peopoly_moai/peopoly_moai_coarse.inst.cfg +++ b/resources/quality/peopoly_moai/peopoly_moai_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = peopoly_moai [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = 3 diff --git a/resources/quality/peopoly_moai/peopoly_moai_draft.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_draft.inst.cfg index 53abc477ae..72953e5305 100644 --- a/resources/quality/peopoly_moai/peopoly_moai_draft.inst.cfg +++ b/resources/quality/peopoly_moai/peopoly_moai_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = peopoly_moai [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/peopoly_moai/peopoly_moai_extra_high.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_extra_high.inst.cfg index 796c2cff3c..30d41aa7f8 100644 --- a/resources/quality/peopoly_moai/peopoly_moai_extra_high.inst.cfg +++ b/resources/quality/peopoly_moai/peopoly_moai_extra_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra High definition = peopoly_moai [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extra_high weight = 0 diff --git a/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg index b36163d9f1..37442ed20c 100644 --- a/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg +++ b/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = peopoly_moai [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg index 89d0aa2980..33bb5673ae 100644 --- a/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg +++ b/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = peopoly_moai [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/tevo_blackwidow/tevo_blackwidow_draft.inst.cfg b/resources/quality/tevo_blackwidow/tevo_blackwidow_draft.inst.cfg index be83533e0b..13f12ef643 100644 --- a/resources/quality/tevo_blackwidow/tevo_blackwidow_draft.inst.cfg +++ b/resources/quality/tevo_blackwidow/tevo_blackwidow_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = tevo_blackwidow [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/tevo_blackwidow/tevo_blackwidow_high.inst.cfg b/resources/quality/tevo_blackwidow/tevo_blackwidow_high.inst.cfg index 5ca8a6e4ef..0f0ccf64c6 100644 --- a/resources/quality/tevo_blackwidow/tevo_blackwidow_high.inst.cfg +++ b/resources/quality/tevo_blackwidow/tevo_blackwidow_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = tevo_blackwidow [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/tevo_blackwidow/tevo_blackwidow_normal.inst.cfg b/resources/quality/tevo_blackwidow/tevo_blackwidow_normal.inst.cfg index f542952fab..ebd5997027 100644 --- a/resources/quality/tevo_blackwidow/tevo_blackwidow_normal.inst.cfg +++ b/resources/quality/tevo_blackwidow/tevo_blackwidow_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = tevo_blackwidow [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/tizyx_k25/tizyx_k25_normal.inst.cfg b/resources/quality/tizyx_k25/tizyx_k25_normal.inst.cfg index 8b066f139f..f259ad1b34 100644 --- a/resources/quality/tizyx_k25/tizyx_k25_normal.inst.cfg +++ b/resources/quality/tizyx_k25/tizyx_k25_normal.inst.cfg @@ -5,7 +5,7 @@ definition = tizyx_k25 [metadata] quality_type = normal -setting_version = 5 +setting_version = 6 type = quality global_quality = True diff --git a/resources/quality/ultimaker2/um2_draft.inst.cfg b/resources/quality/ultimaker2/um2_draft.inst.cfg index 8c34d2c09d..7d38ba6bf4 100644 --- a/resources/quality/ultimaker2/um2_draft.inst.cfg +++ b/resources/quality/ultimaker2/um2_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = ultimaker2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker2/um2_fast.inst.cfg b/resources/quality/ultimaker2/um2_fast.inst.cfg index 084ed05f92..39cd4da4ef 100644 --- a/resources/quality/ultimaker2/um2_fast.inst.cfg +++ b/resources/quality/ultimaker2/um2_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2/um2_high.inst.cfg b/resources/quality/ultimaker2/um2_high.inst.cfg index 83bb6bb972..142440d53e 100644 --- a/resources/quality/ultimaker2/um2_high.inst.cfg +++ b/resources/quality/ultimaker2/um2_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker2/um2_normal.inst.cfg b/resources/quality/ultimaker2/um2_normal.inst.cfg index febee8581f..b5a87f07f3 100644 --- a/resources/quality/ultimaker2/um2_normal.inst.cfg +++ b/resources/quality/ultimaker2/um2_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg index ff830ae660..d27a136765 100644 --- a/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg index 94ea62a7ca..5bc62e5fd0 100644 --- a/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg index 03de437ee2..2847ab8c15 100644 --- a/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg index 836d866eab..009fcf7877 100644 --- a/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg index de55623c0f..7c492f2ec0 100644 --- a/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg index c96260d52f..1b6cee0e1d 100644 --- a/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg index 886daf58e2..f55567f986 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg index b727acc510..63904632dc 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg index 20e217315b..f76efeb7b2 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg index 853a87c751..fd7dfc86a7 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg index 6d3ef94b9d..aba3222412 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg index 7b39ce966a..23618e2e1d 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg index 8f225271d6..db184abe54 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg index 1e181e23d1..2dc076b012 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg index 9ffb8a05bb..300d5242e2 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg index ee7101f2ec..17a9f1a579 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg index d2de84eae6..6807a1a86a 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg index 581dc0368d..7a15ed53ec 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.4_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.4_draft.inst.cfg index 7549c0081d..cc68478dd8 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpep_0.4_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.4_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.4_normal.inst.cfg index b1e5552562..0d0e0e2043 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpep_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.4_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.6_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.6_draft.inst.cfg index 616f13f110..e08a7fc357 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpep_0.6_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.6_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.6_normal.inst.cfg index d28dc76af8..7c8589f09e 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpep_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.6_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.8_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.8_draft.inst.cfg index 1c4fa746ad..1c42d28128 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpep_0.8_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.8_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.8_normal.inst.cfg index e40d6efc58..072081e092 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpep_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.8_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_global_Coarse_Quality.inst.cfg b/resources/quality/ultimaker2_plus/um2p_global_Coarse_Quality.inst.cfg index a10cb4030c..2a4fe17a24 100644 --- a/resources/quality/ultimaker2_plus/um2p_global_Coarse_Quality.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_global_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Coarse Quality definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = -4 diff --git a/resources/quality/ultimaker2_plus/um2p_global_Draft_Quality.inst.cfg b/resources/quality/ultimaker2_plus/um2p_global_Draft_Quality.inst.cfg index 5645bbee0b..bdf79827b2 100644 --- a/resources/quality/ultimaker2_plus/um2p_global_Draft_Quality.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_global_Draft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Draft Quality definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker2_plus/um2p_global_Extra_Coarse_Quality.inst.cfg b/resources/quality/ultimaker2_plus/um2p_global_Extra_Coarse_Quality.inst.cfg index d9afc804ba..e5338c0e34 100644 --- a/resources/quality/ultimaker2_plus/um2p_global_Extra_Coarse_Quality.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_global_Extra_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse Quality definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extra coarse weight = -3 diff --git a/resources/quality/ultimaker2_plus/um2p_global_Fast_Quality.inst.cfg b/resources/quality/ultimaker2_plus/um2p_global_Fast_Quality.inst.cfg index 7fd6d54c87..453def0668 100644 --- a/resources/quality/ultimaker2_plus/um2p_global_Fast_Quality.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_global_Fast_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_global_High_Quality.inst.cfg b/resources/quality/ultimaker2_plus/um2p_global_High_Quality.inst.cfg index c47efcfb7d..20b9e7ba16 100644 --- a/resources/quality/ultimaker2_plus/um2p_global_High_Quality.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_global_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker2_plus/um2p_global_Normal_Quality.inst.cfg b/resources/quality/ultimaker2_plus/um2p_global_Normal_Quality.inst.cfg index 76c7b8163c..c901687f22 100644 --- a/resources/quality/ultimaker2_plus/um2p_global_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_global_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.25_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.25_high.inst.cfg index 2cab693c74..512f9e499b 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.25_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.25_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.25_normal.inst.cfg index f61a29a35a..ce607f7a83 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.25_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.4_fast.inst.cfg index 341dc7422f..7b06d5205c 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.4_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.4_normal.inst.cfg index 63bc156e15..b65f694e11 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.4_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.6_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.6_fast.inst.cfg index 8aea23fb50..6caa1d2e82 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.6_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.6_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.6_normal.inst.cfg index 28ccd6ffcf..3dad97297f 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.6_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.8_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.8_draft.inst.cfg index f868313ba9..fe5749aeff 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.8_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.8_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.8_normal.inst.cfg index c30d849553..3e16229ad1 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.8_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.25_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.25_high.inst.cfg index 08b60eeb20..0195a6170f 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.25_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.25_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.25_normal.inst.cfg index dbc36f0c25..fe15f050c7 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.25_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg index 18f299b64d..1268e4f5a5 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.4_normal.inst.cfg index 9ebb46c4d3..31a55131bd 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.4_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg index 47f84fe790..a4b0e7865e 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.6_normal.inst.cfg index 2c857435c5..9fef7be2f8 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.6_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.8_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.8_draft.inst.cfg index 6450d9fe56..cfbd0795ab 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.8_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.8_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.8_normal.inst.cfg index 91c990712e..fd24f29c40 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.8_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.4_fast.inst.cfg index 4266bcd46b..8e320bef25 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.4_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.4_normal.inst.cfg index b995c92922..94d7a22965 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.4_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.6_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.6_draft.inst.cfg index a9e4917fa2..aee8437e39 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.6_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.6_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.6_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.6_fast.inst.cfg index 2fec539e2f..f1e709495b 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.6_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.6_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg index f0da3e678d..0e84d2c2e4 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg index 586eb04dd8..905c147e41 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker2_plus/um2p_tpu_0.25_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_tpu_0.25_high.inst.cfg index e0c016abee..47bf078c2f 100644 --- a/resources/quality/ultimaker2_plus/um2p_tpu_0.25_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_tpu_0.25_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker2_plus/um2p_tpu_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_tpu_0.4_normal.inst.cfg index 127f281913..d8543f1f8a 100644 --- a/resources/quality/ultimaker2_plus/um2p_tpu_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_tpu_0.4_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_tpu_0.6_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_tpu_0.6_fast.inst.cfg index c39ea9cec3..1983878a79 100644 --- a/resources/quality/ultimaker2_plus/um2p_tpu_0.6_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_tpu_0.6_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.25_ABS_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_ABS_Normal_Quality.inst.cfg index 5139a1fea8..dda9fd3891 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_ABS_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_ABS_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.25_CPE_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_CPE_Normal_Quality.inst.cfg index 4e81b4f39e..922366d716 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_CPE_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_CPE_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.25_Nylon_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_Nylon_Normal_Quality.inst.cfg index 04dc2ec79b..3535bc4cba 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_Nylon_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_Nylon_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg index 4d585b54c1..f24c53aaee 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine - Experimental definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.25_PLA_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_PLA_Normal_Quality.inst.cfg index 8dbca3cd05..a59c404754 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_PLA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_PLA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg index bee345e302..6f9734511b 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine - Experimental definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.25_TPLA_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_TPLA_Normal_Quality.inst.cfg index 768864bfef..af9bea762a 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_TPLA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_TPLA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.4_ABS_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_ABS_Draft_Print.inst.cfg index 8877912a33..a6ba0a666b 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_ABS_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_ABS_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.4_ABS_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_ABS_Fast_Print.inst.cfg index 926cfd6995..4bd04e36af 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_ABS_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_ABS_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg index 4e79728945..6ef2fa3cb4 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg index 3bded3b97c..e0862a137c 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.4_BAM_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_BAM_Draft_Print.inst.cfg index df7f0fdf02..3de7252b86 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_BAM_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_BAM_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.4_BAM_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_BAM_Fast_Print.inst.cfg index cf330dc984..28bce4eb15 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_BAM_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_BAM_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_BAM_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_BAM_Normal_Quality.inst.cfg index 705c9c4105..0f15931e59 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_BAM_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_BAM_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Draft_Print.inst.cfg index 4e94789a6b..c27fc027fb 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Fast_Print.inst.cfg index d93915d721..6a035522f1 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPEP_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPEP_High_Quality.inst.cfg index 082152c50f..3387430d26 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPEP_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPEP_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Normal_Quality.inst.cfg index 889b94e001..8d0283a20f 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPE_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPE_Draft_Print.inst.cfg index 1891a274c8..a8d5c26315 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPE_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPE_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPE_Fast_Print.inst.cfg index e4cfdb67fc..e4b4e2e21b 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPE_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPE_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPE_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPE_High_Quality.inst.cfg index cec4b950cf..3964608aec 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPE_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPE_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPE_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPE_Normal_Quality.inst.cfg index 892083b264..b0e7234c90 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPE_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPE_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Draft_Print.inst.cfg index 2e4b8f8dcc..5bfa29fd61 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Fast_Print.inst.cfg index 9b271c47cd..eaec1cdbdb 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_Nylon_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_Nylon_High_Quality.inst.cfg index 16c0b6febb..7a0a04b6c2 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_Nylon_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_Nylon_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Normal_Quality.inst.cfg index 17661efbb8..8b18ee20df 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PC_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PC_Draft_Print.inst.cfg index 96acf403a5..fafb839f17 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PC_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PC_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PC_Fast_Print.inst.cfg index f9159b5fca..57527f928c 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PC_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PC_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PC_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PC_High_Quality.inst.cfg index d175e99ad6..37e31c5863 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PC_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PC_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PC_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PC_Normal_Quality.inst.cfg index 557a449022..0961b3ccd6 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PC_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PC_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PLA_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PLA_Draft_Print.inst.cfg index 16626dc544..c24c2cacdf 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PLA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PLA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PLA_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PLA_Fast_Print.inst.cfg index 7f50a2a6f0..d20a06a94a 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PLA_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PLA_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PLA_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PLA_High_Quality.inst.cfg index 507afc5526..bd365c56ae 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PLA_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PLA_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PLA_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PLA_Normal_Quality.inst.cfg index 05febab06d..a291357e58 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PLA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PLA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PP_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PP_Draft_Print.inst.cfg index 4efa5199cb..6dbb444454 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PP_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PP_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PP_Fast_Print.inst.cfg index ad03df5d86..60c304794b 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PP_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PP_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PP_Normal_Quality.inst.cfg index d8d51dd716..92d53d6295 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PP_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.4_TPLA_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_TPLA_Draft_Print.inst.cfg index 9959a39457..6d8c6690a2 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_TPLA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_TPLA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.4_TPLA_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_TPLA_Fast_Print.inst.cfg index 5c68557e9b..c8fbe827e3 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_TPLA_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_TPLA_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_TPLA_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_TPLA_Normal_Quality.inst.cfg index 90556ea487..d1a1bc994c 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_TPLA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_TPLA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.4_TPU_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_TPU_Draft_Print.inst.cfg index 9b9dca3a16..13bc7c0b7e 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_TPU_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_TPU_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.4_TPU_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_TPU_Fast_Print.inst.cfg index e6233a8184..cb3692a84f 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_TPU_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_TPU_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_TPU_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_TPU_Normal_Quality.inst.cfg index e725615854..a5264ce6ec 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_TPU_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_TPU_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.8_ABS_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_ABS_Draft_Print.inst.cfg index e71ea07531..474b24a462 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_ABS_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_ABS_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.8_ABS_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_ABS_Superdraft_Print.inst.cfg index 39aa103631..e9c4f9e3e9 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_ABS_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_ABS_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_aa0.8_ABS_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_ABS_Verydraft_Print.inst.cfg index 3a08643086..213298653a 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_ABS_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_ABS_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg index fc4acf3cb0..bb2aa2d6ef 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast - Experimental definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Superdraft_Print.inst.cfg index 36b3ef603f..98086b2bf1 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint - Experimental definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Verydraft_Print.inst.cfg index 14e08cb14d..0684b9ac1e 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast - Experimental definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPE_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPE_Draft_Print.inst.cfg index 170643275c..05294737b6 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPE_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPE_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPE_Superdraft_Print.inst.cfg index 5b3cb52f18..555d6da1bf 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPE_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPE_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPE_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPE_Verydraft_Print.inst.cfg index fff96ba9fc..da71c679ff 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPE_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPE_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Draft_Print.inst.cfg index e9b0873716..ab11f0fe86 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Superdraft_Print.inst.cfg index 7518acc7f0..46f5a87a1b 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Verydraft_Print.inst.cfg index 040632efec..12d96e9f7d 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg index 80be29ed85..8005618066 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast - Experimental definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg index 149712dde9..601a68ef46 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint - Experimental definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg index 7311cc43a6..0d5b579846 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast - Experimental definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PLA_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PLA_Draft_Print.inst.cfg index 9b861030d8..c5000b0a43 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PLA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PLA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PLA_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PLA_Superdraft_Print.inst.cfg index 42a499f22c..e03663bc2b 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PLA_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PLA_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PLA_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PLA_Verydraft_Print.inst.cfg index d1f3937244..06bf4cf224 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PLA_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PLA_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PP_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PP_Draft_Print.inst.cfg index 19496565bc..b577ba8185 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PP_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PP_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PP_Superdraft_Print.inst.cfg index aeee3b4e09..c0917a9e8e 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PP_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PP_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PP_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PP_Verydraft_Print.inst.cfg index fcd4fcd999..00eb39a400 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PP_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PP_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_TPLA_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_TPLA_Draft_Print.inst.cfg index 3f679870fd..30ce94000f 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_TPLA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_TPLA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.8_TPLA_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_TPLA_Superdraft_Print.inst.cfg index 17dbd1faf9..ea3525c7ee 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_TPLA_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_TPLA_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_aa0.8_TPLA_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_TPLA_Verydraft_Print.inst.cfg index 624496a9ec..1027f52b38 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_TPLA_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_TPLA_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_TPU_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_TPU_Draft_Print.inst.cfg index 90b5103f20..83fb56a84d 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_TPU_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_TPU_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.8_TPU_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_TPU_Superdraft_Print.inst.cfg index a9fab40d4e..36e38654db 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_TPU_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_TPU_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_aa0.8_TPU_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_TPU_Verydraft_Print.inst.cfg index e2ced0a364..96b1406adb 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_TPU_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_TPU_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker3/um3_bb0.4_PVA_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_PVA_Draft_Print.inst.cfg index 7010d292b2..a41b0c0210 100644 --- a/resources/quality/ultimaker3/um3_bb0.4_PVA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.4_PVA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_bb0.4_PVA_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_PVA_Fast_Print.inst.cfg index 325609362f..d7a8885bf9 100644 --- a/resources/quality/ultimaker3/um3_bb0.4_PVA_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.4_PVA_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_bb0.4_PVA_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_PVA_High_Quality.inst.cfg index a0507299fb..be4eedadc8 100644 --- a/resources/quality/ultimaker3/um3_bb0.4_PVA_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.4_PVA_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker3/um3_bb0.4_PVA_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_PVA_Normal_Quality.inst.cfg index 086f811b36..ae576790a8 100644 --- a/resources/quality/ultimaker3/um3_bb0.4_PVA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.4_PVA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_bb0.8_PVA_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_PVA_Draft_Print.inst.cfg index 28556ca7bf..247e7f12c6 100644 --- a/resources/quality/ultimaker3/um3_bb0.8_PVA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.8_PVA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_bb0.8_PVA_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_PVA_Superdraft_Print.inst.cfg index 9ad5499f18..8a4c0cc992 100644 --- a/resources/quality/ultimaker3/um3_bb0.8_PVA_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.8_PVA_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_bb0.8_PVA_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_PVA_Verydraft_Print.inst.cfg index e616214704..c931e6ad5d 100644 --- a/resources/quality/ultimaker3/um3_bb0.8_PVA_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.8_PVA_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg index a421203220..b95ddb1aa9 100644 --- a/resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg index 2ecf7526a2..3510a05343 100644 --- a/resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg index a1fa758163..55fe2bdfda 100644 --- a/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg index afadda378a..cffacfd312 100644 --- a/resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_global_Superdraft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Superdraft_Quality.inst.cfg index f88f5df85f..5fd966bb9f 100644 --- a/resources/quality/ultimaker3/um3_global_Superdraft_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_global_Superdraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_global_Verydraft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Verydraft_Quality.inst.cfg index df626dc724..7e65a6c4c4 100644 --- a/resources/quality/ultimaker3/um3_global_Verydraft_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_global_Verydraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_original/umo_global_Coarse_Quality.inst.cfg b/resources/quality/ultimaker_original/umo_global_Coarse_Quality.inst.cfg index 34f3a2a901..6125d0f687 100644 --- a/resources/quality/ultimaker_original/umo_global_Coarse_Quality.inst.cfg +++ b/resources/quality/ultimaker_original/umo_global_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Coarse Quality definition = ultimaker_original [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = -3 diff --git a/resources/quality/ultimaker_original/umo_global_Draft_Quality.inst.cfg b/resources/quality/ultimaker_original/umo_global_Draft_Quality.inst.cfg index ed8c0ddb97..ebabe4dd46 100644 --- a/resources/quality/ultimaker_original/umo_global_Draft_Quality.inst.cfg +++ b/resources/quality/ultimaker_original/umo_global_Draft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Draft Quality definition = ultimaker_original [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_original/umo_global_Extra_Coarse_Quality.inst.cfg b/resources/quality/ultimaker_original/umo_global_Extra_Coarse_Quality.inst.cfg index 1ad10ac4db..b625ec45ea 100644 --- a/resources/quality/ultimaker_original/umo_global_Extra_Coarse_Quality.inst.cfg +++ b/resources/quality/ultimaker_original/umo_global_Extra_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse Quality definition = ultimaker_original [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extra coarse weight = -4 diff --git a/resources/quality/ultimaker_original/umo_global_Fast_Quality.inst.cfg b/resources/quality/ultimaker_original/umo_global_Fast_Quality.inst.cfg index 6c83239164..e2bceeae7e 100644 --- a/resources/quality/ultimaker_original/umo_global_Fast_Quality.inst.cfg +++ b/resources/quality/ultimaker_original/umo_global_Fast_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_original [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_original/umo_global_High_Quality.inst.cfg b/resources/quality/ultimaker_original/umo_global_High_Quality.inst.cfg index 19752f07bf..883048f557 100644 --- a/resources/quality/ultimaker_original/umo_global_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_original/umo_global_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_original [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_original/umo_global_Normal_Quality.inst.cfg b/resources/quality/ultimaker_original/umo_global_Normal_Quality.inst.cfg index a7dedc9b88..2cec4bfbda 100644 --- a/resources/quality/ultimaker_original/umo_global_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_original/umo_global_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_original [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.25_ABS_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.25_ABS_Normal_Quality.inst.cfg index f2e05b08e8..be8e56d133 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.25_ABS_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.25_ABS_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.25_CPE_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.25_CPE_Normal_Quality.inst.cfg index c15311d104..3eaeda67d5 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.25_CPE_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.25_CPE_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.25_Nylon_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.25_Nylon_Normal_Quality.inst.cfg index 3a8ed8e773..9407fb72b0 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.25_Nylon_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.25_Nylon_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.25_PC_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.25_PC_Normal_Quality.inst.cfg index 53c319d6e6..7cde76a1e1 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.25_PC_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.25_PC_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine - Experimental definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.25_PLA_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.25_PLA_Normal_Quality.inst.cfg index a06f2158fe..ab45d82a3b 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.25_PLA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.25_PLA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.25_PP_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.25_PP_Normal_Quality.inst.cfg index b4d34cc392..1474cad5c1 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.25_PP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.25_PP_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine - Experimental definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.25_TPLA_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.25_TPLA_Normal_Quality.inst.cfg index e9628225bc..ea4375b854 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.25_TPLA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.25_TPLA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Draft_Print.inst.cfg index b86c61b3a2..6d26c2bb97 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Fast_Print.inst.cfg index f3c099724a..e2e8bd82e5 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_High_Quality.inst.cfg index 8d016a2ee4..fc39383f04 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Normal_Quality.inst.cfg index 6ce623b66e..8ec7e6453b 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Draft_Print.inst.cfg index 254afbc109..93665c36de 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Fast_Print.inst.cfg index 39bedce77f..478df58f43 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Normal_Quality.inst.cfg index c87d590650..e936d0f131 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Draft_Print.inst.cfg index 627302e0ab..da639d22c9 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Fast_Print.inst.cfg index cda8d85211..2c2eb99fb0 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_High_Quality.inst.cfg index 3ce76bf6be..20fbcd9430 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Normal_Quality.inst.cfg index d402b663c6..e40949fc7d 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Draft_Print.inst.cfg index 505cd952d2..7ccfe4f786 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Fast_Print.inst.cfg index cc5df0abb9..f12c90bc05 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_High_Quality.inst.cfg index c81dc0f5a7..04957025f1 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Normal_Quality.inst.cfg index 7d29f8fb7c..b0a5fb820f 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Draft_Print.inst.cfg index 991ad30a5a..1a198f3e03 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Fast_Print.inst.cfg index 695ce2c8fb..e6b882d2af 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_High_Quality.inst.cfg index e55867efe5..292ef73a4c 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Normal_Quality.inst.cfg index 41e28c51d5..2b71a01e0d 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Draft_Print.inst.cfg index 5d03e1c980..e27a6894e3 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Fast_Print.inst.cfg index b630ab6232..db1ecee3bc 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_High_Quality.inst.cfg index 1c080c3b47..ca80494f3d 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Normal_Quality.inst.cfg index 79ce686da5..d2d5171fed 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Draft_Print.inst.cfg index c7a4864328..9bf58d4f39 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Fast_Print.inst.cfg index 42048fa297..017bf46bd8 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_High_Quality.inst.cfg index b7ad8bd5c4..314f7fe0bb 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Normal_Quality.inst.cfg index 911fa9a0a8..2bb0d31d76 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Draft_Print.inst.cfg index 68558bcf93..8b8bdfd999 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Fast_Print.inst.cfg index 1145d1900f..0fd70e5973 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Normal_Quality.inst.cfg index c0b094f0a2..0d683a9f87 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Draft_Print.inst.cfg index 280e5c4bfb..df45c190e1 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Fast_Print.inst.cfg index 304c170b55..96b77ebca9 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_High_Quality.inst.cfg index cd5c598d4f..3a2cf495a3 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Normal_Quality.inst.cfg index 2522c0f20f..2d93d1e980 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Draft_Print.inst.cfg index 9b4ab52543..30a1e0c29f 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Fast_Print.inst.cfg index 35cf66a93b..3b57900a46 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Normal_Quality.inst.cfg index 4357d765df..368bfd9e48 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Draft_Print.inst.cfg index c8d64f9dcb..a2b7aa7b87 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Fast_Print.inst.cfg index c7fa604e89..8e82e27210 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_High_Quality.inst.cfg index 187023d3c0..7e4f17cbf1 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Normal_Quality.inst.cfg index 81cb27f060..959d9241c7 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Draft_Print.inst.cfg index 4a55f5d24c..c9083cf2ab 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Fast_Print.inst.cfg index 730e058212..9d7663b6e1 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_High_Quality.inst.cfg index e6921e63d8..ba796da940 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Normal_Quality.inst.cfg index a4eec45e38..96ec8d9e36 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Draft_Print.inst.cfg index 4f085f10a6..bae8b09016 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Fast_Print.inst.cfg index 2580bf952d..f585c2a787 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_High_Quality.inst.cfg index d6f07c37a5..a580a27176 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Normal_Quality.inst.cfg index 6032ff3845..3db4053d2a 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Draft_Print.inst.cfg index f05ecddc25..e86c3b363b 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Fast_Print.inst.cfg index 6103519f1c..0da88626b6 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_High_Quality.inst.cfg index 130afb8c91..d7552ba921 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Normal_Quality.inst.cfg index 9e1bf394d4..638ce2323e 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Draft_Print.inst.cfg index 6124dff257..c0ca84281d 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Fast_Print.inst.cfg index 2791e9f5d5..43b77f6492 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Normal_Quality.inst.cfg index f78b4048fb..04abd0d18b 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Draft_Print.inst.cfg index 911fc6e78e..fb786c7759 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Superdraft_Print.inst.cfg index 0fcdac4a85..cfacaebad0 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Verydraft_Print.inst.cfg index e3346bbd1d..18ce266cd6 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Fast_Print.inst.cfg index d126dddaad..a4a7a5e08c 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast - Experimental definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Superdraft_Print.inst.cfg index dd8b20652a..e4f330099b 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint - Experimental definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Verydraft_Print.inst.cfg index bc107422f1..0685b27b8a 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast - Experimental definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Draft_Print.inst.cfg index 7cb69ba3eb..a57bde98b1 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Superdraft_Print.inst.cfg index 6c323fe602..2f0851d9fb 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Verydraft_Print.inst.cfg index a0380ecc0e..6ccca75b44 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Draft_Print.inst.cfg index 2108839d3f..5d04892443 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Superdraft_Print.inst.cfg index 0702d174a0..5c31e26bd6 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Verydraft_Print.inst.cfg index d02d410ed6..d04482c94c 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Fast_Print.inst.cfg index 378028694b..97afe62e07 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast - Experimental definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Superdraft_Print.inst.cfg index a179d6b7c9..3f296c0300 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint - Experimental definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Verydraft_Print.inst.cfg index b474cb23d9..5eec532f22 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast - Experimental definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Draft_Print.inst.cfg index 7db4e96311..1410290859 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Superdraft_Print.inst.cfg index c59f015b5d..2c65968d77 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Verydraft_Print.inst.cfg index 6fdff8bf8d..9b6e7c2ed9 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Draft_Print.inst.cfg index fee58b367d..c5b01ab1b1 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Superdraft_Print.inst.cfg index aaa810e864..5c83f24395 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Verydraft_Print.inst.cfg index 5b8aa6d2e1..f182d5c6cb 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Draft_Print.inst.cfg index 50dead746b..5b39508f3c 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Superdraft_Print.inst.cfg index 0bdb088f8c..b07a78419a 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Verydraft_Print.inst.cfg index c7cb5902a2..46a61bb79f 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Draft_Print.inst.cfg index e8276d54c5..088414fa34 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Superdraft_Print.inst.cfg index 7da73a200d..d74309c476 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Verydraft_Print.inst.cfg index 60dbbf38e6..deb2b55dbb 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Draft_Print.inst.cfg index 37dceff349..062fcfdd5b 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Superdraft_Print.inst.cfg index eac339baa8..38c341af28 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Verydraft_Print.inst.cfg index 590496df0f..8a38bb9aa3 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Fast_Print.inst.cfg index 50091a6fb4..d9dd09c7b6 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast - Experimental definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Superdraft_Print.inst.cfg index b9c9ef6611..bc6a04ae55 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Verydraft_Print.inst.cfg index be2cc62b08..b384bd7083 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Draft_Print.inst.cfg index 0d0ed8f8b2..28409d4181 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Superdraft_Print.inst.cfg index a163e0c735..33c5d73a59 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Verydraft_Print.inst.cfg index 2137cf740b..8db23c11c2 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Fast_Print.inst.cfg index a313ac56fc..c0af70748a 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast - Experimental definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Superdraft_Print.inst.cfg index f1c1762d2c..bba2dfa92f 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Verydraft_Print.inst.cfg index 399c139412..3987c01ecc 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Draft_Print.inst.cfg index b80af1b75f..5a2c3005c9 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Superdraft_Print.inst.cfg index 970e0971a9..aaa8cbfcd3 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Verydraft_Print.inst.cfg index e51ba3207b..782cadce6b 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Draft_Print.inst.cfg index 73639be0b6..34b078278c 100644 --- a/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Fast_Print.inst.cfg index 5da25be32d..5677c5931c 100644 --- a/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_High_Quality.inst.cfg index 36634af2c8..b9e32cb7c5 100644 --- a/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Normal_Quality.inst.cfg index f76c4c944a..081ee2261e 100644 --- a/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Draft_Print.inst.cfg index e4e3ab772a..0193081db6 100644 --- a/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Superdraft_Print.inst.cfg index 5e78e51014..121b32f903 100644 --- a/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Verydraft_Print.inst.cfg index 5af09aebcc..f0296c9279 100644 --- a/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFCPE_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFCPE_Draft_Print.inst.cfg index feb8891d26..35da5b113e 100644 --- a/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFCPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFCPE_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFPA_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFPA_Draft_Print.inst.cfg index 980ded99e9..67400daf9f 100644 --- a/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFPA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFPA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFCPE_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFCPE_Draft_Print.inst.cfg index 331c5e6d73..0c4f55bddf 100644 --- a/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFCPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFCPE_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFPA_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFPA_Draft_Print.inst.cfg index 0e90d6df78..8a6f9d2ac8 100644 --- a/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFPA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFPA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_global_Draft_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_global_Draft_Quality.inst.cfg index ed5303637b..f0121fa4d7 100644 --- a/resources/quality/ultimaker_s5/um_s5_global_Draft_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_global_Draft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_global_Fast_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_global_Fast_Quality.inst.cfg index ee9c6a8409..b9bb0beff6 100644 --- a/resources/quality/ultimaker_s5/um_s5_global_Fast_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_global_Fast_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_global_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_global_High_Quality.inst.cfg index 96005a48da..aa2420e465 100644 --- a/resources/quality/ultimaker_s5/um_s5_global_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_global_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_global_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_global_Normal_Quality.inst.cfg index 099ba7c584..8bb8f7f282 100644 --- a/resources/quality/ultimaker_s5/um_s5_global_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_global_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_global_Superdraft_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_global_Superdraft_Quality.inst.cfg index 4c0bd40bd1..ec46668b61 100644 --- a/resources/quality/ultimaker_s5/um_s5_global_Superdraft_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_global_Superdraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_global_Verydraft_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_global_Verydraft_Quality.inst.cfg index ec4ec910ff..dd6c7bb4b8 100644 --- a/resources/quality/ultimaker_s5/um_s5_global_Verydraft_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_global_Verydraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/vertex_delta_k8800/k8800_ABS_Extreme_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_ABS_Extreme_Quality.inst.cfg index 70aac3f666..370cc149a2 100644 --- a/resources/quality/vertex_delta_k8800/k8800_ABS_Extreme_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_ABS_Extreme_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extreme definition = vertex_delta_k8800 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extreme weight = 2 diff --git a/resources/quality/vertex_delta_k8800/k8800_ABS_High_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_ABS_High_Quality.inst.cfg index 564b330132..6c96b47169 100644 --- a/resources/quality/vertex_delta_k8800/k8800_ABS_High_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_ABS_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High definition = vertex_delta_k8800 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/vertex_delta_k8800/k8800_ABS_Normal_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_ABS_Normal_Quality.inst.cfg index e2f740a60a..19150baab9 100644 --- a/resources/quality/vertex_delta_k8800/k8800_ABS_Normal_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_ABS_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = vertex_delta_k8800 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/vertex_delta_k8800/k8800_Global_Extreme_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_Global_Extreme_Quality.inst.cfg index 48e80b5512..00d626d72c 100644 --- a/resources/quality/vertex_delta_k8800/k8800_Global_Extreme_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_Global_Extreme_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extreme definition = vertex_delta_k8800 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extreme weight = 2 diff --git a/resources/quality/vertex_delta_k8800/k8800_Global_High_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_Global_High_Quality.inst.cfg index 496144772c..0bd519affe 100644 --- a/resources/quality/vertex_delta_k8800/k8800_Global_High_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_Global_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High definition = vertex_delta_k8800 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/vertex_delta_k8800/k8800_Global_Normal_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_Global_Normal_Quality.inst.cfg index 75ae5f15e6..2b18891998 100644 --- a/resources/quality/vertex_delta_k8800/k8800_Global_Normal_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_Global_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = vertex_delta_k8800 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/vertex_delta_k8800/k8800_PET_Extreme_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PET_Extreme_Quality.inst.cfg index 8309106d9f..8715e573ab 100644 --- a/resources/quality/vertex_delta_k8800/k8800_PET_Extreme_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_PET_Extreme_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extreme definition = vertex_delta_k8800 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extreme weight = 2 diff --git a/resources/quality/vertex_delta_k8800/k8800_PET_High_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PET_High_Quality.inst.cfg index 6efaa3299f..0c94cc5ca4 100644 --- a/resources/quality/vertex_delta_k8800/k8800_PET_High_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_PET_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High definition = vertex_delta_k8800 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/vertex_delta_k8800/k8800_PET_Normal_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PET_Normal_Quality.inst.cfg index bd3b0c35fb..40698f134d 100644 --- a/resources/quality/vertex_delta_k8800/k8800_PET_Normal_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_PET_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = vertex_delta_k8800 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/vertex_delta_k8800/k8800_PLA_Extreme_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PLA_Extreme_Quality.inst.cfg index d10b4c3f8d..f81c82fa9b 100644 --- a/resources/quality/vertex_delta_k8800/k8800_PLA_Extreme_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_PLA_Extreme_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extreme definition = vertex_delta_k8800 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extreme weight = 2 diff --git a/resources/quality/vertex_delta_k8800/k8800_PLA_High_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PLA_High_Quality.inst.cfg index ede77b0dfe..e4b4771b0e 100644 --- a/resources/quality/vertex_delta_k8800/k8800_PLA_High_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_PLA_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High definition = vertex_delta_k8800 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/vertex_delta_k8800/k8800_PLA_Normal_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PLA_Normal_Quality.inst.cfg index a75cff6968..41950da7a1 100644 --- a/resources/quality/vertex_delta_k8800/k8800_PLA_Normal_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_PLA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = vertex_delta_k8800 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/vertex_delta_k8800/k8800_TPU_Extreme_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_TPU_Extreme_Quality.inst.cfg index bee6b3bf11..32077f6cc1 100644 --- a/resources/quality/vertex_delta_k8800/k8800_TPU_Extreme_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_TPU_Extreme_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extreme definition = vertex_delta_k8800 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extreme weight = 2 diff --git a/resources/quality/vertex_delta_k8800/k8800_TPU_High_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_TPU_High_Quality.inst.cfg index 8b0f87cc77..a7ef7d8cc8 100644 --- a/resources/quality/vertex_delta_k8800/k8800_TPU_High_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_TPU_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High definition = vertex_delta_k8800 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/vertex_delta_k8800/k8800_TPU_Normal_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_TPU_Normal_Quality.inst.cfg index bd4e04744f..17a09f366f 100644 --- a/resources/quality/vertex_delta_k8800/k8800_TPU_Normal_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_TPU_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = vertex_delta_k8800 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/zyyx/zyyx_agile_global_fast.inst.cfg b/resources/quality/zyyx/zyyx_agile_global_fast.inst.cfg index 67e350b39e..19cda650d3 100644 --- a/resources/quality/zyyx/zyyx_agile_global_fast.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_global_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = zyyx_agile [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = 1 diff --git a/resources/quality/zyyx/zyyx_agile_global_fine.inst.cfg b/resources/quality/zyyx/zyyx_agile_global_fine.inst.cfg index b8bc7eb628..f2f127f483 100644 --- a/resources/quality/zyyx/zyyx_agile_global_fine.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_global_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = zyyx_agile [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fine weight = 1 diff --git a/resources/quality/zyyx/zyyx_agile_global_normal.inst.cfg b/resources/quality/zyyx/zyyx_agile_global_normal.inst.cfg index 3f934b0114..d9cbdc691e 100644 --- a/resources/quality/zyyx/zyyx_agile_global_normal.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_global_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = zyyx_agile [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/zyyx/zyyx_agile_pro_flex_fast.inst.cfg b/resources/quality/zyyx/zyyx_agile_pro_flex_fast.inst.cfg index 188bdd25e5..d6f715c09f 100644 --- a/resources/quality/zyyx/zyyx_agile_pro_flex_fast.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_pro_flex_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = zyyx_agile [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = 1 diff --git a/resources/quality/zyyx/zyyx_agile_pro_flex_fine.inst.cfg b/resources/quality/zyyx/zyyx_agile_pro_flex_fine.inst.cfg index d69bc930e9..a0aa1996ac 100644 --- a/resources/quality/zyyx/zyyx_agile_pro_flex_fine.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_pro_flex_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = zyyx_agile [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fine weight = 1 diff --git a/resources/quality/zyyx/zyyx_agile_pro_flex_normal.inst.cfg b/resources/quality/zyyx/zyyx_agile_pro_flex_normal.inst.cfg index d717f11528..a70b1dd19a 100644 --- a/resources/quality/zyyx/zyyx_agile_pro_flex_normal.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_pro_flex_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = zyyx_agile [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/zyyx/zyyx_agile_pro_pla_fast.inst.cfg b/resources/quality/zyyx/zyyx_agile_pro_pla_fast.inst.cfg index 7ae4be06b0..5b32c3f07b 100644 --- a/resources/quality/zyyx/zyyx_agile_pro_pla_fast.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_pro_pla_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = zyyx_agile [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = 1 diff --git a/resources/quality/zyyx/zyyx_agile_pro_pla_fine.inst.cfg b/resources/quality/zyyx/zyyx_agile_pro_pla_fine.inst.cfg index 44b722ac32..a3849bf5e2 100644 --- a/resources/quality/zyyx/zyyx_agile_pro_pla_fine.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_pro_pla_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = zyyx_agile [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fine weight = 1 diff --git a/resources/quality/zyyx/zyyx_agile_pro_pla_normal.inst.cfg b/resources/quality/zyyx/zyyx_agile_pro_pla_normal.inst.cfg index 01424a9422..d126308660 100644 --- a/resources/quality/zyyx/zyyx_agile_pro_pla_normal.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_pro_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = zyyx_agile [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/variants/cartesio_0.25.inst.cfg b/resources/variants/cartesio_0.25.inst.cfg index b3aae8a393..53048622f2 100644 --- a/resources/variants/cartesio_0.25.inst.cfg +++ b/resources/variants/cartesio_0.25.inst.cfg @@ -5,7 +5,7 @@ definition = cartesio [metadata] author = Cartesio -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/cartesio_0.4.inst.cfg b/resources/variants/cartesio_0.4.inst.cfg index 5cea5823c4..3ad6b3f3d9 100644 --- a/resources/variants/cartesio_0.4.inst.cfg +++ b/resources/variants/cartesio_0.4.inst.cfg @@ -5,7 +5,7 @@ definition = cartesio [metadata] author = Cartesio -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/cartesio_0.8.inst.cfg b/resources/variants/cartesio_0.8.inst.cfg index b4009cf9ed..f19c4d58d4 100644 --- a/resources/variants/cartesio_0.8.inst.cfg +++ b/resources/variants/cartesio_0.8.inst.cfg @@ -5,7 +5,7 @@ definition = cartesio [metadata] author = Cartesio -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/fabtotum_hyb35.inst.cfg b/resources/variants/fabtotum_hyb35.inst.cfg index d3f0077792..5ed9eca26a 100644 --- a/resources/variants/fabtotum_hyb35.inst.cfg +++ b/resources/variants/fabtotum_hyb35.inst.cfg @@ -5,7 +5,7 @@ definition = fabtotum [metadata] author = FABtotum -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/fabtotum_lite04.inst.cfg b/resources/variants/fabtotum_lite04.inst.cfg index 226c136564..7b52bf5c29 100644 --- a/resources/variants/fabtotum_lite04.inst.cfg +++ b/resources/variants/fabtotum_lite04.inst.cfg @@ -5,7 +5,7 @@ definition = fabtotum [metadata] author = FABtotum -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/fabtotum_lite06.inst.cfg b/resources/variants/fabtotum_lite06.inst.cfg index 62e3014b60..f518f60ce9 100644 --- a/resources/variants/fabtotum_lite06.inst.cfg +++ b/resources/variants/fabtotum_lite06.inst.cfg @@ -5,7 +5,7 @@ definition = fabtotum [metadata] author = FABtotum -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/fabtotum_pro02.inst.cfg b/resources/variants/fabtotum_pro02.inst.cfg index 3e4661ee2c..897bd5aea9 100644 --- a/resources/variants/fabtotum_pro02.inst.cfg +++ b/resources/variants/fabtotum_pro02.inst.cfg @@ -5,7 +5,7 @@ definition = fabtotum [metadata] author = FABtotum -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/fabtotum_pro04.inst.cfg b/resources/variants/fabtotum_pro04.inst.cfg index 3fe140f8be..d27be2f3b8 100644 --- a/resources/variants/fabtotum_pro04.inst.cfg +++ b/resources/variants/fabtotum_pro04.inst.cfg @@ -5,7 +5,7 @@ definition = fabtotum [metadata] author = FABtotum -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/fabtotum_pro06.inst.cfg b/resources/variants/fabtotum_pro06.inst.cfg index fcb5c71ef0..25b9d7c710 100644 --- a/resources/variants/fabtotum_pro06.inst.cfg +++ b/resources/variants/fabtotum_pro06.inst.cfg @@ -5,7 +5,7 @@ definition = fabtotum [metadata] author = FABtotum -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/fabtotum_pro08.inst.cfg b/resources/variants/fabtotum_pro08.inst.cfg index bef04734eb..627e26e2a2 100644 --- a/resources/variants/fabtotum_pro08.inst.cfg +++ b/resources/variants/fabtotum_pro08.inst.cfg @@ -5,7 +5,7 @@ definition = fabtotum [metadata] author = FABtotum -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/felixtec4_0.25.inst.cfg b/resources/variants/felixtec4_0.25.inst.cfg index 7d8bca94b0..3dda15171b 100644 --- a/resources/variants/felixtec4_0.25.inst.cfg +++ b/resources/variants/felixtec4_0.25.inst.cfg @@ -6,7 +6,7 @@ definition = felixtec4dual [metadata] author = kerog777 type = variant -setting_version = 5 +setting_version = 6 hardware_type = nozzle [values] diff --git a/resources/variants/felixtec4_0.35.inst.cfg b/resources/variants/felixtec4_0.35.inst.cfg index f061aa1cbc..db79c3bad4 100644 --- a/resources/variants/felixtec4_0.35.inst.cfg +++ b/resources/variants/felixtec4_0.35.inst.cfg @@ -6,7 +6,7 @@ definition = felixtec4dual [metadata] author = kerog777 type = variant -setting_version = 5 +setting_version = 6 hardware_type = nozzle [values] diff --git a/resources/variants/felixtec4_0.50.inst.cfg b/resources/variants/felixtec4_0.50.inst.cfg index 3c68c42dae..6d52881ee5 100644 --- a/resources/variants/felixtec4_0.50.inst.cfg +++ b/resources/variants/felixtec4_0.50.inst.cfg @@ -7,7 +7,7 @@ definition = felixtec4dual author = kerog777 type = variant hardware_type = nozzle -setting_version = 5 +setting_version = 6 [values] machine_nozzle_size = 0.5 diff --git a/resources/variants/felixtec4_0.70.inst.cfg b/resources/variants/felixtec4_0.70.inst.cfg index 3a52644714..4edeebbc84 100644 --- a/resources/variants/felixtec4_0.70.inst.cfg +++ b/resources/variants/felixtec4_0.70.inst.cfg @@ -7,7 +7,7 @@ definition = felixtec4dual author = kerog777 type = variant hardware_type = nozzle -setting_version = 5 +setting_version = 6 [values] machine_nozzle_size = 0.70 diff --git a/resources/variants/gmax15plus_025_e3d.inst.cfg b/resources/variants/gmax15plus_025_e3d.inst.cfg index 8a6b37067d..a085be0526 100644 --- a/resources/variants/gmax15plus_025_e3d.inst.cfg +++ b/resources/variants/gmax15plus_025_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus [metadata] author = gcreate -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_04_e3d.inst.cfg b/resources/variants/gmax15plus_04_e3d.inst.cfg index 48fe7ada16..05473dafd2 100644 --- a/resources/variants/gmax15plus_04_e3d.inst.cfg +++ b/resources/variants/gmax15plus_04_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus [metadata] author = gcreate -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_05_e3d.inst.cfg b/resources/variants/gmax15plus_05_e3d.inst.cfg index 0bb9517da8..f3324382ba 100644 --- a/resources/variants/gmax15plus_05_e3d.inst.cfg +++ b/resources/variants/gmax15plus_05_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus [metadata] author = gcreate -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_05_jhead.inst.cfg b/resources/variants/gmax15plus_05_jhead.inst.cfg index 6d0b084969..d480b47367 100644 --- a/resources/variants/gmax15plus_05_jhead.inst.cfg +++ b/resources/variants/gmax15plus_05_jhead.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus [metadata] author = gcreate -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_06_e3d.inst.cfg b/resources/variants/gmax15plus_06_e3d.inst.cfg index 3a372b20c9..732870f044 100644 --- a/resources/variants/gmax15plus_06_e3d.inst.cfg +++ b/resources/variants/gmax15plus_06_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus [metadata] author = gcreate -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_08_e3d.inst.cfg b/resources/variants/gmax15plus_08_e3d.inst.cfg index 39eeef748e..0c4137a018 100644 --- a/resources/variants/gmax15plus_08_e3d.inst.cfg +++ b/resources/variants/gmax15plus_08_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus [metadata] author = gcreate -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_10_jhead.inst.cfg b/resources/variants/gmax15plus_10_jhead.inst.cfg index 37d2546d2a..8ae93fc93c 100644 --- a/resources/variants/gmax15plus_10_jhead.inst.cfg +++ b/resources/variants/gmax15plus_10_jhead.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus [metadata] author = gcreate -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_12_e3d.inst.cfg b/resources/variants/gmax15plus_12_e3d.inst.cfg index 57052dd0f8..016f48c1a3 100644 --- a/resources/variants/gmax15plus_12_e3d.inst.cfg +++ b/resources/variants/gmax15plus_12_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus [metadata] author = gcreate -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_dual_025_e3d.inst.cfg b/resources/variants/gmax15plus_dual_025_e3d.inst.cfg index 750a5381b3..185166d3b5 100644 --- a/resources/variants/gmax15plus_dual_025_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_025_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus_dual [metadata] author = gcreate -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_dual_04_e3d.inst.cfg b/resources/variants/gmax15plus_dual_04_e3d.inst.cfg index 809227a62c..1c534f13e0 100644 --- a/resources/variants/gmax15plus_dual_04_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_04_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus_dual [metadata] author = gcreate -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_dual_05_e3d.inst.cfg b/resources/variants/gmax15plus_dual_05_e3d.inst.cfg index 05d9a88d54..f1d67509a9 100644 --- a/resources/variants/gmax15plus_dual_05_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_05_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus_dual [metadata] author = gcreate -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_dual_05_jhead.inst.cfg b/resources/variants/gmax15plus_dual_05_jhead.inst.cfg index 54a237e848..bc72c4ae20 100644 --- a/resources/variants/gmax15plus_dual_05_jhead.inst.cfg +++ b/resources/variants/gmax15plus_dual_05_jhead.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus_dual [metadata] author = gcreate -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_dual_06_e3d.inst.cfg b/resources/variants/gmax15plus_dual_06_e3d.inst.cfg index 39c41be968..545cfcb238 100644 --- a/resources/variants/gmax15plus_dual_06_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_06_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus_dual [metadata] author = gcreate -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_dual_08_e3d.inst.cfg b/resources/variants/gmax15plus_dual_08_e3d.inst.cfg index 1f2d7b9790..1923aac7f7 100644 --- a/resources/variants/gmax15plus_dual_08_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_08_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus_dual [metadata] author = gcreate -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_dual_10_jhead.inst.cfg b/resources/variants/gmax15plus_dual_10_jhead.inst.cfg index ee0c8fa948..de0776ad9b 100644 --- a/resources/variants/gmax15plus_dual_10_jhead.inst.cfg +++ b/resources/variants/gmax15plus_dual_10_jhead.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus_dual [metadata] author = gcreate -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/imade3d_jellybox_0.4.inst.cfg b/resources/variants/imade3d_jellybox_0.4.inst.cfg index 2bd0f578cf..1623e6755c 100644 --- a/resources/variants/imade3d_jellybox_0.4.inst.cfg +++ b/resources/variants/imade3d_jellybox_0.4.inst.cfg @@ -5,7 +5,7 @@ definition = imade3d_jellybox [metadata] author = IMADE3D -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg b/resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg index 6a93cdf13d..2f1cb002b4 100644 --- a/resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg +++ b/resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg @@ -5,7 +5,7 @@ definition = imade3d_jellybox [metadata] author = IMADE3D -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/tizyx_k25_0.2.inst.cfg b/resources/variants/tizyx_k25_0.2.inst.cfg index cd9f1bcbd1..c616579911 100644 --- a/resources/variants/tizyx_k25_0.2.inst.cfg +++ b/resources/variants/tizyx_k25_0.2.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = tizyx_k25 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/tizyx_k25_0.3.inst.cfg b/resources/variants/tizyx_k25_0.3.inst.cfg index 8b34d23bf6..180d831cca 100644 --- a/resources/variants/tizyx_k25_0.3.inst.cfg +++ b/resources/variants/tizyx_k25_0.3.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = tizyx_k25 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/tizyx_k25_0.4.inst.cfg b/resources/variants/tizyx_k25_0.4.inst.cfg index c147eb0ad0..07ef3ca8ed 100644 --- a/resources/variants/tizyx_k25_0.4.inst.cfg +++ b/resources/variants/tizyx_k25_0.4.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = tizyx_k25 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/tizyx_k25_0.5.inst.cfg b/resources/variants/tizyx_k25_0.5.inst.cfg index 14102fb2c7..a09a207e7a 100644 --- a/resources/variants/tizyx_k25_0.5.inst.cfg +++ b/resources/variants/tizyx_k25_0.5.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = tizyx_k25 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/tizyx_k25_0.6.inst.cfg b/resources/variants/tizyx_k25_0.6.inst.cfg index 00f69f71f4..751cf8e794 100644 --- a/resources/variants/tizyx_k25_0.6.inst.cfg +++ b/resources/variants/tizyx_k25_0.6.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = tizyx_k25 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/tizyx_k25_0.8.inst.cfg b/resources/variants/tizyx_k25_0.8.inst.cfg index c80f5e70d2..cca0986ed5 100644 --- a/resources/variants/tizyx_k25_0.8.inst.cfg +++ b/resources/variants/tizyx_k25_0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = tizyx_k25 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/tizyx_k25_1.0.inst.cfg b/resources/variants/tizyx_k25_1.0.inst.cfg index ce8593b1e8..d99948c26c 100644 --- a/resources/variants/tizyx_k25_1.0.inst.cfg +++ b/resources/variants/tizyx_k25_1.0.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = tizyx_k25 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_0.25.inst.cfg b/resources/variants/ultimaker2_0.25.inst.cfg index a58b4d9a56..004cdaf671 100644 --- a/resources/variants/ultimaker2_0.25.inst.cfg +++ b/resources/variants/ultimaker2_0.25.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_0.4.inst.cfg b/resources/variants/ultimaker2_0.4.inst.cfg index 46845d974e..607d0c4f29 100644 --- a/resources/variants/ultimaker2_0.4.inst.cfg +++ b/resources/variants/ultimaker2_0.4.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_0.6.inst.cfg b/resources/variants/ultimaker2_0.6.inst.cfg index f9ab1f1358..1ddc07817b 100644 --- a/resources/variants/ultimaker2_0.6.inst.cfg +++ b/resources/variants/ultimaker2_0.6.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_0.8.inst.cfg b/resources/variants/ultimaker2_0.8.inst.cfg index 3d9c273783..938b472c2c 100644 --- a/resources/variants/ultimaker2_0.8.inst.cfg +++ b/resources/variants/ultimaker2_0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_extended_0.25.inst.cfg b/resources/variants/ultimaker2_extended_0.25.inst.cfg index f5471fc505..45546c55aa 100644 --- a/resources/variants/ultimaker2_extended_0.25.inst.cfg +++ b/resources/variants/ultimaker2_extended_0.25.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_extended [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_extended_0.4.inst.cfg b/resources/variants/ultimaker2_extended_0.4.inst.cfg index a7d03f2408..fb3d8c1116 100644 --- a/resources/variants/ultimaker2_extended_0.4.inst.cfg +++ b/resources/variants/ultimaker2_extended_0.4.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_extended [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_extended_0.6.inst.cfg b/resources/variants/ultimaker2_extended_0.6.inst.cfg index 25c180e07e..50f7dc04c6 100644 --- a/resources/variants/ultimaker2_extended_0.6.inst.cfg +++ b/resources/variants/ultimaker2_extended_0.6.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_extended [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_extended_0.8.inst.cfg b/resources/variants/ultimaker2_extended_0.8.inst.cfg index c33f483da3..178737dbd5 100644 --- a/resources/variants/ultimaker2_extended_0.8.inst.cfg +++ b/resources/variants/ultimaker2_extended_0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_extended [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg index c65940251c..7e67824d16 100644 --- a/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_extended_plus [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg index 7493f2af44..1150c6127c 100644 --- a/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_extended_plus [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg index c4a3ab6340..fbdef77918 100644 --- a/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_extended_plus [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg index e77ec2a5c2..106537e0a7 100644 --- a/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_extended_plus [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_plus_0.25.inst.cfg b/resources/variants/ultimaker2_plus_0.25.inst.cfg index 7fd7f3980f..c07b80c246 100644 --- a/resources/variants/ultimaker2_plus_0.25.inst.cfg +++ b/resources/variants/ultimaker2_plus_0.25.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_plus_0.4.inst.cfg b/resources/variants/ultimaker2_plus_0.4.inst.cfg index 3b54e0cdef..623fffbeb9 100644 --- a/resources/variants/ultimaker2_plus_0.4.inst.cfg +++ b/resources/variants/ultimaker2_plus_0.4.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_plus_0.6.inst.cfg b/resources/variants/ultimaker2_plus_0.6.inst.cfg index d8fea055e5..b57fa81dfe 100644 --- a/resources/variants/ultimaker2_plus_0.6.inst.cfg +++ b/resources/variants/ultimaker2_plus_0.6.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_plus_0.8.inst.cfg b/resources/variants/ultimaker2_plus_0.8.inst.cfg index 3ae902ac2f..702ec2ef31 100644 --- a/resources/variants/ultimaker2_plus_0.8.inst.cfg +++ b/resources/variants/ultimaker2_plus_0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker3_aa0.25.inst.cfg b/resources/variants/ultimaker3_aa0.25.inst.cfg index b46fdf5dfb..fc8cc3b090 100644 --- a/resources/variants/ultimaker3_aa0.25.inst.cfg +++ b/resources/variants/ultimaker3_aa0.25.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker3_aa0.8.inst.cfg b/resources/variants/ultimaker3_aa0.8.inst.cfg index 56740233dd..308bed6fcb 100644 --- a/resources/variants/ultimaker3_aa0.8.inst.cfg +++ b/resources/variants/ultimaker3_aa0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker3_aa04.inst.cfg b/resources/variants/ultimaker3_aa04.inst.cfg index ce91e89d26..25230cd30b 100644 --- a/resources/variants/ultimaker3_aa04.inst.cfg +++ b/resources/variants/ultimaker3_aa04.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker3_bb0.8.inst.cfg b/resources/variants/ultimaker3_bb0.8.inst.cfg index ace0bf3a94..5ccf2816ff 100644 --- a/resources/variants/ultimaker3_bb0.8.inst.cfg +++ b/resources/variants/ultimaker3_bb0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker3_bb04.inst.cfg b/resources/variants/ultimaker3_bb04.inst.cfg index d571cabc9b..d919e5aab7 100644 --- a/resources/variants/ultimaker3_bb04.inst.cfg +++ b/resources/variants/ultimaker3_bb04.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker3_extended_aa0.25.inst.cfg b/resources/variants/ultimaker3_extended_aa0.25.inst.cfg index 714b017653..ce0f20fa7e 100644 --- a/resources/variants/ultimaker3_extended_aa0.25.inst.cfg +++ b/resources/variants/ultimaker3_extended_aa0.25.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker3_extended [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker3_extended_aa0.8.inst.cfg b/resources/variants/ultimaker3_extended_aa0.8.inst.cfg index f72c96b551..f209508875 100644 --- a/resources/variants/ultimaker3_extended_aa0.8.inst.cfg +++ b/resources/variants/ultimaker3_extended_aa0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker3_extended [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker3_extended_aa04.inst.cfg b/resources/variants/ultimaker3_extended_aa04.inst.cfg index f354784fc6..714d19051f 100644 --- a/resources/variants/ultimaker3_extended_aa04.inst.cfg +++ b/resources/variants/ultimaker3_extended_aa04.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker3_extended [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker3_extended_bb0.8.inst.cfg b/resources/variants/ultimaker3_extended_bb0.8.inst.cfg index fe760c93b8..528c7f70ec 100644 --- a/resources/variants/ultimaker3_extended_bb0.8.inst.cfg +++ b/resources/variants/ultimaker3_extended_bb0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker3_extended [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker3_extended_bb04.inst.cfg b/resources/variants/ultimaker3_extended_bb04.inst.cfg index 742dc9896e..5ee562ee38 100644 --- a/resources/variants/ultimaker3_extended_bb04.inst.cfg +++ b/resources/variants/ultimaker3_extended_bb04.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker3_extended [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker_s5_aa0.25.inst.cfg b/resources/variants/ultimaker_s5_aa0.25.inst.cfg index 643513faad..ebdb096b6f 100644 --- a/resources/variants/ultimaker_s5_aa0.25.inst.cfg +++ b/resources/variants/ultimaker_s5_aa0.25.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker_s5_aa0.8.inst.cfg b/resources/variants/ultimaker_s5_aa0.8.inst.cfg index eca8c400d0..d8ff1c020e 100644 --- a/resources/variants/ultimaker_s5_aa0.8.inst.cfg +++ b/resources/variants/ultimaker_s5_aa0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker_s5_aa04.inst.cfg b/resources/variants/ultimaker_s5_aa04.inst.cfg index b5b694d0c1..ac377e3e78 100644 --- a/resources/variants/ultimaker_s5_aa04.inst.cfg +++ b/resources/variants/ultimaker_s5_aa04.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker_s5_aluminum.inst.cfg b/resources/variants/ultimaker_s5_aluminum.inst.cfg index 1018b7e5ab..ca457bd7e7 100644 --- a/resources/variants/ultimaker_s5_aluminum.inst.cfg +++ b/resources/variants/ultimaker_s5_aluminum.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = buildplate diff --git a/resources/variants/ultimaker_s5_bb0.8.inst.cfg b/resources/variants/ultimaker_s5_bb0.8.inst.cfg index c1c5c1a10b..bb7f2d1420 100644 --- a/resources/variants/ultimaker_s5_bb0.8.inst.cfg +++ b/resources/variants/ultimaker_s5_bb0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker_s5_bb04.inst.cfg b/resources/variants/ultimaker_s5_bb04.inst.cfg index b5ff8d51f6..cda1036507 100644 --- a/resources/variants/ultimaker_s5_bb04.inst.cfg +++ b/resources/variants/ultimaker_s5_bb04.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker_s5_cc06.inst.cfg b/resources/variants/ultimaker_s5_cc06.inst.cfg index 7adf7ab7a0..afbeb44462 100644 --- a/resources/variants/ultimaker_s5_cc06.inst.cfg +++ b/resources/variants/ultimaker_s5_cc06.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker_s5_glass.inst.cfg b/resources/variants/ultimaker_s5_glass.inst.cfg index d74eb3c6c9..e7431c933f 100644 --- a/resources/variants/ultimaker_s5_glass.inst.cfg +++ b/resources/variants/ultimaker_s5_glass.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = buildplate From 265a1b3fa0bf472da347328a46996df7f11a2527 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 27 Dec 2018 16:50:05 +0100 Subject: [PATCH 1116/1292] Add version upgrade plug-in for 4.0 to 4.1 This currently only updates the stack files, but all files have to be upgraded because of that stupid setting_version. Contributes to issue CURA-5848. --- .../VersionUpgrade34to35.py | 4 +- .../VersionUpgrade34to35/plugin.json | 2 +- .../VersionUpgrade40to41.py | 86 +++++++++++++++++++ .../VersionUpgrade40to41/__init__.py | 39 +++++++++ .../VersionUpgrade40to41/plugin.json | 8 ++ 5 files changed, 136 insertions(+), 3 deletions(-) create mode 100644 plugins/VersionUpgrade/VersionUpgrade40to41/VersionUpgrade40to41.py create mode 100644 plugins/VersionUpgrade/VersionUpgrade40to41/__init__.py create mode 100644 plugins/VersionUpgrade/VersionUpgrade40to41/plugin.json diff --git a/plugins/VersionUpgrade/VersionUpgrade34to35/VersionUpgrade34to35.py b/plugins/VersionUpgrade/VersionUpgrade34to35/VersionUpgrade34to35.py index d930b6e217..8e45d7cf73 100644 --- a/plugins/VersionUpgrade/VersionUpgrade34to35/VersionUpgrade34to35.py +++ b/plugins/VersionUpgrade/VersionUpgrade34to35/VersionUpgrade34to35.py @@ -63,9 +63,9 @@ _RENAMED_MATERIAL_PROFILES = { ## Upgrades configurations from the state they were in at version 3.4 to the # state they should be in at version 3.5. class VersionUpgrade34to35(VersionUpgrade): - ## Gets the version number from a CFG file in Uranium's 3.3 format. + ## Gets the version number from a CFG file in Uranium's 3.4 format. # - # Since the format may change, this is implemented for the 3.3 format only + # Since the format may change, this is implemented for the 3.4 format only # and needs to be included in the version upgrade system rather than # globally in Uranium. # diff --git a/plugins/VersionUpgrade/VersionUpgrade34to35/plugin.json b/plugins/VersionUpgrade/VersionUpgrade34to35/plugin.json index 02635ec606..71b13ee5a9 100644 --- a/plugins/VersionUpgrade/VersionUpgrade34to35/plugin.json +++ b/plugins/VersionUpgrade/VersionUpgrade34to35/plugin.json @@ -1,4 +1,4 @@ - { +{ "name": "Version Upgrade 3.4 to 3.5", "author": "Ultimaker B.V.", "version": "1.0.1", diff --git a/plugins/VersionUpgrade/VersionUpgrade40to41/VersionUpgrade40to41.py b/plugins/VersionUpgrade/VersionUpgrade40to41/VersionUpgrade40to41.py new file mode 100644 index 0000000000..ac54b7c8e0 --- /dev/null +++ b/plugins/VersionUpgrade/VersionUpgrade40to41/VersionUpgrade40to41.py @@ -0,0 +1,86 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +import configparser +import io +from typing import Dict, List, Tuple + +from UM.VersionUpgrade import VersionUpgrade + +_renamed_quality_profiles = { + "gmax15plus_pla_dual_normal": "gmax15plus_global_dual_normal", + "gmax15plus_pla_dual_thick": "gmax15plus_global_dual_thick", + "gmax15plus_pla_dual_thin": "gmax15plus_global_dual_thin", + "gmax15plus_pla_dual_very_thick": "gmax15plus_global_dual_very_thick", + "gmax15plus_pla_normal": "gmax15plus_global_normal", + "gmax15plus_pla_thick": "gmax15plus_global_thick", + "gmax15plus_pla_thin": "gmax15plus_global_thin", + "gmax15plus_pla_very_thick": "gmax15plus_global_very_thick" +} # type: Dict[str, str] + +## Upgrades configurations from the state they were in at version 4.0 to the +# state they should be in at version 4.1. +class VersionUpgrade40to41(VersionUpgrade): + ## Gets the version number from a CFG file in Uranium's 4.0 format. + # + # Since the format may change, this is implemented for the 4.0 format only + # and needs to be included in the version upgrade system rather than + # globally in Uranium. + # + # \param serialised The serialised form of a CFG file. + # \return The version number stored in the CFG file. + # \raises ValueError The format of the version number in the file is + # incorrect. + # \raises KeyError The format of the file is incorrect. + def getCfgVersion(self, serialised: str) -> int: + parser = configparser.ConfigParser(interpolation = None) + parser.read_string(serialised) + format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised. + setting_version = int(parser.get("metadata", "setting_version", fallback = "0")) + return format_version * 1000000 + setting_version + + ## Upgrades instance containers to have the new version + # number. + def upgradeInstanceContainer(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]: + parser = configparser.ConfigParser(interpolation = None) + parser.read_string(serialized) + + # Update version number. + parser["general"]["version"] = "4" + parser["metadata"]["setting_version"] = "6" + + result = io.StringIO() + parser.write(result) + return [filename], [result.getvalue()] + + ## Upgrades Preferences to have the new version number. + def upgradePreferences(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]: + parser = configparser.ConfigParser(interpolation = None) + parser.read_string(serialized) + + # Update version number. + parser["general"]["version"] = "6" + if "metadata" not in parser: + parser["metadata"] = {} + parser["metadata"]["setting_version"] = "6" + + result = io.StringIO() + parser.write(result) + return [filename], [result.getvalue()] + + ## Upgrades stacks to have the new version number. + def upgradeStack(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]: + parser = configparser.ConfigParser(interpolation = None) + parser.read_string(serialized) + + # Update version number. + parser["general"]["version"] = "4" + parser["metadata"]["setting_version"] = "6" + + #Update the name of the quality profile. + if parser["containers"]["4"] in _renamed_quality_profiles: + parser["containers"]["4"] = _renamed_quality_profiles[parser["containers"]["4"]] + + result = io.StringIO() + parser.write(result) + return [filename], [result.getvalue()] \ No newline at end of file diff --git a/plugins/VersionUpgrade/VersionUpgrade40to41/__init__.py b/plugins/VersionUpgrade/VersionUpgrade40to41/__init__.py new file mode 100644 index 0000000000..757a7a51c0 --- /dev/null +++ b/plugins/VersionUpgrade/VersionUpgrade40to41/__init__.py @@ -0,0 +1,39 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from typing import Any, Dict, TYPE_CHECKING + +from . import VersionUpgrade40to41 + +if TYPE_CHECKING: + from UM.Application import Application + +upgrade = VersionUpgrade40to41.VersionUpgrade40to41() + +def getMetaData() -> Dict[str, Any]: + return { + "version_upgrade": { + # From To Upgrade function + ("machine_stack", 4000005): ("machine_stack", 4000006, upgrade.upgradeStack), + ("extruder_train", 4000005): ("extruder_train", 4000006, upgrade.upgradeStack), + ("preferences", 6000005): ("preferences", 6000006, upgrade.upgradePreferences), + ("definition_changes", 4000005): ("definition_changes", 4000006, upgrade.upgradeInstanceContainer), + ("quality_changes", 4000005): ("quality_changes", 4000006, upgrade.upgradeInstanceContainer), + ("quality", 4000005): ("quality", 4000006, upgrade.upgradeInstanceContainer), + ("user", 4000005): ("user", 4000006, upgrade.upgradeInstanceContainer), + }, + "sources": { + "machine_stack": { + "get_version": upgrade.getCfgVersion, + "location": {"./machine_instances"} + }, + "extruder_train": { + "get_version": upgrade.getCfgVersion, + "location": {"./extruders"} + } + } + } + + +def register(app: "Application") -> Dict[str, Any]: + return { "version_upgrade": upgrade } diff --git a/plugins/VersionUpgrade/VersionUpgrade40to41/plugin.json b/plugins/VersionUpgrade/VersionUpgrade40to41/plugin.json new file mode 100644 index 0000000000..b1c6d75669 --- /dev/null +++ b/plugins/VersionUpgrade/VersionUpgrade40to41/plugin.json @@ -0,0 +1,8 @@ +{ + "name": "Version Upgrade 4.0 to 4.1", + "author": "Ultimaker B.V.", + "version": "1.0.1", + "description": "Upgrades configurations from Cura 4.0 to Cura 4.1.", + "api": "6.0", + "i18n-catalog": "cura" +} From 52d97dfbd21bfc0d190955734163a702cefdfe86 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 31 Dec 2018 09:32:16 +0100 Subject: [PATCH 1117/1292] Change back the behavior of the output device selector to the old way Although the new way was discussed with our UXers, we got a number of reports that it was confusing. I also accidentally started a print while using it --- resources/qml/ActionPanel/OutputDevicesActionButton.qml | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/qml/ActionPanel/OutputDevicesActionButton.qml b/resources/qml/ActionPanel/OutputDevicesActionButton.qml index fc0f9b8303..3bfaab0fc1 100644 --- a/resources/qml/ActionPanel/OutputDevicesActionButton.qml +++ b/resources/qml/ActionPanel/OutputDevicesActionButton.qml @@ -93,7 +93,6 @@ Item onClicked: { UM.OutputDeviceManager.setActiveDevice(model.id) - widget.requestWriteToDevice() popup.close() } } From a16e40650754f45f178cdc33f0ef9076863cd55b Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 31 Dec 2018 11:01:30 +0100 Subject: [PATCH 1118/1292] Properly display the full type + brand of unknown material CURA-6033 --- .../src/ClusterUM3OutputDevice.py | 3 ++- .../ConfigurationMenu/ConfigurationItem.qml | 16 ++++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index bebccc54e3..5e8aaa9fa9 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -620,8 +620,9 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): if material_group_list is None: material_name = i18n_catalog.i18nc("@label:material", "Empty") if len(material_data.get("guid", "")) == 0 \ else i18n_catalog.i18nc("@label:material", "Unknown") + return MaterialOutputModel(guid = material_data.get("guid", ""), - type = material_data.get("type", ""), + type = material_data.get("material", ""), color = material_data.get("color", ""), brand = material_data.get("brand", ""), name = material_data.get("name", material_name) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 75a1b21186..51ba77d012 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -105,10 +105,22 @@ Button for (var index in extruderConfigurations) { var name = extruderConfigurations[index].material ? extruderConfigurations[index].material.name : "" - if (name == "" || name == "Unknown") { - unknownMaterials.push(extruderConfigurations[index].material.brand ? extruderConfigurations[index].material.brand : "Unknown Brand") + var materialType = extruderConfigurations[index].material.type + if (extruderConfigurations[index].material.type == "") + { + materialType = "Unknown" + } + + var brand = extruderConfigurations[index].material.brand + if (brand == "") + { + brand = "Unknown" + } + + name = materialType + " (" + brand + ")" + unknownMaterials.push(name) } } From c333899d18dd7ecb548ca1066e7eb22127c66dff Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 31 Dec 2018 11:09:10 +0100 Subject: [PATCH 1119/1292] Fix reference to renamed file --- plugins/SimulationView/SimulationView.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/SimulationView/SimulationView.py b/plugins/SimulationView/SimulationView.py index ae01b7cdb0..3b2db2efac 100644 --- a/plugins/SimulationView/SimulationView.py +++ b/plugins/SimulationView/SimulationView.py @@ -50,7 +50,7 @@ catalog = i18nCatalog("cura") ## View used to display g-code paths. class SimulationView(CuraView): - # Must match SimulationView.qml + # Must match SimulationViewMenuComponent.qml LAYER_VIEW_TYPE_MATERIAL_TYPE = 0 LAYER_VIEW_TYPE_LINE_TYPE = 1 LAYER_VIEW_TYPE_FEEDRATE = 2 From fd9b29fee2558e9e387d2cdb9f74fed5c69bbf53 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 31 Dec 2018 11:09:39 +0100 Subject: [PATCH 1120/1292] Rename printersModel to GlobalStacksModel This is a better description for the model anyway. CURA-6011 --- cura/CuraApplication.py | 4 ++-- cura/{PrintersModel.py => GlobalStacksModel.py} | 3 ++- resources/qml/Menus/LocalPrinterMenu.qml | 2 +- resources/qml/Menus/NetworkPrinterMenu.qml | 2 +- resources/qml/PrinterSelector/MachineSelectorList.qml | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) rename cura/{PrintersModel.py => GlobalStacksModel.py} (97%) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 905c367cd1..0edf6c1899 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -51,7 +51,7 @@ from cura.Arranging.ArrangeObjectsJob import ArrangeObjectsJob from cura.Arranging.ArrangeObjectsAllBuildPlatesJob import ArrangeObjectsAllBuildPlatesJob from cura.Arranging.ShapeArray import ShapeArray from cura.MultiplyObjectsJob import MultiplyObjectsJob -from cura.PrintersModel import PrintersModel +from cura.GlobalStacksModel import GlobalStacksModel from cura.Scene.ConvexHullDecorator import ConvexHullDecorator from cura.Operations.SetParentOperation import SetParentOperation from cura.Scene.SliceableObjectDecorator import SliceableObjectDecorator @@ -971,7 +971,7 @@ class CuraApplication(QtApplication): qmlRegisterType(MultiBuildPlateModel, "Cura", 1, 0, "MultiBuildPlateModel") qmlRegisterType(InstanceContainer, "Cura", 1, 0, "InstanceContainer") qmlRegisterType(ExtrudersModel, "Cura", 1, 0, "ExtrudersModel") - qmlRegisterType(PrintersModel, "Cura", 1, 0, "PrintersModel") + qmlRegisterType(GlobalStacksModel, "Cura", 1, 0, "GlobalStacksModel") qmlRegisterType(FavoriteMaterialsModel, "Cura", 1, 0, "FavoriteMaterialsModel") qmlRegisterType(GenericMaterialsModel, "Cura", 1, 0, "GenericMaterialsModel") diff --git a/cura/PrintersModel.py b/cura/GlobalStacksModel.py similarity index 97% rename from cura/PrintersModel.py rename to cura/GlobalStacksModel.py index 8b5d2f6cc9..8ae6b05291 100644 --- a/cura/PrintersModel.py +++ b/cura/GlobalStacksModel.py @@ -12,7 +12,8 @@ from cura.PrinterOutputDevice import ConnectionType from cura.Settings.GlobalStack import GlobalStack -class PrintersModel(ListModel): + +class GlobalStacksModel(ListModel): NameRole = Qt.UserRole + 1 IdRole = Qt.UserRole + 2 HasRemoteConnectionRole = Qt.UserRole + 3 diff --git a/resources/qml/Menus/LocalPrinterMenu.qml b/resources/qml/Menus/LocalPrinterMenu.qml index e7c5037814..4da1de2abf 100644 --- a/resources/qml/Menus/LocalPrinterMenu.qml +++ b/resources/qml/Menus/LocalPrinterMenu.qml @@ -9,7 +9,7 @@ import Cura 1.0 as Cura Instantiator { - model: Cura.PrintersModel {} + model: Cura.GlobalStacksModel {} MenuItem { diff --git a/resources/qml/Menus/NetworkPrinterMenu.qml b/resources/qml/Menus/NetworkPrinterMenu.qml index 8c607bc5ae..3cb0aae016 100644 --- a/resources/qml/Menus/NetworkPrinterMenu.qml +++ b/resources/qml/Menus/NetworkPrinterMenu.qml @@ -9,7 +9,7 @@ import Cura 1.0 as Cura Instantiator { - model: Cura.PrintersModel {} + model: Cura.GlobalStacksModel {} MenuItem { text: model.metadata["connect_group_name"] diff --git a/resources/qml/PrinterSelector/MachineSelectorList.qml b/resources/qml/PrinterSelector/MachineSelectorList.qml index ea8068fa95..62ecf48cc5 100644 --- a/resources/qml/PrinterSelector/MachineSelectorList.qml +++ b/resources/qml/PrinterSelector/MachineSelectorList.qml @@ -11,7 +11,7 @@ ListView { id: listView height: childrenRect.height - model: Cura.PrintersModel {} + model: Cura.GlobalStacksModel {} section.property: "hasRemoteConnection" section.delegate: Label From 1277fbabc588634a78b6544f10abdcbc16f9c8ad Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 31 Dec 2018 11:15:03 +0100 Subject: [PATCH 1121/1292] Fix connection type not always being seen correctly CURA-6011 --- cura/GlobalStacksModel.py | 3 +-- cura/Settings/MachineManager.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/cura/GlobalStacksModel.py b/cura/GlobalStacksModel.py index 8ae6b05291..b0052900cd 100644 --- a/cura/GlobalStacksModel.py +++ b/cura/GlobalStacksModel.py @@ -54,9 +54,8 @@ class GlobalStacksModel(ListModel): container_stacks = ContainerRegistry.getInstance().findContainerStacks(type = "machine") for container_stack in container_stacks: - connection_type = container_stack.getMetaDataEntry("connection_type") + connection_type = int(container_stack.getMetaDataEntry("connection_type", "-1")) has_remote_connection = connection_type in [ConnectionType.NetworkConnection.value, ConnectionType.CloudConnection.value] - if container_stack.getMetaDataEntry("hidden", False) in ["True", True]: continue diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 2185bbce9d..5b99b73b3c 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -527,7 +527,7 @@ class MachineManager(QObject): @pyqtProperty(bool, notify = printerConnectedStatusChanged) def activeMachineHasRemoteConnection(self) -> bool: if self._global_container_stack: - connection_type = self._global_container_stack.getMetaDataEntry("connection_type") + connection_type = int(self._global_container_stack.getMetaDataEntry("connection_type", "-1")) return connection_type in [ConnectionType.NetworkConnection.value, ConnectionType.CloudConnection.value] return False From 89040b6d8f9957d41b92c7b88bc78f6fb25fca2e Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 31 Dec 2018 11:18:17 +0100 Subject: [PATCH 1122/1292] Remove unneeded nameChanged signal connection CURA-6011 --- cura/GlobalStacksModel.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/cura/GlobalStacksModel.py b/cura/GlobalStacksModel.py index b0052900cd..3ad110b7d0 100644 --- a/cura/GlobalStacksModel.py +++ b/cura/GlobalStacksModel.py @@ -42,14 +42,8 @@ class GlobalStacksModel(ListModel): if isinstance(container, GlobalStack): self._update() - ## Handler for container name change events. - def _onContainerNameChanged(self): - self._update() - def _update(self) -> None: items = [] - for container in self._container_stacks: - container.nameChanged.disconnect(self._onContainerNameChanged) container_stacks = ContainerRegistry.getInstance().findContainerStacks(type = "machine") From d9d1c93bd08d262a52aafe61024498ea4421f9a3 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 31 Dec 2018 11:25:23 +0100 Subject: [PATCH 1123/1292] Use "NotConnected" as default for the connection state CURA-6011 --- cura/GlobalStacksModel.py | 2 +- cura/PrinterOutputDevice.py | 4 ++-- cura/Settings/MachineManager.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cura/GlobalStacksModel.py b/cura/GlobalStacksModel.py index 3ad110b7d0..939809151d 100644 --- a/cura/GlobalStacksModel.py +++ b/cura/GlobalStacksModel.py @@ -48,7 +48,7 @@ class GlobalStacksModel(ListModel): container_stacks = ContainerRegistry.getInstance().findContainerStacks(type = "machine") for container_stack in container_stacks: - connection_type = int(container_stack.getMetaDataEntry("connection_type", "-1")) + connection_type = int(container_stack.getMetaDataEntry("connection_type", ConnectionType.NotConnected.value)) has_remote_connection = connection_type in [ConnectionType.NetworkConnection.value, ConnectionType.CloudConnection.value] if container_stack.getMetaDataEntry("hidden", False) in ["True", True]: continue diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index aeeb0381b2..99e8835c2f 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -36,7 +36,7 @@ class ConnectionState(IntEnum): class ConnectionType(IntEnum): - Unknown = 0 + NotConnected = 0 UsbConnection = 1 NetworkConnection = 2 CloudConnection = 3 @@ -74,7 +74,7 @@ class PrinterOutputDevice(QObject, OutputDevice): # Signal to indicate that the configuration of one of the printers has changed. uniqueConfigurationsChanged = pyqtSignal() - def __init__(self, device_id: str, connection_type: "ConnectionType" = ConnectionType.Unknown, parent: QObject = None) -> None: + def __init__(self, device_id: str, connection_type: "ConnectionType" = ConnectionType.NotConnected, parent: QObject = None) -> None: super().__init__(device_id = device_id, parent = parent) # type: ignore # MyPy complains with the multiple inheritance self._printers = [] # type: List[PrinterOutputModel] diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 5b99b73b3c..32b83ead28 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -527,7 +527,7 @@ class MachineManager(QObject): @pyqtProperty(bool, notify = printerConnectedStatusChanged) def activeMachineHasRemoteConnection(self) -> bool: if self._global_container_stack: - connection_type = int(self._global_container_stack.getMetaDataEntry("connection_type", "-1")) + connection_type = int(self._global_container_stack.getMetaDataEntry("connection_type", ConnectionType.NotConnected.value)) return connection_type in [ConnectionType.NetworkConnection.value, ConnectionType.CloudConnection.value] return False From b5c406dc43930f2eca4fe866e07cc96cbb237b98 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 31 Dec 2018 13:11:24 +0100 Subject: [PATCH 1124/1292] Make default font size slightly smaller In accordance with the designs. Contributes to issue CURA-6025. --- resources/themes/cura-light/theme.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 5be1de1cfb..b14fdf0b4f 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -25,17 +25,17 @@ "family": "Noto Sans" }, "default": { - "size": 1.0, + "size": 0.95, "weight": 40, "family": "Noto Sans" }, "default_bold": { - "size": 1.0, + "size": 0.95, "weight": 60, "family": "Noto Sans" }, "default_italic": { - "size": 1.0, + "size": 0.95, "weight": 40, "italic": true, "family": "Noto Sans" From 8dbebaa23c0ba8132e0245a62221cababb6bf3b4 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 31 Dec 2018 13:14:08 +0100 Subject: [PATCH 1125/1292] Ensure that the machine selector list scales properly The old implementation directly listend to the height (instead of childrenRect). This caused issues, since other things apart from adding / removing machines could influence the height. CURA-6060 --- resources/qml/PrinterSelector/MachineSelector.qml | 8 +++++--- resources/qml/PrinterSelector/MachineSelectorList.qml | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index 28e01c7ae9..9f0d3b4ac6 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -93,14 +93,16 @@ Cura.ExpandablePopup width: scroll.width - scroll.leftPadding - scroll.rightPadding property real maximumHeight: UM.Theme.getSize("machine_selector_widget_content").height - buttonRow.height - onHeightChanged: + // We use an extra property here, since we only want to to be informed about the content size changes. + onContentHeightChanged: { - scroll.height = Math.min(height, maximumHeight) + scroll.height = Math.min(contentHeight, maximumHeight) popup.height = scroll.height + buttonRow.height } + Component.onCompleted: { - scroll.height = Math.min(height, maximumHeight) + scroll.height = Math.min(contentHeight, maximumHeight) popup.height = scroll.height + buttonRow.height } diff --git a/resources/qml/PrinterSelector/MachineSelectorList.qml b/resources/qml/PrinterSelector/MachineSelectorList.qml index 62ecf48cc5..604e0f668d 100644 --- a/resources/qml/PrinterSelector/MachineSelectorList.qml +++ b/resources/qml/PrinterSelector/MachineSelectorList.qml @@ -10,9 +10,9 @@ import Cura 1.0 as Cura ListView { id: listView - height: childrenRect.height model: Cura.GlobalStacksModel {} section.property: "hasRemoteConnection" + property real contentHeight: childrenRect.height section.delegate: Label { From c6fb0d70af8877f840f6cbbc8348eaa4dc63b8de Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 31 Dec 2018 13:22:53 +0100 Subject: [PATCH 1126/1292] Use medium font size for everything in stage menu Except the material manufacturer, which should remain default. Contributes to issue CURA-6025. --- plugins/SimulationView/SimulationViewMenuComponent.qml | 4 ++-- resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml | 4 ++-- resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml | 4 ++++ resources/qml/ViewsSelector.qml | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/plugins/SimulationView/SimulationViewMenuComponent.qml b/plugins/SimulationView/SimulationViewMenuComponent.qml index fe32fe9eb1..4c952d4c43 100644 --- a/plugins/SimulationView/SimulationViewMenuComponent.qml +++ b/plugins/SimulationView/SimulationViewMenuComponent.qml @@ -43,7 +43,7 @@ Cura.ExpandableComponent verticalAlignment: Text.AlignVCenter height: parent.height elide: Text.ElideRight - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("medium") color: UM.Theme.getColor("text_medium") renderType: Text.NativeRendering } @@ -60,7 +60,7 @@ Cura.ExpandableComponent } height: parent.height elide: Text.ElideRight - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("medium") color: UM.Theme.getColor("text") renderType: Text.NativeRendering } diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index 207b65afc7..3001efac54 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -86,7 +86,7 @@ Cura.ExpandablePopup { text: model.material elide: Text.ElideRight - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("medium") color: UM.Theme.getColor("text") renderType: Text.NativeRendering @@ -107,7 +107,7 @@ Cura.ExpandablePopup { text: catalog.i18nc("@label", "Select configuration") elide: Text.ElideRight - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("medium") color: UM.Theme.getColor("text") renderType: Text.NativeRendering diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml index 94da5bdd6f..5ae9488cd3 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml @@ -29,6 +29,7 @@ RowLayout } return "" } + font: UM.Theme.getFont("medium") UM.SettingPropertyProvider { @@ -43,6 +44,7 @@ RowLayout { source: UM.Theme.getIcon("category_infill") text: Cura.MachineManager.activeStack ? parseInt(infillDensity.properties.value) + "%" : "0%" + font: UM.Theme.getFont("medium") UM.SettingPropertyProvider { @@ -57,6 +59,7 @@ RowLayout { source: UM.Theme.getIcon("category_support") text: supportEnabled.properties.value == "True" ? enabledText : disabledText + font: UM.Theme.getFont("medium") UM.SettingPropertyProvider { @@ -71,6 +74,7 @@ RowLayout { source: UM.Theme.getIcon("category_adhesion") text: platformAdhesionType.properties.value != "skirt" && platformAdhesionType.properties.value != "none" ? enabledText : disabledText + font: UM.Theme.getFont("medium") UM.SettingPropertyProvider { diff --git a/resources/qml/ViewsSelector.qml b/resources/qml/ViewsSelector.qml index 1f5a0bbc85..da9693be6e 100644 --- a/resources/qml/ViewsSelector.qml +++ b/resources/qml/ViewsSelector.qml @@ -51,7 +51,7 @@ Cura.ExpandablePopup verticalAlignment: Text.AlignVCenter height: parent.height elide: Text.ElideRight - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("medium") color: UM.Theme.getColor("text_medium") renderType: Text.NativeRendering } From d020a49b751d885ff366f648c1d1b0d0c46ee003 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 31 Dec 2018 13:26:55 +0100 Subject: [PATCH 1127/1292] Assign a font to Marketplace button Otherwise the font face may be different, and the theme has no effect on the font. Contributes to issue CURA-6025. --- resources/qml/MainWindow/MainWindowHeader.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/qml/MainWindow/MainWindowHeader.qml b/resources/qml/MainWindow/MainWindowHeader.qml index e3b7e199fa..3e296ead40 100644 --- a/resources/qml/MainWindow/MainWindowHeader.qml +++ b/resources/qml/MainWindow/MainWindowHeader.qml @@ -102,6 +102,7 @@ Item { id: label text: marketplaceButton.text + font: UM.Theme.getFont("default") color: marketplaceButton.hovered ? UM.Theme.getColor("main_window_header_background") : UM.Theme.getColor("primary_text") width: contentWidth verticalAlignment: Text.AlignVCenter From c74d6fc1e7c6fe01a4e03719861e580e5bbc4640 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 31 Dec 2018 13:32:49 +0100 Subject: [PATCH 1128/1292] Make printerTypeLabel smaller More in line with the theme. Contributes to issue CURA-6025. --- resources/qml/PrinterTypeLabel.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/PrinterTypeLabel.qml b/resources/qml/PrinterTypeLabel.qml index cfc9e56513..b445228e83 100644 --- a/resources/qml/PrinterTypeLabel.qml +++ b/resources/qml/PrinterTypeLabel.qml @@ -29,7 +29,7 @@ Item anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter renderType: Text.NativeRendering - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("small") color: UM.Theme.getColor("text") } } \ No newline at end of file From 8d8133d521d546b19bf32c2fa58a96894a7d152e Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 31 Dec 2018 13:34:57 +0100 Subject: [PATCH 1129/1292] Make synced material name larger than the rest In accordance with the designs. Contributes to issue CURA-6025. --- .../qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml index a344e31d4f..db6a97aa65 100644 --- a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml @@ -39,7 +39,7 @@ Row text: printCoreConfiguration.material.brand ? printCoreConfiguration.material.name : " " //Use space so that the height is still correct. renderType: Text.NativeRendering elide: Text.ElideRight - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("medium") color: UM.Theme.getColor("text") } Label From 60a5438db6b10942357ba77d40b9d61202780886 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 31 Dec 2018 13:43:31 +0100 Subject: [PATCH 1130/1292] Make expandable component header fonts larger As per the design. Contributes to issue CURA-6025. --- resources/qml/ExpandableComponentHeader.qml | 2 +- resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml | 2 +- resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml | 2 +- resources/qml/ViewsSelector.qml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/qml/ExpandableComponentHeader.qml b/resources/qml/ExpandableComponentHeader.qml index 09ea262c82..94066340e3 100644 --- a/resources/qml/ExpandableComponentHeader.qml +++ b/resources/qml/ExpandableComponentHeader.qml @@ -25,7 +25,7 @@ Cura.RoundedRectangle { id: headerLabel text: "" - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("medium") renderType: Text.NativeRendering verticalAlignment: Text.AlignVCenter color: UM.Theme.getColor("small_button_text") diff --git a/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml index a3ed5040b7..18409dd43a 100644 --- a/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml @@ -16,7 +16,7 @@ Item { id: header text: catalog.i18nc("@header", "Configurations") - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("medium") color: UM.Theme.getColor("small_button_text") height: contentHeight renderType: Text.NativeRendering diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index 4d6d80c1b4..5cecda4e5c 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -23,7 +23,7 @@ Item { id: header text: catalog.i18nc("@header", "Custom") - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("medium") color: UM.Theme.getColor("small_button_text") height: contentHeight renderType: Text.NativeRendering diff --git a/resources/qml/ViewsSelector.qml b/resources/qml/ViewsSelector.qml index da9693be6e..0e9be649db 100644 --- a/resources/qml/ViewsSelector.qml +++ b/resources/qml/ViewsSelector.qml @@ -68,7 +68,7 @@ Cura.ExpandablePopup } height: parent.height elide: Text.ElideRight - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("medium") color: UM.Theme.getColor("text") renderType: Text.NativeRendering } From 4be228a4e2e46e59a53c446224e6850518cba176 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 31 Dec 2018 13:43:47 +0100 Subject: [PATCH 1131/1292] Fix merging & grouping I made a boo-boo while adding typing. CURA-6058 --- cura/CuraApplication.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 07464c97ca..186d30fe89 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -1404,7 +1404,7 @@ class CuraApplication(QtApplication): selected_nodes = Selection.getAllSelectedObjects().copy() for node in selected_nodes: parent = node.getParent() - if parent is not None and node in selected_nodes and not node.callDecoration("isGroup"): + if parent is not None and parent in selected_nodes and not parent.callDecoration("isGroup"): Selection.remove(node) # Move selected nodes into the group-node From 44f21b37ac613fc229e32fa507077b1641d2fede Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 31 Dec 2018 13:49:03 +0100 Subject: [PATCH 1132/1292] Make labels on left side of recommended mode larger Contributes to issue CURA-6025. --- .../Recommended/RecommendedAdhesionSelector.qml | 1 + .../Recommended/RecommendedInfillDensitySelector.qml | 1 + .../Recommended/RecommendedQualityProfileSelector.qml | 1 + .../Recommended/RecommendedSupportSelector.qml | 1 + 4 files changed, 4 insertions(+) diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedAdhesionSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedAdhesionSelector.qml index a5f35f333b..941199707c 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedAdhesionSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedAdhesionSelector.qml @@ -26,6 +26,7 @@ Item anchors.left: parent.left source: UM.Theme.getIcon("category_adhesion") text: catalog.i18nc("@label", "Adhesion") + font: UM.Theme.getFont("medium") width: labelColumnWidth } diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml index 0da53cc1c1..b733a576e4 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml @@ -63,6 +63,7 @@ Item anchors.left: parent.left source: UM.Theme.getIcon("category_infill") text: catalog.i18nc("@label", "Infill") + " (%)" + font: UM.Theme.getFont("medium") width: labelColumnWidth } diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml index 1e71134404..af145410b5 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml @@ -173,6 +173,7 @@ Item id: qualityRowTitle source: UM.Theme.getIcon("category_layer_height") text: catalog.i18nc("@label", "Layer Height") + font: UM.Theme.getFont("medium") anchors.left: parent.left anchors.right: customisedSettings.left } diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml index 87fb664713..0e834ac4df 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml @@ -27,6 +27,7 @@ Item visible: enableSupportCheckBox.visible source: UM.Theme.getIcon("category_support") text: catalog.i18nc("@label", "Support") + font: UM.Theme.getFont("medium") width: labelColumnWidth } From 4be9fbb75ec6f31d51fbed3e44086dc756b22f08 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 31 Dec 2018 13:57:49 +0100 Subject: [PATCH 1133/1292] Give tick marks a font Otherwise it uses your system's font, which is not consistent. Contributes to issue CURA-6025. --- .../Recommended/RecommendedInfillDensitySelector.qml | 1 + .../Recommended/RecommendedQualityProfileSelector.qml | 1 + 2 files changed, 2 insertions(+) diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml index b733a576e4..19f199fea6 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml @@ -141,6 +141,7 @@ Item Label { text: index + font: UM.Theme.getFont("default") visible: (index % 20) == 0 // Only show steps of 20% anchors.horizontalCenter: parent.horizontalCenter y: UM.Theme.getSize("thin_margin").height diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml index af145410b5..801e76382b 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml @@ -272,6 +272,7 @@ Item return Math.round((settingsColumnWidth / qualityModel.totalTicks) * index - (width / 2)) } } + font: UM.Theme.getFont("default") } } } From cf6cce5df0f4da01adbb8631d3349d4b8e8d2d33 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 31 Dec 2018 14:00:39 +0100 Subject: [PATCH 1134/1292] Make 'Profile' text larger As per the design. Contributes to issue CURA-6025. --- .../qml/PrintSetupSelector/Custom/GlobalProfileSelector.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/PrintSetupSelector/Custom/GlobalProfileSelector.qml b/resources/qml/PrintSetupSelector/Custom/GlobalProfileSelector.qml index 8baaf9a7ae..32c07a52a6 100644 --- a/resources/qml/PrintSetupSelector/Custom/GlobalProfileSelector.qml +++ b/resources/qml/PrintSetupSelector/Custom/GlobalProfileSelector.qml @@ -25,7 +25,7 @@ Item right: globalProfileSelection.left } text: catalog.i18nc("@label", "Profile") - font: UM.Theme.getFont("default") + font: UM.Theme.getFont("medium") color: UM.Theme.getColor("text") verticalAlignment: Text.AlignVCenter } From 66aeb2d1dd0bd8e59dbd4c988b282fbb664c48c9 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 31 Dec 2018 14:27:01 +0100 Subject: [PATCH 1135/1292] Give print time estimate a large font Contributes to issue CURA-6025. --- resources/qml/ActionPanel/OutputProcessWidget.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/ActionPanel/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml index 03fa00d504..223ddacb31 100644 --- a/resources/qml/ActionPanel/OutputProcessWidget.qml +++ b/resources/qml/ActionPanel/OutputProcessWidget.qml @@ -51,7 +51,7 @@ Column text: preSlicedData ? catalog.i18nc("@label", "No time estimation available") : PrintInformation.currentPrintTime.getDisplayString(UM.DurationFormat.Long) source: UM.Theme.getIcon("clock") - font: UM.Theme.getFont("default_bold") + font: UM.Theme.getFont("large_bold") } Cura.IconWithText From c92a0f1fd43d79e24f70ff3e7f09774769743fcb Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 31 Dec 2018 15:09:15 +0100 Subject: [PATCH 1136/1292] Fix bold fonts on Linux I'm not sure how this performs on other platforms, but on mine it needs at least 63 weight for bold. This is because there is a normal font at weight 40 and a bold font at weight 85. From 63+ it rounds to the bold font with the closest weight then. Contributes to issue CURA-6025. --- resources/themes/cura-light/theme.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index b14fdf0b4f..dbd1ad34b1 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -11,7 +11,7 @@ }, "large_bold": { "size": 1.35, - "weight": 60, + "weight": 63, "family": "Noto Sans" }, "medium": { @@ -21,7 +21,7 @@ }, "medium_bold": { "size": 1.16, - "weight": 60, + "weight": 63, "family": "Noto Sans" }, "default": { @@ -31,7 +31,7 @@ }, "default_bold": { "size": 0.95, - "weight": 60, + "weight": 63, "family": "Noto Sans" }, "default_italic": { From df0351acd44386e6a50809d842c379cece3938d7 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 31 Dec 2018 15:14:23 +0100 Subject: [PATCH 1137/1292] Fix fonts of plug-in tiles Contributes to issue CURA-6025. --- plugins/Toolbox/resources/qml/SmallRatingWidget.qml | 2 +- plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml | 2 +- resources/qml/PrintSetupTooltip.qml | 3 ++- resources/qml/ToolTip.qml | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/plugins/Toolbox/resources/qml/SmallRatingWidget.qml b/plugins/Toolbox/resources/qml/SmallRatingWidget.qml index 4950ea9242..965b81dc0f 100644 --- a/plugins/Toolbox/resources/qml/SmallRatingWidget.qml +++ b/plugins/Toolbox/resources/qml/SmallRatingWidget.qml @@ -30,7 +30,7 @@ Row width: contentWidth anchors.verticalCenter: starIcon.verticalCenter color: starIcon.color - font: UM.Theme.getFont("small") + font: UM.Theme.getFont("default") renderType: Text.NativeRendering } } \ No newline at end of file diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index 58e4f070e0..a11c6ee963 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -112,7 +112,7 @@ Item elide: Text.ElideRight width: parent.width wrapMode: Text.WordWrap - color: UM.Theme.getColor("text_medium") + color: UM.Theme.getColor("text") font: UM.Theme.getFont("default") anchors.top: name.bottom anchors.bottom: rating.top diff --git a/resources/qml/PrintSetupTooltip.qml b/resources/qml/PrintSetupTooltip.qml index 693b703813..6b1538d849 100644 --- a/resources/qml/PrintSetupTooltip.qml +++ b/resources/qml/PrintSetupTooltip.qml @@ -41,7 +41,8 @@ UM.PointingRectangle { base.opacity = 0; } - Label { + Label + { id: label; anchors { top: parent.top; diff --git a/resources/qml/ToolTip.qml b/resources/qml/ToolTip.qml index 87586f76d8..e82caf01b2 100644 --- a/resources/qml/ToolTip.qml +++ b/resources/qml/ToolTip.qml @@ -25,7 +25,7 @@ ToolTip text: "" delay: 500 font: UM.Theme.getFont("default") - + // If the text is not set, just set the height to 0 to prevent it from showing height: text != "" ? label.contentHeight + 2 * UM.Theme.getSize("thin_margin").width: 0 From 30ab1a957ff935872ba6cad4a8cf1fcc461bdc61 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 31 Dec 2018 15:18:50 +0100 Subject: [PATCH 1138/1292] Make headers of Marketplace large As per the design. Contributes to issue CURA-6025. --- plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml | 2 +- plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml index 85f0ff8be4..a9fcb39b28 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml @@ -22,7 +22,7 @@ Column text: gridArea.heading width: parent.width color: UM.Theme.getColor("text_medium") - font: UM.Theme.getFont("medium") + font: UM.Theme.getFont("large") renderType: Text.NativeRendering } Grid diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml index 820b74554a..795622cf82 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml @@ -23,7 +23,7 @@ Rectangle text: catalog.i18nc("@label", "Featured") width: parent.width color: UM.Theme.getColor("text_medium") - font: UM.Theme.getFont("medium") + font: UM.Theme.getFont("large") renderType: Text.NativeRendering } Grid From 346c8209597ad3c7357320ae4cd6475d82a6ef41 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 31 Dec 2018 15:22:34 +0100 Subject: [PATCH 1139/1292] Remove hover color for Marketplace header tabs It was not desirable, as discussed with the designer. Contributes to issue CURA-6025. --- resources/themes/cura-light/theme.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index dbd1ad34b1..fa8f96b6b3 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -298,7 +298,7 @@ "printer_config_mismatch": [127, 127, 127, 255], "toolbox_header_button_text_active": [0, 0, 0, 255], - "toolbox_header_button_text_inactive": [128, 128, 128, 255], + "toolbox_header_button_text_inactive": [0, 0, 0, 255], "toolbox_header_button_text_hovered": [0, 0, 0, 255], "favorites_header_bar": [245, 245, 245, 255], From 7ef8287e52c686cab72cf674a7cbd7c3df713aa5 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 31 Dec 2018 15:33:37 +0100 Subject: [PATCH 1140/1292] Fix theming of back button in Marketplace Give it a bit more space for if the translated text is wider, and if it is wider also align it properly with the arrow. Contributes to issue CURA-6025. --- plugins/Toolbox/resources/qml/ToolboxBackColumn.qml | 9 +++++++-- plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml | 2 +- resources/themes/cura-light/theme.json | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml b/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml index edb1967fee..dba9f19ccd 100644 --- a/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml +++ b/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml @@ -61,8 +61,13 @@ Item id: labelStyle text: control.text color: control.enabled ? (control.hovered ? UM.Theme.getColor("primary") : UM.Theme.getColor("text")) : UM.Theme.getColor("text_inactive") - font: UM.Theme.getFont("default_bold") - horizontalAlignment: Text.AlignRight + font: UM.Theme.getFont("medium_bold") + horizontalAlignment: Text.AlignLeft + anchors + { + left: parent.left + leftMargin: UM.Theme.getSize("default_margin").width + } width: control.width renderType: Text.NativeRendering } diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml index e1d01db59a..a85a69cbac 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml @@ -37,7 +37,7 @@ ScrollView width: page.width text: catalog.i18nc("@title:tab", "Plugins") color: UM.Theme.getColor("text_medium") - font: UM.Theme.getFont("medium") + font: UM.Theme.getFont("large") renderType: Text.NativeRendering } Rectangle diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index fa8f96b6b3..e0a1c0f9bd 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -487,7 +487,7 @@ "toolbox_detail_header": [1.0, 14.0], "toolbox_detail_tile": [1.0, 8.0], "toolbox_back_column": [6.0, 1.0], - "toolbox_back_button": [4.0, 2.0], + "toolbox_back_button": [6.0, 2.0], "toolbox_installed_tile": [1.0, 8.0], "toolbox_property_label": [1.0, 2.0], "toolbox_heading_label": [1.0, 3.8], From 4177faa6eac5b65d796fe27f3e16a0c82ec1cf34 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 31 Dec 2018 15:37:31 +0100 Subject: [PATCH 1141/1292] Fix font usage in installed plug-ins Several different font sizes should be used here. Contributes to issue CURA-6025. --- plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml index 593e024309..333d4dd50a 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml @@ -49,13 +49,14 @@ Item width: parent.width height: Math.floor(UM.Theme.getSize("toolbox_property_label").height) wrapMode: Text.WordWrap - font: UM.Theme.getFont("default_bold") + font: UM.Theme.getFont("large_bold") color: pluginInfo.color renderType: Text.NativeRendering } Label { text: model.description + font: UM.Theme.getFont("default") maximumLineCount: 3 elide: Text.ElideRight width: parent.width @@ -82,6 +83,7 @@ Item return model.author_name } } + font: UM.Theme.getFont("medium") width: parent.width height: Math.floor(UM.Theme.getSize("toolbox_property_label").height) wrapMode: Text.WordWrap @@ -96,6 +98,7 @@ Item Label { text: model.version + font: UM.Theme.getFont("default") width: parent.width height: UM.Theme.getSize("toolbox_property_label").height color: UM.Theme.getColor("text") From 6092402a878c6ba4bab877b31dbf1033dc9c8a8e Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 31 Dec 2018 15:44:09 +0100 Subject: [PATCH 1142/1292] Fix 'Slicing...' message when not autoslicing Also changes the 'auto slicing' text to just 'slicing', because that's more what the user expects. Discussed with UX. Contributes to issue CURA-6025. --- resources/qml/ActionPanel/SliceProcessWidget.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index 6c3b136ca0..51c5e4cac7 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -44,9 +44,9 @@ Column { id: autoSlicingLabel width: parent.width - visible: prepareButtons.autoSlice && (widget.backendState == UM.Backend.Processing || widget.backendState == UM.Backend.NotStarted) + visible: progressBar.visible - text: catalog.i18nc("@label:PrintjobStatus", "Auto slicing...") + text: catalog.i18nc("@label:PrintjobStatus", "Slicing...") color: UM.Theme.getColor("text") font: UM.Theme.getFont("default") renderType: Text.NativeRendering From 208811f383322c8b28dceeb6d2d13af567461636 Mon Sep 17 00:00:00 2001 From: pinchies Date: Wed, 2 Jan 2019 02:58:19 +1100 Subject: [PATCH 1143/1292] fix start gcode on alfawise u20 small tweak to fixestart gcode to avoid default position of bed clamps --- resources/definitions/alfawise_u20.def.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/definitions/alfawise_u20.def.json b/resources/definitions/alfawise_u20.def.json index abc206c4d2..e8ea283670 100644 --- a/resources/definitions/alfawise_u20.def.json +++ b/resources/definitions/alfawise_u20.def.json @@ -18,7 +18,7 @@ "default_value": "Alfawise U20" }, "machine_start_gcode": { - "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 ;home all axis\nG92 E0 ;zero the extruded length\nG1 Z1 F1000 ;move up slightly\nG1 X60.0 Z0 E9.0 F1000.0;intro line\nG1 X100.0 E21.5 F1000.0 ;continue line\nG92 E0 ;zero the extruded length again\n; -- end of START GCODE --" + "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 ;home all axis\nG92 E0 ;zero the extruded length\nG1 Z1 F1000 ;move up slightly\nG1 Y60.0 Z0 E9.0 F1000.0;intro line\nG1 Y100.0 E21.5 F1000.0 ;continue line\nG92 E0 ;zero the extruded length again\n; -- end of START GCODE --" }, "machine_end_gcode": { "default_value": "; -- END GCODE --\nM104 S0 ;turn off nozzle heater\nM140 S0 ;turn off bed heater\nG91 ;set to relative positioning\nG1 E-10 F300 ;retract the filament slightly\nG90 ;set to absolute positioning\nG28 X0 ;move to the X-axis origin (Home)\nG0 Y280 F600 ;bring the bed to the front for easy print removal\nM84 ;turn off stepper motors\n; -- end of END GCODE --" From 0b0f674e4b4cf7ab470a374e3ba41c1fa989845f Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 2 Jan 2019 09:22:50 +0100 Subject: [PATCH 1144/1292] Remove unused code --- cura/Settings/MachineManager.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 32b83ead28..3af7c7fba8 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -64,8 +64,6 @@ class MachineManager(QObject): self._default_extruder_position = "0" # to be updated when extruders are switched on and off - self.machine_extruder_material_update_dict = collections.defaultdict(list) #type: Dict[str, List[Callable[[], None]]] - self._instance_container_timer = QTimer() # type: QTimer self._instance_container_timer.setInterval(250) self._instance_container_timer.setSingleShot(True) @@ -275,11 +273,6 @@ class MachineManager(QObject): extruder_stack.propertyChanged.connect(self._onPropertyChanged) extruder_stack.containersChanged.connect(self._onContainersChanged) - if self._global_container_stack.getId() in self.machine_extruder_material_update_dict: - for func in self.machine_extruder_material_update_dict[self._global_container_stack.getId()]: - self._application.callLater(func) - del self.machine_extruder_material_update_dict[self._global_container_stack.getId()] - self.activeQualityGroupChanged.emit() def _onActiveExtruderStackChanged(self) -> None: From e8febaff59dacd03ac71917b4508c68117a1ad2a Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 2 Jan 2019 09:23:20 +0100 Subject: [PATCH 1145/1292] Remove code duplication --- cura/Settings/ExtruderManager.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index 8fa0172305..a459d65ba3 100755 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -301,12 +301,7 @@ class ExtruderManager(QObject): global_stack = self._application.getGlobalContainerStack() if not global_stack: return [] - - result_tuple_list = sorted(list(global_stack.extruders.items()), key = lambda x: int(x[0])) - result_list = [item[1] for item in result_tuple_list] - - machine_extruder_count = global_stack.getProperty("machine_extruder_count", "value") - return result_list[:machine_extruder_count] + return global_stack.extruderList def _globalContainerStackChanged(self) -> None: # If the global container changed, the machine changed and might have extruders that were not registered yet From 2a4c66888e2432e932e2ffe472db021b9715df5e Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 2 Jan 2019 09:39:44 +0100 Subject: [PATCH 1146/1292] Use getNumInstances instead of counting the number of instances in machinemanager This should prevent having to initiate the cached values if we only want to know the number of settings. --- cura/Settings/MachineManager.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 3af7c7fba8..dec2524e6b 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -436,12 +436,12 @@ class MachineManager(QObject): if not self._global_container_stack: return False - if self._global_container_stack.getTop().findInstances(): + if self._global_container_stack.getTop().getNumInstances() != 0: return True stacks = ExtruderManager.getInstance().getActiveExtruderStacks() for stack in stacks: - if stack.getTop().findInstances(): + if stack.getTop().getNumInstances() != 0: return True return False @@ -451,10 +451,10 @@ class MachineManager(QObject): if not self._global_container_stack: return 0 num_user_settings = 0 - num_user_settings += len(self._global_container_stack.getTop().findInstances()) - stacks = ExtruderManager.getInstance().getActiveExtruderStacks() + num_user_settings += self._global_container_stack.getTop().getNumInstances() + stacks = self._global_container_stack.extruderList for stack in stacks: - num_user_settings += len(stack.getTop().findInstances()) + num_user_settings += stack.getTop().getNumInstances() return num_user_settings ## Delete a user setting from the global stack and all extruder stacks. From 11dfb9acdc04a047e9914db08a338c7252aecb49 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 2 Jan 2019 11:18:15 +0100 Subject: [PATCH 1147/1292] Remove PluginsPage.qml CURA-6066 --- resources/qml/Cura.qml | 3 --- 1 file changed, 3 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 8a34c7e219..ca1c2e38c1 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -353,9 +353,6 @@ UM.MainWindow insertPage(4, catalog.i18nc("@title:tab", "Profiles"), Qt.resolvedUrl("Preferences/ProfilesPage.qml")); - // Remove plug-ins page because we will use the shiny new plugin browser: - removePage(5); - //Force refresh setPage(0); } From a0031853d365a3ad9d44f898be77df66899a3a9d Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 2 Jan 2019 11:32:49 +0100 Subject: [PATCH 1148/1292] Fix button color in toolpanel for dark theme --- resources/themes/cura-light/styles.qml | 2 +- resources/themes/cura-light/theme.json | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index 89729fc08c..2c4dab7c89 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -256,7 +256,7 @@ QtObject source: control.iconSource width: Theme.getSize("button_icon").width height: Theme.getSize("button_icon").height - color: Theme.getColor("toolbar_button_text") + color: Theme.getColor("icon") sourceSize: Theme.getSize("button_icon") } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 2b9ce3d218..d56869d895 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -118,7 +118,6 @@ "warning": [245, 166, 35, 255], "disabled": [229, 229, 229, 255], - "toolbar_button_text": [8, 7, 63, 255], "toolbar_button_hover": [232, 242, 252, 255], "toolbar_button_active": [232, 242, 252, 255], "toolbar_button_active_hover": [232, 242, 252, 255], From 9be1f8aa7bff7d3c8bc1b107c7656de920e86603 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 2 Jan 2019 11:33:49 +0100 Subject: [PATCH 1149/1292] Removed marketplace menu item from top menu It was a bit double since we had the marketplace button in the top bar --- resources/qml/MainWindow/ApplicationMenu.qml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/resources/qml/MainWindow/ApplicationMenu.qml b/resources/qml/MainWindow/ApplicationMenu.qml index 04c068cb54..a694b8e403 100644 --- a/resources/qml/MainWindow/ApplicationMenu.qml +++ b/resources/qml/MainWindow/ApplicationMenu.qml @@ -83,14 +83,6 @@ Item } } - Menu - { - id: plugin_menu - title: catalog.i18nc("@title:menu menubar:toplevel", "&Marketplace") - - MenuItem { action: Cura.Actions.browsePackages } - } - Menu { id: preferencesMenu From df23097a99b1b1d027b55c64332354ec5d070ae2 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 2 Jan 2019 11:36:07 +0100 Subject: [PATCH 1150/1292] Changed the label for when no remote configurations are loaded yet --- resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index 684e575bfd..e57b21cb78 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -51,7 +51,7 @@ Item anchors.left: icon.right anchors.right: parent.right anchors.leftMargin: UM.Theme.getSize("default_margin").width - text: catalog.i18nc("@label", "The configurations are not available because the printer is disconnected.") + text: catalog.i18nc("@label", "Downloading the configurations from the remote printer") color: UM.Theme.getColor("text") font: UM.Theme.getFont("default") renderType: Text.NativeRendering From 9e0a423f28775c59204b62482f04e46464589a23 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 2 Jan 2019 13:30:16 +0100 Subject: [PATCH 1151/1292] Disable visibility of glass buildplate configuration in sync menu Because the build plate swapping is not implemented yet. --- resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 51ba77d012..5e47cafcf1 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -187,7 +187,7 @@ Button rightMargin: UM.Theme.getSize("wide_margin").width } height: childrenRect.height - visible: configuration.buildplateConfiguration != "" + visible: configuration.buildplateConfiguration != "" && false //Buildplate is disabled as long as we have no printers that properly support buildplate swapping (so we can't test). UM.RecolorImage { From 71632fd098fd4e55a54948adaeb6c6af460d5782 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 2 Jan 2019 13:53:35 +0100 Subject: [PATCH 1152/1292] Add the postProcessing button back next to the slice button CURA-6043 --- .../qml/ActionPanel/SliceProcessWidget.qml | 45 ++++++++++++++++++- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index 6c3b136ca0..4c5ae24f25 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -107,7 +107,13 @@ Column { id: sliceButton fixedWidthMode: true - anchors.fill: parent + + height: parent.height + + anchors.right: additionalComponents.left + anchors.rightMargin: additionalComponents.width != 0 ? UM.Theme.getSize("default_margin").width : 0 + anchors.left: parent.left + text: catalog.i18nc("@button", "Slice") tooltip: catalog.i18nc("@label", "Start the slicing process") enabled: widget.backendState != UM.Backend.Error @@ -119,12 +125,47 @@ Column { id: cancelButton fixedWidthMode: true - anchors.fill: parent + height: parent.height + anchors.left: parent.left + + anchors.right: additionalComponents.left + anchors.rightMargin: additionalComponents.width != 0 ? UM.Theme.getSize("default_margin").width : 0 text: catalog.i18nc("@button", "Cancel") enabled: sliceButton.enabled visible: !sliceButton.visible onClicked: sliceOrStopSlicing() } + Item + { + id: additionalComponents + width: childrenRect.width + anchors.right: parent.right + height: parent.height + Row + { + id: additionalComponentsRow + anchors.verticalCenter: parent.verticalCenter + spacing: UM.Theme.getSize("default_margin").width + } + } + Component.onCompleted: prepareButtons.addAdditionalComponents("saveButton") + + Connections + { + target: CuraApplication + onAdditionalComponentsChanged: prepareButtons.addAdditionalComponents("saveButton") + } + + function addAdditionalComponents (areaId) + { + if(areaId == "saveButton") + { + for (var component in CuraApplication.additionalComponents["saveButton"]) + { + CuraApplication.additionalComponents["saveButton"][component].parent = additionalComponentsRow + } + } + } } From 96a6b7559eec9d6c79925cc253c754e615a5bb68 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 2 Jan 2019 14:04:56 +0100 Subject: [PATCH 1153/1292] Remember opened state of settings panel So if you restart Cura while the settings panel was open, it'll stay open when Cura is started back up. Contributes to issue CURA-6069. --- cura/CuraApplication.py | 1 + resources/qml/ExpandableComponent.qml | 2 +- resources/qml/PrintSetupSelector/PrintSetupSelector.qml | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 0edf6c1899..4d1c530237 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -500,6 +500,7 @@ class CuraApplication(QtApplication): preferences.addPreference("cura/choice_on_open_project", "always_ask") preferences.addPreference("cura/use_multi_build_plate", False) preferences.addPreference("view/settings_list_height", 600) + preferences.addPreference("view/settings_visible", False) preferences.addPreference("cura/currency", "€") preferences.addPreference("cura/material_settings", "{}") diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index afe15bcb1d..025c63d754 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -64,7 +64,7 @@ Item property alias iconSize: collapseButton.height // Is the "drawer" open? - readonly property alias expanded: contentContainer.visible + property alias expanded: contentContainer.visible // What should the radius of the header be. This is also influenced by the headerCornerSide property alias headerRadius: background.radius diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelector.qml b/resources/qml/PrintSetupSelector/PrintSetupSelector.qml index 2d4d7f6cf1..48ac07679d 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelector.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelector.qml @@ -29,4 +29,7 @@ Cura.ExpandableComponent property var extrudersModel: CuraApplication.getExtrudersModel() contentItem: PrintSetupSelectorContents {} + + onExpandedChanged: UM.Preferences.setValue("view/settings_visible", expanded) + Component.onCompleted: expanded = UM.Preferences.getValue("view/settings_visible") } \ No newline at end of file From a5385b229acf0afc5f1b1fca9cd7dee368c3054d Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 2 Jan 2019 16:37:19 +0100 Subject: [PATCH 1154/1292] Make text in printer type label bigger Just shown it to our UX designer and she thinks it's better this way. Contributes to issue CURA-6025. --- resources/qml/PrinterTypeLabel.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/PrinterTypeLabel.qml b/resources/qml/PrinterTypeLabel.qml index b445228e83..cfc9e56513 100644 --- a/resources/qml/PrinterTypeLabel.qml +++ b/resources/qml/PrinterTypeLabel.qml @@ -29,7 +29,7 @@ Item anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter renderType: Text.NativeRendering - font: UM.Theme.getFont("small") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") } } \ No newline at end of file From ee72284616bbf191cdc71c7ac9b1471dca926ba6 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 3 Jan 2019 08:32:39 +0100 Subject: [PATCH 1155/1292] Use appropriate log level CURA-6035 --- plugins/UM3NetworkPrinting/src/SendMaterialJob.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py index ab6ebfef2e..9d0d3dbbad 100644 --- a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/src/SendMaterialJob.py @@ -97,7 +97,7 @@ class SendMaterialJob(Job): file_path = container_registry.getContainerFilePathById(root_material_id) if not file_path: - Logger.log("e", "Cannot get file path for material container [%s]", root_material_id) + Logger.log("w", "Cannot get file path for material container [%s]", root_material_id) continue file_name = os.path.basename(file_path) From 3505eb321f5e7908840caeb49e8faa0a9dcdf5c7 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 3 Jan 2019 09:42:22 +0100 Subject: [PATCH 1156/1292] Also add space for the savebutton additional components with the output widget CURA-6043 --- .../qml/ActionPanel/OutputProcessWidget.qml | 56 ++++++++++++++----- .../qml/ActionPanel/SliceProcessWidget.qml | 1 + 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/resources/qml/ActionPanel/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml index 03fa00d504..a8797670b4 100644 --- a/resources/qml/ActionPanel/OutputProcessWidget.qml +++ b/resources/qml/ActionPanel/OutputProcessWidget.qml @@ -40,8 +40,7 @@ Column anchors { left: parent.left - right: printInformationPanel.left - rightMargin: printInformationPanel.visible ? UM.Theme.getSize("thin_margin").width : 0 + right: parent.right } Cura.IconWithText @@ -52,6 +51,13 @@ Column text: preSlicedData ? catalog.i18nc("@label", "No time estimation available") : PrintInformation.currentPrintTime.getDisplayString(UM.DurationFormat.Long) source: UM.Theme.getIcon("clock") font: UM.Theme.getFont("default_bold") + PrintInformationWidget + { + id: printInformationPanel + visible: !preSlicedData + anchors.left: parent.left + anchors.leftMargin: parent.contentWidth + UM.Theme.getSize("default_margin").width + } } Cura.IconWithText @@ -84,20 +90,43 @@ Column return totalWeights + "g · " + totalLengths.toFixed(2) + "m" } source: UM.Theme.getIcon("spool") + + Item + { + id: additionalComponents + width: childrenRect.width + anchors.right: parent.right + height: parent.height + Row + { + id: additionalComponentsRow + anchors.right: parent.right + anchors.bottom: parent.bottom + spacing: UM.Theme.getSize("default_margin").width + } + } + Component.onCompleted: addAdditionalComponents("saveButton") + + Connections + { + target: CuraApplication + onAdditionalComponentsChanged: addAdditionalComponents("saveButton") + } + + function addAdditionalComponents (areaId) + { + if(areaId == "saveButton") + { + for (var component in CuraApplication.additionalComponents["saveButton"]) + { + CuraApplication.additionalComponents["saveButton"][component].parent = additionalComponentsRow + } + } + } } } - PrintInformationWidget - { - id: printInformationPanel - visible: !preSlicedData - anchors - { - right: parent.right - verticalCenter: timeAndCostsInformation.verticalCenter - } - } } Item @@ -127,9 +156,6 @@ Column onClicked: UM.Controller.setActiveStage("PreviewStage") visible: UM.Controller.activeStage != null && UM.Controller.activeStage.stageId != "PreviewStage" - - shadowEnabled: true - shadowColor: UM.Theme.getColor("action_button_disabled_shadow") } Cura.OutputDevicesActionButton diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index 4c5ae24f25..127f454902 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -135,6 +135,7 @@ Column visible: !sliceButton.visible onClicked: sliceOrStopSlicing() } + Item { id: additionalComponents From 195d39f698cda58b1bedcfcf2d75acb4c2de344d Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 3 Jan 2019 09:47:48 +0100 Subject: [PATCH 1157/1292] Update the style of the postprocessing button CURA-6043 --- .../PostProcessingPlugin.qml | 40 ++----------------- 1 file changed, 3 insertions(+), 37 deletions(-) diff --git a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml index 09fda8d454..5aa7660237 100644 --- a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml +++ b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml @@ -484,7 +484,7 @@ UM.Dialog onClicked: dialog.accept() } - Button + Cura.SecondaryButton { objectName: "postProcessingSaveAreaButton" visible: activeScriptsList.count > 0 @@ -492,41 +492,7 @@ UM.Dialog width: height tooltip: catalog.i18nc("@info:tooltip", "Change active post-processing scripts") onClicked: dialog.show() - - style: ButtonStyle - { - background: Rectangle - { - id: deviceSelectionIcon - border.width: UM.Theme.getSize("default_lining").width - border.color: !control.enabled ? UM.Theme.getColor("action_button_disabled_border") : - control.pressed ? UM.Theme.getColor("action_button_active_border") : - control.hovered ? UM.Theme.getColor("action_button_hovered_border") : UM.Theme.getColor("action_button_border") - color: !control.enabled ? UM.Theme.getColor("action_button_disabled") : - control.pressed ? UM.Theme.getColor("action_button_active") : - control.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") - Behavior on color { ColorAnimation { duration: 50; } } - - anchors.left: parent.left - anchors.leftMargin: Math.round(UM.Theme.getSize("save_button_text_margin").width / 2) - - width: parent.height - height: parent.height - - UM.RecolorImage - { - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.horizontalCenter - width: Math.round(parent.width / 2) - height: Math.round(parent.height / 2) - sourceSize.height: height - color: !control.enabled ? UM.Theme.getColor("action_button_disabled_text") : - control.pressed ? UM.Theme.getColor("action_button_active_text") : - control.hovered ? UM.Theme.getColor("action_button_hovered_text") : UM.Theme.getColor("action_button_text") - source: "postprocessing.svg" - } - } - label: Label { } - } + iconSource: "postprocessing.svg" + fixedWidthMode: true } } \ No newline at end of file From 979fd507dee720501422e17045b71c5abc46f467 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 3 Jan 2019 10:39:43 +0100 Subject: [PATCH 1158/1292] Give the section delegates a fixed height This fixes the issue where the first printer would be drawn over the section label CURA-6011 --- resources/qml/PrinterSelector/MachineSelectorList.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/PrinterSelector/MachineSelectorList.qml b/resources/qml/PrinterSelector/MachineSelectorList.qml index 604e0f668d..b9c20d0de1 100644 --- a/resources/qml/PrinterSelector/MachineSelectorList.qml +++ b/resources/qml/PrinterSelector/MachineSelectorList.qml @@ -18,7 +18,7 @@ ListView { text: section == "true" ? catalog.i18nc("@label", "Connected printers") : catalog.i18nc("@label", "Preset printers") width: parent.width - height: visible ? contentHeight + 2 * UM.Theme.getSize("default_margin").height : 0 + height: UM.Theme.getSize("action_button").height leftPadding: UM.Theme.getSize("default_margin").width renderType: Text.NativeRendering font: UM.Theme.getFont("medium") From 707c3a26a88400bc2e0cd781053a0f5a3a3de938 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 3 Jan 2019 11:05:54 +0100 Subject: [PATCH 1159/1292] Make job specs not bold As per the design. Contributes to issue CURA-6025. --- resources/qml/JobSpecs.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/JobSpecs.qml b/resources/qml/JobSpecs.qml index c7f82b8876..144616c22d 100644 --- a/resources/qml/JobSpecs.qml +++ b/resources/qml/JobSpecs.qml @@ -97,7 +97,7 @@ Item style: TextFieldStyle { textColor: UM.Theme.getColor("text_scene") - font: UM.Theme.getFont("default_bold") + font: UM.Theme.getFont("default") background: Rectangle { opacity: 0 @@ -115,7 +115,7 @@ Item height: UM.Theme.getSize("jobspecs_line").height verticalAlignment: Text.AlignVCenter - font: UM.Theme.getFont("default_bold") + font: UM.Theme.getFont("default") color: UM.Theme.getColor("text_scene") text: CuraApplication.getSceneBoundingBoxString } From 136317c3c761e416ddaad78f455fb5c79062ad50 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 3 Jan 2019 11:08:01 +0100 Subject: [PATCH 1160/1292] Fix code styles CURA-6005 --- resources/qml/ActionButton.qml | 7 +++---- resources/qml/CheckBox.qml | 8 +++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index 2448b9a551..9e963f8d3e 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -120,12 +120,11 @@ Button visible: text != "" && button.hovered } - BusyIndicator { + BusyIndicator + { id: busyIndicator - anchors { - centerIn: parent - } + anchors.centerIn: parent width: height height: parent.height diff --git a/resources/qml/CheckBox.qml b/resources/qml/CheckBox.qml index 7a79182a4b..403efb4d7b 100644 --- a/resources/qml/CheckBox.qml +++ b/resources/qml/CheckBox.qml @@ -13,11 +13,12 @@ CheckBox property alias tooltip: tooltip.text - indicator: Rectangle { + indicator: Rectangle + { implicitWidth: UM.Theme.getSize("checkbox").width implicitHeight: UM.Theme.getSize("checkbox").height x: 0 - y: Math.round(parent.height / 2 - height / 2) + anchors.verticalCenter: parent.verticalCenter color: UM.Theme.getColor("main_background") radius: UM.Theme.getSize("checkbox_radius").width border.width: UM.Theme.getSize("default_lining").width @@ -37,7 +38,8 @@ CheckBox } } - contentItem: Label { + contentItem: Label + { anchors { left: checkbox.indicator.right From 56c9de44f741f919214e7d7f563876944f5b9bf4 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 3 Jan 2019 11:09:10 +0100 Subject: [PATCH 1161/1292] Update Cura Backups sdk_version to 6 in bundled json CURA-6005 --- resources/bundled_packages/cura.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/bundled_packages/cura.json b/resources/bundled_packages/cura.json index 896033fb22..2b5750ea8d 100644 --- a/resources/bundled_packages/cura.json +++ b/resources/bundled_packages/cura.json @@ -57,7 +57,7 @@ "display_name": "Cura Backups", "description": "Backup and restore your configuration.", "package_version": "1.2.0", - "sdk_version": 5, + "sdk_version": 6, "website": "https://ultimaker.com", "author": { "author_id": "UltimakerPackages", From a14c846e294acbc169fdca3c5756222ae2088c6a Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 3 Jan 2019 11:53:17 +0100 Subject: [PATCH 1162/1292] Rename CheckBox.qml to CheckBoxWithTooltip.qml CURA-6005 --- plugins/CuraDrive/src/qml/components/BackupListFooter.qml | 2 +- resources/qml/{CheckBox.qml => CheckBoxWithTooltip.qml} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename resources/qml/{CheckBox.qml => CheckBoxWithTooltip.qml} (100%) diff --git a/plugins/CuraDrive/src/qml/components/BackupListFooter.qml b/plugins/CuraDrive/src/qml/components/BackupListFooter.qml index 2a6d82bc74..a0bc212597 100644 --- a/plugins/CuraDrive/src/qml/components/BackupListFooter.qml +++ b/plugins/CuraDrive/src/qml/components/BackupListFooter.qml @@ -35,7 +35,7 @@ RowLayout busy: CuraDrive.isCreatingBackup } - Cura.CheckBox + Cura.CheckBoxWithTooltip { id: autoBackupEnabled checked: CuraDrive.autoBackupEnabled diff --git a/resources/qml/CheckBox.qml b/resources/qml/CheckBoxWithTooltip.qml similarity index 100% rename from resources/qml/CheckBox.qml rename to resources/qml/CheckBoxWithTooltip.qml From 1973397b929dd2e42a051c34fbb4533bf3007f33 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 3 Jan 2019 15:34:41 +0100 Subject: [PATCH 1163/1292] Remove confusing printer preference text CURA-6003 --- .../resources/qml/UM3InfoComponents.qml | 63 --------- .../src/DiscoverUM3Action.py | 1 - resources/qml/Preferences/MachinesPage.qml | 123 +----------------- 3 files changed, 3 insertions(+), 184 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml b/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml index 320201e165..c99ed1688e 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml @@ -90,67 +90,4 @@ Item { source: "DiscoverUM3Action.qml"; } } - - Column { - anchors.fill: parent; - objectName: "networkPrinterConnectionInfo"; - spacing: UM.Theme.getSize("default_margin").width; - visible: isUM3; - - Button { - onClicked: Cura.MachineManager.printerOutputDevices[0].requestAuthentication(); - text: catalog.i18nc("@action:button", "Request Access"); - tooltip: catalog.i18nc("@info:tooltip", "Send access request to the printer"); - visible: printerConnected && !printerAcceptsCommands && !authenticationRequested; - } - - Row { - anchors { - left: parent.left; - right: parent.right; - } - height: childrenRect.height; - spacing: UM.Theme.getSize("default_margin").width; - visible: printerConnected; - - Column { - Repeater { - model: CuraApplication.getExtrudersModel() - - Label { - text: model.name; - } - } - } - - Column { - Repeater { - id: nozzleColumn; - model: hotendIds - - Label { - text: nozzleColumn.model[index]; - } - } - } - - Column { - Repeater { - id: materialColumn; - model: materialNames - - Label { - text: materialColumn.model[index]; - } - } - } - } - - Button { - onClicked: manager.loadConfigurationFromPrinter(); - text: catalog.i18nc("@action:button", "Activate Configuration"); - tooltip: catalog.i18nc("@info:tooltip", "Load the configuration of the printer into Cura"); - visible: false; // printerConnected && !isClusterPrinter() - } - } } diff --git a/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py b/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py index 6ce99e4891..68af2bd575 100644 --- a/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py +++ b/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py @@ -193,4 +193,3 @@ class DiscoverUM3Action(MachineAction): # Create extra components CuraApplication.getInstance().addAdditionalComponent("monitorButtons", self.__additional_components_view.findChild(QObject, "networkPrinterConnectButton")) - CuraApplication.getInstance().addAdditionalComponent("machinesDetailPane", self.__additional_components_view.findChild(QObject, "networkPrinterConnectionInfo")) diff --git a/resources/qml/Preferences/MachinesPage.qml b/resources/qml/Preferences/MachinesPage.qml index d5ecb10658..f9c1a9b0a0 100644 --- a/resources/qml/Preferences/MachinesPage.qml +++ b/resources/qml/Preferences/MachinesPage.qml @@ -126,132 +126,15 @@ UM.ManagementPage } } - Grid - { - id: machineInfo - - anchors.top: machineActions.visible ? machineActions.bottom : machineActions.anchors.top - anchors.topMargin: UM.Theme.getSize("default_margin").height - anchors.left: parent.left - anchors.right: parent.right - spacing: UM.Theme.getSize("default_margin").height - rowSpacing: UM.Theme.getSize("default_lining").height - columns: 2 - - visible: base.currentItem - - property bool printerConnected: Cura.MachineManager.printerConnected - property var connectedPrinter: printerConnected ? Cura.MachineManager.printerOutputDevices[0] : null - property bool printerAcceptsCommands: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands - property var printJob: connectedPrinter != null ? connectedPrinter.activePrintJob: null - Label - { - text: catalog.i18nc("@label", "Printer type:") - visible: base.currentItem && "definition_name" in base.currentItem.metadata - } - Label - { - text: (base.currentItem && "definition_name" in base.currentItem.metadata) ? base.currentItem.metadata.definition_name : "" - } - Label - { - text: catalog.i18nc("@label", "Connection:") - visible: base.currentItem && base.currentItem.id == Cura.MachineManager.activeMachineId - } - Label - { - width: (parent.width * 0.7) | 0 - text: machineInfo.printerConnected ? machineInfo.connectedPrinter.connectionText : catalog.i18nc("@info:status", "The printer is not connected.") - visible: base.currentItem && base.currentItem.id == Cura.MachineManager.activeMachineId - wrapMode: Text.WordWrap - } - Label - { - text: catalog.i18nc("@label", "State:") - visible: base.currentItem && base.currentItem.id == Cura.MachineManager.activeMachineId && machineInfo.printerAcceptsCommands - } - Label { - width: (parent.width * 0.7) | 0 - text: - { - if(!machineInfo.printerConnected || !machineInfo.printerAcceptsCommands) { - return ""; - } - - if (machineInfo.printJob == null) - { - return catalog.i18nc("@label:MonitorStatus", "Waiting for a printjob"); - } - - switch(machineInfo.printJob.state) - { - case "printing": - return catalog.i18nc("@label:MonitorStatus", "Printing..."); - case "paused": - return catalog.i18nc("@label:MonitorStatus", "Paused"); - case "pre_print": - return catalog.i18nc("@label:MonitorStatus", "Preparing..."); - case "wait_cleanup": - return catalog.i18nc("@label:MonitorStatus", "Waiting for someone to clear the build plate"); - case "error": - return printerOutputDevice.errorText; - case "maintenance": - return catalog.i18nc("@label:MonitorStatus", "In maintenance. Please check the printer"); - case "abort": // note sure if this jobState actually occurs in the wild - return catalog.i18nc("@label:MonitorStatus", "Aborting print..."); - - } - return "" - } - visible: base.currentItem && base.currentItem.id == Cura.MachineManager.activeMachineId && machineInfo.printerAcceptsCommands - wrapMode: Text.WordWrap - } - } - - Column { - id: additionalComponentsColumn - anchors.left: parent.left - anchors.right: parent.right - anchors.top: machineInfo.visible ? machineInfo.bottom : machineInfo.anchors.top - anchors.topMargin: UM.Theme.getSize("default_margin").width - - spacing: UM.Theme.getSize("default_margin").width - visible: base.currentItem && base.currentItem.id == Cura.MachineManager.activeMachineId - - Component.onCompleted: - { - for (var component in CuraApplication.additionalComponents["machinesDetailPane"]) { - CuraApplication.additionalComponents["machinesDetailPane"][component].parent = additionalComponentsColumn - } - } - } - - Component.onCompleted: { - addAdditionalComponents("machinesDetailPane") - } - - Connections { - target: CuraApplication - onAdditionalComponentsChanged: addAdditionalComponents - } - - function addAdditionalComponents (areaId) { - if(areaId == "machinesDetailPane") { - for (var component in CuraApplication.additionalComponents["machinesDetailPane"]) { - CuraApplication.additionalComponents["machinesDetailPane"][component].parent = additionalComponentsColumn - } - } - } - UM.I18nCatalog { id: catalog; name: "cura"; } UM.ConfirmRemoveDialog { - id: confirmDialog; - object: base.currentItem && base.currentItem.name ? base.currentItem.name : ""; + id: confirmDialog + object: base.currentItem && base.currentItem.name ? base.currentItem.name : "" onYes: { - Cura.MachineManager.removeMachine(base.currentItem.id); + Cura.MachineManager.removeMachine(base.currentItem.id) if(!base.currentItem) { objectList.currentIndex = activeMachineIndex() From 6eca0ce69f906457a0760d4e8ae9c01c0c57e449 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 3 Jan 2019 11:52:03 +0100 Subject: [PATCH 1164/1292] Use native rendering for text fields Hopefully this fixes the font rendering issue we're seeing on MacOS now. --- resources/themes/cura-light/styles.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index 4361c3ae2b..b314190e24 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -585,6 +585,7 @@ QtObject text: control.unit ? control.unit : "" color: Theme.getColor("setting_unit"); font: Theme.getFont("default"); + renderType: Text.NativeRendering } } } From 798c1f198c48c0f3f590bca64f254c776befc0da Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 3 Jan 2019 16:02:49 +0100 Subject: [PATCH 1165/1292] Hide action panel when displaying a stage with a background This is not the worst hack ever, but it's quite a hack. Contributes to issue CURA-6054. --- plugins/MonitorStage/MonitorMain.qml | 41 +++++++++++++--------------- resources/qml/Cura.qml | 33 +++++++++++++++++++++- 2 files changed, 51 insertions(+), 23 deletions(-) diff --git a/plugins/MonitorStage/MonitorMain.qml b/plugins/MonitorStage/MonitorMain.qml index 34cf4ad801..5fda32db9e 100644 --- a/plugins/MonitorStage/MonitorMain.qml +++ b/plugins/MonitorStage/MonitorMain.qml @@ -1,4 +1,5 @@ -// 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.10 import QtQuick.Controls 1.4 @@ -7,31 +8,27 @@ import UM 1.3 as UM import Cura 1.0 as Cura -Item +// We show a nice overlay on the 3D viewer when the current output device has no monitor view +Rectangle { - // We show a nice overlay on the 3D viewer when the current output device has no monitor view - Rectangle + id: viewportOverlay + + color: UM.Theme.getColor("viewport_overlay") + anchors.fill: parent + + // This mouse area is to prevent mouse clicks to be passed onto the scene. + MouseArea { - id: viewportOverlay - - color: UM.Theme.getColor("viewport_overlay") anchors.fill: parent - - // This mouse area is to prevent mouse clicks to be passed onto the scene. - MouseArea - { - anchors.fill: parent - acceptedButtons: Qt.AllButtons - onWheel: wheel.accepted = true - } - - // Disable dropping files into Cura when the monitor page is active - DropArea - { - anchors.fill: parent - } + acceptedButtons: Qt.AllButtons + onWheel: wheel.accepted = true } + // Disable dropping files into Cura when the monitor page is active + DropArea + { + anchors.fill: parent + } Loader { id: monitorViewComponent @@ -45,4 +42,4 @@ Item sourceComponent: Cura.MachineManager.printerOutputDevices.length > 0 ? Cura.MachineManager.printerOutputDevices[0].monitorItem : null } -} +} \ No newline at end of file diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 8a34c7e219..a78295e7fa 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -252,7 +252,21 @@ UM.MainWindow anchors.bottom: parent.bottom anchors.rightMargin: UM.Theme.getSize("thick_margin").width anchors.bottomMargin: UM.Theme.getSize("thick_margin").height - visible: CuraApplication.platformActivity + + /* + Show this panel only if there is something on the build plate, and there is NOT an opaque item in front of the build plate. + This cannot be solved by Z indexing! If you want to try solving this, please increase this counter when you're done: + Number of people having tried to fix this by z-indexing: 2 + The problem arises from the following render order requirements: + - The stage menu must be rendered above the stage main. + - The stage main must be rendered above the action panel (because the monitor page must be rendered above the action panel). + - The action panel must be rendered above the expandable components drop-down. + However since the expandable components drop-downs are child elements of the stage menu, + they can't be rendered lower than elements that are lower than the stage menu. + Therefore we opted to forego the second requirement and hide the action panel instead when something obscures it (except the expandable components). + We assume that QQuickRectangles are always opaque and any other item is not. + */ + visible: CuraApplication.platformActivity && (main.item == null || !qmlTypeOf(main.item, "QQuickRectangle")) } Loader @@ -818,4 +832,21 @@ UM.MainWindow } } } + + /** + * Function to check whether a QML object has a certain type. + * Taken from StackOverflow: https://stackoverflow.com/a/28384228 and + * adapted to our code style. + * Licensed under CC BY-SA 3.0. + * \param obj The QtObject to get the name of. + * \param class_name (str) The name of the class to check against. Has to be + * the QtObject class name, not the QML entity name. + */ + function qmlTypeOf(obj, class_name) + { + //className plus "(" is the class instance without modification. + //className plus "_QML" is the class instance with user-defined properties. + var str = obj.toString(); + return str.indexOf(class_name + "(") == 0 || str.indexOf(class_name + "_QML") == 0; + } } From e15e06f29f2d18c6629d66f0f3196d0279ae1db0 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 3 Jan 2019 16:04:17 +0100 Subject: [PATCH 1166/1292] Make Z relative This way if we ever want to change the parent's Z for some other ordering requirements, the children will stay in order. --- plugins/Toolbox/resources/qml/Toolbox.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Toolbox/resources/qml/Toolbox.qml b/plugins/Toolbox/resources/qml/Toolbox.qml index 9ede2a6bda..d15d98eed7 100644 --- a/plugins/Toolbox/resources/qml/Toolbox.qml +++ b/plugins/Toolbox/resources/qml/Toolbox.qml @@ -38,7 +38,7 @@ Window { id: mainView width: parent.width - z: -1 + z: parent.z - 1 anchors { top: header.bottom From f1d01e733da25cd430b647140d52ef22de2352e6 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Thu, 3 Jan 2019 16:34:05 +0100 Subject: [PATCH 1167/1292] Add variant to the configuration menu headerItem --- .../ConfigurationMenu/ConfigurationMenu.qml | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index 3001efac54..35b3770af9 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -61,6 +61,27 @@ Cura.ExpandablePopup width: height } + // Label that shows the name of the variant + Label + { + id: variantLabel + + visible: Cura.MachineManager.hasVariants + + text: model.variant + elide: Text.ElideRight + font: UM.Theme.getFont("medium") + color: UM.Theme.getColor("text") + renderType: Text.NativeRendering + + anchors + { + left: extruderIcon.right + leftMargin: UM.Theme.getSize("default_margin").width + verticalCenter: parent.verticalCenter + } + } + // Label for the brand of the material Label { @@ -74,7 +95,7 @@ Cura.ExpandablePopup anchors { - left: extruderIcon.right + left: variantLabel.visible ? variantLabel.right : extruderIcon.right leftMargin: UM.Theme.getSize("default_margin").width right: parent.right rightMargin: UM.Theme.getSize("default_margin").width @@ -92,7 +113,7 @@ Cura.ExpandablePopup anchors { - left: extruderIcon.right + left: variantLabel.visible ? variantLabel.right : extruderIcon.right leftMargin: UM.Theme.getSize("default_margin").width right: parent.right rightMargin: UM.Theme.getSize("default_margin").width From 65183ade0a53deceac8c00413e656aec79e12628 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 3 Jan 2019 16:44:08 +0100 Subject: [PATCH 1168/1292] No longer chache singleton objects CURA-6005 --- plugins/CuraDrive/__init__.py | 2 +- plugins/CuraDrive/src/DriveApiService.py | 11 ++++------- plugins/CuraDrive/src/DrivePluginExtension.py | 18 ++++++++---------- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/plugins/CuraDrive/__init__.py b/plugins/CuraDrive/__init__.py index 766d94752f..dd7ffeaac3 100644 --- a/plugins/CuraDrive/__init__.py +++ b/plugins/CuraDrive/__init__.py @@ -7,4 +7,4 @@ def getMetaData(): return {} def register(app): - return {"extension": DrivePluginExtension(app)} + return {"extension": DrivePluginExtension()} diff --git a/plugins/CuraDrive/src/DriveApiService.py b/plugins/CuraDrive/src/DriveApiService.py index a542ac439e..3b6641cd74 100644 --- a/plugins/CuraDrive/src/DriveApiService.py +++ b/plugins/CuraDrive/src/DriveApiService.py @@ -12,16 +12,14 @@ import requests from UM.Logger import Logger from UM.Message import Message from UM.Signal import Signal +from cura.CuraApplication import CuraApplication from .UploadBackupJob import UploadBackupJob from .Settings import Settings +## The DriveApiService is responsible for interacting with the CuraDrive API and Cura's backup handling. class DriveApiService: - """ - The DriveApiService is responsible for interacting with the CuraDrive API and Cura's backup handling. - """ - GET_BACKUPS_URL = "{}/backups".format(Settings.DRIVE_API_URL) PUT_BACKUP_URL = "{}/backups".format(Settings.DRIVE_API_URL) DELETE_BACKUP_URL = "{}/backups".format(Settings.DRIVE_API_URL) @@ -32,9 +30,8 @@ class DriveApiService: # Emit signal when creating backup started or finished. onCreatingStateChanged = Signal() - def __init__(self, cura_api) -> None: - """Create a new instance of the Drive API service and set the cura_api object.""" - self._cura_api = cura_api + def __init__(self) -> None: + self._cura_api = CuraApplication.getInstance().getCuraAPI() def getBackups(self) -> List[Dict[str, Any]]: """Get all backups from the API.""" diff --git a/plugins/CuraDrive/src/DrivePluginExtension.py b/plugins/CuraDrive/src/DrivePluginExtension.py index a76c623fe8..bed54140d9 100644 --- a/plugins/CuraDrive/src/DrivePluginExtension.py +++ b/plugins/CuraDrive/src/DrivePluginExtension.py @@ -7,8 +7,10 @@ from typing import Optional from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal +from UM.Application import Application from UM.Extension import Extension from UM.Message import Message +from cura.CuraApplication import CuraApplication from .Settings import Settings from .DriveApiService import DriveApiService @@ -34,11 +36,8 @@ class DrivePluginExtension(QObject, Extension): DATE_FORMAT = "%d/%m/%Y %H:%M:%S" - def __init__(self, application): + def __init__(self): super(DrivePluginExtension, self).__init__() - - # Re-usable instance of application. - self._application = application # Local data caching for the UI. self._drive_window = None # type: Optional[QObject] @@ -47,12 +46,11 @@ class DrivePluginExtension(QObject, Extension): self._is_creating_backup = False # Initialize services. - self._preferences = self._application.getPreferences() - self._cura_api = self._application.getCuraAPI() - self._drive_api_service = DriveApiService(self._cura_api) + self._preferences = CuraApplication.getInstance().getPreferences() + self._drive_api_service = DriveApiService() # Attach signals. - self._cura_api.account.loginStateChanged.connect(self._onLoginStateChanged) + CuraApplication.getInstance().getCuraAPI().account.loginStateChanged.connect(self._onLoginStateChanged) self._drive_api_service.onRestoringStateChanged.connect(self._onRestoringStateChanged) self._drive_api_service.onCreatingStateChanged.connect(self._onCreatingStateChanged) @@ -65,7 +63,7 @@ class DrivePluginExtension(QObject, Extension): self._updateMenuItems() # Make auto-backup on boot if required. - self._application.engineCreatedSignal.connect(self._autoBackup) + CuraApplication.getInstance().engineCreatedSignal.connect(self._autoBackup) def showDriveWindow(self) -> None: """Show the Drive UI popup window.""" @@ -81,7 +79,7 @@ class DrivePluginExtension(QObject, Extension): :return: The popup window object. """ path = os.path.join(os.path.dirname(__file__), "qml", "main.qml") - return self._application.createQmlComponent(path, {"CuraDrive": self}) + return CuraApplication.getInstance().createQmlComponent(path, {"CuraDrive": self}) def _updateMenuItems(self) -> None: """Update the menu items.""" From ea1712df0f120985fb62fb474a698320b4da6726 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 3 Jan 2019 16:51:11 +0100 Subject: [PATCH 1169/1292] Codestyle fixes & simplifications CURA-6005 --- plugins/CuraDrive/src/DrivePluginExtension.py | 64 ++++--------------- 1 file changed, 11 insertions(+), 53 deletions(-) diff --git a/plugins/CuraDrive/src/DrivePluginExtension.py b/plugins/CuraDrive/src/DrivePluginExtension.py index bed54140d9..cd8274f83a 100644 --- a/plugins/CuraDrive/src/DrivePluginExtension.py +++ b/plugins/CuraDrive/src/DrivePluginExtension.py @@ -16,6 +16,9 @@ from .Settings import Settings from .DriveApiService import DriveApiService from .models.BackupListModel import BackupListModel +from UM.i18n import i18nCatalog +catalog = i18nCatalog("cura") + class DrivePluginExtension(QObject, Extension): """ @@ -37,7 +40,8 @@ class DrivePluginExtension(QObject, Extension): DATE_FORMAT = "%d/%m/%Y %H:%M:%S" def __init__(self): - super(DrivePluginExtension, self).__init__() + QObject.__init__(self, None) + Extension.__init__(self) # Local data caching for the UI. self._drive_window = None # type: Optional[QObject] @@ -59,8 +63,8 @@ class DrivePluginExtension(QObject, Extension): self._preferences.addPreference(Settings.AUTO_BACKUP_LAST_DATE_PREFERENCE_KEY, datetime.now() .strftime(self.DATE_FORMAT)) - # Register menu items. - self._updateMenuItems() + # Register the menu item + self.addMenuItem(catalog.i18nc("@item:inmenu", "Manage backups"), self.showDriveWindow) # Make auto-backup on boot if required. CuraApplication.getInstance().engineCreatedSignal.connect(self._autoBackup) @@ -68,59 +72,41 @@ class DrivePluginExtension(QObject, Extension): def showDriveWindow(self) -> None: """Show the Drive UI popup window.""" if not self._drive_window: - self._drive_window = self.createDriveWindow() + path = os.path.join(os.path.dirname(__file__), "qml", "main.qml") + self._drive_window = CuraApplication.getInstance().createQmlComponent(path, {"CuraDrive": self}) self.refreshBackups() if self._drive_window: self._drive_window.show() - def createDriveWindow(self) -> Optional["QObject"]: - """ - Create an instance of the Drive UI popup window. - :return: The popup window object. - """ - path = os.path.join(os.path.dirname(__file__), "qml", "main.qml") - return CuraApplication.getInstance().createQmlComponent(path, {"CuraDrive": self}) - - def _updateMenuItems(self) -> None: - """Update the menu items.""" - self.addMenuItem(Settings.translatable_messages["extension_menu_entry"], self.showDriveWindow) - def _autoBackup(self) -> None: - """Automatically make a backup on boot if enabled.""" - if self._preferences.getValue(Settings.AUTO_BACKUP_ENABLED_PREFERENCE_KEY) and self._lastBackupTooLongAgo(): + if self._preferences.getValue(Settings.AUTO_BACKUP_ENABLED_PREFERENCE_KEY) and self._isLastBackupTooLongAgo(): self.createBackup() - def _lastBackupTooLongAgo(self) -> bool: - """Check if the last backup was longer than 1 day ago.""" + def _isLastBackupTooLongAgo(self) -> bool: current_date = datetime.now() last_backup_date = self._getLastBackupDate() date_diff = current_date - last_backup_date return date_diff.days > 1 def _getLastBackupDate(self) -> "datetime": - """Get the last backup date as datetime object.""" last_backup_date = self._preferences.getValue(Settings.AUTO_BACKUP_LAST_DATE_PREFERENCE_KEY) return datetime.strptime(last_backup_date, self.DATE_FORMAT) def _storeBackupDate(self) -> None: - """Store the current date as last backup date.""" backup_date = datetime.now().strftime(self.DATE_FORMAT) self._preferences.setValue(Settings.AUTO_BACKUP_LAST_DATE_PREFERENCE_KEY, backup_date) def _onLoginStateChanged(self, logged_in: bool = False) -> None: - """Callback handler for changes in the login state.""" if logged_in: self.refreshBackups() def _onRestoringStateChanged(self, is_restoring: bool = False, error_message: str = None) -> None: - """Callback handler for changes in the restoring state.""" self._is_restoring_backup = is_restoring self.restoringStateChanged.emit() if error_message: Message(error_message, title = Settings.MESSAGE_TITLE, lifetime = 5).show() def _onCreatingStateChanged(self, is_creating: bool = False, error_message: str = None) -> None: - """Callback handler for changes in the creation state.""" self._is_creating_backup = is_creating self.creatingStateChanged.emit() if error_message: @@ -133,69 +119,41 @@ class DrivePluginExtension(QObject, Extension): @pyqtSlot(bool, name = "toggleAutoBackup") def toggleAutoBackup(self, enabled: bool) -> None: - """Enable or disable the auto-backup feature.""" self._preferences.setValue(Settings.AUTO_BACKUP_ENABLED_PREFERENCE_KEY, enabled) self.preferencesChanged.emit() @pyqtProperty(bool, notify = preferencesChanged) def autoBackupEnabled(self) -> bool: - """Check if auto-backup is enabled or not.""" return bool(self._preferences.getValue(Settings.AUTO_BACKUP_ENABLED_PREFERENCE_KEY)) @pyqtProperty(QObject, notify = backupsChanged) def backups(self) -> BackupListModel: - """ - Get a list of the backups. - :return: The backups as Qt List Model. - """ return self._backups_list_model @pyqtSlot(name = "refreshBackups") def refreshBackups(self) -> None: - """ - Forcefully refresh the backups list. - """ self._backups_list_model.loadBackups(self._drive_api_service.getBackups()) self.backupsChanged.emit() @pyqtProperty(bool, notify = restoringStateChanged) def isRestoringBackup(self) -> bool: - """ - Get the current restoring state. - :return: Boolean if we are restoring or not. - """ return self._is_restoring_backup @pyqtProperty(bool, notify = creatingStateChanged) def isCreatingBackup(self) -> bool: - """ - Get the current creating state. - :return: Boolean if we are creating or not. - """ return self._is_creating_backup @pyqtSlot(str, name = "restoreBackup") def restoreBackup(self, backup_id: str) -> None: - """ - Download and restore a backup by ID. - :param backup_id: The ID of the backup. - """ index = self._backups_list_model.find("backup_id", backup_id) backup = self._backups_list_model.getItem(index) self._drive_api_service.restoreBackup(backup) @pyqtSlot(name = "createBackup") def createBackup(self) -> None: - """ - Create a new backup. - """ self._drive_api_service.createBackup() @pyqtSlot(str, name = "deleteBackup") def deleteBackup(self, backup_id: str) -> None: - """ - Delete a backup by ID. - :param backup_id: The ID of the backup. - """ self._drive_api_service.deleteBackup(backup_id) self.refreshBackups() From 4d1e9d24f98d3c12e8f91f02d416ab1ddb8287b7 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 3 Jan 2019 16:58:51 +0100 Subject: [PATCH 1170/1292] Cleanup documentation Either fix the style to doxygen or remove it if it just repeated the functionnname. CURA-6005 --- plugins/CuraDrive/src/DriveApiService.py | 43 +++++++----------------- 1 file changed, 13 insertions(+), 30 deletions(-) diff --git a/plugins/CuraDrive/src/DriveApiService.py b/plugins/CuraDrive/src/DriveApiService.py index 3b6641cd74..39045d1317 100644 --- a/plugins/CuraDrive/src/DriveApiService.py +++ b/plugins/CuraDrive/src/DriveApiService.py @@ -34,7 +34,6 @@ class DriveApiService: self._cura_api = CuraApplication.getInstance().getCuraAPI() def getBackups(self) -> List[Dict[str, Any]]: - """Get all backups from the API.""" access_token = self._cura_api.account.accessToken if not access_token: Logger.log("w", "Could not get access token.") @@ -43,6 +42,7 @@ class DriveApiService: backup_list_request = requests.get(self.GET_BACKUPS_URL, headers = { "Authorization": "Bearer {}".format(access_token) }) + if backup_list_request.status_code > 299: Logger.log("w", "Could not get backups list from remote: %s", backup_list_request.text) Message(Settings.translatable_messages["get_backups_error"], title = Settings.MESSAGE_TITLE, @@ -51,7 +51,6 @@ class DriveApiService: return backup_list_request.json()["data"] def createBackup(self) -> None: - """Create a backup and upload it to CuraDrive cloud storage.""" self.onCreatingStateChanged.emit(is_creating = True) # Create the backup. @@ -74,10 +73,6 @@ class DriveApiService: upload_backup_job.start() def _onUploadFinished(self, job: "UploadBackupJob") -> None: - """ - Callback handler for the upload job. - :param job: The executed job. - """ if job.backup_upload_error_message != "": # If the job contains an error message we pass it along so the UI can display it. self.onCreatingStateChanged.emit(is_creating = False, error_message = job.backup_upload_error_message) @@ -85,10 +80,6 @@ class DriveApiService: self.onCreatingStateChanged.emit(is_creating = False) def restoreBackup(self, backup: Dict[str, Any]) -> None: - """ - Restore a previously exported backup from cloud storage. - :param backup: A dict containing an entry from the API list response. - """ self.onRestoringStateChanged.emit(is_restoring = True) download_url = backup.get("download_url") if not download_url: @@ -119,30 +110,22 @@ class DriveApiService: self.onRestoringStateChanged.emit(is_restoring = False) def _emitRestoreError(self, error_message: str = Settings.translatable_messages["backup_restore_error_message"]): - """Helper method for emitting a signal when restoring failed.""" self.onRestoringStateChanged.emit( is_restoring = False, error_message = error_message ) + # Verify the MD5 hash of a file. + # \param file_path Full path to the file. + # \param known_hash The known MD5 hash of the file. + # \return: Success or not. @staticmethod def _verifyMd5Hash(file_path: str, known_hash: str) -> bool: - """ - Verify the MD5 hash of a file. - :param file_path: Full path to the file. - :param known_hash: The known MD5 hash of the file. - :return: Success or not. - """ with open(file_path, "rb") as read_backup: local_md5_hash = base64.b64encode(hashlib.md5(read_backup.read()).digest(), altchars = b"_-").decode("utf-8") return known_hash == local_md5_hash def deleteBackup(self, backup_id: str) -> bool: - """ - Delete a backup from the server by ID. - :param backup_id: The ID of the backup to delete. - :return: Success bool. - """ access_token = self._cura_api.account.accessToken if not access_token: Logger.log("w", "Could not get access token.") @@ -156,13 +139,12 @@ class DriveApiService: return False return True + # Request a backup upload slot from the API. + # \param backup_metadata: A dict containing some meta data about the backup. + # \param backup_size The size of the backup file in bytes. + # \return: The upload URL for the actual backup file if successful, otherwise None. def _requestBackupUpload(self, backup_metadata: Dict[str, Any], backup_size: int) -> Optional[str]: - """ - Request a backup upload slot from the API. - :param backup_metadata: A dict containing some meta data about the backup. - :param backup_size: The size of the backup file in bytes. - :return: The upload URL for the actual backup file if successful, otherwise None. - """ + access_token = self._cura_api.account.accessToken if not access_token: Logger.log("w", "Could not get access token.") @@ -176,8 +158,9 @@ class DriveApiService: }, headers = { "Authorization": "Bearer {}".format(access_token) }) - - if backup_upload_request.status_code > 299: + + # Any status code of 300 or above indicates an error. + if backup_upload_request.status_code >= 300: Logger.log("w", "Could not request backup upload: %s", backup_upload_request.text) return None From ed9a51791b9ed83c517dc5d1ba26b489905078ec Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 3 Jan 2019 17:05:58 +0100 Subject: [PATCH 1171/1292] Handle bunch of review comments CURA-6005 --- plugins/CuraDrive/src/DriveApiService.py | 23 ++++++++++++----------- plugins/CuraDrive/src/Settings.py | 2 +- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/plugins/CuraDrive/src/DriveApiService.py b/plugins/CuraDrive/src/DriveApiService.py index 39045d1317..f74f30bcda 100644 --- a/plugins/CuraDrive/src/DriveApiService.py +++ b/plugins/CuraDrive/src/DriveApiService.py @@ -17,6 +17,9 @@ from cura.CuraApplication import CuraApplication from .UploadBackupJob import UploadBackupJob from .Settings import Settings +from UM.i18n import i18nCatalog +catalog = i18nCatalog("cura") + ## The DriveApiService is responsible for interacting with the CuraDrive API and Cura's backup handling. class DriveApiService: @@ -42,11 +45,10 @@ class DriveApiService: backup_list_request = requests.get(self.GET_BACKUPS_URL, headers = { "Authorization": "Bearer {}".format(access_token) }) - - if backup_list_request.status_code > 299: + + if backup_list_request.status_code >= 300: Logger.log("w", "Could not get backups list from remote: %s", backup_list_request.text) - Message(Settings.translatable_messages["get_backups_error"], title = Settings.MESSAGE_TITLE, - lifetime = 10).show() + Message(catalog.i18nc("@info:backup_status", "There was an error listing your backups."), title = Settings.MESSAGE_TITLE).show() return [] return backup_list_request.json()["data"] @@ -87,7 +89,7 @@ class DriveApiService: return self._emitRestoreError() download_package = requests.get(download_url, stream = True) - if download_package.status_code != 200: + if download_package.status_code >= 300: # Something went wrong when attempting to download the backup. Logger.log("w", "Could not download backup from url %s: %s", download_url, download_package.text) return self._emitRestoreError() @@ -109,11 +111,10 @@ class DriveApiService: self._cura_api.backups.restoreBackup(read_backup.read(), backup.get("data")) self.onRestoringStateChanged.emit(is_restoring = False) - def _emitRestoreError(self, error_message: str = Settings.translatable_messages["backup_restore_error_message"]): - self.onRestoringStateChanged.emit( - is_restoring = False, - error_message = error_message - ) + def _emitRestoreError(self): + self.onRestoringStateChanged.emit(is_restoring = False, + error_message = catalog.i18nc("@info:backup_status", + "There was an error trying to restore your backup.")) # Verify the MD5 hash of a file. # \param file_path Full path to the file. @@ -134,7 +135,7 @@ class DriveApiService: delete_backup = requests.delete("{}/{}".format(self.DELETE_BACKUP_URL, backup_id), headers = { "Authorization": "Bearer {}".format(access_token) }) - if delete_backup.status_code > 299: + if delete_backup.status_code >= 300: Logger.log("w", "Could not delete backup: %s", delete_backup.text) return False return True diff --git a/plugins/CuraDrive/src/Settings.py b/plugins/CuraDrive/src/Settings.py index 04ace8af95..10d1ba4397 100644 --- a/plugins/CuraDrive/src/Settings.py +++ b/plugins/CuraDrive/src/Settings.py @@ -19,7 +19,7 @@ class Settings: I18N_CATALOG_ID = "cura" I18N_CATALOG = i18nCatalog(I18N_CATALOG_ID) - MESSAGE_TITLE = I18N_CATALOG.i18nc("@info:title", "Backups"), + MESSAGE_TITLE = I18N_CATALOG.i18nc("@info:title", "Backups") # Translatable messages for the entire plugin. translatable_messages = { From cfdce25a6214c2d4e56183869c05973fe8aaaf54 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 3 Jan 2019 17:06:17 +0100 Subject: [PATCH 1172/1292] Add grip lines to bottom of resizable panel Looks all right now. Contributes to issue CURA-6054. --- .../PrintSetupSelectorContents.qml | 18 ++++++++++++++++++ .../themes/cura-light/icons/grip_lines.svg | 4 ++++ 2 files changed, 22 insertions(+) create mode 100644 resources/themes/cura-light/icons/grip_lines.svg diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml index 35c5f008b6..77b6cd9b63 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml @@ -176,6 +176,24 @@ Item UM.Preferences.setValue("view/settings_list_height", h); } } + + UM.RecolorImage + { + width: parent.width * 0.05 + sourceSize.height: height + sourceSize.width: width + anchors + { + horizontalCenter: parent.horizontalCenter + top: parent.top + topMargin: UM.Theme.getSize("thick_lining").height + bottom: parent.bottom + bottomMargin: UM.Theme.getSize("thick_lining").height + } + + source: UM.Theme.getIcon("grip_lines") + color: UM.Theme.getColor("lining") + } } } } \ No newline at end of file diff --git a/resources/themes/cura-light/icons/grip_lines.svg b/resources/themes/cura-light/icons/grip_lines.svg new file mode 100644 index 0000000000..253d1fb486 --- /dev/null +++ b/resources/themes/cura-light/icons/grip_lines.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file From e36b3e37d1b680b89f2beb2b4af4bd2cdab233ec Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 3 Jan 2019 17:13:47 +0100 Subject: [PATCH 1173/1292] Remove indirection in the translation CURA-6005 --- plugins/CuraDrive/src/Settings.py | 22 ++-------------------- plugins/CuraDrive/src/UploadBackupJob.py | 14 +++++++------- 2 files changed, 9 insertions(+), 27 deletions(-) diff --git a/plugins/CuraDrive/src/Settings.py b/plugins/CuraDrive/src/Settings.py index 10d1ba4397..fcb05b8c04 100644 --- a/plugins/CuraDrive/src/Settings.py +++ b/plugins/CuraDrive/src/Settings.py @@ -16,24 +16,6 @@ class Settings: AUTO_BACKUP_ENABLED_PREFERENCE_KEY = "cura_drive/auto_backup_enabled" AUTO_BACKUP_LAST_DATE_PREFERENCE_KEY = "cura_drive/auto_backup_date" - I18N_CATALOG_ID = "cura" - I18N_CATALOG = i18nCatalog(I18N_CATALOG_ID) + I18N_CATALOG = i18nCatalog("cura") - MESSAGE_TITLE = I18N_CATALOG.i18nc("@info:title", "Backups") - - # Translatable messages for the entire plugin. - translatable_messages = { - - # Menu items. - "extension_menu_entry": I18N_CATALOG.i18nc("@item:inmenu", "Manage backups"), - - # Notification messages. - "backup_failed": I18N_CATALOG.i18nc("@info:backup_status", "There was an error while creating your backup."), - "uploading_backup": I18N_CATALOG.i18nc("@info:backup_status", "Uploading your backup..."), - "uploading_backup_success": I18N_CATALOG.i18nc("@info:backup_status", "Your backup has finished uploading."), - "uploading_backup_error": I18N_CATALOG.i18nc("@info:backup_status", - "There was an error while uploading your backup."), - "get_backups_error": I18N_CATALOG.i18nc("@info:backup_status", "There was an error listing your backups."), - "backup_restore_error_message": I18N_CATALOG.i18nc("@info:backup_status", - "There was an error trying to restore your backup.") - } + MESSAGE_TITLE = I18N_CATALOG.i18nc("@info:title", "Backups") \ No newline at end of file diff --git a/plugins/CuraDrive/src/UploadBackupJob.py b/plugins/CuraDrive/src/UploadBackupJob.py index ae6cb13f2e..bdcc8dd8a6 100644 --- a/plugins/CuraDrive/src/UploadBackupJob.py +++ b/plugins/CuraDrive/src/UploadBackupJob.py @@ -8,14 +8,17 @@ from UM.Logger import Logger from UM.Message import Message from .Settings import Settings +from UM.i18n import i18nCatalog +catalog = i18nCatalog("cura") class UploadBackupJob(Job): + MESSAGE_TITLE = catalog.i18nc("@info:title", "Backups") + """ This job is responsible for uploading the backup file to cloud storage. As it can take longer than some other tasks, we schedule this using a Cura Job. """ - def __init__(self, signed_upload_url: str, backup_zip: bytes) -> None: super().__init__() self._signed_upload_url = signed_upload_url @@ -24,18 +27,15 @@ class UploadBackupJob(Job): self.backup_upload_error_message = "" def run(self) -> None: - Message(Settings.translatable_messages["uploading_backup"], title = Settings.MESSAGE_TITLE, - lifetime = 10).show() + Message(catalog.i18nc("@info:backup_status", "Uploading your backup..."), title = self.MESSAGE_TITLE).show() backup_upload = requests.put(self._signed_upload_url, data = self._backup_zip) if backup_upload.status_code not in (200, 201): self.backup_upload_error_message = backup_upload.text Logger.log("w", "Could not upload backup file: %s", backup_upload.text) - Message(Settings.translatable_messages["uploading_backup_error"], title = Settings.MESSAGE_TITLE, - lifetime = 10).show() + Message(catalog.i18nc("@info:backup_status", "There was an error while uploading your backup."), title = self.MESSAGE_TITLE).show() else: self._upload_success = True - Message(Settings.translatable_messages["uploading_backup_success"], title = Settings.MESSAGE_TITLE, - lifetime = 10).show() + Message(catalog.i18nc("@info:backup_status", "Your backup has finished uploading."), title = self.MESSAGE_TITLE).show() self.finished.emit(self) From 83fbb78c9ee4437d736696e5e74a9a747daabcad Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 3 Jan 2019 17:15:32 +0100 Subject: [PATCH 1174/1292] Backup uploading now shows a intermediate progress bar and hides when done CURA-6005 --- plugins/CuraDrive/src/UploadBackupJob.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/CuraDrive/src/UploadBackupJob.py b/plugins/CuraDrive/src/UploadBackupJob.py index bdcc8dd8a6..d9532a96f0 100644 --- a/plugins/CuraDrive/src/UploadBackupJob.py +++ b/plugins/CuraDrive/src/UploadBackupJob.py @@ -27,9 +27,12 @@ class UploadBackupJob(Job): self.backup_upload_error_message = "" def run(self) -> None: - Message(catalog.i18nc("@info:backup_status", "Uploading your backup..."), title = self.MESSAGE_TITLE).show() + upload_message = Message(catalog.i18nc("@info:backup_status", "Uploading your backup..."), title = self.MESSAGE_TITLE, progress = -1) + upload_message.show() backup_upload = requests.put(self._signed_upload_url, data = self._backup_zip) + upload_message.hide() + if backup_upload.status_code not in (200, 201): self.backup_upload_error_message = backup_upload.text Logger.log("w", "Could not upload backup file: %s", backup_upload.text) From 1578aaa301876cce04dfb6f7fc0c5c936fdad56a Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 3 Jan 2019 17:17:40 +0100 Subject: [PATCH 1175/1292] Minor code cleanup CURA-6005 --- plugins/CuraDrive/src/UploadBackupJob.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/plugins/CuraDrive/src/UploadBackupJob.py b/plugins/CuraDrive/src/UploadBackupJob.py index d9532a96f0..2e76ed9b4b 100644 --- a/plugins/CuraDrive/src/UploadBackupJob.py +++ b/plugins/CuraDrive/src/UploadBackupJob.py @@ -7,7 +7,6 @@ from UM.Job import Job from UM.Logger import Logger from UM.Message import Message -from .Settings import Settings from UM.i18n import i18nCatalog catalog = i18nCatalog("cura") @@ -15,10 +14,8 @@ catalog = i18nCatalog("cura") class UploadBackupJob(Job): MESSAGE_TITLE = catalog.i18nc("@info:title", "Backups") - """ - This job is responsible for uploading the backup file to cloud storage. - As it can take longer than some other tasks, we schedule this using a Cura Job. - """ + # This job is responsible for uploading the backup file to cloud storage. + # As it can take longer than some other tasks, we schedule this using a Cura Job. def __init__(self, signed_upload_url: str, backup_zip: bytes) -> None: super().__init__() self._signed_upload_url = signed_upload_url @@ -33,7 +30,7 @@ class UploadBackupJob(Job): backup_upload = requests.put(self._signed_upload_url, data = self._backup_zip) upload_message.hide() - if backup_upload.status_code not in (200, 201): + if backup_upload.status_code >= 300: self.backup_upload_error_message = backup_upload.text Logger.log("w", "Could not upload backup file: %s", backup_upload.text) Message(catalog.i18nc("@info:backup_status", "There was an error while uploading your backup."), title = self.MESSAGE_TITLE).show() From efac7c39c05e441c59b583a866d9623abc961dd8 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 3 Jan 2019 17:22:22 +0100 Subject: [PATCH 1176/1292] Fix indentation --- resources/bundled_packages/cura.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/bundled_packages/cura.json b/resources/bundled_packages/cura.json index c32b94af3f..f912958f74 100644 --- a/resources/bundled_packages/cura.json +++ b/resources/bundled_packages/cura.json @@ -356,7 +356,7 @@ } } }, - "PreviewStage": { + "PreviewStage": { "package_info": { "package_id": "PreviewStage", "package_type": "plugin", @@ -1585,4 +1585,4 @@ } } } -} +} \ No newline at end of file From 49076a7103715703b9a7aeef591cbf2f74207c88 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 3 Jan 2019 17:42:58 +0100 Subject: [PATCH 1177/1292] Remove the unneeded BackupListModel CURA-6005 --- plugins/CuraDrive/src/DrivePluginExtension.py | 23 ++++++----- .../CuraDrive/src/models/BackupListModel.py | 40 ------------------- plugins/CuraDrive/src/models/__init__.py | 0 .../src/qml/components/BackupListItem.qml | 10 ++--- .../qml/components/BackupListItemDetails.qml | 10 ++--- 5 files changed, 22 insertions(+), 61 deletions(-) delete mode 100644 plugins/CuraDrive/src/models/BackupListModel.py delete mode 100644 plugins/CuraDrive/src/models/__init__.py diff --git a/plugins/CuraDrive/src/DrivePluginExtension.py b/plugins/CuraDrive/src/DrivePluginExtension.py index cd8274f83a..041c01a14d 100644 --- a/plugins/CuraDrive/src/DrivePluginExtension.py +++ b/plugins/CuraDrive/src/DrivePluginExtension.py @@ -3,18 +3,17 @@ import os from datetime import datetime -from typing import Optional +from typing import Optional, List from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal -from UM.Application import Application from UM.Extension import Extension +from UM.Logger import Logger from UM.Message import Message from cura.CuraApplication import CuraApplication from .Settings import Settings from .DriveApiService import DriveApiService -from .models.BackupListModel import BackupListModel from UM.i18n import i18nCatalog catalog = i18nCatalog("cura") @@ -45,7 +44,7 @@ class DrivePluginExtension(QObject, Extension): # Local data caching for the UI. self._drive_window = None # type: Optional[QObject] - self._backups_list_model = BackupListModel() + self._backups = [] self._is_restoring_backup = False self._is_creating_backup = False @@ -126,13 +125,13 @@ class DrivePluginExtension(QObject, Extension): def autoBackupEnabled(self) -> bool: return bool(self._preferences.getValue(Settings.AUTO_BACKUP_ENABLED_PREFERENCE_KEY)) - @pyqtProperty(QObject, notify = backupsChanged) - def backups(self) -> BackupListModel: - return self._backups_list_model + @pyqtProperty("QVariantList", notify = backupsChanged) + def backups(self) -> List: + return self._backups @pyqtSlot(name = "refreshBackups") def refreshBackups(self) -> None: - self._backups_list_model.loadBackups(self._drive_api_service.getBackups()) + self._backups = self._drive_api_service.getBackups() self.backupsChanged.emit() @pyqtProperty(bool, notify = restoringStateChanged) @@ -145,9 +144,11 @@ class DrivePluginExtension(QObject, Extension): @pyqtSlot(str, name = "restoreBackup") def restoreBackup(self, backup_id: str) -> None: - index = self._backups_list_model.find("backup_id", backup_id) - backup = self._backups_list_model.getItem(index) - self._drive_api_service.restoreBackup(backup) + for backup in self._backups: + if backup.get("backup_id") == backup_id: + self._drive_api_service.restoreBackup(backup) + return + Logger.log("w", "Unable to find backup with the ID %s", backup_id) @pyqtSlot(name = "createBackup") def createBackup(self) -> None: diff --git a/plugins/CuraDrive/src/models/BackupListModel.py b/plugins/CuraDrive/src/models/BackupListModel.py deleted file mode 100644 index 06b256b22c..0000000000 --- a/plugins/CuraDrive/src/models/BackupListModel.py +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright (c) 2018 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. - -from typing import Any, List, Dict - -from UM.Qt.ListModel import ListModel - -from PyQt5.QtCore import Qt - - -class BackupListModel(ListModel): - """ - The BackupListModel transforms the backups data that came from the server so it can be served to the Qt UI. - """ - - def __init__(self, parent = None) -> None: - super().__init__(parent) - self.addRoleName(Qt.UserRole + 1, "backup_id") - self.addRoleName(Qt.UserRole + 2, "download_url") - self.addRoleName(Qt.UserRole + 3, "generated_time") - self.addRoleName(Qt.UserRole + 4, "md5_hash") - self.addRoleName(Qt.UserRole + 5, "data") - - def loadBackups(self, data: List[Dict[str, Any]]) -> None: - """ - Populate the model with server data. - :param data: - """ - items = [] - for backup in data: - # We do this loop because we only want to append these specific fields. - # Without this, ListModel will break. - items.append({ - "backup_id": backup["backup_id"], - "download_url": backup["download_url"], - "generated_time": backup["generated_time"], - "md5_hash": backup["md5_hash"], - "data": backup["metadata"] - }) - self.setItems(items) diff --git a/plugins/CuraDrive/src/models/__init__.py b/plugins/CuraDrive/src/models/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/plugins/CuraDrive/src/qml/components/BackupListItem.qml b/plugins/CuraDrive/src/qml/components/BackupListItem.qml index ba4f1a32a4..0cd897fada 100644 --- a/plugins/CuraDrive/src/qml/components/BackupListItem.qml +++ b/plugins/CuraDrive/src/qml/components/BackupListItem.qml @@ -44,7 +44,7 @@ Item Label { - text: new Date(model["generated_time"]).toLocaleString(UM.Preferences.getValue("general/language")) + text: new Date(modelData.generated_time).toLocaleString(UM.Preferences.getValue("general/language")) color: UM.Theme.getColor("text") elide: Text.ElideRight Layout.minimumWidth: 100 * screenScaleFactor @@ -55,7 +55,7 @@ Item Label { - text: model["data"]["description"] + text: modelData.metadata.description color: UM.Theme.getColor("text") elide: Text.ElideRight Layout.minimumWidth: 100 * screenScaleFactor @@ -85,7 +85,7 @@ Item BackupListItemDetails { id: backupDetails - backupDetailsData: model + backupDetailsData: modelData width: parent.width visible: parent.showDetails anchors.top: dataRow.bottom @@ -97,7 +97,7 @@ Item title: catalog.i18nc("@dialog:title", "Delete Backup") text: catalog.i18nc("@dialog:info", "Are you sure you want to delete this backup? This cannot be undone.") standardButtons: StandardButton.Yes | StandardButton.No - onYes: CuraDrive.deleteBackup(model["backup_id"]) + onYes: CuraDrive.deleteBackup(modelData.backup_id) } MessageDialog @@ -106,6 +106,6 @@ Item title: catalog.i18nc("@dialog:title", "Restore Backup") text: catalog.i18nc("@dialog:info", "You will need to restart Cura before your backup is restored. Do you want to close Cura now?") standardButtons: StandardButton.Yes | StandardButton.No - onYes: CuraDrive.restoreBackup(model["backup_id"]) + onYes: CuraDrive.restoreBackup(modelData.backup_id) } } diff --git a/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml b/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml index 38a2557c47..e84f1e0982 100644 --- a/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml +++ b/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml @@ -19,7 +19,7 @@ ColumnLayout { iconSource: "../images/cura.svg" label: catalog.i18nc("@backuplist:label", "Cura Version") - value: backupDetailsData["data"]["cura_release"] + value: backupDetailsData.metadata.cura_release } // Machine count. @@ -27,7 +27,7 @@ ColumnLayout { iconSource: "../images/printer.svg" label: catalog.i18nc("@backuplist:label", "Machines") - value: backupDetailsData["data"]["machine_count"] + value: backupDetailsData.metadata.machine_count } // Meterial count. @@ -35,7 +35,7 @@ ColumnLayout { iconSource: "../images/material.svg" label: catalog.i18nc("@backuplist:label", "Materials") - value: backupDetailsData["data"]["material_count"] + value: backupDetailsData.metadata.material_count } // Meterial count. @@ -43,7 +43,7 @@ ColumnLayout { iconSource: "../images/profile.svg" label: catalog.i18nc("@backuplist:label", "Profiles") - value: backupDetailsData["data"]["profile_count"] + value: backupDetailsData.metadata.profile_count } // Meterial count. @@ -51,7 +51,7 @@ ColumnLayout { iconSource: "../images/plugin.svg" label: catalog.i18nc("@backuplist:label", "Plugins") - value: backupDetailsData["data"]["plugin_count"] + value: backupDetailsData.metadata.plugin_count } // Spacer. From 0edc3f2680d03aa158a6218c30580290e37a6664 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 4 Jan 2019 10:17:06 +0100 Subject: [PATCH 1178/1292] Make some minor improvements to the qml This implements some of the best practices that weren't used yet for the QML CURA-6005 --- .../qml/components/BackupListItemDetails.qml | 2 +- .../components/BackupListItemDetailsRow.qml | 16 ++--- plugins/CuraDrive/src/qml/components/Icon.qml | 58 ------------------- plugins/CuraDrive/src/qml/main.qml | 2 +- .../CuraDrive/src/qml/pages/BackupsPage.qml | 2 +- .../CuraDrive/src/qml/pages/WelcomePage.qml | 5 +- 6 files changed, 16 insertions(+), 69 deletions(-) delete mode 100644 plugins/CuraDrive/src/qml/components/Icon.qml diff --git a/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml b/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml index e84f1e0982..d07bb50b11 100644 --- a/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml +++ b/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml @@ -11,7 +11,7 @@ ColumnLayout { id: backupDetails width: parent.width - spacing: 10 * screenScaleFactor + spacing: UM.Theme.getSize("default_margin").width property var backupDetailsData // Cura version diff --git a/plugins/CuraDrive/src/qml/components/BackupListItemDetailsRow.qml b/plugins/CuraDrive/src/qml/components/BackupListItemDetailsRow.qml index d1c8dd33d2..550bdaefab 100644 --- a/plugins/CuraDrive/src/qml/components/BackupListItemDetailsRow.qml +++ b/plugins/CuraDrive/src/qml/components/BackupListItemDetailsRow.qml @@ -13,9 +13,9 @@ RowLayout width: parent.width height: 40 * screenScaleFactor - property var iconSource - property var label - property var value + property alias iconSource: icon.source + property alias label: detailName.text + property alias value: detailValue.text // Spacing. Item @@ -23,16 +23,18 @@ RowLayout width: 40 * screenScaleFactor } - Icon + UM.RecolorImage { + id: icon width: 18 * screenScaleFactor - iconSource: detailsRow.iconSource + height: width + source: "" color: UM.Theme.getColor("text") } Label { - text: detailsRow.label + id: detailName color: UM.Theme.getColor("text") elide: Text.ElideRight Layout.minimumWidth: 50 * screenScaleFactor @@ -43,7 +45,7 @@ RowLayout Label { - text: detailsRow.value + id: detailValue color: UM.Theme.getColor("text") elide: Text.ElideRight Layout.minimumWidth: 50 * screenScaleFactor diff --git a/plugins/CuraDrive/src/qml/components/Icon.qml b/plugins/CuraDrive/src/qml/components/Icon.qml deleted file mode 100644 index 8d559bc2b4..0000000000 --- a/plugins/CuraDrive/src/qml/components/Icon.qml +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.7 -import QtQuick.Controls 2.1 -import QtGraphicalEffects 1.0 - -Item -{ - id: icon - width: parent.height - height: width - property var color: "transparent" - property var iconSource - property bool animated: false - - Image - { - id: iconImage - width: parent.height - height: width - smooth: true - source: icon.iconSource - sourceSize.width: width - sourceSize.height: height - antialiasing: true - visible: !icon.animated - } - - AnimatedImage - { - id: animatedIconImage - width: parent.height - height: width - smooth: true - antialiasing: true - source: "../images/loading.gif" - visible: icon.animated - } - - ColorOverlay - { - anchors.fill: iconImage - source: iconImage - color: icon.color - antialiasing: true - visible: !icon.animated - } - - ColorOverlay - { - anchors.fill: animatedIconImage - source: animatedIconImage - color: icon.color - antialiasing: true - visible: icon.animated - } -} diff --git a/plugins/CuraDrive/src/qml/main.qml b/plugins/CuraDrive/src/qml/main.qml index e8a49a49e5..48bf3b6ea4 100644 --- a/plugins/CuraDrive/src/qml/main.qml +++ b/plugins/CuraDrive/src/qml/main.qml @@ -27,7 +27,7 @@ Window UM.I18nCatalog { id: catalog - name: "cura_drive" + name: "cura" } WelcomePage diff --git a/plugins/CuraDrive/src/qml/pages/BackupsPage.qml b/plugins/CuraDrive/src/qml/pages/BackupsPage.qml index 0a7b00d2cb..3b905a4a39 100644 --- a/plugins/CuraDrive/src/qml/pages/BackupsPage.qml +++ b/plugins/CuraDrive/src/qml/pages/BackupsPage.qml @@ -18,7 +18,7 @@ Item ColumnLayout { - spacing: UM.Theme.getSize("default_margin").height * 2 + spacing: UM.Theme.getSize("wide_margin").height width: parent.width anchors.fill: parent diff --git a/plugins/CuraDrive/src/qml/pages/WelcomePage.qml b/plugins/CuraDrive/src/qml/pages/WelcomePage.qml index 19eecedf28..0b207bc170 100644 --- a/plugins/CuraDrive/src/qml/pages/WelcomePage.qml +++ b/plugins/CuraDrive/src/qml/pages/WelcomePage.qml @@ -10,12 +10,14 @@ import Cura 1.1 as Cura import "../components" + Column { id: welcomePage spacing: UM.Theme.getSize("wide_margin").height width: parent.width - topPadding: 150 * screenScaleFactor + height: childrenRect.height + anchors.centerIn: parent Image { @@ -51,3 +53,4 @@ Column fixedWidthMode: true } } + From 6492b51d7cbbefa0123f0c86bf9b4a984fd127b6 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 4 Jan 2019 10:25:22 +0100 Subject: [PATCH 1179/1292] Remove duplicated icons CURA-6005 --- .../src/qml/components/BackupListItemDetails.qml | 12 ++++++------ plugins/CuraDrive/src/qml/images/material.svg | 7 ------- plugins/CuraDrive/src/qml/images/plugin.svg | 7 ------- plugins/CuraDrive/src/qml/images/profile.svg | 3 --- 4 files changed, 6 insertions(+), 23 deletions(-) delete mode 100644 plugins/CuraDrive/src/qml/images/material.svg delete mode 100644 plugins/CuraDrive/src/qml/images/plugin.svg delete mode 100644 plugins/CuraDrive/src/qml/images/profile.svg diff --git a/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml b/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml index d07bb50b11..cf365501ec 100644 --- a/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml +++ b/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml @@ -30,26 +30,26 @@ ColumnLayout value: backupDetailsData.metadata.machine_count } - // Meterial count. + // Material count BackupListItemDetailsRow { - iconSource: "../images/material.svg" + iconSource: UM.Theme.getIcon("category_material") label: catalog.i18nc("@backuplist:label", "Materials") value: backupDetailsData.metadata.material_count } - // Meterial count. + // Profile count. BackupListItemDetailsRow { - iconSource: "../images/profile.svg" + iconSource: UM.Theme.getIcon("profile") label: catalog.i18nc("@backuplist:label", "Profiles") value: backupDetailsData.metadata.profile_count } - // Meterial count. + // Plugin count. BackupListItemDetailsRow { - iconSource: "../images/plugin.svg" + iconSource: UM.Theme.getIcon("plugin") label: catalog.i18nc("@backuplist:label", "Plugins") value: backupDetailsData.metadata.plugin_count } diff --git a/plugins/CuraDrive/src/qml/images/material.svg b/plugins/CuraDrive/src/qml/images/material.svg deleted file mode 100644 index eac724e471..0000000000 --- a/plugins/CuraDrive/src/qml/images/material.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/plugins/CuraDrive/src/qml/images/plugin.svg b/plugins/CuraDrive/src/qml/images/plugin.svg deleted file mode 100644 index 674eb99a54..0000000000 --- a/plugins/CuraDrive/src/qml/images/plugin.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/plugins/CuraDrive/src/qml/images/profile.svg b/plugins/CuraDrive/src/qml/images/profile.svg deleted file mode 100644 index ec2130f3d6..0000000000 --- a/plugins/CuraDrive/src/qml/images/profile.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file From 551f07552789505f4c456bcb4d35d6be4572ab15 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 4 Jan 2019 10:27:41 +0100 Subject: [PATCH 1180/1292] Removed unneeded destinction between get/put/delete URL They are all the same, so no real need to keep this seperate. CURA-6005 --- plugins/CuraDrive/src/DriveApiService.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/plugins/CuraDrive/src/DriveApiService.py b/plugins/CuraDrive/src/DriveApiService.py index f74f30bcda..d9185cc1d2 100644 --- a/plugins/CuraDrive/src/DriveApiService.py +++ b/plugins/CuraDrive/src/DriveApiService.py @@ -23,9 +23,7 @@ catalog = i18nCatalog("cura") ## The DriveApiService is responsible for interacting with the CuraDrive API and Cura's backup handling. class DriveApiService: - GET_BACKUPS_URL = "{}/backups".format(Settings.DRIVE_API_URL) - PUT_BACKUP_URL = "{}/backups".format(Settings.DRIVE_API_URL) - DELETE_BACKUP_URL = "{}/backups".format(Settings.DRIVE_API_URL) + BACKUP_URL = "{}/backups".format(Settings.DRIVE_API_URL) # Emit signal when restoring backup started or finished. onRestoringStateChanged = Signal() @@ -42,7 +40,7 @@ class DriveApiService: Logger.log("w", "Could not get access token.") return [] - backup_list_request = requests.get(self.GET_BACKUPS_URL, headers = { + backup_list_request = requests.get(self.BACKUP_URL, headers = { "Authorization": "Bearer {}".format(access_token) }) @@ -132,7 +130,7 @@ class DriveApiService: Logger.log("w", "Could not get access token.") return False - delete_backup = requests.delete("{}/{}".format(self.DELETE_BACKUP_URL, backup_id), headers = { + delete_backup = requests.delete("{}/{}".format(self.BACKUP_URL, backup_id), headers = { "Authorization": "Bearer {}".format(access_token) }) if delete_backup.status_code >= 300: @@ -151,7 +149,7 @@ class DriveApiService: Logger.log("w", "Could not get access token.") return None - backup_upload_request = requests.put(self.PUT_BACKUP_URL, json = { + backup_upload_request = requests.put(self.BACKUP_URL, json = { "data": { "backup_size": backup_size, "metadata": backup_metadata From 31156d623017f7a6a00a4cba1a574b4a86230037 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 4 Jan 2019 10:28:54 +0100 Subject: [PATCH 1181/1292] Add missing signalemitter decorater CURA-6005 --- plugins/CuraDrive/src/DriveApiService.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/CuraDrive/src/DriveApiService.py b/plugins/CuraDrive/src/DriveApiService.py index d9185cc1d2..d9116eccb2 100644 --- a/plugins/CuraDrive/src/DriveApiService.py +++ b/plugins/CuraDrive/src/DriveApiService.py @@ -11,7 +11,7 @@ import requests from UM.Logger import Logger from UM.Message import Message -from UM.Signal import Signal +from UM.Signal import Signal, signalemitter from cura.CuraApplication import CuraApplication from .UploadBackupJob import UploadBackupJob @@ -22,6 +22,7 @@ catalog = i18nCatalog("cura") ## The DriveApiService is responsible for interacting with the CuraDrive API and Cura's backup handling. +@signalemitter class DriveApiService: BACKUP_URL = "{}/backups".format(Settings.DRIVE_API_URL) From 8ebd4282fd661582e144531f75ca8ee833841c50 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 4 Jan 2019 10:39:39 +0100 Subject: [PATCH 1182/1292] Make the backupList use a scrollview instead of manually re-doing it CURA-6005 --- .../src/qml/components/BackupList.qml | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/plugins/CuraDrive/src/qml/components/BackupList.qml b/plugins/CuraDrive/src/qml/components/BackupList.qml index af7e72b6e6..10ca15afe5 100644 --- a/plugins/CuraDrive/src/qml/components/BackupList.qml +++ b/plugins/CuraDrive/src/qml/components/BackupList.qml @@ -2,32 +2,35 @@ // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 -import QtQuick.Controls 2.1 +import QtQuick.Controls 2.2 import QtQuick.Layouts 1.3 import UM 1.1 as UM -ListView +ScrollView { - id: backupList + property alias model: backupList.model width: parent.width - clip: true - delegate: Item + ListView { + id: backupList width: parent.width - height: childrenRect.height - - BackupListItem - { - id: backupListItem - width: parent.width - UM.Theme.getSize("default_margin").width // Add a margin, otherwise the scrollbar is be on top of the right most component - } - - Divider + delegate: Item { width: parent.width - anchors.top: backupListItem.bottom + height: childrenRect.height + + BackupListItem + { + id: backupListItem + width: parent.width + } + + Divider + { + width: parent.width + anchors.top: backupListItem.bottom + } } } - ScrollBar.vertical: RightSideScrollBar {} } From 87eb8634512f8f97a191d5074b2f3e07e700487f Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 4 Jan 2019 10:43:40 +0100 Subject: [PATCH 1183/1292] Remove the final traces of the translation indirection CURA-6005 --- plugins/CuraDrive/src/DriveApiService.py | 2 +- plugins/CuraDrive/src/DrivePluginExtension.py | 4 ++-- plugins/CuraDrive/src/Settings.py | 10 ++-------- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/plugins/CuraDrive/src/DriveApiService.py b/plugins/CuraDrive/src/DriveApiService.py index d9116eccb2..7ca009018b 100644 --- a/plugins/CuraDrive/src/DriveApiService.py +++ b/plugins/CuraDrive/src/DriveApiService.py @@ -47,7 +47,7 @@ class DriveApiService: if backup_list_request.status_code >= 300: Logger.log("w", "Could not get backups list from remote: %s", backup_list_request.text) - Message(catalog.i18nc("@info:backup_status", "There was an error listing your backups."), title = Settings.MESSAGE_TITLE).show() + Message(catalog.i18nc("@info:backup_status", "There was an error listing your backups."), title = catalog.i18nc("@info:title", "Backup")).show() return [] return backup_list_request.json()["data"] diff --git a/plugins/CuraDrive/src/DrivePluginExtension.py b/plugins/CuraDrive/src/DrivePluginExtension.py index 041c01a14d..edd89745ea 100644 --- a/plugins/CuraDrive/src/DrivePluginExtension.py +++ b/plugins/CuraDrive/src/DrivePluginExtension.py @@ -103,13 +103,13 @@ class DrivePluginExtension(QObject, Extension): self._is_restoring_backup = is_restoring self.restoringStateChanged.emit() if error_message: - Message(error_message, title = Settings.MESSAGE_TITLE, lifetime = 5).show() + Message(error_message, title = catalog.i18nc("@info:title", "Backup")).show() def _onCreatingStateChanged(self, is_creating: bool = False, error_message: str = None) -> None: self._is_creating_backup = is_creating self.creatingStateChanged.emit() if error_message: - Message(error_message, title = Settings.MESSAGE_TITLE, lifetime = 5).show() + Message(error_message, title = catalog.i18nc("@info:title", "Backup")).show() else: self._storeBackupDate() if not is_creating: diff --git a/plugins/CuraDrive/src/Settings.py b/plugins/CuraDrive/src/Settings.py index fcb05b8c04..c5383555b2 100644 --- a/plugins/CuraDrive/src/Settings.py +++ b/plugins/CuraDrive/src/Settings.py @@ -7,15 +7,9 @@ from cura import UltimakerCloudAuthentication class Settings: - """ - Keeps the application settings. - """ + # Keeps the plugin settings. DRIVE_API_VERSION = 1 DRIVE_API_URL = "{}/cura-drive/v{}".format(UltimakerCloudAuthentication.CuraCloudAPIRoot, str(DRIVE_API_VERSION)) AUTO_BACKUP_ENABLED_PREFERENCE_KEY = "cura_drive/auto_backup_enabled" - AUTO_BACKUP_LAST_DATE_PREFERENCE_KEY = "cura_drive/auto_backup_date" - - I18N_CATALOG = i18nCatalog("cura") - - MESSAGE_TITLE = I18N_CATALOG.i18nc("@info:title", "Backups") \ No newline at end of file + AUTO_BACKUP_LAST_DATE_PREFERENCE_KEY = "cura_drive/auto_backup_date" \ No newline at end of file From 63c2a901bb54a9f50cbdec259d06ae969192419e Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 4 Jan 2019 10:45:24 +0100 Subject: [PATCH 1184/1292] Prevent double emits / recalculations when not needed CURA-6005 --- plugins/CuraDrive/src/DrivePluginExtension.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/CuraDrive/src/DrivePluginExtension.py b/plugins/CuraDrive/src/DrivePluginExtension.py index edd89745ea..d1ea34f4a5 100644 --- a/plugins/CuraDrive/src/DrivePluginExtension.py +++ b/plugins/CuraDrive/src/DrivePluginExtension.py @@ -112,14 +112,13 @@ class DrivePluginExtension(QObject, Extension): Message(error_message, title = catalog.i18nc("@info:title", "Backup")).show() else: self._storeBackupDate() - if not is_creating: + if not is_creating and not error_message: # We've finished creating a new backup, to the list has to be updated. self.refreshBackups() @pyqtSlot(bool, name = "toggleAutoBackup") def toggleAutoBackup(self, enabled: bool) -> None: self._preferences.setValue(Settings.AUTO_BACKUP_ENABLED_PREFERENCE_KEY, enabled) - self.preferencesChanged.emit() @pyqtProperty(bool, notify = preferencesChanged) def autoBackupEnabled(self) -> bool: From 23315260ae1870f393f720393e8b3d5af6df0c47 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 4 Jan 2019 10:49:41 +0100 Subject: [PATCH 1185/1292] Fix some of the documentation CURA-6005 --- plugins/CuraDrive/src/DrivePluginExtension.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/plugins/CuraDrive/src/DrivePluginExtension.py b/plugins/CuraDrive/src/DrivePluginExtension.py index d1ea34f4a5..ce9a6651d5 100644 --- a/plugins/CuraDrive/src/DrivePluginExtension.py +++ b/plugins/CuraDrive/src/DrivePluginExtension.py @@ -18,11 +18,8 @@ from .DriveApiService import DriveApiService from UM.i18n import i18nCatalog catalog = i18nCatalog("cura") - +# The DivePluginExtension provides functionality to backup and restore your Cura configuration to Ultimaker's cloud. class DrivePluginExtension(QObject, Extension): - """ - The DivePluginExtension provides functionality to backup and restore your Cura configuration to Ultimaker's cloud. - """ # Signal emitted when the list of backups changed. backupsChanged = pyqtSignal() @@ -38,7 +35,7 @@ class DrivePluginExtension(QObject, Extension): DATE_FORMAT = "%d/%m/%Y %H:%M:%S" - def __init__(self): + def __init__(self) -> None: QObject.__init__(self, None) Extension.__init__(self) @@ -69,7 +66,6 @@ class DrivePluginExtension(QObject, Extension): CuraApplication.getInstance().engineCreatedSignal.connect(self._autoBackup) def showDriveWindow(self) -> None: - """Show the Drive UI popup window.""" if not self._drive_window: path = os.path.join(os.path.dirname(__file__), "qml", "main.qml") self._drive_window = CuraApplication.getInstance().createQmlComponent(path, {"CuraDrive": self}) From 3b498d3a34cbfd1a1abd3ae909cec8383ec5f8b1 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 4 Jan 2019 10:51:07 +0100 Subject: [PATCH 1186/1292] Change name of the signals so they are consistent with rest of the code CURA-6005 --- plugins/CuraDrive/src/DriveApiService.py | 22 +++++++++---------- plugins/CuraDrive/src/DrivePluginExtension.py | 4 ++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/plugins/CuraDrive/src/DriveApiService.py b/plugins/CuraDrive/src/DriveApiService.py index 7ca009018b..3bb416fce6 100644 --- a/plugins/CuraDrive/src/DriveApiService.py +++ b/plugins/CuraDrive/src/DriveApiService.py @@ -27,10 +27,10 @@ class DriveApiService: BACKUP_URL = "{}/backups".format(Settings.DRIVE_API_URL) # Emit signal when restoring backup started or finished. - onRestoringStateChanged = Signal() + restoringStateChanged = Signal() # Emit signal when creating backup started or finished. - onCreatingStateChanged = Signal() + creatingStateChanged = Signal() def __init__(self) -> None: self._cura_api = CuraApplication.getInstance().getCuraAPI() @@ -52,12 +52,12 @@ class DriveApiService: return backup_list_request.json()["data"] def createBackup(self) -> None: - self.onCreatingStateChanged.emit(is_creating = True) + self.creatingStateChanged.emit(is_creating = True) # Create the backup. backup_zip_file, backup_meta_data = self._cura_api.backups.createBackup() if not backup_zip_file or not backup_meta_data: - self.onCreatingStateChanged.emit(is_creating = False, error_message = "Could not create backup.") + self.creatingStateChanged.emit(is_creating = False, error_message ="Could not create backup.") return # Create an upload entry for the backup. @@ -65,7 +65,7 @@ class DriveApiService: backup_meta_data["description"] = "{}.backup.{}.cura.zip".format(timestamp, backup_meta_data["cura_release"]) backup_upload_url = self._requestBackupUpload(backup_meta_data, len(backup_zip_file)) if not backup_upload_url: - self.onCreatingStateChanged.emit(is_creating = False, error_message = "Could not upload backup.") + self.creatingStateChanged.emit(is_creating = False, error_message ="Could not upload backup.") return # Upload the backup to storage. @@ -76,12 +76,12 @@ class DriveApiService: def _onUploadFinished(self, job: "UploadBackupJob") -> None: if job.backup_upload_error_message != "": # If the job contains an error message we pass it along so the UI can display it. - self.onCreatingStateChanged.emit(is_creating = False, error_message = job.backup_upload_error_message) + self.creatingStateChanged.emit(is_creating = False, error_message = job.backup_upload_error_message) else: - self.onCreatingStateChanged.emit(is_creating = False) + self.creatingStateChanged.emit(is_creating = False) def restoreBackup(self, backup: Dict[str, Any]) -> None: - self.onRestoringStateChanged.emit(is_restoring = True) + self.restoringStateChanged.emit(is_restoring = True) download_url = backup.get("download_url") if not download_url: # If there is no download URL, we can't restore the backup. @@ -108,11 +108,11 @@ class DriveApiService: # Tell Cura to place the backup back in the user data folder. with open(temporary_backup_file.name, "rb") as read_backup: self._cura_api.backups.restoreBackup(read_backup.read(), backup.get("data")) - self.onRestoringStateChanged.emit(is_restoring = False) + self.restoringStateChanged.emit(is_restoring = False) def _emitRestoreError(self): - self.onRestoringStateChanged.emit(is_restoring = False, - error_message = catalog.i18nc("@info:backup_status", + self.restoringStateChanged.emit(is_restoring = False, + error_message = catalog.i18nc("@info:backup_status", "There was an error trying to restore your backup.")) # Verify the MD5 hash of a file. diff --git a/plugins/CuraDrive/src/DrivePluginExtension.py b/plugins/CuraDrive/src/DrivePluginExtension.py index ce9a6651d5..8944b9a980 100644 --- a/plugins/CuraDrive/src/DrivePluginExtension.py +++ b/plugins/CuraDrive/src/DrivePluginExtension.py @@ -51,8 +51,8 @@ class DrivePluginExtension(QObject, Extension): # Attach signals. CuraApplication.getInstance().getCuraAPI().account.loginStateChanged.connect(self._onLoginStateChanged) - self._drive_api_service.onRestoringStateChanged.connect(self._onRestoringStateChanged) - self._drive_api_service.onCreatingStateChanged.connect(self._onCreatingStateChanged) + self._drive_api_service.restoringStateChanged.connect(self._onRestoringStateChanged) + self._drive_api_service.creatingStateChanged.connect(self._onCreatingStateChanged) # Register preferences. self._preferences.addPreference(Settings.AUTO_BACKUP_ENABLED_PREFERENCE_KEY, False) From 0ec0b68360d7029349702f0e7099e9c8e28087bb Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 4 Jan 2019 10:54:23 +0100 Subject: [PATCH 1187/1292] Remove unneeded component CURA-6005 --- .../src/qml/components/RightSideScrollBar.qml | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 plugins/CuraDrive/src/qml/components/RightSideScrollBar.qml diff --git a/plugins/CuraDrive/src/qml/components/RightSideScrollBar.qml b/plugins/CuraDrive/src/qml/components/RightSideScrollBar.qml deleted file mode 100644 index 5ef8558ee7..0000000000 --- a/plugins/CuraDrive/src/qml/components/RightSideScrollBar.qml +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.7 -import QtQuick.Controls 2.1 -import QtQuick.Layouts 1.3 - -ScrollBar -{ - active: true - size: parent.height - anchors.top: parent.top - anchors.right: parent.right - anchors.bottom: parent.bottom -} From 74087ade05117ee2c048de387de023cfdd69c1a1 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 4 Jan 2019 10:58:51 +0100 Subject: [PATCH 1188/1292] Remove a number of orphaned files CURA-6005 --- .../CuraDrive/src/qml/images/avatar_default.png | Bin 3115 -> 0 bytes plugins/CuraDrive/src/qml/images/background.svg | 12 ------------ plugins/CuraDrive/src/qml/images/cura_logo.jpg | Bin 19308 -> 0 bytes plugins/CuraDrive/src/qml/images/cura_logo.png | Bin 13258 -> 0 bytes plugins/CuraDrive/src/qml/images/folder.svg | 7 ------- plugins/CuraDrive/src/qml/images/home.svg | 3 --- .../src/qml/images/inverted_circle.png | Bin 1608 -> 0 bytes plugins/CuraDrive/src/qml/images/restore.svg | 7 ------- 8 files changed, 29 deletions(-) delete mode 100644 plugins/CuraDrive/src/qml/images/avatar_default.png delete mode 100644 plugins/CuraDrive/src/qml/images/background.svg delete mode 100644 plugins/CuraDrive/src/qml/images/cura_logo.jpg delete mode 100644 plugins/CuraDrive/src/qml/images/cura_logo.png delete mode 100644 plugins/CuraDrive/src/qml/images/folder.svg delete mode 100644 plugins/CuraDrive/src/qml/images/home.svg delete mode 100644 plugins/CuraDrive/src/qml/images/inverted_circle.png delete mode 100644 plugins/CuraDrive/src/qml/images/restore.svg diff --git a/plugins/CuraDrive/src/qml/images/avatar_default.png b/plugins/CuraDrive/src/qml/images/avatar_default.png deleted file mode 100644 index 0c306680f721dba0de73fb7be90fe5c548608692..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3115 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 - - - Polygon 18 - Created with Sketch. - - - - - - - \ No newline at end of file diff --git a/plugins/CuraDrive/src/qml/images/cura_logo.jpg b/plugins/CuraDrive/src/qml/images/cura_logo.jpg deleted file mode 100644 index 621c03f035cddb3c9337099c25bccf19a5866968..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19308 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 V{_(E9+wT8(SKsZ~f4r-A{|^$iZYBT# diff --git a/plugins/CuraDrive/src/qml/images/cura_logo.png b/plugins/CuraDrive/src/qml/images/cura_logo.png deleted file mode 100644 index f846f2a0f0934f4843c3279ed741c149c77b2e1e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13258 zcmeHu;4V*)BSRu^XaTvbLN?uz4uJ)2XzHpY!LRVSFdoD6lJwuy+WyZdCve~ygc*u(2ZXX z6n8BJ=~tEGlzXpU@kS`gN`3M{In2g&`K-Ng?48+YOUK6%Q!&j{8UO%f(B`2OjGe6E z=pFl$ws^S=Htqi&Eu+nt`f5zkAyuM|<9+lUC7ObBbhAJ)l>)Q49oq{+g+>xugU({Y z!PhW}n#xpMueQi{{k(Xgq^qIfb|t>U@SfRMr>zd5Z{lC^?1wlPJ#bg}3RdVQbU~*? z`TxiNdl#7g_x2?FIG|)>n5~LZ=;-U{r$9xWcyi_~xxLz49$qf=d`tG6X zIStGm9v<#dC-s0$b#qRMgsHFQp^FeRDg%|8>pO3^vnue#Z%ltH62Zo)abYu)lLUvz zhB9bh6s{bH^OfNC;bPHuwsUnckKTeN_+-^P3q;Rl_BXG`4v(a2lIvSvy%OYFLvt*Z39TCgr_a$F=Mp8M>*tj%kWC~v)94VFN5 z1qXZl?GEiRi;f`o`qcv{-e76%eFdNVsQd3-SZTWP)QI7xn+|JN!Q5xxAATLlA*Y)u z8pe!KMjd{a`|_;R{4@b4QtZ`tcX#VkMd;L<4<)IL{^KurzKG;6p8r3E0*#`BRc1%Z4{vHItk9179tO)8Rr)A_% z^@S+;h%bJ(TWOfDQ?c0pN|yDfn~1yLxnevG5wggjcb=tILHvFOzr@qF%`oJMOSJ+{ zvx|e^`kBeW*=VvqpXlg0-=GhY0MM;vt$z~ATSwB$WVr;veV2t$H*iB= z9Qz*R+wd#7o~OW+AvB*R9cy`8kkDbTmzQzWzP^*cskOBg%~EfKP~j8Ris_&aPFLcN zUi#uzboWne?!(MqzJEh8^?ZVidSPC0n3@71p>*8%Z)6$;fFKy%0QQAvykQl%ipl86D zp6LP5w;D0G`6p$=CEh&yyO5|8W$0;Ch)sve$3xGmuBW@dNk;N!XYs*xus)kGap#&jjLnRa>E$AcC6{{L0hB2p z(d5UzFVqZCgKNN3ck+4~>(E_#s08-L_qzM?y77I))HmP8By}+g-%woX6(1QP(8wUT z8_$T)hmPi*wF8sEf`U=ZECL~5A8}a?!?V`I{7*d4ZwX7Lx}uJP?o@<9_<=V#dT;p< zkU)+;E_S^HTK+lpxLcUa<4?$|o6Zp!vVcu&0D#Dwt;O`Ed(S5i;&3`TIyU^WPfJ>o zMJ{QDzv6}BI!lIRtO*usuLGIrp1YIl0XL^Co4C=jrpf69aHA(>N7tQyTpu5(GS~d5%UqzuqpMu?ZR; zn5YT+op(z-ohE~l$Y}oqN`(%5@MOS)F7%$_xUvh1wzo$U0txB7mObYxX2K4(z=BQ| zLm$e;sDrk?iu{re_7*`Ura)P?pJy5L-*KN1(;Z=9a~CixFsrkfDi}Z}`u3eqNJx

    {tidI^DPfL*th*F*+_ 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 diff --git a/plugins/CuraDrive/src/qml/images/folder.svg b/plugins/CuraDrive/src/qml/images/folder.svg deleted file mode 100644 index f66f83a888..0000000000 --- a/plugins/CuraDrive/src/qml/images/folder.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/plugins/CuraDrive/src/qml/images/home.svg b/plugins/CuraDrive/src/qml/images/home.svg deleted file mode 100644 index 9d0e4d802c..0000000000 --- a/plugins/CuraDrive/src/qml/images/home.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/plugins/CuraDrive/src/qml/images/inverted_circle.png b/plugins/CuraDrive/src/qml/images/inverted_circle.png deleted file mode 100644 index 3612b37d4d38cd7b1218be42c943932a79f7b465..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1608 zcmV-O2DkZ%P)Px*0!c(cRCodHojY&bMihm$2^^$|ogzu+GJuKziK{dQ0@$6KbS?t}`UTGaabp-t z;i~kgR zm9(f#Bk`Hh#bQJToQuwp^t1Gf^xI;wNV0G!$A#wim2^+K zFMT83l8Q%Z1I|R?x%5mr7Vv*8h{%xl)y`e%JL#eHu~Z~V7{F5fT6!wI6!f=6GOrqy z86Rr&Tj`PXKw@pN3pPPU@weJJl)kXbZnu``Th&MUY7%<}t&q$U>GR!il>0P&t@@nZ zh};GoD-m{nlMMPUkwdn~WxyZm@quK!J<0Kd99kqasqEGcb@~(JT5IK!cP27c-S#u#kG0(8mB)x!EuI zv3W3&cHSKAY5+T(*>3Y==1IR!KzbqHGm%;v-v;2 z4RYK2u#!6cSnF!Qxky!b|3W&lo2<^=jwe1)mBu@+orz~NMqnp!_)z@gNL*nofa?r5*u znHuo8zp#~HypGs_SMis8IxPW_f3>Esk@uq6KaHk+GChGN|X7 z)YpLLr7x7tnD=OAT`}g0@KppSG~}9j4+8?Q4&1{|_)ITw&Af*J0a!~gU+;vEtZt4l z$ZzybRIHEaXxImETabq>ffaLB1BD-WvxU#5{|?|8IhXvfv%LWvraosAbfRrilDiR& zbC`5<74ws&0h7*T+MRa;3j5~MnScA#mXalmQ=Fbpry4LcAnp|E$84L0IpEm`5cgIC|7%EK z$vhZv->_kCYDHkhoYg?#mnIr67UI3WG%@T0Fu^a*H8KI#04KsGh^8rI?O{XU9qW}3 z%fEhuh5>w$-g<)uCETeZ?va-OjA6Zs+8V&9-=r77WEzU`k9FqtoiMNaZK|2TGh6X( zy-gJp{6_6eCcqZJ^@!I1-t$rg84M8D&ZP=4!HabyHUXx9jpMR4fX}cN_+2xJOn_y@ zRD))0Gk{Nd!KMTTh-0sUO~Iyv1bvwGECjN5$udmvqJ0AvAMqPpv=0-!Y-LXqU{d?E`(IhHzx!sYx(+Mf - - - - - - \ No newline at end of file From add5f17ae75bd23734142875e348f4aa2574b774 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 4 Jan 2019 11:06:43 +0100 Subject: [PATCH 1189/1292] And removed even more unneeded / duplicate / orphaned images CURA-6005 --- .../src/qml/components/BackupListFooter.qml | 2 +- .../src/qml/components/BackupListItemDetails.qml | 6 +++--- plugins/CuraDrive/src/qml/images/backup.svg | 3 --- plugins/CuraDrive/src/qml/images/cura.svg | 7 ------- .../CuraDrive/src/qml/images/preview_banner.png | Bin 8324 -> 0 bytes plugins/CuraDrive/src/qml/images/printer.svg | 14 -------------- 6 files changed, 4 insertions(+), 28 deletions(-) delete mode 100644 plugins/CuraDrive/src/qml/images/backup.svg delete mode 100644 plugins/CuraDrive/src/qml/images/cura.svg delete mode 100644 plugins/CuraDrive/src/qml/images/preview_banner.png delete mode 100644 plugins/CuraDrive/src/qml/images/printer.svg diff --git a/plugins/CuraDrive/src/qml/components/BackupListFooter.qml b/plugins/CuraDrive/src/qml/components/BackupListFooter.qml index a0bc212597..56706b9990 100644 --- a/plugins/CuraDrive/src/qml/components/BackupListFooter.qml +++ b/plugins/CuraDrive/src/qml/components/BackupListFooter.qml @@ -29,7 +29,7 @@ RowLayout { id: createBackupButton text: catalog.i18nc("@button", "Backup Now") - iconSource: "../images/backup.svg" + iconSource: UM.Theme.getIcon("plus") enabled: !CuraDrive.isCreatingBackup && !CuraDrive.isRestoringBackup && !backupListFooter.showInfoButton onClicked: CuraDrive.createBackup() busy: CuraDrive.isCreatingBackup diff --git a/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml b/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml index cf365501ec..2f2dd48e13 100644 --- a/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml +++ b/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml @@ -17,7 +17,7 @@ ColumnLayout // Cura version BackupListItemDetailsRow { - iconSource: "../images/cura.svg" + iconSource: UM.Theme.getIcon("application") label: catalog.i18nc("@backuplist:label", "Cura Version") value: backupDetailsData.metadata.cura_release } @@ -25,7 +25,7 @@ ColumnLayout // Machine count. BackupListItemDetailsRow { - iconSource: "../images/printer.svg" + iconSource: UM.Theme.getIcon("printer_single") label: catalog.i18nc("@backuplist:label", "Machines") value: backupDetailsData.metadata.machine_count } @@ -41,7 +41,7 @@ ColumnLayout // Profile count. BackupListItemDetailsRow { - iconSource: UM.Theme.getIcon("profile") + iconSource: UM.Theme.getIcon("settings") label: catalog.i18nc("@backuplist:label", "Profiles") value: backupDetailsData.metadata.profile_count } diff --git a/plugins/CuraDrive/src/qml/images/backup.svg b/plugins/CuraDrive/src/qml/images/backup.svg deleted file mode 100644 index 51f6be4cba..0000000000 --- a/plugins/CuraDrive/src/qml/images/backup.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/plugins/CuraDrive/src/qml/images/cura.svg b/plugins/CuraDrive/src/qml/images/cura.svg deleted file mode 100644 index 6b1b6c0c79..0000000000 --- a/plugins/CuraDrive/src/qml/images/cura.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/plugins/CuraDrive/src/qml/images/preview_banner.png b/plugins/CuraDrive/src/qml/images/preview_banner.png deleted file mode 100644 index 414019531beed2e503e05cc394fc7e6de246830a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8324 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 E2O#6GiU0rr diff --git a/plugins/CuraDrive/src/qml/images/printer.svg b/plugins/CuraDrive/src/qml/images/printer.svg deleted file mode 100644 index f7dc83987d..0000000000 --- a/plugins/CuraDrive/src/qml/images/printer.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - icn_singlePrinter - Created with Sketch. - - - - - - - - - \ No newline at end of file From 98153769ff64c306bcf7f6997c10875a2dffbe20 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 4 Jan 2019 11:23:34 +0100 Subject: [PATCH 1190/1292] Use wide_margin instead of multiplying default margin CURA-6005 --- plugins/CuraDrive/src/qml/pages/BackupsPage.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/CuraDrive/src/qml/pages/BackupsPage.qml b/plugins/CuraDrive/src/qml/pages/BackupsPage.qml index 3b905a4a39..0ba0cae09b 100644 --- a/plugins/CuraDrive/src/qml/pages/BackupsPage.qml +++ b/plugins/CuraDrive/src/qml/pages/BackupsPage.qml @@ -14,7 +14,7 @@ Item { id: backupsPage anchors.fill: parent - anchors.margins: UM.Theme.getSize("default_margin").width * 3 + anchors.margins: UM.Theme.getSize("wide_margin").width ColumnLayout { From b4911478e343dfcb0dde658014b20181790a40da Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 4 Jan 2019 11:35:34 +0100 Subject: [PATCH 1191/1292] Made the plugin depend more on the theme CURA-6005 --- plugins/CuraDrive/src/qml/components/BackupListItem.qml | 2 ++ .../src/qml/components/BackupListItemDetails.qml | 2 +- .../src/qml/components/BackupListItemDetailsRow.qml | 8 ++------ 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/plugins/CuraDrive/src/qml/components/BackupListItem.qml b/plugins/CuraDrive/src/qml/components/BackupListItem.qml index 0cd897fada..5cdb500b4e 100644 --- a/plugins/CuraDrive/src/qml/components/BackupListItem.qml +++ b/plugins/CuraDrive/src/qml/components/BackupListItem.qml @@ -50,6 +50,7 @@ Item Layout.minimumWidth: 100 * screenScaleFactor Layout.maximumWidth: 500 * screenScaleFactor Layout.fillWidth: true + font: UM.Theme.getFont("default") renderType: Text.NativeRendering } @@ -61,6 +62,7 @@ Item Layout.minimumWidth: 100 * screenScaleFactor Layout.maximumWidth: 500 * screenScaleFactor Layout.fillWidth: true + font: UM.Theme.getFont("default") renderType: Text.NativeRendering } diff --git a/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml b/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml index 2f2dd48e13..4da15c6f16 100644 --- a/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml +++ b/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml @@ -58,6 +58,6 @@ ColumnLayout Item { width: parent.width - height: 10 * screenScaleFactor + height: UM.Theme.getSize("default_margin").height } } diff --git a/plugins/CuraDrive/src/qml/components/BackupListItemDetailsRow.qml b/plugins/CuraDrive/src/qml/components/BackupListItemDetailsRow.qml index 550bdaefab..9e4612fcf8 100644 --- a/plugins/CuraDrive/src/qml/components/BackupListItemDetailsRow.qml +++ b/plugins/CuraDrive/src/qml/components/BackupListItemDetailsRow.qml @@ -17,12 +17,6 @@ RowLayout property alias label: detailName.text property alias value: detailValue.text - // Spacing. - Item - { - width: 40 * screenScaleFactor - } - UM.RecolorImage { id: icon @@ -40,6 +34,7 @@ RowLayout Layout.minimumWidth: 50 * screenScaleFactor Layout.maximumWidth: 100 * screenScaleFactor Layout.fillWidth: true + font: UM.Theme.getFont("default") renderType: Text.NativeRendering } @@ -51,6 +46,7 @@ RowLayout Layout.minimumWidth: 50 * screenScaleFactor Layout.maximumWidth: 100 * screenScaleFactor Layout.fillWidth: true + font: UM.Theme.getFont("default") renderType: Text.NativeRendering } } From c10b8b5c3f5f97a3c08be797614bd6e03662422c Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 4 Jan 2019 11:37:52 +0100 Subject: [PATCH 1192/1292] Fix crash when attempting to restore backup CURA-6005 --- plugins/CuraDrive/src/DriveApiService.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/CuraDrive/src/DriveApiService.py b/plugins/CuraDrive/src/DriveApiService.py index 3bb416fce6..79f49bf1a3 100644 --- a/plugins/CuraDrive/src/DriveApiService.py +++ b/plugins/CuraDrive/src/DriveApiService.py @@ -107,7 +107,7 @@ class DriveApiService: # Tell Cura to place the backup back in the user data folder. with open(temporary_backup_file.name, "rb") as read_backup: - self._cura_api.backups.restoreBackup(read_backup.read(), backup.get("data")) + self._cura_api.backups.restoreBackup(read_backup.read(), backup.get("metadata", {})) self.restoringStateChanged.emit(is_restoring = False) def _emitRestoreError(self): From 3df9b369f7aaa4aaddee974cfd2449cecd69064d Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 4 Jan 2019 11:40:09 +0100 Subject: [PATCH 1193/1292] Removed the divider as a seperate component Since it's only used in one place, there is no real point in making it a seperate file CURA-6005 --- plugins/CuraDrive/src/qml/components/BackupList.qml | 7 ++++--- plugins/CuraDrive/src/qml/components/Divider.qml | 13 ------------- 2 files changed, 4 insertions(+), 16 deletions(-) delete mode 100644 plugins/CuraDrive/src/qml/components/Divider.qml diff --git a/plugins/CuraDrive/src/qml/components/BackupList.qml b/plugins/CuraDrive/src/qml/components/BackupList.qml index 10ca15afe5..afa9538486 100644 --- a/plugins/CuraDrive/src/qml/components/BackupList.qml +++ b/plugins/CuraDrive/src/qml/components/BackupList.qml @@ -26,10 +26,11 @@ ScrollView width: parent.width } - Divider + Rectangle { - width: parent.width - anchors.top: backupListItem.bottom + id: divider + color: UM.Theme.getColor("lining") + height: UM.Theme.getSize("default_lining").height } } } diff --git a/plugins/CuraDrive/src/qml/components/Divider.qml b/plugins/CuraDrive/src/qml/components/Divider.qml deleted file mode 100644 index 202794fe23..0000000000 --- a/plugins/CuraDrive/src/qml/components/Divider.qml +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.7 - -import UM 1.3 as UM - -Rectangle -{ - id: divider - color: UM.Theme.getColor("lining") - height: UM.Theme.getSize("default_lining").height -} From bca070d567937f5743b3707f25d84a095e1e31d9 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 4 Jan 2019 11:41:21 +0100 Subject: [PATCH 1194/1292] Fixed typing CURA-6005 --- cura/API/Backups.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cura/API/Backups.py b/cura/API/Backups.py index 8e5cd7b83a..ef74e74be0 100644 --- a/cura/API/Backups.py +++ b/cura/API/Backups.py @@ -1,6 +1,6 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import Tuple, Optional, TYPE_CHECKING +from typing import Tuple, Optional, TYPE_CHECKING, Dict, Any from cura.Backups.BackupsManager import BackupsManager @@ -24,12 +24,12 @@ class Backups: ## Create a new back-up using the BackupsManager. # \return Tuple containing a ZIP file with the back-up data and a dict # with metadata about the back-up. - def createBackup(self) -> Tuple[Optional[bytes], Optional[dict]]: + def createBackup(self) -> Tuple[Optional[bytes], Optional[Dict[str, Any]]]: return self.manager.createBackup() ## Restore a back-up using the BackupsManager. # \param zip_file A ZIP file containing the actual back-up data. # \param meta_data Some metadata needed for restoring a back-up, like the # Cura version number. - def restoreBackup(self, zip_file: bytes, meta_data: dict) -> None: + def restoreBackup(self, zip_file: bytes, meta_data: Dict[str, Any]) -> None: return self.manager.restoreBackup(zip_file, meta_data) From b363be4afb861bb128357433d765bdc69104d746 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 4 Jan 2019 11:48:06 +0100 Subject: [PATCH 1195/1292] Fix typing --- cura/UltimakerCloudAuthentication.py | 2 +- plugins/CuraDrive/src/DrivePluginExtension.py | 4 ++-- plugins/Toolbox/src/Toolbox.py | 3 --- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/cura/UltimakerCloudAuthentication.py b/cura/UltimakerCloudAuthentication.py index 7ebdfd054b..ac752231b9 100644 --- a/cura/UltimakerCloudAuthentication.py +++ b/cura/UltimakerCloudAuthentication.py @@ -5,7 +5,7 @@ # Constants used for the Cloud API # --------- DEFAULT_CLOUD_API_ROOT = "https://api.ultimaker.com" # type: str -DEFAULT_CLOUD_API_VERSION = "1" # type: str +DEFAULT_CLOUD_API_VERSION = 1 # type: int DEFAULT_CLOUD_ACCOUNT_API_ROOT = "https://account.ultimaker.com" # type: str try: diff --git a/plugins/CuraDrive/src/DrivePluginExtension.py b/plugins/CuraDrive/src/DrivePluginExtension.py index 8944b9a980..baa8ce092e 100644 --- a/plugins/CuraDrive/src/DrivePluginExtension.py +++ b/plugins/CuraDrive/src/DrivePluginExtension.py @@ -3,7 +3,7 @@ import os from datetime import datetime -from typing import Optional, List +from typing import Optional, List, Dict, Any from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal @@ -41,7 +41,7 @@ class DrivePluginExtension(QObject, Extension): # Local data caching for the UI. self._drive_window = None # type: Optional[QObject] - self._backups = [] + self._backups = [] # type: List[Dict[str, Any]] self._is_restoring_backup = False self._is_creating_backup = False diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index e7e849f1d2..192471a357 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -31,9 +31,6 @@ i18n_catalog = i18nCatalog("cura") ## The Toolbox class is responsible of communicating with the server through the API class Toolbox(QObject, Extension): - DEFAULT_CLOUD_API_ROOT = "https://api.ultimaker.com" # type: str - DEFAULT_CLOUD_API_VERSION = 1 # type: int - def __init__(self, application: CuraApplication) -> None: super().__init__() From b4b7e1fc2138718a92a3470254c957d99a2d2b9d Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 4 Jan 2019 11:50:02 +0100 Subject: [PATCH 1196/1292] Codestyle & typing --- plugins/CuraDrive/__init__.py | 2 ++ plugins/CuraDrive/src/DriveApiService.py | 3 +-- plugins/CuraDrive/src/DrivePluginExtension.py | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/CuraDrive/__init__.py b/plugins/CuraDrive/__init__.py index dd7ffeaac3..eeb6b78689 100644 --- a/plugins/CuraDrive/__init__.py +++ b/plugins/CuraDrive/__init__.py @@ -3,8 +3,10 @@ from .src.DrivePluginExtension import DrivePluginExtension + def getMetaData(): return {} + def register(app): return {"extension": DrivePluginExtension()} diff --git a/plugins/CuraDrive/src/DriveApiService.py b/plugins/CuraDrive/src/DriveApiService.py index 79f49bf1a3..23e70a978c 100644 --- a/plugins/CuraDrive/src/DriveApiService.py +++ b/plugins/CuraDrive/src/DriveApiService.py @@ -110,7 +110,7 @@ class DriveApiService: self._cura_api.backups.restoreBackup(read_backup.read(), backup.get("metadata", {})) self.restoringStateChanged.emit(is_restoring = False) - def _emitRestoreError(self): + def _emitRestoreError(self) -> None: self.restoringStateChanged.emit(is_restoring = False, error_message = catalog.i18nc("@info:backup_status", "There was an error trying to restore your backup.")) @@ -144,7 +144,6 @@ class DriveApiService: # \param backup_size The size of the backup file in bytes. # \return: The upload URL for the actual backup file if successful, otherwise None. def _requestBackupUpload(self, backup_metadata: Dict[str, Any], backup_size: int) -> Optional[str]: - access_token = self._cura_api.account.accessToken if not access_token: Logger.log("w", "Could not get access token.") diff --git a/plugins/CuraDrive/src/DrivePluginExtension.py b/plugins/CuraDrive/src/DrivePluginExtension.py index baa8ce092e..fdf7fc1609 100644 --- a/plugins/CuraDrive/src/DrivePluginExtension.py +++ b/plugins/CuraDrive/src/DrivePluginExtension.py @@ -121,7 +121,7 @@ class DrivePluginExtension(QObject, Extension): return bool(self._preferences.getValue(Settings.AUTO_BACKUP_ENABLED_PREFERENCE_KEY)) @pyqtProperty("QVariantList", notify = backupsChanged) - def backups(self) -> List: + def backups(self) -> List[Dict[str, Any]]: return self._backups @pyqtSlot(name = "refreshBackups") From ffce9bd1723b71c42c0c5d0b34e4f94130cab3c3 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 4 Jan 2019 14:59:26 +0100 Subject: [PATCH 1197/1292] Ensure that the primetower gets drawn in the right color again CURA-5932 --- cura/LayerPolygon.py | 11 +++++++--- plugins/CuraEngineBackend/Cura.proto | 1 + .../ProcessSlicedLayersJob.py | 1 + plugins/SimulationView/layers3d.shader | 2 +- plugins/SimulationView/layers_shadow.shader | 20 ++++++++++++------- resources/themes/cura-light/theme.json | 1 + 6 files changed, 25 insertions(+), 11 deletions(-) diff --git a/cura/LayerPolygon.py b/cura/LayerPolygon.py index f33934de0c..1941a558ba 100644 --- a/cura/LayerPolygon.py +++ b/cura/LayerPolygon.py @@ -5,6 +5,8 @@ from UM.Application import Application from typing import Any import numpy +from UM.Logger import Logger + class LayerPolygon: NoneType = 0 @@ -18,7 +20,8 @@ class LayerPolygon: MoveCombingType = 8 MoveRetractionType = 9 SupportInterfaceType = 10 - __number_of_types = 11 + PrimeTower = 11 + __number_of_types = 12 __jump_map = numpy.logical_or(numpy.logical_or(numpy.arange(__number_of_types) == NoneType, numpy.arange(__number_of_types) == MoveCombingType), numpy.arange(__number_of_types) == MoveRetractionType) @@ -33,7 +36,8 @@ class LayerPolygon: self._extruder = extruder self._types = line_types for i in range(len(self._types)): - if self._types[i] >= self.__number_of_types: #Got faulty line data from the engine. + if self._types[i] >= self.__number_of_types: # Got faulty line data from the engine. + Logger.log("w", "Found an unknown line type: %s", i) self._types[i] = self.NoneType self._data = data self._line_widths = line_widths @@ -236,7 +240,8 @@ class LayerPolygon: theme.getColor("layerview_support_infill").getRgbF(), # SupportInfillType theme.getColor("layerview_move_combing").getRgbF(), # MoveCombingType theme.getColor("layerview_move_retraction").getRgbF(), # MoveRetractionType - theme.getColor("layerview_support_interface").getRgbF() # SupportInterfaceType + theme.getColor("layerview_support_interface").getRgbF(), # SupportInterfaceType + theme.getColor("layerview_prime_tower").getRgbF() ]) return cls.__color_map diff --git a/plugins/CuraEngineBackend/Cura.proto b/plugins/CuraEngineBackend/Cura.proto index c4f934bc00..2eabe62366 100644 --- a/plugins/CuraEngineBackend/Cura.proto +++ b/plugins/CuraEngineBackend/Cura.proto @@ -58,6 +58,7 @@ message Polygon { MoveCombingType = 8; MoveRetractionType = 9; SupportInterfaceType = 10; + PrimeTowerType = 11; } Type type = 1; // Type of move bytes points = 2; // The points of the polygon, or two points if only a line segment (Currently only line segments are used) diff --git a/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py b/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py index 71c96880e8..3cc23130ea 100644 --- a/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py +++ b/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py @@ -137,6 +137,7 @@ class ProcessSlicedLayersJob(Job): extruder = polygon.extruder line_types = numpy.fromstring(polygon.line_type, dtype="u1") # Convert bytearray to numpy array + line_types = line_types.reshape((-1,1)) points = numpy.fromstring(polygon.points, dtype="f4") # Convert bytearray to numpy array diff --git a/plugins/SimulationView/layers3d.shader b/plugins/SimulationView/layers3d.shader index de2b9335d8..a277606509 100644 --- a/plugins/SimulationView/layers3d.shader +++ b/plugins/SimulationView/layers3d.shader @@ -154,7 +154,7 @@ geometry41core = if ((u_show_travel_moves == 0) && ((v_line_type[0] == 8) || (v_line_type[0] == 9))) { return; } - if ((u_show_helpers == 0) && ((v_line_type[0] == 4) || (v_line_type[0] == 5) || (v_line_type[0] == 7) || (v_line_type[0] == 10))) { + if ((u_show_helpers == 0) && ((v_line_type[0] == 4) || (v_line_type[0] == 5) || (v_line_type[0] == 7) || (v_line_type[0] == 10) || v_line_type[0] == 11)) { return; } if ((u_show_skin == 0) && ((v_line_type[0] == 1) || (v_line_type[0] == 2) || (v_line_type[0] == 3))) { diff --git a/plugins/SimulationView/layers_shadow.shader b/plugins/SimulationView/layers_shadow.shader index 7ceccff21e..6149cc1703 100644 --- a/plugins/SimulationView/layers_shadow.shader +++ b/plugins/SimulationView/layers_shadow.shader @@ -45,19 +45,23 @@ fragment = void main() { - if ((u_show_travel_moves == 0) && (v_line_type >= 7.5) && (v_line_type <= 9.5)) { // actually, 8 and 9 + if ((u_show_travel_moves == 0) && (v_line_type >= 7.5) && (v_line_type <= 9.5)) + { // actually, 8 and 9 // discard movements discard; } - // support: 4, 5, 7, 10 + // support: 4, 5, 7, 10, 11 if ((u_show_helpers == 0) && ( ((v_line_type >= 3.5) && (v_line_type <= 4.5)) || ((v_line_type >= 6.5) && (v_line_type <= 7.5)) || ((v_line_type >= 9.5) && (v_line_type <= 10.5)) || - ((v_line_type >= 4.5) && (v_line_type <= 5.5)) - )) { + ((v_line_type >= 4.5) && (v_line_type <= 5.5)) || + ((v_line_type >= 10.5) && (v_line_type <= 11.5)) + )) + { discard; } + // skin: 1, 2, 3 if ((u_show_skin == 0) && ( (v_line_type >= 0.5) && (v_line_type <= 3.5) @@ -65,7 +69,8 @@ fragment = discard; } // infill: - if ((u_show_infill == 0) && (v_line_type >= 5.5) && (v_line_type <= 6.5)) { + if ((u_show_infill == 0) && (v_line_type >= 5.5) && (v_line_type <= 6.5)) + { // discard movements discard; } @@ -117,12 +122,13 @@ fragment41core = // discard movements discard; } - // helpers: 4, 5, 7, 10 + // helpers: 4, 5, 7, 10, 11 if ((u_show_helpers == 0) && ( ((v_line_type >= 3.5) && (v_line_type <= 4.5)) || ((v_line_type >= 6.5) && (v_line_type <= 7.5)) || ((v_line_type >= 9.5) && (v_line_type <= 10.5)) || - ((v_line_type >= 4.5) && (v_line_type <= 5.5)) + ((v_line_type >= 4.5) && (v_line_type <= 5.5)) || + ((v_line_type >= 10.5) && (v_line_type <= 11.5)) )) { discard; } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 2b9ce3d218..9770994e74 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -294,6 +294,7 @@ "layerview_move_combing": [0, 0, 255, 255], "layerview_move_retraction": [128, 128, 255, 255], "layerview_support_interface": [64, 192, 255, 255], + "layerview_prime_tower": [0, 255, 255, 255], "layerview_nozzle": [181, 166, 66, 50], "tab_status_connected": [50, 130, 255, 255], From 4c1f68a44727f9d3c303d85c418bf4a62b3b6b01 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 4 Jan 2019 15:24:01 +0100 Subject: [PATCH 1198/1292] Ensure that the connectiontype of a connected printer is set correctly CURA-6011 --- plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py index 80212fcf00..57bc96b0e0 100644 --- a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py +++ b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py @@ -114,6 +114,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): if key == um_network_key: if not self._discovered_devices[key].isConnected(): Logger.log("d", "Attempting to connect with [%s]" % key) + active_machine.setMetaDataEntry("connection_type", self._discovered_devices[key].getConnectionType().value) self._discovered_devices[key].connect() self._discovered_devices[key].connectionStateChanged.connect(self._onDeviceConnectionStateChanged) else: From f631332dc2297c6301b85ba3adec4078e3bdd2e1 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Sat, 5 Jan 2019 00:03:48 +0100 Subject: [PATCH 1199/1292] Fix z-fighting on bottom layer of x-ray view --- plugins/XRayView/XRayView.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/XRayView/XRayView.py b/plugins/XRayView/XRayView.py index 0c4035c62d..86533fe51c 100644 --- a/plugins/XRayView/XRayView.py +++ b/plugins/XRayView/XRayView.py @@ -17,6 +17,7 @@ from UM.View.RenderBatch import RenderBatch from UM.View.GL.OpenGL import OpenGL from cura.CuraApplication import CuraApplication +from cura.Scene.ConvexHullNode import ConvexHullNode from . import XRayPass @@ -41,6 +42,10 @@ class XRayView(View): self._xray_shader.setUniformValue("u_color", Color(*Application.getInstance().getTheme().getColor("xray").getRgb())) for node in BreadthFirstIterator(scene.getRoot()): + # We do not want to render ConvexHullNode as it conflicts with the bottom of the X-Ray (z-fighting). + if type(node) is ConvexHullNode: + continue + if not node.render(renderer): if node.getMeshData() and node.isVisible(): renderer.queueNode(node, From 39cdb3ed0a115ce52dcff1bc2c57512241c40748 Mon Sep 17 00:00:00 2001 From: Nico Salvador Date: Sun, 6 Jan 2019 10:19:21 +0800 Subject: [PATCH 1200/1292] Fixed typo in ChangeAtZ.py --- plugins/PostProcessingPlugin/scripts/ChangeAtZ.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/PostProcessingPlugin/scripts/ChangeAtZ.py b/plugins/PostProcessingPlugin/scripts/ChangeAtZ.py index 919b06d28e..be9f93c0f6 100644 --- a/plugins/PostProcessingPlugin/scripts/ChangeAtZ.py +++ b/plugins/PostProcessingPlugin/scripts/ChangeAtZ.py @@ -112,7 +112,7 @@ class ChangeAtZ(Script): "e1_Change_speed": { "label": "Change Speed", - "description": "Select if total speed (print and travel) has to be cahnged", + "description": "Select if total speed (print and travel) has to be changed", "type": "bool", "default_value": false }, From d21bf53230a52a768d7794efc02fc3f7f318fa2a Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 7 Jan 2019 10:33:14 +0100 Subject: [PATCH 1201/1292] Add version upgrade for 4.0 Contributes to CURA-6011 and CURA-5995 --- cura/CuraApplication.py | 2 +- .../VersionUpgrade35to40.py | 68 +++++++++++++++++++ .../VersionUpgrade35to40/__init__.py | 56 +++++++++++++++ .../VersionUpgrade35to40/plugin.json | 8 +++ .../quality/abax_pri3/apri3_pla_fast.inst.cfg | 2 +- .../quality/abax_pri3/apri3_pla_high.inst.cfg | 2 +- .../abax_pri3/apri3_pla_normal.inst.cfg | 2 +- .../quality/abax_pri5/apri5_pla_fast.inst.cfg | 2 +- .../quality/abax_pri5/apri5_pla_high.inst.cfg | 2 +- .../abax_pri5/apri5_pla_normal.inst.cfg | 2 +- .../abax_titan/atitan_pla_fast.inst.cfg | 2 +- .../abax_titan/atitan_pla_high.inst.cfg | 2 +- .../abax_titan/atitan_pla_normal.inst.cfg | 2 +- .../abs/anycubic_4max_abs_draft.inst.cfg | 2 +- .../abs/anycubic_4max_abs_high.inst.cfg | 2 +- .../abs/anycubic_4max_abs_normal.inst.cfg | 2 +- .../anycubic_4max_draft.inst.cfg | 2 +- .../anycubic_4max/anycubic_4max_high.inst.cfg | 2 +- .../anycubic_4max_normal.inst.cfg | 2 +- .../hips/anycubic_4max_hips_draft.inst.cfg | 2 +- .../hips/anycubic_4max_hips_high.inst.cfg | 2 +- .../hips/anycubic_4max_hips_normal.inst.cfg | 2 +- .../petg/anycubic_4max_petg_draft.inst.cfg | 2 +- .../petg/anycubic_4max_petg_high.inst.cfg | 2 +- .../petg/anycubic_4max_petg_normal.inst.cfg | 2 +- .../pla/anycubic_4max_pla_draft.inst.cfg | 2 +- .../pla/anycubic_4max_pla_high.inst.cfg | 2 +- .../pla/anycubic_4max_pla_normal.inst.cfg | 2 +- .../anycubic_i3_mega_draft.inst.cfg | 2 +- .../anycubic_i3_mega_high.inst.cfg | 2 +- .../anycubic_i3_mega_normal.inst.cfg | 2 +- .../bp_BVOH_Coarse_Quality.inst.cfg | 2 +- .../bp_BVOH_High_Quality.inst.cfg | 2 +- .../bp_BVOH_Normal_Quality.inst.cfg | 2 +- .../bp_Innoflex60_Coarse_Quality.inst.cfg | 2 +- .../bp_Innoflex60_High_Quality.inst.cfg | 2 +- .../bp_Innoflex60_Normal_Quality.inst.cfg | 2 +- .../bp_PET_Coarse_Quality.inst.cfg | 2 +- .../bp_PET_High_Quality.inst.cfg | 2 +- .../bp_PET_Normal_Quality.inst.cfg | 2 +- .../bp_PLA_Coarse_Quality.inst.cfg | 2 +- .../bp_PLA_High_Quality.inst.cfg | 2 +- .../bp_PLA_Normal_Quality.inst.cfg | 2 +- .../bp_PVA_Coarse_Quality.inst.cfg | 2 +- .../bp_PVA_High_Quality.inst.cfg | 2 +- .../bp_PVA_Normal_Quality.inst.cfg | 2 +- .../bp_global_Coarse_Quality.inst.cfg | 2 +- .../bp_global_High_Quality.inst.cfg | 2 +- .../bp_global_Normal_Quality.inst.cfg | 2 +- .../abs/cartesio_0.25_abs_high.inst.cfg | 2 +- .../abs/cartesio_0.25_abs_normal.inst.cfg | 2 +- .../abs/cartesio_0.4_abs_high.inst.cfg | 2 +- .../abs/cartesio_0.4_abs_normal.inst.cfg | 2 +- .../abs/cartesio_0.8_abs_coarse.inst.cfg | 2 +- .../cartesio_0.8_abs_extra_coarse.inst.cfg | 2 +- .../abs/cartesio_0.8_abs_high.inst.cfg | 2 +- .../abs/cartesio_0.8_abs_normal.inst.cfg | 2 +- .../cartesio_0.4_arnitel2045_high.inst.cfg | 2 +- .../cartesio_0.4_arnitel2045_normal.inst.cfg | 2 +- .../cartesio_global_Coarse_Quality.inst.cfg | 2 +- ...tesio_global_Extra_Coarse_Quality.inst.cfg | 2 +- .../cartesio_global_High_Quality.inst.cfg | 2 +- .../cartesio_global_Normal_Quality.inst.cfg | 2 +- .../hips/cartesio_0.25_hips_high.inst.cfg | 2 +- .../hips/cartesio_0.25_hips_normal.inst.cfg | 2 +- .../hips/cartesio_0.4_hips_high.inst.cfg | 2 +- .../hips/cartesio_0.4_hips_normal.inst.cfg | 2 +- .../hips/cartesio_0.8_hips_coarse.inst.cfg | 2 +- .../cartesio_0.8_hips_extra_coarse.inst.cfg | 2 +- .../hips/cartesio_0.8_hips_high.inst.cfg | 2 +- .../hips/cartesio_0.8_hips_normal.inst.cfg | 2 +- .../nylon/cartesio_0.25_nylon_high.inst.cfg | 2 +- .../nylon/cartesio_0.25_nylon_normal.inst.cfg | 2 +- .../nylon/cartesio_0.4_nylon_high.inst.cfg | 2 +- .../nylon/cartesio_0.4_nylon_normal.inst.cfg | 2 +- .../nylon/cartesio_0.8_nylon_coarse.inst.cfg | 2 +- .../cartesio_0.8_nylon_extra_coarse.inst.cfg | 2 +- .../nylon/cartesio_0.8_nylon_high.inst.cfg | 2 +- .../nylon/cartesio_0.8_nylon_normal.inst.cfg | 2 +- .../pc/cartesio_0.25_pc_high.inst.cfg | 2 +- .../pc/cartesio_0.25_pc_normal.inst.cfg | 2 +- .../cartesio/pc/cartesio_0.4_pc_high.inst.cfg | 2 +- .../pc/cartesio_0.4_pc_normal.inst.cfg | 2 +- .../pc/cartesio_0.8_pc_coarse.inst.cfg | 2 +- .../pc/cartesio_0.8_pc_extra_coarse.inst.cfg | 2 +- .../cartesio/pc/cartesio_0.8_pc_high.inst.cfg | 2 +- .../pc/cartesio_0.8_pc_normal.inst.cfg | 2 +- .../petg/cartesio_0.25_petg_high.inst.cfg | 2 +- .../petg/cartesio_0.25_petg_normal.inst.cfg | 2 +- .../petg/cartesio_0.4_petg_high.inst.cfg | 2 +- .../petg/cartesio_0.4_petg_normal.inst.cfg | 2 +- .../petg/cartesio_0.8_petg_coarse.inst.cfg | 2 +- .../cartesio_0.8_petg_extra_coarse.inst.cfg | 2 +- .../petg/cartesio_0.8_petg_high.inst.cfg | 2 +- .../petg/cartesio_0.8_petg_normal.inst.cfg | 2 +- .../pla/cartesio_0.25_pla_high.inst.cfg | 2 +- .../pla/cartesio_0.25_pla_normal.inst.cfg | 2 +- .../pla/cartesio_0.4_pla_high.inst.cfg | 2 +- .../pla/cartesio_0.4_pla_normal.inst.cfg | 2 +- .../pla/cartesio_0.8_pla_coarse.inst.cfg | 2 +- .../cartesio_0.8_pla_extra_coarse.inst.cfg | 2 +- .../pla/cartesio_0.8_pla_high.inst.cfg | 2 +- .../pla/cartesio_0.8_pla_normal.inst.cfg | 2 +- .../pva/cartesio_0.25_pva_high.inst.cfg | 2 +- .../pva/cartesio_0.25_pva_normal.inst.cfg | 2 +- .../pva/cartesio_0.4_pva_high.inst.cfg | 2 +- .../pva/cartesio_0.4_pva_normal.inst.cfg | 2 +- .../pva/cartesio_0.8_pva_coarse.inst.cfg | 2 +- .../cartesio_0.8_pva_extra_coarse.inst.cfg | 2 +- .../pva/cartesio_0.8_pva_high.inst.cfg | 2 +- .../pva/cartesio_0.8_pva_normal.inst.cfg | 2 +- resources/quality/coarse.inst.cfg | 2 +- .../dagoma_discoeasy200_pla_fast.inst.cfg | 2 +- .../dagoma_discoeasy200_pla_fine.inst.cfg | 2 +- .../dagoma_discoeasy200_pla_standard.inst.cfg | 2 +- .../dagoma/dagoma_global_fast.inst.cfg | 2 +- .../dagoma/dagoma_global_fine.inst.cfg | 2 +- .../dagoma/dagoma_global_standard.inst.cfg | 2 +- .../dagoma/dagoma_magis_pla_fast.inst.cfg | 2 +- .../dagoma/dagoma_magis_pla_fine.inst.cfg | 2 +- .../dagoma/dagoma_magis_pla_standard.inst.cfg | 2 +- .../dagoma/dagoma_neva_pla_fast.inst.cfg | 2 +- .../dagoma/dagoma_neva_pla_fine.inst.cfg | 2 +- .../dagoma/dagoma_neva_pla_standard.inst.cfg | 2 +- .../deltacomb_abs_Draft_Quality.inst.cfg | 2 +- .../deltacomb_abs_Fast_Quality.inst.cfg | 2 +- .../deltacomb_abs_High_Quality.inst.cfg | 2 +- .../deltacomb_abs_Normal_Quality.inst.cfg | 2 +- .../deltacomb_abs_Verydraft_Quality.inst.cfg | 2 +- .../deltacomb_global_Draft_Quality.inst.cfg | 2 +- .../deltacomb_global_Fast_Quality.inst.cfg | 2 +- .../deltacomb_global_High_Quality.inst.cfg | 2 +- .../deltacomb_global_Normal_Quality.inst.cfg | 2 +- ...eltacomb_global_Verydraft_Quality.inst.cfg | 2 +- .../deltacomb_pla_Draft_Quality.inst.cfg | 2 +- .../deltacomb_pla_Fast_Quality.inst.cfg | 2 +- .../deltacomb_pla_High_Quality.inst.cfg | 2 +- .../deltacomb_pla_Normal_Quality.inst.cfg | 2 +- .../deltacomb_pla_Verydraft_Quality.inst.cfg | 2 +- resources/quality/draft.inst.cfg | 2 +- resources/quality/extra_coarse.inst.cfg | 2 +- resources/quality/extra_fast.inst.cfg | 2 +- .../fabtotum/fabtotum_abs_fast.inst.cfg | 2 +- .../fabtotum/fabtotum_abs_high.inst.cfg | 2 +- .../fabtotum/fabtotum_abs_normal.inst.cfg | 2 +- .../fabtotum/fabtotum_nylon_fast.inst.cfg | 2 +- .../fabtotum/fabtotum_nylon_high.inst.cfg | 2 +- .../fabtotum/fabtotum_nylon_normal.inst.cfg | 2 +- .../fabtotum/fabtotum_pla_fast.inst.cfg | 2 +- .../fabtotum/fabtotum_pla_high.inst.cfg | 2 +- .../fabtotum/fabtotum_pla_normal.inst.cfg | 2 +- .../fabtotum/fabtotum_tpu_fast.inst.cfg | 2 +- .../fabtotum/fabtotum_tpu_high.inst.cfg | 2 +- .../fabtotum/fabtotum_tpu_normal.inst.cfg | 2 +- resources/quality/fast.inst.cfg | 2 +- .../gmax15plus_pla_dual_normal.inst.cfg | 2 +- .../gmax15plus_pla_dual_thick.inst.cfg | 2 +- .../gmax15plus_pla_dual_thin.inst.cfg | 2 +- .../gmax15plus_pla_dual_very_thick.inst.cfg | 2 +- .../gmax15plus/gmax15plus_pla_normal.inst.cfg | 2 +- .../gmax15plus/gmax15plus_pla_thick.inst.cfg | 2 +- .../gmax15plus/gmax15plus_pla_thin.inst.cfg | 2 +- .../gmax15plus_pla_very_thick.inst.cfg | 2 +- resources/quality/high.inst.cfg | 2 +- .../generic_petg_0.4_coarse.inst.cfg | 2 +- .../generic_petg_0.4_coarse_2-fans.inst.cfg | 2 +- .../generic_petg_0.4_medium.inst.cfg | 2 +- .../generic_petg_0.4_medium_2-fans.inst.cfg | 2 +- .../generic_pla_0.4_coarse.inst.cfg | 2 +- .../generic_pla_0.4_coarse_2-fans.inst.cfg | 2 +- .../generic_pla_0.4_fine.inst.cfg | 2 +- .../generic_pla_0.4_fine_2-fans.inst.cfg | 2 +- .../generic_pla_0.4_medium.inst.cfg | 2 +- .../generic_pla_0.4_medium_2-fans.inst.cfg | 2 +- .../generic_pla_0.4_ultrafine.inst.cfg | 2 +- .../generic_pla_0.4_ultrafine_2-fans.inst.cfg | 2 +- .../imade3d_jellybox_coarse.inst.cfg | 2 +- .../imade3d_jellybox_fine.inst.cfg | 2 +- .../imade3d_jellybox_normal.inst.cfg | 2 +- .../imade3d_jellybox_ultrafine.inst.cfg | 2 +- .../kemiq_q2/kemiq_q2_beta_abs_draft.inst.cfg | 2 +- .../kemiq_q2_beta_abs_extra_fine.inst.cfg | 2 +- .../kemiq_q2/kemiq_q2_beta_abs_fine.inst.cfg | 2 +- .../kemiq_q2/kemiq_q2_beta_abs_low.inst.cfg | 2 +- .../kemiq_q2_beta_abs_normal.inst.cfg | 2 +- .../kemiq_q2/kemiq_q2_beta_pla_draft.inst.cfg | 2 +- .../kemiq_q2_beta_pla_extra_fine.inst.cfg | 2 +- .../kemiq_q2/kemiq_q2_beta_pla_fine.inst.cfg | 2 +- .../kemiq_q2/kemiq_q2_beta_pla_low.inst.cfg | 2 +- .../kemiq_q2_beta_pla_normal.inst.cfg | 2 +- .../kemiq_q2/kemiq_q2_gama_pla_draft.inst.cfg | 2 +- .../kemiq_q2_gama_pla_extra_fine.inst.cfg | 2 +- .../kemiq_q2/kemiq_q2_gama_pla_fine.inst.cfg | 2 +- .../kemiq_q2/kemiq_q2_gama_pla_low.inst.cfg | 2 +- .../kemiq_q2_gama_pla_normal.inst.cfg | 2 +- .../abs/malyan_m200_abs_draft.inst.cfg | 2 +- .../abs/malyan_m200_abs_fast.inst.cfg | 2 +- .../abs/malyan_m200_abs_high.inst.cfg | 2 +- .../abs/malyan_m200_abs_normal.inst.cfg | 2 +- .../abs/malyan_m200_abs_superdraft.inst.cfg | 2 +- .../abs/malyan_m200_abs_thickerdraft.inst.cfg | 2 +- .../abs/malyan_m200_abs_ultra.inst.cfg | 2 +- .../abs/malyan_m200_abs_verydraft.inst.cfg | 2 +- .../malyan_m200_global_Draft_Quality.inst.cfg | 2 +- .../malyan_m200_global_Fast_Quality.inst.cfg | 2 +- .../malyan_m200_global_High_Quality.inst.cfg | 2 +- ...malyan_m200_global_Normal_Quality.inst.cfg | 2 +- ...an_m200_global_SuperDraft_Quality.inst.cfg | 2 +- ..._m200_global_ThickerDraft_Quality.inst.cfg | 2 +- .../malyan_m200_global_Ultra_Quality.inst.cfg | 2 +- ...yan_m200_global_VeryDraft_Quality.inst.cfg | 2 +- .../petg/malyan_m200_petg_draft.inst.cfg | 2 +- .../petg/malyan_m200_petg_fast.inst.cfg | 2 +- .../petg/malyan_m200_petg_high.inst.cfg | 2 +- .../petg/malyan_m200_petg_normal.inst.cfg | 2 +- .../petg/malyan_m200_petg_superdraft.inst.cfg | 2 +- .../malyan_m200_petg_thickerdraft.inst.cfg | 2 +- .../petg/malyan_m200_petg_ultra.inst.cfg | 2 +- .../petg/malyan_m200_petg_verydraft.inst.cfg | 2 +- .../pla/malyan_m200_pla_draft.inst.cfg | 2 +- .../pla/malyan_m200_pla_fast.inst.cfg | 2 +- .../pla/malyan_m200_pla_high.inst.cfg | 2 +- .../pla/malyan_m200_pla_normal.inst.cfg | 2 +- .../pla/malyan_m200_pla_superdraft.inst.cfg | 2 +- .../pla/malyan_m200_pla_thickerdraft.inst.cfg | 2 +- .../pla/malyan_m200_pla_ultra.inst.cfg | 2 +- .../pla/malyan_m200_pla_verydraft.inst.cfg | 2 +- ...onoprice_select_mini_v2_abs_draft.inst.cfg | 2 +- ...monoprice_select_mini_v2_abs_fast.inst.cfg | 2 +- ...monoprice_select_mini_v2_abs_high.inst.cfg | 2 +- ...noprice_select_mini_v2_abs_normal.inst.cfg | 2 +- ...ice_select_mini_v2_abs_superdraft.inst.cfg | 2 +- ...e_select_mini_v2_abs_thickerdraft.inst.cfg | 2 +- ...onoprice_select_mini_v2_abs_ultra.inst.cfg | 2 +- ...rice_select_mini_v2_abs_verydraft.inst.cfg | 2 +- ...lect_mini_v2_global_Draft_Quality.inst.cfg | 2 +- ...elect_mini_v2_global_Fast_Quality.inst.cfg | 2 +- ...elect_mini_v2_global_High_Quality.inst.cfg | 2 +- ...ect_mini_v2_global_Normal_Quality.inst.cfg | 2 +- ...mini_v2_global_SuperDraft_Quality.inst.cfg | 2 +- ...ni_v2_global_ThickerDraft_Quality.inst.cfg | 2 +- ...lect_mini_v2_global_Ultra_Quality.inst.cfg | 2 +- ..._mini_v2_global_VeryDraft_Quality.inst.cfg | 2 +- ...oprice_select_mini_v2_nylon_draft.inst.cfg | 2 +- ...noprice_select_mini_v2_nylon_fast.inst.cfg | 2 +- ...noprice_select_mini_v2_nylon_high.inst.cfg | 2 +- ...price_select_mini_v2_nylon_normal.inst.cfg | 2 +- ...e_select_mini_v2_nylon_superdraft.inst.cfg | 2 +- ...select_mini_v2_nylon_thickerdraft.inst.cfg | 2 +- ...oprice_select_mini_v2_nylon_ultra.inst.cfg | 2 +- ...ce_select_mini_v2_nylon_verydraft.inst.cfg | 2 +- ...monoprice_select_mini_v2_pc_draft.inst.cfg | 2 +- .../monoprice_select_mini_v2_pc_fast.inst.cfg | 2 +- .../monoprice_select_mini_v2_pc_high.inst.cfg | 2 +- ...onoprice_select_mini_v2_pc_normal.inst.cfg | 2 +- ...rice_select_mini_v2_pc_superdraft.inst.cfg | 2 +- ...ce_select_mini_v2_pc_thickerdraft.inst.cfg | 2 +- ...monoprice_select_mini_v2_pc_ultra.inst.cfg | 2 +- ...price_select_mini_v2_pc_verydraft.inst.cfg | 2 +- ...noprice_select_mini_v2_petg_draft.inst.cfg | 2 +- ...onoprice_select_mini_v2_petg_fast.inst.cfg | 2 +- ...onoprice_select_mini_v2_petg_high.inst.cfg | 2 +- ...oprice_select_mini_v2_petg_normal.inst.cfg | 2 +- ...ce_select_mini_v2_petg_superdraft.inst.cfg | 2 +- ..._select_mini_v2_petg_thickerdraft.inst.cfg | 2 +- ...noprice_select_mini_v2_petg_ultra.inst.cfg | 2 +- ...ice_select_mini_v2_petg_verydraft.inst.cfg | 2 +- ...onoprice_select_mini_v2_pla_draft.inst.cfg | 2 +- ...monoprice_select_mini_v2_pla_fast.inst.cfg | 2 +- ...monoprice_select_mini_v2_pla_high.inst.cfg | 2 +- ...noprice_select_mini_v2_pla_normal.inst.cfg | 2 +- ...ice_select_mini_v2_pla_superdraft.inst.cfg | 2 +- ...e_select_mini_v2_pla_thickerdraft.inst.cfg | 2 +- ...onoprice_select_mini_v2_pla_ultra.inst.cfg | 2 +- ...rice_select_mini_v2_pla_verydraft.inst.cfg | 2 +- resources/quality/normal.inst.cfg | 2 +- .../peopoly_moai/peopoly_moai_coarse.inst.cfg | 2 +- .../peopoly_moai/peopoly_moai_draft.inst.cfg | 2 +- .../peopoly_moai_extra_high.inst.cfg | 2 +- .../peopoly_moai/peopoly_moai_high.inst.cfg | 2 +- .../peopoly_moai/peopoly_moai_normal.inst.cfg | 2 +- .../tevo_blackwidow_draft.inst.cfg | 2 +- .../tevo_blackwidow_high.inst.cfg | 2 +- .../tevo_blackwidow_normal.inst.cfg | 2 +- .../tizyx_k25/tizyx_k25_normal.inst.cfg | 2 +- .../quality/ultimaker2/um2_draft.inst.cfg | 2 +- .../quality/ultimaker2/um2_fast.inst.cfg | 2 +- .../quality/ultimaker2/um2_high.inst.cfg | 2 +- .../quality/ultimaker2/um2_normal.inst.cfg | 2 +- .../ultimaker2_plus/pla_0.25_normal.inst.cfg | 2 +- .../ultimaker2_plus/pla_0.4_fast.inst.cfg | 2 +- .../ultimaker2_plus/pla_0.4_high.inst.cfg | 2 +- .../ultimaker2_plus/pla_0.4_normal.inst.cfg | 2 +- .../ultimaker2_plus/pla_0.6_normal.inst.cfg | 2 +- .../ultimaker2_plus/pla_0.8_normal.inst.cfg | 2 +- .../um2p_abs_0.25_normal.inst.cfg | 2 +- .../um2p_abs_0.4_fast.inst.cfg | 2 +- .../um2p_abs_0.4_high.inst.cfg | 2 +- .../um2p_abs_0.4_normal.inst.cfg | 2 +- .../um2p_abs_0.6_normal.inst.cfg | 2 +- .../um2p_abs_0.8_normal.inst.cfg | 2 +- .../um2p_cpe_0.25_normal.inst.cfg | 2 +- .../um2p_cpe_0.4_fast.inst.cfg | 2 +- .../um2p_cpe_0.4_high.inst.cfg | 2 +- .../um2p_cpe_0.4_normal.inst.cfg | 2 +- .../um2p_cpe_0.6_normal.inst.cfg | 2 +- .../um2p_cpe_0.8_normal.inst.cfg | 2 +- .../um2p_cpep_0.4_draft.inst.cfg | 2 +- .../um2p_cpep_0.4_normal.inst.cfg | 2 +- .../um2p_cpep_0.6_draft.inst.cfg | 2 +- .../um2p_cpep_0.6_normal.inst.cfg | 2 +- .../um2p_cpep_0.8_draft.inst.cfg | 2 +- .../um2p_cpep_0.8_normal.inst.cfg | 2 +- .../um2p_global_Coarse_Quality.inst.cfg | 2 +- .../um2p_global_Draft_Quality.inst.cfg | 2 +- .../um2p_global_Extra_Coarse_Quality.inst.cfg | 2 +- .../um2p_global_Fast_Quality.inst.cfg | 2 +- .../um2p_global_High_Quality.inst.cfg | 2 +- .../um2p_global_Normal_Quality.inst.cfg | 2 +- .../um2p_nylon_0.25_high.inst.cfg | 2 +- .../um2p_nylon_0.25_normal.inst.cfg | 2 +- .../um2p_nylon_0.4_fast.inst.cfg | 2 +- .../um2p_nylon_0.4_normal.inst.cfg | 2 +- .../um2p_nylon_0.6_fast.inst.cfg | 2 +- .../um2p_nylon_0.6_normal.inst.cfg | 2 +- .../um2p_nylon_0.8_draft.inst.cfg | 2 +- .../um2p_nylon_0.8_normal.inst.cfg | 2 +- .../um2p_pc_0.25_high.inst.cfg | 2 +- .../um2p_pc_0.25_normal.inst.cfg | 2 +- .../ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg | 2 +- .../um2p_pc_0.4_normal.inst.cfg | 2 +- .../ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg | 2 +- .../um2p_pc_0.6_normal.inst.cfg | 2 +- .../um2p_pc_0.8_draft.inst.cfg | 2 +- .../um2p_pc_0.8_normal.inst.cfg | 2 +- .../ultimaker2_plus/um2p_pp_0.4_fast.inst.cfg | 2 +- .../um2p_pp_0.4_normal.inst.cfg | 2 +- .../um2p_pp_0.6_draft.inst.cfg | 2 +- .../ultimaker2_plus/um2p_pp_0.6_fast.inst.cfg | 2 +- .../um2p_pp_0.8_draft.inst.cfg | 2 +- .../um2p_pp_0.8_verydraft.inst.cfg | 2 +- .../um2p_tpu_0.25_high.inst.cfg | 2 +- .../um2p_tpu_0.4_normal.inst.cfg | 2 +- .../um2p_tpu_0.6_fast.inst.cfg | 2 +- .../um3_aa0.25_ABS_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.25_CPE_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.25_Nylon_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.25_PC_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.25_PLA_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.25_PP_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.25_TPLA_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.4_ABS_Draft_Print.inst.cfg | 2 +- .../um3_aa0.4_ABS_Fast_Print.inst.cfg | 2 +- .../um3_aa0.4_ABS_High_Quality.inst.cfg | 2 +- .../um3_aa0.4_ABS_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.4_BAM_Draft_Print.inst.cfg | 2 +- .../um3_aa0.4_BAM_Fast_Print.inst.cfg | 2 +- .../um3_aa0.4_BAM_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.4_CPEP_Draft_Print.inst.cfg | 2 +- .../um3_aa0.4_CPEP_Fast_Print.inst.cfg | 2 +- .../um3_aa0.4_CPEP_High_Quality.inst.cfg | 2 +- .../um3_aa0.4_CPEP_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.4_CPE_Draft_Print.inst.cfg | 2 +- .../um3_aa0.4_CPE_Fast_Print.inst.cfg | 2 +- .../um3_aa0.4_CPE_High_Quality.inst.cfg | 2 +- .../um3_aa0.4_CPE_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.4_Nylon_Draft_Print.inst.cfg | 2 +- .../um3_aa0.4_Nylon_Fast_Print.inst.cfg | 2 +- .../um3_aa0.4_Nylon_High_Quality.inst.cfg | 2 +- .../um3_aa0.4_Nylon_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.4_PC_Draft_Print.inst.cfg | 2 +- .../um3_aa0.4_PC_Fast_Print.inst.cfg | 2 +- .../um3_aa0.4_PC_High_Quality.inst.cfg | 2 +- .../um3_aa0.4_PC_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.4_PLA_Draft_Print.inst.cfg | 2 +- .../um3_aa0.4_PLA_Fast_Print.inst.cfg | 2 +- .../um3_aa0.4_PLA_High_Quality.inst.cfg | 2 +- .../um3_aa0.4_PLA_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.4_PP_Draft_Print.inst.cfg | 2 +- .../um3_aa0.4_PP_Fast_Print.inst.cfg | 2 +- .../um3_aa0.4_PP_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.4_TPLA_Draft_Print.inst.cfg | 2 +- .../um3_aa0.4_TPLA_Fast_Print.inst.cfg | 2 +- .../um3_aa0.4_TPLA_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.4_TPU_Draft_Print.inst.cfg | 2 +- .../um3_aa0.4_TPU_Fast_Print.inst.cfg | 2 +- .../um3_aa0.4_TPU_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.8_ABS_Draft_Print.inst.cfg | 2 +- .../um3_aa0.8_ABS_Superdraft_Print.inst.cfg | 2 +- .../um3_aa0.8_ABS_Verydraft_Print.inst.cfg | 2 +- .../um3_aa0.8_CPEP_Fast_Print.inst.cfg | 2 +- .../um3_aa0.8_CPEP_Superdraft_Print.inst.cfg | 2 +- .../um3_aa0.8_CPEP_Verydraft_Print.inst.cfg | 2 +- .../um3_aa0.8_CPE_Draft_Print.inst.cfg | 2 +- .../um3_aa0.8_CPE_Superdraft_Print.inst.cfg | 2 +- .../um3_aa0.8_CPE_Verydraft_Print.inst.cfg | 2 +- .../um3_aa0.8_Nylon_Draft_Print.inst.cfg | 2 +- .../um3_aa0.8_Nylon_Superdraft_Print.inst.cfg | 2 +- .../um3_aa0.8_Nylon_Verydraft_Print.inst.cfg | 2 +- .../um3_aa0.8_PC_Fast_Print.inst.cfg | 2 +- .../um3_aa0.8_PC_Superdraft_Print.inst.cfg | 2 +- .../um3_aa0.8_PC_Verydraft_Print.inst.cfg | 2 +- .../um3_aa0.8_PLA_Draft_Print.inst.cfg | 2 +- .../um3_aa0.8_PLA_Superdraft_Print.inst.cfg | 2 +- .../um3_aa0.8_PLA_Verydraft_Print.inst.cfg | 2 +- .../um3_aa0.8_PP_Draft_Print.inst.cfg | 2 +- .../um3_aa0.8_PP_Superdraft_Print.inst.cfg | 2 +- .../um3_aa0.8_PP_Verydraft_Print.inst.cfg | 2 +- .../um3_aa0.8_TPLA_Draft_Print.inst.cfg | 2 +- .../um3_aa0.8_TPLA_Superdraft_Print.inst.cfg | 2 +- .../um3_aa0.8_TPLA_Verydraft_Print.inst.cfg | 2 +- .../um3_aa0.8_TPU_Draft_Print.inst.cfg | 2 +- .../um3_aa0.8_TPU_Superdraft_Print.inst.cfg | 2 +- .../um3_aa0.8_TPU_Verydraft_Print.inst.cfg | 2 +- .../um3_bb0.4_PVA_Draft_Print.inst.cfg | 2 +- .../um3_bb0.4_PVA_Fast_Print.inst.cfg | 2 +- .../um3_bb0.4_PVA_High_Quality.inst.cfg | 2 +- .../um3_bb0.4_PVA_Normal_Quality.inst.cfg | 2 +- .../um3_bb0.8_PVA_Draft_Print.inst.cfg | 2 +- .../um3_bb0.8_PVA_Superdraft_Print.inst.cfg | 2 +- .../um3_bb0.8_PVA_Verydraft_Print.inst.cfg | 2 +- .../um3_global_Draft_Quality.inst.cfg | 2 +- .../um3_global_Fast_Quality.inst.cfg | 2 +- .../um3_global_High_Quality.inst.cfg | 2 +- .../um3_global_Normal_Quality.inst.cfg | 2 +- .../um3_global_Superdraft_Quality.inst.cfg | 2 +- .../um3_global_Verydraft_Quality.inst.cfg | 2 +- .../umo_global_Coarse_Quality.inst.cfg | 2 +- .../umo_global_Draft_Quality.inst.cfg | 2 +- .../umo_global_Extra_Coarse_Quality.inst.cfg | 2 +- .../umo_global_Fast_Quality.inst.cfg | 2 +- .../umo_global_High_Quality.inst.cfg | 2 +- .../umo_global_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.25_ABS_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.25_CPE_Normal_Quality.inst.cfg | 2 +- ...um_s5_aa0.25_Nylon_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.25_PC_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.25_PLA_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.25_PP_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.25_TPLA_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_ABS_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.4_ABS_Fast_Print.inst.cfg | 2 +- .../um_s5_aa0.4_ABS_High_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_ABS_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_BAM_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.4_BAM_Fast_Print.inst.cfg | 2 +- .../um_s5_aa0.4_BAM_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_CPEP_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.4_CPEP_Fast_Print.inst.cfg | 2 +- .../um_s5_aa0.4_CPEP_High_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_CPEP_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_CPE_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.4_CPE_Fast_Print.inst.cfg | 2 +- .../um_s5_aa0.4_CPE_High_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_CPE_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_Nylon_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.4_Nylon_Fast_Print.inst.cfg | 2 +- .../um_s5_aa0.4_Nylon_High_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_Nylon_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_PC_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.4_PC_Fast_Print.inst.cfg | 2 +- .../um_s5_aa0.4_PC_High_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_PC_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_PLA_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.4_PLA_Fast_Print.inst.cfg | 2 +- .../um_s5_aa0.4_PLA_High_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_PLA_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_PP_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.4_PP_Fast_Print.inst.cfg | 2 +- .../um_s5_aa0.4_PP_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_TPLA_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.4_TPLA_Fast_Print.inst.cfg | 2 +- .../um_s5_aa0.4_TPLA_High_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_TPLA_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_TPU_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.4_TPU_Fast_Print.inst.cfg | 2 +- .../um_s5_aa0.4_TPU_Normal_Quality.inst.cfg | 2 +- ...s5_aa0.4_aluminum_ABS_Draft_Print.inst.cfg | 2 +- ..._s5_aa0.4_aluminum_ABS_Fast_Print.inst.cfg | 2 +- ...5_aa0.4_aluminum_ABS_High_Quality.inst.cfg | 2 +- ...aa0.4_aluminum_ABS_Normal_Quality.inst.cfg | 2 +- ...5_aa0.4_aluminum_CPEP_Draft_Print.inst.cfg | 2 +- ...s5_aa0.4_aluminum_CPEP_Fast_Print.inst.cfg | 2 +- ..._aa0.4_aluminum_CPEP_High_Quality.inst.cfg | 2 +- ...a0.4_aluminum_CPEP_Normal_Quality.inst.cfg | 2 +- ...s5_aa0.4_aluminum_CPE_Draft_Print.inst.cfg | 2 +- ..._s5_aa0.4_aluminum_CPE_Fast_Print.inst.cfg | 2 +- ...5_aa0.4_aluminum_CPE_High_Quality.inst.cfg | 2 +- ...aa0.4_aluminum_CPE_Normal_Quality.inst.cfg | 2 +- ..._s5_aa0.4_aluminum_PC_Draft_Print.inst.cfg | 2 +- ...m_s5_aa0.4_aluminum_PC_Fast_Print.inst.cfg | 2 +- ...s5_aa0.4_aluminum_PC_High_Quality.inst.cfg | 2 +- ..._aa0.4_aluminum_PC_Normal_Quality.inst.cfg | 2 +- ..._s5_aa0.4_aluminum_PP_Draft_Print.inst.cfg | 2 +- ...m_s5_aa0.4_aluminum_PP_Fast_Print.inst.cfg | 2 +- ..._aa0.4_aluminum_PP_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.8_ABS_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_ABS_Superdraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_ABS_Verydraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_CPEP_Fast_Print.inst.cfg | 2 +- ...um_s5_aa0.8_CPEP_Superdraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_CPEP_Verydraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_CPE_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_CPE_Superdraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_CPE_Verydraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_Nylon_Draft_Print.inst.cfg | 2 +- ...m_s5_aa0.8_Nylon_Superdraft_Print.inst.cfg | 2 +- ...um_s5_aa0.8_Nylon_Verydraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_PC_Fast_Print.inst.cfg | 2 +- .../um_s5_aa0.8_PC_Superdraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_PC_Verydraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_PLA_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_PLA_Superdraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_PLA_Verydraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_PP_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_PP_Superdraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_PP_Verydraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_TPLA_Draft_Print.inst.cfg | 2 +- ...um_s5_aa0.8_TPLA_Superdraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_TPLA_Verydraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_TPU_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_TPU_Superdraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_TPU_Verydraft_Print.inst.cfg | 2 +- ...s5_aa0.8_aluminum_ABS_Draft_Print.inst.cfg | 2 +- ...0.8_aluminum_ABS_Superdraft_Print.inst.cfg | 2 +- ...a0.8_aluminum_ABS_Verydraft_Print.inst.cfg | 2 +- ...s5_aa0.8_aluminum_CPEP_Fast_Print.inst.cfg | 2 +- ....8_aluminum_CPEP_Superdraft_Print.inst.cfg | 2 +- ...0.8_aluminum_CPEP_Verydraft_Print.inst.cfg | 2 +- ...s5_aa0.8_aluminum_CPE_Draft_Print.inst.cfg | 2 +- ...0.8_aluminum_CPE_Superdraft_Print.inst.cfg | 2 +- ...a0.8_aluminum_CPE_Verydraft_Print.inst.cfg | 2 +- ...m_s5_aa0.8_aluminum_PC_Fast_Print.inst.cfg | 2 +- ...a0.8_aluminum_PC_Superdraft_Print.inst.cfg | 2 +- ...aa0.8_aluminum_PC_Verydraft_Print.inst.cfg | 2 +- ..._s5_aa0.8_aluminum_PP_Draft_Print.inst.cfg | 2 +- ...a0.8_aluminum_PP_Superdraft_Print.inst.cfg | 2 +- ...aa0.8_aluminum_PP_Verydraft_Print.inst.cfg | 2 +- .../um_s5_bb0.4_PVA_Draft_Print.inst.cfg | 2 +- .../um_s5_bb0.4_PVA_Fast_Print.inst.cfg | 2 +- .../um_s5_bb0.4_PVA_High_Quality.inst.cfg | 2 +- .../um_s5_bb0.4_PVA_Normal_Quality.inst.cfg | 2 +- .../um_s5_bb0.8_PVA_Draft_Print.inst.cfg | 2 +- .../um_s5_bb0.8_PVA_Superdraft_Print.inst.cfg | 2 +- .../um_s5_bb0.8_PVA_Verydraft_Print.inst.cfg | 2 +- .../um_s5_cc0.6_CFFCPE_Draft_Print.inst.cfg | 2 +- .../um_s5_cc0.6_CFFPA_Draft_Print.inst.cfg | 2 +- .../um_s5_cc0.6_GFFCPE_Draft_Print.inst.cfg | 2 +- .../um_s5_cc0.6_GFFPA_Draft_Print.inst.cfg | 2 +- .../um_s5_global_Draft_Quality.inst.cfg | 2 +- .../um_s5_global_Fast_Quality.inst.cfg | 2 +- .../um_s5_global_High_Quality.inst.cfg | 2 +- .../um_s5_global_Normal_Quality.inst.cfg | 2 +- .../um_s5_global_Superdraft_Quality.inst.cfg | 2 +- .../um_s5_global_Verydraft_Quality.inst.cfg | 2 +- .../k8800_ABS_Extreme_Quality.inst.cfg | 2 +- .../k8800_ABS_High_Quality.inst.cfg | 2 +- .../k8800_ABS_Normal_Quality.inst.cfg | 2 +- .../k8800_Global_Extreme_Quality.inst.cfg | 2 +- .../k8800_Global_High_Quality.inst.cfg | 2 +- .../k8800_Global_Normal_Quality.inst.cfg | 2 +- .../k8800_PET_Extreme_Quality.inst.cfg | 2 +- .../k8800_PET_High_Quality.inst.cfg | 2 +- .../k8800_PET_Normal_Quality.inst.cfg | 2 +- .../k8800_PLA_Extreme_Quality.inst.cfg | 2 +- .../k8800_PLA_High_Quality.inst.cfg | 2 +- .../k8800_PLA_Normal_Quality.inst.cfg | 2 +- .../k8800_TPU_Extreme_Quality.inst.cfg | 2 +- .../k8800_TPU_High_Quality.inst.cfg | 2 +- .../k8800_TPU_Normal_Quality.inst.cfg | 2 +- .../zyyx/zyyx_agile_global_fast.inst.cfg | 2 +- .../zyyx/zyyx_agile_global_fine.inst.cfg | 2 +- .../zyyx/zyyx_agile_global_normal.inst.cfg | 2 +- .../zyyx/zyyx_agile_pro_flex_fast.inst.cfg | 2 +- .../zyyx/zyyx_agile_pro_flex_fine.inst.cfg | 2 +- .../zyyx/zyyx_agile_pro_flex_normal.inst.cfg | 2 +- .../zyyx/zyyx_agile_pro_pla_fast.inst.cfg | 2 +- .../zyyx/zyyx_agile_pro_pla_fine.inst.cfg | 2 +- .../zyyx/zyyx_agile_pro_pla_normal.inst.cfg | 2 +- resources/variants/cartesio_0.25.inst.cfg | 2 +- resources/variants/cartesio_0.4.inst.cfg | 2 +- resources/variants/cartesio_0.8.inst.cfg | 2 +- resources/variants/fabtotum_hyb35.inst.cfg | 2 +- resources/variants/fabtotum_lite04.inst.cfg | 2 +- resources/variants/fabtotum_lite06.inst.cfg | 2 +- resources/variants/fabtotum_pro02.inst.cfg | 2 +- resources/variants/fabtotum_pro04.inst.cfg | 2 +- resources/variants/fabtotum_pro06.inst.cfg | 2 +- resources/variants/fabtotum_pro08.inst.cfg | 2 +- resources/variants/felixtec4_0.25.inst.cfg | 2 +- resources/variants/felixtec4_0.35.inst.cfg | 2 +- resources/variants/felixtec4_0.50.inst.cfg | 2 +- resources/variants/felixtec4_0.70.inst.cfg | 2 +- .../variants/gmax15plus_025_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_04_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_05_e3d.inst.cfg | 2 +- .../variants/gmax15plus_05_jhead.inst.cfg | 2 +- resources/variants/gmax15plus_06_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_08_e3d.inst.cfg | 2 +- .../variants/gmax15plus_10_jhead.inst.cfg | 2 +- .../variants/gmax15plus_dual_025_e3d.inst.cfg | 2 +- .../variants/gmax15plus_dual_04_e3d.inst.cfg | 2 +- .../variants/gmax15plus_dual_05_e3d.inst.cfg | 2 +- .../gmax15plus_dual_05_jhead.inst.cfg | 2 +- .../variants/gmax15plus_dual_06_e3d.inst.cfg | 2 +- .../variants/gmax15plus_dual_08_e3d.inst.cfg | 2 +- .../gmax15plus_dual_10_jhead.inst.cfg | 2 +- .../variants/imade3d_jellybox_0.4.inst.cfg | 2 +- .../imade3d_jellybox_0.4_2-fans.inst.cfg | 2 +- resources/variants/tizyx_k25_0.2.inst.cfg | 2 +- resources/variants/tizyx_k25_0.3.inst.cfg | 2 +- resources/variants/tizyx_k25_0.4.inst.cfg | 2 +- resources/variants/tizyx_k25_0.5.inst.cfg | 2 +- resources/variants/tizyx_k25_0.6.inst.cfg | 2 +- resources/variants/tizyx_k25_0.8.inst.cfg | 2 +- resources/variants/tizyx_k25_1.0.inst.cfg | 2 +- resources/variants/ultimaker2_0.25.inst.cfg | 2 +- resources/variants/ultimaker2_0.4.inst.cfg | 2 +- resources/variants/ultimaker2_0.6.inst.cfg | 2 +- resources/variants/ultimaker2_0.8.inst.cfg | 2 +- .../ultimaker2_extended_0.25.inst.cfg | 2 +- .../variants/ultimaker2_extended_0.4.inst.cfg | 2 +- .../variants/ultimaker2_extended_0.6.inst.cfg | 2 +- .../variants/ultimaker2_extended_0.8.inst.cfg | 2 +- .../ultimaker2_extended_plus_0.25.inst.cfg | 2 +- .../ultimaker2_extended_plus_0.4.inst.cfg | 2 +- .../ultimaker2_extended_plus_0.6.inst.cfg | 2 +- .../ultimaker2_extended_plus_0.8.inst.cfg | 2 +- .../variants/ultimaker2_plus_0.25.inst.cfg | 2 +- .../variants/ultimaker2_plus_0.4.inst.cfg | 2 +- .../variants/ultimaker2_plus_0.6.inst.cfg | 2 +- .../variants/ultimaker2_plus_0.8.inst.cfg | 2 +- resources/variants/ultimaker3_aa0.25.inst.cfg | 2 +- resources/variants/ultimaker3_aa0.8.inst.cfg | 2 +- resources/variants/ultimaker3_aa04.inst.cfg | 2 +- resources/variants/ultimaker3_bb0.8.inst.cfg | 2 +- resources/variants/ultimaker3_bb04.inst.cfg | 2 +- .../ultimaker3_extended_aa0.25.inst.cfg | 2 +- .../ultimaker3_extended_aa0.8.inst.cfg | 2 +- .../ultimaker3_extended_aa04.inst.cfg | 2 +- .../ultimaker3_extended_bb0.8.inst.cfg | 2 +- .../ultimaker3_extended_bb04.inst.cfg | 2 +- .../variants/ultimaker_s5_aa0.25.inst.cfg | 2 +- .../variants/ultimaker_s5_aa0.8.inst.cfg | 2 +- resources/variants/ultimaker_s5_aa04.inst.cfg | 2 +- .../variants/ultimaker_s5_aluminum.inst.cfg | 2 +- .../variants/ultimaker_s5_bb0.8.inst.cfg | 2 +- resources/variants/ultimaker_s5_bb04.inst.cfg | 2 +- resources/variants/ultimaker_s5_cc06.inst.cfg | 2 +- .../variants/ultimaker_s5_glass.inst.cfg | 2 +- 650 files changed, 779 insertions(+), 647 deletions(-) create mode 100644 plugins/VersionUpgrade/VersionUpgrade35to40/VersionUpgrade35to40.py create mode 100644 plugins/VersionUpgrade/VersionUpgrade35to40/__init__.py create mode 100644 plugins/VersionUpgrade/VersionUpgrade35to40/plugin.json diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 4d1c530237..c64e7416c9 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -143,7 +143,7 @@ class CuraApplication(QtApplication): # SettingVersion represents the set of settings available in the machine/extruder definitions. # You need to make sure that this version number needs to be increased if there is any non-backwards-compatible # changes of the settings. - SettingVersion = 5 + SettingVersion = 6 Created = False diff --git a/plugins/VersionUpgrade/VersionUpgrade35to40/VersionUpgrade35to40.py b/plugins/VersionUpgrade/VersionUpgrade35to40/VersionUpgrade35to40.py new file mode 100644 index 0000000000..52cd7cf3cb --- /dev/null +++ b/plugins/VersionUpgrade/VersionUpgrade35to40/VersionUpgrade35to40.py @@ -0,0 +1,68 @@ +import configparser +from typing import Tuple, List, Set +import io +from UM.VersionUpgrade import VersionUpgrade +from cura.PrinterOutputDevice import ConnectionType +deleted_settings = {"bridge_wall_max_overhang"} # type: Set[str] + + +class VersionUpgrade35to40(VersionUpgrade): + # Upgrades stacks to have the new version number. + def upgradeStack(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]: + parser = configparser.ConfigParser(interpolation=None) + parser.read_string(serialized) + + # Update version number. + parser["general"]["version"] = "4" + parser["metadata"]["setting_version"] = "6" + + if parser["metadata"].get("um_network_key") is not None or parser["metadata"].get("octoprint_api_key") is not None: + # Set the connection type if um_network_key or the octoprint key is set. + parser["metadata"]["connection_type"] = str(ConnectionType.NetworkConnection.value) + + result = io.StringIO() + parser.write(result) + return [filename], [result.getvalue()] + pass + + def getCfgVersion(self, serialised: str) -> int: + parser = configparser.ConfigParser(interpolation = None) + parser.read_string(serialised) + format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised. + setting_version = int(parser.get("metadata", "setting_version", fallback = "0")) + return format_version * 1000000 + setting_version + + ## Upgrades Preferences to have the new version number. + def upgradePreferences(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]: + parser = configparser.ConfigParser(interpolation=None) + parser.read_string(serialized) + + if "metadata" not in parser: + parser["metadata"] = {} + parser["general"]["version"] = "6" + parser["metadata"]["setting_version"] = "6" + + result = io.StringIO() + parser.write(result) + return [filename], [result.getvalue()] + + ## Upgrades instance containers to have the new version + # number. + def upgradeInstanceContainer(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]: + parser = configparser.ConfigParser(interpolation=None) + parser.read_string(serialized) + + # Update version number. + parser["general"]["version"] = "4" + parser["metadata"]["setting_version"] = "6" + + #self._resetConcentric3DInfillPattern(parser) + if "values" in parser: + for deleted_setting in deleted_settings: + if deleted_setting not in parser["values"]: + continue + del parser["values"][deleted_setting] + + result = io.StringIO() + parser.write(result) + return [filename], [result.getvalue()] \ No newline at end of file diff --git a/plugins/VersionUpgrade/VersionUpgrade35to40/__init__.py b/plugins/VersionUpgrade/VersionUpgrade35to40/__init__.py new file mode 100644 index 0000000000..2ad1dddbf2 --- /dev/null +++ b/plugins/VersionUpgrade/VersionUpgrade35to40/__init__.py @@ -0,0 +1,56 @@ +from typing import Dict, Any + +from . import VersionUpgrade35to40 + +upgrade = VersionUpgrade35to40.VersionUpgrade35to40() + + +def getMetaData() -> Dict[str, Any]: + return { + "version_upgrade": { + # From To Upgrade function + ("preferences", 6000005): ("preferences", 6000006, upgrade.upgradePreferences), + + ("definition_changes", 4000005): ("definition_changes", 4000006, upgrade.upgradeInstanceContainer), + ("quality_changes", 4000005): ("quality_changes", 4000006, upgrade.upgradeInstanceContainer), + ("quality", 4000005): ("quality", 4000006, upgrade.upgradeInstanceContainer), + ("user", 4000005): ("user", 4000006, upgrade.upgradeInstanceContainer), + + ("machine_stack", 4000005): ("machine_stack", 4000006, upgrade.upgradeStack), + ("extruder_train", 4000005): ("extruder_train", 4000006, upgrade.upgradeStack), + }, + "sources": { + "preferences": { + "get_version": upgrade.getCfgVersion, + "location": {"."} + }, + "machine_stack": { + "get_version": upgrade.getCfgVersion, + "location": {"./machine_instances"} + }, + "extruder_train": { + "get_version": upgrade.getCfgVersion, + "location": {"./extruders"} + }, + "definition_changes": { + "get_version": upgrade.getCfgVersion, + "location": {"./definition_changes"} + }, + "quality_changes": { + "get_version": upgrade.getCfgVersion, + "location": {"./quality_changes"} + }, + "quality": { + "get_version": upgrade.getCfgVersion, + "location": {"./quality"} + }, + "user": { + "get_version": upgrade.getCfgVersion, + "location": {"./user"} + } + } + } + + +def register(app) -> Dict[str, Any]: + return {"version_upgrade": upgrade} \ No newline at end of file diff --git a/plugins/VersionUpgrade/VersionUpgrade35to40/plugin.json b/plugins/VersionUpgrade/VersionUpgrade35to40/plugin.json new file mode 100644 index 0000000000..578594fb6d --- /dev/null +++ b/plugins/VersionUpgrade/VersionUpgrade35to40/plugin.json @@ -0,0 +1,8 @@ + { + "name": "Version Upgrade 3.5 to 4.0", + "author": "Ultimaker B.V.", + "version": "1.0.0", + "description": "Upgrades configurations from Cura 3.5 to Cura 4.0.", + "api": "6.0", + "i18n-catalog": "cura" +} diff --git a/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg b/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg index 1d406e4387..fcd6b46f2d 100644 --- a/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg +++ b/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = abax_pri3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = -1 diff --git a/resources/quality/abax_pri3/apri3_pla_high.inst.cfg b/resources/quality/abax_pri3/apri3_pla_high.inst.cfg index 20d2c024aa..e9e8d53a03 100644 --- a/resources/quality/abax_pri3/apri3_pla_high.inst.cfg +++ b/resources/quality/abax_pri3/apri3_pla_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = abax_pri3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg b/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg index 0a4d1f1c62..40399c9548 100644 --- a/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg +++ b/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = abax_pri3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg b/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg index 6d0fdd40d2..6747ada00d 100644 --- a/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg +++ b/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = abax_pri5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = -1 diff --git a/resources/quality/abax_pri5/apri5_pla_high.inst.cfg b/resources/quality/abax_pri5/apri5_pla_high.inst.cfg index 212c92e7d1..99bd10d654 100644 --- a/resources/quality/abax_pri5/apri5_pla_high.inst.cfg +++ b/resources/quality/abax_pri5/apri5_pla_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = abax_pri5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg b/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg index 8a1338f28c..55e0a7755a 100644 --- a/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg +++ b/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = abax_pri5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/abax_titan/atitan_pla_fast.inst.cfg b/resources/quality/abax_titan/atitan_pla_fast.inst.cfg index 71740ede84..e1e558be6d 100644 --- a/resources/quality/abax_titan/atitan_pla_fast.inst.cfg +++ b/resources/quality/abax_titan/atitan_pla_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = abax_titan [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = -1 diff --git a/resources/quality/abax_titan/atitan_pla_high.inst.cfg b/resources/quality/abax_titan/atitan_pla_high.inst.cfg index 73cd31f3fd..7dd5833297 100644 --- a/resources/quality/abax_titan/atitan_pla_high.inst.cfg +++ b/resources/quality/abax_titan/atitan_pla_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = abax_titan [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/abax_titan/atitan_pla_normal.inst.cfg b/resources/quality/abax_titan/atitan_pla_normal.inst.cfg index c356e197ce..b6aae46c6d 100644 --- a/resources/quality/abax_titan/atitan_pla_normal.inst.cfg +++ b/resources/quality/abax_titan/atitan_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = abax_titan [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/anycubic_4max/abs/anycubic_4max_abs_draft.inst.cfg b/resources/quality/anycubic_4max/abs/anycubic_4max_abs_draft.inst.cfg index f5baa55029..3a85bd77b5 100644 --- a/resources/quality/anycubic_4max/abs/anycubic_4max_abs_draft.inst.cfg +++ b/resources/quality/anycubic_4max/abs/anycubic_4max_abs_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = anycubic_4max [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = 0 diff --git a/resources/quality/anycubic_4max/abs/anycubic_4max_abs_high.inst.cfg b/resources/quality/anycubic_4max/abs/anycubic_4max_abs_high.inst.cfg index bd613c6aad..a3b4275f39 100644 --- a/resources/quality/anycubic_4max/abs/anycubic_4max_abs_high.inst.cfg +++ b/resources/quality/anycubic_4max/abs/anycubic_4max_abs_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = anycubic_4max [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 2 diff --git a/resources/quality/anycubic_4max/abs/anycubic_4max_abs_normal.inst.cfg b/resources/quality/anycubic_4max/abs/anycubic_4max_abs_normal.inst.cfg index 7cff1db4d2..e3add50a4a 100644 --- a/resources/quality/anycubic_4max/abs/anycubic_4max_abs_normal.inst.cfg +++ b/resources/quality/anycubic_4max/abs/anycubic_4max_abs_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = anycubic_4max [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 1 diff --git a/resources/quality/anycubic_4max/anycubic_4max_draft.inst.cfg b/resources/quality/anycubic_4max/anycubic_4max_draft.inst.cfg index c0114e3d6c..78c61b112b 100644 --- a/resources/quality/anycubic_4max/anycubic_4max_draft.inst.cfg +++ b/resources/quality/anycubic_4max/anycubic_4max_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = anycubic_4max [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = 0 diff --git a/resources/quality/anycubic_4max/anycubic_4max_high.inst.cfg b/resources/quality/anycubic_4max/anycubic_4max_high.inst.cfg index 4a0993412a..722403ed23 100644 --- a/resources/quality/anycubic_4max/anycubic_4max_high.inst.cfg +++ b/resources/quality/anycubic_4max/anycubic_4max_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = anycubic_4max [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 2 diff --git a/resources/quality/anycubic_4max/anycubic_4max_normal.inst.cfg b/resources/quality/anycubic_4max/anycubic_4max_normal.inst.cfg index eeb1d699e4..b57f0357e3 100644 --- a/resources/quality/anycubic_4max/anycubic_4max_normal.inst.cfg +++ b/resources/quality/anycubic_4max/anycubic_4max_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = anycubic_4max [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 1 diff --git a/resources/quality/anycubic_4max/hips/anycubic_4max_hips_draft.inst.cfg b/resources/quality/anycubic_4max/hips/anycubic_4max_hips_draft.inst.cfg index 3cd0226bd4..4f04512596 100644 --- a/resources/quality/anycubic_4max/hips/anycubic_4max_hips_draft.inst.cfg +++ b/resources/quality/anycubic_4max/hips/anycubic_4max_hips_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = anycubic_4max [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = 0 diff --git a/resources/quality/anycubic_4max/hips/anycubic_4max_hips_high.inst.cfg b/resources/quality/anycubic_4max/hips/anycubic_4max_hips_high.inst.cfg index ff5c6bee2f..a3749d734e 100644 --- a/resources/quality/anycubic_4max/hips/anycubic_4max_hips_high.inst.cfg +++ b/resources/quality/anycubic_4max/hips/anycubic_4max_hips_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = anycubic_4max [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 2 diff --git a/resources/quality/anycubic_4max/hips/anycubic_4max_hips_normal.inst.cfg b/resources/quality/anycubic_4max/hips/anycubic_4max_hips_normal.inst.cfg index c4701ae246..23b0ded57a 100644 --- a/resources/quality/anycubic_4max/hips/anycubic_4max_hips_normal.inst.cfg +++ b/resources/quality/anycubic_4max/hips/anycubic_4max_hips_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = anycubic_4max [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 1 diff --git a/resources/quality/anycubic_4max/petg/anycubic_4max_petg_draft.inst.cfg b/resources/quality/anycubic_4max/petg/anycubic_4max_petg_draft.inst.cfg index 5e0c3e204a..3d44ec8d1b 100644 --- a/resources/quality/anycubic_4max/petg/anycubic_4max_petg_draft.inst.cfg +++ b/resources/quality/anycubic_4max/petg/anycubic_4max_petg_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = anycubic_4max [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = 0 diff --git a/resources/quality/anycubic_4max/petg/anycubic_4max_petg_high.inst.cfg b/resources/quality/anycubic_4max/petg/anycubic_4max_petg_high.inst.cfg index 57a89c4ec2..74e7e96d6e 100644 --- a/resources/quality/anycubic_4max/petg/anycubic_4max_petg_high.inst.cfg +++ b/resources/quality/anycubic_4max/petg/anycubic_4max_petg_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = anycubic_4max [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 2 diff --git a/resources/quality/anycubic_4max/petg/anycubic_4max_petg_normal.inst.cfg b/resources/quality/anycubic_4max/petg/anycubic_4max_petg_normal.inst.cfg index 14a4607ceb..2aa77a4089 100644 --- a/resources/quality/anycubic_4max/petg/anycubic_4max_petg_normal.inst.cfg +++ b/resources/quality/anycubic_4max/petg/anycubic_4max_petg_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = anycubic_4max [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 1 diff --git a/resources/quality/anycubic_4max/pla/anycubic_4max_pla_draft.inst.cfg b/resources/quality/anycubic_4max/pla/anycubic_4max_pla_draft.inst.cfg index eae9e3b5ef..e479ee4a1f 100644 --- a/resources/quality/anycubic_4max/pla/anycubic_4max_pla_draft.inst.cfg +++ b/resources/quality/anycubic_4max/pla/anycubic_4max_pla_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = anycubic_4max [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = 0 diff --git a/resources/quality/anycubic_4max/pla/anycubic_4max_pla_high.inst.cfg b/resources/quality/anycubic_4max/pla/anycubic_4max_pla_high.inst.cfg index c856fc66a7..40ca97078c 100644 --- a/resources/quality/anycubic_4max/pla/anycubic_4max_pla_high.inst.cfg +++ b/resources/quality/anycubic_4max/pla/anycubic_4max_pla_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = anycubic_4max [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 2 diff --git a/resources/quality/anycubic_4max/pla/anycubic_4max_pla_normal.inst.cfg b/resources/quality/anycubic_4max/pla/anycubic_4max_pla_normal.inst.cfg index be33bfe53a..17f9cfe7cd 100644 --- a/resources/quality/anycubic_4max/pla/anycubic_4max_pla_normal.inst.cfg +++ b/resources/quality/anycubic_4max/pla/anycubic_4max_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = anycubic_4max [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 1 diff --git a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg index e94b9f01d1..96b423d9d0 100644 --- a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg +++ b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = anycubic_i3_mega [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = 0 diff --git a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg index c8c4bf9a81..90d6135c4c 100644 --- a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg +++ b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = anycubic_i3_mega [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 2 diff --git a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg index 399c3ebc55..2f24a4c6f0 100644 --- a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg +++ b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = anycubic_i3_mega [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 1 diff --git a/resources/quality/builder_premium/bp_BVOH_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_BVOH_Coarse_Quality.inst.cfg index 10c8bc553f..491d24c919 100644 --- a/resources/quality/builder_premium/bp_BVOH_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_BVOH_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = -1 diff --git a/resources/quality/builder_premium/bp_BVOH_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_BVOH_High_Quality.inst.cfg index b09ceb8872..3ff0f07ac1 100644 --- a/resources/quality/builder_premium/bp_BVOH_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_BVOH_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High Quality definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/builder_premium/bp_BVOH_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_BVOH_Normal_Quality.inst.cfg index c2425a6d86..cf67185706 100644 --- a/resources/quality/builder_premium/bp_BVOH_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_BVOH_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/builder_premium/bp_Innoflex60_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_Innoflex60_Coarse_Quality.inst.cfg index 038fd02fff..aedb45a2b1 100644 --- a/resources/quality/builder_premium/bp_Innoflex60_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_Innoflex60_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = -1 diff --git a/resources/quality/builder_premium/bp_Innoflex60_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_Innoflex60_High_Quality.inst.cfg index e9512e30f8..08fb395a36 100644 --- a/resources/quality/builder_premium/bp_Innoflex60_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_Innoflex60_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High Quality definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/builder_premium/bp_Innoflex60_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_Innoflex60_Normal_Quality.inst.cfg index fb6ec6c89f..008de91758 100644 --- a/resources/quality/builder_premium/bp_Innoflex60_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_Innoflex60_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/builder_premium/bp_PET_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_PET_Coarse_Quality.inst.cfg index 572e83d4b3..0e2c26812b 100644 --- a/resources/quality/builder_premium/bp_PET_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PET_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = -1 diff --git a/resources/quality/builder_premium/bp_PET_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_PET_High_Quality.inst.cfg index f4a45dd43a..8217ca9156 100644 --- a/resources/quality/builder_premium/bp_PET_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PET_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High Quality definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/builder_premium/bp_PET_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_PET_Normal_Quality.inst.cfg index d927ab0851..48b2df0cae 100644 --- a/resources/quality/builder_premium/bp_PET_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PET_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/builder_premium/bp_PLA_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_PLA_Coarse_Quality.inst.cfg index fc877df05d..6834cbb2c4 100644 --- a/resources/quality/builder_premium/bp_PLA_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PLA_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = -1 diff --git a/resources/quality/builder_premium/bp_PLA_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_PLA_High_Quality.inst.cfg index 586133a500..9fc5426cf9 100644 --- a/resources/quality/builder_premium/bp_PLA_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PLA_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High Quality definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/builder_premium/bp_PLA_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_PLA_Normal_Quality.inst.cfg index e84b2eaa87..161bee24df 100644 --- a/resources/quality/builder_premium/bp_PLA_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PLA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/builder_premium/bp_PVA_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_PVA_Coarse_Quality.inst.cfg index f661e58b6d..149b938bac 100644 --- a/resources/quality/builder_premium/bp_PVA_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PVA_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = -1 diff --git a/resources/quality/builder_premium/bp_PVA_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_PVA_High_Quality.inst.cfg index 31b9c094df..ba310a0890 100644 --- a/resources/quality/builder_premium/bp_PVA_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PVA_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High Quality definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/builder_premium/bp_PVA_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_PVA_Normal_Quality.inst.cfg index 8c3ca85124..4ab949957f 100644 --- a/resources/quality/builder_premium/bp_PVA_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PVA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/builder_premium/bp_global_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_global_Coarse_Quality.inst.cfg index a1d80774a1..9a85c924ee 100644 --- a/resources/quality/builder_premium/bp_global_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_global_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = -1 diff --git a/resources/quality/builder_premium/bp_global_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_global_High_Quality.inst.cfg index 465ea6090a..ca2f8c843f 100644 --- a/resources/quality/builder_premium/bp_global_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_global_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High Quality definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/builder_premium/bp_global_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_global_Normal_Quality.inst.cfg index e872561b90..3b24f9963d 100644 --- a/resources/quality/builder_premium/bp_global_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_global_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = builder_premium_small [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/abs/cartesio_0.25_abs_high.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.25_abs_high.inst.cfg index 5626ed58de..f19635331d 100644 --- a/resources/quality/cartesio/abs/cartesio_0.25_abs_high.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.25_abs_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg index f74918ef4f..e203e88e0c 100644 --- a/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 2 diff --git a/resources/quality/cartesio/abs/cartesio_0.4_abs_high.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.4_abs_high.inst.cfg index d4dd85b09d..99e1290c77 100644 --- a/resources/quality/cartesio/abs/cartesio_0.4_abs_high.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.4_abs_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg index ab72092035..54a7d094ce 100644 --- a/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 2 diff --git a/resources/quality/cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg index d15efb770f..5496468fd6 100644 --- a/resources/quality/cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = 3 diff --git a/resources/quality/cartesio/abs/cartesio_0.8_abs_extra_coarse.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.8_abs_extra_coarse.inst.cfg index 7467da765f..360397ddc9 100644 --- a/resources/quality/cartesio/abs/cartesio_0.8_abs_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.8_abs_extra_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extra coarse weight = 4 diff --git a/resources/quality/cartesio/abs/cartesio_0.8_abs_high.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.8_abs_high.inst.cfg index caa6b71a4a..82e0afa853 100644 --- a/resources/quality/cartesio/abs/cartesio_0.8_abs_high.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.8_abs_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg index 9eea2177a8..a3f2c1d796 100644 --- a/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 2 diff --git a/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_high.inst.cfg b/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_high.inst.cfg index 17f2acd8d1..fa89b4c3aa 100644 --- a/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_high.inst.cfg +++ b/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg b/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg index 8215eb2f50..5a2be13737 100644 --- a/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg +++ b/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 2 diff --git a/resources/quality/cartesio/cartesio_global_Coarse_Quality.inst.cfg b/resources/quality/cartesio/cartesio_global_Coarse_Quality.inst.cfg index f92fc49981..7ce1111dd8 100644 --- a/resources/quality/cartesio/cartesio_global_Coarse_Quality.inst.cfg +++ b/resources/quality/cartesio/cartesio_global_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = -3 diff --git a/resources/quality/cartesio/cartesio_global_Extra_Coarse_Quality.inst.cfg b/resources/quality/cartesio/cartesio_global_Extra_Coarse_Quality.inst.cfg index 1681e83279..0369c74e2a 100644 --- a/resources/quality/cartesio/cartesio_global_Extra_Coarse_Quality.inst.cfg +++ b/resources/quality/cartesio/cartesio_global_Extra_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extra coarse weight = -4 diff --git a/resources/quality/cartesio/cartesio_global_High_Quality.inst.cfg b/resources/quality/cartesio/cartesio_global_High_Quality.inst.cfg index 95d1f3b37e..dafe5ef621 100644 --- a/resources/quality/cartesio/cartesio_global_High_Quality.inst.cfg +++ b/resources/quality/cartesio/cartesio_global_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/cartesio_global_Normal_Quality.inst.cfg b/resources/quality/cartesio/cartesio_global_Normal_Quality.inst.cfg index 6bb348282e..100da3c70a 100644 --- a/resources/quality/cartesio/cartesio_global_Normal_Quality.inst.cfg +++ b/resources/quality/cartesio/cartesio_global_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/hips/cartesio_0.25_hips_high.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.25_hips_high.inst.cfg index 3e212b2446..93e04e1514 100644 --- a/resources/quality/cartesio/hips/cartesio_0.25_hips_high.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.25_hips_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg index 0cf82847a0..a90a0823df 100644 --- a/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 2 diff --git a/resources/quality/cartesio/hips/cartesio_0.4_hips_high.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.4_hips_high.inst.cfg index a9664cf9d1..91b1627650 100644 --- a/resources/quality/cartesio/hips/cartesio_0.4_hips_high.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.4_hips_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg index 8101fb6dd8..f9242fe62a 100644 --- a/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 2 diff --git a/resources/quality/cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg index f009383ad8..6b84c5e864 100644 --- a/resources/quality/cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = 3 diff --git a/resources/quality/cartesio/hips/cartesio_0.8_hips_extra_coarse.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.8_hips_extra_coarse.inst.cfg index 1adbbb0fb9..16f299813b 100644 --- a/resources/quality/cartesio/hips/cartesio_0.8_hips_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.8_hips_extra_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extra coarse weight = 4 diff --git a/resources/quality/cartesio/hips/cartesio_0.8_hips_high.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.8_hips_high.inst.cfg index d3e6df227f..686759bc4d 100644 --- a/resources/quality/cartesio/hips/cartesio_0.8_hips_high.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.8_hips_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg index 0b019d555f..724abcd63a 100644 --- a/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 2 diff --git a/resources/quality/cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg index 9eb5d5c4e9..bd2dca940f 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg index e0100d37ec..ce7e344ad9 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 2 diff --git a/resources/quality/cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg index d4b261b99f..05e9abbe8f 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg index 7d899ae927..87cfd33f51 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 2 diff --git a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg index 21e6d357b0..279e2d98bf 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = 3 diff --git a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg index 15128584e1..69f9a8caad 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extra coarse weight = 4 diff --git a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg index 1d78bd0f1d..ff4d152ef2 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg index 95be159ff2..2e74b2cc77 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 2 diff --git a/resources/quality/cartesio/pc/cartesio_0.25_pc_high.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.25_pc_high.inst.cfg index c45194e18b..15c7f17451 100644 --- a/resources/quality/cartesio/pc/cartesio_0.25_pc_high.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.25_pc_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg index 248517d769..020c2a1111 100644 --- a/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 2 diff --git a/resources/quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg index 8c46693c91..73e1ff6bc5 100644 --- a/resources/quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg index a0b71f1f0a..44a0c4874a 100644 --- a/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 2 diff --git a/resources/quality/cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg index 04f01db6ba..cba868e95e 100644 --- a/resources/quality/cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = 3 diff --git a/resources/quality/cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg index 53e21ec4d0..4aff24ed02 100644 --- a/resources/quality/cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extra coarse weight = 4 diff --git a/resources/quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg index 0b2b9dcb26..f00e83f63e 100644 --- a/resources/quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg index 173ad406f3..60e1e4e3ef 100644 --- a/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 2 diff --git a/resources/quality/cartesio/petg/cartesio_0.25_petg_high.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.25_petg_high.inst.cfg index 9dc7adfc88..3c8dcc7af6 100644 --- a/resources/quality/cartesio/petg/cartesio_0.25_petg_high.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.25_petg_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg index 019af9d905..6c704fb9d5 100644 --- a/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 2 diff --git a/resources/quality/cartesio/petg/cartesio_0.4_petg_high.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.4_petg_high.inst.cfg index 93388787e6..3788a4dd51 100644 --- a/resources/quality/cartesio/petg/cartesio_0.4_petg_high.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.4_petg_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg index ed17ccce31..46df45cbb0 100644 --- a/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 2 diff --git a/resources/quality/cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg index 754c55caf5..d7d6e35a3c 100644 --- a/resources/quality/cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = 3 diff --git a/resources/quality/cartesio/petg/cartesio_0.8_petg_extra_coarse.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.8_petg_extra_coarse.inst.cfg index 81b1de32a2..784bd0d6af 100644 --- a/resources/quality/cartesio/petg/cartesio_0.8_petg_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.8_petg_extra_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extra coarse weight = 4 diff --git a/resources/quality/cartesio/petg/cartesio_0.8_petg_high.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.8_petg_high.inst.cfg index 86e93c8a32..bced328a9c 100644 --- a/resources/quality/cartesio/petg/cartesio_0.8_petg_high.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.8_petg_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg index 08f918f59b..4f588b7b7b 100644 --- a/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 2 diff --git a/resources/quality/cartesio/pla/cartesio_0.25_pla_high.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.25_pla_high.inst.cfg index 4841f9f368..15456a0b78 100644 --- a/resources/quality/cartesio/pla/cartesio_0.25_pla_high.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.25_pla_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/pla/cartesio_0.25_pla_normal.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.25_pla_normal.inst.cfg index 3ba36f9436..bfa792f133 100644 --- a/resources/quality/cartesio/pla/cartesio_0.25_pla_normal.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.25_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/pla/cartesio_0.4_pla_high.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.4_pla_high.inst.cfg index 7c785a750a..e64b67b59b 100644 --- a/resources/quality/cartesio/pla/cartesio_0.4_pla_high.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.4_pla_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/pla/cartesio_0.4_pla_normal.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.4_pla_normal.inst.cfg index b24394daf0..704a974b63 100644 --- a/resources/quality/cartesio/pla/cartesio_0.4_pla_normal.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.4_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg index 6443f2d526..b8ff99c256 100644 --- a/resources/quality/cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = -3 diff --git a/resources/quality/cartesio/pla/cartesio_0.8_pla_extra_coarse.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.8_pla_extra_coarse.inst.cfg index 51a93f76d9..da613e6e1a 100644 --- a/resources/quality/cartesio/pla/cartesio_0.8_pla_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.8_pla_extra_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extra coarse weight = -4 diff --git a/resources/quality/cartesio/pla/cartesio_0.8_pla_high.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.8_pla_high.inst.cfg index 2f72d9d158..05c0f72686 100644 --- a/resources/quality/cartesio/pla/cartesio_0.8_pla_high.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.8_pla_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/pla/cartesio_0.8_pla_normal.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.8_pla_normal.inst.cfg index 431f7c0fff..8434f4abc6 100644 --- a/resources/quality/cartesio/pla/cartesio_0.8_pla_normal.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.8_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/pva/cartesio_0.25_pva_high.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.25_pva_high.inst.cfg index fe21c17e22..7df550917f 100644 --- a/resources/quality/cartesio/pva/cartesio_0.25_pva_high.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.25_pva_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg index 6525991986..c31a97c41a 100644 --- a/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 2 diff --git a/resources/quality/cartesio/pva/cartesio_0.4_pva_high.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.4_pva_high.inst.cfg index cdf8f8cae7..faf1633ce2 100644 --- a/resources/quality/cartesio/pva/cartesio_0.4_pva_high.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.4_pva_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg index e7267735e4..e6eb02409c 100644 --- a/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 2 diff --git a/resources/quality/cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg index fc35e14fc6..35b2d1690d 100644 --- a/resources/quality/cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = 3 diff --git a/resources/quality/cartesio/pva/cartesio_0.8_pva_extra_coarse.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.8_pva_extra_coarse.inst.cfg index 0e1b8b1241..3d41308a5d 100644 --- a/resources/quality/cartesio/pva/cartesio_0.8_pva_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.8_pva_extra_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extra coarse weight = 4 diff --git a/resources/quality/cartesio/pva/cartesio_0.8_pva_high.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.8_pva_high.inst.cfg index 249cf6485e..0293ee9acb 100644 --- a/resources/quality/cartesio/pva/cartesio_0.8_pva_high.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.8_pva_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg index a6c0a89fcc..247fa7b787 100644 --- a/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 2 diff --git a/resources/quality/coarse.inst.cfg b/resources/quality/coarse.inst.cfg index e9b8156a70..77b9004aa6 100644 --- a/resources/quality/coarse.inst.cfg +++ b/resources/quality/coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = fdmprinter [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = -3 diff --git a/resources/quality/dagoma/dagoma_discoeasy200_pla_fast.inst.cfg b/resources/quality/dagoma/dagoma_discoeasy200_pla_fast.inst.cfg index a302f5b513..b12a92dc1c 100644 --- a/resources/quality/dagoma/dagoma_discoeasy200_pla_fast.inst.cfg +++ b/resources/quality/dagoma/dagoma_discoeasy200_pla_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = dagoma_discoeasy200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/dagoma/dagoma_discoeasy200_pla_fine.inst.cfg b/resources/quality/dagoma/dagoma_discoeasy200_pla_fine.inst.cfg index b26eb1d910..055b3e30d6 100644 --- a/resources/quality/dagoma/dagoma_discoeasy200_pla_fine.inst.cfg +++ b/resources/quality/dagoma/dagoma_discoeasy200_pla_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = dagoma_discoeasy200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/dagoma/dagoma_discoeasy200_pla_standard.inst.cfg b/resources/quality/dagoma/dagoma_discoeasy200_pla_standard.inst.cfg index 9ec56f696a..7c244b3f18 100644 --- a/resources/quality/dagoma/dagoma_discoeasy200_pla_standard.inst.cfg +++ b/resources/quality/dagoma/dagoma_discoeasy200_pla_standard.inst.cfg @@ -4,7 +4,7 @@ name = Standard definition = dagoma_discoeasy200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/dagoma/dagoma_global_fast.inst.cfg b/resources/quality/dagoma/dagoma_global_fast.inst.cfg index 28569387f2..f0d312e0a7 100644 --- a/resources/quality/dagoma/dagoma_global_fast.inst.cfg +++ b/resources/quality/dagoma/dagoma_global_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = dagoma_discoeasy200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/dagoma/dagoma_global_fine.inst.cfg b/resources/quality/dagoma/dagoma_global_fine.inst.cfg index 1f7d577c1b..bf0a173ec3 100644 --- a/resources/quality/dagoma/dagoma_global_fine.inst.cfg +++ b/resources/quality/dagoma/dagoma_global_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = dagoma_discoeasy200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/dagoma/dagoma_global_standard.inst.cfg b/resources/quality/dagoma/dagoma_global_standard.inst.cfg index 167062c1d7..afeb925e96 100644 --- a/resources/quality/dagoma/dagoma_global_standard.inst.cfg +++ b/resources/quality/dagoma/dagoma_global_standard.inst.cfg @@ -4,7 +4,7 @@ name = Standard definition = dagoma_discoeasy200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/dagoma/dagoma_magis_pla_fast.inst.cfg b/resources/quality/dagoma/dagoma_magis_pla_fast.inst.cfg index d87c913eb6..8387ff2401 100644 --- a/resources/quality/dagoma/dagoma_magis_pla_fast.inst.cfg +++ b/resources/quality/dagoma/dagoma_magis_pla_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = dagoma_magis [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/dagoma/dagoma_magis_pla_fine.inst.cfg b/resources/quality/dagoma/dagoma_magis_pla_fine.inst.cfg index d046726e0e..60c0cae7ec 100644 --- a/resources/quality/dagoma/dagoma_magis_pla_fine.inst.cfg +++ b/resources/quality/dagoma/dagoma_magis_pla_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = dagoma_magis [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/dagoma/dagoma_magis_pla_standard.inst.cfg b/resources/quality/dagoma/dagoma_magis_pla_standard.inst.cfg index 39961ea93b..b406d43cb1 100644 --- a/resources/quality/dagoma/dagoma_magis_pla_standard.inst.cfg +++ b/resources/quality/dagoma/dagoma_magis_pla_standard.inst.cfg @@ -4,7 +4,7 @@ name = Standard definition = dagoma_magis [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/dagoma/dagoma_neva_pla_fast.inst.cfg b/resources/quality/dagoma/dagoma_neva_pla_fast.inst.cfg index efdf2f7d32..c0e8d7fe94 100644 --- a/resources/quality/dagoma/dagoma_neva_pla_fast.inst.cfg +++ b/resources/quality/dagoma/dagoma_neva_pla_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = dagoma_neva [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/dagoma/dagoma_neva_pla_fine.inst.cfg b/resources/quality/dagoma/dagoma_neva_pla_fine.inst.cfg index 50915db112..b6d6966c81 100644 --- a/resources/quality/dagoma/dagoma_neva_pla_fine.inst.cfg +++ b/resources/quality/dagoma/dagoma_neva_pla_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = dagoma_neva [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/dagoma/dagoma_neva_pla_standard.inst.cfg b/resources/quality/dagoma/dagoma_neva_pla_standard.inst.cfg index ed67800eac..eff587c908 100644 --- a/resources/quality/dagoma/dagoma_neva_pla_standard.inst.cfg +++ b/resources/quality/dagoma/dagoma_neva_pla_standard.inst.cfg @@ -4,7 +4,7 @@ name = Standard definition = dagoma_neva [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/deltacomb/deltacomb_abs_Draft_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_abs_Draft_Quality.inst.cfg index f540400575..9316a84175 100644 --- a/resources/quality/deltacomb/deltacomb_abs_Draft_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_abs_Draft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fast (beta) definition = deltacomb [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/deltacomb/deltacomb_abs_Fast_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_abs_Fast_Quality.inst.cfg index 2214813913..a2c67ff890 100644 --- a/resources/quality/deltacomb/deltacomb_abs_Fast_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_abs_Fast_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal (beta) definition = deltacomb [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/deltacomb/deltacomb_abs_High_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_abs_High_Quality.inst.cfg index c196209553..6322c311d0 100644 --- a/resources/quality/deltacomb/deltacomb_abs_High_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_abs_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine (beta) definition = deltacomb [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 0 diff --git a/resources/quality/deltacomb/deltacomb_abs_Normal_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_abs_Normal_Quality.inst.cfg index 332e1890c6..1f4184f3ad 100644 --- a/resources/quality/deltacomb/deltacomb_abs_Normal_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_abs_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine (beta) definition = deltacomb [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/deltacomb/deltacomb_abs_Verydraft_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_abs_Verydraft_Quality.inst.cfg index 674174c0bd..37925e0e4c 100644 --- a/resources/quality/deltacomb/deltacomb_abs_Verydraft_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_abs_Verydraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast (beta) definition = deltacomb [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/deltacomb/deltacomb_global_Draft_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_global_Draft_Quality.inst.cfg index f8887810d5..072f0435f6 100755 --- a/resources/quality/deltacomb/deltacomb_global_Draft_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_global_Draft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = deltacomb [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/deltacomb/deltacomb_global_Fast_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_global_Fast_Quality.inst.cfg index 99030a084b..eef96e35b8 100755 --- a/resources/quality/deltacomb/deltacomb_global_Fast_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_global_Fast_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = deltacomb [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/deltacomb/deltacomb_global_High_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_global_High_Quality.inst.cfg index d6d853466a..bb120877aa 100755 --- a/resources/quality/deltacomb/deltacomb_global_High_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_global_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = deltacomb [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 0 diff --git a/resources/quality/deltacomb/deltacomb_global_Normal_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_global_Normal_Quality.inst.cfg index a3bafadeec..4c95c74cfa 100755 --- a/resources/quality/deltacomb/deltacomb_global_Normal_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_global_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = deltacomb [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/deltacomb/deltacomb_global_Verydraft_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_global_Verydraft_Quality.inst.cfg index 84c6e66f61..0ba6ca588f 100755 --- a/resources/quality/deltacomb/deltacomb_global_Verydraft_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_global_Verydraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = deltacomb [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/deltacomb/deltacomb_pla_Draft_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_pla_Draft_Quality.inst.cfg index c4f884486e..e0e695570d 100644 --- a/resources/quality/deltacomb/deltacomb_pla_Draft_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_pla_Draft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = deltacomb [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/deltacomb/deltacomb_pla_Fast_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_pla_Fast_Quality.inst.cfg index 714d4e3517..3f43871a8f 100644 --- a/resources/quality/deltacomb/deltacomb_pla_Fast_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_pla_Fast_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = deltacomb [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/deltacomb/deltacomb_pla_High_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_pla_High_Quality.inst.cfg index 774b8969c0..ba435c8bde 100644 --- a/resources/quality/deltacomb/deltacomb_pla_High_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_pla_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = deltacomb [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 0 diff --git a/resources/quality/deltacomb/deltacomb_pla_Normal_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_pla_Normal_Quality.inst.cfg index 58470ed650..98ec4f46cd 100644 --- a/resources/quality/deltacomb/deltacomb_pla_Normal_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_pla_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = deltacomb [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/deltacomb/deltacomb_pla_Verydraft_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_pla_Verydraft_Quality.inst.cfg index 9c00877c24..f67a2d8a26 100644 --- a/resources/quality/deltacomb/deltacomb_pla_Verydraft_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_pla_Verydraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = deltacomb [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/draft.inst.cfg b/resources/quality/draft.inst.cfg index ac1d9ec52f..a605b9c83c 100644 --- a/resources/quality/draft.inst.cfg +++ b/resources/quality/draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = fdmprinter [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/extra_coarse.inst.cfg b/resources/quality/extra_coarse.inst.cfg index 2a1a203d22..bf22b7ac3c 100644 --- a/resources/quality/extra_coarse.inst.cfg +++ b/resources/quality/extra_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse definition = fdmprinter [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extra coarse weight = -4 diff --git a/resources/quality/extra_fast.inst.cfg b/resources/quality/extra_fast.inst.cfg index da890f1653..eb1e7b3a42 100644 --- a/resources/quality/extra_fast.inst.cfg +++ b/resources/quality/extra_fast.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = fdmprinter [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/fabtotum/fabtotum_abs_fast.inst.cfg b/resources/quality/fabtotum/fabtotum_abs_fast.inst.cfg index 95e8b93b36..036d49a94f 100644 --- a/resources/quality/fabtotum/fabtotum_abs_fast.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_abs_fast.inst.cfg @@ -4,7 +4,7 @@ definition = fabtotum name = Fast Quality [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/fabtotum/fabtotum_abs_high.inst.cfg b/resources/quality/fabtotum/fabtotum_abs_high.inst.cfg index baedf0ed2b..f3d6f33952 100644 --- a/resources/quality/fabtotum/fabtotum_abs_high.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_abs_high.inst.cfg @@ -4,7 +4,7 @@ definition = fabtotum name = High Quality [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/fabtotum/fabtotum_abs_normal.inst.cfg b/resources/quality/fabtotum/fabtotum_abs_normal.inst.cfg index 58933486ee..d01599a392 100644 --- a/resources/quality/fabtotum/fabtotum_abs_normal.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_abs_normal.inst.cfg @@ -4,7 +4,7 @@ definition = fabtotum name = Normal Quality [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/fabtotum/fabtotum_nylon_fast.inst.cfg b/resources/quality/fabtotum/fabtotum_nylon_fast.inst.cfg index 00f0737227..1f0c050126 100644 --- a/resources/quality/fabtotum/fabtotum_nylon_fast.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_nylon_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fast Quality definition = fabtotum [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/fabtotum/fabtotum_nylon_high.inst.cfg b/resources/quality/fabtotum/fabtotum_nylon_high.inst.cfg index bd7f32c9ba..4e234f62f8 100644 --- a/resources/quality/fabtotum/fabtotum_nylon_high.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_nylon_high.inst.cfg @@ -4,7 +4,7 @@ name = High Quality definition = fabtotum [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/fabtotum/fabtotum_nylon_normal.inst.cfg b/resources/quality/fabtotum/fabtotum_nylon_normal.inst.cfg index 6a450e7ffe..67998dea38 100644 --- a/resources/quality/fabtotum/fabtotum_nylon_normal.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_nylon_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal Quality definition = fabtotum [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/fabtotum/fabtotum_pla_fast.inst.cfg b/resources/quality/fabtotum/fabtotum_pla_fast.inst.cfg index afac0b0884..e27477e8de 100644 --- a/resources/quality/fabtotum/fabtotum_pla_fast.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_pla_fast.inst.cfg @@ -4,7 +4,7 @@ definition = fabtotum name = Fast Quality [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/fabtotum/fabtotum_pla_high.inst.cfg b/resources/quality/fabtotum/fabtotum_pla_high.inst.cfg index 89dc6d9b33..bab6d5fc82 100644 --- a/resources/quality/fabtotum/fabtotum_pla_high.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_pla_high.inst.cfg @@ -4,7 +4,7 @@ definition = fabtotum name = High Quality [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/fabtotum/fabtotum_pla_normal.inst.cfg b/resources/quality/fabtotum/fabtotum_pla_normal.inst.cfg index e5496a13d4..7bd3bc024e 100644 --- a/resources/quality/fabtotum/fabtotum_pla_normal.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_pla_normal.inst.cfg @@ -4,7 +4,7 @@ definition = fabtotum name = Normal Quality [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/fabtotum/fabtotum_tpu_fast.inst.cfg b/resources/quality/fabtotum/fabtotum_tpu_fast.inst.cfg index 7917c92514..5668d4a5b9 100644 --- a/resources/quality/fabtotum/fabtotum_tpu_fast.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_tpu_fast.inst.cfg @@ -5,7 +5,7 @@ name = Fast Quality [metadata] type = quality -setting_version = 5 +setting_version = 6 material = generic_tpu quality_type = fast weight = -1 diff --git a/resources/quality/fabtotum/fabtotum_tpu_high.inst.cfg b/resources/quality/fabtotum/fabtotum_tpu_high.inst.cfg index 1c31967d79..6af9e88f00 100644 --- a/resources/quality/fabtotum/fabtotum_tpu_high.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_tpu_high.inst.cfg @@ -5,7 +5,7 @@ name = High Quality [metadata] type = quality -setting_version = 5 +setting_version = 6 material = generic_tpu quality_type = high weight = 1 diff --git a/resources/quality/fabtotum/fabtotum_tpu_normal.inst.cfg b/resources/quality/fabtotum/fabtotum_tpu_normal.inst.cfg index 0a3821f953..13faf5bc2f 100644 --- a/resources/quality/fabtotum/fabtotum_tpu_normal.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_tpu_normal.inst.cfg @@ -5,7 +5,7 @@ name = Normal Quality [metadata] type = quality -setting_version = 5 +setting_version = 6 material = generic_tpu quality_type = normal weight = 0 diff --git a/resources/quality/fast.inst.cfg b/resources/quality/fast.inst.cfg index 7568c42e8f..94a7961320 100644 --- a/resources/quality/fast.inst.cfg +++ b/resources/quality/fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = fdmprinter [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/gmax15plus/gmax15plus_pla_dual_normal.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_dual_normal.inst.cfg index 7fd2ab2296..b04d933d5d 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_dual_normal.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_dual_normal.inst.cfg @@ -4,7 +4,7 @@ name = gMax 1.5+ Dual Normal Layers definition = gmax15plus_dual [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = -1 diff --git a/resources/quality/gmax15plus/gmax15plus_pla_dual_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_dual_thick.inst.cfg index 30a99ef243..c1282c4a80 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_dual_thick.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_dual_thick.inst.cfg @@ -4,7 +4,7 @@ name = gMax 1.5+ Dual Thick Layers definition = gmax15plus_dual [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = course weight = -2 diff --git a/resources/quality/gmax15plus/gmax15plus_pla_dual_thin.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_dual_thin.inst.cfg index decafac241..eaf86ee152 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_dual_thin.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_dual_thin.inst.cfg @@ -4,7 +4,7 @@ name = gMax 1.5+ Dual Thin Layers definition = gmax15plus_dual [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 0 diff --git a/resources/quality/gmax15plus/gmax15plus_pla_dual_very_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_dual_very_thick.inst.cfg index a74bdfdd78..95e93f7932 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_dual_very_thick.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_dual_very_thick.inst.cfg @@ -4,7 +4,7 @@ name = gMax 1.5+ Dual Very Thick Layers definition = gmax15plus_dual [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extra_course weight = -3 diff --git a/resources/quality/gmax15plus/gmax15plus_pla_normal.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_normal.inst.cfg index ddf5a4c491..400966c645 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_normal.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = gMax 1.5+ Normal Layers definition = gmax15plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = -1 diff --git a/resources/quality/gmax15plus/gmax15plus_pla_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_thick.inst.cfg index e6cb2b5854..2dbfd27dd5 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_thick.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_thick.inst.cfg @@ -4,7 +4,7 @@ name = gMax 1.5+ Thick Layers definition = gmax15plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = course weight = -2 diff --git a/resources/quality/gmax15plus/gmax15plus_pla_thin.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_thin.inst.cfg index d119539d32..516054a378 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_thin.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_thin.inst.cfg @@ -4,7 +4,7 @@ name = gMax 1.5+ Thin Layers definition = gmax15plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 0 diff --git a/resources/quality/gmax15plus/gmax15plus_pla_very_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_very_thick.inst.cfg index 884029a4ae..1b260e4388 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_very_thick.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_very_thick.inst.cfg @@ -4,7 +4,7 @@ name = gMax 1.5+ Very Thick Layers definition = gmax15plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extra_course weight = -3 diff --git a/resources/quality/high.inst.cfg b/resources/quality/high.inst.cfg index 1b687bf5e4..2ef1aba9e1 100644 --- a/resources/quality/high.inst.cfg +++ b/resources/quality/high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = fdmprinter [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg index 6a50e24678..e299e675e0 100644 --- a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg index 2c8a43874a..7123c6440a 100644 --- a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg index 264c95c933..297531f989 100644 --- a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg @@ -4,7 +4,7 @@ name = Medium definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg index dfdfc2458c..d15c4a3b2d 100644 --- a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg @@ -4,7 +4,7 @@ name = Medium definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg index 68eec0c753..9ff4e6d49e 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg index 46f81d0c1a..88635bb56d 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg index f614b7cc3c..89dcca901c 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg index 5525899ea7..c7fd702eeb 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg index 28b4307cea..7f030b53e2 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg @@ -4,7 +4,7 @@ name = Medium definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg index 52a8594505..2759a24a8d 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg @@ -4,7 +4,7 @@ name = Medium definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg index bf3d409050..b74b9434b7 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg @@ -4,7 +4,7 @@ name = UltraFine definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = ultrahigh weight = 2 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine_2-fans.inst.cfg index 676ea84825..21df5445ab 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine_2-fans.inst.cfg @@ -4,7 +4,7 @@ name = UltraFine definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = ultrahigh weight = 2 diff --git a/resources/quality/imade3d_jellybox/imade3d_jellybox_coarse.inst.cfg b/resources/quality/imade3d_jellybox/imade3d_jellybox_coarse.inst.cfg index 819501c727..1c6ef69145 100644 --- a/resources/quality/imade3d_jellybox/imade3d_jellybox_coarse.inst.cfg +++ b/resources/quality/imade3d_jellybox/imade3d_jellybox_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/imade3d_jellybox/imade3d_jellybox_fine.inst.cfg b/resources/quality/imade3d_jellybox/imade3d_jellybox_fine.inst.cfg index 0f312aa62d..702c5182c9 100644 --- a/resources/quality/imade3d_jellybox/imade3d_jellybox_fine.inst.cfg +++ b/resources/quality/imade3d_jellybox/imade3d_jellybox_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/imade3d_jellybox/imade3d_jellybox_normal.inst.cfg b/resources/quality/imade3d_jellybox/imade3d_jellybox_normal.inst.cfg index 25d0e65d74..87256a9af7 100644 --- a/resources/quality/imade3d_jellybox/imade3d_jellybox_normal.inst.cfg +++ b/resources/quality/imade3d_jellybox/imade3d_jellybox_normal.inst.cfg @@ -4,7 +4,7 @@ name = Medium definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/imade3d_jellybox/imade3d_jellybox_ultrafine.inst.cfg b/resources/quality/imade3d_jellybox/imade3d_jellybox_ultrafine.inst.cfg index ebe5ab620c..ffa7ed4550 100644 --- a/resources/quality/imade3d_jellybox/imade3d_jellybox_ultrafine.inst.cfg +++ b/resources/quality/imade3d_jellybox/imade3d_jellybox_ultrafine.inst.cfg @@ -4,7 +4,7 @@ name = UltraFine definition = imade3d_jellybox [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = ultrahigh weight = 2 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_draft.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_draft.inst.cfg index edba5e79ce..e4b6411ef6 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_draft.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = kemiq_q2_beta [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = -3 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_extra_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_extra_fine.inst.cfg index 899af00b78..faeaee854d 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_extra_fine.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_extra_fine.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = kemiq_q2_beta [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_fine.inst.cfg index 9b7ae123df..1ee9821018 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_fine.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = kemiq_q2_beta [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_low.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_low.inst.cfg index 96888821e3..c47239ee4a 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_low.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_low.inst.cfg @@ -4,7 +4,7 @@ name = Low definition = kemiq_q2_beta [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg index c8f27f6a8f..8eac1515ca 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = kemiq_q2_beta [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_draft.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_draft.inst.cfg index a121d921cc..e51e3f6cd8 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_draft.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = kemiq_q2_beta [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = -3 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_extra_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_extra_fine.inst.cfg index 211da57f0c..f3d9aa9409 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_extra_fine.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_extra_fine.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = kemiq_q2_beta [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_fine.inst.cfg index 5879a76012..92d1a98e2b 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_fine.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = kemiq_q2_beta [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_low.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_low.inst.cfg index 0b437327d8..3fa48b32a6 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_low.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_low.inst.cfg @@ -4,7 +4,7 @@ name = Low definition = kemiq_q2_beta [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg index ca5ac5bd0e..277ddc7ec5 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = kemiq_q2_beta [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_draft.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_draft.inst.cfg index cd6ee5356e..e73ff9b982 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_draft.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = kemiq_q2_gama [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = -3 diff --git a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_extra_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_extra_fine.inst.cfg index 345fdc2f0d..0175eb8ffa 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_extra_fine.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_extra_fine.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = kemiq_q2_gama [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_fine.inst.cfg index bafc8f0016..415fbef684 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_fine.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = kemiq_q2_gama [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_low.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_low.inst.cfg index c8aa72def2..94aa963911 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_low.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_low.inst.cfg @@ -4,7 +4,7 @@ name = Low definition = kemiq_q2_gama [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg index 62c43104e1..cc69216ecd 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = kemiq_q2_gama [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_draft.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_draft.inst.cfg index 5bb967b78a..d54f0071cd 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_draft.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_fast.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_fast.inst.cfg index 30641b863a..bdd9a1ccb8 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_fast.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_high.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_high.inst.cfg index 746b579c70..7a4722d599 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_high.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_high.inst.cfg @@ -4,7 +4,7 @@ name = Finer definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_normal.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_normal.inst.cfg index e4ab115bc5..4cd3f34466 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_normal.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_superdraft.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_superdraft.inst.cfg index d8a7607c5c..bd349b6d72 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_superdraft.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_superdraft.inst.cfg @@ -4,7 +4,7 @@ name = Lowest Quality Draft definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -5 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_thickerdraft.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_thickerdraft.inst.cfg index 44cad5a198..a01282748b 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_thickerdraft.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_thickerdraft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = thickerdraft weight = -3 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg index 995074f330..ac82e263a7 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg @@ -4,7 +4,7 @@ name = Ultra Fine definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = ultra weight = 2 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg index 373908b2bd..fbdcb22262 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg @@ -4,7 +4,7 @@ name = Low Detail Draft definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -4 diff --git a/resources/quality/malyan_m200/malyan_m200_global_Draft_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_Draft_Quality.inst.cfg index e53aa86a94..aa1f30d0b3 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_Draft_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_Draft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/malyan_m200/malyan_m200_global_Fast_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_Fast_Quality.inst.cfg index 4379d9fdcb..8cbbdac2e4 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_Fast_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_Fast_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/malyan_m200/malyan_m200_global_High_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_High_Quality.inst.cfg index a9a5720e14..a56a5771d8 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_High_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Finer definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/malyan_m200/malyan_m200_global_Normal_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_Normal_Quality.inst.cfg index 96b982e86a..f24faf98f0 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_Normal_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/malyan_m200/malyan_m200_global_SuperDraft_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_SuperDraft_Quality.inst.cfg index 0550efd603..ff0d97b1cc 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_SuperDraft_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_SuperDraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Lowest Quality Draft definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -5 diff --git a/resources/quality/malyan_m200/malyan_m200_global_ThickerDraft_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_ThickerDraft_Quality.inst.cfg index 9a0454fc75..623b48acff 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_ThickerDraft_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_ThickerDraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = thickerdraft weight = -3 diff --git a/resources/quality/malyan_m200/malyan_m200_global_Ultra_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_Ultra_Quality.inst.cfg index 76eaa3463f..ec04f9055b 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_Ultra_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_Ultra_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Ultra Fine definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = ultra weight = 2 diff --git a/resources/quality/malyan_m200/malyan_m200_global_VeryDraft_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_VeryDraft_Quality.inst.cfg index 42c670920f..637b37c1ca 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_VeryDraft_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_VeryDraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Low Detail Draft definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -4 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_draft.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_draft.inst.cfg index 96144c193f..6f36402470 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_draft.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_fast.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_fast.inst.cfg index f390034a1f..ff14d6a96e 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_fast.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_high.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_high.inst.cfg index 693c6efc08..74ab347def 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_high.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_high.inst.cfg @@ -4,7 +4,7 @@ name = Finer definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_normal.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_normal.inst.cfg index 09c5c2b14d..0862f96460 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_normal.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_superdraft.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_superdraft.inst.cfg index 0faec6b357..df50ebcc42 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_superdraft.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_superdraft.inst.cfg @@ -4,7 +4,7 @@ name = Lowest Quality Draft definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -5 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_thickerdraft.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_thickerdraft.inst.cfg index 988082f783..3697573e0e 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_thickerdraft.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_thickerdraft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = thickerdraft weight = -3 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg index 4eb84672e7..c9858b63c7 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg @@ -4,7 +4,7 @@ name = Ultra Fine definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = ultra weight = 2 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg index 2f33760afa..4bb5c5cbe4 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg @@ -4,7 +4,7 @@ name = Low Detail Draft definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -4 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_draft.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_draft.inst.cfg index 9a26d1b2a1..7a3af8285a 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_draft.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_fast.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_fast.inst.cfg index ef4d002ce3..f813e062dd 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_fast.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_high.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_high.inst.cfg index 6ff347a7cc..5fe854ddab 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_high.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_high.inst.cfg @@ -4,7 +4,7 @@ name = Finer definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_normal.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_normal.inst.cfg index b6aa938b94..cce3508550 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_normal.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_superdraft.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_superdraft.inst.cfg index 8a4b63691f..477256a933 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_superdraft.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_superdraft.inst.cfg @@ -4,7 +4,7 @@ name = Lowest Quality Draft definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -5 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_thickerdraft.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_thickerdraft.inst.cfg index 98a8363c85..1841b91d3d 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_thickerdraft.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_thickerdraft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = thickerdraft weight = -3 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg index 5a334bd9c1..24717cda19 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg @@ -4,7 +4,7 @@ name = Ultra Fine definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = ultra weight = 2 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg index 7d96a9f56d..8b007f5c03 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg @@ -4,7 +4,7 @@ name = Low Detail Draft definition = malyan_m200 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -4 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_draft.inst.cfg index ef579a567e..e8959a1235 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_draft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_fast.inst.cfg index 33296bf677..256eea1976 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_fast.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_high.inst.cfg index e282847f14..6d0250121f 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_high.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_high.inst.cfg @@ -4,7 +4,7 @@ name = Finer definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_normal.inst.cfg index 2979f574a4..88c12a38f0 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_normal.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_superdraft.inst.cfg index 2d4d3c7461..2eacd312f4 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_superdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_superdraft.inst.cfg @@ -4,7 +4,7 @@ name = Lowest Quality Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -5 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_thickerdraft.inst.cfg index ed43dec3ae..4b311bcfed 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_thickerdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_thickerdraft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = thickerdraft weight = -3 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_ultra.inst.cfg index eb556fe862..e9857b76b3 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_ultra.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_ultra.inst.cfg @@ -4,7 +4,7 @@ name = Ultra Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = thickerdraft weight = 2 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg index 279f58d64f..7c39073c34 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg @@ -4,7 +4,7 @@ name = Low Detail Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -4 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Draft_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Draft_Quality.inst.cfg index 1d81d7535e..add2590cce 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Draft_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Draft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Fast_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Fast_Quality.inst.cfg index 6a5a041244..2feddbd32a 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Fast_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Fast_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_High_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_High_Quality.inst.cfg index 65925a1ea4..263bd8544c 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_High_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Finer definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Normal_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Normal_Quality.inst.cfg index 0ac150c117..52e2ec79f3 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Normal_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_SuperDraft_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_SuperDraft_Quality.inst.cfg index b02910cf12..dfbd2d4d3d 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_SuperDraft_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_SuperDraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Lowest Quality Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -5 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_ThickerDraft_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_ThickerDraft_Quality.inst.cfg index 46434555ad..f05617c4f0 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_ThickerDraft_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_ThickerDraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = thickerdraft weight = -3 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Ultra_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Ultra_Quality.inst.cfg index dfb4942b29..e6d835d683 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Ultra_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Ultra_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Ultra Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = ultra weight = 2 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_VeryDraft_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_VeryDraft_Quality.inst.cfg index 79d9c8abb9..8e1a86a732 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_VeryDraft_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_VeryDraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Low Detail Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -4 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_draft.inst.cfg index 4d7d1cd848..c7701b56d3 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_draft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_fast.inst.cfg index 1a18df9651..dbe3b03148 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_fast.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_high.inst.cfg index ac0ca29caa..4612b19638 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_high.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_high.inst.cfg @@ -4,7 +4,7 @@ name = Finer definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_normal.inst.cfg index 32c5e33f0d..7b887afb8d 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_normal.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_superdraft.inst.cfg index 26f260f861..c696c71fd5 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_superdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_superdraft.inst.cfg @@ -4,7 +4,7 @@ name = Lowest Quality Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -5 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_thickerdraft.inst.cfg index b5bcc7d455..c561bcda04 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_thickerdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_thickerdraft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = thickerdraft weight = -3 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_ultra.inst.cfg index 6fc41e34b6..e16e044708 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_ultra.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_ultra.inst.cfg @@ -4,7 +4,7 @@ name = Ultra Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = ultra weight = 2 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg index 8f568d3948..319bf8b39a 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg @@ -4,7 +4,7 @@ name = Low Detail Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -4 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_draft.inst.cfg index 76b210eba1..6cc27cd3e8 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_draft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_fast.inst.cfg index 53a099f42d..95ef667be9 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_fast.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_high.inst.cfg index 1a6193fbaf..c874fc5c42 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_high.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_high.inst.cfg @@ -4,7 +4,7 @@ name = Finer definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_normal.inst.cfg index 72e94d1828..62fb4046aa 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_normal.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_superdraft.inst.cfg index 13914d07e7..e1c88805e7 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_superdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_superdraft.inst.cfg @@ -4,7 +4,7 @@ name = Lowest Quality Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -5 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_thickerdraft.inst.cfg index d02a793b25..0cec8831bf 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_thickerdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_thickerdraft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = thickerdraft weight = -3 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_ultra.inst.cfg index 41b3821727..6aaf8680f5 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_ultra.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_ultra.inst.cfg @@ -4,7 +4,7 @@ name = Ultra Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = ultra weight = 2 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg index 23b72a3a3b..7a3b3d6f3e 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg @@ -4,7 +4,7 @@ name = Low Detail Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -4 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_draft.inst.cfg index c2c8889127..4e31a46fbd 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_draft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_fast.inst.cfg index 881311d395..e0d7d393c5 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_fast.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_high.inst.cfg index f9f1e169cb..64451b0788 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_high.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_high.inst.cfg @@ -4,7 +4,7 @@ name = Finer definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_normal.inst.cfg index 026279f012..1f5b6c956c 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_normal.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_superdraft.inst.cfg index 3ff71bf416..9b269ee95b 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_superdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_superdraft.inst.cfg @@ -4,7 +4,7 @@ name = Lowest Quality Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -5 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_thickerdraft.inst.cfg index 5524ec59ea..e180b50a89 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_thickerdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_thickerdraft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = thickerdraft weight = -3 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_ultra.inst.cfg index 99d1da45c7..fe77254c56 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_ultra.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_ultra.inst.cfg @@ -4,7 +4,7 @@ name = Ultra Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = ultra weight = 2 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg index 99874f0571..0dd0300db3 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg @@ -4,7 +4,7 @@ name = Low Detail Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -4 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_draft.inst.cfg index a64020a89e..8333cd10ac 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_draft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_fast.inst.cfg index 994d6ff0fd..ab83dacbe8 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_fast.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = 0 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg index 9f64ce57f0..9a931d6a81 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg @@ -4,7 +4,7 @@ name = Finer definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 0 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_normal.inst.cfg index afbc03d5af..57fb63fdea 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_normal.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_superdraft.inst.cfg index ec30cfe2b9..77c3a18b54 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_superdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_superdraft.inst.cfg @@ -4,7 +4,7 @@ name = Lowest Quality Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -5 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_thickerdraft.inst.cfg index 916285385d..52b871217b 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_thickerdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_thickerdraft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = thickerdraft weight = -3 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_ultra.inst.cfg index 5d627b6d35..36ef492905 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_ultra.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_ultra.inst.cfg @@ -4,7 +4,7 @@ name = Ultra Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = ultra weight = 2 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_verydraft.inst.cfg index 9f22fb3692..e1d636b2b1 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_verydraft.inst.cfg @@ -4,7 +4,7 @@ name = Low Detail Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 5 +setting_version = 6 type = quality material = generic_pla weight = 0 diff --git a/resources/quality/normal.inst.cfg b/resources/quality/normal.inst.cfg index f32c87bc60..02b9ebf621 100644 --- a/resources/quality/normal.inst.cfg +++ b/resources/quality/normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = fdmprinter [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/peopoly_moai/peopoly_moai_coarse.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_coarse.inst.cfg index ac4f9ee81d..9ca6cec759 100644 --- a/resources/quality/peopoly_moai/peopoly_moai_coarse.inst.cfg +++ b/resources/quality/peopoly_moai/peopoly_moai_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = peopoly_moai [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = 3 diff --git a/resources/quality/peopoly_moai/peopoly_moai_draft.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_draft.inst.cfg index 2d21b1f7e0..1989675688 100644 --- a/resources/quality/peopoly_moai/peopoly_moai_draft.inst.cfg +++ b/resources/quality/peopoly_moai/peopoly_moai_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = peopoly_moai [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = 4 diff --git a/resources/quality/peopoly_moai/peopoly_moai_extra_high.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_extra_high.inst.cfg index 796c2cff3c..30d41aa7f8 100644 --- a/resources/quality/peopoly_moai/peopoly_moai_extra_high.inst.cfg +++ b/resources/quality/peopoly_moai/peopoly_moai_extra_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra High definition = peopoly_moai [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extra_high weight = 0 diff --git a/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg index b36163d9f1..37442ed20c 100644 --- a/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg +++ b/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = peopoly_moai [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg index cf67591ab2..9d80b972b4 100644 --- a/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg +++ b/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = peopoly_moai [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 2 diff --git a/resources/quality/tevo_blackwidow/tevo_blackwidow_draft.inst.cfg b/resources/quality/tevo_blackwidow/tevo_blackwidow_draft.inst.cfg index be83533e0b..13f12ef643 100644 --- a/resources/quality/tevo_blackwidow/tevo_blackwidow_draft.inst.cfg +++ b/resources/quality/tevo_blackwidow/tevo_blackwidow_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = tevo_blackwidow [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/tevo_blackwidow/tevo_blackwidow_high.inst.cfg b/resources/quality/tevo_blackwidow/tevo_blackwidow_high.inst.cfg index 5ca8a6e4ef..0f0ccf64c6 100644 --- a/resources/quality/tevo_blackwidow/tevo_blackwidow_high.inst.cfg +++ b/resources/quality/tevo_blackwidow/tevo_blackwidow_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = tevo_blackwidow [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/tevo_blackwidow/tevo_blackwidow_normal.inst.cfg b/resources/quality/tevo_blackwidow/tevo_blackwidow_normal.inst.cfg index f542952fab..ebd5997027 100644 --- a/resources/quality/tevo_blackwidow/tevo_blackwidow_normal.inst.cfg +++ b/resources/quality/tevo_blackwidow/tevo_blackwidow_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = tevo_blackwidow [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/tizyx_k25/tizyx_k25_normal.inst.cfg b/resources/quality/tizyx_k25/tizyx_k25_normal.inst.cfg index 8b066f139f..f259ad1b34 100644 --- a/resources/quality/tizyx_k25/tizyx_k25_normal.inst.cfg +++ b/resources/quality/tizyx_k25/tizyx_k25_normal.inst.cfg @@ -5,7 +5,7 @@ definition = tizyx_k25 [metadata] quality_type = normal -setting_version = 5 +setting_version = 6 type = quality global_quality = True diff --git a/resources/quality/ultimaker2/um2_draft.inst.cfg b/resources/quality/ultimaker2/um2_draft.inst.cfg index 8c34d2c09d..7d38ba6bf4 100644 --- a/resources/quality/ultimaker2/um2_draft.inst.cfg +++ b/resources/quality/ultimaker2/um2_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = ultimaker2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker2/um2_fast.inst.cfg b/resources/quality/ultimaker2/um2_fast.inst.cfg index 084ed05f92..39cd4da4ef 100644 --- a/resources/quality/ultimaker2/um2_fast.inst.cfg +++ b/resources/quality/ultimaker2/um2_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2/um2_high.inst.cfg b/resources/quality/ultimaker2/um2_high.inst.cfg index 83bb6bb972..142440d53e 100644 --- a/resources/quality/ultimaker2/um2_high.inst.cfg +++ b/resources/quality/ultimaker2/um2_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker2/um2_normal.inst.cfg b/resources/quality/ultimaker2/um2_normal.inst.cfg index febee8581f..b5a87f07f3 100644 --- a/resources/quality/ultimaker2/um2_normal.inst.cfg +++ b/resources/quality/ultimaker2/um2_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg index ff830ae660..d27a136765 100644 --- a/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg index 94ea62a7ca..5bc62e5fd0 100644 --- a/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg index 03de437ee2..2847ab8c15 100644 --- a/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg index 836d866eab..009fcf7877 100644 --- a/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg index de55623c0f..7c492f2ec0 100644 --- a/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg index c96260d52f..1b6cee0e1d 100644 --- a/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg index 886daf58e2..f55567f986 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg index b727acc510..63904632dc 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg index 20e217315b..f76efeb7b2 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg index 853a87c751..fd7dfc86a7 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg index 6d3ef94b9d..aba3222412 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg index 7b39ce966a..23618e2e1d 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg index eca5070eb9..c0434aca4f 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg index 1e181e23d1..2dc076b012 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg index 9ffb8a05bb..300d5242e2 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg index ee7101f2ec..17a9f1a579 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg index d2de84eae6..6807a1a86a 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg index 581dc0368d..7a15ed53ec 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.4_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.4_draft.inst.cfg index 7549c0081d..cc68478dd8 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpep_0.4_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.4_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.4_normal.inst.cfg index b1e5552562..0d0e0e2043 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpep_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.4_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.6_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.6_draft.inst.cfg index 616f13f110..e08a7fc357 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpep_0.6_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.6_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.6_normal.inst.cfg index d28dc76af8..7c8589f09e 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpep_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.6_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.8_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.8_draft.inst.cfg index 1c4fa746ad..1c42d28128 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpep_0.8_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.8_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.8_normal.inst.cfg index e40d6efc58..072081e092 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpep_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.8_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_global_Coarse_Quality.inst.cfg b/resources/quality/ultimaker2_plus/um2p_global_Coarse_Quality.inst.cfg index a10cb4030c..2a4fe17a24 100644 --- a/resources/quality/ultimaker2_plus/um2p_global_Coarse_Quality.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_global_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Coarse Quality definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = -4 diff --git a/resources/quality/ultimaker2_plus/um2p_global_Draft_Quality.inst.cfg b/resources/quality/ultimaker2_plus/um2p_global_Draft_Quality.inst.cfg index 5645bbee0b..bdf79827b2 100644 --- a/resources/quality/ultimaker2_plus/um2p_global_Draft_Quality.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_global_Draft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Draft Quality definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker2_plus/um2p_global_Extra_Coarse_Quality.inst.cfg b/resources/quality/ultimaker2_plus/um2p_global_Extra_Coarse_Quality.inst.cfg index d9afc804ba..e5338c0e34 100644 --- a/resources/quality/ultimaker2_plus/um2p_global_Extra_Coarse_Quality.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_global_Extra_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse Quality definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extra coarse weight = -3 diff --git a/resources/quality/ultimaker2_plus/um2p_global_Fast_Quality.inst.cfg b/resources/quality/ultimaker2_plus/um2p_global_Fast_Quality.inst.cfg index 7fd6d54c87..453def0668 100644 --- a/resources/quality/ultimaker2_plus/um2p_global_Fast_Quality.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_global_Fast_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_global_High_Quality.inst.cfg b/resources/quality/ultimaker2_plus/um2p_global_High_Quality.inst.cfg index ade183d14a..f7ac2a62b6 100644 --- a/resources/quality/ultimaker2_plus/um2p_global_High_Quality.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_global_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_global_Normal_Quality.inst.cfg b/resources/quality/ultimaker2_plus/um2p_global_Normal_Quality.inst.cfg index 76c7b8163c..c901687f22 100644 --- a/resources/quality/ultimaker2_plus/um2p_global_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_global_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.25_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.25_high.inst.cfg index 2cab693c74..512f9e499b 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.25_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.25_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.25_normal.inst.cfg index f61a29a35a..ce607f7a83 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.25_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.4_fast.inst.cfg index 341dc7422f..7b06d5205c 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.4_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.4_normal.inst.cfg index 63bc156e15..b65f694e11 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.4_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.6_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.6_fast.inst.cfg index 8aea23fb50..6caa1d2e82 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.6_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.6_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.6_normal.inst.cfg index 28ccd6ffcf..3dad97297f 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.6_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.8_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.8_draft.inst.cfg index f868313ba9..fe5749aeff 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.8_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.8_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.8_normal.inst.cfg index c30d849553..3e16229ad1 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.8_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.25_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.25_high.inst.cfg index 08b60eeb20..0195a6170f 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.25_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.25_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.25_normal.inst.cfg index dbc36f0c25..fe15f050c7 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.25_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg index 18f299b64d..1268e4f5a5 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.4_normal.inst.cfg index 9ebb46c4d3..31a55131bd 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.4_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg index 47f84fe790..a4b0e7865e 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.6_normal.inst.cfg index 2c857435c5..9fef7be2f8 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.6_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.8_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.8_draft.inst.cfg index 6450d9fe56..cfbd0795ab 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.8_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.8_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.8_normal.inst.cfg index 91c990712e..fd24f29c40 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.8_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.4_fast.inst.cfg index 4266bcd46b..8e320bef25 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.4_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.4_normal.inst.cfg index b995c92922..94d7a22965 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.4_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.6_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.6_draft.inst.cfg index a9e4917fa2..aee8437e39 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.6_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.6_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.6_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.6_fast.inst.cfg index 2fec539e2f..f1e709495b 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.6_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.6_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg index 2bba1be3d4..a3170f49d6 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -2 diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg index 15f7577bdb..eaa18ad931 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -3 diff --git a/resources/quality/ultimaker2_plus/um2p_tpu_0.25_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_tpu_0.25_high.inst.cfg index e0c016abee..47bf078c2f 100644 --- a/resources/quality/ultimaker2_plus/um2p_tpu_0.25_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_tpu_0.25_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker2_plus/um2p_tpu_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_tpu_0.4_normal.inst.cfg index 127f281913..d8543f1f8a 100644 --- a/resources/quality/ultimaker2_plus/um2p_tpu_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_tpu_0.4_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_tpu_0.6_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_tpu_0.6_fast.inst.cfg index c39ea9cec3..1983878a79 100644 --- a/resources/quality/ultimaker2_plus/um2p_tpu_0.6_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_tpu_0.6_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.25_ABS_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_ABS_Normal_Quality.inst.cfg index 5139a1fea8..dda9fd3891 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_ABS_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_ABS_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.25_CPE_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_CPE_Normal_Quality.inst.cfg index 4e81b4f39e..922366d716 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_CPE_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_CPE_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.25_Nylon_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_Nylon_Normal_Quality.inst.cfg index 04dc2ec79b..3535bc4cba 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_Nylon_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_Nylon_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg index 4d585b54c1..f24c53aaee 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine - Experimental definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.25_PLA_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_PLA_Normal_Quality.inst.cfg index 8dbca3cd05..a59c404754 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_PLA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_PLA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg index bee345e302..6f9734511b 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine - Experimental definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.25_TPLA_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_TPLA_Normal_Quality.inst.cfg index 768864bfef..af9bea762a 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_TPLA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_TPLA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.4_ABS_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_ABS_Draft_Print.inst.cfg index 8877912a33..a6ba0a666b 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_ABS_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_ABS_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.4_ABS_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_ABS_Fast_Print.inst.cfg index 926cfd6995..4bd04e36af 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_ABS_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_ABS_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg index 4e79728945..6ef2fa3cb4 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg index 3bded3b97c..e0862a137c 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.4_BAM_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_BAM_Draft_Print.inst.cfg index df7f0fdf02..3de7252b86 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_BAM_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_BAM_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.4_BAM_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_BAM_Fast_Print.inst.cfg index cf330dc984..28bce4eb15 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_BAM_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_BAM_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_BAM_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_BAM_Normal_Quality.inst.cfg index 705c9c4105..0f15931e59 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_BAM_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_BAM_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Draft_Print.inst.cfg index 4e94789a6b..c27fc027fb 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Fast_Print.inst.cfg index d93915d721..6a035522f1 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPEP_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPEP_High_Quality.inst.cfg index 082152c50f..3387430d26 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPEP_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPEP_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Normal_Quality.inst.cfg index 889b94e001..8d0283a20f 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPE_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPE_Draft_Print.inst.cfg index 1891a274c8..a8d5c26315 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPE_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPE_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPE_Fast_Print.inst.cfg index e4cfdb67fc..e4b4e2e21b 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPE_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPE_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPE_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPE_High_Quality.inst.cfg index cec4b950cf..3964608aec 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPE_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPE_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPE_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPE_Normal_Quality.inst.cfg index 892083b264..b0e7234c90 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPE_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPE_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Draft_Print.inst.cfg index 2e4b8f8dcc..5bfa29fd61 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Fast_Print.inst.cfg index 9b271c47cd..eaec1cdbdb 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_Nylon_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_Nylon_High_Quality.inst.cfg index 16c0b6febb..7a0a04b6c2 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_Nylon_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_Nylon_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Normal_Quality.inst.cfg index 17661efbb8..8b18ee20df 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PC_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PC_Draft_Print.inst.cfg index 96acf403a5..fafb839f17 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PC_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PC_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PC_Fast_Print.inst.cfg index f9159b5fca..57527f928c 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PC_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PC_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PC_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PC_High_Quality.inst.cfg index d175e99ad6..37e31c5863 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PC_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PC_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PC_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PC_Normal_Quality.inst.cfg index 557a449022..0961b3ccd6 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PC_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PC_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PLA_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PLA_Draft_Print.inst.cfg index 16626dc544..c24c2cacdf 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PLA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PLA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PLA_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PLA_Fast_Print.inst.cfg index 7f50a2a6f0..d20a06a94a 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PLA_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PLA_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PLA_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PLA_High_Quality.inst.cfg index 507afc5526..bd365c56ae 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PLA_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PLA_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PLA_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PLA_Normal_Quality.inst.cfg index 05febab06d..a291357e58 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PLA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PLA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PP_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PP_Draft_Print.inst.cfg index 4efa5199cb..6dbb444454 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PP_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PP_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PP_Fast_Print.inst.cfg index ad03df5d86..60c304794b 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PP_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PP_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PP_Normal_Quality.inst.cfg index d8d51dd716..92d53d6295 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PP_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.4_TPLA_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_TPLA_Draft_Print.inst.cfg index 9959a39457..6d8c6690a2 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_TPLA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_TPLA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.4_TPLA_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_TPLA_Fast_Print.inst.cfg index 5c68557e9b..c8fbe827e3 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_TPLA_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_TPLA_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_TPLA_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_TPLA_Normal_Quality.inst.cfg index 90556ea487..d1a1bc994c 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_TPLA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_TPLA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.4_TPU_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_TPU_Draft_Print.inst.cfg index 9b9dca3a16..13bc7c0b7e 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_TPU_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_TPU_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.4_TPU_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_TPU_Fast_Print.inst.cfg index e6233a8184..cb3692a84f 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_TPU_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_TPU_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_TPU_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_TPU_Normal_Quality.inst.cfg index e725615854..a5264ce6ec 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_TPU_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_TPU_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.8_ABS_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_ABS_Draft_Print.inst.cfg index e71ea07531..474b24a462 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_ABS_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_ABS_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.8_ABS_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_ABS_Superdraft_Print.inst.cfg index 39aa103631..e9c4f9e3e9 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_ABS_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_ABS_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_aa0.8_ABS_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_ABS_Verydraft_Print.inst.cfg index 3a08643086..213298653a 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_ABS_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_ABS_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg index fc4acf3cb0..bb2aa2d6ef 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast - Experimental definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Superdraft_Print.inst.cfg index 36b3ef603f..98086b2bf1 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint - Experimental definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Verydraft_Print.inst.cfg index 14e08cb14d..0684b9ac1e 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast - Experimental definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPE_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPE_Draft_Print.inst.cfg index 170643275c..05294737b6 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPE_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPE_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPE_Superdraft_Print.inst.cfg index 5b3cb52f18..555d6da1bf 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPE_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPE_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPE_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPE_Verydraft_Print.inst.cfg index fff96ba9fc..da71c679ff 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPE_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPE_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Draft_Print.inst.cfg index e9b0873716..ab11f0fe86 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Superdraft_Print.inst.cfg index 7518acc7f0..46f5a87a1b 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Verydraft_Print.inst.cfg index 040632efec..12d96e9f7d 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg index c2bb6d4988..7fbd9dbf57 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast - Experimental definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg index e815b673d1..5e0b65507f 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint - Experimental definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg index c50cee576d..35558f7b80 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast - Experimental definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PLA_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PLA_Draft_Print.inst.cfg index 9b861030d8..c5000b0a43 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PLA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PLA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PLA_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PLA_Superdraft_Print.inst.cfg index 42a499f22c..e03663bc2b 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PLA_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PLA_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PLA_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PLA_Verydraft_Print.inst.cfg index d1f3937244..06bf4cf224 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PLA_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PLA_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PP_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PP_Draft_Print.inst.cfg index 19496565bc..b577ba8185 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PP_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PP_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PP_Superdraft_Print.inst.cfg index aeee3b4e09..c0917a9e8e 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PP_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PP_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PP_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PP_Verydraft_Print.inst.cfg index fcd4fcd999..00eb39a400 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PP_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PP_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_TPLA_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_TPLA_Draft_Print.inst.cfg index 3f679870fd..30ce94000f 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_TPLA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_TPLA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.8_TPLA_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_TPLA_Superdraft_Print.inst.cfg index 17dbd1faf9..ea3525c7ee 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_TPLA_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_TPLA_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_aa0.8_TPLA_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_TPLA_Verydraft_Print.inst.cfg index 624496a9ec..1027f52b38 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_TPLA_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_TPLA_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_TPU_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_TPU_Draft_Print.inst.cfg index 90b5103f20..83fb56a84d 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_TPU_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_TPU_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.8_TPU_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_TPU_Superdraft_Print.inst.cfg index a9fab40d4e..36e38654db 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_TPU_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_TPU_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_aa0.8_TPU_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_TPU_Verydraft_Print.inst.cfg index e2ced0a364..96b1406adb 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_TPU_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_TPU_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker3/um3_bb0.4_PVA_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_PVA_Draft_Print.inst.cfg index 7010d292b2..a41b0c0210 100644 --- a/resources/quality/ultimaker3/um3_bb0.4_PVA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.4_PVA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_bb0.4_PVA_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_PVA_Fast_Print.inst.cfg index 325609362f..d7a8885bf9 100644 --- a/resources/quality/ultimaker3/um3_bb0.4_PVA_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.4_PVA_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_bb0.4_PVA_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_PVA_High_Quality.inst.cfg index a0507299fb..be4eedadc8 100644 --- a/resources/quality/ultimaker3/um3_bb0.4_PVA_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.4_PVA_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker3/um3_bb0.4_PVA_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_PVA_Normal_Quality.inst.cfg index 086f811b36..ae576790a8 100644 --- a/resources/quality/ultimaker3/um3_bb0.4_PVA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.4_PVA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_bb0.8_PVA_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_PVA_Draft_Print.inst.cfg index 28556ca7bf..247e7f12c6 100644 --- a/resources/quality/ultimaker3/um3_bb0.8_PVA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.8_PVA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_bb0.8_PVA_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_PVA_Superdraft_Print.inst.cfg index 9ad5499f18..8a4c0cc992 100644 --- a/resources/quality/ultimaker3/um3_bb0.8_PVA_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.8_PVA_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_bb0.8_PVA_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_PVA_Verydraft_Print.inst.cfg index e616214704..c931e6ad5d 100644 --- a/resources/quality/ultimaker3/um3_bb0.8_PVA_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.8_PVA_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg index a421203220..b95ddb1aa9 100644 --- a/resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg index 2ecf7526a2..3510a05343 100644 --- a/resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg index ce5497bd39..a738449255 100644 --- a/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 0 diff --git a/resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg index afadda378a..cffacfd312 100644 --- a/resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_global_Superdraft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Superdraft_Quality.inst.cfg index f88f5df85f..5fd966bb9f 100644 --- a/resources/quality/ultimaker3/um3_global_Superdraft_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_global_Superdraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_global_Verydraft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Verydraft_Quality.inst.cfg index df626dc724..7e65a6c4c4 100644 --- a/resources/quality/ultimaker3/um3_global_Verydraft_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_global_Verydraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_original/umo_global_Coarse_Quality.inst.cfg b/resources/quality/ultimaker_original/umo_global_Coarse_Quality.inst.cfg index 34f3a2a901..6125d0f687 100644 --- a/resources/quality/ultimaker_original/umo_global_Coarse_Quality.inst.cfg +++ b/resources/quality/ultimaker_original/umo_global_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Coarse Quality definition = ultimaker_original [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = coarse weight = -3 diff --git a/resources/quality/ultimaker_original/umo_global_Draft_Quality.inst.cfg b/resources/quality/ultimaker_original/umo_global_Draft_Quality.inst.cfg index ed8c0ddb97..ebabe4dd46 100644 --- a/resources/quality/ultimaker_original/umo_global_Draft_Quality.inst.cfg +++ b/resources/quality/ultimaker_original/umo_global_Draft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Draft Quality definition = ultimaker_original [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_original/umo_global_Extra_Coarse_Quality.inst.cfg b/resources/quality/ultimaker_original/umo_global_Extra_Coarse_Quality.inst.cfg index 1ad10ac4db..b625ec45ea 100644 --- a/resources/quality/ultimaker_original/umo_global_Extra_Coarse_Quality.inst.cfg +++ b/resources/quality/ultimaker_original/umo_global_Extra_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse Quality definition = ultimaker_original [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extra coarse weight = -4 diff --git a/resources/quality/ultimaker_original/umo_global_Fast_Quality.inst.cfg b/resources/quality/ultimaker_original/umo_global_Fast_Quality.inst.cfg index 6c83239164..e2bceeae7e 100644 --- a/resources/quality/ultimaker_original/umo_global_Fast_Quality.inst.cfg +++ b/resources/quality/ultimaker_original/umo_global_Fast_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_original [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_original/umo_global_High_Quality.inst.cfg b/resources/quality/ultimaker_original/umo_global_High_Quality.inst.cfg index 19752f07bf..883048f557 100644 --- a/resources/quality/ultimaker_original/umo_global_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_original/umo_global_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_original [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_original/umo_global_Normal_Quality.inst.cfg b/resources/quality/ultimaker_original/umo_global_Normal_Quality.inst.cfg index a7dedc9b88..2cec4bfbda 100644 --- a/resources/quality/ultimaker_original/umo_global_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_original/umo_global_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_original [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.25_ABS_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.25_ABS_Normal_Quality.inst.cfg index f2e05b08e8..be8e56d133 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.25_ABS_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.25_ABS_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.25_CPE_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.25_CPE_Normal_Quality.inst.cfg index c15311d104..3eaeda67d5 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.25_CPE_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.25_CPE_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.25_Nylon_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.25_Nylon_Normal_Quality.inst.cfg index 3a8ed8e773..9407fb72b0 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.25_Nylon_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.25_Nylon_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.25_PC_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.25_PC_Normal_Quality.inst.cfg index 53c319d6e6..7cde76a1e1 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.25_PC_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.25_PC_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine - Experimental definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.25_PLA_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.25_PLA_Normal_Quality.inst.cfg index a06f2158fe..ab45d82a3b 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.25_PLA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.25_PLA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.25_PP_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.25_PP_Normal_Quality.inst.cfg index b4d34cc392..1474cad5c1 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.25_PP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.25_PP_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine - Experimental definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.25_TPLA_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.25_TPLA_Normal_Quality.inst.cfg index e9628225bc..ea4375b854 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.25_TPLA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.25_TPLA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Draft_Print.inst.cfg index b86c61b3a2..6d26c2bb97 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Fast_Print.inst.cfg index f3c099724a..e2e8bd82e5 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_High_Quality.inst.cfg index 8d016a2ee4..fc39383f04 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Normal_Quality.inst.cfg index 6ce623b66e..8ec7e6453b 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Draft_Print.inst.cfg index 254afbc109..93665c36de 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Fast_Print.inst.cfg index 39bedce77f..478df58f43 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Normal_Quality.inst.cfg index c87d590650..e936d0f131 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Draft_Print.inst.cfg index 627302e0ab..da639d22c9 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Fast_Print.inst.cfg index cda8d85211..2c2eb99fb0 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_High_Quality.inst.cfg index 3ce76bf6be..20fbcd9430 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Normal_Quality.inst.cfg index d402b663c6..e40949fc7d 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Draft_Print.inst.cfg index 505cd952d2..7ccfe4f786 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Fast_Print.inst.cfg index cc5df0abb9..f12c90bc05 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_High_Quality.inst.cfg index c81dc0f5a7..04957025f1 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Normal_Quality.inst.cfg index 7d29f8fb7c..b0a5fb820f 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Draft_Print.inst.cfg index 991ad30a5a..1a198f3e03 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Fast_Print.inst.cfg index 695ce2c8fb..e6b882d2af 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_High_Quality.inst.cfg index e55867efe5..292ef73a4c 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Normal_Quality.inst.cfg index 41e28c51d5..2b71a01e0d 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Draft_Print.inst.cfg index 5d03e1c980..e27a6894e3 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Fast_Print.inst.cfg index b630ab6232..db1ecee3bc 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_High_Quality.inst.cfg index 1c080c3b47..ca80494f3d 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Normal_Quality.inst.cfg index 79ce686da5..d2d5171fed 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Draft_Print.inst.cfg index c7a4864328..9bf58d4f39 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Fast_Print.inst.cfg index 42048fa297..017bf46bd8 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_High_Quality.inst.cfg index b7ad8bd5c4..314f7fe0bb 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Normal_Quality.inst.cfg index 911fa9a0a8..2bb0d31d76 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Draft_Print.inst.cfg index 68558bcf93..8b8bdfd999 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Fast_Print.inst.cfg index 1145d1900f..0fd70e5973 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Normal_Quality.inst.cfg index c0b094f0a2..0d683a9f87 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Draft_Print.inst.cfg index 280e5c4bfb..df45c190e1 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Fast_Print.inst.cfg index 304c170b55..96b77ebca9 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_High_Quality.inst.cfg index cd5c598d4f..3a2cf495a3 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Normal_Quality.inst.cfg index 2522c0f20f..2d93d1e980 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Draft_Print.inst.cfg index 9b4ab52543..30a1e0c29f 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Fast_Print.inst.cfg index 35cf66a93b..3b57900a46 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Normal_Quality.inst.cfg index 4357d765df..368bfd9e48 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Draft_Print.inst.cfg index c8d64f9dcb..a2b7aa7b87 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Fast_Print.inst.cfg index c7fa604e89..8e82e27210 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_High_Quality.inst.cfg index 187023d3c0..7e4f17cbf1 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Normal_Quality.inst.cfg index 81cb27f060..959d9241c7 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Draft_Print.inst.cfg index 4a55f5d24c..c9083cf2ab 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Fast_Print.inst.cfg index 730e058212..9d7663b6e1 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_High_Quality.inst.cfg index e6921e63d8..ba796da940 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Normal_Quality.inst.cfg index a4eec45e38..96ec8d9e36 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Draft_Print.inst.cfg index 4f085f10a6..bae8b09016 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Fast_Print.inst.cfg index 2580bf952d..f585c2a787 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_High_Quality.inst.cfg index d6f07c37a5..a580a27176 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Normal_Quality.inst.cfg index 6032ff3845..3db4053d2a 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Draft_Print.inst.cfg index f05ecddc25..e86c3b363b 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Fast_Print.inst.cfg index 6103519f1c..0da88626b6 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_High_Quality.inst.cfg index 130afb8c91..d7552ba921 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Normal_Quality.inst.cfg index 9e1bf394d4..638ce2323e 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Draft_Print.inst.cfg index 6124dff257..c0ca84281d 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Fast_Print.inst.cfg index 2791e9f5d5..43b77f6492 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Normal_Quality.inst.cfg index f78b4048fb..04abd0d18b 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Draft_Print.inst.cfg index 911fc6e78e..fb786c7759 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Superdraft_Print.inst.cfg index 0fcdac4a85..cfacaebad0 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Verydraft_Print.inst.cfg index e3346bbd1d..18ce266cd6 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Fast_Print.inst.cfg index d126dddaad..a4a7a5e08c 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast - Experimental definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Superdraft_Print.inst.cfg index dd8b20652a..e4f330099b 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint - Experimental definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Verydraft_Print.inst.cfg index bc107422f1..0685b27b8a 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast - Experimental definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Draft_Print.inst.cfg index 7cb69ba3eb..a57bde98b1 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Superdraft_Print.inst.cfg index 6c323fe602..2f0851d9fb 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Verydraft_Print.inst.cfg index a0380ecc0e..6ccca75b44 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Draft_Print.inst.cfg index 2108839d3f..5d04892443 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Superdraft_Print.inst.cfg index 0702d174a0..5c31e26bd6 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Verydraft_Print.inst.cfg index d02d410ed6..d04482c94c 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Fast_Print.inst.cfg index c24aa9a98d..0513aa7920 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast - Experimental definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Superdraft_Print.inst.cfg index 5fc306b1f1..f37f3fd6f5 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint - Experimental definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Verydraft_Print.inst.cfg index 996adf5be7..7b4da2d7cc 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast - Experimental definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Draft_Print.inst.cfg index 7db4e96311..1410290859 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Superdraft_Print.inst.cfg index c59f015b5d..2c65968d77 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Verydraft_Print.inst.cfg index 6fdff8bf8d..9b6e7c2ed9 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Draft_Print.inst.cfg index fee58b367d..c5b01ab1b1 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Superdraft_Print.inst.cfg index aaa810e864..5c83f24395 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Verydraft_Print.inst.cfg index 5b8aa6d2e1..f182d5c6cb 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Draft_Print.inst.cfg index 50dead746b..5b39508f3c 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Superdraft_Print.inst.cfg index 0bdb088f8c..b07a78419a 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Verydraft_Print.inst.cfg index c7cb5902a2..46a61bb79f 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Draft_Print.inst.cfg index e8276d54c5..088414fa34 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Superdraft_Print.inst.cfg index 7da73a200d..d74309c476 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Verydraft_Print.inst.cfg index 60dbbf38e6..deb2b55dbb 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Draft_Print.inst.cfg index 37dceff349..062fcfdd5b 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Superdraft_Print.inst.cfg index eac339baa8..38c341af28 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Verydraft_Print.inst.cfg index 590496df0f..8a38bb9aa3 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Fast_Print.inst.cfg index 50091a6fb4..d9dd09c7b6 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast - Experimental definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Superdraft_Print.inst.cfg index b9c9ef6611..bc6a04ae55 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Verydraft_Print.inst.cfg index be2cc62b08..b384bd7083 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Draft_Print.inst.cfg index 0d0ed8f8b2..28409d4181 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Superdraft_Print.inst.cfg index a163e0c735..33c5d73a59 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Verydraft_Print.inst.cfg index 2137cf740b..8db23c11c2 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Fast_Print.inst.cfg index 6fdd22c6b0..c853d3ebc5 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast - Experimental definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Superdraft_Print.inst.cfg index 689652dc06..f78e6a92d2 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Verydraft_Print.inst.cfg index 0480ee5620..b1d199ec9b 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Draft_Print.inst.cfg index b80af1b75f..5a2c3005c9 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Superdraft_Print.inst.cfg index 970e0971a9..aaa8cbfcd3 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Verydraft_Print.inst.cfg index e51ba3207b..782cadce6b 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Draft_Print.inst.cfg index 73639be0b6..34b078278c 100644 --- a/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Fast_Print.inst.cfg index 5da25be32d..5677c5931c 100644 --- a/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_High_Quality.inst.cfg index 36634af2c8..b9e32cb7c5 100644 --- a/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Normal_Quality.inst.cfg index f76c4c944a..081ee2261e 100644 --- a/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Draft_Print.inst.cfg index e4e3ab772a..0193081db6 100644 --- a/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Superdraft_Print.inst.cfg index 5e78e51014..121b32f903 100644 --- a/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Verydraft_Print.inst.cfg index 5af09aebcc..f0296c9279 100644 --- a/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFCPE_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFCPE_Draft_Print.inst.cfg index 99b4b142fa..4aa31aaba3 100644 --- a/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFCPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFCPE_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFPA_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFPA_Draft_Print.inst.cfg index 80c383aa8d..14aeca4194 100644 --- a/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFPA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFPA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFCPE_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFCPE_Draft_Print.inst.cfg index c94d239c81..1a0abc1ee2 100644 --- a/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFCPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFCPE_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFPA_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFPA_Draft_Print.inst.cfg index e7d4d1955b..7f462e5634 100644 --- a/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFPA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFPA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_global_Draft_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_global_Draft_Quality.inst.cfg index ed5303637b..f0121fa4d7 100644 --- a/resources/quality/ultimaker_s5/um_s5_global_Draft_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_global_Draft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_global_Fast_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_global_Fast_Quality.inst.cfg index ee9c6a8409..b9bb0beff6 100644 --- a/resources/quality/ultimaker_s5/um_s5_global_Fast_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_global_Fast_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_global_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_global_High_Quality.inst.cfg index cd1c269b1d..aa07e1dc3c 100644 --- a/resources/quality/ultimaker_s5/um_s5_global_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_global_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_global_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_global_Normal_Quality.inst.cfg index 099ba7c584..8bb8f7f282 100644 --- a/resources/quality/ultimaker_s5/um_s5_global_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_global_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_global_Superdraft_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_global_Superdraft_Quality.inst.cfg index 4c0bd40bd1..ec46668b61 100644 --- a/resources/quality/ultimaker_s5/um_s5_global_Superdraft_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_global_Superdraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_global_Verydraft_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_global_Verydraft_Quality.inst.cfg index ec4ec910ff..dd6c7bb4b8 100644 --- a/resources/quality/ultimaker_s5/um_s5_global_Verydraft_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_global_Verydraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/vertex_delta_k8800/k8800_ABS_Extreme_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_ABS_Extreme_Quality.inst.cfg index 70aac3f666..370cc149a2 100644 --- a/resources/quality/vertex_delta_k8800/k8800_ABS_Extreme_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_ABS_Extreme_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extreme definition = vertex_delta_k8800 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extreme weight = 2 diff --git a/resources/quality/vertex_delta_k8800/k8800_ABS_High_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_ABS_High_Quality.inst.cfg index 564b330132..6c96b47169 100644 --- a/resources/quality/vertex_delta_k8800/k8800_ABS_High_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_ABS_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High definition = vertex_delta_k8800 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/vertex_delta_k8800/k8800_ABS_Normal_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_ABS_Normal_Quality.inst.cfg index e2f740a60a..19150baab9 100644 --- a/resources/quality/vertex_delta_k8800/k8800_ABS_Normal_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_ABS_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = vertex_delta_k8800 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/vertex_delta_k8800/k8800_Global_Extreme_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_Global_Extreme_Quality.inst.cfg index 48e80b5512..00d626d72c 100644 --- a/resources/quality/vertex_delta_k8800/k8800_Global_Extreme_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_Global_Extreme_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extreme definition = vertex_delta_k8800 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extreme weight = 2 diff --git a/resources/quality/vertex_delta_k8800/k8800_Global_High_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_Global_High_Quality.inst.cfg index 496144772c..0bd519affe 100644 --- a/resources/quality/vertex_delta_k8800/k8800_Global_High_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_Global_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High definition = vertex_delta_k8800 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/vertex_delta_k8800/k8800_Global_Normal_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_Global_Normal_Quality.inst.cfg index 75ae5f15e6..2b18891998 100644 --- a/resources/quality/vertex_delta_k8800/k8800_Global_Normal_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_Global_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = vertex_delta_k8800 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/vertex_delta_k8800/k8800_PET_Extreme_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PET_Extreme_Quality.inst.cfg index 8309106d9f..8715e573ab 100644 --- a/resources/quality/vertex_delta_k8800/k8800_PET_Extreme_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_PET_Extreme_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extreme definition = vertex_delta_k8800 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extreme weight = 2 diff --git a/resources/quality/vertex_delta_k8800/k8800_PET_High_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PET_High_Quality.inst.cfg index 6efaa3299f..0c94cc5ca4 100644 --- a/resources/quality/vertex_delta_k8800/k8800_PET_High_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_PET_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High definition = vertex_delta_k8800 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/vertex_delta_k8800/k8800_PET_Normal_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PET_Normal_Quality.inst.cfg index bd3b0c35fb..40698f134d 100644 --- a/resources/quality/vertex_delta_k8800/k8800_PET_Normal_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_PET_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = vertex_delta_k8800 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/vertex_delta_k8800/k8800_PLA_Extreme_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PLA_Extreme_Quality.inst.cfg index d10b4c3f8d..f81c82fa9b 100644 --- a/resources/quality/vertex_delta_k8800/k8800_PLA_Extreme_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_PLA_Extreme_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extreme definition = vertex_delta_k8800 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extreme weight = 2 diff --git a/resources/quality/vertex_delta_k8800/k8800_PLA_High_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PLA_High_Quality.inst.cfg index ede77b0dfe..e4b4771b0e 100644 --- a/resources/quality/vertex_delta_k8800/k8800_PLA_High_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_PLA_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High definition = vertex_delta_k8800 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/vertex_delta_k8800/k8800_PLA_Normal_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PLA_Normal_Quality.inst.cfg index a75cff6968..41950da7a1 100644 --- a/resources/quality/vertex_delta_k8800/k8800_PLA_Normal_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_PLA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = vertex_delta_k8800 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/vertex_delta_k8800/k8800_TPU_Extreme_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_TPU_Extreme_Quality.inst.cfg index bee6b3bf11..32077f6cc1 100644 --- a/resources/quality/vertex_delta_k8800/k8800_TPU_Extreme_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_TPU_Extreme_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extreme definition = vertex_delta_k8800 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = extreme weight = 2 diff --git a/resources/quality/vertex_delta_k8800/k8800_TPU_High_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_TPU_High_Quality.inst.cfg index 8b0f87cc77..a7ef7d8cc8 100644 --- a/resources/quality/vertex_delta_k8800/k8800_TPU_High_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_TPU_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High definition = vertex_delta_k8800 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = high weight = 1 diff --git a/resources/quality/vertex_delta_k8800/k8800_TPU_Normal_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_TPU_Normal_Quality.inst.cfg index bd4e04744f..17a09f366f 100644 --- a/resources/quality/vertex_delta_k8800/k8800_TPU_Normal_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_TPU_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = vertex_delta_k8800 [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/zyyx/zyyx_agile_global_fast.inst.cfg b/resources/quality/zyyx/zyyx_agile_global_fast.inst.cfg index 67e350b39e..19cda650d3 100644 --- a/resources/quality/zyyx/zyyx_agile_global_fast.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_global_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = zyyx_agile [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = 1 diff --git a/resources/quality/zyyx/zyyx_agile_global_fine.inst.cfg b/resources/quality/zyyx/zyyx_agile_global_fine.inst.cfg index 58e13b22c5..f5b6aca497 100644 --- a/resources/quality/zyyx/zyyx_agile_global_fine.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_global_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = zyyx_agile [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fine weight = 3 diff --git a/resources/quality/zyyx/zyyx_agile_global_normal.inst.cfg b/resources/quality/zyyx/zyyx_agile_global_normal.inst.cfg index cb4e042e7b..46d31c9749 100644 --- a/resources/quality/zyyx/zyyx_agile_global_normal.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_global_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = zyyx_agile [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 2 diff --git a/resources/quality/zyyx/zyyx_agile_pro_flex_fast.inst.cfg b/resources/quality/zyyx/zyyx_agile_pro_flex_fast.inst.cfg index 188bdd25e5..d6f715c09f 100644 --- a/resources/quality/zyyx/zyyx_agile_pro_flex_fast.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_pro_flex_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = zyyx_agile [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = 1 diff --git a/resources/quality/zyyx/zyyx_agile_pro_flex_fine.inst.cfg b/resources/quality/zyyx/zyyx_agile_pro_flex_fine.inst.cfg index 6654889c10..c617eb646e 100644 --- a/resources/quality/zyyx/zyyx_agile_pro_flex_fine.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_pro_flex_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = zyyx_agile [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fine weight = 3 diff --git a/resources/quality/zyyx/zyyx_agile_pro_flex_normal.inst.cfg b/resources/quality/zyyx/zyyx_agile_pro_flex_normal.inst.cfg index f56355100c..a9164b5118 100644 --- a/resources/quality/zyyx/zyyx_agile_pro_flex_normal.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_pro_flex_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = zyyx_agile [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 2 diff --git a/resources/quality/zyyx/zyyx_agile_pro_pla_fast.inst.cfg b/resources/quality/zyyx/zyyx_agile_pro_pla_fast.inst.cfg index 7ae4be06b0..5b32c3f07b 100644 --- a/resources/quality/zyyx/zyyx_agile_pro_pla_fast.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_pro_pla_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = zyyx_agile [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fast weight = 1 diff --git a/resources/quality/zyyx/zyyx_agile_pro_pla_fine.inst.cfg b/resources/quality/zyyx/zyyx_agile_pro_pla_fine.inst.cfg index 64c7d4afc8..8ec5495334 100644 --- a/resources/quality/zyyx/zyyx_agile_pro_pla_fine.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_pro_pla_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = zyyx_agile [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = fine weight = 3 diff --git a/resources/quality/zyyx/zyyx_agile_pro_pla_normal.inst.cfg b/resources/quality/zyyx/zyyx_agile_pro_pla_normal.inst.cfg index dbdd600ece..c00daca9af 100644 --- a/resources/quality/zyyx/zyyx_agile_pro_pla_normal.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_pro_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = zyyx_agile [metadata] -setting_version = 5 +setting_version = 6 type = quality quality_type = normal weight = 2 diff --git a/resources/variants/cartesio_0.25.inst.cfg b/resources/variants/cartesio_0.25.inst.cfg index b3aae8a393..53048622f2 100644 --- a/resources/variants/cartesio_0.25.inst.cfg +++ b/resources/variants/cartesio_0.25.inst.cfg @@ -5,7 +5,7 @@ definition = cartesio [metadata] author = Cartesio -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/cartesio_0.4.inst.cfg b/resources/variants/cartesio_0.4.inst.cfg index 5cea5823c4..3ad6b3f3d9 100644 --- a/resources/variants/cartesio_0.4.inst.cfg +++ b/resources/variants/cartesio_0.4.inst.cfg @@ -5,7 +5,7 @@ definition = cartesio [metadata] author = Cartesio -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/cartesio_0.8.inst.cfg b/resources/variants/cartesio_0.8.inst.cfg index b4009cf9ed..f19c4d58d4 100644 --- a/resources/variants/cartesio_0.8.inst.cfg +++ b/resources/variants/cartesio_0.8.inst.cfg @@ -5,7 +5,7 @@ definition = cartesio [metadata] author = Cartesio -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/fabtotum_hyb35.inst.cfg b/resources/variants/fabtotum_hyb35.inst.cfg index d3f0077792..5ed9eca26a 100644 --- a/resources/variants/fabtotum_hyb35.inst.cfg +++ b/resources/variants/fabtotum_hyb35.inst.cfg @@ -5,7 +5,7 @@ definition = fabtotum [metadata] author = FABtotum -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/fabtotum_lite04.inst.cfg b/resources/variants/fabtotum_lite04.inst.cfg index 226c136564..7b52bf5c29 100644 --- a/resources/variants/fabtotum_lite04.inst.cfg +++ b/resources/variants/fabtotum_lite04.inst.cfg @@ -5,7 +5,7 @@ definition = fabtotum [metadata] author = FABtotum -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/fabtotum_lite06.inst.cfg b/resources/variants/fabtotum_lite06.inst.cfg index 62e3014b60..f518f60ce9 100644 --- a/resources/variants/fabtotum_lite06.inst.cfg +++ b/resources/variants/fabtotum_lite06.inst.cfg @@ -5,7 +5,7 @@ definition = fabtotum [metadata] author = FABtotum -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/fabtotum_pro02.inst.cfg b/resources/variants/fabtotum_pro02.inst.cfg index 3e4661ee2c..897bd5aea9 100644 --- a/resources/variants/fabtotum_pro02.inst.cfg +++ b/resources/variants/fabtotum_pro02.inst.cfg @@ -5,7 +5,7 @@ definition = fabtotum [metadata] author = FABtotum -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/fabtotum_pro04.inst.cfg b/resources/variants/fabtotum_pro04.inst.cfg index 3fe140f8be..d27be2f3b8 100644 --- a/resources/variants/fabtotum_pro04.inst.cfg +++ b/resources/variants/fabtotum_pro04.inst.cfg @@ -5,7 +5,7 @@ definition = fabtotum [metadata] author = FABtotum -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/fabtotum_pro06.inst.cfg b/resources/variants/fabtotum_pro06.inst.cfg index fcb5c71ef0..25b9d7c710 100644 --- a/resources/variants/fabtotum_pro06.inst.cfg +++ b/resources/variants/fabtotum_pro06.inst.cfg @@ -5,7 +5,7 @@ definition = fabtotum [metadata] author = FABtotum -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/fabtotum_pro08.inst.cfg b/resources/variants/fabtotum_pro08.inst.cfg index bef04734eb..627e26e2a2 100644 --- a/resources/variants/fabtotum_pro08.inst.cfg +++ b/resources/variants/fabtotum_pro08.inst.cfg @@ -5,7 +5,7 @@ definition = fabtotum [metadata] author = FABtotum -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/felixtec4_0.25.inst.cfg b/resources/variants/felixtec4_0.25.inst.cfg index 7d8bca94b0..3dda15171b 100644 --- a/resources/variants/felixtec4_0.25.inst.cfg +++ b/resources/variants/felixtec4_0.25.inst.cfg @@ -6,7 +6,7 @@ definition = felixtec4dual [metadata] author = kerog777 type = variant -setting_version = 5 +setting_version = 6 hardware_type = nozzle [values] diff --git a/resources/variants/felixtec4_0.35.inst.cfg b/resources/variants/felixtec4_0.35.inst.cfg index f061aa1cbc..db79c3bad4 100644 --- a/resources/variants/felixtec4_0.35.inst.cfg +++ b/resources/variants/felixtec4_0.35.inst.cfg @@ -6,7 +6,7 @@ definition = felixtec4dual [metadata] author = kerog777 type = variant -setting_version = 5 +setting_version = 6 hardware_type = nozzle [values] diff --git a/resources/variants/felixtec4_0.50.inst.cfg b/resources/variants/felixtec4_0.50.inst.cfg index 3c68c42dae..6d52881ee5 100644 --- a/resources/variants/felixtec4_0.50.inst.cfg +++ b/resources/variants/felixtec4_0.50.inst.cfg @@ -7,7 +7,7 @@ definition = felixtec4dual author = kerog777 type = variant hardware_type = nozzle -setting_version = 5 +setting_version = 6 [values] machine_nozzle_size = 0.5 diff --git a/resources/variants/felixtec4_0.70.inst.cfg b/resources/variants/felixtec4_0.70.inst.cfg index 3a52644714..4edeebbc84 100644 --- a/resources/variants/felixtec4_0.70.inst.cfg +++ b/resources/variants/felixtec4_0.70.inst.cfg @@ -7,7 +7,7 @@ definition = felixtec4dual author = kerog777 type = variant hardware_type = nozzle -setting_version = 5 +setting_version = 6 [values] machine_nozzle_size = 0.70 diff --git a/resources/variants/gmax15plus_025_e3d.inst.cfg b/resources/variants/gmax15plus_025_e3d.inst.cfg index 8a6b37067d..a085be0526 100644 --- a/resources/variants/gmax15plus_025_e3d.inst.cfg +++ b/resources/variants/gmax15plus_025_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus [metadata] author = gcreate -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_04_e3d.inst.cfg b/resources/variants/gmax15plus_04_e3d.inst.cfg index a2f779f426..a76e04074b 100644 --- a/resources/variants/gmax15plus_04_e3d.inst.cfg +++ b/resources/variants/gmax15plus_04_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus [metadata] author = gcreate -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_05_e3d.inst.cfg b/resources/variants/gmax15plus_05_e3d.inst.cfg index 68ee111aa1..71e8251fa6 100644 --- a/resources/variants/gmax15plus_05_e3d.inst.cfg +++ b/resources/variants/gmax15plus_05_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus [metadata] author = gcreate -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_05_jhead.inst.cfg b/resources/variants/gmax15plus_05_jhead.inst.cfg index 6d0b084969..d480b47367 100644 --- a/resources/variants/gmax15plus_05_jhead.inst.cfg +++ b/resources/variants/gmax15plus_05_jhead.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus [metadata] author = gcreate -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_06_e3d.inst.cfg b/resources/variants/gmax15plus_06_e3d.inst.cfg index 987e882a09..4c4684cbc8 100644 --- a/resources/variants/gmax15plus_06_e3d.inst.cfg +++ b/resources/variants/gmax15plus_06_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus [metadata] author = gcreate -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_08_e3d.inst.cfg b/resources/variants/gmax15plus_08_e3d.inst.cfg index bf59b47da0..1265dbf474 100644 --- a/resources/variants/gmax15plus_08_e3d.inst.cfg +++ b/resources/variants/gmax15plus_08_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus [metadata] author = gcreate -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_10_jhead.inst.cfg b/resources/variants/gmax15plus_10_jhead.inst.cfg index 47355f344c..aa9e4b76ac 100644 --- a/resources/variants/gmax15plus_10_jhead.inst.cfg +++ b/resources/variants/gmax15plus_10_jhead.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus [metadata] author = gcreate -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_dual_025_e3d.inst.cfg b/resources/variants/gmax15plus_dual_025_e3d.inst.cfg index 750a5381b3..185166d3b5 100644 --- a/resources/variants/gmax15plus_dual_025_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_025_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus_dual [metadata] author = gcreate -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_dual_04_e3d.inst.cfg b/resources/variants/gmax15plus_dual_04_e3d.inst.cfg index 4b5a71c53b..7798d965d6 100644 --- a/resources/variants/gmax15plus_dual_04_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_04_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus_dual [metadata] author = gcreate -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_dual_05_e3d.inst.cfg b/resources/variants/gmax15plus_dual_05_e3d.inst.cfg index 05d9a88d54..f1d67509a9 100644 --- a/resources/variants/gmax15plus_dual_05_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_05_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus_dual [metadata] author = gcreate -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_dual_05_jhead.inst.cfg b/resources/variants/gmax15plus_dual_05_jhead.inst.cfg index 54a237e848..bc72c4ae20 100644 --- a/resources/variants/gmax15plus_dual_05_jhead.inst.cfg +++ b/resources/variants/gmax15plus_dual_05_jhead.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus_dual [metadata] author = gcreate -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_dual_06_e3d.inst.cfg b/resources/variants/gmax15plus_dual_06_e3d.inst.cfg index 39c41be968..545cfcb238 100644 --- a/resources/variants/gmax15plus_dual_06_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_06_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus_dual [metadata] author = gcreate -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_dual_08_e3d.inst.cfg b/resources/variants/gmax15plus_dual_08_e3d.inst.cfg index 1f2d7b9790..1923aac7f7 100644 --- a/resources/variants/gmax15plus_dual_08_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_08_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus_dual [metadata] author = gcreate -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_dual_10_jhead.inst.cfg b/resources/variants/gmax15plus_dual_10_jhead.inst.cfg index cf615bb874..31a1918ab2 100644 --- a/resources/variants/gmax15plus_dual_10_jhead.inst.cfg +++ b/resources/variants/gmax15plus_dual_10_jhead.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus_dual [metadata] author = gcreate -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/imade3d_jellybox_0.4.inst.cfg b/resources/variants/imade3d_jellybox_0.4.inst.cfg index 2bd0f578cf..1623e6755c 100644 --- a/resources/variants/imade3d_jellybox_0.4.inst.cfg +++ b/resources/variants/imade3d_jellybox_0.4.inst.cfg @@ -5,7 +5,7 @@ definition = imade3d_jellybox [metadata] author = IMADE3D -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg b/resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg index 6a93cdf13d..2f1cb002b4 100644 --- a/resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg +++ b/resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg @@ -5,7 +5,7 @@ definition = imade3d_jellybox [metadata] author = IMADE3D -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/tizyx_k25_0.2.inst.cfg b/resources/variants/tizyx_k25_0.2.inst.cfg index cd9f1bcbd1..c616579911 100644 --- a/resources/variants/tizyx_k25_0.2.inst.cfg +++ b/resources/variants/tizyx_k25_0.2.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = tizyx_k25 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/tizyx_k25_0.3.inst.cfg b/resources/variants/tizyx_k25_0.3.inst.cfg index 8b34d23bf6..180d831cca 100644 --- a/resources/variants/tizyx_k25_0.3.inst.cfg +++ b/resources/variants/tizyx_k25_0.3.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = tizyx_k25 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/tizyx_k25_0.4.inst.cfg b/resources/variants/tizyx_k25_0.4.inst.cfg index c147eb0ad0..07ef3ca8ed 100644 --- a/resources/variants/tizyx_k25_0.4.inst.cfg +++ b/resources/variants/tizyx_k25_0.4.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = tizyx_k25 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/tizyx_k25_0.5.inst.cfg b/resources/variants/tizyx_k25_0.5.inst.cfg index 14102fb2c7..a09a207e7a 100644 --- a/resources/variants/tizyx_k25_0.5.inst.cfg +++ b/resources/variants/tizyx_k25_0.5.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = tizyx_k25 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/tizyx_k25_0.6.inst.cfg b/resources/variants/tizyx_k25_0.6.inst.cfg index 00f69f71f4..751cf8e794 100644 --- a/resources/variants/tizyx_k25_0.6.inst.cfg +++ b/resources/variants/tizyx_k25_0.6.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = tizyx_k25 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/tizyx_k25_0.8.inst.cfg b/resources/variants/tizyx_k25_0.8.inst.cfg index c80f5e70d2..cca0986ed5 100644 --- a/resources/variants/tizyx_k25_0.8.inst.cfg +++ b/resources/variants/tizyx_k25_0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = tizyx_k25 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/tizyx_k25_1.0.inst.cfg b/resources/variants/tizyx_k25_1.0.inst.cfg index ce8593b1e8..d99948c26c 100644 --- a/resources/variants/tizyx_k25_1.0.inst.cfg +++ b/resources/variants/tizyx_k25_1.0.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = tizyx_k25 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_0.25.inst.cfg b/resources/variants/ultimaker2_0.25.inst.cfg index a58b4d9a56..004cdaf671 100644 --- a/resources/variants/ultimaker2_0.25.inst.cfg +++ b/resources/variants/ultimaker2_0.25.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_0.4.inst.cfg b/resources/variants/ultimaker2_0.4.inst.cfg index 46845d974e..607d0c4f29 100644 --- a/resources/variants/ultimaker2_0.4.inst.cfg +++ b/resources/variants/ultimaker2_0.4.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_0.6.inst.cfg b/resources/variants/ultimaker2_0.6.inst.cfg index f9ab1f1358..1ddc07817b 100644 --- a/resources/variants/ultimaker2_0.6.inst.cfg +++ b/resources/variants/ultimaker2_0.6.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_0.8.inst.cfg b/resources/variants/ultimaker2_0.8.inst.cfg index 3d9c273783..938b472c2c 100644 --- a/resources/variants/ultimaker2_0.8.inst.cfg +++ b/resources/variants/ultimaker2_0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_extended_0.25.inst.cfg b/resources/variants/ultimaker2_extended_0.25.inst.cfg index f5471fc505..45546c55aa 100644 --- a/resources/variants/ultimaker2_extended_0.25.inst.cfg +++ b/resources/variants/ultimaker2_extended_0.25.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_extended [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_extended_0.4.inst.cfg b/resources/variants/ultimaker2_extended_0.4.inst.cfg index a7d03f2408..fb3d8c1116 100644 --- a/resources/variants/ultimaker2_extended_0.4.inst.cfg +++ b/resources/variants/ultimaker2_extended_0.4.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_extended [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_extended_0.6.inst.cfg b/resources/variants/ultimaker2_extended_0.6.inst.cfg index 25c180e07e..50f7dc04c6 100644 --- a/resources/variants/ultimaker2_extended_0.6.inst.cfg +++ b/resources/variants/ultimaker2_extended_0.6.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_extended [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_extended_0.8.inst.cfg b/resources/variants/ultimaker2_extended_0.8.inst.cfg index c33f483da3..178737dbd5 100644 --- a/resources/variants/ultimaker2_extended_0.8.inst.cfg +++ b/resources/variants/ultimaker2_extended_0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_extended [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg index c65940251c..7e67824d16 100644 --- a/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_extended_plus [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg index 7493f2af44..1150c6127c 100644 --- a/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_extended_plus [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg index c4a3ab6340..fbdef77918 100644 --- a/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_extended_plus [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg index e77ec2a5c2..106537e0a7 100644 --- a/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_extended_plus [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_plus_0.25.inst.cfg b/resources/variants/ultimaker2_plus_0.25.inst.cfg index 7fd7f3980f..c07b80c246 100644 --- a/resources/variants/ultimaker2_plus_0.25.inst.cfg +++ b/resources/variants/ultimaker2_plus_0.25.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_plus_0.4.inst.cfg b/resources/variants/ultimaker2_plus_0.4.inst.cfg index 3b54e0cdef..623fffbeb9 100644 --- a/resources/variants/ultimaker2_plus_0.4.inst.cfg +++ b/resources/variants/ultimaker2_plus_0.4.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_plus_0.6.inst.cfg b/resources/variants/ultimaker2_plus_0.6.inst.cfg index d8fea055e5..b57fa81dfe 100644 --- a/resources/variants/ultimaker2_plus_0.6.inst.cfg +++ b/resources/variants/ultimaker2_plus_0.6.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_plus_0.8.inst.cfg b/resources/variants/ultimaker2_plus_0.8.inst.cfg index 3ae902ac2f..702ec2ef31 100644 --- a/resources/variants/ultimaker2_plus_0.8.inst.cfg +++ b/resources/variants/ultimaker2_plus_0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_plus [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker3_aa0.25.inst.cfg b/resources/variants/ultimaker3_aa0.25.inst.cfg index b46fdf5dfb..fc8cc3b090 100644 --- a/resources/variants/ultimaker3_aa0.25.inst.cfg +++ b/resources/variants/ultimaker3_aa0.25.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker3_aa0.8.inst.cfg b/resources/variants/ultimaker3_aa0.8.inst.cfg index 56740233dd..308bed6fcb 100644 --- a/resources/variants/ultimaker3_aa0.8.inst.cfg +++ b/resources/variants/ultimaker3_aa0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker3_aa04.inst.cfg b/resources/variants/ultimaker3_aa04.inst.cfg index ce91e89d26..25230cd30b 100644 --- a/resources/variants/ultimaker3_aa04.inst.cfg +++ b/resources/variants/ultimaker3_aa04.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker3_bb0.8.inst.cfg b/resources/variants/ultimaker3_bb0.8.inst.cfg index ace0bf3a94..5ccf2816ff 100644 --- a/resources/variants/ultimaker3_bb0.8.inst.cfg +++ b/resources/variants/ultimaker3_bb0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker3_bb04.inst.cfg b/resources/variants/ultimaker3_bb04.inst.cfg index d571cabc9b..d919e5aab7 100644 --- a/resources/variants/ultimaker3_bb04.inst.cfg +++ b/resources/variants/ultimaker3_bb04.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker3 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker3_extended_aa0.25.inst.cfg b/resources/variants/ultimaker3_extended_aa0.25.inst.cfg index 714b017653..ce0f20fa7e 100644 --- a/resources/variants/ultimaker3_extended_aa0.25.inst.cfg +++ b/resources/variants/ultimaker3_extended_aa0.25.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker3_extended [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker3_extended_aa0.8.inst.cfg b/resources/variants/ultimaker3_extended_aa0.8.inst.cfg index f72c96b551..f209508875 100644 --- a/resources/variants/ultimaker3_extended_aa0.8.inst.cfg +++ b/resources/variants/ultimaker3_extended_aa0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker3_extended [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker3_extended_aa04.inst.cfg b/resources/variants/ultimaker3_extended_aa04.inst.cfg index f354784fc6..714d19051f 100644 --- a/resources/variants/ultimaker3_extended_aa04.inst.cfg +++ b/resources/variants/ultimaker3_extended_aa04.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker3_extended [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker3_extended_bb0.8.inst.cfg b/resources/variants/ultimaker3_extended_bb0.8.inst.cfg index fe760c93b8..528c7f70ec 100644 --- a/resources/variants/ultimaker3_extended_bb0.8.inst.cfg +++ b/resources/variants/ultimaker3_extended_bb0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker3_extended [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker3_extended_bb04.inst.cfg b/resources/variants/ultimaker3_extended_bb04.inst.cfg index 742dc9896e..5ee562ee38 100644 --- a/resources/variants/ultimaker3_extended_bb04.inst.cfg +++ b/resources/variants/ultimaker3_extended_bb04.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker3_extended [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker_s5_aa0.25.inst.cfg b/resources/variants/ultimaker_s5_aa0.25.inst.cfg index 643513faad..ebdb096b6f 100644 --- a/resources/variants/ultimaker_s5_aa0.25.inst.cfg +++ b/resources/variants/ultimaker_s5_aa0.25.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker_s5_aa0.8.inst.cfg b/resources/variants/ultimaker_s5_aa0.8.inst.cfg index eca8c400d0..d8ff1c020e 100644 --- a/resources/variants/ultimaker_s5_aa0.8.inst.cfg +++ b/resources/variants/ultimaker_s5_aa0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker_s5_aa04.inst.cfg b/resources/variants/ultimaker_s5_aa04.inst.cfg index b5b694d0c1..ac377e3e78 100644 --- a/resources/variants/ultimaker_s5_aa04.inst.cfg +++ b/resources/variants/ultimaker_s5_aa04.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker_s5_aluminum.inst.cfg b/resources/variants/ultimaker_s5_aluminum.inst.cfg index 1018b7e5ab..ca457bd7e7 100644 --- a/resources/variants/ultimaker_s5_aluminum.inst.cfg +++ b/resources/variants/ultimaker_s5_aluminum.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = buildplate diff --git a/resources/variants/ultimaker_s5_bb0.8.inst.cfg b/resources/variants/ultimaker_s5_bb0.8.inst.cfg index c1c5c1a10b..bb7f2d1420 100644 --- a/resources/variants/ultimaker_s5_bb0.8.inst.cfg +++ b/resources/variants/ultimaker_s5_bb0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker_s5_bb04.inst.cfg b/resources/variants/ultimaker_s5_bb04.inst.cfg index b5ff8d51f6..cda1036507 100644 --- a/resources/variants/ultimaker_s5_bb04.inst.cfg +++ b/resources/variants/ultimaker_s5_bb04.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker_s5_cc06.inst.cfg b/resources/variants/ultimaker_s5_cc06.inst.cfg index 7adf7ab7a0..afbeb44462 100644 --- a/resources/variants/ultimaker_s5_cc06.inst.cfg +++ b/resources/variants/ultimaker_s5_cc06.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker_s5_glass.inst.cfg b/resources/variants/ultimaker_s5_glass.inst.cfg index d74eb3c6c9..e7431c933f 100644 --- a/resources/variants/ultimaker_s5_glass.inst.cfg +++ b/resources/variants/ultimaker_s5_glass.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker_s5 [metadata] -setting_version = 5 +setting_version = 6 type = variant hardware_type = buildplate From a8128919afe233adc5539791028d08cacb22f92d Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 7 Jan 2019 10:41:03 +0100 Subject: [PATCH 1202/1292] Make resize bar slim CURA-6054 --- .../PrintSetupSelectorContents.qml | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml index 77b6cd9b63..0b8fb89311 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml @@ -180,16 +180,9 @@ Item UM.RecolorImage { width: parent.width * 0.05 - sourceSize.height: height - sourceSize.width: width - anchors - { - horizontalCenter: parent.horizontalCenter - top: parent.top - topMargin: UM.Theme.getSize("thick_lining").height - bottom: parent.bottom - bottomMargin: UM.Theme.getSize("thick_lining").height - } + height: parent.height * 0.3 + + anchors.centerIn: parent source: UM.Theme.getIcon("grip_lines") color: UM.Theme.getColor("lining") From 059fede06e7e5e06971cf59d8f34acf86b4562d1 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 7 Jan 2019 10:53:18 +0100 Subject: [PATCH 1203/1292] Mkae default custom settings panel height smaller CURA-6054 --- cura/CuraApplication.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 4d1c530237..f927e64044 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -499,7 +499,7 @@ class CuraApplication(QtApplication): preferences.addPreference("cura/choice_on_profile_override", "always_ask") preferences.addPreference("cura/choice_on_open_project", "always_ask") preferences.addPreference("cura/use_multi_build_plate", False) - preferences.addPreference("view/settings_list_height", 600) + preferences.addPreference("view/settings_list_height", 400) preferences.addPreference("view/settings_visible", False) preferences.addPreference("cura/currency", "€") preferences.addPreference("cura/material_settings", "{}") From a43900b0adea19c85222793f68290f06d79fe814 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 7 Jan 2019 11:17:08 +0100 Subject: [PATCH 1204/1292] Fix version upgrade for XMLMaterialProfile CURA-5995 --- plugins/XmlMaterialProfile/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/XmlMaterialProfile/__init__.py b/plugins/XmlMaterialProfile/__init__.py index e8bde78424..c50df69516 100644 --- a/plugins/XmlMaterialProfile/__init__.py +++ b/plugins/XmlMaterialProfile/__init__.py @@ -16,7 +16,7 @@ def getMetaData(): "mimetype": "application/x-ultimaker-material-profile" }, "version_upgrade": { - ("materials", 1000000): ("materials", 1000004, upgrader.upgradeMaterial), + ("materials", 1000000): ("materials", 1000006, upgrader.upgradeMaterial), }, "sources": { "materials": { From d4b0c157aab37e57e3dc2b785eea72f142abaf1c Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 7 Jan 2019 13:18:28 +0100 Subject: [PATCH 1205/1292] Fix layers.shader to check feature prime_tower CURA-5932 --- plugins/SimulationView/layers.shader | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/SimulationView/layers.shader b/plugins/SimulationView/layers.shader index 30f23a3189..69c7c61ee5 100644 --- a/plugins/SimulationView/layers.shader +++ b/plugins/SimulationView/layers.shader @@ -49,12 +49,13 @@ fragment = // discard movements discard; } - // support: 4, 5, 7, 10 + // support: 4, 5, 7, 10, 11 (prime tower) if ((u_show_helpers == 0) && ( ((v_line_type >= 3.5) && (v_line_type <= 4.5)) || + ((v_line_type >= 4.5) && (v_line_type <= 5.5)) || ((v_line_type >= 6.5) && (v_line_type <= 7.5)) || ((v_line_type >= 9.5) && (v_line_type <= 10.5)) || - ((v_line_type >= 4.5) && (v_line_type <= 5.5)) + ((v_line_type >= 10.5) && (v_line_type <= 11.5)) )) { discard; } From 4dbab887925dab91001e33ff2dd9bd5a2773f46b Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 7 Jan 2019 13:56:04 +0100 Subject: [PATCH 1206/1292] Add dummy printer for loading --- plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml index d20c2247b4..fe7892840a 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml @@ -67,7 +67,7 @@ Component MonitorCarousel { id: carousel - printers: OutputDevice.printers + printers: OutputDevice.printers.concat([null]) } } From af634b82b25fdd765a134288b101588ed2fdc22c Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 8 Jan 2019 09:39:46 +0100 Subject: [PATCH 1207/1292] Chnage default font sizes and unify font weights CURA-6085 --- resources/themes/cura-light/theme.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 42ef632673..c277ee7f6c 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -6,7 +6,7 @@ "fonts": { "large": { "size": 1.35, - "weight": 40, + "weight": 50, "family": "Noto Sans" }, "large_bold": { @@ -16,7 +16,7 @@ }, "medium": { "size": 1.16, - "weight": 40, + "weight": 50, "family": "Noto Sans" }, "medium_bold": { @@ -25,24 +25,24 @@ "family": "Noto Sans" }, "default": { - "size": 0.95, - "weight": 40, + "size": 1.0, + "weight": 50, "family": "Noto Sans" }, "default_bold": { - "size": 0.95, + "size": 1.0, "weight": 63, "family": "Noto Sans" }, "default_italic": { - "size": 0.95, - "weight": 40, + "size": 1.0, + "weight": 50, "italic": true, "family": "Noto Sans" }, "small": { "size": 0.7, - "weight": 40, + "weight": 50, "family": "Noto Sans" } }, From 8e898148f619b1580a63a5b17d2728d545bfe210 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 8 Jan 2019 09:42:50 +0100 Subject: [PATCH 1208/1292] Make checkboxes and texts more aligned CURA-6085 --- plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml index 333d4dd50a..f50c3f3ac6 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml @@ -30,6 +30,7 @@ Item CheckBox { id: disableButton + anchors.verticalCenter: pluginInfo.verticalCenter checked: isEnabled visible: model.type == "plugin" width: visible ? UM.Theme.getSize("checkbox").width : 0 From 2124de3d4dcfb69c7b7a61297ba48b153021034f Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 8 Jan 2019 10:45:52 +0100 Subject: [PATCH 1209/1292] Revert "Chnage default font sizes and unify font weights" This reverts commit af634b82b25fdd765a134288b101588ed2fdc22c. CURA-6085 --- resources/themes/cura-light/theme.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index c277ee7f6c..42ef632673 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -6,7 +6,7 @@ "fonts": { "large": { "size": 1.35, - "weight": 50, + "weight": 40, "family": "Noto Sans" }, "large_bold": { @@ -16,7 +16,7 @@ }, "medium": { "size": 1.16, - "weight": 50, + "weight": 40, "family": "Noto Sans" }, "medium_bold": { @@ -25,24 +25,24 @@ "family": "Noto Sans" }, "default": { - "size": 1.0, - "weight": 50, + "size": 0.95, + "weight": 40, "family": "Noto Sans" }, "default_bold": { - "size": 1.0, + "size": 0.95, "weight": 63, "family": "Noto Sans" }, "default_italic": { - "size": 1.0, - "weight": 50, + "size": 0.95, + "weight": 40, "italic": true, "family": "Noto Sans" }, "small": { "size": 0.7, - "weight": 50, + "weight": 40, "family": "Noto Sans" } }, From 578027182e91c543c9937956e17430b37ef5800c Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 8 Jan 2019 10:49:55 +0100 Subject: [PATCH 1210/1292] Prevent setting items from overlapping with column headers --- resources/qml/Preferences/ProfilesPage.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index d9b679e344..f23a04d800 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -376,6 +376,7 @@ Item width: true ? (parent.width * 0.4) | 0 : parent.width frameVisible: true + clip: true ListView { From 4cb853cdb07d5785aeb21cacb048a7182f772218 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 8 Jan 2019 10:51:27 +0100 Subject: [PATCH 1211/1292] Fix (bigger) fonts for Chinese and Japanese CURA-6085 --- resources/themes/cura-light/theme.json | 93 ++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 42ef632673..ea1c64e2ac 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -9,6 +9,21 @@ "weight": 40, "family": "Noto Sans" }, + "large_ja_JP": { + "size": 1.35, + "weight": 50, + "family": "Noto Sans" + }, + "large_zh_CN": { + "size": 1.35, + "weight": 50, + "family": "Noto Sans" + }, + "large_zh_TW": { + "size": 1.35, + "weight": 50, + "family": "Noto Sans" + }, "large_bold": { "size": 1.35, "weight": 63, @@ -19,6 +34,21 @@ "weight": 40, "family": "Noto Sans" }, + "medium_ja_JP": { + "size": 1.16, + "weight": 50, + "family": "Noto Sans" + }, + "medium_zh_CN": { + "size": 1.16, + "weight": 50, + "family": "Noto Sans" + }, + "medium_zh_TW": { + "size": 1.16, + "weight": 50, + "family": "Noto Sans" + }, "medium_bold": { "size": 1.16, "weight": 63, @@ -29,21 +59,84 @@ "weight": 40, "family": "Noto Sans" }, + "default_ja_JP": { + "size": 1.0, + "weight": 50, + "family": "Noto Sans" + }, + "default_zh_CN": { + "size": 1.0, + "weight": 50, + "family": "Noto Sans" + }, + "default_zh_TW": { + "size": 1.0, + "weight": 50, + "family": "Noto Sans" + }, "default_bold": { "size": 0.95, "weight": 63, "family": "Noto Sans" }, + "default_bold_ja_JP": { + "size": 1.0, + "weight": 63, + "family": "Noto Sans" + }, + "default_bold_zh_CN": { + "size": 1.0, + "weight": 63, + "family": "Noto Sans" + }, + "default_bold_zh_TW": { + "size": 1.0, + "weight": 63, + "family": "Noto Sans" + }, "default_italic": { "size": 0.95, "weight": 40, "italic": true, "family": "Noto Sans" }, + "default_italic_ja_JP": { + "size": 1.0, + "weight": 50, + "italic": true, + "family": "Noto Sans" + }, + "default_italic_zh_CN": { + "size": 1.0, + "weight": 50, + "italic": true, + "family": "Noto Sans" + }, + "default_italic_zh_TW": { + "size": 1.0, + "weight": 50, + "italic": true, + "family": "Noto Sans" + }, "small": { "size": 0.7, "weight": 40, "family": "Noto Sans" + }, + "small_ja_JP": { + "size": 0.7, + "weight": 50, + "family": "Noto Sans" + }, + "small_zh_CN": { + "size": 0.7, + "weight": 50, + "family": "Noto Sans" + }, + "small_zh_TW": { + "size": 0.7, + "weight": 50, + "family": "Noto Sans" } }, From 7c7bca31c75432dca58f14c2e1db8a6672753931 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 8 Jan 2019 11:52:27 +0100 Subject: [PATCH 1212/1292] Fix renamed property connectionType --- plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py index 5f6b6b15bf..4a510903dd 100644 --- a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py +++ b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py @@ -118,7 +118,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): if key == um_network_key: if not self._discovered_devices[key].isConnected(): Logger.log("d", "Attempting to connect with [%s]" % key) - active_machine.setMetaDataEntry("connection_type", self._discovered_devices[key].getConnectionType().value) + active_machine.setMetaDataEntry("connection_type", self._discovered_devices[key].connectionType.value) self._discovered_devices[key].connect() self._discovered_devices[key].connectionStateChanged.connect(self._onDeviceConnectionStateChanged) else: From 485b471522968e1099cee3aa1e0055f01cd5dbec Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 8 Jan 2019 12:19:00 +0100 Subject: [PATCH 1213/1292] Fix some review comments --- .../NetworkedPrinterOutputDevice.py | 4 +- .../src/Cloud/CloudApiClient.py | 35 ++++++------ .../src/Cloud/CloudOutputDevice.py | 55 +++++-------------- .../src/Cloud/CloudOutputDeviceManager.py | 4 +- .../{CloudErrorObject.py => CloudError.py} | 2 +- .../src/Cloud/Translations.py | 31 +++++++++++ .../tests/Cloud/TestCloudApiClient.py | 4 +- 7 files changed, 73 insertions(+), 62 deletions(-) rename plugins/UM3NetworkPrinting/src/Cloud/Models/{CloudErrorObject.py => CloudError.py} (97%) create mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Translations.py diff --git a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py index 3dcc43dd00..4a8aa0a6b2 100644 --- a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py +++ b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py @@ -18,6 +18,7 @@ from enum import IntEnum import os # To get the username import gzip + class AuthState(IntEnum): NotAuthenticated = 1 AuthenticationRequested = 2 @@ -207,7 +208,8 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): self._last_request_time = time() if not self._manager: - return Logger.log("e", "No network manager was created to execute the PUT call with.") + Logger.log("e", "No network manager was created to execute the PUT call with.") + return body = data if isinstance(data, bytes) else data.encode() # type: bytes reply = self._manager.put(request, body) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py index 302ca86d32..8f10d02802 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py @@ -14,13 +14,17 @@ from cura.API import Account from .MeshUploader import MeshUploader from ..Models import BaseModel from .Models.CloudClusterResponse import CloudClusterResponse -from .Models.CloudErrorObject import CloudErrorObject +from .Models.CloudError import CloudError from .Models.CloudClusterStatus import CloudClusterStatus from .Models.CloudPrintJobUploadRequest import CloudPrintJobUploadRequest from .Models.CloudPrintResponse import CloudPrintResponse from .Models.CloudPrintJobResponse import CloudPrintJobResponse +## The generic type variable used to document the methods below. +CloudApiClientModel = TypeVar("Model", bound = BaseModel) + + ## The cloud API client is responsible for handling the requests and responses from the cloud. # Each method should only handle models instead of exposing Any HTTP details. class CloudApiClient: @@ -33,7 +37,7 @@ class CloudApiClient: ## Initializes a new cloud API client. # \param account: The user's account object # \param on_error: The callback to be called whenever we receive errors from the server. - def __init__(self, account: Account, on_error: Callable[[List[CloudErrorObject]], None]) -> None: + def __init__(self, account: Account, on_error: Callable[[List[CloudError]], None]) -> None: super().__init__() self._manager = QNetworkAccessManager() self._account = account @@ -115,33 +119,31 @@ class CloudApiClient: # Logger.log("i", "Received a reply %s from %s with %s", status_code, reply.url().toString(), response) return status_code, json.loads(response) except (UnicodeDecodeError, JSONDecodeError, ValueError) as err: - error = CloudErrorObject(code=type(err).__name__, title=str(err), http_code=str(status_code), - id=str(time()), http_status="500") + error = CloudError(code=type(err).__name__, title=str(err), http_code=str(status_code), + id=str(time()), http_status="500") Logger.logException("e", "Could not parse the stardust response: %s", error) return status_code, {"errors": [error.toDict()]} - ## The generic type variable used to document the methods below. - Model = TypeVar("Model", bound=BaseModel) - ## Parses the given models and calls the correct callback depending on the result. # \param response: The response from the server, after being converted to a dict. # \param on_finished: The callback in case the response is successful. # \param model_class: The type of the model to convert the response to. It may either be a single record or a list. def _parseModels(self, response: Dict[str, Any], - on_finished: Union[Callable[[Model], Any], Callable[[List[Model]], Any]], - model_class: Type[Model]) -> None: + on_finished: Union[Callable[[CloudApiClientModel], Any], + Callable[[List[CloudApiClientModel]], Any]], + model_class: Type[CloudApiClientModel]) -> None: if "data" in response: data = response["data"] if isinstance(data, list): - results = [model_class(**c) for c in data] # type: List[CloudApiClient.Model] - on_finished_list = cast(Callable[[List[CloudApiClient.Model]], Any], on_finished) + results = [model_class(**c) for c in data] # type: List[CloudApiClientModel] + on_finished_list = cast(Callable[[List[CloudApiClientModel]], Any], on_finished) on_finished_list(results) else: - result = model_class(**data) # type: CloudApiClient.Model - on_finished_item = cast(Callable[[CloudApiClient.Model], Any], on_finished) + result = model_class(**data) # type: CloudApiClientModel + on_finished_item = cast(Callable[[CloudApiClientModel], Any], on_finished) on_finished_item(result) elif "errors" in response: - self._on_error([CloudErrorObject(**error) for error in response["errors"]]) + self._on_error([CloudError(**error) for error in response["errors"]]) else: Logger.log("e", "Cannot find data or errors in the cloud response: %s", response) @@ -153,8 +155,9 @@ class CloudApiClient: # \param model: The type of the model to convert the response to. def _addCallback(self, reply: QNetworkReply, - on_finished: Union[Callable[[Model], Any], Callable[[List[Model]], Any]], - model: Type[Model], + on_finished: Union[Callable[[CloudApiClientModel], Any], + Callable[[List[CloudApiClientModel]], Any]], + model: Type[CloudApiClientModel], ) -> None: def parse() -> None: status_code, response = self._parseReply(reply) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 093aa05ea9..e866303d27 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -7,7 +7,6 @@ from typing import Dict, List, Optional, Set, cast from PyQt5.QtCore import QObject, QUrl, pyqtProperty, pyqtSignal, pyqtSlot -from UM import i18nCatalog from UM.Backend.Backend import BackendState from UM.FileHandler.FileHandler import FileHandler from UM.Logger import Logger @@ -18,7 +17,8 @@ from cura.CuraApplication import CuraApplication from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState, NetworkedPrinterOutputDevice from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from cura.PrinterOutputDevice import ConnectionType -from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputController import CloudOutputController + +from .CloudOutputController import CloudOutputController from ..MeshFormatHandler import MeshFormatHandler from ..UM3PrintJobOutputModel import UM3PrintJobOutputModel from .CloudProgressMessage import CloudProgressMessage @@ -30,37 +30,10 @@ from .Models.CloudPrintResponse import CloudPrintResponse from .Models.CloudPrintJobResponse import CloudPrintJobResponse from .Models.CloudClusterPrinterStatus import CloudClusterPrinterStatus from .Models.CloudClusterPrintJobStatus import CloudClusterPrintJobStatus +from .Translations import Translations from .Utils import findChanges, formatDateCompleted, formatTimeCompleted -## Class that contains all the translations for this module. -class T: - # The translation catalog for this device. - - _I18N_CATALOG = i18nCatalog("cura") - - PRINT_VIA_CLOUD_BUTTON = _I18N_CATALOG.i18nc("@action:button", "Print via Cloud") - PRINT_VIA_CLOUD_TOOLTIP = _I18N_CATALOG.i18nc("@properties:tooltip", "Print via Cloud") - - CONNECTED_VIA_CLOUD = _I18N_CATALOG.i18nc("@info:status", "Connected via Cloud") - BLOCKED_UPLOADING = _I18N_CATALOG.i18nc("@info:status", "Sending new jobs (temporarily) blocked, still sending " - "the previous print job.") - - COULD_NOT_EXPORT = _I18N_CATALOG.i18nc("@info:status", "Could not export print job.") - - ERROR = _I18N_CATALOG.i18nc("@info:title", "Error") - UPLOAD_ERROR = _I18N_CATALOG.i18nc("@info:text", "Could not upload the data to the printer.") - - UPLOAD_SUCCESS_TITLE = _I18N_CATALOG.i18nc("@info:title", "Data Sent") - UPLOAD_SUCCESS_TEXT = _I18N_CATALOG.i18nc("@info:status", "Print job was successfully sent to the printer.") - - JOB_COMPLETED_TITLE = _I18N_CATALOG.i18nc("@info:status", "Print finished") - JOB_COMPLETED_PRINTER = _I18N_CATALOG.i18nc("@info:status", - "Printer '{printer_name}' has finished printing '{job_name}'.") - - JOB_COMPLETED_NO_PRINTER = _I18N_CATALOG.i18nc("@info:status", "The print job '{job_name}' was finished.") - - ## The cloud output device is a network output device that works remotely but has limited functionality. # Currently it only supports viewing the printer and print job status and adding a new job to the queue. # As such, those methods have been implemented here. @@ -159,9 +132,9 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def _setInterfaceElements(self) -> None: self.setPriority(2) # make sure we end up below the local networking and above 'save to file' self.setName(self._id) - self.setShortDescription(T.PRINT_VIA_CLOUD_BUTTON) - self.setDescription(T.PRINT_VIA_CLOUD_TOOLTIP) - self.setConnectionText(T.CONNECTED_VIA_CLOUD) + self.setShortDescription(Translations.PRINT_VIA_CLOUD_BUTTON) + self.setDescription(Translations.PRINT_VIA_CLOUD_TOOLTIP) + self.setConnectionText(Translations.CONNECTED_VIA_CLOUD) ## Called when Cura requests an output device to receive a (G-code) file. def requestWrite(self, nodes: List[SceneNode], file_name: Optional[str] = None, limit_mimetypes: bool = False, @@ -169,7 +142,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # Show an error message if we're already sending a job. if self._progress.visible: - message = Message(text = T.BLOCKED_UPLOADING, title = T.ERROR, lifetime = 10) + message = Message(text = Translations.BLOCKED_UPLOADING, title = Translations.ERROR, lifetime = 10) message.show() return @@ -184,7 +157,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): mesh_format = MeshFormatHandler(file_handler, self.firmwareVersion) if not mesh_format.is_valid: Logger.log("e", "Missing file or mesh writer!") - return self._onUploadError(T.COULD_NOT_EXPORT) + return self._onUploadError(Translations.COULD_NOT_EXPORT) mesh = mesh_format.getBytes(nodes) @@ -292,9 +265,11 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): if job.state == "wait_cleanup" and job.key not in self._finished_jobs and job.owner == user_name: self._finished_jobs.add(job.key) Message( - title = T.JOB_COMPLETED_TITLE, - text = (T.JOB_COMPLETED_PRINTER.format(printer_name=job.assignedPrinter.name, job_name=job.name) - if job.assignedPrinter else T.JOB_COMPLETED_NO_PRINTER.format(job_name=job.name)), + title = Translations.JOB_COMPLETED_TITLE, + text = (Translations.JOB_COMPLETED_PRINTER.format(printer_name=job.assignedPrinter.name, + job_name=job.name) + if job.assignedPrinter else + Translations.JOB_COMPLETED_NO_PRINTER.format(job_name=job.name)), ).show() # Ensure UI gets updated @@ -330,7 +305,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def _onUploadError(self, message = None) -> None: self._progress.hide() self._uploaded_print_job = None - Message(text = message or T.UPLOAD_ERROR, title = T.ERROR, lifetime = 10).show() + Message(text = message or Translations.UPLOAD_ERROR, title = Translations.ERROR, lifetime = 10).show() self.writeError.emit() ## Shows a message when the upload has succeeded @@ -338,7 +313,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def _onPrintRequested(self, response: CloudPrintResponse) -> None: Logger.log("d", "The cluster will be printing this print job with the ID %s", response.cluster_job_id) self._progress.hide() - Message(text = T.UPLOAD_SUCCESS_TEXT, title = T.UPLOAD_SUCCESS_TITLE, lifetime = 5).show() + Message(text = Translations.UPLOAD_SUCCESS_TEXT, title = Translations.UPLOAD_SUCCESS_TITLE, lifetime = 5).show() self.writeFinished.emit() ## Gets the remote printers. diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index b1dc13e34f..72ac34ff34 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -13,7 +13,7 @@ from cura.Settings.GlobalStack import GlobalStack from .CloudApiClient import CloudApiClient from .CloudOutputDevice import CloudOutputDevice from .Models.CloudClusterResponse import CloudClusterResponse -from .Models.CloudErrorObject import CloudErrorObject +from .Models.CloudError import CloudError from .Utils import findChanges @@ -138,7 +138,7 @@ class CloudOutputDeviceManager: ## Handles an API error received from the cloud. # \param errors: The errors received - def _onApiError(self, errors: List[CloudErrorObject]) -> None: + def _onApiError(self, errors: List[CloudError]) -> None: text = ". ".join(e.title for e in errors) # TODO: translate errors message = Message( text = text, diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudErrorObject.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudError.py similarity index 97% rename from plugins/UM3NetworkPrinting/src/Cloud/Models/CloudErrorObject.py rename to plugins/UM3NetworkPrinting/src/Cloud/Models/CloudError.py index 28b4d916a1..b53361022e 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudErrorObject.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudError.py @@ -7,7 +7,7 @@ from .BaseCloudModel import BaseCloudModel ## Class representing errors generated by the cloud servers, according to the JSON-API standard. # Spec: https://api-staging.ultimaker.com/connect/v1/spec -class CloudErrorObject(BaseCloudModel): +class CloudError(BaseCloudModel): ## Creates a new error object. # \param id: Unique identifier for this particular occurrence of the problem. # \param title: A short, human-readable summary of the problem that SHOULD NOT change from occurrence to occurrence diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Translations.py b/plugins/UM3NetworkPrinting/src/Cloud/Translations.py new file mode 100644 index 0000000000..278bf91c37 --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Cloud/Translations.py @@ -0,0 +1,31 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +from UM import i18nCatalog + + +## Class that contains all the translations for this module. +class Translations: + # The translation catalog for this device. + + _I18N_CATALOG = i18nCatalog("cura") + + PRINT_VIA_CLOUD_BUTTON = _I18N_CATALOG.i18nc("@action:button", "Print via Cloud") + PRINT_VIA_CLOUD_TOOLTIP = _I18N_CATALOG.i18nc("@properties:tooltip", "Print via Cloud") + + CONNECTED_VIA_CLOUD = _I18N_CATALOG.i18nc("@info:status", "Connected via Cloud") + BLOCKED_UPLOADING = _I18N_CATALOG.i18nc("@info:status", "Sending new jobs (temporarily) blocked, still sending " + "the previous print job.") + + COULD_NOT_EXPORT = _I18N_CATALOG.i18nc("@info:status", "Could not export print job.") + + ERROR = _I18N_CATALOG.i18nc("@info:title", "Error") + UPLOAD_ERROR = _I18N_CATALOG.i18nc("@info:text", "Could not upload the data to the printer.") + + UPLOAD_SUCCESS_TITLE = _I18N_CATALOG.i18nc("@info:title", "Data Sent") + UPLOAD_SUCCESS_TEXT = _I18N_CATALOG.i18nc("@info:status", "Print job was successfully sent to the printer.") + + JOB_COMPLETED_TITLE = _I18N_CATALOG.i18nc("@info:status", "Print finished") + JOB_COMPLETED_PRINTER = _I18N_CATALOG.i18nc("@info:status", + "Printer '{printer_name}' has finished printing '{job_name}'.") + + JOB_COMPLETED_NO_PRINTER = _I18N_CATALOG.i18nc("@info:status", "The print job '{job_name}' was finished.") \ No newline at end of file diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py index 0c0c8cffdf..b57334b2da 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py @@ -12,7 +12,7 @@ from src.Cloud.Models.CloudClusterResponse import CloudClusterResponse from src.Cloud.Models.CloudClusterStatus import CloudClusterStatus from src.Cloud.Models.CloudPrintJobResponse import CloudPrintJobResponse from src.Cloud.Models.CloudPrintJobUploadRequest import CloudPrintJobUploadRequest -from src.Cloud.Models.CloudErrorObject import CloudErrorObject +from src.Cloud.Models.CloudError import CloudError from tests.Cloud.Fixtures import readFixture, parseFixture from .NetworkManagerMock import NetworkManagerMock @@ -20,7 +20,7 @@ from .NetworkManagerMock import NetworkManagerMock class TestCloudApiClient(TestCase): maxDiff = None - def _errorHandler(self, errors: List[CloudErrorObject]): + def _errorHandler(self, errors: List[CloudError]): raise Exception("Received unexpected error: {}".format(errors)) def setUp(self): From b8da720c1d528b3a7becfda00cf006543bc162c8 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 8 Jan 2019 13:10:42 +0100 Subject: [PATCH 1214/1292] Move translations in-line --- .../src/Cloud/CloudOutputDevice.py | 44 +++++++++++++------ .../src/Cloud/Translations.py | 31 ------------- 2 files changed, 31 insertions(+), 44 deletions(-) delete mode 100644 plugins/UM3NetworkPrinting/src/Cloud/Translations.py diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index e866303d27..f3c4830e24 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -7,6 +7,7 @@ from typing import Dict, List, Optional, Set, cast from PyQt5.QtCore import QObject, QUrl, pyqtProperty, pyqtSignal, pyqtSlot +from UM import i18nCatalog from UM.Backend.Backend import BackendState from UM.FileHandler.FileHandler import FileHandler from UM.Logger import Logger @@ -30,10 +31,12 @@ from .Models.CloudPrintResponse import CloudPrintResponse from .Models.CloudPrintJobResponse import CloudPrintJobResponse from .Models.CloudClusterPrinterStatus import CloudClusterPrinterStatus from .Models.CloudClusterPrintJobStatus import CloudClusterPrintJobStatus -from .Translations import Translations from .Utils import findChanges, formatDateCompleted, formatTimeCompleted +I18N_CATALOG = i18nCatalog("cura") + + ## The cloud output device is a network output device that works remotely but has limited functionality. # Currently it only supports viewing the printer and print job status and adding a new job to the queue. # As such, those methods have been implemented here. @@ -132,9 +135,9 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def _setInterfaceElements(self) -> None: self.setPriority(2) # make sure we end up below the local networking and above 'save to file' self.setName(self._id) - self.setShortDescription(Translations.PRINT_VIA_CLOUD_BUTTON) - self.setDescription(Translations.PRINT_VIA_CLOUD_TOOLTIP) - self.setConnectionText(Translations.CONNECTED_VIA_CLOUD) + self.setShortDescription(I18N_CATALOG.i18nc("@action:button", "Print via Cloud")) + self.setDescription(I18N_CATALOG.i18nc("@properties:tooltip", "Print via Cloud")) + self.setConnectionText(I18N_CATALOG.i18nc("@info:status", "Connected via Cloud")) ## Called when Cura requests an output device to receive a (G-code) file. def requestWrite(self, nodes: List[SceneNode], file_name: Optional[str] = None, limit_mimetypes: bool = False, @@ -142,7 +145,11 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # Show an error message if we're already sending a job. if self._progress.visible: - message = Message(text = Translations.BLOCKED_UPLOADING, title = Translations.ERROR, lifetime = 10) + message = Message( + text = I18N_CATALOG.i18nc("@info:status", "Sending new jobs (temporarily) blocked, still sending the previous print job."), + title = I18N_CATALOG.i18nc("@info:title", "Cloud error"), + lifetime = 10 + ) message.show() return @@ -157,7 +164,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): mesh_format = MeshFormatHandler(file_handler, self.firmwareVersion) if not mesh_format.is_valid: Logger.log("e", "Missing file or mesh writer!") - return self._onUploadError(Translations.COULD_NOT_EXPORT) + return self._onUploadError(I18N_CATALOG.i18nc("@info:status", "Could not export print job.")) mesh = mesh_format.getBytes(nodes) @@ -265,11 +272,14 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): if job.state == "wait_cleanup" and job.key not in self._finished_jobs and job.owner == user_name: self._finished_jobs.add(job.key) Message( - title = Translations.JOB_COMPLETED_TITLE, - text = (Translations.JOB_COMPLETED_PRINTER.format(printer_name=job.assignedPrinter.name, - job_name=job.name) - if job.assignedPrinter else - Translations.JOB_COMPLETED_NO_PRINTER.format(job_name=job.name)), + title = I18N_CATALOG.i18nc("@info:status", "Print finished"), + text = (I18N_CATALOG.i18nc("@info:status", "Printer '{printer_name}' has finished printing '{job_name}'.").format( + printer_name = job.assignedPrinter.name, + job_name = job.name + ) if job.assignedPrinter else + I18N_CATALOG.i18nc("@info:status", "The print job '{job_name}' was finished.").format( + job_name = job.name + )), ).show() # Ensure UI gets updated @@ -305,7 +315,11 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def _onUploadError(self, message = None) -> None: self._progress.hide() self._uploaded_print_job = None - Message(text = message or Translations.UPLOAD_ERROR, title = Translations.ERROR, lifetime = 10).show() + Message( + text = message or I18N_CATALOG.i18nc("@info:text", "Could not upload the data to the printer."), + title = I18N_CATALOG.i18nc("@info:title", "Cloud error"), + lifetime = 10 + ).show() self.writeError.emit() ## Shows a message when the upload has succeeded @@ -313,7 +327,11 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def _onPrintRequested(self, response: CloudPrintResponse) -> None: Logger.log("d", "The cluster will be printing this print job with the ID %s", response.cluster_job_id) self._progress.hide() - Message(text = Translations.UPLOAD_SUCCESS_TEXT, title = Translations.UPLOAD_SUCCESS_TITLE, lifetime = 5).show() + Message( + text = I18N_CATALOG.i18nc("@info:status", "Print job was successfully sent to the printer."), + title = I18N_CATALOG.i18nc("@info:title", "Data Sent"), + lifetime = 5 + ).show() self.writeFinished.emit() ## Gets the remote printers. diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Translations.py b/plugins/UM3NetworkPrinting/src/Cloud/Translations.py deleted file mode 100644 index 278bf91c37..0000000000 --- a/plugins/UM3NetworkPrinting/src/Cloud/Translations.py +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (c) 2018 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. -from UM import i18nCatalog - - -## Class that contains all the translations for this module. -class Translations: - # The translation catalog for this device. - - _I18N_CATALOG = i18nCatalog("cura") - - PRINT_VIA_CLOUD_BUTTON = _I18N_CATALOG.i18nc("@action:button", "Print via Cloud") - PRINT_VIA_CLOUD_TOOLTIP = _I18N_CATALOG.i18nc("@properties:tooltip", "Print via Cloud") - - CONNECTED_VIA_CLOUD = _I18N_CATALOG.i18nc("@info:status", "Connected via Cloud") - BLOCKED_UPLOADING = _I18N_CATALOG.i18nc("@info:status", "Sending new jobs (temporarily) blocked, still sending " - "the previous print job.") - - COULD_NOT_EXPORT = _I18N_CATALOG.i18nc("@info:status", "Could not export print job.") - - ERROR = _I18N_CATALOG.i18nc("@info:title", "Error") - UPLOAD_ERROR = _I18N_CATALOG.i18nc("@info:text", "Could not upload the data to the printer.") - - UPLOAD_SUCCESS_TITLE = _I18N_CATALOG.i18nc("@info:title", "Data Sent") - UPLOAD_SUCCESS_TEXT = _I18N_CATALOG.i18nc("@info:status", "Print job was successfully sent to the printer.") - - JOB_COMPLETED_TITLE = _I18N_CATALOG.i18nc("@info:status", "Print finished") - JOB_COMPLETED_PRINTER = _I18N_CATALOG.i18nc("@info:status", - "Printer '{printer_name}' has finished printing '{job_name}'.") - - JOB_COMPLETED_NO_PRINTER = _I18N_CATALOG.i18nc("@info:status", "The print job '{job_name}' was finished.") \ No newline at end of file From 53cb2ce1891066c0437effb7a961a1c982f320f2 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 8 Jan 2019 13:29:45 +0100 Subject: [PATCH 1215/1292] Add comments for http status >=300 check CURA-6005 --- plugins/CuraDrive/src/DriveApiService.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/CuraDrive/src/DriveApiService.py b/plugins/CuraDrive/src/DriveApiService.py index 23e70a978c..7c1f8faa83 100644 --- a/plugins/CuraDrive/src/DriveApiService.py +++ b/plugins/CuraDrive/src/DriveApiService.py @@ -45,6 +45,8 @@ class DriveApiService: "Authorization": "Bearer {}".format(access_token) }) + # HTTP status 300s mean redirection. 400s and 500s are errors. + # Technically 300s are not errors, but the use case here relies on "requests" to handle redirects automatically. if backup_list_request.status_code >= 300: Logger.log("w", "Could not get backups list from remote: %s", backup_list_request.text) Message(catalog.i18nc("@info:backup_status", "There was an error listing your backups."), title = catalog.i18nc("@info:title", "Backup")).show() From a8fe5ced89c92bc7a8362fe280b0c1b5e62cc14e Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 8 Jan 2019 13:33:46 +0100 Subject: [PATCH 1216/1292] Remove unused import CURA-6005 --- plugins/CuraDrive/src/Settings.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/CuraDrive/src/Settings.py b/plugins/CuraDrive/src/Settings.py index c5383555b2..abe64e0acd 100644 --- a/plugins/CuraDrive/src/Settings.py +++ b/plugins/CuraDrive/src/Settings.py @@ -1,8 +1,6 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from UM import i18nCatalog - from cura import UltimakerCloudAuthentication @@ -12,4 +10,4 @@ class Settings: DRIVE_API_URL = "{}/cura-drive/v{}".format(UltimakerCloudAuthentication.CuraCloudAPIRoot, str(DRIVE_API_VERSION)) AUTO_BACKUP_ENABLED_PREFERENCE_KEY = "cura_drive/auto_backup_enabled" - AUTO_BACKUP_LAST_DATE_PREFERENCE_KEY = "cura_drive/auto_backup_date" \ No newline at end of file + AUTO_BACKUP_LAST_DATE_PREFERENCE_KEY = "cura_drive/auto_backup_date" From e81742d296eab1d9d7ba81d3b9ea2ac5ce897445 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 8 Jan 2019 14:27:54 +0100 Subject: [PATCH 1217/1292] Add skeleton loading to printer cards Contributes to CL-1157 --- .../qml/MonitorBuildplateConfiguration.qml | 17 ++- .../resources/qml/MonitorCarousel.qml | 1 + .../qml/MonitorConfigOverrideDialog.qml | 2 +- .../qml/MonitorExtruderConfiguration.qml | 62 +++++--- .../resources/qml/MonitorIconExtruder.qml | 1 + .../resources/qml/MonitorPrintJobPreview.qml | 23 +-- .../qml/MonitorPrintJobProgressBar.qml | 8 +- .../resources/qml/MonitorPrinterCard.qml | 143 +++++++++++++----- .../qml/MonitorPrinterConfiguration.qml | 12 +- .../resources/qml/MonitorPrinterPill.qml | 7 +- 10 files changed, 192 insertions(+), 84 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml index 44bd47f904..192a5a7f76 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml @@ -18,7 +18,7 @@ import UM 1.3 as UM Item { // The buildplate name - property alias buildplate: buildplateLabel.text + property var buildplate: null // Height is one 18px label/icon height: 18 * screenScaleFactor // TODO: Theme! @@ -34,7 +34,16 @@ Item Item { height: parent.height - width: 32 * screenScaleFactor // TODO: Theme! (Should be same as extruder icon width) + width: 32 * screenScaleFactor // Ensure the icon is centered under the extruder icon (same width) + + Rectangle + { + anchors.centerIn: parent + height: parent.height + width: height + color: buildplateIcon.visible > 0 ? "transparent" : "#eeeeee" // TODO: Theme! + radius: Math.floor(height / 2) + } UM.RecolorImage { @@ -44,6 +53,7 @@ Item height: parent.height source: "../svg/icons/buildplate.svg" width: height + visible: buildplate } } @@ -53,7 +63,8 @@ Item color: "#191919" // TODO: Theme! elide: Text.ElideRight font: UM.Theme.getFont("default") // 12pt, regular - text: "" + text: buildplate ? buildplate : "" + visible: text !== "" // FIXED-LINE-HEIGHT: height: 18 * screenScaleFactor // TODO: Theme! diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml index 7c0d9b95b6..de24ee5a8c 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml @@ -230,6 +230,7 @@ Item topMargin: 36 * screenScaleFactor // TODO: Theme! } spacing: 8 * screenScaleFactor // TODO: Theme! + visible: printers.length > 1 Repeater { model: printers diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml index 6a32310dd5..1718994d83 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml @@ -54,7 +54,7 @@ UM.Dialog wrapMode: Text.WordWrap text: { - if (!printer.activePrintJob) + if (!printer || !printer.activePrintJob) { return "" } diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorExtruderConfiguration.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorExtruderConfiguration.qml index 1e53191d8c..17c0fa8651 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorExtruderConfiguration.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorExtruderConfiguration.qml @@ -39,38 +39,62 @@ Item color: "#eeeeee" // TODO: Theme! position: 0 } - Label + + Rectangle { - id: materialLabel + id: materialLabelWrapper anchors { left: extruderIcon.right leftMargin: 12 * screenScaleFactor // TODO: Theme! } - color: "#191919" // TODO: Theme! - elide: Text.ElideRight - font: UM.Theme.getFont("default") // 12pt, regular - text: "" - - // FIXED-LINE-HEIGHT: + color: materialLabel.visible > 0 ? "transparent" : "#eeeeee" // TODO: Theme! height: 18 * screenScaleFactor // TODO: Theme! - verticalAlignment: Text.AlignVCenter + width: Math.max(materialLabel.contentWidth, 60 * screenScaleFactor) // TODO: Theme! + radius: 2 * screenScaleFactor // TODO: Theme! + + Label + { + id: materialLabel + + color: "#191919" // TODO: Theme! + elide: Text.ElideRight + font: UM.Theme.getFont("default") // 12pt, regular + text: "" + visible: text !== "" + + // FIXED-LINE-HEIGHT: + height: parent.height + verticalAlignment: Text.AlignVCenter + } } - Label + + Rectangle { - id: printCoreLabel + id: printCoreLabelWrapper anchors { - left: materialLabel.left + left: materialLabelWrapper.left bottom: parent.bottom } - color: "#191919" // TODO: Theme! - elide: Text.ElideRight - font: UM.Theme.getFont("default_bold") // 12pt, bold - text: "" - - // FIXED-LINE-HEIGHT: + color: printCoreLabel.visible > 0 ? "transparent" : "#eeeeee" // TODO: Theme! height: 18 * screenScaleFactor // TODO: Theme! - verticalAlignment: Text.AlignVCenter + width: Math.max(printCoreLabel.contentWidth, 36 * screenScaleFactor) // TODO: Theme! + radius: 2 * screenScaleFactor // TODO: Theme! + + Label + { + id: printCoreLabel + + color: "#191919" // TODO: Theme! + elide: Text.ElideRight + font: UM.Theme.getFont("default_bold") // 12pt, bold + text: "" + visible: text !== "" + + // FIXED-LINE-HEIGHT: + height: parent.height + verticalAlignment: Text.AlignVCenter + } } } \ No newline at end of file diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorIconExtruder.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorIconExtruder.qml index 971c6b2251..93dbebc8c6 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorIconExtruder.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorIconExtruder.qml @@ -56,5 +56,6 @@ Item x: Math.round(size * 0.25) * screenScaleFactor y: Math.round(size * 0.15625) * screenScaleFactor // TODO: Once 'size' is themed, screenScaleFactor won't be needed + visible: position >= 0 } } \ No newline at end of file diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml index 2f17db0c65..d0bad63258 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml @@ -16,23 +16,28 @@ Item width: size height: size - // Actual content - Image + Rectangle { - id: previewImage anchors.fill: parent - opacity: + color: printJob ? "transparent" : "#eeeeee" // TODO: Theme! + radius: 8 // TODO: Theme! + Image { - if (printJob && (printJob.state == "error" || printJob.configurationChanges.length > 0 || !printJob.isActive)) + id: previewImage + anchors.fill: parent + opacity: { - return 0.5 + if (printJob && (printJob.state == "error" || printJob.configurationChanges.length > 0 || !printJob.isActive)) + { + return 0.5 + } + return 1.0 } - return 1.0 + source: printJob ? printJob.previewImageUrl : "" } - source: printJob ? printJob.previewImageUrl : "" - visible: printJob } + UM.RecolorImage { id: ultiBotImage diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml index cfb7aba84d..d5d4705a36 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml @@ -34,16 +34,16 @@ Item { background: Rectangle { - color: printJob && printJob.isActive ? "#e4e4f2" : "#f3f3f9" // TODO: Theme! + color: "#f5f5f5" // TODO: Theme! implicitHeight: visible ? 8 * screenScaleFactor : 0 // TODO: Theme! implicitWidth: 180 * screenScaleFactor // TODO: Theme! - radius: 4 * screenScaleFactor // TODO: Theme! + radius: 2 * screenScaleFactor // TODO: Theme! } progress: Rectangle { id: progressItem; - color: printJob && printJob.isActive ? "#0a0850" : "#9392b2" // TODO: Theme! - radius: 4 * screenScaleFactor // TODO: Theme! + color: printJob && printJob.isActive ? "#3282ff" : "#CCCCCC" // TODO: Theme! + radius: 2 * screenScaleFactor // TODO: Theme! } } } diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml index b8c4353811..facfaaaaaf 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml @@ -33,16 +33,24 @@ Item width: 834 * screenScaleFactor // TODO: Theme! height: childrenRect.height - // Printer portion Rectangle { - id: printerInfo + id: background + anchors.fill: parent + color: "#FFFFFF" // TODO: Theme! border { color: "#CCCCCC" // TODO: Theme! width: borderSize // TODO: Remove once themed } - color: "white" // TODO: Theme! + radius: 2 * screenScaleFactor // TODO: Theme! + } + + // Printer portion + Item + { + id: printerInfo + width: parent.width height: 144 * screenScaleFactor // TODO: Theme! @@ -56,15 +64,22 @@ Item } spacing: 18 * screenScaleFactor // TODO: Theme! - Image + Rectangle { id: printerImage width: 108 * screenScaleFactor // TODO: Theme! height: 108 * screenScaleFactor // TODO: Theme! - fillMode: Image.PreserveAspectFit - source: "../png/" + printer.type + ".png" - mipmap: true + color: printer ? "transparent" : "#eeeeee" // TODO: Theme! + radius: 8 // TODO: Theme! + Image + { + anchors.fill: parent + fillMode: Image.PreserveAspectFit + source: printer ? "../png/" + printer.type + ".png" : "" + mipmap: true + } } + Item { @@ -75,20 +90,38 @@ Item width: 180 * screenScaleFactor // TODO: Theme! height: printerNameLabel.height + printerFamilyPill.height + 6 * screenScaleFactor // TODO: Theme! - Label + Rectangle { id: printerNameLabel - text: printer && printer.name ? printer.name : "" - color: "#414054" // TODO: Theme! - elide: Text.ElideRight - font: UM.Theme.getFont("large_bold") // 16pt, bold - width: parent.width - - // FIXED-LINE-HEIGHT: + // color: "#414054" // TODO: Theme! + color: printer ? "transparent" : "#eeeeee" // TODO: Theme! height: 18 * screenScaleFactor // TODO: Theme! - verticalAlignment: Text.AlignVCenter + width: parent.width + radius: 2 * screenScaleFactor // TODO: Theme! + + Label + { + text: printer && printer.name ? printer.name : "" + color: "#414054" // TODO: Theme! + elide: Text.ElideRight + font: UM.Theme.getFont("large") // 16pt, bold + width: parent.width + visible: printer + + // FIXED-LINE-HEIGHT: + height: parent.height + verticalAlignment: Text.AlignVCenter + } } + Rectangle + { + color: "#eeeeee" // TODO: Theme! + height: 18 * screenScaleFactor // TODO: Theme! + radius: 2 * screenScaleFactor // TODO: Theme! + visible: !printer + width: 48 * screenScaleFactor // TODO: Theme! + } MonitorPrinterPill { id: printerFamilyPill @@ -98,7 +131,7 @@ Item topMargin: 6 * screenScaleFactor // TODO: Theme! left: printerNameLabel.left } - text: printer.type + text: printer ? printer.type : "" } } @@ -106,16 +139,30 @@ Item { id: printerConfiguration anchors.verticalCenter: parent.verticalCenter - buildplate: "Glass" + buildplate: printer ? "Glass" : null // 'Glass' as a default configurations: - [ - base.printer.printerConfiguration.extruderConfigurations[0], - base.printer.printerConfiguration.extruderConfigurations[1] - ] - height: 72 * screenScaleFactor // TODO: Theme! + { + var configs = [] + if (printer) + { + configs.push(printer.printerConfiguration.extruderConfigurations[0]) + configs.push(printer.printerConfiguration.extruderConfigurations[1]) + } + else + { + configs.push(null, null) + } + return configs + } + height: 72 * screenScaleFactor // TODO: Theme!te theRect's x property } + + // TODO: Make this work. + PropertyAnimation { target: printerConfiguration; property: "visible"; to: 0; loops: Animation.Infinite; duration: 500 } } + + PrintJobContextMenu { id: contextButton @@ -126,10 +173,11 @@ Item top: parent.top topMargin: 12 * screenScaleFactor // TODO: Theme! } - printJob: printer.activePrintJob + printJob: printer ? printer.activePrintJob : null width: 36 * screenScaleFactor // TODO: Theme! height: 36 * screenScaleFactor // TODO: Theme! enabled: base.enabled + visible: printer } CameraButton { @@ -143,10 +191,24 @@ Item } iconSource: "../svg/icons/camera.svg" enabled: base.enabled + visible: printer } } + // Divider + Rectangle + { + anchors + { + top: printJobInfo.top + left: printJobInfo.left + right: printJobInfo.right + } + height: borderSize // Remove once themed + color: background.border.color + } + // Print job portion Rectangle { @@ -158,10 +220,10 @@ Item } border { - color: printer.activePrintJob && printer.activePrintJob.configurationChanges.length > 0 ? "#f5a623" : "#CCCCCC" // TODO: Theme! + color: printer && printer.activePrintJob && printer.activePrintJob.configurationChanges.length > 0 ? "#f5a623" : "transparent" // TODO: Theme! width: borderSize // TODO: Remove once themed } - color: "white" // TODO: Theme! + color: "transparent" // TODO: Theme! height: 84 * screenScaleFactor + borderSize // TODO: Remove once themed width: parent.width @@ -184,9 +246,12 @@ Item { verticalCenter: parent.verticalCenter } - color: "#414054" // TODO: Theme! + color: printer ? "#414054" : "#aaaaaa" // TODO: Theme! font: UM.Theme.getFont("large_bold") // 16pt, bold text: { + if (!printer) { + return catalog.i18nc("@label:status", "Loading...") + } if (printer && printer.state == "disabled") { return catalog.i18nc("@label:status", "Unavailable") @@ -215,10 +280,10 @@ Item MonitorPrintJobPreview { anchors.centerIn: parent - printJob: base.printer.activePrintJob + printJob: printer ? printer.activePrintJob : null size: parent.height } - visible: printer.activePrintJob + visible: printer && printer.activePrintJob && !printerStatus.visible } Item @@ -229,15 +294,15 @@ Item } width: 180 * screenScaleFactor // TODO: Theme! height: printerNameLabel.height + printerFamilyPill.height + 6 * screenScaleFactor // TODO: Theme! - visible: printer.activePrintJob + visible: printer && printer.activePrintJob && !printerStatus.visible Label { id: printerJobNameLabel - color: printer.activePrintJob && printer.activePrintJob.isActive ? "#414054" : "#babac1" // TODO: Theme! + color: printer && printer.activePrintJob && printer.activePrintJob.isActive ? "#414054" : "#babac1" // TODO: Theme! elide: Text.ElideRight - font: UM.Theme.getFont("large_bold") // 16pt, bold - text: base.printer.activePrintJob ? base.printer.activePrintJob.name : "Untitled" // TODO: I18N + font: UM.Theme.getFont("large") // 16pt, bold + text: printer && printer.activePrintJob ? printer.activePrintJob.name : "Untitled" // TODO: I18N width: parent.width // FIXED-LINE-HEIGHT: @@ -254,10 +319,10 @@ Item topMargin: 6 * screenScaleFactor // TODO: Theme! left: printerJobNameLabel.left } - color: printer.activePrintJob && printer.activePrintJob.isActive ? "#53657d" : "#babac1" // TODO: Theme! + color: printer && printer.activePrintJob && printer.activePrintJob.isActive ? "#53657d" : "#babac1" // TODO: Theme! elide: Text.ElideRight font: UM.Theme.getFont("default") // 12pt, regular - text: printer.activePrintJob ? printer.activePrintJob.owner : "Anonymous" // TODO: I18N + text: printer && printer.activePrintJob ? printer.activePrintJob.owner : "Anonymous" // TODO: I18N width: parent.width // FIXED-LINE-HEIGHT: @@ -272,8 +337,8 @@ Item { verticalCenter: parent.verticalCenter } - printJob: printer.activePrintJob - visible: printer.activePrintJob && printer.activePrintJob.configurationChanges.length === 0 + printJob: printer && printer.activePrintJob + visible: printer && printer.activePrintJob && printer.activePrintJob.configurationChanges.length === 0 && !printerStatus.visible } Label @@ -284,7 +349,7 @@ Item } font: UM.Theme.getFont("default") text: "Requires configuration changes" - visible: printer.activePrintJob && printer.activePrintJob.configurationChanges.length > 0 + visible: printer && printer.activePrintJob && printer.activePrintJob.configurationChanges.length > 0 && !printerStatus.visible // FIXED-LINE-HEIGHT: height: 18 * screenScaleFactor // TODO: Theme! @@ -326,7 +391,7 @@ Item } implicitHeight: 32 * screenScaleFactor // TODO: Theme! implicitWidth: 96 * screenScaleFactor // TODO: Theme! - visible: printer.activePrintJob && printer.activePrintJob.configurationChanges.length > 0 + visible: printer && printer.activePrintJob && printer.activePrintJob.configurationChanges.length > 0 && !printerStatus.visible onClicked: base.enabled ? overrideConfirmationDialog.open() : {} } } diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterConfiguration.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterConfiguration.qml index 6aa11528de..78af227408 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterConfiguration.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterConfiguration.qml @@ -19,7 +19,7 @@ Item property alias buildplate: buildplateConfig.buildplate // Array of extracted extruder configurations - property var configurations: null + property var configurations: [null,null] // Default size, but should be stretched to fill parent height: 72 * parent.height @@ -37,10 +37,10 @@ Item MonitorExtruderConfiguration { - color: modelData.activeMaterial ? modelData.activeMaterial.color : "#eeeeee" // TODO: Theme! - material: modelData.activeMaterial ? modelData.activeMaterial.name : "" - position: modelData.position - printCore: modelData.hotendID + color: modelData && modelData.activeMaterial ? modelData.activeMaterial.color : "#eeeeee" // TODO: Theme! + material: modelData && modelData.activeMaterial ? modelData.activeMaterial.name : "" + position: modelData && modelData.position ? modelData.position : -1 // Use negative one to create empty extruder number + printCore: modelData ? modelData.hotendID : "" // Keep things responsive! width: Math.floor((base.width - (configurations.length - 1) * extruderConfigurationRow.spacing) / configurations.length) @@ -53,6 +53,6 @@ Item { id: buildplateConfig anchors.bottom: parent.bottom - buildplate: "Glass" // 'Glass' as a default + buildplate: null } } \ No newline at end of file diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterPill.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterPill.qml index 80a089cc2a..2408089e1e 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterPill.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterPill.qml @@ -27,12 +27,12 @@ Item } implicitHeight: 18 * screenScaleFactor // TODO: Theme! - implicitWidth: printerNameLabel.contentWidth + 12 // TODO: Theme! + implicitWidth: Math.max(printerNameLabel.contentWidth + 12 * screenScaleFactor, 36 * screenScaleFactor) // TODO: Theme! Rectangle { id: background anchors.fill: parent - color: "#e4e4f2" // TODO: Theme! + color: printerNameLabel.visible ? "#e4e4f2" : "#eeeeee"// TODO: Theme! radius: 2 * screenScaleFactor // TODO: Theme! } @@ -41,6 +41,7 @@ Item anchors.centerIn: parent color: "#535369" // TODO: Theme! text: tagText - font.pointSize: 10 + font.pointSize: 10 // TODO: Theme! + visible: text !== "" } } \ No newline at end of file From 8f37b65ffecbb3d54ae4232d2439cf56ed8937f8 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 8 Jan 2019 15:15:21 +0100 Subject: [PATCH 1218/1292] Add skeleton loading to print job queue Contributes to CL-1157 --- .../resources/qml/ExpandableCard.qml | 11 ++- .../resources/qml/MonitorPrintJobCard.qml | 76 ++++++++++++++----- .../resources/qml/MonitorQueue.qml | 3 +- 3 files changed, 64 insertions(+), 26 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml b/plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml index f86135ae62..d4c123652d 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml @@ -15,6 +15,7 @@ Item id: base property bool expanded: false + property bool enabled: true property var borderWidth: 1 property color borderColor: "#CCCCCC" property color headerBackgroundColor: "white" @@ -34,7 +35,7 @@ Item color: borderColor width: borderWidth } - color: headerMouseArea.containsMouse ? headerHoverColor : headerBackgroundColor + color: base.enabled && headerMouseArea.containsMouse ? headerHoverColor : headerBackgroundColor height: childrenRect.height width: parent.width Behavior on color @@ -50,8 +51,12 @@ Item { id: headerMouseArea anchors.fill: header - onClicked: base.expanded = !base.expanded - hoverEnabled: true + onClicked: + { + if (!base.enabled) return + base.expanded = !base.expanded + } + hoverEnabled: base.enabled } Rectangle diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml index f431ef1c52..f2b9c3cff7 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml @@ -26,6 +26,7 @@ Item ExpandableCard { + enabled: printJob != null borderColor: printJob.configurationChanges.length !== 0 ? "#f5a623" : "#CCCCCC" // TODO: Theme! headerItem: Row { @@ -41,32 +42,56 @@ Item anchors.verticalCenter: parent.verticalCenter } - Label + Item { - text: printJob && printJob.name ? printJob.name : "" - color: "#374355" - elide: Text.ElideRight - font: UM.Theme.getFont("medium") // 14pt, regular anchors.verticalCenter: parent.verticalCenter - width: 216 * screenScaleFactor // TODO: Theme! (Should match column size) - - // FIXED-LINE-HEIGHT: height: 18 * screenScaleFactor // TODO: Theme! - verticalAlignment: Text.AlignVCenter + width: 216 * screenScaleFactor // TODO: Theme! (Should match column size) + Rectangle + { + color: "#eeeeee" + width: Math.round(parent.width / 2) + height: parent.height + visible: !printJob + } + Label + { + text: printJob && printJob.name ? printJob.name : "" + color: "#374355" + elide: Text.ElideRight + font: UM.Theme.getFont("medium") // 14pt, regular + visible: printJob + + // FIXED-LINE-HEIGHT: + height: parent.height + verticalAlignment: Text.AlignVCenter + } } - - Label - { - text: printJob ? OutputDevice.formatDuration(printJob.timeTotal) : "" - color: "#374355" - elide: Text.ElideRight - font: UM.Theme.getFont("medium") // 14pt, regular - anchors.verticalCenter: parent.verticalCenter - width: 216 * screenScaleFactor // TODO: Theme! (Should match column size) - // FIXED-LINE-HEIGHT: + Item + { + anchors.verticalCenter: parent.verticalCenter height: 18 * screenScaleFactor // TODO: Theme! - verticalAlignment: Text.AlignVCenter + width: 216 * screenScaleFactor // TODO: Theme! (Should match column size) + Rectangle + { + color: "#eeeeee" + width: Math.round(parent.width / 3) + height: parent.height + visible: !printJob + } + Label + { + text: printJob ? OutputDevice.formatDuration(printJob.timeTotal) : "" + color: "#374355" + elide: Text.ElideRight + font: UM.Theme.getFont("medium") // 14pt, regular + visible: printJob + + // FIXED-LINE-HEIGHT: + height: 18 * screenScaleFactor // TODO: Theme! + verticalAlignment: Text.AlignVCenter + } } Item @@ -75,6 +100,14 @@ Item height: 18 * screenScaleFactor // TODO: This should be childrenRect.height but QML throws warnings width: childrenRect.width + Rectangle + { + color: "#eeeeee" + width: 72 * screenScaleFactor // TODO: Theme! + height: parent.height + visible: !printJob + } + Label { id: printerAssignmentLabel @@ -100,7 +133,7 @@ Item width: 120 * screenScaleFactor // TODO: Theme! // FIXED-LINE-HEIGHT: - height: 18 * screenScaleFactor // TODO: Theme! + height: parent.height verticalAlignment: Text.AlignVCenter } @@ -115,6 +148,7 @@ Item } height: childrenRect.height spacing: 6 // TODO: Theme! + visible: printJob Repeater { diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml index f2a0e785b8..2fa524c4be 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml @@ -144,7 +144,6 @@ Item topMargin: 12 * screenScaleFactor // TODO: Theme! } style: UM.Theme.styles.scrollview - visible: OutputDevice.receivedPrintJobs width: parent.width ListView @@ -160,7 +159,7 @@ Item } printJob: modelData } - model: OutputDevice.queuedPrintJobs + model: OutputDevice.receivedPrintJobs ? OutputDevice.queuedPrintJobs.concat([null,null]) : [null,null] spacing: 6 // TODO: Theme! } } From 97e17d9fb88873737bb5aacd69be1ea07c863490 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 8 Jan 2019 15:17:42 +0100 Subject: [PATCH 1219/1292] Remove debug behavior Contributes to CL-1157 --- plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml | 2 +- plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml index 2fa524c4be..124b268300 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml @@ -159,7 +159,7 @@ Item } printJob: modelData } - model: OutputDevice.receivedPrintJobs ? OutputDevice.queuedPrintJobs.concat([null,null]) : [null,null] + model: OutputDevice.receivedPrintJobs ? OutputDevice.queuedPrintJobs : [null,null] spacing: 6 // TODO: Theme! } } diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml index fe7892840a..8723e6f46e 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml @@ -67,7 +67,7 @@ Component MonitorCarousel { id: carousel - printers: OutputDevice.printers.concat([null]) + printers: OutputDevice.receivedPrintJobs ? OutputDevice.printers : [null] } } From aee4034e3e5d01f43ba34324efb38dc676a6c7c9 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 8 Jan 2019 15:49:34 +0100 Subject: [PATCH 1220/1292] No caching preferences CURA-6005 --- plugins/CuraDrive/src/DrivePluginExtension.py | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/plugins/CuraDrive/src/DrivePluginExtension.py b/plugins/CuraDrive/src/DrivePluginExtension.py index fdf7fc1609..1f66706ce6 100644 --- a/plugins/CuraDrive/src/DrivePluginExtension.py +++ b/plugins/CuraDrive/src/DrivePluginExtension.py @@ -18,6 +18,7 @@ from .DriveApiService import DriveApiService from UM.i18n import i18nCatalog catalog = i18nCatalog("cura") + # The DivePluginExtension provides functionality to backup and restore your Cura configuration to Ultimaker's cloud. class DrivePluginExtension(QObject, Extension): @@ -32,7 +33,7 @@ class DrivePluginExtension(QObject, Extension): # Signal emitted when preferences changed (like auto-backup). preferencesChanged = pyqtSignal() - + DATE_FORMAT = "%d/%m/%Y %H:%M:%S" def __init__(self) -> None: @@ -46,7 +47,7 @@ class DrivePluginExtension(QObject, Extension): self._is_creating_backup = False # Initialize services. - self._preferences = CuraApplication.getInstance().getPreferences() + preferences = CuraApplication.getInstance().getPreferences() self._drive_api_service = DriveApiService() # Attach signals. @@ -55,10 +56,10 @@ class DrivePluginExtension(QObject, Extension): self._drive_api_service.creatingStateChanged.connect(self._onCreatingStateChanged) # Register preferences. - self._preferences.addPreference(Settings.AUTO_BACKUP_ENABLED_PREFERENCE_KEY, False) - self._preferences.addPreference(Settings.AUTO_BACKUP_LAST_DATE_PREFERENCE_KEY, datetime.now() - .strftime(self.DATE_FORMAT)) - + preferences.addPreference(Settings.AUTO_BACKUP_ENABLED_PREFERENCE_KEY, False) + preferences.addPreference(Settings.AUTO_BACKUP_LAST_DATE_PREFERENCE_KEY, + datetime.now().strftime(self.DATE_FORMAT)) + # Register the menu item self.addMenuItem(catalog.i18nc("@item:inmenu", "Manage backups"), self.showDriveWindow) @@ -74,9 +75,10 @@ class DrivePluginExtension(QObject, Extension): self._drive_window.show() def _autoBackup(self) -> None: - if self._preferences.getValue(Settings.AUTO_BACKUP_ENABLED_PREFERENCE_KEY) and self._isLastBackupTooLongAgo(): + preferences = CuraApplication.getInstance().getPreferences() + if preferences.getValue(Settings.AUTO_BACKUP_ENABLED_PREFERENCE_KEY) and self._isLastBackupTooLongAgo(): self.createBackup() - + def _isLastBackupTooLongAgo(self) -> bool: current_date = datetime.now() last_backup_date = self._getLastBackupDate() @@ -84,12 +86,14 @@ class DrivePluginExtension(QObject, Extension): return date_diff.days > 1 def _getLastBackupDate(self) -> "datetime": - last_backup_date = self._preferences.getValue(Settings.AUTO_BACKUP_LAST_DATE_PREFERENCE_KEY) + preferences = CuraApplication.getInstance().getPreferences() + last_backup_date = preferences.getValue(Settings.AUTO_BACKUP_LAST_DATE_PREFERENCE_KEY) return datetime.strptime(last_backup_date, self.DATE_FORMAT) def _storeBackupDate(self) -> None: backup_date = datetime.now().strftime(self.DATE_FORMAT) - self._preferences.setValue(Settings.AUTO_BACKUP_LAST_DATE_PREFERENCE_KEY, backup_date) + preferences = CuraApplication.getInstance().getPreferences() + preferences.setValue(Settings.AUTO_BACKUP_LAST_DATE_PREFERENCE_KEY, backup_date) def _onLoginStateChanged(self, logged_in: bool = False) -> None: if logged_in: @@ -114,11 +118,13 @@ class DrivePluginExtension(QObject, Extension): @pyqtSlot(bool, name = "toggleAutoBackup") def toggleAutoBackup(self, enabled: bool) -> None: - self._preferences.setValue(Settings.AUTO_BACKUP_ENABLED_PREFERENCE_KEY, enabled) + preferences = CuraApplication.getInstance().getPreferences() + preferences.setValue(Settings.AUTO_BACKUP_ENABLED_PREFERENCE_KEY, enabled) @pyqtProperty(bool, notify = preferencesChanged) def autoBackupEnabled(self) -> bool: - return bool(self._preferences.getValue(Settings.AUTO_BACKUP_ENABLED_PREFERENCE_KEY)) + preferences = CuraApplication.getInstance().getPreferences() + return bool(preferences.getValue(Settings.AUTO_BACKUP_ENABLED_PREFERENCE_KEY)) @pyqtProperty("QVariantList", notify = backupsChanged) def backups(self) -> List[Dict[str, Any]]: From 520b34ab8901df47a55c90fe98bf827cef9d2499 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 9 Jan 2019 08:41:13 +0100 Subject: [PATCH 1221/1292] Use getPluginPath() CURA-6005 --- plugins/CuraDrive/src/DrivePluginExtension.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/CuraDrive/src/DrivePluginExtension.py b/plugins/CuraDrive/src/DrivePluginExtension.py index 1f66706ce6..060f1496f1 100644 --- a/plugins/CuraDrive/src/DrivePluginExtension.py +++ b/plugins/CuraDrive/src/DrivePluginExtension.py @@ -68,7 +68,8 @@ class DrivePluginExtension(QObject, Extension): def showDriveWindow(self) -> None: if not self._drive_window: - path = os.path.join(os.path.dirname(__file__), "qml", "main.qml") + plugin_dir_path = CuraApplication.getInstance().getPluginRegistry().getPluginPath("CuraDrive") + path = os.path.join(plugin_dir_path, "src", "qml", "main.qml") self._drive_window = CuraApplication.getInstance().createQmlComponent(path, {"CuraDrive": self}) self.refreshBackups() if self._drive_window: From 580a69f11e864f1d5328143613398abbec29ec39 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 9 Jan 2019 09:27:31 +0100 Subject: [PATCH 1222/1292] Add CuraCloudAccountAPIRoot to CuraVersion.py.in CURA-6005 --- cura/CuraVersion.py.in | 1 + 1 file changed, 1 insertion(+) diff --git a/cura/CuraVersion.py.in b/cura/CuraVersion.py.in index 7c6304231d..d0f07ebb8c 100644 --- a/cura/CuraVersion.py.in +++ b/cura/CuraVersion.py.in @@ -8,3 +8,4 @@ CuraDebugMode = True if "@_cura_debugmode@" == "ON" else False CuraSDKVersion = "@CURA_SDK_VERSION@" CuraCloudAPIRoot = "@CURA_CLOUD_API_ROOT@" CuraCloudAPIVersion = "@CURA_CLOUD_API_VERSION@" +CuraCloudAccountAPIRoot = "CURA_CLOUD_ACCOUNT_API_ROOT" From 862c76a2eac51f7280e8118bcce56c1ba2a483fc Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 9 Jan 2019 12:51:20 +0100 Subject: [PATCH 1223/1292] Check if the optimised layer data is stored before attempting to delete it --- plugins/CuraEngineBackend/CuraEngineBackend.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index f12a5b1222..ef0898bb04 100755 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -833,7 +833,10 @@ class CuraEngineBackend(QObject, Backend): self._onChanged() def _onProcessLayersFinished(self, job: ProcessSlicedLayersJob) -> None: - del self._stored_optimized_layer_data[job.getBuildPlate()] + if job.getBuildPlate() in self._stored_optimized_layer_data: + del self._stored_optimized_layer_data[job.getBuildPlate()] + else: + Logger.log("w", "The optimized layer data was already deleted for buildplate %s", job.getBuildPlate()) self._process_layers_job = None Logger.log("d", "See if there is more to slice(2)...") self._invokeSlice() From d928e0979d4bbfba4ecf06bcc30c0636c6fbc3d0 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 9 Jan 2019 12:54:33 +0100 Subject: [PATCH 1224/1292] Handle attempting to remove a favorite material that was already removed --- cura/Machines/MaterialManager.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index 4d9574bf38..160508e7a6 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -683,7 +683,11 @@ class MaterialManager(QObject): @pyqtSlot(str) def removeFavorite(self, root_material_id: str) -> None: - self._favorites.remove(root_material_id) + try: + self._favorites.remove(root_material_id) + except KeyError: + Logger.log("w", "Could not delete material %s from favorites as it was already deleted", root_material_id) + return self.materialsUpdated.emit() # Ensure all settings are saved. @@ -692,4 +696,4 @@ class MaterialManager(QObject): @pyqtSlot() def getFavorites(self): - return self._favorites \ No newline at end of file + return self._favorites From 366d2c8114a2de79786c1bf1a43b9a348ef0ed88 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 9 Jan 2019 12:56:49 +0100 Subject: [PATCH 1225/1292] Prevent crash for firmware updater if the activePrinter is not set --- plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.py b/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.py index 0a3e3a0ff0..59552775b6 100644 --- a/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.py +++ b/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.py @@ -57,7 +57,7 @@ class FirmwareUpdaterMachineAction(MachineAction): outputDeviceCanUpdateFirmwareChanged = pyqtSignal() @pyqtProperty(QObject, notify = outputDeviceCanUpdateFirmwareChanged) def firmwareUpdater(self) -> Optional["FirmwareUpdater"]: - if self._active_output_device and self._active_output_device.activePrinter.getController().can_update_firmware: + if self._active_output_device and self._active_output_device.activePrinter and self._active_output_device.activePrinter.getController().can_update_firmware: self._active_firmware_updater = self._active_output_device.getFirmwareUpdater() return self._active_firmware_updater From 8831ba04e1ae3e6d2a0bafa559246874afcae6b6 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Wed, 9 Jan 2019 17:05:10 +0100 Subject: [PATCH 1226/1292] Fix missing extruder number --- .../resources/qml/MonitorPrinterConfiguration.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterConfiguration.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterConfiguration.qml index 78af227408..debc8b7959 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterConfiguration.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterConfiguration.qml @@ -39,7 +39,7 @@ Item { color: modelData && modelData.activeMaterial ? modelData.activeMaterial.color : "#eeeeee" // TODO: Theme! material: modelData && modelData.activeMaterial ? modelData.activeMaterial.name : "" - position: modelData && modelData.position ? modelData.position : -1 // Use negative one to create empty extruder number + position: modelData && typeof(modelData.position) === "number" ? modelData.position : -1 // Use negative one to create empty extruder number printCore: modelData ? modelData.hotendID : "" // Keep things responsive! From 03b4121d2289a89d0b779309190bd3d0b8d4efa6 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 10 Jan 2019 13:59:22 +0100 Subject: [PATCH 1227/1292] Fix broken shortcut for slice or stop slicing. --- resources/qml/ActionPanel/SliceProcessWidget.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index 1695be8748..0f415a6a2d 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -194,7 +194,7 @@ Column shortcut: "Ctrl+P" onTriggered: { - if (prepareButton.enabled) + if (sliceButton.enabled) { sliceOrStopSlicing() } From a042de128b64b91421625507e4410496cf050b1a Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Thu, 10 Jan 2019 14:16:20 +0100 Subject: [PATCH 1228/1292] Tag CuraCloudAPIVersion-string-value as expression instead of literal. [CURA-6005] --- cura/CuraVersion.py.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/CuraVersion.py.in b/cura/CuraVersion.py.in index d0f07ebb8c..770a0efd7b 100644 --- a/cura/CuraVersion.py.in +++ b/cura/CuraVersion.py.in @@ -8,4 +8,4 @@ CuraDebugMode = True if "@_cura_debugmode@" == "ON" else False CuraSDKVersion = "@CURA_SDK_VERSION@" CuraCloudAPIRoot = "@CURA_CLOUD_API_ROOT@" CuraCloudAPIVersion = "@CURA_CLOUD_API_VERSION@" -CuraCloudAccountAPIRoot = "CURA_CLOUD_ACCOUNT_API_ROOT" +CuraCloudAccountAPIRoot = "@CURA_CLOUD_ACCOUNT_API_ROOT@" From 36191fbe0f57aa2a3c88b358e7de408b9b94fa83 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Thu, 10 Jan 2019 15:36:12 +0100 Subject: [PATCH 1229/1292] Fix typevar typing issue --- plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py | 2 +- plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py index 2ff323555a..1b60ee7aae 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py @@ -22,7 +22,7 @@ from .Models.CloudPrintJobResponse import CloudPrintJobResponse ## The generic type variable used to document the methods below. -CloudApiClientModel = TypeVar("Model", bound = BaseModel) +CloudApiClientModel = TypeVar("CloudApiClientModel", bound = BaseModel) ## The cloud API client is responsible for handling the requests and responses from the cloud. diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index f3c4830e24..e8356cb897 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -44,7 +44,7 @@ I18N_CATALOG = i18nCatalog("cura") class CloudOutputDevice(NetworkedPrinterOutputDevice): # The interval with which the remote clusters are checked - CHECK_CLUSTER_INTERVAL = 50.0 # seconds + CHECK_CLUSTER_INTERVAL = 20.0 # seconds # Signal triggered when the print jobs in the queue were changed. printJobsChanged = pyqtSignal() From 614b1000fd8642d77ea38b1f6de21e0d24d1adbe Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 10 Jan 2019 15:36:36 +0100 Subject: [PATCH 1230/1292] Added missing material compatibility chart link CURA-6090 --- .../ConfigurationMenu/ConfigurationMenu.qml | 42 +++++++++++++++++++ .../themes/cura-light/icons/external_link.svg | 8 ++++ 2 files changed, 50 insertions(+) create mode 100644 resources/themes/cura-light/icons/external_link.svg diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index 3001efac54..491a2f069f 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -173,6 +173,48 @@ Cura.ExpandablePopup } } + Item + { + height: visible ? childrenRect.height: 0 + anchors.right: parent.right + anchors.rightMargin: UM.Theme.getSize("default_margin").width + width: childrenRect.width + UM.Theme.getSize("default_margin").width + visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.Custom + UM.RecolorImage + { + id: externalLinkIcon + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("default_margin").width + height: materialInfoLabel.height + width: height + sourceSize.height: width + color: UM.Theme.getColor("text_link") + source: UM.Theme.getIcon("external_link") + } + + Label + { + id: materialInfoLabel + wrapMode: Text.WordWrap + text: catalog.i18nc("@label", "See the material compatibility chart") + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text_link") + anchors.left: externalLinkIcon.right + anchors.leftMargin: UM.Theme.getSize("narrow_margin").width + + MouseArea + { + anchors.fill: parent + onClicked: + { + // open the material URL with web browser + var url = "https://ultimaker.com/incoming-links/cura/material-compatibilty" + Qt.openUrlExternally(url) + } + } + } + } + Rectangle { id: separator diff --git a/resources/themes/cura-light/icons/external_link.svg b/resources/themes/cura-light/icons/external_link.svg new file mode 100644 index 0000000000..a2130fb97b --- /dev/null +++ b/resources/themes/cura-light/icons/external_link.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file From ff79e91686c070c1df206c2dc7f93555f04758fd Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 10 Jan 2019 16:32:43 +0100 Subject: [PATCH 1231/1292] Move the additional components for the save button out of the action panel CURA-6097 --- .../PostProcessingPlugin.qml | 2 +- .../qml/ActionPanel/OutputProcessWidget.qml | 50 +++---------------- .../qml/ActionPanel/SliceProcessWidget.qml | 38 +------------- resources/qml/Cura.qml | 34 +++++++++++++ 4 files changed, 44 insertions(+), 80 deletions(-) diff --git a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml index d5fe618b2d..cd8303d1d3 100644 --- a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml +++ b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml @@ -488,7 +488,7 @@ UM.Dialog { objectName: "postProcessingSaveAreaButton" visible: activeScriptsList.count > 0 - height: UM.Theme.getSize("save_button_save_to_button").height + height: UM.Theme.getSize("action_button").height width: height tooltip: catalog.i18nc("@info:tooltip", "Change active post-processing scripts") onClicked: dialog.show() diff --git a/resources/qml/ActionPanel/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml index 15214f212c..e3b623b675 100644 --- a/resources/qml/ActionPanel/OutputProcessWidget.qml +++ b/resources/qml/ActionPanel/OutputProcessWidget.qml @@ -31,6 +31,13 @@ Column id: information width: parent.width height: childrenRect.height + + PrintInformationWidget + { + id: printInformationPanel + visible: !preSlicedData + anchors.right: parent.right + } Column { @@ -51,14 +58,6 @@ Column text: preSlicedData ? catalog.i18nc("@label", "No time estimation available") : PrintInformation.currentPrintTime.getDisplayString(UM.DurationFormat.Long) source: UM.Theme.getIcon("clock") font: UM.Theme.getFont("large_bold") - - PrintInformationWidget - { - id: printInformationPanel - visible: !preSlicedData - anchors.left: parent.left - anchors.leftMargin: parent.contentWidth + UM.Theme.getSize("default_margin").width - } } Cura.IconWithText @@ -91,43 +90,8 @@ Column return totalWeights + "g · " + totalLengths.toFixed(2) + "m" } source: UM.Theme.getIcon("spool") - - Item - { - id: additionalComponents - width: childrenRect.width - anchors.right: parent.right - height: parent.height - Row - { - id: additionalComponentsRow - anchors.right: parent.right - anchors.bottom: parent.bottom - spacing: UM.Theme.getSize("default_margin").width - } - } - Component.onCompleted: addAdditionalComponents("saveButton") - - Connections - { - target: CuraApplication - onAdditionalComponentsChanged: addAdditionalComponents("saveButton") - } - - function addAdditionalComponents (areaId) - { - if(areaId == "saveButton") - { - for (var component in CuraApplication.additionalComponents["saveButton"]) - { - CuraApplication.additionalComponents["saveButton"][component].parent = additionalComponentsRow - } - } - } } } - - } Item diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index 0f415a6a2d..08966ce82c 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -110,8 +110,7 @@ Column height: parent.height - anchors.right: additionalComponents.left - anchors.rightMargin: additionalComponents.width != 0 ? UM.Theme.getSize("default_margin").width : 0 + anchors.right: parent.right anchors.left: parent.left text: catalog.i18nc("@button", "Slice") @@ -128,45 +127,12 @@ Column height: parent.height anchors.left: parent.left - anchors.right: additionalComponents.left - anchors.rightMargin: additionalComponents.width != 0 ? UM.Theme.getSize("default_margin").width : 0 + anchors.right: parent.right text: catalog.i18nc("@button", "Cancel") enabled: sliceButton.enabled visible: !sliceButton.visible onClicked: sliceOrStopSlicing() } - - Item - { - id: additionalComponents - width: childrenRect.width - anchors.right: parent.right - height: parent.height - Row - { - id: additionalComponentsRow - anchors.verticalCenter: parent.verticalCenter - spacing: UM.Theme.getSize("default_margin").width - } - } - Component.onCompleted: prepareButtons.addAdditionalComponents("saveButton") - - Connections - { - target: CuraApplication - onAdditionalComponentsChanged: prepareButtons.addAdditionalComponents("saveButton") - } - - function addAdditionalComponents (areaId) - { - if(areaId == "saveButton") - { - for (var component in CuraApplication.additionalComponents["saveButton"]) - { - CuraApplication.additionalComponents["saveButton"][component].parent = additionalComponentsRow - } - } - } } diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 4a031e33fa..f3d2e7295a 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -248,6 +248,7 @@ UM.MainWindow Cura.ActionPanelWidget { + id: actionPanelWidget anchors.right: parent.right anchors.bottom: parent.bottom anchors.rightMargin: UM.Theme.getSize("thick_margin").width @@ -269,6 +270,39 @@ UM.MainWindow visible: CuraApplication.platformActivity && (main.item == null || !qmlTypeOf(main.item, "QQuickRectangle")) } + Item + { + id: additionalComponents + width: childrenRect.width + anchors.right: actionPanelWidget.left + anchors.rightMargin: UM.Theme.getSize("default_margin").width + anchors.bottom: actionPanelWidget.bottom + anchors.bottomMargin: UM.Theme.getSize("thick_margin").height * 2 + visible: actionPanelWidget.visible + Row + { + id: additionalComponentsRow + anchors.verticalCenter: parent.verticalCenter + spacing: UM.Theme.getSize("default_margin").width + } + } + + Component.onCompleted: contentItem.addAdditionalComponents() + + Connections + { + target: CuraApplication + onAdditionalComponentsChanged: contentItem.addAdditionalComponents("saveButton") + } + + function addAdditionalComponents() + { + for (var component in CuraApplication.additionalComponents["saveButton"]) + { + CuraApplication.additionalComponents["saveButton"][component].parent = additionalComponentsRow + } + } + Loader { // A stage can control this area. If nothing is set, it will therefore show the 3D view. From d4621ec5043f2be107abfee6e5779cbdaaebccad Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 11 Jan 2019 13:20:14 +0100 Subject: [PATCH 1232/1292] Ensure that if no CuraCloudApiRoot is set that the default is used CURA-6005 --- cura/UltimakerCloudAuthentication.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cura/UltimakerCloudAuthentication.py b/cura/UltimakerCloudAuthentication.py index ac752231b9..5f69329dbb 100644 --- a/cura/UltimakerCloudAuthentication.py +++ b/cura/UltimakerCloudAuthentication.py @@ -10,6 +10,8 @@ DEFAULT_CLOUD_ACCOUNT_API_ROOT = "https://account.ultimaker.com" # type: str try: from cura.CuraVersion import CuraCloudAPIRoot # type: ignore + if CuraCloudAPIRoot == "": + CuraCloudAPIRoot = DEFAULT_CLOUD_API_ROOT except ImportError: CuraCloudAPIRoot = DEFAULT_CLOUD_API_ROOT @@ -20,5 +22,7 @@ except ImportError: try: from cura.CuraVersion import CuraCloudAccountAPIRoot # type: ignore + if CuraCloudAccountAPIRoot == "": + CuraCloudAccountAPIRoot = DEFAULT_CLOUD_ACCOUNT_API_ROOT except ImportError: CuraCloudAccountAPIRoot = DEFAULT_CLOUD_ACCOUNT_API_ROOT From 2dead8759329767f2348c07a4b8df6516dbe519c Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 11 Jan 2019 14:43:20 +0100 Subject: [PATCH 1233/1292] Ensure that the installed & canUpdate properties get set correctly CURA-6053 --- plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml b/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml index 7160dafa2d..87fc5d6955 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml @@ -91,5 +91,10 @@ Column target: toolbox onInstallChanged: installed = toolbox.isInstalled(model.id) onMetadataChanged: canUpdate = toolbox.canUpdate(model.id) + onFilterChanged: + { + installed = toolbox.isInstalled(model.id) + canUpdate = toolbox.canUpdate(model.id) + } } } From e7060206396f7cc4a30e82e3d4b8c7036e152d4b Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 11 Jan 2019 14:44:49 +0100 Subject: [PATCH 1234/1292] Improve the text when there is no configuration available It can happen that the list is empty because the data is still coming or because the connection has been lost. There are also some improvements in the link to the compatibility chart. Now the two external links in Cura have the same behaviour. Contributes to CURA-6011. --- .../UM3NetworkPrinting/resources/qml/MonitorQueue.qml | 9 +++++---- .../resources/svg/icons/external_link.svg | 8 -------- .../Menus/ConfigurationMenu/ConfigurationListView.qml | 8 ++++++-- .../qml/Menus/ConfigurationMenu/ConfigurationMenu.qml | 11 +++++++++++ 4 files changed, 22 insertions(+), 14 deletions(-) delete mode 100644 plugins/UM3NetworkPrinting/resources/svg/icons/external_link.svg diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml index 124b268300..f2dc09de95 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml @@ -42,8 +42,8 @@ Item { id: externalLinkIcon anchors.verticalCenter: manageQueueLabel.verticalCenter - color: UM.Theme.getColor("primary") - source: "../svg/icons/external_link.svg" + color: UM.Theme.getColor("text_link") + source: UM.Theme.getIcon("external_link") width: 16 * screenScaleFactor // TODO: Theme! (Y U NO USE 18 LIKE ALL OTHER ICONS?!) height: 16 * screenScaleFactor // TODO: Theme! (Y U NO USE 18 LIKE ALL OTHER ICONS?!) } @@ -56,10 +56,11 @@ Item leftMargin: 6 * screenScaleFactor // TODO: Theme! verticalCenter: externalLinkIcon.verticalCenter } - color: UM.Theme.getColor("primary") + color: UM.Theme.getColor("text_link") font: UM.Theme.getFont("default") // 12pt, regular - linkColor: UM.Theme.getColor("primary") + linkColor: UM.Theme.getColor("text_link") text: catalog.i18nc("@label link to connect manager", "Manage queue in Cura Connect") + renderType: Text.NativeRendering } } diff --git a/plugins/UM3NetworkPrinting/resources/svg/icons/external_link.svg b/plugins/UM3NetworkPrinting/resources/svg/icons/external_link.svg deleted file mode 100644 index a2130fb97b..0000000000 --- a/plugins/UM3NetworkPrinting/resources/svg/icons/external_link.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index e57b21cb78..15d882fdf5 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -23,7 +23,7 @@ Item } } - // This component will appear when there is no configurations (e.g. when losing connection) + // This component will appear when there are no configurations (e.g. when losing connection or when they are being loaded) Item { width: parent.width @@ -51,7 +51,11 @@ Item anchors.left: icon.right anchors.right: parent.right anchors.leftMargin: UM.Theme.getSize("default_margin").width - text: catalog.i18nc("@label", "Downloading the configurations from the remote printer") + // There are two cases that we want to diferenciate, one is when Cura is loading the configurations and the + // other when the connection was lost + text: Cura.MachineManager.printerConnected ? + catalog.i18nc("@label", "Loading available configurations from the printer...") : + catalog.i18nc("@label", "The configurations are not available because the printer is disconnected.") color: UM.Theme.getColor("text") font: UM.Theme.getFont("default") renderType: Text.NativeRendering diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index 491a2f069f..7d09f4be38 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -199,18 +199,29 @@ Cura.ExpandablePopup text: catalog.i18nc("@label", "See the material compatibility chart") font: UM.Theme.getFont("default") color: UM.Theme.getColor("text_link") + linkColor: UM.Theme.getColor("text_link") anchors.left: externalLinkIcon.right anchors.leftMargin: UM.Theme.getSize("narrow_margin").width + renderType: Text.NativeRendering MouseArea { anchors.fill: parent + hoverEnabled: true onClicked: { // open the material URL with web browser var url = "https://ultimaker.com/incoming-links/cura/material-compatibilty" Qt.openUrlExternally(url) } + onEntered: + { + materialInfoLabel.font.underline = true + } + onExited: + { + materialInfoLabel.font.underline = false + } } } } From cbeadb234314a3dc18372cced43dacee7f859aa1 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 11 Jan 2019 14:47:59 +0100 Subject: [PATCH 1235/1292] Set the font of the time estimation to medium bold This way it will also fit when a very long time is used in german. If we don't do this, 14 Tages 12 Stunden 33 Minuten didn't fit. CURA-6097 --- resources/qml/ActionPanel/OutputProcessWidget.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/ActionPanel/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml index e3b623b675..63974d7f34 100644 --- a/resources/qml/ActionPanel/OutputProcessWidget.qml +++ b/resources/qml/ActionPanel/OutputProcessWidget.qml @@ -57,7 +57,7 @@ Column text: preSlicedData ? catalog.i18nc("@label", "No time estimation available") : PrintInformation.currentPrintTime.getDisplayString(UM.DurationFormat.Long) source: UM.Theme.getIcon("clock") - font: UM.Theme.getFont("large_bold") + font: UM.Theme.getFont("medium_bold") } Cura.IconWithText From b78ac0664f1ebd869a6487f64f9e9b6859481dac Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Fri, 11 Jan 2019 16:07:08 +0100 Subject: [PATCH 1236/1292] Fix return types from review --- cura/PrinterOutput/NetworkedPrinterOutputDevice.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py index 4a8aa0a6b2..985d742728 100644 --- a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py +++ b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py @@ -228,7 +228,8 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): self._last_request_time = time() if not self._manager: - return Logger.log("e", "No network manager was created to execute the DELETE call with.") + Logger.log("e", "No network manager was created to execute the DELETE call with.") + return reply = self._manager.deleteResource(request) self._registerOnFinishedCallback(reply, on_finished) @@ -243,7 +244,8 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): self._last_request_time = time() if not self._manager: - return Logger.log("e", "No network manager was created to execute the GET call with.") + Logger.log("e", "No network manager was created to execute the GET call with.") + return reply = self._manager.get(request) self._registerOnFinishedCallback(reply, on_finished) @@ -262,7 +264,8 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): self._last_request_time = time() if not self._manager: - return Logger.log("e", "Could not find manager.") + Logger.log("e", "Could not find manager.") + return body = data if isinstance(data, bytes) else data.encode() # type: bytes reply = self._manager.post(request, body) From 36e49ee6bb0ee7261268135a3ab212f036fe2fc7 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Fri, 11 Jan 2019 16:08:46 +0100 Subject: [PATCH 1237/1292] Make activeMachineIsGroup more robust --- cura/Settings/MachineManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 2f9cb106fb..5f33be1c54 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -534,7 +534,7 @@ class MachineManager(QObject): @pyqtProperty(bool, notify = printerConnectedStatusChanged) def activeMachineIsGroup(self) -> bool: - return bool(self._printer_output_devices) and self._printer_output_devices[0].clusterSize > 1 + return bool(self._printer_output_devices) and len(self._printer_output_devices[0].printers) > 1 @pyqtProperty(bool, notify = printerConnectedStatusChanged) def activeMachineHasActiveNetworkConnection(self) -> bool: From d8b5f75e2a297c9ce269bc7b0208f2d65f90239e Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Fri, 11 Jan 2019 16:14:55 +0100 Subject: [PATCH 1238/1292] Solve some review comments --- cura/PrinterOutput/NetworkedPrinterOutputDevice.py | 14 +++++++------- .../UM3NetworkPrinting/src/Cloud/CloudApiClient.py | 4 +--- .../src/Cloud/CloudOutputDevice.py | 2 +- .../src/Cloud/CloudProgressMessage.py | 11 +++-------- .../UM3NetworkPrinting/src/MeshFormatHandler.py | 10 ++++------ 5 files changed, 16 insertions(+), 25 deletions(-) diff --git a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py index 985d742728..6b19ca9564 100644 --- a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py +++ b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py @@ -194,11 +194,11 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): assert (self._manager is not None) ## Sends a put request to the given path. - # url: The path after the API prefix. - # data: The data to be sent in the body - # content_type: The content type of the body data. - # on_finished: The function to call when the response is received. - # on_progress: The function to call when the progress changes. Parameters are bytes_sent / bytes_total. + # \param url: The path after the API prefix. + # \param data: The data to be sent in the body + # \param content_type: The content type of the body data. + # \param on_finished: The function to call when the response is received. + # \param on_progress: The function to call when the progress changes. Parameters are bytes_sent / bytes_total. def put(self, url: str, data: Union[str, bytes], content_type: Optional[str] = None, on_finished: Optional[Callable[[QNetworkReply], None]] = None, on_progress: Optional[Callable[[int, int], None]] = None) -> None: @@ -219,8 +219,8 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): reply.uploadProgress.connect(on_progress) ## Sends a delete request to the given path. - # url: The path after the API prefix. - # on_finished: The function to be call when the response is received. + # \param url: The path after the API prefix. + # \param on_finished: The function to be call when the response is received. def delete(self, url: str, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: self._validateManager() diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py index 1b60ee7aae..836a0eb393 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py @@ -43,7 +43,7 @@ class CloudApiClient: self._account = account self._on_error = on_error self._upload = None # type: Optional[MeshUploader] - # in order to avoid garbage collection we keep the callbacks in this list. + # In order to avoid garbage collection we keep the callbacks in this list. self._anti_gc_callbacks = [] # type: List[Callable[[], None]] ## Gets the account used for the API. @@ -105,7 +105,6 @@ class CloudApiClient: request.setHeader(QNetworkRequest.ContentTypeHeader, content_type) if self._account.isLoggedIn: request.setRawHeader(b"Authorization", "Bearer {}".format(self._account.accessToken).encode()) - # Logger.log("i", "Created request for URL %s. Logged in = %s", path, self._account.isLoggedIn) return request ## Parses the given JSON network reply into a status code and a dictionary, handling unexpected errors as well. @@ -116,7 +115,6 @@ class CloudApiClient: status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) try: response = bytes(reply.readAll()).decode() - # Logger.log("i", "Received a reply %s from %s with %s", status_code, reply.url().toString(), response) return status_code, json.loads(response) except (UnicodeDecodeError, JSONDecodeError, ValueError) as err: error = CloudError(code=type(err).__name__, title=str(err), http_code=str(status_code), diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index e8356cb897..0b832fc8b4 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -107,7 +107,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## Disconnects the device def disconnect(self) -> None: super().disconnect() - Logger.log("i", "Disconnected to cluster %s", self.key) + Logger.log("i", "Disconnected from cluster %s", self.key) CuraApplication.getInstance().getBackend().backendStateChange.disconnect(self._onBackendStateChange) ## Resets the print job that was uploaded to force a new upload, runs whenever the user re-slices. diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudProgressMessage.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudProgressMessage.py index aefe59cc85..c4618c1d50 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudProgressMessage.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudProgressMessage.py @@ -4,20 +4,15 @@ from UM import i18nCatalog from UM.Message import Message -## Class that contains all the translations for this module. -class T: - _I18N_CATALOG = i18nCatalog("cura") - - SENDING_DATA_TEXT = _I18N_CATALOG.i18nc("@info:status", "Sending data to remote cluster") - SENDING_DATA_TITLE = _I18N_CATALOG.i18nc("@info:status", "Sending data to remote cluster") +I18N_CATALOG = i18nCatalog("cura") ## Class responsible for showing a progress message while a mesh is being uploaded to the cloud. class CloudProgressMessage(Message): def __init__(self): super().__init__( - text = T.SENDING_DATA_TEXT, - title = T.SENDING_DATA_TITLE, + text = I18N_CATALOG.i18nc("@info:status", "Sending data to remote cluster"), + title = I18N_CATALOG.i18nc("@info:status", "Sending data to remote cluster"), progress = -1, lifetime = 0, dismissable = False, diff --git a/plugins/UM3NetworkPrinting/src/MeshFormatHandler.py b/plugins/UM3NetworkPrinting/src/MeshFormatHandler.py index 72da3c4e6b..c3cd82a86d 100644 --- a/plugins/UM3NetworkPrinting/src/MeshFormatHandler.py +++ b/plugins/UM3NetworkPrinting/src/MeshFormatHandler.py @@ -13,11 +13,7 @@ from UM.i18n import i18nCatalog from cura.CuraApplication import CuraApplication -## Class that contains all the translations for this module. -class T: - # The translation catalog for this module. - _I18N_CATALOG = i18nCatalog("cura") - NO_FORMATS_AVAILABLE = _I18N_CATALOG.i18nc("@info:status", "There are no file formats available to write with!") +I18N_CATALOG = i18nCatalog("cura") ## This class is responsible for choosing the formats used by the connected clusters. @@ -106,7 +102,9 @@ class MeshFormatHandler: if len(file_formats) == 0: Logger.log("e", "There are no file formats available to write with!") - raise OutputDeviceError.WriteRequestFailedError(T.NO_FORMATS_AVAILABLE) + raise OutputDeviceError.WriteRequestFailedError( + I18N_CATALOG.i18nc("@info:status", "There are no file formats available to write with!") + ) return file_formats[0] ## Gets the file writer for the given file handler and mime type. From e465bd771ae8a5261980e53203e3b76178c78203 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Fri, 11 Jan 2019 16:18:47 +0100 Subject: [PATCH 1239/1292] Use toolpath instead of mesh, some review fixes --- cura/PrinterOutput/NetworkedPrinterOutputDevice.py | 2 +- plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py | 8 ++++---- plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py | 2 +- .../UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py index 6b19ca9564..47a6caf3e5 100644 --- a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py +++ b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py @@ -275,7 +275,7 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): def postFormWithParts(self, target: str, parts: List[QHttpPart], on_finished: Optional[Callable[[QNetworkReply], None]], - on_progress: Callable = None) -> QNetworkReply: + on_progress: Optional[Callable[[int, int], None]] = None) -> QNetworkReply: self._validateManager() request = self._createEmptyRequest(target, content_type=None) multi_post_part = QHttpMultiPart(QHttpMultiPart.FormDataType) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py index 836a0eb393..f82d244fa9 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py @@ -76,14 +76,14 @@ class CloudApiClient: reply = self._manager.put(self._createEmptyRequest(url), body.encode()) self._addCallback(reply, on_finished, CloudPrintJobResponse) - ## Uploads a print job mesh to the cloud. + ## Uploads a print job tool path to the cloud. # \param print_job: The object received after requesting an upload with `self.requestUpload`. - # \param mesh: The mesh data to be uploaded. + # \param mesh: The tool path data to be uploaded. # \param on_finished: The function to be called after the upload is successful. # \param on_progress: A function to be called during upload progress. It receives a percentage (0-100). # \param on_error: A function to be called if the upload fails. - def uploadMesh(self, print_job: CloudPrintJobResponse, mesh: bytes, on_finished: Callable[[], Any], - on_progress: Callable[[int], Any], on_error: Callable[[], Any]): + def uploadToolPath(self, print_job: CloudPrintJobResponse, mesh: bytes, on_finished: Callable[[], Any], + on_progress: Callable[[int], Any], on_error: Callable[[], Any]): self._upload = MeshUploader(self._manager, print_job, mesh, on_finished, on_progress, on_error) self._upload.start() diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 0b832fc8b4..054c465ef2 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -302,7 +302,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self._progress.show() self._uploaded_print_job = job_response mesh = cast(bytes, self._mesh) - self._api.uploadMesh(job_response, mesh, self._onPrintJobUploaded, self._progress.update, self._onUploadError) + self._api.uploadToolPath(job_response, mesh, self._onPrintJobUploaded, self._progress.update, self._onUploadError) ## Requests the print to be sent to the printer when we finished uploading the mesh. def _onPrintJobUploaded(self) -> None: diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py index b57334b2da..3c0617a290 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py @@ -74,7 +74,7 @@ class TestCloudApiClient(TestCase): self.assertEqual(["text/plain"], [r.content_type for r in results]) self.assertEqual(["uploading"], [r.status for r in results]) - def test_uploadMesh(self): + def test_uploadToolPath(self): results = [] progress = MagicMock() @@ -86,7 +86,7 @@ class TestCloudApiClient(TestCase): self.network.prepareReply("PUT", upload_response.upload_url, 200, b'{}') mesh = ("1234" * 100000).encode() - self.api.uploadMesh(upload_response, mesh, lambda: results.append("sent"), progress.advance, progress.error) + self.api.uploadToolPath(upload_response, mesh, lambda: results.append("sent"), progress.advance, progress.error) for _ in range(10): self.network.flushReplies() From 3c10cca0dee6c4a0fc0599bc33e51aaff7f4e5d9 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Fri, 11 Jan 2019 16:33:49 +0100 Subject: [PATCH 1240/1292] Fixed all codestyle and nitpicks from review --- .../src/Cloud/CloudOutputDevice.py | 32 +++++++++---------- .../src/Cloud/CloudOutputDeviceManager.py | 6 ++-- .../src/Cloud/CloudProgressMessage.py | 5 --- .../src/ClusterUM3OutputDevice.py | 2 +- .../tests/Cloud/NetworkManagerMock.py | 8 ++--- .../tests/Cloud/TestCloudApiClient.py | 2 +- .../qml/PrinterSelector/MachineSelector.qml | 22 +++++++++---- 7 files changed, 39 insertions(+), 38 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 054c465ef2..2cf6a3c236 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -95,7 +95,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self._finished_jobs = set() # type: Set[str] # Reference to the uploaded print job / mesh - self._mesh = None # type: Optional[bytes] + self._tool_path = None # type: Optional[bytes] self._uploaded_print_job = None # type: Optional[CloudPrintJobResponse] ## Connects this device. @@ -112,7 +112,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## Resets the print job that was uploaded to force a new upload, runs whenever the user re-slices. def _onBackendStateChange(self, _: BackendState) -> None: - self._mesh = None + self._tool_path = None self._uploaded_print_job = None ## Gets the cluster response from which this device was created. @@ -133,7 +133,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## Set all the interface elements and texts for this output device. def _setInterfaceElements(self) -> None: - self.setPriority(2) # make sure we end up below the local networking and above 'save to file' + self.setPriority(2) # Make sure we end up below the local networking and above 'save to file' self.setName(self._id) self.setShortDescription(I18N_CATALOG.i18nc("@action:button", "Print via Cloud")) self.setDescription(I18N_CATALOG.i18nc("@properties:tooltip", "Print via Cloud")) @@ -154,8 +154,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): return if self._uploaded_print_job: - # the mesh didn't change, let's not upload it again - self._api.requestPrint(self.key, self._uploaded_print_job.job_id, self._onPrintRequested) + # The mesh didn't change, let's not upload it again + self._api.requestPrint(self.key, self._uploaded_print_job.job_id, self._onPrintUploadCompleted) return # Indicate we have started sending a job. @@ -168,7 +168,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): mesh = mesh_format.getBytes(nodes) - self._mesh = mesh + self._tool_path = mesh request = CloudPrintJobUploadRequest( job_name = file_name or mesh_format.file_extension, file_size = len(mesh), @@ -180,7 +180,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def _update(self) -> None: super()._update() if self._last_request_time and time() - self._last_request_time < self.CHECK_CLUSTER_INTERVAL: - return # avoid calling the cloud too often + return # Avoid calling the cloud too often Logger.log("d", "Updating: %s - %s >= %s", time(), self._last_request_time, self.CHECK_CLUSTER_INTERVAL) if self._account.isLoggedIn: @@ -226,7 +226,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): if self._printers and not self._active_printer: self.setActivePrinter(self._printers[0]) - if added_printers or removed_printers or updated_printers: + if added_printers or removed_printers: self.printersChanged.emit() ## Updates the local list of print jobs with the list received from the cloud. @@ -253,7 +253,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # We only have to update when jobs are added or removed # updated jobs push their changes via their output model - if added_jobs or removed_jobs or updated_jobs: + if added_jobs or removed_jobs: self.printJobsChanged.emit() ## Registers a new print job received via the cloud API. @@ -268,6 +268,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## Handles the event of a change in a print job state def _onPrintJobStateChanged(self) -> None: user_name = self._getUserName() + # TODO: confirm that notifications in Cura are still required for job in self._print_jobs: if job.state == "wait_cleanup" and job.key not in self._finished_jobs and job.owner == user_name: self._finished_jobs.add(job.key) @@ -282,9 +283,6 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): )), ).show() - # Ensure UI gets updated - self.printJobsChanged.emit() - ## Updates the printer assignment for the given print job model. def _updateAssignedPrinter(self, model: UM3PrintJobOutputModel, printer_uuid: str) -> None: printer = next((p for p in self._printers if printer_uuid == p.key), None) @@ -301,18 +299,18 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): def _onPrintJobCreated(self, job_response: CloudPrintJobResponse) -> None: self._progress.show() self._uploaded_print_job = job_response - mesh = cast(bytes, self._mesh) - self._api.uploadToolPath(job_response, mesh, self._onPrintJobUploaded, self._progress.update, self._onUploadError) + tool_path = cast(bytes, self._tool_path) + self._api.uploadToolPath(job_response, tool_path, self._onPrintJobUploaded, self._progress.update, self._onUploadError) ## Requests the print to be sent to the printer when we finished uploading the mesh. def _onPrintJobUploaded(self) -> None: self._progress.update(100) print_job = cast(CloudPrintJobResponse, self._uploaded_print_job) - self._api.requestPrint(self.key, print_job.job_id, self._onPrintRequested) + self._api.requestPrint(self.key, print_job.job_id, self._onPrintUploadCompleted) ## Displays the given message if uploading the mesh has failed # \param message: The message to display. - def _onUploadError(self, message = None) -> None: + def _onUploadError(self, message: str = None) -> None: self._progress.hide() self._uploaded_print_job = None Message( @@ -324,7 +322,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## Shows a message when the upload has succeeded # \param response: The response from the cloud API. - def _onPrintRequested(self, response: CloudPrintResponse) -> None: + def _onPrintUploadCompleted(self, response: CloudPrintResponse) -> None: Logger.log("d", "The cluster will be printing this print job with the ID %s", response.cluster_job_id) self._progress.hide() Message( diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 72ac34ff34..ba852e36c0 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -41,7 +41,7 @@ class CloudOutputDeviceManager: self._account = application.getCuraAPI().account # type: Account self._api = CloudApiClient(self._account, self._onApiError) - # create a timer to update the remote cluster list + # Create a timer to update the remote cluster list self._update_timer = QTimer(application) self._update_timer.setInterval(int(self.CHECK_CLUSTER_INTERVAL * 1000)) self._update_timer.setSingleShot(False) @@ -99,7 +99,6 @@ class CloudOutputDeviceManager: def _connectToActiveMachine(self) -> None: active_machine = CuraApplication.getInstance().getGlobalContainerStack() if not active_machine: - Logger.log("d", "no active machine") return # Remove all output devices that we have registered. @@ -143,8 +142,7 @@ class CloudOutputDeviceManager: message = Message( text = text, title = self.I18N_CATALOG.i18nc("@info:title", "Error"), - lifetime = 10, - dismissable = True + lifetime = 10 ) message.show() diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudProgressMessage.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudProgressMessage.py index c4618c1d50..d85f49c1a0 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudProgressMessage.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudProgressMessage.py @@ -30,8 +30,3 @@ class CloudProgressMessage(Message): if not self._visible: super().show() self.setProgress(percentage) - - ## Returns a boolean indicating whether the message is currently visible. - @property - def visible(self) -> bool: - return self._visible diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index e40cad10f8..84740ae856 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -64,7 +64,7 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../resources/qml/MonitorStage.qml") - # trigger the printersChanged signal when the private signal is triggered + # Trigger the printersChanged signal when the private signal is triggered self.printersChanged.connect(self._clusterPrintersChanged) self._accepts_commands = True # type: bool diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py b/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py index 5b5d89ca54..e504509d67 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py @@ -30,7 +30,7 @@ class FakeSignal: # Any requests not prepared beforehand will cause KeyErrors. class NetworkManagerMock: - # an enumeration of the supported operations and their code for the network access manager. + # An enumeration of the supported operations and their code for the network access manager. _OPERATIONS = { "GET": QNetworkAccessManager.GetOperation, "POST": QNetworkAccessManager.PostOperation, @@ -41,11 +41,11 @@ class NetworkManagerMock: ## Initializes the network manager mock. def __init__(self) -> None: - # a dict with the prepared replies, using the format {(http_method, url): reply} + # A dict with the prepared replies, using the format {(http_method, url): reply} self.replies = {} # type: Dict[Tuple[str, str], MagicMock] self.request_bodies = {} # type: Dict[Tuple[str, str], bytes] - # signals used in the network manager. + # Signals used in the network manager. self.finished = Signal() self.authenticationRequired = Signal() @@ -55,7 +55,7 @@ class NetworkManagerMock: # \return The mocked function, if the method name is known. Defaults to the standard getattr function. def __getattr__(self, method: str) -> Any: ## This mock implementation will simply return the reply from the prepared ones. - # it raises a KeyError if requests are done without being prepared. + # it raises a KeyError if requests are done without being prepared. def doRequest(request: QNetworkRequest, body: Optional[bytes] = None, *_): key = method.upper(), request.url().toString() if body: diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py index 3c0617a290..acce55751c 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py @@ -39,7 +39,7 @@ class TestCloudApiClient(TestCase): data = parseFixture("getClusters")["data"] self.network.prepareReply("GET", CuraCloudAPIRoot + "/connect/v1/clusters", 200, response) - # the callback is a function that adds the result of the call to getClusters to the result list + # The callback is a function that adds the result of the call to getClusters to the result list self.api.getClusters(lambda clusters: result.extend(clusters)) self.network.flushReplies() diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index 7018131f45..84f63a854a 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -29,11 +29,16 @@ Cura.ExpandablePopup text: isNetworkPrinter ? Cura.MachineManager.activeMachineNetworkGroupName : Cura.MachineManager.activeMachineName source: { - if (isGroup) { + if (isGroup) + { return UM.Theme.getIcon("printer_group") - } else if (isNetworkPrinter || isCloudPrinter) { + } + else if (isNetworkPrinter || isCloudPrinter) + { return UM.Theme.getIcon("printer_single") - } else { + } + else + { return "" } } @@ -52,11 +57,16 @@ Cura.ExpandablePopup source: { - if (isNetworkPrinter) { + if (isNetworkPrinter) + { return UM.Theme.getIcon("printer_connected") - } else if (isCloudPrinter) { + } + else if (isCloudPrinter) + { return UM.Theme.getIcon("printer_cloud_connected") - } else { + } + else + { return "" } } From 7bbd43928a4d8d3adcc7d8119995add058c57bea Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Fri, 11 Jan 2019 16:38:25 +0100 Subject: [PATCH 1241/1292] Fix more review comments --- plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py | 6 +++--- plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py | 2 ++ .../src/Cloud/CloudOutputDeviceManager.py | 3 +-- .../src/Cloud/{MeshUploader.py => ToolPathUploader.py} | 2 +- .../tests/Cloud/TestCloudOutputDeviceManager.py | 1 - 5 files changed, 7 insertions(+), 7 deletions(-) rename plugins/UM3NetworkPrinting/src/Cloud/{MeshUploader.py => ToolPathUploader.py} (99%) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py index f82d244fa9..9d6c29c0a4 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py @@ -11,7 +11,7 @@ from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply, QNetworkAccessManage from UM.Logger import Logger from cura import UltimakerCloudAuthentication from cura.API import Account -from .MeshUploader import MeshUploader +from .ToolPathUploader import ToolPathUploader from ..Models import BaseModel from .Models.CloudClusterResponse import CloudClusterResponse from .Models.CloudError import CloudError @@ -42,7 +42,7 @@ class CloudApiClient: self._manager = QNetworkAccessManager() self._account = account self._on_error = on_error - self._upload = None # type: Optional[MeshUploader] + self._upload = None # type: Optional[ToolPathUploader] # In order to avoid garbage collection we keep the callbacks in this list. self._anti_gc_callbacks = [] # type: List[Callable[[], None]] @@ -84,7 +84,7 @@ class CloudApiClient: # \param on_error: A function to be called if the upload fails. def uploadToolPath(self, print_job: CloudPrintJobResponse, mesh: bytes, on_finished: Callable[[], Any], on_progress: Callable[[int], Any], on_error: Callable[[], Any]): - self._upload = MeshUploader(self._manager, print_job, mesh, on_finished, on_progress, on_error) + self._upload = ToolPathUploader(self._manager, print_job, mesh, on_finished, on_progress, on_error) self._upload.start() # Requests a cluster to print the given print job. diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 2cf6a3c236..2947cd421c 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -100,6 +100,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): ## Connects this device. def connect(self) -> None: + if self.isConnected(): + return super().connect() Logger.log("i", "Connected to cluster %s", self.key) CuraApplication.getInstance().getBackend().backendStateChange.connect(self._onBackendStateChange) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index ba852e36c0..f9bd635bbd 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -131,8 +131,7 @@ class CloudOutputDeviceManager: ## Connects to an output device and makes sure it is registered in the output device manager. def _connectToOutputDevice(self, device: CloudOutputDevice) -> None: - if not device.isConnected(): - device.connect() + device.connect() self._output_device_manager.addOutputDevice(device) ## Handles an API error received from the cloud. diff --git a/plugins/UM3NetworkPrinting/src/Cloud/MeshUploader.py b/plugins/UM3NetworkPrinting/src/Cloud/ToolPathUploader.py similarity index 99% rename from plugins/UM3NetworkPrinting/src/Cloud/MeshUploader.py rename to plugins/UM3NetworkPrinting/src/Cloud/ToolPathUploader.py index cb721b872e..176b7e6ab7 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/MeshUploader.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/ToolPathUploader.py @@ -10,7 +10,7 @@ from .Models.CloudPrintJobResponse import CloudPrintJobResponse ## Class responsible for uploading meshes to the cloud in separate requests. -class MeshUploader: +class ToolPathUploader: # The maximum amount of times to retry if the server returns one of the RETRY_HTTP_CODES MAX_RETRIES = 10 diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py index 96137a3edb..8b72c9d62d 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py @@ -125,5 +125,4 @@ class TestCloudOutputDeviceManager(TestCase): } self.network.prepareReply("GET", self.URL, 200, self.clusters_response) self._loadData() - message_mock.assert_called_once_with(text='Not found!', title='Error', lifetime=10, dismissable=True) message_mock.return_value.show.assert_called_once_with() From 801a43c874dabc93c2b1ad8555b457544d16f55e Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 11 Jan 2019 17:04:51 +0100 Subject: [PATCH 1242/1292] Add a small margin in the right so the close button is never behind the scrollbar Contributes to CURA-6005. --- plugins/CuraDrive/src/qml/components/BackupList.qml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/CuraDrive/src/qml/components/BackupList.qml b/plugins/CuraDrive/src/qml/components/BackupList.qml index afa9538486..a4a460a885 100644 --- a/plugins/CuraDrive/src/qml/components/BackupList.qml +++ b/plugins/CuraDrive/src/qml/components/BackupList.qml @@ -11,13 +11,15 @@ ScrollView { property alias model: backupList.model width: parent.width + clip: true ListView { id: backupList width: parent.width delegate: Item { - width: parent.width + // Add a margin, otherwise the scrollbar is on top of the right most component + width: parent.width - UM.Theme.getSize("default_margin").width height: childrenRect.height BackupListItem From 7b3cf6be64e5e243baa9bf4f21bf0f55d3e1c897 Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Fri, 11 Jan 2019 17:32:15 +0100 Subject: [PATCH 1243/1292] Fix resizable Settings-Panel for change in window size. [CURA-6054] --- .../qml/PrintSetupSelector/PrintSetupSelectorContents.qml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml index 0b8fb89311..edf5d952a5 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml @@ -77,7 +77,12 @@ Item target: UM.Preferences onPreferenceChanged: { - customPrintSetup.height = UM.Preferences.getValue("view/settings_list_height"); + customPrintSetup.height = + Math.min + ( + UM.Preferences.getValue("view/settings_list_height"), + base.height - (customPrintSetup.mapToItem(null, 0, 0).y + buttonRow.height) + ); } } visible: currentModeIndex == PrintSetupSelectorContents.Mode.Custom From c81689d23361af8d8a86bba129e0336112baf819 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 11 Jan 2019 17:40:36 +0100 Subject: [PATCH 1244/1292] Prevent a recurring qml warning Note that the connect_group metadata is also queried for non-connected printers; the model is not filtered, but non-connected printers are set to be invisible. --- resources/qml/Menus/NetworkPrinterMenu.qml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/resources/qml/Menus/NetworkPrinterMenu.qml b/resources/qml/Menus/NetworkPrinterMenu.qml index 3cb0aae016..41f3054e92 100644 --- a/resources/qml/Menus/NetworkPrinterMenu.qml +++ b/resources/qml/Menus/NetworkPrinterMenu.qml @@ -12,10 +12,18 @@ Instantiator model: Cura.GlobalStacksModel {} MenuItem { - text: model.metadata["connect_group_name"] + property string connectGroupName: + { + if("connect_group_name" in model.metadata) + { + return model.metadata["connect_group_name"] + } + return "" + } + text: connectGroupName checkable: true visible: model.hasRemoteConnection - checked: Cura.MachineManager.activeMachineNetworkGroupName == model.metadata["connect_group_name"] + checked: Cura.MachineManager.activeMachineNetworkGroupName == connectGroupName exclusiveGroup: group onTriggered: Cura.MachineManager.setActiveMachine(model.id) } From c6fa47e584a38998809916d6d5ff694afe21f75a Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 11 Jan 2019 17:52:28 +0100 Subject: [PATCH 1245/1292] Mark PrinterOutputDevice without printer type as invalid Since self._printer_type was defined as an empty string and the setter only accepts strings, it could never be None --- cura/PrinterOutput/ConfigurationModel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/PrinterOutput/ConfigurationModel.py b/cura/PrinterOutput/ConfigurationModel.py index 89e609c913..f9d0c7e36b 100644 --- a/cura/PrinterOutput/ConfigurationModel.py +++ b/cura/PrinterOutput/ConfigurationModel.py @@ -54,7 +54,7 @@ class ConfigurationModel(QObject): for configuration in self._extruder_configurations: if configuration is None: return False - return self._printer_type is not None + return self._printer_type != "" def __str__(self): message_chunks = [] From d03ec22dee514c305edc8e4482b9e43584f2c7b0 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 11 Jan 2019 17:55:06 +0100 Subject: [PATCH 1246/1292] Hide empty abbreviated machinename Connected printers that are not Cura Connect printers may not have a connect_group_name. --- resources/qml/PrinterSelector/MachineSelector.qml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index 9f0d3b4ac6..0a2e304efc 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -26,7 +26,14 @@ Cura.ExpandablePopup headerItem: Cura.IconWithText { - text: isNetworkPrinter ? Cura.MachineManager.activeMachineNetworkGroupName : Cura.MachineManager.activeMachineName + text: + { + if (isNetworkPrinter && Cura.MachineManager.activeMachineNetworkGroupName != "") + { + Cura.MachineManager.activeMachineNetworkGroupName + } + return Cura.MachineManager.activeMachineName + } source: { if (isNetworkPrinter) From f8bfca6079569835550a80f4eba2095d97cc53a3 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 11 Jan 2019 18:27:44 +0100 Subject: [PATCH 1247/1292] Don't show auto configuration selection when there are no configurations --- resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index 7d09f4be38..86cb7f9acf 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -136,9 +136,9 @@ Cura.ExpandablePopup onVisibleChanged: { - is_connected = Cura.MachineManager.activeMachineHasRemoteConnection && Cura.MachineManager.printerConnected //Re-evaluate. + is_connected = Cura.MachineManager.activeMachineHasRemoteConnection && Cura.MachineManager.printerConnected && Cura.MachineManager.printerOutputDevices[0].uniqueConfigurations.length > 0 //Re-evaluate. - // If the printer is not connected, we switch always to the custom mode. If is connected instead, the auto mode + // If the printer is not connected or does not have configurations, we switch always to the custom mode. If is connected instead, the auto mode // or the previous state is selected configuration_method = is_connected ? (manual_selected_method == -1 ? ConfigurationMenu.ConfigurationMethod.Auto : manual_selected_method) : ConfigurationMenu.ConfigurationMethod.Custom } From c11e0cecc87f768bc08980511b3a9fa810bb3fc9 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Sun, 13 Jan 2019 16:58:38 +0100 Subject: [PATCH 1248/1292] Remove loading gif Instead of an external gif, use the BusyIndicator that exists in the ActionButton. --- plugins/CuraDrive/src/qml/images/loading.gif | Bin 6762 -> 0 bytes plugins/Toolbox/resources/images/loading.gif | Bin 93386 -> 0 bytes plugins/Toolbox/resources/images/loading.svg | 1 - .../resources/qml/ToolboxProgressButton.qml | 13 +------------ resources/qml/ActionButton.qml | 10 ++++++++++ 5 files changed, 11 insertions(+), 13 deletions(-) delete mode 100644 plugins/CuraDrive/src/qml/images/loading.gif delete mode 100644 plugins/Toolbox/resources/images/loading.gif delete mode 100644 plugins/Toolbox/resources/images/loading.svg diff --git a/plugins/CuraDrive/src/qml/images/loading.gif b/plugins/CuraDrive/src/qml/images/loading.gif deleted file mode 100644 index 791dcaa0c93f0666b0738fa04633c291fd544d91..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6762 zcmcK9X;71Q9tZFzC%F$2NC-J0qV-^@MMqtCiyRgK0Rg$B%8?=nghPyAQ6dDQ2q>oo zK~Pay#k1N~OD$HkXlch*$LY3i$6D7J9oktfbz0YT_xt35v>xp%^o5gmkk9}7`~LpV z!yAhh&Y7F0C-lT#f?(2_whG(eM}xtE!MAVSo<4PY&+eYl2cvR#d2vy(fG22fZNB!! zwTQ3?|JnX0-aGO5(c{{h+TqK?Blkv_Y^JT+Hh6I`cwzAEJGcF3`u82~8+|yc)~d_a zl?g3{s>@slS{h?nrs@IQWJNL*~tg6NQ$zJ3fEeuUu{CYMEc6Vu5b zM}AF$Z5?PR2vuve?TZR8nQF8`9?>oFKN23Ed6^|Rni{(Q>rbsmcCb%>J@+-ky`M&p z7ye0B6dB-kToIHbm#*0mB4L?0?o|Cgk3TBVMQj{`VPp`*Ry+VyKjA0rM0r_kKkj1w9DY}n{!%r)npIDP``@Gsj? z)_=C&lx_kz{9lqe=?c`f1KSEh1)7;^apjU|dDoS+^Lirj$n}8YX(RfhsROspub*xF z_TN=0+EoX#{r1kN`j~4Qs$BeW50@q>D-M!n%T=~$oo6cFy=I9jRkW>Pi!@QZeHlYR zh`5y8TO!4XFf2jRcc2gP1OrIGfc#Qs z;6%V7T5KVs4L``u|Lc6{BFm)cvn)Q!WOswO&Z5$A<-Fz{)jM`}b?@4}r)TfJ{k>0HTE-Qp zyhsr+Z~{Qjz8*lL3m{ipUyETzG!ZpWp)7z0T^NHC35F1Cs8T?zkymITujFa`FoHD0 z55a{u{BQ_p2ebxgC(4q&CZM?>G`LOBWYaU!1Lj}omA`d&6BHlbnv=Bes?{=oxnSVJ z#j4?p%jGNl4}5-@F{daktyVAbTB9m8y7Bouu`$r7qUlVM(o&%yS?bc*IN6iqv9hhL zu=_=dWFk+FOB!D&Nd@XaA29J{k*2s9QWAy;Ao7K;4;B;wQU*pRAcPTH00NoR(~@04 z3Zo800vKY>QJYVRxn$L`vs;?0tNg?_cJSTZawO%8c{-EcQXQhn;nhWWnWT*i z`57^8=Iz1FDGfV=6ef>7L0Wx`AiOtFB~$8m9~rC3@!bla8a_T2kMf5TqDAuggfeiT>TSWj!sJF2evH$t7p1u>yUBg z@g?&b-1yzEl_W2a(o^|a{zop+w@>@IqKc5G`j@i(Z{0Yu9_`xOC|oQY2kcWkzqiRGZ<^BhFCuNX1H} zxF<+j@quHXU;KFJ(&cg3XLdTmirJ<15Ux^~T~j8xhmc6%U?%~JOr8T4n2>}sbxlHd zQema;QPhnKH2{2ab>U+0l5N>#n97M3n$+W+Oo{5$mE#W>kTxsvQll{2N( z(<)uf@=9rzn@6QAOWVN8T2-kL^O*LAz{1niMJak5bnSM&x!8QRR@{0U{ zk20b(A%%4VTpR$n$wjlSj55VOf;$9p9>7Jo5p?t?<&H*0C7^);J+Z{NBw?}t3VNlt zIP6f&U!(_Lr61emJL&rZ<`jl9-7q8==!xRbPHj3nH21E(ztMNrm%4mru4{!YTUwsE zF@0UGPqt5yEM2R~buUhCv?m*i2t&H6NS_uziBsf}EzcF@GioGB`7Cx{K5m}zB0Y)m;)M9Ug5JQcAfG$OdRKpLh6dQ^HW@rY~F3ixvfSg!4 z=de3Juq{uA(_xu>6IXjV7zBXPfvn7Z#@}-)kB7J!_J>I2*(8r5f^0}Ey6&>6a@fvBq{GCL#J4fP{ z@_ytv<@5JV@~O%38FxOmFd{_fAn}P z&m!`2iU4Emk#i(=Vz)fIl)P^~6H5o>C*QC8a5$_gJkXEF&U=f-qa_i=%D`pzJG3Fc6FjSW z+fe${)d8%$3k44ddAvwcVr9gNbnZ-Rkub`jWj0sW6ADq3WP82Bvq9EbDr}Dux$G(4 z6hrHzbGl;<9KJ%z*K^oT%4e_e)i$#2aPdSc_x0c!1Wi~VaX>*%QF~Nhf{eVRPbDu# zq|u|t(8L)~!NhsMj(i+KW~mKzmV729%d)W<2Y}2{_fy1qqHx(oiMY~Hu^rmuaKjfz5b>>1lE@{vsLlj6`V&gz zI}=MW6-Q(dr$8>8dm}gn$fGJzm?(n@UoyYVBK4VF{Cib7o=9Ks*Wdgk;FdItFS2&T zq@~V!FyGo8+8rdoTM`DlJj{Jvjf+z0S)-58acWvxM3!)YzO|EZX^U{@@2t^83#5v@ z45>ZZLnV_i7!sL^<%E3pK?r%o{&vhJBrx5;z_SoGE&>P-DvX#}2muW0P(;wseW0Sk zNF|yw?$}9|DWXax5$Ax@cuC6#kCb>2`u#l4QSl0O{DB4OpQRH80s3WagS6I7{}KIc zI?5<35#}xRt{|9tv0I#hx2eEI;^oDyi^7|ZwX35It{sKCswk;sHzA5Ou;>l!1P;rU zr`5{UdqaPxB&oY0=8}x$9rE!TUmU?iJaO*UYU}?QYa{!i9OfZQi+B&9!N(*AVnX zjed>TJyB9YXf+AyI;EDI7pvJ&M<~i-`0aJ-r5fH2W`astp{(+h7I2oaIBvovZNJ(Zm)0n(BrEM%SMOheM7h>v8?hW zj#aQek#6NxS|yA`vB0WsO3+ye$y*5?xCAAL-8#w=Joj5Yn|G}eWF`t#82Ds^_}vxG z3+1!7Ajfc%d&047V1jTVebhAuEEr;>4+(`2B;khPM(ALLc=FaP(aV@tssZHN7W_t_U zkFv7Gxjxp6ignqX#7x(GQ7$Wgd8Q#>ydhKFxGi5;xPne1LsRJ^ zlPbE7ldpwC{xFvqTWaCpsS%Da0v0vD+M3bSIhP^dW$WM z)1sxhyBj)Nyt&&>kG#PsF=bH>7-T< z8iAyCyu|}M_09v~CJ#j`L6VyFF36+efiNcu>b91hmeBYW~6B{LvzC0rBUs^hE{1IfW%@@vDpG z#D>R2g~vs%Hbo{USr)yqE+{U3jo%`3PI6dGaeBTbdZA_E;#tKx(Rm54&0HB@GBZCs F;r|kGDY5_n diff --git a/plugins/Toolbox/resources/images/loading.gif b/plugins/Toolbox/resources/images/loading.gif deleted file mode 100644 index 43cc1ed6d72fbe9b118747d3fc3365c469ef5061..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 93386 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 z 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 diff --git a/plugins/Toolbox/resources/images/loading.svg b/plugins/Toolbox/resources/images/loading.svg deleted file mode 100644 index 1ceb4a8d7f..0000000000 --- a/plugins/Toolbox/resources/images/loading.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml b/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml index 933e3a5900..4d4ae92e73 100644 --- a/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml +++ b/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml @@ -62,17 +62,6 @@ Item readyAction() } } - } - - AnimatedImage - { - id: loader - visible: active - source: visible ? "../images/loading.gif" : "" - width: UM.Theme.getSize("toolbox_loader").width - height: UM.Theme.getSize("toolbox_loader").height - anchors.right: button.left - anchors.rightMargin: UM.Theme.getSize("default_margin").width - anchors.verticalCenter: button.verticalCenter + busy: active } } diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index fabdcebc64..6406e83efe 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -130,5 +130,15 @@ Button height: parent.height visible: false + + RotationAnimator + { + target: busyIndicator.contentItem + running: busyIndicator.visible && busyIndicator.running + from: 0 + to: 360 + loops: Animation.Infinite + duration: 2500 + } } } \ No newline at end of file From 81abc84741c161ead9c8a7b7825e7b714ad54292 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 14 Jan 2019 10:41:10 +0100 Subject: [PATCH 1249/1292] Fix typing of CloudOutputDevice in controller --- plugins/UM3NetworkPrinting/src/Cloud/CloudOutputController.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputController.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputController.py index c139be0c38..af98b55587 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputController.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputController.py @@ -1,11 +1,11 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from UM.OutputDevice.OutputDevice import OutputDevice from cura.PrinterOutput.PrinterOutputController import PrinterOutputController +from .CloudOutputDevice import CloudOutputDevice class CloudOutputController(PrinterOutputController): - def __init__(self, output_device: OutputDevice) -> None: + def __init__(self, output_device: CloudOutputDevice) -> None: super().__init__(output_device) # The cloud connection only supports fetching the printer and queue status and adding a job to the queue. From 13d390a7d9dc0949262107fd445e1a10cce24e3e Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 14 Jan 2019 10:43:32 +0100 Subject: [PATCH 1250/1292] Fix imports in tests, some cleanup --- .../tests/Cloud/TestCloudApiClient.py | 17 ++++++++--------- .../tests/Cloud/TestCloudOutputDevice.py | 12 +++++------- .../tests/Cloud/TestCloudOutputDeviceManager.py | 8 ++++---- 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py index acce55751c..fcaa14b055 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py @@ -1,19 +1,18 @@ # Copyright (c) 2018 Ultimaker B.V. # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -import os from typing import List from unittest import TestCase from unittest.mock import patch, MagicMock -from cura.CuraConstants import CuraCloudAPIRoot -from src.Cloud.CloudApiClient import CloudApiClient -from src.Cloud.Models.CloudClusterResponse import CloudClusterResponse -from src.Cloud.Models.CloudClusterStatus import CloudClusterStatus -from src.Cloud.Models.CloudPrintJobResponse import CloudPrintJobResponse -from src.Cloud.Models.CloudPrintJobUploadRequest import CloudPrintJobUploadRequest -from src.Cloud.Models.CloudError import CloudError -from tests.Cloud.Fixtures import readFixture, parseFixture +from cura.UltimakerCloudAuthentication import CuraCloudAPIRoot +from ...src.Cloud.CloudApiClient import CloudApiClient +from ...src.Cloud.Models.CloudClusterResponse import CloudClusterResponse +from ...src.Cloud.Models.CloudClusterStatus import CloudClusterStatus +from ...src.Cloud.Models.CloudPrintJobResponse import CloudPrintJobResponse +from ...src.Cloud.Models.CloudPrintJobUploadRequest import CloudPrintJobUploadRequest +from ...src.Cloud.Models.CloudError import CloudError +from .Fixtures import readFixture, parseFixture from .NetworkManagerMock import NetworkManagerMock diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py index 34e04689c2..0e2220ee04 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py @@ -5,14 +5,12 @@ from unittest import TestCase from unittest.mock import patch, MagicMock from UM.Scene.SceneNode import SceneNode -from UM.Signal import Signal -from cura.CuraApplication import CuraApplication -from cura.CuraConstants import CuraCloudAPIRoot +from cura.UltimakerCloudAuthentication import CuraCloudAPIRoot from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel -from src.Cloud.CloudApiClient import CloudApiClient -from src.Cloud.CloudOutputDevice import CloudOutputDevice -from src.Cloud.Models.CloudClusterResponse import CloudClusterResponse -from tests.Cloud.Fixtures import readFixture, parseFixture +from ...src.Cloud.CloudApiClient import CloudApiClient +from ...src.Cloud.CloudOutputDevice import CloudOutputDevice +from ...src.Cloud.Models.CloudClusterResponse import CloudClusterResponse +from .Fixtures import readFixture, parseFixture from .NetworkManagerMock import NetworkManagerMock diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py index 8b72c9d62d..5388cf152d 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py @@ -4,10 +4,10 @@ from unittest import TestCase from unittest.mock import patch, MagicMock from UM.OutputDevice.OutputDeviceManager import OutputDeviceManager -from cura.CuraConstants import CuraCloudAPIRoot -from src.Cloud.CloudOutputDevice import CloudOutputDevice -from src.Cloud.CloudOutputDeviceManager import CloudOutputDeviceManager -from tests.Cloud.Fixtures import parseFixture, readFixture +from cura.UltimakerCloudAuthentication import CuraCloudAPIRoot +from ...src.Cloud.CloudOutputDevice import CloudOutputDevice +from ...src.Cloud.CloudOutputDeviceManager import CloudOutputDeviceManager +from .Fixtures import parseFixture, readFixture from .NetworkManagerMock import NetworkManagerMock, FakeSignal From 1e2a8aa23e366491bbe0597d3eeca204e27f6b8d Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 14 Jan 2019 10:52:50 +0100 Subject: [PATCH 1251/1292] revert to prevent circular dependency --- plugins/UM3NetworkPrinting/src/Cloud/CloudOutputController.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputController.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputController.py index af98b55587..ec89b1d6c4 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputController.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputController.py @@ -1,11 +1,11 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +from UM.OutputDevice.OutputDevice import OutputDevice from cura.PrinterOutput.PrinterOutputController import PrinterOutputController -from .CloudOutputDevice import CloudOutputDevice class CloudOutputController(PrinterOutputController): - def __init__(self, output_device: CloudOutputDevice) -> None: + def __init__(self, output_device: "OutputDevice") -> None: super().__init__(output_device) # The cloud connection only supports fetching the printer and queue status and adding a job to the queue. From 29bb31729350ebeada5c61be6ade7e16b8499443 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 14 Jan 2019 10:54:28 +0100 Subject: [PATCH 1252/1292] Add a margin to settings panel bottom CURA-6054 --- resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml index edf5d952a5..7c82a7324d 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml @@ -81,7 +81,7 @@ Item Math.min ( UM.Preferences.getValue("view/settings_list_height"), - base.height - (customPrintSetup.mapToItem(null, 0, 0).y + buttonRow.height) + base.height - (customPrintSetup.mapToItem(null, 0, 0).y + buttonRow.height + UM.Theme.getSize("default_margin").height) ); } } From 402097f4d087867906ed2b4e67f484fe552900ed Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 14 Jan 2019 10:57:50 +0100 Subject: [PATCH 1253/1292] Fix imports --- .../src/Cloud/Models/CloudClusterPrintJobStatus.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py index 5d62471710..45b7d838a5 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py @@ -3,17 +3,15 @@ from typing import List, Optional, Union, Dict, Any from cura.PrinterOutput.ConfigurationModel import ConfigurationModel -from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputController import CloudOutputController -from plugins.UM3NetworkPrinting.src.ConfigurationChangeModel import ConfigurationChangeModel +from ...UM3PrintJobOutputModel import UM3PrintJobOutputModel +from ...ConfigurationChangeModel import ConfigurationChangeModel +from ..CloudOutputController import CloudOutputController +from .BaseCloudModel import BaseCloudModel from .CloudClusterBuildPlate import CloudClusterBuildPlate from .CloudClusterPrintJobConfigurationChange import CloudClusterPrintJobConfigurationChange from .CloudClusterPrintJobImpediment import CloudClusterPrintJobImpediment from .CloudClusterPrintCoreConfiguration import CloudClusterPrintCoreConfiguration from .CloudClusterPrintJobConstraint import CloudClusterPrintJobConstraints -from .BaseCloudModel import BaseCloudModel - -## Class representing a print job -from plugins.UM3NetworkPrinting.src.UM3PrintJobOutputModel import UM3PrintJobOutputModel ## Model for the status of a single print job in a cluster. From cd19eec98a8e69f0f454276ae7be8e6d8e62b95c Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 14 Jan 2019 11:06:16 +0100 Subject: [PATCH 1254/1292] Remove weird argument for timer --- .../UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index f9bd635bbd..c282463e55 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -42,7 +42,7 @@ class CloudOutputDeviceManager: self._api = CloudApiClient(self._account, self._onApiError) # Create a timer to update the remote cluster list - self._update_timer = QTimer(application) + self._update_timer = QTimer() self._update_timer.setInterval(int(self.CHECK_CLUSTER_INTERVAL * 1000)) self._update_timer.setSingleShot(False) From b2dace2d4840cc661034f4fcf76189c0afce0c2a Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 14 Jan 2019 11:24:59 +0100 Subject: [PATCH 1255/1292] Fix version upgrade CURA-6113 --- cura/CuraApplication.py | 2 +- .../VersionUpgrade40to41/__init__.py | 34 +++++++++++++++---- plugins/XmlMaterialProfile/__init__.py | 2 +- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 0d71dff106..57b5dd1b42 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -145,7 +145,7 @@ class CuraApplication(QtApplication): # SettingVersion represents the set of settings available in the machine/extruder definitions. # You need to make sure that this version number needs to be increased if there is any non-backwards-compatible # changes of the settings. - SettingVersion = 6 + SettingVersion = 7 Created = False diff --git a/plugins/VersionUpgrade/VersionUpgrade40to41/__init__.py b/plugins/VersionUpgrade/VersionUpgrade40to41/__init__.py index 757a7a51c0..7f39bb9d39 100644 --- a/plugins/VersionUpgrade/VersionUpgrade40to41/__init__.py +++ b/plugins/VersionUpgrade/VersionUpgrade40to41/__init__.py @@ -14,15 +14,19 @@ def getMetaData() -> Dict[str, Any]: return { "version_upgrade": { # From To Upgrade function - ("machine_stack", 4000005): ("machine_stack", 4000006, upgrade.upgradeStack), - ("extruder_train", 4000005): ("extruder_train", 4000006, upgrade.upgradeStack), - ("preferences", 6000005): ("preferences", 6000006, upgrade.upgradePreferences), - ("definition_changes", 4000005): ("definition_changes", 4000006, upgrade.upgradeInstanceContainer), - ("quality_changes", 4000005): ("quality_changes", 4000006, upgrade.upgradeInstanceContainer), - ("quality", 4000005): ("quality", 4000006, upgrade.upgradeInstanceContainer), - ("user", 4000005): ("user", 4000006, upgrade.upgradeInstanceContainer), + ("preferences", 6000006): ("preferences", 6000007, upgrade.upgradePreferences), + ("machine_stack", 4000006): ("machine_stack", 4000007, upgrade.upgradeStack), + ("extruder_train", 4000006): ("extruder_train", 4000007, upgrade.upgradeStack), + ("definition_changes", 4000006): ("definition_changes", 4000007, upgrade.upgradeInstanceContainer), + ("quality_changes", 4000006): ("quality_changes", 4000007, upgrade.upgradeInstanceContainer), + ("quality", 4000006): ("quality", 4000007, upgrade.upgradeInstanceContainer), + ("user", 4000006): ("user", 4000007, upgrade.upgradeInstanceContainer), }, "sources": { + "preferences": { + "get_version": upgrade.getCfgVersion, + "location": {"."} + }, "machine_stack": { "get_version": upgrade.getCfgVersion, "location": {"./machine_instances"} @@ -30,6 +34,22 @@ def getMetaData() -> Dict[str, Any]: "extruder_train": { "get_version": upgrade.getCfgVersion, "location": {"./extruders"} + }, + "definition_changes": { + "get_version": upgrade.getCfgVersion, + "location": {"./definition_changes"} + }, + "quality_changes": { + "get_version": upgrade.getCfgVersion, + "location": {"./quality_changes"} + }, + "quality": { + "get_version": upgrade.getCfgVersion, + "location": {"./quality"} + }, + "user": { + "get_version": upgrade.getCfgVersion, + "location": {"./user"} } } } diff --git a/plugins/XmlMaterialProfile/__init__.py b/plugins/XmlMaterialProfile/__init__.py index c50df69516..b3810c97dc 100644 --- a/plugins/XmlMaterialProfile/__init__.py +++ b/plugins/XmlMaterialProfile/__init__.py @@ -16,7 +16,7 @@ def getMetaData(): "mimetype": "application/x-ultimaker-material-profile" }, "version_upgrade": { - ("materials", 1000000): ("materials", 1000006, upgrader.upgradeMaterial), + ("materials", 1000000): ("materials", 1000007, upgrader.upgradeMaterial), }, "sources": { "materials": { From 71036abd870ce0b517b5c8636a6444505cd9cff1 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 14 Jan 2019 12:11:41 +0100 Subject: [PATCH 1256/1292] Add troubleshooting link for recommended CURA-6114 --- .../Recommended/RecommendedPrintSetup.qml | 5 +++ .../RecommendedTroubleshootingGuides.qml | 36 +++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 resources/qml/PrintSetupSelector/Recommended/RecommendedTroubleshootingGuides.qml diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml index 6885f8c041..44b3abf7cd 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedPrintSetup.qml @@ -68,6 +68,11 @@ Item // TODO Create a reusable component with these properties to not define them separately for each component labelColumnWidth: parent.firstColumnWidth } + + RecommendedTroubleshootingGuides + { + width: parent.width + } } UM.SettingPropertyProvider diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedTroubleshootingGuides.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedTroubleshootingGuides.qml new file mode 100644 index 0000000000..846e343028 --- /dev/null +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedTroubleshootingGuides.qml @@ -0,0 +1,36 @@ +// Copyright (c) 2019 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.10 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 + +import UM 1.2 as UM +import Cura 1.0 as Cura + + +Item +{ + id: tipsCell + anchors.top: adhesionCheckBox.visible ? adhesionCheckBox.bottom : (enableSupportCheckBox.visible ? supportExtruderCombobox.bottom : infillCellRight.bottom) + anchors.topMargin: Math.round(UM.Theme.getSize("sidebar_margin").height * 2) + anchors.left: parent.left + width: parent.width + height: tipsText.contentHeight * tipsText.lineCount + + Label + { + id: tipsText + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width + anchors.right: parent.right + anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width + anchors.top: parent.top + wrapMode: Text.WordWrap + text: catalog.i18nc("@label", "Need help improving your prints?
    Read the Ultimaker Troubleshooting Guides").arg("https://ultimaker.com/en/troubleshooting") + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + linkColor: UM.Theme.getColor("text_link") + onLinkActivated: Qt.openUrlExternally(link) + } +} \ No newline at end of file From 9d94b55596ea9b805d9088b46a498d7a648fe09a Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 14 Jan 2019 13:35:10 +0100 Subject: [PATCH 1257/1292] Ensure that the toolbox correctly handles multiple supported SDK versions CURA-6087 --- plugins/Toolbox/src/Toolbox.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 192471a357..ccd181cdbc 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -235,12 +235,17 @@ class Toolbox(QObject, Extension): def _convertPluginMetadata(self, plugin_data: Dict[str, Any]) -> Optional[Dict[str, Any]]: try: + highest_sdk_version_supported = Version(0) + for supported_version in plugin_data["plugin"]["supported_sdk_versions"]: + if supported_version > highest_sdk_version_supported: + highest_sdk_version_supported = supported_version + formatted = { "package_id": plugin_data["id"], "package_type": "plugin", "display_name": plugin_data["plugin"]["name"], "package_version": plugin_data["plugin"]["version"], - "sdk_version": plugin_data["plugin"]["api"], + "sdk_version": highest_sdk_version_supported, "author": { "author_id": plugin_data["plugin"]["author"], "display_name": plugin_data["plugin"]["author"] From b1b61fa466eafa51121ce7a276dc2046d5f38ea7 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 14 Jan 2019 14:14:47 +0100 Subject: [PATCH 1258/1292] Add missing return --- resources/qml/PrinterSelector/MachineSelector.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index 0a2e304efc..4bee917751 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -30,7 +30,7 @@ Cura.ExpandablePopup { if (isNetworkPrinter && Cura.MachineManager.activeMachineNetworkGroupName != "") { - Cura.MachineManager.activeMachineNetworkGroupName + return Cura.MachineManager.activeMachineNetworkGroupName } return Cura.MachineManager.activeMachineName } From 7bf319dfd12ce82385ff2c290dfdceb64921b778 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 14 Jan 2019 14:17:36 +0100 Subject: [PATCH 1259/1292] Better fix for circular dependency --- .../UM3NetworkPrinting/src/Cloud/CloudOutputController.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputController.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputController.py index ec89b1d6c4..bd56ef3185 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputController.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputController.py @@ -1,11 +1,14 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from UM.OutputDevice.OutputDevice import OutputDevice from cura.PrinterOutput.PrinterOutputController import PrinterOutputController +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from .CloudOutputDevice import CloudOutputDevice + class CloudOutputController(PrinterOutputController): - def __init__(self, output_device: "OutputDevice") -> None: + def __init__(self, output_device: "CloudOutputDevice") -> None: super().__init__(output_device) # The cloud connection only supports fetching the printer and queue status and adding a job to the queue. From f478653c371ee9a97fc1f44bdb78421f108d1afe Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 14 Jan 2019 14:56:14 +0100 Subject: [PATCH 1260/1292] Uncomment code that was needed for testing --- plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index 84740ae856..b48f9380e1 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -389,9 +389,8 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): ## Called when the connection to the cluster changes. def connect(self) -> None: - # super().connect() - # self.sendMaterialProfiles() - pass + super().connect() + self.sendMaterialProfiles() def _onGetPreviewImageFinished(self, reply: QNetworkReply) -> None: reply_url = reply.url().toString() From fa7b38243c8a8fd16d9fdfd98220200abd57a773 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 14 Jan 2019 17:02:02 +0100 Subject: [PATCH 1261/1292] Add VersionUpgrade35to40 as a bundled package Otherwise it will show up as an old plugin and the uninstall button will appear in the Markeplace. --- resources/bundled_packages/cura.json | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/resources/bundled_packages/cura.json b/resources/bundled_packages/cura.json index 172b27b452..07a1ae5276 100644 --- a/resources/bundled_packages/cura.json +++ b/resources/bundled_packages/cura.json @@ -730,6 +730,23 @@ } } }, + "VersionUpgrade35to40": { + "package_info": { + "package_id": "VersionUpgrade35to40", + "package_type": "plugin", + "display_name": "Version Upgrade 3.5 to 4.0", + "description": "Upgrades configurations from Cura 3.5 to Cura 4.0.", + "package_version": "1.0.0", + "sdk_version": "6.0", + "website": "https://ultimaker.com", + "author": { + "author_id": "UltimakerPackages", + "display_name": "Ultimaker B.V.", + "email": "plugins@ultimaker.com", + "website": "https://ultimaker.com" + } + } + }, "X3DReader": { "package_info": { "package_id": "X3DReader", From f16735a5bed7c905016c32352b433a5353d4482c Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Mon, 14 Jan 2019 17:10:52 +0100 Subject: [PATCH 1262/1292] Add VersionUpgrade40to41 as a bundled package Otherwise it will show up as an old plugin and the uninstall button will appear in the Markeplace. --- resources/bundled_packages/cura.json | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/resources/bundled_packages/cura.json b/resources/bundled_packages/cura.json index 709ffd66e6..21da1d9fdb 100644 --- a/resources/bundled_packages/cura.json +++ b/resources/bundled_packages/cura.json @@ -747,6 +747,23 @@ } } }, + "VersionUpgrade40to41": { + "package_info": { + "package_id": "VersionUpgrade40to41", + "package_type": "plugin", + "display_name": "Version Upgrade 4.0 to 4.1", + "description": "Upgrades configurations from Cura 4.0 to Cura 4.1.", + "package_version": "1.0.1", + "sdk_version": "6.0", + "website": "https://ultimaker.com", + "author": { + "author_id": "UltimakerPackages", + "display_name": "Ultimaker B.V.", + "email": "plugins@ultimaker.com", + "website": "https://ultimaker.com" + } + } + }, "X3DReader": { "package_info": { "package_id": "X3DReader", From 77c30c891f92d68e00dde62044317c90b978a706 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Tue, 15 Jan 2019 08:20:39 +0100 Subject: [PATCH 1263/1292] Fix tests --- cura/UltimakerCloudAuthentication.py | 2 +- .../src/Cloud/CloudOutputDeviceManager.py | 2 +- .../src/Cloud/CloudProgressMessage.py | 5 ++++ .../tests/Cloud/TestCloudApiClient.py | 2 +- .../tests/Cloud/TestCloudOutputDevice.py | 3 +- .../Cloud/TestCloudOutputDeviceManager.py | 30 ++++++++----------- 6 files changed, 23 insertions(+), 21 deletions(-) diff --git a/cura/UltimakerCloudAuthentication.py b/cura/UltimakerCloudAuthentication.py index 5f69329dbb..69bb577354 100644 --- a/cura/UltimakerCloudAuthentication.py +++ b/cura/UltimakerCloudAuthentication.py @@ -5,7 +5,7 @@ # Constants used for the Cloud API # --------- DEFAULT_CLOUD_API_ROOT = "https://api.ultimaker.com" # type: str -DEFAULT_CLOUD_API_VERSION = 1 # type: int +DEFAULT_CLOUD_API_VERSION = "1" # type: str DEFAULT_CLOUD_ACCOUNT_API_ROOT = "https://account.ultimaker.com" # type: str try: diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index c282463e55..237947b21e 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -101,7 +101,7 @@ class CloudOutputDeviceManager: if not active_machine: return - # Remove all output devices that we have registered. + # Remove all output devices that we have registered. TODO: Why?? for stored_cluster_id in self._remote_clusters: self._output_device_manager.removeOutputDevice(stored_cluster_id) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudProgressMessage.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudProgressMessage.py index d85f49c1a0..32aa6044d3 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudProgressMessage.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudProgressMessage.py @@ -19,6 +19,11 @@ class CloudProgressMessage(Message): use_inactivity_timer = False ) + ## Returns a boolean indicating whether this message is currently visible + @property + def visible(self) -> bool: + return self._visible + ## Shows the progress message. def show(self): self.setProgress(0) diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py index fcaa14b055..0be1d82141 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py @@ -28,7 +28,7 @@ class TestCloudApiClient(TestCase): self.account.isLoggedIn.return_value = True self.network = NetworkManagerMock() - with patch("src.Cloud.CloudApiClient.QNetworkAccessManager", return_value = self.network): + with patch("plugins.UM3NetworkPrinting.src.Cloud.CloudApiClient.QNetworkAccessManager", return_value = self.network): self.api = CloudApiClient(self.account, self._errorHandler) def test_getClusters(self): diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py index 0e2220ee04..191b92bdd5 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py @@ -41,7 +41,8 @@ class TestCloudOutputDevice(TestCase): self.network = NetworkManagerMock() self.account = MagicMock(isLoggedIn=True, accessToken="TestAccessToken") self.onError = MagicMock() - with patch("src.Cloud.CloudApiClient.QNetworkAccessManager", return_value = self.network): + with patch("plugins.UM3NetworkPrinting.src.Cloud.CloudApiClient.QNetworkAccessManager", + return_value = self.network): self._api = CloudApiClient(self.account, self.onError) self.device = CloudOutputDevice(self._api, self.cluster) diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py index 5388cf152d..c5006f35a1 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py @@ -5,7 +5,6 @@ from unittest.mock import patch, MagicMock from UM.OutputDevice.OutputDeviceManager import OutputDeviceManager from cura.UltimakerCloudAuthentication import CuraCloudAPIRoot -from ...src.Cloud.CloudOutputDevice import CloudOutputDevice from ...src.Cloud.CloudOutputDeviceManager import CloudOutputDeviceManager from .Fixtures import parseFixture, readFixture from .NetworkManagerMock import NetworkManagerMock, FakeSignal @@ -29,8 +28,10 @@ class TestCloudOutputDeviceManager(TestCase): self.network = NetworkManagerMock() self.timer = MagicMock(timeout = FakeSignal()) - with patch("src.Cloud.CloudApiClient.QNetworkAccessManager", return_value = self.network), \ - patch("src.Cloud.CloudOutputDeviceManager.QTimer", return_value = self.timer): + with patch("plugins.UM3NetworkPrinting.src.Cloud.CloudApiClient.QNetworkAccessManager", + return_value = self.network), \ + patch("plugins.UM3NetworkPrinting.src.Cloud.CloudOutputDeviceManager.QTimer", + return_value = self.timer): self.manager = CloudOutputDeviceManager() self.clusters_response = parseFixture("getClusters") self.network.prepareReply("GET", self.URL, 200, readFixture("getClusters")) @@ -53,16 +54,12 @@ class TestCloudOutputDeviceManager(TestCase): self.network.flushReplies() # get the created devices devices = self.device_manager.getOutputDevices() - # get the server data - clusters = self.clusters_response.get("data", []) - self.assertEqual([CloudOutputDevice] * len(clusters), [type(d) for d in devices]) - self.assertEqual({cluster["cluster_id"] for cluster in clusters}, {device.key for device in devices}) - self.assertEqual(clusters, sorted((device.clusterData.toDict() for device in devices), - key=lambda device_dict: device_dict["host_version"])) + # TODO: Check active device - for device in clusters: - self.device_manager.getOutputDevice(device["cluster_id"]).close() - self.device_manager.removeOutputDevice(device["cluster_id"]) + response_clusters = self.clusters_response.get("data", []) + manager_clusters = sorted([device.clusterData.toDict() for device in self.manager._remote_clusters.values()], + key=lambda cluster: cluster['cluster_id'], reverse=True) + self.assertEqual(response_clusters, manager_clusters) ## Runs the initial request to retrieve the clusters. def _loadData(self): @@ -100,7 +97,7 @@ class TestCloudOutputDeviceManager(TestCase): self._loadData() self.assertTrue(self.device_manager.getOutputDevice(cluster1["cluster_id"]).isConnected()) - self.assertFalse(self.device_manager.getOutputDevice(cluster2["cluster_id"]).isConnected()) + self.assertIsNone(self.device_manager.getOutputDevice(cluster2["cluster_id"])) self.assertEquals([], active_machine_mock.setMetaDataEntry.mock_calls) def test_device_connects_by_network_key(self): @@ -112,13 +109,12 @@ class TestCloudOutputDeviceManager(TestCase): self._loadData() - self.assertEqual([False, True], - [self.device_manager.getOutputDevice(cluster["cluster_id"]).isConnected() - for cluster in (cluster1, cluster2)]) + self.assertIsNone(self.device_manager.getOutputDevice(cluster1["cluster_id"])) + self.assertTrue(self.device_manager.getOutputDevice(cluster2["cluster_id"]).isConnected()) active_machine_mock.setMetaDataEntry.assert_called_with("um_cloud_cluster_id", cluster2["cluster_id"]) - @patch("src.Cloud.CloudOutputDeviceManager.Message") + @patch("plugins.UM3NetworkPrinting.src.Cloud.CloudOutputDeviceManager.Message") def test_api_error(self, message_mock): self.clusters_response = { "errors": [{"id": "notFound", "title": "Not found!", "http_status": "404", "code": "notFound"}] From 7785555a943b600636809ae5c5e50cabecdd79fd Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Tue, 15 Jan 2019 08:21:17 +0100 Subject: [PATCH 1264/1292] Remove mock changes used locally --- .../UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py | 2 +- .../UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py | 2 +- .../tests/Cloud/TestCloudOutputDeviceManager.py | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py index 0be1d82141..fcaa14b055 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py @@ -28,7 +28,7 @@ class TestCloudApiClient(TestCase): self.account.isLoggedIn.return_value = True self.network = NetworkManagerMock() - with patch("plugins.UM3NetworkPrinting.src.Cloud.CloudApiClient.QNetworkAccessManager", return_value = self.network): + with patch("src.Cloud.CloudApiClient.QNetworkAccessManager", return_value = self.network): self.api = CloudApiClient(self.account, self._errorHandler) def test_getClusters(self): diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py index 191b92bdd5..1a72c170d3 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py @@ -41,7 +41,7 @@ class TestCloudOutputDevice(TestCase): self.network = NetworkManagerMock() self.account = MagicMock(isLoggedIn=True, accessToken="TestAccessToken") self.onError = MagicMock() - with patch("plugins.UM3NetworkPrinting.src.Cloud.CloudApiClient.QNetworkAccessManager", + with patch("src.Cloud.CloudApiClient.QNetworkAccessManager", return_value = self.network): self._api = CloudApiClient(self.account, self.onError) diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py index c5006f35a1..6fe17f7759 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py @@ -28,9 +28,9 @@ class TestCloudOutputDeviceManager(TestCase): self.network = NetworkManagerMock() self.timer = MagicMock(timeout = FakeSignal()) - with patch("plugins.UM3NetworkPrinting.src.Cloud.CloudApiClient.QNetworkAccessManager", + with patch("src.Cloud.CloudApiClient.QNetworkAccessManager", return_value = self.network), \ - patch("plugins.UM3NetworkPrinting.src.Cloud.CloudOutputDeviceManager.QTimer", + patch("src.Cloud.CloudOutputDeviceManager.QTimer", return_value = self.timer): self.manager = CloudOutputDeviceManager() self.clusters_response = parseFixture("getClusters") @@ -114,7 +114,7 @@ class TestCloudOutputDeviceManager(TestCase): active_machine_mock.setMetaDataEntry.assert_called_with("um_cloud_cluster_id", cluster2["cluster_id"]) - @patch("plugins.UM3NetworkPrinting.src.Cloud.CloudOutputDeviceManager.Message") + @patch("src.Cloud.CloudOutputDeviceManager.Message") def test_api_error(self, message_mock): self.clusters_response = { "errors": [{"id": "notFound", "title": "Not found!", "http_status": "404", "code": "notFound"}] From de24c7d9c34e5bd80e6311e4d1c7ea1e1eaaea98 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 15 Jan 2019 09:35:28 +0100 Subject: [PATCH 1265/1292] Revert "Remove mock changes used locally" This reverts commit 7785555a943b600636809ae5c5e50cabecdd79fd. --- .../UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py | 2 +- .../UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py | 2 +- .../tests/Cloud/TestCloudOutputDeviceManager.py | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py index fcaa14b055..0be1d82141 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py @@ -28,7 +28,7 @@ class TestCloudApiClient(TestCase): self.account.isLoggedIn.return_value = True self.network = NetworkManagerMock() - with patch("src.Cloud.CloudApiClient.QNetworkAccessManager", return_value = self.network): + with patch("plugins.UM3NetworkPrinting.src.Cloud.CloudApiClient.QNetworkAccessManager", return_value = self.network): self.api = CloudApiClient(self.account, self._errorHandler) def test_getClusters(self): diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py index 1a72c170d3..191b92bdd5 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py @@ -41,7 +41,7 @@ class TestCloudOutputDevice(TestCase): self.network = NetworkManagerMock() self.account = MagicMock(isLoggedIn=True, accessToken="TestAccessToken") self.onError = MagicMock() - with patch("src.Cloud.CloudApiClient.QNetworkAccessManager", + with patch("plugins.UM3NetworkPrinting.src.Cloud.CloudApiClient.QNetworkAccessManager", return_value = self.network): self._api = CloudApiClient(self.account, self.onError) diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py index 6fe17f7759..c5006f35a1 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py @@ -28,9 +28,9 @@ class TestCloudOutputDeviceManager(TestCase): self.network = NetworkManagerMock() self.timer = MagicMock(timeout = FakeSignal()) - with patch("src.Cloud.CloudApiClient.QNetworkAccessManager", + with patch("plugins.UM3NetworkPrinting.src.Cloud.CloudApiClient.QNetworkAccessManager", return_value = self.network), \ - patch("src.Cloud.CloudOutputDeviceManager.QTimer", + patch("plugins.UM3NetworkPrinting.src.Cloud.CloudOutputDeviceManager.QTimer", return_value = self.timer): self.manager = CloudOutputDeviceManager() self.clusters_response = parseFixture("getClusters") @@ -114,7 +114,7 @@ class TestCloudOutputDeviceManager(TestCase): active_machine_mock.setMetaDataEntry.assert_called_with("um_cloud_cluster_id", cluster2["cluster_id"]) - @patch("src.Cloud.CloudOutputDeviceManager.Message") + @patch("plugins.UM3NetworkPrinting.src.Cloud.CloudOutputDeviceManager.Message") def test_api_error(self, message_mock): self.clusters_response = { "errors": [{"id": "notFound", "title": "Not found!", "http_status": "404", "code": "notFound"}] From b7fb969524fc8dbb3ebbe66b26a2598c9791cfba Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 15 Jan 2019 09:37:38 +0100 Subject: [PATCH 1266/1292] Fixes for review --- .../UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py | 4 +++- plugins/UM3NetworkPrinting/src/Cloud/CloudProgressMessage.py | 5 ----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 237947b21e..541b30b05d 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -101,7 +101,9 @@ class CloudOutputDeviceManager: if not active_machine: return - # Remove all output devices that we have registered. TODO: Why?? + # Remove all output devices that we have registered. + # This is needed because when we switch machines we can only leave + # output devices that are meant for that machine. for stored_cluster_id in self._remote_clusters: self._output_device_manager.removeOutputDevice(stored_cluster_id) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudProgressMessage.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudProgressMessage.py index 32aa6044d3..d85f49c1a0 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudProgressMessage.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudProgressMessage.py @@ -19,11 +19,6 @@ class CloudProgressMessage(Message): use_inactivity_timer = False ) - ## Returns a boolean indicating whether this message is currently visible - @property - def visible(self) -> bool: - return self._visible - ## Shows the progress message. def show(self): self.setProgress(0) From d4b47c75abf8fe3445b9b906b45d2af0b84a5cfb Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 15 Jan 2019 11:15:37 +0100 Subject: [PATCH 1268/1292] Fix typo in multiply message --- cura/MultiplyObjectsJob.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/MultiplyObjectsJob.py b/cura/MultiplyObjectsJob.py index 3cbf795952..e71bbf6668 100644 --- a/cura/MultiplyObjectsJob.py +++ b/cura/MultiplyObjectsJob.py @@ -25,7 +25,7 @@ class MultiplyObjectsJob(Job): def run(self): status_message = Message(i18n_catalog.i18nc("@info:status", "Multiplying and placing objects"), lifetime=0, - dismissable=False, progress=0, title = i18n_catalog.i18nc("@info:title", "Placing Object")) + dismissable=False, progress=0, title = i18n_catalog.i18nc("@info:title", "Placing Objects")) status_message.show() scene = Application.getInstance().getController().getScene() From d8850f49462eaf0668cf35d9de46815623434a9d Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 15 Jan 2019 11:36:08 +0100 Subject: [PATCH 1269/1292] Fix version upgrade 40 to 41 to set setting_version 7 CURA-6113 --- .../VersionUpgrade40to41/VersionUpgrade40to41.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/VersionUpgrade/VersionUpgrade40to41/VersionUpgrade40to41.py b/plugins/VersionUpgrade/VersionUpgrade40to41/VersionUpgrade40to41.py index ac54b7c8e0..d80e0007aa 100644 --- a/plugins/VersionUpgrade/VersionUpgrade40to41/VersionUpgrade40to41.py +++ b/plugins/VersionUpgrade/VersionUpgrade40to41/VersionUpgrade40to41.py @@ -47,7 +47,7 @@ class VersionUpgrade40to41(VersionUpgrade): # Update version number. parser["general"]["version"] = "4" - parser["metadata"]["setting_version"] = "6" + parser["metadata"]["setting_version"] = "7" result = io.StringIO() parser.write(result) @@ -62,7 +62,7 @@ class VersionUpgrade40to41(VersionUpgrade): parser["general"]["version"] = "6" if "metadata" not in parser: parser["metadata"] = {} - parser["metadata"]["setting_version"] = "6" + parser["metadata"]["setting_version"] = "7" result = io.StringIO() parser.write(result) @@ -75,7 +75,7 @@ class VersionUpgrade40to41(VersionUpgrade): # Update version number. parser["general"]["version"] = "4" - parser["metadata"]["setting_version"] = "6" + parser["metadata"]["setting_version"] = "7" #Update the name of the quality profile. if parser["containers"]["4"] in _renamed_quality_profiles: @@ -83,4 +83,4 @@ class VersionUpgrade40to41(VersionUpgrade): result = io.StringIO() parser.write(result) - return [filename], [result.getvalue()] \ No newline at end of file + return [filename], [result.getvalue()] From a702661b5de80bbd1d0ef3063b5c0f16608992f2 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 15 Jan 2019 14:17:38 +0100 Subject: [PATCH 1270/1292] Decrease the API call intervals to get quicker UI updates --- plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py | 2 +- .../UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 2947cd421c..33968beb6d 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -44,7 +44,7 @@ I18N_CATALOG = i18nCatalog("cura") class CloudOutputDevice(NetworkedPrinterOutputDevice): # The interval with which the remote clusters are checked - CHECK_CLUSTER_INTERVAL = 20.0 # seconds + CHECK_CLUSTER_INTERVAL = 10.0 # seconds # Signal triggered when the print jobs in the queue were changed. printJobsChanged = pyqtSignal() diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 541b30b05d..f9a0a59c81 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -26,7 +26,7 @@ class CloudOutputDeviceManager: META_CLUSTER_ID = "um_cloud_cluster_id" # The interval with which the remote clusters are checked - CHECK_CLUSTER_INTERVAL = 50.0 # seconds + CHECK_CLUSTER_INTERVAL = 30.0 # seconds # The translation catalog for this device. I18N_CATALOG = i18nCatalog("cura") From f057c9a7dfaa908100db71eb1b577ceca083b5fc Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Tue, 15 Jan 2019 17:15:12 +0100 Subject: [PATCH 1271/1292] Prevent spurious updates to 'onPreferenceChanged's if the preference doesn't match. --- plugins/SimulationView/SimulationViewMainComponent.qml | 5 +++++ plugins/SimulationView/SimulationViewMenuComponent.qml | 5 +++++ resources/qml/ActionPanel/SliceProcessWidget.qml | 5 +++++ resources/qml/Preferences/GeneralPage.qml | 5 +++++ .../qml/Preferences/Materials/MaterialsBrandSection.qml | 5 +++++ resources/qml/Preferences/Materials/MaterialsTypeSection.qml | 5 +++++ .../qml/PrintSetupSelector/PrintSetupSelectorContents.qml | 5 +++++ 7 files changed, 35 insertions(+) diff --git a/plugins/SimulationView/SimulationViewMainComponent.qml b/plugins/SimulationView/SimulationViewMainComponent.qml index 16b049c921..58901652d3 100644 --- a/plugins/SimulationView/SimulationViewMainComponent.qml +++ b/plugins/SimulationView/SimulationViewMainComponent.qml @@ -71,6 +71,11 @@ Item target: UM.Preferences onPreferenceChanged: { + if (preference !== "view/only_show_top_layers" && preference !== "view/top_layer_count" && ! preference.match("layerview/")) + { + return; + } + playButton.pauseSimulation() } } diff --git a/plugins/SimulationView/SimulationViewMenuComponent.qml b/plugins/SimulationView/SimulationViewMenuComponent.qml index 4c952d4c43..957d8170cf 100644 --- a/plugins/SimulationView/SimulationViewMenuComponent.qml +++ b/plugins/SimulationView/SimulationViewMenuComponent.qml @@ -22,6 +22,11 @@ Cura.ExpandableComponent target: UM.Preferences onPreferenceChanged: { + if (preference !== "view/only_show_top_layers" && preference !== "view/top_layer_count" && ! preference.match("layerview/")) + { + return; + } + layerTypeCombobox.currentIndex = UM.SimulationView.compatibilityMode ? 1 : UM.Preferences.getValue("layerview/layer_view_type") layerTypeCombobox.updateLegends(layerTypeCombobox.currentIndex) viewSettings.extruder_opacities = UM.Preferences.getValue("layerview/extruder_opacities").split("|") diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index 08966ce82c..21d6fac2d8 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -142,6 +142,11 @@ Column target: UM.Preferences onPreferenceChanged: { + if (preference !== "general/auto_slice") + { + return; + } + var autoSlice = UM.Preferences.getValue("general/auto_slice") if(prepareButtons.autoSlice != autoSlice) { diff --git a/resources/qml/Preferences/GeneralPage.qml b/resources/qml/Preferences/GeneralPage.qml index 5ff5f567ea..0dd6c6313a 100644 --- a/resources/qml/Preferences/GeneralPage.qml +++ b/resources/qml/Preferences/GeneralPage.qml @@ -746,6 +746,11 @@ UM.PreferencesPage target: UM.Preferences onPreferenceChanged: { + if (preference !== "info/send_slice_info") + { + return; + } + sendDataCheckbox.checked = boolCheck(UM.Preferences.getValue("info/send_slice_info")) } } diff --git a/resources/qml/Preferences/Materials/MaterialsBrandSection.qml b/resources/qml/Preferences/Materials/MaterialsBrandSection.qml index c976233805..8db8e99d44 100644 --- a/resources/qml/Preferences/Materials/MaterialsBrandSection.qml +++ b/resources/qml/Preferences/Materials/MaterialsBrandSection.qml @@ -139,6 +139,11 @@ Item target: UM.Preferences onPreferenceChanged: { + if (preference !== "cura/expanded_types" && preference !== "cura/expanded_brands") + { + return; + } + expanded = materialList.expandedBrands.indexOf(sectionName) > -1 } } diff --git a/resources/qml/Preferences/Materials/MaterialsTypeSection.qml b/resources/qml/Preferences/Materials/MaterialsTypeSection.qml index 8f34217cce..b5054591c0 100644 --- a/resources/qml/Preferences/Materials/MaterialsTypeSection.qml +++ b/resources/qml/Preferences/Materials/MaterialsTypeSection.qml @@ -130,6 +130,11 @@ Item target: UM.Preferences onPreferenceChanged: { + if (preference !== "cura/expanded_types" && preference !== "cura/expanded_brands") + { + return; + } + expanded = materialList.expandedTypes.indexOf(materialType.brand + "_" + materialType.name) > -1 } } diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml index 7c82a7324d..e5de8bfb7d 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml @@ -77,6 +77,11 @@ Item target: UM.Preferences onPreferenceChanged: { + if (preference !== "view/settings_list_height" && preference !== "general/window_height" && preference !== "general/window_state") + { + return; + } + customPrintSetup.height = Math.min ( From 1b7b302f42f82f2a5424d969b370d896febacc33 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 15 Jan 2019 17:31:51 +0100 Subject: [PATCH 1272/1292] Fix some typos --- cura/Scene/ConvexHullDecorator.py | 2 +- cura/Scene/ConvexHullNode.py | 2 +- plugins/ChangeLogPlugin/ChangeLog.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cura/Scene/ConvexHullDecorator.py b/cura/Scene/ConvexHullDecorator.py index 661106dec7..9bdb6a2c0e 100644 --- a/cura/Scene/ConvexHullDecorator.py +++ b/cura/Scene/ConvexHullDecorator.py @@ -242,7 +242,7 @@ class ConvexHullDecorator(SceneNodeDecorator): # See http://stackoverflow.com/questions/16970982/find-unique-rows-in-numpy-array vertex_byte_view = numpy.ascontiguousarray(vertex_data).view( numpy.dtype((numpy.void, vertex_data.dtype.itemsize * vertex_data.shape[1]))) - _, idx = numpy.unique(vertex_byte_view, return_index=True) + _, idx = numpy.unique(vertex_byte_view, return_index = True) vertex_data = vertex_data[idx] # Select the unique rows by index. hull = Polygon(vertex_data) diff --git a/cura/Scene/ConvexHullNode.py b/cura/Scene/ConvexHullNode.py index 886ed93ad3..90bf536308 100644 --- a/cura/Scene/ConvexHullNode.py +++ b/cura/Scene/ConvexHullNode.py @@ -54,7 +54,7 @@ class ConvexHullNode(SceneNode): if hull_mesh_builder.addConvexPolygonExtrusion( self._hull.getPoints()[::-1], # bottom layer is reversed - self._mesh_height-thickness, self._mesh_height, color=self._color): + self._mesh_height - thickness, self._mesh_height, color = self._color): hull_mesh = hull_mesh_builder.build() self.setMeshData(hull_mesh) diff --git a/plugins/ChangeLogPlugin/ChangeLog.txt b/plugins/ChangeLogPlugin/ChangeLog.txt index 7e5cf2dd3b..651abb0cac 100755 --- a/plugins/ChangeLogPlugin/ChangeLog.txt +++ b/plugins/ChangeLogPlugin/ChangeLog.txt @@ -943,7 +943,7 @@ This release adds support for printers with elliptic buildplates. This feature h *AppImage for Linux The Linux distribution is now in AppImage format, which makes Cura easier to install. -*bugfixes +*Bugfixes The user is now notified when a new version of Cura is available. When searching in the setting visibility preferences, the category for each setting is always displayed. 3MF files are now saved and loaded correctly. From d9a8bb0eb7940b4c606627275a6572b8ca4ccdfa Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Wed, 16 Jan 2019 15:18:04 +0100 Subject: [PATCH 1273/1292] Remove empty init py in plugins dir --- plugins/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 plugins/__init__.py diff --git a/plugins/__init__.py b/plugins/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 From 04ff27c5f3f54406f9f7d6b177f8b56a6a8a2912 Mon Sep 17 00:00:00 2001 From: TiZYX Date: Wed, 16 Jan 2019 15:28:00 +0100 Subject: [PATCH 1274/1292] Update tizyx_k25_normal.inst.cfg --- resources/quality/tizyx_k25/tizyx_k25_normal.inst.cfg | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/quality/tizyx_k25/tizyx_k25_normal.inst.cfg b/resources/quality/tizyx_k25/tizyx_k25_normal.inst.cfg index d38f094d1a..f223d0ce76 100644 --- a/resources/quality/tizyx_k25/tizyx_k25_normal.inst.cfg +++ b/resources/quality/tizyx_k25/tizyx_k25_normal.inst.cfg @@ -20,7 +20,6 @@ material_diameter = 1.75 retraction_amount = 2.5 retraction_min_travel = 2 retraction_speed = 30 -skin_angles = [] speed_print = 60 speed_topbottom = 50 speed_wall_0 = 40 From 7c7f6a1f038aa985d857e174fdf835fb476e4681 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 16 Jan 2019 15:28:16 +0100 Subject: [PATCH 1275/1292] Ensure sane defaults for the ApplicationMetada when making builds --- cura/ApplicationMetadata.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cura/ApplicationMetadata.py b/cura/ApplicationMetadata.py index e2ac4453eb..4cb19edb72 100644 --- a/cura/ApplicationMetadata.py +++ b/cura/ApplicationMetadata.py @@ -12,11 +12,15 @@ DEFAULT_CURA_SDK_VERSION = "6.0.0" try: from cura.CuraVersion import CuraAppDisplayName # type: ignore + if CuraAppDisplayName == "": + CuraAppDisplayName = DEFAULT_CURA_DISPLAY_NAME except ImportError: CuraAppDisplayName = DEFAULT_CURA_DISPLAY_NAME try: from cura.CuraVersion import CuraVersion # type: ignore + if CuraVersion == "": + CuraVersion = DEFAULT_CURA_VERSION except ImportError: CuraVersion = DEFAULT_CURA_VERSION # [CodeStyle: Reflecting imported value] @@ -32,5 +36,7 @@ except ImportError: try: from cura.CuraVersion import CuraSDKVersion # type: ignore + if CuraSDKVersion == "": + CuraSDKVersion = DEFAULT_CURA_SDK_VERSION except ImportError: CuraSDKVersion = DEFAULT_CURA_SDK_VERSION From 54cbadd09e9d21442bcad5227f89f93dfc362314 Mon Sep 17 00:00:00 2001 From: TiZYX Date: Wed, 16 Jan 2019 15:28:22 +0100 Subject: [PATCH 1276/1292] Update tizyx_k25_normal.inst.cfg --- resources/quality/tizyx_k25/tizyx_k25_normal.inst.cfg | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/quality/tizyx_k25/tizyx_k25_normal.inst.cfg b/resources/quality/tizyx_k25/tizyx_k25_normal.inst.cfg index f223d0ce76..6404a6b02c 100644 --- a/resources/quality/tizyx_k25/tizyx_k25_normal.inst.cfg +++ b/resources/quality/tizyx_k25/tizyx_k25_normal.inst.cfg @@ -14,7 +14,6 @@ adhesion_type = skirt skirt_line_count = 2 skirt_gap = 2 fill_outline_gaps = True -infill_angles = [] infill_sparse_density = 15 material_diameter = 1.75 retraction_amount = 2.5 From a0dd3f06e6031b4a263b7da4735e1977a1f401a6 Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Wed, 16 Jan 2019 15:41:09 +0100 Subject: [PATCH 1277/1292] Add 'Experimental' tag for quality profiles in the header. When an experimental quality profile is active, the stage panel does not show that it is experimental. It is however shown on the quality drop-down menu in Custom mode. This commit also fixes the untranslated (hardcoded) 'Experimental' string in the dropdown in Custom. Fixes the issue reported in CURA-6118. --- resources/qml/Menus/ProfileMenu.qml | 2 +- resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/qml/Menus/ProfileMenu.qml b/resources/qml/Menus/ProfileMenu.qml index bf950aa409..68260f2502 100644 --- a/resources/qml/Menus/ProfileMenu.qml +++ b/resources/qml/Menus/ProfileMenu.qml @@ -20,7 +20,7 @@ Menu text: { var full_text = (model.layer_height != "") ? model.name + " - " + model.layer_height + model.layer_height_unit : model.name - full_text += model.is_experimental ? " - Experimental" : "" + full_text += model.is_experimental ? " - " + catalog.i18nc("@label", "Experimental") : "" return full_text } checkable: true diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml index 5ae9488cd3..96b244d803 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml @@ -24,6 +24,7 @@ RowLayout if (!Cura.MachineManager.hasNotSupportedQuality) { text += " " + layerHeight.properties.value + "mm" + text += Cura.MachineManager.isActiveQualityExperimental ? " - " + catalog.i18nc("@label", "Experimental") : "" } return text } From c28aefac4ed0eeca2d96a0459c168cb89df87c3b Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 16 Jan 2019 17:33:14 +0100 Subject: [PATCH 1278/1292] Add the maximum backups message to the backups plugin It didn't work after previous changes, so now it will show again when the user already has 5 backups. Contributes to CURA-6005 --- plugins/CuraDrive/src/qml/components/BackupListFooter.qml | 2 +- plugins/CuraDrive/src/qml/pages/BackupsPage.qml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/CuraDrive/src/qml/components/BackupListFooter.qml b/plugins/CuraDrive/src/qml/components/BackupListFooter.qml index 56706b9990..8decdc5c27 100644 --- a/plugins/CuraDrive/src/qml/components/BackupListFooter.qml +++ b/plugins/CuraDrive/src/qml/components/BackupListFooter.qml @@ -30,7 +30,7 @@ RowLayout id: createBackupButton text: catalog.i18nc("@button", "Backup Now") iconSource: UM.Theme.getIcon("plus") - enabled: !CuraDrive.isCreatingBackup && !CuraDrive.isRestoringBackup && !backupListFooter.showInfoButton + enabled: !CuraDrive.isCreatingBackup && !CuraDrive.isRestoringBackup onClicked: CuraDrive.createBackup() busy: CuraDrive.isCreatingBackup } diff --git a/plugins/CuraDrive/src/qml/pages/BackupsPage.qml b/plugins/CuraDrive/src/qml/pages/BackupsPage.qml index 0ba0cae09b..c337294744 100644 --- a/plugins/CuraDrive/src/qml/pages/BackupsPage.qml +++ b/plugins/CuraDrive/src/qml/pages/BackupsPage.qml @@ -40,7 +40,7 @@ Item font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") wrapMode: Label.WordWrap - visible: backupList.count == 0 + visible: backupList.model.length == 0 Layout.fillWidth: true Layout.fillHeight: true renderType: Text.NativeRendering @@ -62,14 +62,14 @@ Item font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") wrapMode: Label.WordWrap - visible: backupList.count > 4 + visible: backupList.model.length > 4 renderType: Text.NativeRendering } BackupListFooter { id: backupListFooter - showInfoButton: backupList.count > 4 + showInfoButton: backupList.model.length > 4 } } } From 909c74c9b62fdd4e9c162211852c13a1d157eb9f Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 17 Jan 2019 09:56:46 +0100 Subject: [PATCH 1279/1292] Fix the tests so they don't rely on external URL --- .../FirmwareUpdateCheckerJob.py | 1 - .../FirmwareUpdateCheckerLookup.py | 2 +- .../tests/TestFirmwareUpdateChecker.py | 18 ++++++------------ 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py b/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py index 906c20dd25..a1460cca3f 100644 --- a/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py +++ b/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py @@ -44,7 +44,6 @@ class FirmwareUpdateCheckerJob(Job): result = response.read().decode("utf-8") except URLError: Logger.log("w", "Could not reach '{0}', if this URL is old, consider removal.".format(url)) - return result def parseVersionResponse(self, response: str) -> Version: diff --git a/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerLookup.py b/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerLookup.py index a21ad3f0e5..c78e6f6025 100644 --- a/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerLookup.py +++ b/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerLookup.py @@ -18,7 +18,7 @@ class FirmwareUpdateCheckerLookup: self._machine_id = machine_json.get("id") self._machine_name = machine_name.lower() # Lower in-case upper-case chars are added to the original json. self._check_urls = [] # type:List[str] - for check_url in machine_json.get("check_urls"): + for check_url in machine_json.get("check_urls", []): self._check_urls.append(check_url) self._redirect_user = machine_json.get("update_url") diff --git a/plugins/FirmwareUpdateChecker/tests/TestFirmwareUpdateChecker.py b/plugins/FirmwareUpdateChecker/tests/TestFirmwareUpdateChecker.py index 21d15922a2..8cd7083f16 100644 --- a/plugins/FirmwareUpdateChecker/tests/TestFirmwareUpdateChecker.py +++ b/plugins/FirmwareUpdateChecker/tests/TestFirmwareUpdateChecker.py @@ -2,10 +2,8 @@ # Cura is released under the terms of the LGPLv3 or higher. import pytest -import json -import unittest.mock -from cura.CuraApplication import CuraApplication +from unittest.mock import MagicMock from UM.Version import Version @@ -18,7 +16,7 @@ json_data = \ { "id": 1, "name": "ned", - "check_urls": ["http://urlecho.appspot.com/echo?status=200&body=5.1.2.3"], + "check_urls": [""], "update_url": "https://ultimaker.com/en/resources/20500-upgrade-firmware", "version_parser": "default" }, @@ -26,7 +24,7 @@ json_data = \ { "id": 3, "name": "olivia", - "check_urls": ["http://urlecho.appspot.com/echo?status=200&body=4.3.2.1", "https://this-url-clearly-doesnt-exist.net"], + "check_urls": [""], "update_url": "https://ultimaker.com/en/resources/20500-upgrade-firmware", "version_parser": "default" }, @@ -34,15 +32,12 @@ json_data = \ { "id": 5, "name": "emmerson", - "check_urls": ["http://urlecho.appspot.com/echo?status=200&body=0.2.2.2", "http://urlecho.appspot.com/echo?status=200&body=6.7.8.1"], + "check_urls": [""], "update_url": "https://ultimaker.com/en/resources/20500-upgrade-firmware", "version_parser": "default" } } -def dummyCallback(): - pass - @pytest.mark.parametrize("name, id", [ ("ned" , 1), ("olivia" , 3), @@ -63,7 +58,6 @@ def test_FirmwareUpdateCheckerLookup(id, name): ]) def test_FirmwareUpdateCheckerJob_getCurrentVersion(name, version): machine_data = json_data.get(name) - job = FirmwareUpdateCheckerJob(False, name, machine_data, dummyCallback) - job._headers = {"User-Agent": "Cura-UnitTests 0"} - + job = FirmwareUpdateCheckerJob(False, name, machine_data, MagicMock) + job.getUrlResponse = MagicMock(return_value = str(version)) # Pretend like we got a good response from the server assert job.getCurrentVersion() == version From aab1fbc73f93027b5a275ef39f98200eb062ad14 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Thu, 17 Jan 2019 10:22:37 +0100 Subject: [PATCH 1280/1292] Try other patch values for relative imports --- .../UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py | 2 +- .../tests/Cloud/TestCloudOutputDevice.py | 2 +- .../tests/Cloud/TestCloudOutputDeviceManager.py | 8 +++----- plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py | 3 +-- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py index 0be1d82141..36e03c6213 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py @@ -28,7 +28,7 @@ class TestCloudApiClient(TestCase): self.account.isLoggedIn.return_value = True self.network = NetworkManagerMock() - with patch("plugins.UM3NetworkPrinting.src.Cloud.CloudApiClient.QNetworkAccessManager", return_value = self.network): + with patch("CloudApiClient.QNetworkAccessManager", return_value = self.network): self.api = CloudApiClient(self.account, self._errorHandler) def test_getClusters(self): diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py index 191b92bdd5..d9f983640e 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py @@ -41,7 +41,7 @@ class TestCloudOutputDevice(TestCase): self.network = NetworkManagerMock() self.account = MagicMock(isLoggedIn=True, accessToken="TestAccessToken") self.onError = MagicMock() - with patch("plugins.UM3NetworkPrinting.src.Cloud.CloudApiClient.QNetworkAccessManager", + with patch("CloudApiClient.QNetworkAccessManager", return_value = self.network): self._api = CloudApiClient(self.account, self.onError) diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py index c5006f35a1..66acac8eff 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py @@ -28,10 +28,8 @@ class TestCloudOutputDeviceManager(TestCase): self.network = NetworkManagerMock() self.timer = MagicMock(timeout = FakeSignal()) - with patch("plugins.UM3NetworkPrinting.src.Cloud.CloudApiClient.QNetworkAccessManager", - return_value = self.network), \ - patch("plugins.UM3NetworkPrinting.src.Cloud.CloudOutputDeviceManager.QTimer", - return_value = self.timer): + with patch("CloudApiClient.QNetworkAccessManager", return_value = self.network), \ + patch("CloudOutputDeviceManager.QTimer", return_value = self.timer): self.manager = CloudOutputDeviceManager() self.clusters_response = parseFixture("getClusters") self.network.prepareReply("GET", self.URL, 200, readFixture("getClusters")) @@ -114,7 +112,7 @@ class TestCloudOutputDeviceManager(TestCase): active_machine_mock.setMetaDataEntry.assert_called_with("um_cloud_cluster_id", cluster2["cluster_id"]) - @patch("plugins.UM3NetworkPrinting.src.Cloud.CloudOutputDeviceManager.Message") + @patch("CloudOutputDeviceManager.Message") def test_api_error(self, message_mock): self.clusters_response = { "errors": [{"id": "notFound", "title": "Not found!", "http_status": "404", "code": "notFound"}] diff --git a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py index 6eac892af6..952d38dcf4 100644 --- a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py @@ -1,7 +1,6 @@ # Copyright (c) 2018 Ultimaker B.V. # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -import copy import io import json from unittest import TestCase, mock @@ -14,7 +13,7 @@ from UM.Application import Application from cura.Machines.MaterialGroup import MaterialGroup from cura.Machines.MaterialNode import MaterialNode -from plugins.UM3NetworkPrinting.src.SendMaterialJob import SendMaterialJob +from ..src.SendMaterialJob import SendMaterialJob _FILES_MAP = {"generic_pla_white": "/materials/generic_pla_white.xml.fdm_material", "generic_pla_black": "/materials/generic_pla_black.xml.fdm_material", From 3b3baeac03cb4b29566fd335503185d828056f7d Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 17 Jan 2019 11:20:19 +0100 Subject: [PATCH 1281/1292] Remove hard-coded account URLs in QMLs CURA-6117 --- cura/CuraApplication.py | 20 +++++++++----------- resources/qml/Account/GeneralOperations.qml | 2 +- resources/qml/Account/UserOperations.qml | 2 +- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index cf4e85f850..1ded631def 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -117,7 +117,7 @@ from cura.ObjectsModel import ObjectsModel from cura.PrinterOutputDevice import PrinterOutputDevice from cura.PrinterOutput.NetworkMJPGImage import NetworkMJPGImage -from cura import ApplicationMetadata +from cura import ApplicationMetadata, UltimakerCloudAuthentication from UM.FlameProfiler import pyqtSlot from UM.Decorators import override @@ -132,16 +132,6 @@ if TYPE_CHECKING: numpy.seterr(all = "ignore") -try: - from cura.CuraVersion import CuraAppDisplayName, CuraVersion, CuraBuildType, CuraDebugMode, CuraSDKVersion # type: ignore -except ImportError: - CuraAppDisplayName = "Ultimaker Cura" - CuraVersion = "master" # [CodeStyle: Reflecting imported value] - CuraBuildType = "" - CuraDebugMode = False - CuraSDKVersion = "6.0.0" - - class CuraApplication(QtApplication): # SettingVersion represents the set of settings available in the machine/extruder definitions. # You need to make sure that this version number needs to be increased if there is any non-backwards-compatible @@ -266,6 +256,14 @@ class CuraApplication(QtApplication): from cura.CuraPackageManager import CuraPackageManager self._package_manager_class = CuraPackageManager + @pyqtProperty(str, constant=True) + def ultimakerCloudApiRootUrl(self) -> str: + return UltimakerCloudAuthentication.CuraCloudAPIRoot + + @pyqtProperty(str, constant = True) + def ultimakerCloudAccountRootUrl(self) -> str: + return UltimakerCloudAuthentication.CuraCloudAccountAPIRoot + # Adds command line options to the command line parser. This should be called after the application is created and # before the pre-start. def addCommandLineOptions(self): diff --git a/resources/qml/Account/GeneralOperations.qml b/resources/qml/Account/GeneralOperations.qml index b9f1025d5e..666a254cd1 100644 --- a/resources/qml/Account/GeneralOperations.qml +++ b/resources/qml/Account/GeneralOperations.qml @@ -16,7 +16,7 @@ Row width: UM.Theme.getSize("account_button").width height: UM.Theme.getSize("account_button").height text: catalog.i18nc("@button", "Create account") - onClicked: Qt.openUrlExternally("https://account.ultimaker.com/app/create") + onClicked: Qt.openUrlExternally(CuraApplication.ultimakerCloudAccountRootUrl + "/app/create") fixedWidthMode: true } diff --git a/resources/qml/Account/UserOperations.qml b/resources/qml/Account/UserOperations.qml index b9ffa395d6..56c2dc416f 100644 --- a/resources/qml/Account/UserOperations.qml +++ b/resources/qml/Account/UserOperations.qml @@ -16,7 +16,7 @@ Row width: UM.Theme.getSize("account_button").width height: UM.Theme.getSize("account_button").height text: catalog.i18nc("@button", "Manage account") - onClicked: Qt.openUrlExternally("https://account.ultimaker.com") + onClicked: Qt.openUrlExternally(CuraApplication.ultimakerCloudAccountRootUrl) fixedWidthMode: true } From 2aa985c6deb22c927a8905027b4454e2efe2b491 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 17 Jan 2019 11:49:22 +0100 Subject: [PATCH 1282/1292] Update all profiles to setting_version 7 CURA-6113 --- .../quality/abax_pri3/apri3_pla_fast.inst.cfg | 2 +- .../quality/abax_pri3/apri3_pla_high.inst.cfg | 2 +- .../abax_pri3/apri3_pla_normal.inst.cfg | 2 +- .../quality/abax_pri5/apri5_pla_fast.inst.cfg | 2 +- .../quality/abax_pri5/apri5_pla_high.inst.cfg | 2 +- .../abax_pri5/apri5_pla_normal.inst.cfg | 2 +- .../abax_titan/atitan_pla_fast.inst.cfg | 2 +- .../abax_titan/atitan_pla_high.inst.cfg | 2 +- .../abax_titan/atitan_pla_normal.inst.cfg | 2 +- .../abs/anycubic_4max_abs_draft.inst.cfg | 2 +- .../abs/anycubic_4max_abs_high.inst.cfg | 2 +- .../abs/anycubic_4max_abs_normal.inst.cfg | 2 +- .../anycubic_4max_draft.inst.cfg | 2 +- .../anycubic_4max/anycubic_4max_high.inst.cfg | 2 +- .../anycubic_4max_normal.inst.cfg | 2 +- .../hips/anycubic_4max_hips_draft.inst.cfg | 2 +- .../hips/anycubic_4max_hips_high.inst.cfg | 2 +- .../hips/anycubic_4max_hips_normal.inst.cfg | 2 +- .../petg/anycubic_4max_petg_draft.inst.cfg | 2 +- .../petg/anycubic_4max_petg_high.inst.cfg | 2 +- .../petg/anycubic_4max_petg_normal.inst.cfg | 2 +- .../pla/anycubic_4max_pla_draft.inst.cfg | 2 +- .../pla/anycubic_4max_pla_high.inst.cfg | 2 +- .../pla/anycubic_4max_pla_normal.inst.cfg | 2 +- .../anycubic_i3_mega_draft.inst.cfg | 2 +- .../anycubic_i3_mega_high.inst.cfg | 2 +- .../anycubic_i3_mega_normal.inst.cfg | 2 +- .../bp_BVOH_Coarse_Quality.inst.cfg | 2 +- .../bp_BVOH_High_Quality.inst.cfg | 2 +- .../bp_BVOH_Normal_Quality.inst.cfg | 2 +- .../bp_Innoflex60_Coarse_Quality.inst.cfg | 2 +- .../bp_Innoflex60_High_Quality.inst.cfg | 2 +- .../bp_Innoflex60_Normal_Quality.inst.cfg | 2 +- .../bp_PET_Coarse_Quality.inst.cfg | 2 +- .../bp_PET_High_Quality.inst.cfg | 2 +- .../bp_PET_Normal_Quality.inst.cfg | 2 +- .../bp_PLA_Coarse_Quality.inst.cfg | 2 +- .../bp_PLA_High_Quality.inst.cfg | 2 +- .../bp_PLA_Normal_Quality.inst.cfg | 2 +- .../bp_PVA_Coarse_Quality.inst.cfg | 2 +- .../bp_PVA_High_Quality.inst.cfg | 2 +- .../bp_PVA_Normal_Quality.inst.cfg | 2 +- .../bp_global_Coarse_Quality.inst.cfg | 2 +- .../bp_global_High_Quality.inst.cfg | 2 +- .../bp_global_Normal_Quality.inst.cfg | 2 +- .../abs/cartesio_0.25_abs_high.inst.cfg | 2 +- .../abs/cartesio_0.25_abs_normal.inst.cfg | 2 +- .../abs/cartesio_0.4_abs_high.inst.cfg | 2 +- .../abs/cartesio_0.4_abs_normal.inst.cfg | 2 +- .../abs/cartesio_0.8_abs_coarse.inst.cfg | 2 +- .../cartesio_0.8_abs_extra_coarse.inst.cfg | 2 +- .../abs/cartesio_0.8_abs_high.inst.cfg | 2 +- .../abs/cartesio_0.8_abs_normal.inst.cfg | 2 +- .../cartesio_0.4_arnitel2045_high.inst.cfg | 2 +- .../cartesio_0.4_arnitel2045_normal.inst.cfg | 2 +- .../cartesio_global_Coarse_Quality.inst.cfg | 2 +- ...tesio_global_Extra_Coarse_Quality.inst.cfg | 2 +- .../cartesio_global_High_Quality.inst.cfg | 2 +- .../cartesio_global_Normal_Quality.inst.cfg | 2 +- .../hips/cartesio_0.25_hips_high.inst.cfg | 2 +- .../hips/cartesio_0.25_hips_normal.inst.cfg | 2 +- .../hips/cartesio_0.4_hips_high.inst.cfg | 2 +- .../hips/cartesio_0.4_hips_normal.inst.cfg | 2 +- .../hips/cartesio_0.8_hips_coarse.inst.cfg | 2 +- .../cartesio_0.8_hips_extra_coarse.inst.cfg | 2 +- .../hips/cartesio_0.8_hips_high.inst.cfg | 2 +- .../hips/cartesio_0.8_hips_normal.inst.cfg | 2 +- .../nylon/cartesio_0.25_nylon_high.inst.cfg | 2 +- .../nylon/cartesio_0.25_nylon_normal.inst.cfg | 2 +- .../nylon/cartesio_0.4_nylon_high.inst.cfg | 2 +- .../nylon/cartesio_0.4_nylon_normal.inst.cfg | 2 +- .../nylon/cartesio_0.8_nylon_coarse.inst.cfg | 2 +- .../cartesio_0.8_nylon_extra_coarse.inst.cfg | 2 +- .../nylon/cartesio_0.8_nylon_high.inst.cfg | 2 +- .../nylon/cartesio_0.8_nylon_normal.inst.cfg | 2 +- .../pc/cartesio_0.25_pc_high.inst.cfg | 2 +- .../pc/cartesio_0.25_pc_normal.inst.cfg | 2 +- .../cartesio/pc/cartesio_0.4_pc_high.inst.cfg | 2 +- .../pc/cartesio_0.4_pc_normal.inst.cfg | 2 +- .../pc/cartesio_0.8_pc_coarse.inst.cfg | 2 +- .../pc/cartesio_0.8_pc_extra_coarse.inst.cfg | 2 +- .../cartesio/pc/cartesio_0.8_pc_high.inst.cfg | 2 +- .../pc/cartesio_0.8_pc_normal.inst.cfg | 2 +- .../petg/cartesio_0.25_petg_high.inst.cfg | 2 +- .../petg/cartesio_0.25_petg_normal.inst.cfg | 2 +- .../petg/cartesio_0.4_petg_high.inst.cfg | 2 +- .../petg/cartesio_0.4_petg_normal.inst.cfg | 2 +- .../petg/cartesio_0.8_petg_coarse.inst.cfg | 2 +- .../cartesio_0.8_petg_extra_coarse.inst.cfg | 2 +- .../petg/cartesio_0.8_petg_high.inst.cfg | 2 +- .../petg/cartesio_0.8_petg_normal.inst.cfg | 2 +- .../pla/cartesio_0.25_pla_high.inst.cfg | 2 +- .../pla/cartesio_0.25_pla_normal.inst.cfg | 2 +- .../pla/cartesio_0.4_pla_high.inst.cfg | 2 +- .../pla/cartesio_0.4_pla_normal.inst.cfg | 2 +- .../pla/cartesio_0.8_pla_coarse.inst.cfg | 2 +- .../cartesio_0.8_pla_extra_coarse.inst.cfg | 2 +- .../pla/cartesio_0.8_pla_high.inst.cfg | 2 +- .../pla/cartesio_0.8_pla_normal.inst.cfg | 2 +- .../pva/cartesio_0.25_pva_high.inst.cfg | 2 +- .../pva/cartesio_0.25_pva_normal.inst.cfg | 2 +- .../pva/cartesio_0.4_pva_high.inst.cfg | 2 +- .../pva/cartesio_0.4_pva_normal.inst.cfg | 2 +- .../pva/cartesio_0.8_pva_coarse.inst.cfg | 2 +- .../cartesio_0.8_pva_extra_coarse.inst.cfg | 2 +- .../pva/cartesio_0.8_pva_high.inst.cfg | 2 +- .../pva/cartesio_0.8_pva_normal.inst.cfg | 2 +- resources/quality/coarse.inst.cfg | 2 +- .../dagoma_discoeasy200_pla_fast.inst.cfg | 2 +- .../dagoma_discoeasy200_pla_fine.inst.cfg | 2 +- .../dagoma_discoeasy200_pla_standard.inst.cfg | 2 +- .../dagoma/dagoma_global_fast.inst.cfg | 2 +- .../dagoma/dagoma_global_fine.inst.cfg | 2 +- .../dagoma/dagoma_global_standard.inst.cfg | 2 +- .../dagoma/dagoma_magis_pla_fast.inst.cfg | 2 +- .../dagoma/dagoma_magis_pla_fine.inst.cfg | 2 +- .../dagoma/dagoma_magis_pla_standard.inst.cfg | 2 +- .../dagoma/dagoma_neva_pla_fast.inst.cfg | 2 +- .../dagoma/dagoma_neva_pla_fine.inst.cfg | 2 +- .../dagoma/dagoma_neva_pla_standard.inst.cfg | 2 +- .../deltacomb_abs_Draft_Quality.inst.cfg | 2 +- .../deltacomb_abs_Fast_Quality.inst.cfg | 2 +- .../deltacomb_abs_High_Quality.inst.cfg | 2 +- .../deltacomb_abs_Normal_Quality.inst.cfg | 2 +- .../deltacomb_abs_Verydraft_Quality.inst.cfg | 2 +- .../deltacomb_global_Draft_Quality.inst.cfg | 2 +- .../deltacomb_global_Fast_Quality.inst.cfg | 2 +- .../deltacomb_global_High_Quality.inst.cfg | 2 +- .../deltacomb_global_Normal_Quality.inst.cfg | 2 +- ...eltacomb_global_Verydraft_Quality.inst.cfg | 2 +- .../deltacomb_pla_Draft_Quality.inst.cfg | 2 +- .../deltacomb_pla_Fast_Quality.inst.cfg | 2 +- .../deltacomb_pla_High_Quality.inst.cfg | 2 +- .../deltacomb_pla_Normal_Quality.inst.cfg | 2 +- .../deltacomb_pla_Verydraft_Quality.inst.cfg | 2 +- resources/quality/draft.inst.cfg | 2 +- resources/quality/extra_coarse.inst.cfg | 2 +- resources/quality/extra_fast.inst.cfg | 2 +- .../fabtotum/fabtotum_abs_fast.inst.cfg | 2 +- .../fabtotum/fabtotum_abs_high.inst.cfg | 2 +- .../fabtotum/fabtotum_abs_normal.inst.cfg | 2 +- .../fabtotum/fabtotum_nylon_fast.inst.cfg | 2 +- .../fabtotum/fabtotum_nylon_high.inst.cfg | 2 +- .../fabtotum/fabtotum_nylon_normal.inst.cfg | 2 +- .../fabtotum/fabtotum_pla_fast.inst.cfg | 2 +- .../fabtotum/fabtotum_pla_high.inst.cfg | 2 +- .../fabtotum/fabtotum_pla_normal.inst.cfg | 2 +- .../fabtotum/fabtotum_tpu_fast.inst.cfg | 2 +- .../fabtotum/fabtotum_tpu_high.inst.cfg | 2 +- .../fabtotum/fabtotum_tpu_normal.inst.cfg | 2 +- resources/quality/fast.inst.cfg | 2 +- .../gmax15plus_global_dual_normal.inst.cfg | 2 +- .../gmax15plus_global_dual_thick.inst.cfg | 2 +- .../gmax15plus_global_dual_thin.inst.cfg | 2 +- ...gmax15plus_global_dual_very_thick.inst.cfg | 2 +- .../gmax15plus_global_normal.inst.cfg | 2 +- .../gmax15plus_global_thick.inst.cfg | 2 +- .../gmax15plus_global_thin.inst.cfg | 2 +- .../gmax15plus_global_very_thick.inst.cfg | 2 +- resources/quality/high.inst.cfg | 2 +- .../generic_petg_0.4_coarse.inst.cfg | 2 +- .../generic_petg_0.4_coarse_2-fans.inst.cfg | 2 +- .../generic_petg_0.4_medium.inst.cfg | 2 +- .../generic_petg_0.4_medium_2-fans.inst.cfg | 2 +- .../generic_pla_0.4_coarse.inst.cfg | 2 +- .../generic_pla_0.4_coarse_2-fans.inst.cfg | 2 +- .../generic_pla_0.4_fine.inst.cfg | 2 +- .../generic_pla_0.4_fine_2-fans.inst.cfg | 2 +- .../generic_pla_0.4_medium.inst.cfg | 2 +- .../generic_pla_0.4_medium_2-fans.inst.cfg | 2 +- .../generic_pla_0.4_ultrafine.inst.cfg | 2 +- .../generic_pla_0.4_ultrafine_2-fans.inst.cfg | 2 +- .../imade3d_jellybox_coarse.inst.cfg | 2 +- .../imade3d_jellybox_fine.inst.cfg | 2 +- .../imade3d_jellybox_normal.inst.cfg | 2 +- .../imade3d_jellybox_ultrafine.inst.cfg | 2 +- .../kemiq_q2/kemiq_q2_beta_abs_draft.inst.cfg | 2 +- .../kemiq_q2_beta_abs_extra_fine.inst.cfg | 2 +- .../kemiq_q2/kemiq_q2_beta_abs_fine.inst.cfg | 2 +- .../kemiq_q2/kemiq_q2_beta_abs_low.inst.cfg | 2 +- .../kemiq_q2_beta_abs_normal.inst.cfg | 2 +- .../kemiq_q2/kemiq_q2_beta_pla_draft.inst.cfg | 2 +- .../kemiq_q2_beta_pla_extra_fine.inst.cfg | 2 +- .../kemiq_q2/kemiq_q2_beta_pla_fine.inst.cfg | 2 +- .../kemiq_q2/kemiq_q2_beta_pla_low.inst.cfg | 2 +- .../kemiq_q2_beta_pla_normal.inst.cfg | 2 +- .../kemiq_q2/kemiq_q2_gama_pla_draft.inst.cfg | 2 +- .../kemiq_q2_gama_pla_extra_fine.inst.cfg | 2 +- .../kemiq_q2/kemiq_q2_gama_pla_fine.inst.cfg | 2 +- .../kemiq_q2/kemiq_q2_gama_pla_low.inst.cfg | 2 +- .../kemiq_q2_gama_pla_normal.inst.cfg | 2 +- .../abs/malyan_m200_abs_draft.inst.cfg | 2 +- .../abs/malyan_m200_abs_fast.inst.cfg | 2 +- .../abs/malyan_m200_abs_high.inst.cfg | 2 +- .../abs/malyan_m200_abs_normal.inst.cfg | 2 +- .../abs/malyan_m200_abs_superdraft.inst.cfg | 2 +- .../abs/malyan_m200_abs_thickerdraft.inst.cfg | 2 +- .../abs/malyan_m200_abs_ultra.inst.cfg | 2 +- .../abs/malyan_m200_abs_verydraft.inst.cfg | 2 +- .../malyan_m200_global_Draft_Quality.inst.cfg | 2 +- .../malyan_m200_global_Fast_Quality.inst.cfg | 2 +- .../malyan_m200_global_High_Quality.inst.cfg | 2 +- ...malyan_m200_global_Normal_Quality.inst.cfg | 2 +- ...an_m200_global_SuperDraft_Quality.inst.cfg | 2 +- ..._m200_global_ThickerDraft_Quality.inst.cfg | 2 +- .../malyan_m200_global_Ultra_Quality.inst.cfg | 2 +- ...yan_m200_global_VeryDraft_Quality.inst.cfg | 2 +- .../petg/malyan_m200_petg_draft.inst.cfg | 2 +- .../petg/malyan_m200_petg_fast.inst.cfg | 2 +- .../petg/malyan_m200_petg_high.inst.cfg | 2 +- .../petg/malyan_m200_petg_normal.inst.cfg | 2 +- .../petg/malyan_m200_petg_superdraft.inst.cfg | 2 +- .../malyan_m200_petg_thickerdraft.inst.cfg | 2 +- .../petg/malyan_m200_petg_ultra.inst.cfg | 2 +- .../petg/malyan_m200_petg_verydraft.inst.cfg | 2 +- .../pla/malyan_m200_pla_draft.inst.cfg | 2 +- .../pla/malyan_m200_pla_fast.inst.cfg | 2 +- .../pla/malyan_m200_pla_high.inst.cfg | 2 +- .../pla/malyan_m200_pla_normal.inst.cfg | 2 +- .../pla/malyan_m200_pla_superdraft.inst.cfg | 2 +- .../pla/malyan_m200_pla_thickerdraft.inst.cfg | 2 +- .../pla/malyan_m200_pla_ultra.inst.cfg | 2 +- .../pla/malyan_m200_pla_verydraft.inst.cfg | 2 +- ...onoprice_select_mini_v2_abs_draft.inst.cfg | 2 +- ...monoprice_select_mini_v2_abs_fast.inst.cfg | 2 +- ...monoprice_select_mini_v2_abs_high.inst.cfg | 2 +- ...noprice_select_mini_v2_abs_normal.inst.cfg | 2 +- ...ice_select_mini_v2_abs_superdraft.inst.cfg | 2 +- ...e_select_mini_v2_abs_thickerdraft.inst.cfg | 2 +- ...onoprice_select_mini_v2_abs_ultra.inst.cfg | 2 +- ...rice_select_mini_v2_abs_verydraft.inst.cfg | 2 +- ...lect_mini_v2_global_Draft_Quality.inst.cfg | 2 +- ...elect_mini_v2_global_Fast_Quality.inst.cfg | 2 +- ...elect_mini_v2_global_High_Quality.inst.cfg | 2 +- ...ect_mini_v2_global_Normal_Quality.inst.cfg | 2 +- ...mini_v2_global_SuperDraft_Quality.inst.cfg | 2 +- ...ni_v2_global_ThickerDraft_Quality.inst.cfg | 2 +- ...lect_mini_v2_global_Ultra_Quality.inst.cfg | 2 +- ..._mini_v2_global_VeryDraft_Quality.inst.cfg | 2 +- ...oprice_select_mini_v2_nylon_draft.inst.cfg | 2 +- ...noprice_select_mini_v2_nylon_fast.inst.cfg | 2 +- ...noprice_select_mini_v2_nylon_high.inst.cfg | 2 +- ...price_select_mini_v2_nylon_normal.inst.cfg | 2 +- ...e_select_mini_v2_nylon_superdraft.inst.cfg | 2 +- ...select_mini_v2_nylon_thickerdraft.inst.cfg | 2 +- ...oprice_select_mini_v2_nylon_ultra.inst.cfg | 2 +- ...ce_select_mini_v2_nylon_verydraft.inst.cfg | 2 +- ...monoprice_select_mini_v2_pc_draft.inst.cfg | 2 +- .../monoprice_select_mini_v2_pc_fast.inst.cfg | 2 +- .../monoprice_select_mini_v2_pc_high.inst.cfg | 2 +- ...onoprice_select_mini_v2_pc_normal.inst.cfg | 2 +- ...rice_select_mini_v2_pc_superdraft.inst.cfg | 2 +- ...ce_select_mini_v2_pc_thickerdraft.inst.cfg | 2 +- ...monoprice_select_mini_v2_pc_ultra.inst.cfg | 2 +- ...price_select_mini_v2_pc_verydraft.inst.cfg | 2 +- ...noprice_select_mini_v2_petg_draft.inst.cfg | 2 +- ...onoprice_select_mini_v2_petg_fast.inst.cfg | 2 +- ...onoprice_select_mini_v2_petg_high.inst.cfg | 2 +- ...oprice_select_mini_v2_petg_normal.inst.cfg | 2 +- ...ce_select_mini_v2_petg_superdraft.inst.cfg | 2 +- ..._select_mini_v2_petg_thickerdraft.inst.cfg | 2 +- ...noprice_select_mini_v2_petg_ultra.inst.cfg | 2 +- ...ice_select_mini_v2_petg_verydraft.inst.cfg | 2 +- ...onoprice_select_mini_v2_pla_draft.inst.cfg | 2 +- ...monoprice_select_mini_v2_pla_fast.inst.cfg | 2 +- ...monoprice_select_mini_v2_pla_high.inst.cfg | 2 +- ...noprice_select_mini_v2_pla_normal.inst.cfg | 2 +- ...ice_select_mini_v2_pla_superdraft.inst.cfg | 2 +- ...e_select_mini_v2_pla_thickerdraft.inst.cfg | 2 +- ...onoprice_select_mini_v2_pla_ultra.inst.cfg | 2 +- ...rice_select_mini_v2_pla_verydraft.inst.cfg | 2 +- resources/quality/normal.inst.cfg | 2 +- .../peopoly_moai/peopoly_moai_coarse.inst.cfg | 2 +- .../peopoly_moai/peopoly_moai_draft.inst.cfg | 2 +- .../peopoly_moai_extra_high.inst.cfg | 2 +- .../peopoly_moai/peopoly_moai_high.inst.cfg | 2 +- .../peopoly_moai/peopoly_moai_normal.inst.cfg | 2 +- .../tevo_blackwidow_draft.inst.cfg | 2 +- .../tevo_blackwidow_high.inst.cfg | 2 +- .../tevo_blackwidow_normal.inst.cfg | 2 +- .../tizyx_k25/tizyx_k25_normal.inst.cfg | 58 +++++++++---------- .../quality/ultimaker2/um2_draft.inst.cfg | 2 +- .../quality/ultimaker2/um2_fast.inst.cfg | 2 +- .../quality/ultimaker2/um2_high.inst.cfg | 2 +- .../quality/ultimaker2/um2_normal.inst.cfg | 2 +- .../ultimaker2_plus/pla_0.25_normal.inst.cfg | 2 +- .../ultimaker2_plus/pla_0.4_fast.inst.cfg | 2 +- .../ultimaker2_plus/pla_0.4_high.inst.cfg | 2 +- .../ultimaker2_plus/pla_0.4_normal.inst.cfg | 2 +- .../ultimaker2_plus/pla_0.6_normal.inst.cfg | 2 +- .../ultimaker2_plus/pla_0.8_normal.inst.cfg | 2 +- .../um2p_abs_0.25_normal.inst.cfg | 2 +- .../um2p_abs_0.4_fast.inst.cfg | 2 +- .../um2p_abs_0.4_high.inst.cfg | 2 +- .../um2p_abs_0.4_normal.inst.cfg | 2 +- .../um2p_abs_0.6_normal.inst.cfg | 2 +- .../um2p_abs_0.8_normal.inst.cfg | 2 +- .../um2p_cpe_0.25_normal.inst.cfg | 2 +- .../um2p_cpe_0.4_fast.inst.cfg | 2 +- .../um2p_cpe_0.4_high.inst.cfg | 2 +- .../um2p_cpe_0.4_normal.inst.cfg | 2 +- .../um2p_cpe_0.6_normal.inst.cfg | 2 +- .../um2p_cpe_0.8_normal.inst.cfg | 2 +- .../um2p_cpep_0.4_draft.inst.cfg | 2 +- .../um2p_cpep_0.4_normal.inst.cfg | 2 +- .../um2p_cpep_0.6_draft.inst.cfg | 2 +- .../um2p_cpep_0.6_normal.inst.cfg | 2 +- .../um2p_cpep_0.8_draft.inst.cfg | 2 +- .../um2p_cpep_0.8_normal.inst.cfg | 2 +- .../um2p_global_Coarse_Quality.inst.cfg | 2 +- .../um2p_global_Draft_Quality.inst.cfg | 2 +- .../um2p_global_Extra_Coarse_Quality.inst.cfg | 2 +- .../um2p_global_Fast_Quality.inst.cfg | 2 +- .../um2p_global_High_Quality.inst.cfg | 2 +- .../um2p_global_Normal_Quality.inst.cfg | 2 +- .../um2p_nylon_0.25_high.inst.cfg | 2 +- .../um2p_nylon_0.25_normal.inst.cfg | 2 +- .../um2p_nylon_0.4_fast.inst.cfg | 2 +- .../um2p_nylon_0.4_normal.inst.cfg | 2 +- .../um2p_nylon_0.6_fast.inst.cfg | 2 +- .../um2p_nylon_0.6_normal.inst.cfg | 2 +- .../um2p_nylon_0.8_draft.inst.cfg | 2 +- .../um2p_nylon_0.8_normal.inst.cfg | 2 +- .../um2p_pc_0.25_high.inst.cfg | 2 +- .../um2p_pc_0.25_normal.inst.cfg | 2 +- .../ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg | 2 +- .../um2p_pc_0.4_normal.inst.cfg | 2 +- .../ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg | 2 +- .../um2p_pc_0.6_normal.inst.cfg | 2 +- .../um2p_pc_0.8_draft.inst.cfg | 2 +- .../um2p_pc_0.8_normal.inst.cfg | 2 +- .../ultimaker2_plus/um2p_pp_0.4_fast.inst.cfg | 2 +- .../um2p_pp_0.4_normal.inst.cfg | 2 +- .../um2p_pp_0.6_draft.inst.cfg | 2 +- .../ultimaker2_plus/um2p_pp_0.6_fast.inst.cfg | 2 +- .../um2p_pp_0.8_draft.inst.cfg | 2 +- .../um2p_pp_0.8_verydraft.inst.cfg | 2 +- .../um2p_tpu_0.25_high.inst.cfg | 2 +- .../um2p_tpu_0.4_normal.inst.cfg | 2 +- .../um2p_tpu_0.6_fast.inst.cfg | 2 +- .../um3_aa0.25_ABS_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.25_CPE_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.25_Nylon_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.25_PC_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.25_PLA_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.25_PP_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.25_TPLA_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.4_ABS_Draft_Print.inst.cfg | 2 +- .../um3_aa0.4_ABS_Fast_Print.inst.cfg | 2 +- .../um3_aa0.4_ABS_High_Quality.inst.cfg | 2 +- .../um3_aa0.4_ABS_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.4_BAM_Draft_Print.inst.cfg | 2 +- .../um3_aa0.4_BAM_Fast_Print.inst.cfg | 2 +- .../um3_aa0.4_BAM_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.4_CPEP_Draft_Print.inst.cfg | 2 +- .../um3_aa0.4_CPEP_Fast_Print.inst.cfg | 2 +- .../um3_aa0.4_CPEP_High_Quality.inst.cfg | 2 +- .../um3_aa0.4_CPEP_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.4_CPE_Draft_Print.inst.cfg | 2 +- .../um3_aa0.4_CPE_Fast_Print.inst.cfg | 2 +- .../um3_aa0.4_CPE_High_Quality.inst.cfg | 2 +- .../um3_aa0.4_CPE_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.4_Nylon_Draft_Print.inst.cfg | 2 +- .../um3_aa0.4_Nylon_Fast_Print.inst.cfg | 2 +- .../um3_aa0.4_Nylon_High_Quality.inst.cfg | 2 +- .../um3_aa0.4_Nylon_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.4_PC_Draft_Print.inst.cfg | 2 +- .../um3_aa0.4_PC_Fast_Print.inst.cfg | 2 +- .../um3_aa0.4_PC_High_Quality.inst.cfg | 2 +- .../um3_aa0.4_PC_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.4_PLA_Draft_Print.inst.cfg | 2 +- .../um3_aa0.4_PLA_Fast_Print.inst.cfg | 2 +- .../um3_aa0.4_PLA_High_Quality.inst.cfg | 2 +- .../um3_aa0.4_PLA_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.4_PP_Draft_Print.inst.cfg | 2 +- .../um3_aa0.4_PP_Fast_Print.inst.cfg | 2 +- .../um3_aa0.4_PP_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.4_TPLA_Draft_Print.inst.cfg | 2 +- .../um3_aa0.4_TPLA_Fast_Print.inst.cfg | 2 +- .../um3_aa0.4_TPLA_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.4_TPU_Draft_Print.inst.cfg | 2 +- .../um3_aa0.4_TPU_Fast_Print.inst.cfg | 2 +- .../um3_aa0.4_TPU_Normal_Quality.inst.cfg | 2 +- .../um3_aa0.8_ABS_Draft_Print.inst.cfg | 2 +- .../um3_aa0.8_ABS_Superdraft_Print.inst.cfg | 2 +- .../um3_aa0.8_ABS_Verydraft_Print.inst.cfg | 2 +- .../um3_aa0.8_CPEP_Fast_Print.inst.cfg | 2 +- .../um3_aa0.8_CPEP_Superdraft_Print.inst.cfg | 2 +- .../um3_aa0.8_CPEP_Verydraft_Print.inst.cfg | 2 +- .../um3_aa0.8_CPE_Draft_Print.inst.cfg | 2 +- .../um3_aa0.8_CPE_Superdraft_Print.inst.cfg | 2 +- .../um3_aa0.8_CPE_Verydraft_Print.inst.cfg | 2 +- .../um3_aa0.8_Nylon_Draft_Print.inst.cfg | 2 +- .../um3_aa0.8_Nylon_Superdraft_Print.inst.cfg | 2 +- .../um3_aa0.8_Nylon_Verydraft_Print.inst.cfg | 2 +- .../um3_aa0.8_PC_Fast_Print.inst.cfg | 2 +- .../um3_aa0.8_PC_Superdraft_Print.inst.cfg | 2 +- .../um3_aa0.8_PC_Verydraft_Print.inst.cfg | 2 +- .../um3_aa0.8_PLA_Draft_Print.inst.cfg | 2 +- .../um3_aa0.8_PLA_Superdraft_Print.inst.cfg | 2 +- .../um3_aa0.8_PLA_Verydraft_Print.inst.cfg | 2 +- .../um3_aa0.8_PP_Draft_Print.inst.cfg | 2 +- .../um3_aa0.8_PP_Superdraft_Print.inst.cfg | 2 +- .../um3_aa0.8_PP_Verydraft_Print.inst.cfg | 2 +- .../um3_aa0.8_TPLA_Draft_Print.inst.cfg | 2 +- .../um3_aa0.8_TPLA_Superdraft_Print.inst.cfg | 2 +- .../um3_aa0.8_TPLA_Verydraft_Print.inst.cfg | 2 +- .../um3_aa0.8_TPU_Draft_Print.inst.cfg | 2 +- .../um3_aa0.8_TPU_Superdraft_Print.inst.cfg | 2 +- .../um3_aa0.8_TPU_Verydraft_Print.inst.cfg | 2 +- .../um3_bb0.4_PVA_Draft_Print.inst.cfg | 2 +- .../um3_bb0.4_PVA_Fast_Print.inst.cfg | 2 +- .../um3_bb0.4_PVA_High_Quality.inst.cfg | 2 +- .../um3_bb0.4_PVA_Normal_Quality.inst.cfg | 2 +- .../um3_bb0.8_PVA_Draft_Print.inst.cfg | 2 +- .../um3_bb0.8_PVA_Superdraft_Print.inst.cfg | 2 +- .../um3_bb0.8_PVA_Verydraft_Print.inst.cfg | 2 +- .../um3_global_Draft_Quality.inst.cfg | 2 +- .../um3_global_Fast_Quality.inst.cfg | 2 +- .../um3_global_High_Quality.inst.cfg | 2 +- .../um3_global_Normal_Quality.inst.cfg | 2 +- .../um3_global_Superdraft_Quality.inst.cfg | 2 +- .../um3_global_Verydraft_Quality.inst.cfg | 2 +- .../umo_global_Coarse_Quality.inst.cfg | 2 +- .../umo_global_Draft_Quality.inst.cfg | 2 +- .../umo_global_Extra_Coarse_Quality.inst.cfg | 2 +- .../umo_global_Fast_Quality.inst.cfg | 2 +- .../umo_global_High_Quality.inst.cfg | 2 +- .../umo_global_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.25_ABS_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.25_CPE_Normal_Quality.inst.cfg | 2 +- ...um_s5_aa0.25_Nylon_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.25_PC_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.25_PLA_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.25_PP_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.25_TPLA_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_ABS_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.4_ABS_Fast_Print.inst.cfg | 2 +- .../um_s5_aa0.4_ABS_High_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_ABS_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_BAM_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.4_BAM_Fast_Print.inst.cfg | 2 +- .../um_s5_aa0.4_BAM_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_CPEP_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.4_CPEP_Fast_Print.inst.cfg | 2 +- .../um_s5_aa0.4_CPEP_High_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_CPEP_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_CPE_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.4_CPE_Fast_Print.inst.cfg | 2 +- .../um_s5_aa0.4_CPE_High_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_CPE_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_Nylon_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.4_Nylon_Fast_Print.inst.cfg | 2 +- .../um_s5_aa0.4_Nylon_High_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_Nylon_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_PC_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.4_PC_Fast_Print.inst.cfg | 2 +- .../um_s5_aa0.4_PC_High_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_PC_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_PLA_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.4_PLA_Fast_Print.inst.cfg | 2 +- .../um_s5_aa0.4_PLA_High_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_PLA_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_PP_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.4_PP_Fast_Print.inst.cfg | 2 +- .../um_s5_aa0.4_PP_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_TPLA_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.4_TPLA_Fast_Print.inst.cfg | 2 +- .../um_s5_aa0.4_TPLA_High_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_TPLA_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.4_TPU_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.4_TPU_Fast_Print.inst.cfg | 2 +- .../um_s5_aa0.4_TPU_Normal_Quality.inst.cfg | 2 +- ...s5_aa0.4_aluminum_ABS_Draft_Print.inst.cfg | 2 +- ..._s5_aa0.4_aluminum_ABS_Fast_Print.inst.cfg | 2 +- ...5_aa0.4_aluminum_ABS_High_Quality.inst.cfg | 2 +- ...aa0.4_aluminum_ABS_Normal_Quality.inst.cfg | 2 +- ...5_aa0.4_aluminum_CPEP_Draft_Print.inst.cfg | 2 +- ...s5_aa0.4_aluminum_CPEP_Fast_Print.inst.cfg | 2 +- ..._aa0.4_aluminum_CPEP_High_Quality.inst.cfg | 2 +- ...a0.4_aluminum_CPEP_Normal_Quality.inst.cfg | 2 +- ...s5_aa0.4_aluminum_CPE_Draft_Print.inst.cfg | 2 +- ..._s5_aa0.4_aluminum_CPE_Fast_Print.inst.cfg | 2 +- ...5_aa0.4_aluminum_CPE_High_Quality.inst.cfg | 2 +- ...aa0.4_aluminum_CPE_Normal_Quality.inst.cfg | 2 +- ..._s5_aa0.4_aluminum_PC_Draft_Print.inst.cfg | 2 +- ...m_s5_aa0.4_aluminum_PC_Fast_Print.inst.cfg | 2 +- ...s5_aa0.4_aluminum_PC_High_Quality.inst.cfg | 2 +- ..._aa0.4_aluminum_PC_Normal_Quality.inst.cfg | 2 +- ..._s5_aa0.4_aluminum_PP_Draft_Print.inst.cfg | 2 +- ...m_s5_aa0.4_aluminum_PP_Fast_Print.inst.cfg | 2 +- ..._aa0.4_aluminum_PP_Normal_Quality.inst.cfg | 2 +- .../um_s5_aa0.8_ABS_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_ABS_Superdraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_ABS_Verydraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_CPEP_Fast_Print.inst.cfg | 2 +- ...um_s5_aa0.8_CPEP_Superdraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_CPEP_Verydraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_CPE_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_CPE_Superdraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_CPE_Verydraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_Nylon_Draft_Print.inst.cfg | 2 +- ...m_s5_aa0.8_Nylon_Superdraft_Print.inst.cfg | 2 +- ...um_s5_aa0.8_Nylon_Verydraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_PC_Fast_Print.inst.cfg | 2 +- .../um_s5_aa0.8_PC_Superdraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_PC_Verydraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_PLA_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_PLA_Superdraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_PLA_Verydraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_PP_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_PP_Superdraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_PP_Verydraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_TPLA_Draft_Print.inst.cfg | 2 +- ...um_s5_aa0.8_TPLA_Superdraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_TPLA_Verydraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_TPU_Draft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_TPU_Superdraft_Print.inst.cfg | 2 +- .../um_s5_aa0.8_TPU_Verydraft_Print.inst.cfg | 2 +- ...s5_aa0.8_aluminum_ABS_Draft_Print.inst.cfg | 2 +- ...0.8_aluminum_ABS_Superdraft_Print.inst.cfg | 2 +- ...a0.8_aluminum_ABS_Verydraft_Print.inst.cfg | 2 +- ...s5_aa0.8_aluminum_CPEP_Fast_Print.inst.cfg | 2 +- ....8_aluminum_CPEP_Superdraft_Print.inst.cfg | 2 +- ...0.8_aluminum_CPEP_Verydraft_Print.inst.cfg | 2 +- ...s5_aa0.8_aluminum_CPE_Draft_Print.inst.cfg | 2 +- ...0.8_aluminum_CPE_Superdraft_Print.inst.cfg | 2 +- ...a0.8_aluminum_CPE_Verydraft_Print.inst.cfg | 2 +- ...m_s5_aa0.8_aluminum_PC_Fast_Print.inst.cfg | 2 +- ...a0.8_aluminum_PC_Superdraft_Print.inst.cfg | 2 +- ...aa0.8_aluminum_PC_Verydraft_Print.inst.cfg | 2 +- ..._s5_aa0.8_aluminum_PP_Draft_Print.inst.cfg | 2 +- ...a0.8_aluminum_PP_Superdraft_Print.inst.cfg | 2 +- ...aa0.8_aluminum_PP_Verydraft_Print.inst.cfg | 2 +- .../um_s5_bb0.4_PVA_Draft_Print.inst.cfg | 2 +- .../um_s5_bb0.4_PVA_Fast_Print.inst.cfg | 2 +- .../um_s5_bb0.4_PVA_High_Quality.inst.cfg | 2 +- .../um_s5_bb0.4_PVA_Normal_Quality.inst.cfg | 2 +- .../um_s5_bb0.8_PVA_Draft_Print.inst.cfg | 2 +- .../um_s5_bb0.8_PVA_Superdraft_Print.inst.cfg | 2 +- .../um_s5_bb0.8_PVA_Verydraft_Print.inst.cfg | 2 +- .../um_s5_cc0.6_CFFCPE_Draft_Print.inst.cfg | 2 +- .../um_s5_cc0.6_CFFPA_Draft_Print.inst.cfg | 2 +- .../um_s5_cc0.6_GFFCPE_Draft_Print.inst.cfg | 2 +- .../um_s5_cc0.6_GFFPA_Draft_Print.inst.cfg | 2 +- .../um_s5_global_Draft_Quality.inst.cfg | 2 +- .../um_s5_global_Fast_Quality.inst.cfg | 2 +- .../um_s5_global_High_Quality.inst.cfg | 2 +- .../um_s5_global_Normal_Quality.inst.cfg | 2 +- .../um_s5_global_Superdraft_Quality.inst.cfg | 2 +- .../um_s5_global_Verydraft_Quality.inst.cfg | 2 +- .../k8800_ABS_Extreme_Quality.inst.cfg | 2 +- .../k8800_ABS_High_Quality.inst.cfg | 2 +- .../k8800_ABS_Normal_Quality.inst.cfg | 2 +- .../k8800_Global_Extreme_Quality.inst.cfg | 2 +- .../k8800_Global_High_Quality.inst.cfg | 2 +- .../k8800_Global_Normal_Quality.inst.cfg | 2 +- .../k8800_PET_Extreme_Quality.inst.cfg | 2 +- .../k8800_PET_High_Quality.inst.cfg | 2 +- .../k8800_PET_Normal_Quality.inst.cfg | 2 +- .../k8800_PLA_Extreme_Quality.inst.cfg | 2 +- .../k8800_PLA_High_Quality.inst.cfg | 2 +- .../k8800_PLA_Normal_Quality.inst.cfg | 2 +- .../k8800_TPU_Extreme_Quality.inst.cfg | 2 +- .../k8800_TPU_High_Quality.inst.cfg | 2 +- .../k8800_TPU_Normal_Quality.inst.cfg | 2 +- .../zyyx/zyyx_agile_global_fast.inst.cfg | 2 +- .../zyyx/zyyx_agile_global_fine.inst.cfg | 2 +- .../zyyx/zyyx_agile_global_normal.inst.cfg | 2 +- .../zyyx/zyyx_agile_pro_flex_fast.inst.cfg | 2 +- .../zyyx/zyyx_agile_pro_flex_fine.inst.cfg | 2 +- .../zyyx/zyyx_agile_pro_flex_normal.inst.cfg | 2 +- .../zyyx/zyyx_agile_pro_pla_fast.inst.cfg | 2 +- .../zyyx/zyyx_agile_pro_pla_fine.inst.cfg | 2 +- .../zyyx/zyyx_agile_pro_pla_normal.inst.cfg | 2 +- resources/variants/cartesio_0.25.inst.cfg | 2 +- resources/variants/cartesio_0.4.inst.cfg | 2 +- resources/variants/cartesio_0.8.inst.cfg | 2 +- resources/variants/fabtotum_hyb35.inst.cfg | 2 +- resources/variants/fabtotum_lite04.inst.cfg | 2 +- resources/variants/fabtotum_lite06.inst.cfg | 2 +- resources/variants/fabtotum_pro02.inst.cfg | 2 +- resources/variants/fabtotum_pro04.inst.cfg | 2 +- resources/variants/fabtotum_pro06.inst.cfg | 2 +- resources/variants/fabtotum_pro08.inst.cfg | 2 +- resources/variants/felixtec4_0.25.inst.cfg | 2 +- resources/variants/felixtec4_0.35.inst.cfg | 2 +- resources/variants/felixtec4_0.50.inst.cfg | 2 +- resources/variants/felixtec4_0.70.inst.cfg | 2 +- .../variants/gmax15plus_025_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_04_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_05_e3d.inst.cfg | 2 +- .../variants/gmax15plus_05_jhead.inst.cfg | 2 +- resources/variants/gmax15plus_06_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_08_e3d.inst.cfg | 2 +- .../variants/gmax15plus_10_jhead.inst.cfg | 2 +- resources/variants/gmax15plus_12_e3d.inst.cfg | 2 +- .../variants/gmax15plus_dual_025_e3d.inst.cfg | 2 +- .../variants/gmax15plus_dual_04_e3d.inst.cfg | 2 +- .../variants/gmax15plus_dual_05_e3d.inst.cfg | 2 +- .../gmax15plus_dual_05_jhead.inst.cfg | 2 +- .../variants/gmax15plus_dual_06_e3d.inst.cfg | 2 +- .../variants/gmax15plus_dual_08_e3d.inst.cfg | 2 +- .../gmax15plus_dual_10_jhead.inst.cfg | 2 +- .../variants/imade3d_jellybox_0.4.inst.cfg | 2 +- .../imade3d_jellybox_0.4_2-fans.inst.cfg | 2 +- resources/variants/tizyx_k25_0.2.inst.cfg | 2 +- resources/variants/tizyx_k25_0.3.inst.cfg | 2 +- resources/variants/tizyx_k25_0.4.inst.cfg | 2 +- resources/variants/tizyx_k25_0.5.inst.cfg | 2 +- resources/variants/tizyx_k25_0.6.inst.cfg | 2 +- resources/variants/tizyx_k25_0.8.inst.cfg | 2 +- resources/variants/tizyx_k25_1.0.inst.cfg | 2 +- resources/variants/ultimaker2_0.25.inst.cfg | 2 +- resources/variants/ultimaker2_0.4.inst.cfg | 2 +- resources/variants/ultimaker2_0.6.inst.cfg | 2 +- resources/variants/ultimaker2_0.8.inst.cfg | 2 +- .../ultimaker2_extended_0.25.inst.cfg | 2 +- .../variants/ultimaker2_extended_0.4.inst.cfg | 2 +- .../variants/ultimaker2_extended_0.6.inst.cfg | 2 +- .../variants/ultimaker2_extended_0.8.inst.cfg | 2 +- .../ultimaker2_extended_plus_0.25.inst.cfg | 2 +- .../ultimaker2_extended_plus_0.4.inst.cfg | 2 +- .../ultimaker2_extended_plus_0.6.inst.cfg | 2 +- .../ultimaker2_extended_plus_0.8.inst.cfg | 2 +- .../variants/ultimaker2_plus_0.25.inst.cfg | 2 +- .../variants/ultimaker2_plus_0.4.inst.cfg | 2 +- .../variants/ultimaker2_plus_0.6.inst.cfg | 2 +- .../variants/ultimaker2_plus_0.8.inst.cfg | 2 +- resources/variants/ultimaker3_aa0.25.inst.cfg | 2 +- resources/variants/ultimaker3_aa0.8.inst.cfg | 2 +- resources/variants/ultimaker3_aa04.inst.cfg | 2 +- resources/variants/ultimaker3_bb0.8.inst.cfg | 2 +- resources/variants/ultimaker3_bb04.inst.cfg | 2 +- .../ultimaker3_extended_aa0.25.inst.cfg | 2 +- .../ultimaker3_extended_aa0.8.inst.cfg | 2 +- .../ultimaker3_extended_aa04.inst.cfg | 2 +- .../ultimaker3_extended_bb0.8.inst.cfg | 2 +- .../ultimaker3_extended_bb04.inst.cfg | 2 +- .../variants/ultimaker_s5_aa0.25.inst.cfg | 2 +- .../variants/ultimaker_s5_aa0.8.inst.cfg | 2 +- resources/variants/ultimaker_s5_aa04.inst.cfg | 2 +- .../variants/ultimaker_s5_aluminum.inst.cfg | 2 +- .../variants/ultimaker_s5_bb0.8.inst.cfg | 2 +- resources/variants/ultimaker_s5_bb04.inst.cfg | 2 +- resources/variants/ultimaker_s5_cc06.inst.cfg | 2 +- .../variants/ultimaker_s5_glass.inst.cfg | 2 +- 647 files changed, 675 insertions(+), 675 deletions(-) diff --git a/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg b/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg index 1ca2674e1f..875812f950 100644 --- a/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg +++ b/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = abax_pri3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/abax_pri3/apri3_pla_high.inst.cfg b/resources/quality/abax_pri3/apri3_pla_high.inst.cfg index e9e8d53a03..ed614faecd 100644 --- a/resources/quality/abax_pri3/apri3_pla_high.inst.cfg +++ b/resources/quality/abax_pri3/apri3_pla_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = abax_pri3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg b/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg index 40399c9548..855335780e 100644 --- a/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg +++ b/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = abax_pri3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg b/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg index c6d20f70da..55bfc6a755 100644 --- a/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg +++ b/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = abax_pri5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/abax_pri5/apri5_pla_high.inst.cfg b/resources/quality/abax_pri5/apri5_pla_high.inst.cfg index 99bd10d654..4d6abb7f78 100644 --- a/resources/quality/abax_pri5/apri5_pla_high.inst.cfg +++ b/resources/quality/abax_pri5/apri5_pla_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = abax_pri5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg b/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg index 55e0a7755a..a23f1808a1 100644 --- a/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg +++ b/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = abax_pri5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/abax_titan/atitan_pla_fast.inst.cfg b/resources/quality/abax_titan/atitan_pla_fast.inst.cfg index 6a2a49b555..bd099abec2 100644 --- a/resources/quality/abax_titan/atitan_pla_fast.inst.cfg +++ b/resources/quality/abax_titan/atitan_pla_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = abax_titan [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/abax_titan/atitan_pla_high.inst.cfg b/resources/quality/abax_titan/atitan_pla_high.inst.cfg index 7dd5833297..49482953cf 100644 --- a/resources/quality/abax_titan/atitan_pla_high.inst.cfg +++ b/resources/quality/abax_titan/atitan_pla_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = abax_titan [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/abax_titan/atitan_pla_normal.inst.cfg b/resources/quality/abax_titan/atitan_pla_normal.inst.cfg index b6aae46c6d..65cfb075f0 100644 --- a/resources/quality/abax_titan/atitan_pla_normal.inst.cfg +++ b/resources/quality/abax_titan/atitan_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = abax_titan [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/anycubic_4max/abs/anycubic_4max_abs_draft.inst.cfg b/resources/quality/anycubic_4max/abs/anycubic_4max_abs_draft.inst.cfg index e12954b6bc..47d6d80527 100644 --- a/resources/quality/anycubic_4max/abs/anycubic_4max_abs_draft.inst.cfg +++ b/resources/quality/anycubic_4max/abs/anycubic_4max_abs_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = anycubic_4max [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/anycubic_4max/abs/anycubic_4max_abs_high.inst.cfg b/resources/quality/anycubic_4max/abs/anycubic_4max_abs_high.inst.cfg index 0218b87a63..5f8e38800c 100644 --- a/resources/quality/anycubic_4max/abs/anycubic_4max_abs_high.inst.cfg +++ b/resources/quality/anycubic_4max/abs/anycubic_4max_abs_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = anycubic_4max [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/anycubic_4max/abs/anycubic_4max_abs_normal.inst.cfg b/resources/quality/anycubic_4max/abs/anycubic_4max_abs_normal.inst.cfg index f686855364..9fc17d2294 100644 --- a/resources/quality/anycubic_4max/abs/anycubic_4max_abs_normal.inst.cfg +++ b/resources/quality/anycubic_4max/abs/anycubic_4max_abs_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = anycubic_4max [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/anycubic_4max/anycubic_4max_draft.inst.cfg b/resources/quality/anycubic_4max/anycubic_4max_draft.inst.cfg index d9dc632c16..3d3f9fdca6 100644 --- a/resources/quality/anycubic_4max/anycubic_4max_draft.inst.cfg +++ b/resources/quality/anycubic_4max/anycubic_4max_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = anycubic_4max [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/anycubic_4max/anycubic_4max_high.inst.cfg b/resources/quality/anycubic_4max/anycubic_4max_high.inst.cfg index 55b5833c3f..f30a53af78 100644 --- a/resources/quality/anycubic_4max/anycubic_4max_high.inst.cfg +++ b/resources/quality/anycubic_4max/anycubic_4max_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = anycubic_4max [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/anycubic_4max/anycubic_4max_normal.inst.cfg b/resources/quality/anycubic_4max/anycubic_4max_normal.inst.cfg index 45c6f19f8b..e687709bd2 100644 --- a/resources/quality/anycubic_4max/anycubic_4max_normal.inst.cfg +++ b/resources/quality/anycubic_4max/anycubic_4max_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = anycubic_4max [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/anycubic_4max/hips/anycubic_4max_hips_draft.inst.cfg b/resources/quality/anycubic_4max/hips/anycubic_4max_hips_draft.inst.cfg index 97c19b7083..69c5b4684c 100644 --- a/resources/quality/anycubic_4max/hips/anycubic_4max_hips_draft.inst.cfg +++ b/resources/quality/anycubic_4max/hips/anycubic_4max_hips_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = anycubic_4max [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/anycubic_4max/hips/anycubic_4max_hips_high.inst.cfg b/resources/quality/anycubic_4max/hips/anycubic_4max_hips_high.inst.cfg index cfa727bcb8..7fcdbf065e 100644 --- a/resources/quality/anycubic_4max/hips/anycubic_4max_hips_high.inst.cfg +++ b/resources/quality/anycubic_4max/hips/anycubic_4max_hips_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = anycubic_4max [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/anycubic_4max/hips/anycubic_4max_hips_normal.inst.cfg b/resources/quality/anycubic_4max/hips/anycubic_4max_hips_normal.inst.cfg index f4372939f5..dd1babf627 100644 --- a/resources/quality/anycubic_4max/hips/anycubic_4max_hips_normal.inst.cfg +++ b/resources/quality/anycubic_4max/hips/anycubic_4max_hips_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = anycubic_4max [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/anycubic_4max/petg/anycubic_4max_petg_draft.inst.cfg b/resources/quality/anycubic_4max/petg/anycubic_4max_petg_draft.inst.cfg index 124bd487b0..84b11721de 100644 --- a/resources/quality/anycubic_4max/petg/anycubic_4max_petg_draft.inst.cfg +++ b/resources/quality/anycubic_4max/petg/anycubic_4max_petg_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = anycubic_4max [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/anycubic_4max/petg/anycubic_4max_petg_high.inst.cfg b/resources/quality/anycubic_4max/petg/anycubic_4max_petg_high.inst.cfg index eeaaac6270..90277985bb 100644 --- a/resources/quality/anycubic_4max/petg/anycubic_4max_petg_high.inst.cfg +++ b/resources/quality/anycubic_4max/petg/anycubic_4max_petg_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = anycubic_4max [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/anycubic_4max/petg/anycubic_4max_petg_normal.inst.cfg b/resources/quality/anycubic_4max/petg/anycubic_4max_petg_normal.inst.cfg index ec0579015a..3ce5342684 100644 --- a/resources/quality/anycubic_4max/petg/anycubic_4max_petg_normal.inst.cfg +++ b/resources/quality/anycubic_4max/petg/anycubic_4max_petg_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = anycubic_4max [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/anycubic_4max/pla/anycubic_4max_pla_draft.inst.cfg b/resources/quality/anycubic_4max/pla/anycubic_4max_pla_draft.inst.cfg index b72ce43e29..9fce900fc2 100644 --- a/resources/quality/anycubic_4max/pla/anycubic_4max_pla_draft.inst.cfg +++ b/resources/quality/anycubic_4max/pla/anycubic_4max_pla_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = anycubic_4max [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/anycubic_4max/pla/anycubic_4max_pla_high.inst.cfg b/resources/quality/anycubic_4max/pla/anycubic_4max_pla_high.inst.cfg index 4386159a66..5bc075d316 100644 --- a/resources/quality/anycubic_4max/pla/anycubic_4max_pla_high.inst.cfg +++ b/resources/quality/anycubic_4max/pla/anycubic_4max_pla_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = anycubic_4max [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/anycubic_4max/pla/anycubic_4max_pla_normal.inst.cfg b/resources/quality/anycubic_4max/pla/anycubic_4max_pla_normal.inst.cfg index 9998fff2ad..50fd145fd2 100644 --- a/resources/quality/anycubic_4max/pla/anycubic_4max_pla_normal.inst.cfg +++ b/resources/quality/anycubic_4max/pla/anycubic_4max_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = anycubic_4max [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg index ba99d30de6..dddc657296 100644 --- a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg +++ b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = anycubic_i3_mega [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg index b1092b115c..87ec96ed96 100644 --- a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg +++ b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = anycubic_i3_mega [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg index d088d650a0..526cb9bc5e 100644 --- a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg +++ b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = anycubic_i3_mega [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/builder_premium/bp_BVOH_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_BVOH_Coarse_Quality.inst.cfg index 491d24c919..c5ccd5a864 100644 --- a/resources/quality/builder_premium/bp_BVOH_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_BVOH_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = builder_premium_small [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = coarse weight = -1 diff --git a/resources/quality/builder_premium/bp_BVOH_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_BVOH_High_Quality.inst.cfg index 3ff0f07ac1..b2a5811bfa 100644 --- a/resources/quality/builder_premium/bp_BVOH_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_BVOH_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High Quality definition = builder_premium_small [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/builder_premium/bp_BVOH_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_BVOH_Normal_Quality.inst.cfg index cf67185706..8c727d9bd3 100644 --- a/resources/quality/builder_premium/bp_BVOH_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_BVOH_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = builder_premium_small [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/builder_premium/bp_Innoflex60_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_Innoflex60_Coarse_Quality.inst.cfg index aedb45a2b1..07f6404f62 100644 --- a/resources/quality/builder_premium/bp_Innoflex60_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_Innoflex60_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = builder_premium_small [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = coarse weight = -1 diff --git a/resources/quality/builder_premium/bp_Innoflex60_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_Innoflex60_High_Quality.inst.cfg index 08fb395a36..df42b0ee3b 100644 --- a/resources/quality/builder_premium/bp_Innoflex60_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_Innoflex60_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High Quality definition = builder_premium_small [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/builder_premium/bp_Innoflex60_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_Innoflex60_Normal_Quality.inst.cfg index 008de91758..dca42bc4c0 100644 --- a/resources/quality/builder_premium/bp_Innoflex60_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_Innoflex60_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = builder_premium_small [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/builder_premium/bp_PET_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_PET_Coarse_Quality.inst.cfg index 0e2c26812b..a5099b36b8 100644 --- a/resources/quality/builder_premium/bp_PET_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PET_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = builder_premium_small [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = coarse weight = -1 diff --git a/resources/quality/builder_premium/bp_PET_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_PET_High_Quality.inst.cfg index 8217ca9156..cad98cba5c 100644 --- a/resources/quality/builder_premium/bp_PET_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PET_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High Quality definition = builder_premium_small [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/builder_premium/bp_PET_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_PET_Normal_Quality.inst.cfg index 48b2df0cae..dcf7974c4c 100644 --- a/resources/quality/builder_premium/bp_PET_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PET_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = builder_premium_small [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/builder_premium/bp_PLA_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_PLA_Coarse_Quality.inst.cfg index 6834cbb2c4..4eec6d3d4f 100644 --- a/resources/quality/builder_premium/bp_PLA_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PLA_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = builder_premium_small [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = coarse weight = -1 diff --git a/resources/quality/builder_premium/bp_PLA_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_PLA_High_Quality.inst.cfg index 9fc5426cf9..a94bfab748 100644 --- a/resources/quality/builder_premium/bp_PLA_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PLA_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High Quality definition = builder_premium_small [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/builder_premium/bp_PLA_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_PLA_Normal_Quality.inst.cfg index 161bee24df..83fe257b96 100644 --- a/resources/quality/builder_premium/bp_PLA_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PLA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = builder_premium_small [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/builder_premium/bp_PVA_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_PVA_Coarse_Quality.inst.cfg index 149b938bac..06e337be77 100644 --- a/resources/quality/builder_premium/bp_PVA_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PVA_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = builder_premium_small [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = coarse weight = -1 diff --git a/resources/quality/builder_premium/bp_PVA_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_PVA_High_Quality.inst.cfg index ba310a0890..e2f002343e 100644 --- a/resources/quality/builder_premium/bp_PVA_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PVA_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High Quality definition = builder_premium_small [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/builder_premium/bp_PVA_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_PVA_Normal_Quality.inst.cfg index 4ab949957f..0e026befb2 100644 --- a/resources/quality/builder_premium/bp_PVA_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PVA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = builder_premium_small [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/builder_premium/bp_global_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_global_Coarse_Quality.inst.cfg index 9a85c924ee..2638a06d89 100644 --- a/resources/quality/builder_premium/bp_global_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_global_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = builder_premium_small [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = coarse weight = -1 diff --git a/resources/quality/builder_premium/bp_global_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_global_High_Quality.inst.cfg index ca2f8c843f..89b6720617 100644 --- a/resources/quality/builder_premium/bp_global_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_global_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High Quality definition = builder_premium_small [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/builder_premium/bp_global_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_global_Normal_Quality.inst.cfg index 3b24f9963d..68c9f5102b 100644 --- a/resources/quality/builder_premium/bp_global_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_global_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = builder_premium_small [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/abs/cartesio_0.25_abs_high.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.25_abs_high.inst.cfg index f19635331d..fd1a1ece09 100644 --- a/resources/quality/cartesio/abs/cartesio_0.25_abs_high.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.25_abs_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg index 14babfa93d..909a23edeb 100644 --- a/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/abs/cartesio_0.4_abs_high.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.4_abs_high.inst.cfg index 99e1290c77..b66931ef40 100644 --- a/resources/quality/cartesio/abs/cartesio_0.4_abs_high.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.4_abs_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg index 32c306ba71..d29b3acf65 100644 --- a/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg index 5496468fd6..dc910c5e06 100644 --- a/resources/quality/cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = coarse weight = 3 diff --git a/resources/quality/cartesio/abs/cartesio_0.8_abs_extra_coarse.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.8_abs_extra_coarse.inst.cfg index 360397ddc9..2792261dd6 100644 --- a/resources/quality/cartesio/abs/cartesio_0.8_abs_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.8_abs_extra_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = extra coarse weight = 4 diff --git a/resources/quality/cartesio/abs/cartesio_0.8_abs_high.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.8_abs_high.inst.cfg index 82e0afa853..498afd9772 100644 --- a/resources/quality/cartesio/abs/cartesio_0.8_abs_high.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.8_abs_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg index 20ba9b777d..66b467de07 100644 --- a/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_high.inst.cfg b/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_high.inst.cfg index fa89b4c3aa..d030257fb0 100644 --- a/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_high.inst.cfg +++ b/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg b/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg index 63abbf1cc5..c606e778b6 100644 --- a/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg +++ b/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/cartesio_global_Coarse_Quality.inst.cfg b/resources/quality/cartesio/cartesio_global_Coarse_Quality.inst.cfg index 7ce1111dd8..77a1c7312c 100644 --- a/resources/quality/cartesio/cartesio_global_Coarse_Quality.inst.cfg +++ b/resources/quality/cartesio/cartesio_global_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = coarse weight = -3 diff --git a/resources/quality/cartesio/cartesio_global_Extra_Coarse_Quality.inst.cfg b/resources/quality/cartesio/cartesio_global_Extra_Coarse_Quality.inst.cfg index 0369c74e2a..8f9d28bbac 100644 --- a/resources/quality/cartesio/cartesio_global_Extra_Coarse_Quality.inst.cfg +++ b/resources/quality/cartesio/cartesio_global_Extra_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = extra coarse weight = -4 diff --git a/resources/quality/cartesio/cartesio_global_High_Quality.inst.cfg b/resources/quality/cartesio/cartesio_global_High_Quality.inst.cfg index dafe5ef621..9faeef3b42 100644 --- a/resources/quality/cartesio/cartesio_global_High_Quality.inst.cfg +++ b/resources/quality/cartesio/cartesio_global_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/cartesio_global_Normal_Quality.inst.cfg b/resources/quality/cartesio/cartesio_global_Normal_Quality.inst.cfg index 100da3c70a..3dae1d45d7 100644 --- a/resources/quality/cartesio/cartesio_global_Normal_Quality.inst.cfg +++ b/resources/quality/cartesio/cartesio_global_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/hips/cartesio_0.25_hips_high.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.25_hips_high.inst.cfg index 93e04e1514..61000f0912 100644 --- a/resources/quality/cartesio/hips/cartesio_0.25_hips_high.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.25_hips_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg index ba3f88ce13..4d4cf5e37d 100644 --- a/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/hips/cartesio_0.4_hips_high.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.4_hips_high.inst.cfg index 91b1627650..76071d46bc 100644 --- a/resources/quality/cartesio/hips/cartesio_0.4_hips_high.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.4_hips_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg index a2f817aef2..304f38e105 100644 --- a/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg index 6b84c5e864..5aaede062d 100644 --- a/resources/quality/cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = coarse weight = 3 diff --git a/resources/quality/cartesio/hips/cartesio_0.8_hips_extra_coarse.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.8_hips_extra_coarse.inst.cfg index 16f299813b..75a4b94541 100644 --- a/resources/quality/cartesio/hips/cartesio_0.8_hips_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.8_hips_extra_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = extra coarse weight = 4 diff --git a/resources/quality/cartesio/hips/cartesio_0.8_hips_high.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.8_hips_high.inst.cfg index 686759bc4d..391c87f28c 100644 --- a/resources/quality/cartesio/hips/cartesio_0.8_hips_high.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.8_hips_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg index 654564f291..415951f4ee 100644 --- a/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg index bd2dca940f..f75dd933a6 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg index 55d22623bb..e95037c242 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg index 05e9abbe8f..4896d60aca 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg index 51327c844a..803cb2b849 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg index 279e2d98bf..7217d3524d 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = coarse weight = 3 diff --git a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg index 69f9a8caad..8a7b46a817 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = extra coarse weight = 4 diff --git a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg index ff4d152ef2..41dd55cfce 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg index f181244796..75cd29e4a3 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/pc/cartesio_0.25_pc_high.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.25_pc_high.inst.cfg index 15c7f17451..66c425078d 100644 --- a/resources/quality/cartesio/pc/cartesio_0.25_pc_high.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.25_pc_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg index 91676e65f0..eea872ed0f 100644 --- a/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg index 73e1ff6bc5..12327636a7 100644 --- a/resources/quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg index d217756cb4..70c4f68135 100644 --- a/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg index cba868e95e..cd4f112370 100644 --- a/resources/quality/cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = coarse weight = 3 diff --git a/resources/quality/cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg index 4aff24ed02..9fae8bfe23 100644 --- a/resources/quality/cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = extra coarse weight = 4 diff --git a/resources/quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg index f00e83f63e..bebffc072b 100644 --- a/resources/quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg index 2f8ed80751..40c47b24a1 100644 --- a/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/petg/cartesio_0.25_petg_high.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.25_petg_high.inst.cfg index 3c8dcc7af6..3b6e326495 100644 --- a/resources/quality/cartesio/petg/cartesio_0.25_petg_high.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.25_petg_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg index 7aedc76af9..17efcfc1ce 100644 --- a/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/petg/cartesio_0.4_petg_high.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.4_petg_high.inst.cfg index 3788a4dd51..9c6840d5ba 100644 --- a/resources/quality/cartesio/petg/cartesio_0.4_petg_high.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.4_petg_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg index 4805ca55bb..9fe00be066 100644 --- a/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg index d7d6e35a3c..6da3d2100a 100644 --- a/resources/quality/cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = coarse weight = 3 diff --git a/resources/quality/cartesio/petg/cartesio_0.8_petg_extra_coarse.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.8_petg_extra_coarse.inst.cfg index 784bd0d6af..c6d45d5faa 100644 --- a/resources/quality/cartesio/petg/cartesio_0.8_petg_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.8_petg_extra_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = extra coarse weight = 4 diff --git a/resources/quality/cartesio/petg/cartesio_0.8_petg_high.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.8_petg_high.inst.cfg index bced328a9c..4a06499b5f 100644 --- a/resources/quality/cartesio/petg/cartesio_0.8_petg_high.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.8_petg_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg index 2a9da4f164..2ab3fe3340 100644 --- a/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/pla/cartesio_0.25_pla_high.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.25_pla_high.inst.cfg index 15456a0b78..7d19528283 100644 --- a/resources/quality/cartesio/pla/cartesio_0.25_pla_high.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.25_pla_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/pla/cartesio_0.25_pla_normal.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.25_pla_normal.inst.cfg index bfa792f133..994f9b886a 100644 --- a/resources/quality/cartesio/pla/cartesio_0.25_pla_normal.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.25_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/pla/cartesio_0.4_pla_high.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.4_pla_high.inst.cfg index e64b67b59b..f8227cfcd9 100644 --- a/resources/quality/cartesio/pla/cartesio_0.4_pla_high.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.4_pla_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/pla/cartesio_0.4_pla_normal.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.4_pla_normal.inst.cfg index 704a974b63..385b79e368 100644 --- a/resources/quality/cartesio/pla/cartesio_0.4_pla_normal.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.4_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg index b8ff99c256..b99a972195 100644 --- a/resources/quality/cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = coarse weight = -3 diff --git a/resources/quality/cartesio/pla/cartesio_0.8_pla_extra_coarse.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.8_pla_extra_coarse.inst.cfg index da613e6e1a..31fd7ddb8a 100644 --- a/resources/quality/cartesio/pla/cartesio_0.8_pla_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.8_pla_extra_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = extra coarse weight = -4 diff --git a/resources/quality/cartesio/pla/cartesio_0.8_pla_high.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.8_pla_high.inst.cfg index 05c0f72686..c93923e70a 100644 --- a/resources/quality/cartesio/pla/cartesio_0.8_pla_high.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.8_pla_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/pla/cartesio_0.8_pla_normal.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.8_pla_normal.inst.cfg index 8434f4abc6..98e2a9bbbb 100644 --- a/resources/quality/cartesio/pla/cartesio_0.8_pla_normal.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.8_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/pva/cartesio_0.25_pva_high.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.25_pva_high.inst.cfg index 7df550917f..444ac7bbc4 100644 --- a/resources/quality/cartesio/pva/cartesio_0.25_pva_high.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.25_pva_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg index 1f1d9549fb..0b03607e34 100644 --- a/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/pva/cartesio_0.4_pva_high.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.4_pva_high.inst.cfg index faf1633ce2..b08e0d2671 100644 --- a/resources/quality/cartesio/pva/cartesio_0.4_pva_high.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.4_pva_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg index 1dc24190c6..32ce160df1 100644 --- a/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg index 35b2d1690d..a6fdd82b5c 100644 --- a/resources/quality/cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = coarse weight = 3 diff --git a/resources/quality/cartesio/pva/cartesio_0.8_pva_extra_coarse.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.8_pva_extra_coarse.inst.cfg index 3d41308a5d..496ecc085d 100644 --- a/resources/quality/cartesio/pva/cartesio_0.8_pva_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.8_pva_extra_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = extra coarse weight = 4 diff --git a/resources/quality/cartesio/pva/cartesio_0.8_pva_high.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.8_pva_high.inst.cfg index 0293ee9acb..e440fdfe3f 100644 --- a/resources/quality/cartesio/pva/cartesio_0.8_pva_high.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.8_pva_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg index ae3d51a03f..c1ad10abe1 100644 --- a/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = cartesio [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/coarse.inst.cfg b/resources/quality/coarse.inst.cfg index 77b9004aa6..3f5e3f47ce 100644 --- a/resources/quality/coarse.inst.cfg +++ b/resources/quality/coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = fdmprinter [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = coarse weight = -3 diff --git a/resources/quality/dagoma/dagoma_discoeasy200_pla_fast.inst.cfg b/resources/quality/dagoma/dagoma_discoeasy200_pla_fast.inst.cfg index b12a92dc1c..89c5c957f6 100644 --- a/resources/quality/dagoma/dagoma_discoeasy200_pla_fast.inst.cfg +++ b/resources/quality/dagoma/dagoma_discoeasy200_pla_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = dagoma_discoeasy200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/dagoma/dagoma_discoeasy200_pla_fine.inst.cfg b/resources/quality/dagoma/dagoma_discoeasy200_pla_fine.inst.cfg index 055b3e30d6..5b24e6edcf 100644 --- a/resources/quality/dagoma/dagoma_discoeasy200_pla_fine.inst.cfg +++ b/resources/quality/dagoma/dagoma_discoeasy200_pla_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = dagoma_discoeasy200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/dagoma/dagoma_discoeasy200_pla_standard.inst.cfg b/resources/quality/dagoma/dagoma_discoeasy200_pla_standard.inst.cfg index 7c244b3f18..c9bc62a72a 100644 --- a/resources/quality/dagoma/dagoma_discoeasy200_pla_standard.inst.cfg +++ b/resources/quality/dagoma/dagoma_discoeasy200_pla_standard.inst.cfg @@ -4,7 +4,7 @@ name = Standard definition = dagoma_discoeasy200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/dagoma/dagoma_global_fast.inst.cfg b/resources/quality/dagoma/dagoma_global_fast.inst.cfg index f0d312e0a7..a37d3fb579 100644 --- a/resources/quality/dagoma/dagoma_global_fast.inst.cfg +++ b/resources/quality/dagoma/dagoma_global_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = dagoma_discoeasy200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/dagoma/dagoma_global_fine.inst.cfg b/resources/quality/dagoma/dagoma_global_fine.inst.cfg index bf0a173ec3..4815dc44cd 100644 --- a/resources/quality/dagoma/dagoma_global_fine.inst.cfg +++ b/resources/quality/dagoma/dagoma_global_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = dagoma_discoeasy200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/dagoma/dagoma_global_standard.inst.cfg b/resources/quality/dagoma/dagoma_global_standard.inst.cfg index afeb925e96..5be7fb75c9 100644 --- a/resources/quality/dagoma/dagoma_global_standard.inst.cfg +++ b/resources/quality/dagoma/dagoma_global_standard.inst.cfg @@ -4,7 +4,7 @@ name = Standard definition = dagoma_discoeasy200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/dagoma/dagoma_magis_pla_fast.inst.cfg b/resources/quality/dagoma/dagoma_magis_pla_fast.inst.cfg index 8387ff2401..99a1f9e61b 100644 --- a/resources/quality/dagoma/dagoma_magis_pla_fast.inst.cfg +++ b/resources/quality/dagoma/dagoma_magis_pla_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = dagoma_magis [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/dagoma/dagoma_magis_pla_fine.inst.cfg b/resources/quality/dagoma/dagoma_magis_pla_fine.inst.cfg index 60c0cae7ec..12e7f2c62f 100644 --- a/resources/quality/dagoma/dagoma_magis_pla_fine.inst.cfg +++ b/resources/quality/dagoma/dagoma_magis_pla_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = dagoma_magis [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/dagoma/dagoma_magis_pla_standard.inst.cfg b/resources/quality/dagoma/dagoma_magis_pla_standard.inst.cfg index b406d43cb1..62054acb4e 100644 --- a/resources/quality/dagoma/dagoma_magis_pla_standard.inst.cfg +++ b/resources/quality/dagoma/dagoma_magis_pla_standard.inst.cfg @@ -4,7 +4,7 @@ name = Standard definition = dagoma_magis [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/dagoma/dagoma_neva_pla_fast.inst.cfg b/resources/quality/dagoma/dagoma_neva_pla_fast.inst.cfg index c0e8d7fe94..ea024726ac 100644 --- a/resources/quality/dagoma/dagoma_neva_pla_fast.inst.cfg +++ b/resources/quality/dagoma/dagoma_neva_pla_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = dagoma_neva [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/dagoma/dagoma_neva_pla_fine.inst.cfg b/resources/quality/dagoma/dagoma_neva_pla_fine.inst.cfg index b6d6966c81..a69798ff2e 100644 --- a/resources/quality/dagoma/dagoma_neva_pla_fine.inst.cfg +++ b/resources/quality/dagoma/dagoma_neva_pla_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = dagoma_neva [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/dagoma/dagoma_neva_pla_standard.inst.cfg b/resources/quality/dagoma/dagoma_neva_pla_standard.inst.cfg index eff587c908..fd92ed4416 100644 --- a/resources/quality/dagoma/dagoma_neva_pla_standard.inst.cfg +++ b/resources/quality/dagoma/dagoma_neva_pla_standard.inst.cfg @@ -4,7 +4,7 @@ name = Standard definition = dagoma_neva [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/deltacomb/deltacomb_abs_Draft_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_abs_Draft_Quality.inst.cfg index 9316a84175..9ac0791b7d 100644 --- a/resources/quality/deltacomb/deltacomb_abs_Draft_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_abs_Draft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fast (beta) definition = deltacomb [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/deltacomb/deltacomb_abs_Fast_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_abs_Fast_Quality.inst.cfg index a2c67ff890..43d6bfb778 100644 --- a/resources/quality/deltacomb/deltacomb_abs_Fast_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_abs_Fast_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal (beta) definition = deltacomb [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/deltacomb/deltacomb_abs_High_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_abs_High_Quality.inst.cfg index be428bb8f4..7116247ca3 100644 --- a/resources/quality/deltacomb/deltacomb_abs_High_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_abs_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine (beta) definition = deltacomb [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/deltacomb/deltacomb_abs_Normal_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_abs_Normal_Quality.inst.cfg index 1f4184f3ad..9b968e1a47 100644 --- a/resources/quality/deltacomb/deltacomb_abs_Normal_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_abs_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine (beta) definition = deltacomb [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/deltacomb/deltacomb_abs_Verydraft_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_abs_Verydraft_Quality.inst.cfg index 37925e0e4c..68846ce68b 100644 --- a/resources/quality/deltacomb/deltacomb_abs_Verydraft_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_abs_Verydraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast (beta) definition = deltacomb [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/deltacomb/deltacomb_global_Draft_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_global_Draft_Quality.inst.cfg index 072f0435f6..6f63b0f5b4 100755 --- a/resources/quality/deltacomb/deltacomb_global_Draft_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_global_Draft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = deltacomb [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/deltacomb/deltacomb_global_Fast_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_global_Fast_Quality.inst.cfg index eef96e35b8..2d76f87d66 100755 --- a/resources/quality/deltacomb/deltacomb_global_Fast_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_global_Fast_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = deltacomb [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/deltacomb/deltacomb_global_High_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_global_High_Quality.inst.cfg index becd10ea65..6495b09042 100755 --- a/resources/quality/deltacomb/deltacomb_global_High_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_global_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = deltacomb [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/deltacomb/deltacomb_global_Normal_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_global_Normal_Quality.inst.cfg index 4c95c74cfa..7bd4591064 100755 --- a/resources/quality/deltacomb/deltacomb_global_Normal_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_global_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = deltacomb [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/deltacomb/deltacomb_global_Verydraft_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_global_Verydraft_Quality.inst.cfg index 0ba6ca588f..a13d029c1a 100755 --- a/resources/quality/deltacomb/deltacomb_global_Verydraft_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_global_Verydraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = deltacomb [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/deltacomb/deltacomb_pla_Draft_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_pla_Draft_Quality.inst.cfg index e0e695570d..d5387f3014 100644 --- a/resources/quality/deltacomb/deltacomb_pla_Draft_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_pla_Draft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = deltacomb [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/deltacomb/deltacomb_pla_Fast_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_pla_Fast_Quality.inst.cfg index 3f43871a8f..b41eb9d81f 100644 --- a/resources/quality/deltacomb/deltacomb_pla_Fast_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_pla_Fast_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = deltacomb [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/deltacomb/deltacomb_pla_High_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_pla_High_Quality.inst.cfg index b3924431af..ceaeb4667e 100644 --- a/resources/quality/deltacomb/deltacomb_pla_High_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_pla_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = deltacomb [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/deltacomb/deltacomb_pla_Normal_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_pla_Normal_Quality.inst.cfg index 98ec4f46cd..ba82feb97d 100644 --- a/resources/quality/deltacomb/deltacomb_pla_Normal_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_pla_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = deltacomb [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/deltacomb/deltacomb_pla_Verydraft_Quality.inst.cfg b/resources/quality/deltacomb/deltacomb_pla_Verydraft_Quality.inst.cfg index f67a2d8a26..f312c27233 100644 --- a/resources/quality/deltacomb/deltacomb_pla_Verydraft_Quality.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_pla_Verydraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = deltacomb [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/draft.inst.cfg b/resources/quality/draft.inst.cfg index a605b9c83c..9fe798dfd4 100644 --- a/resources/quality/draft.inst.cfg +++ b/resources/quality/draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = fdmprinter [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/extra_coarse.inst.cfg b/resources/quality/extra_coarse.inst.cfg index bf22b7ac3c..1a9ade143d 100644 --- a/resources/quality/extra_coarse.inst.cfg +++ b/resources/quality/extra_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse definition = fdmprinter [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = extra coarse weight = -4 diff --git a/resources/quality/extra_fast.inst.cfg b/resources/quality/extra_fast.inst.cfg index eb1e7b3a42..1fcc9bc42d 100644 --- a/resources/quality/extra_fast.inst.cfg +++ b/resources/quality/extra_fast.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = fdmprinter [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/fabtotum/fabtotum_abs_fast.inst.cfg b/resources/quality/fabtotum/fabtotum_abs_fast.inst.cfg index 036d49a94f..ddcdc0632d 100644 --- a/resources/quality/fabtotum/fabtotum_abs_fast.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_abs_fast.inst.cfg @@ -4,7 +4,7 @@ definition = fabtotum name = Fast Quality [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/fabtotum/fabtotum_abs_high.inst.cfg b/resources/quality/fabtotum/fabtotum_abs_high.inst.cfg index f3d6f33952..66faed5084 100644 --- a/resources/quality/fabtotum/fabtotum_abs_high.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_abs_high.inst.cfg @@ -4,7 +4,7 @@ definition = fabtotum name = High Quality [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/fabtotum/fabtotum_abs_normal.inst.cfg b/resources/quality/fabtotum/fabtotum_abs_normal.inst.cfg index d01599a392..2bd980889b 100644 --- a/resources/quality/fabtotum/fabtotum_abs_normal.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_abs_normal.inst.cfg @@ -4,7 +4,7 @@ definition = fabtotum name = Normal Quality [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/fabtotum/fabtotum_nylon_fast.inst.cfg b/resources/quality/fabtotum/fabtotum_nylon_fast.inst.cfg index 1f0c050126..cec7056ff1 100644 --- a/resources/quality/fabtotum/fabtotum_nylon_fast.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_nylon_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fast Quality definition = fabtotum [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/fabtotum/fabtotum_nylon_high.inst.cfg b/resources/quality/fabtotum/fabtotum_nylon_high.inst.cfg index 4e234f62f8..d5a893c408 100644 --- a/resources/quality/fabtotum/fabtotum_nylon_high.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_nylon_high.inst.cfg @@ -4,7 +4,7 @@ name = High Quality definition = fabtotum [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/fabtotum/fabtotum_nylon_normal.inst.cfg b/resources/quality/fabtotum/fabtotum_nylon_normal.inst.cfg index 67998dea38..7fe1b8b8f3 100644 --- a/resources/quality/fabtotum/fabtotum_nylon_normal.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_nylon_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal Quality definition = fabtotum [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/fabtotum/fabtotum_pla_fast.inst.cfg b/resources/quality/fabtotum/fabtotum_pla_fast.inst.cfg index e27477e8de..5ebe5bbdc2 100644 --- a/resources/quality/fabtotum/fabtotum_pla_fast.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_pla_fast.inst.cfg @@ -4,7 +4,7 @@ definition = fabtotum name = Fast Quality [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/fabtotum/fabtotum_pla_high.inst.cfg b/resources/quality/fabtotum/fabtotum_pla_high.inst.cfg index bab6d5fc82..5d5b582b82 100644 --- a/resources/quality/fabtotum/fabtotum_pla_high.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_pla_high.inst.cfg @@ -4,7 +4,7 @@ definition = fabtotum name = High Quality [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/fabtotum/fabtotum_pla_normal.inst.cfg b/resources/quality/fabtotum/fabtotum_pla_normal.inst.cfg index 7bd3bc024e..1c510293a1 100644 --- a/resources/quality/fabtotum/fabtotum_pla_normal.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_pla_normal.inst.cfg @@ -4,7 +4,7 @@ definition = fabtotum name = Normal Quality [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/fabtotum/fabtotum_tpu_fast.inst.cfg b/resources/quality/fabtotum/fabtotum_tpu_fast.inst.cfg index 5668d4a5b9..21a0c9bc09 100644 --- a/resources/quality/fabtotum/fabtotum_tpu_fast.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_tpu_fast.inst.cfg @@ -5,7 +5,7 @@ name = Fast Quality [metadata] type = quality -setting_version = 6 +setting_version = 7 material = generic_tpu quality_type = fast weight = -1 diff --git a/resources/quality/fabtotum/fabtotum_tpu_high.inst.cfg b/resources/quality/fabtotum/fabtotum_tpu_high.inst.cfg index 6af9e88f00..dd27372a07 100644 --- a/resources/quality/fabtotum/fabtotum_tpu_high.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_tpu_high.inst.cfg @@ -5,7 +5,7 @@ name = High Quality [metadata] type = quality -setting_version = 6 +setting_version = 7 material = generic_tpu quality_type = high weight = 1 diff --git a/resources/quality/fabtotum/fabtotum_tpu_normal.inst.cfg b/resources/quality/fabtotum/fabtotum_tpu_normal.inst.cfg index 13faf5bc2f..b7eefeeeeb 100644 --- a/resources/quality/fabtotum/fabtotum_tpu_normal.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_tpu_normal.inst.cfg @@ -5,7 +5,7 @@ name = Normal Quality [metadata] type = quality -setting_version = 6 +setting_version = 7 material = generic_tpu quality_type = normal weight = 0 diff --git a/resources/quality/fast.inst.cfg b/resources/quality/fast.inst.cfg index 94a7961320..d92eeb3ed2 100644 --- a/resources/quality/fast.inst.cfg +++ b/resources/quality/fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = fdmprinter [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/gmax15plus/gmax15plus_global_dual_normal.inst.cfg b/resources/quality/gmax15plus/gmax15plus_global_dual_normal.inst.cfg index 3c9c9c0dfd..7ea63ba7f9 100644 --- a/resources/quality/gmax15plus/gmax15plus_global_dual_normal.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_global_dual_normal.inst.cfg @@ -4,7 +4,7 @@ name = gMax 1.5+ Dual Normal Layers definition = gmax15plus_dual [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/gmax15plus/gmax15plus_global_dual_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_global_dual_thick.inst.cfg index 24740362af..95182aad2d 100644 --- a/resources/quality/gmax15plus/gmax15plus_global_dual_thick.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_global_dual_thick.inst.cfg @@ -4,7 +4,7 @@ name = gMax 1.5+ Dual Thick Layers definition = gmax15plus_dual [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = course weight = -2 diff --git a/resources/quality/gmax15plus/gmax15plus_global_dual_thin.inst.cfg b/resources/quality/gmax15plus/gmax15plus_global_dual_thin.inst.cfg index 845a1c2c39..05e9a84bb4 100644 --- a/resources/quality/gmax15plus/gmax15plus_global_dual_thin.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_global_dual_thin.inst.cfg @@ -4,7 +4,7 @@ name = gMax 1.5+ Dual Thin Layers definition = gmax15plus_dual [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/gmax15plus/gmax15plus_global_dual_very_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_global_dual_very_thick.inst.cfg index 4dbd81255a..fd986e6c1f 100644 --- a/resources/quality/gmax15plus/gmax15plus_global_dual_very_thick.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_global_dual_very_thick.inst.cfg @@ -4,7 +4,7 @@ name = gMax 1.5+ Dual Very Thick Layers definition = gmax15plus_dual [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = extra_course weight = -3 diff --git a/resources/quality/gmax15plus/gmax15plus_global_normal.inst.cfg b/resources/quality/gmax15plus/gmax15plus_global_normal.inst.cfg index 8b91006184..fa50fcee4c 100644 --- a/resources/quality/gmax15plus/gmax15plus_global_normal.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_global_normal.inst.cfg @@ -4,7 +4,7 @@ name = gMax 1.5+ Normal Layers definition = gmax15plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/gmax15plus/gmax15plus_global_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_global_thick.inst.cfg index c5ef9fdf83..e5fd46edbc 100644 --- a/resources/quality/gmax15plus/gmax15plus_global_thick.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_global_thick.inst.cfg @@ -4,7 +4,7 @@ name = gMax 1.5+ Thick Layers definition = gmax15plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = course weight = -2 diff --git a/resources/quality/gmax15plus/gmax15plus_global_thin.inst.cfg b/resources/quality/gmax15plus/gmax15plus_global_thin.inst.cfg index b3a2ed8d82..cc19a478e5 100644 --- a/resources/quality/gmax15plus/gmax15plus_global_thin.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_global_thin.inst.cfg @@ -4,7 +4,7 @@ name = gMax 1.5+ Thin Layers definition = gmax15plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/gmax15plus/gmax15plus_global_very_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_global_very_thick.inst.cfg index 5ebcf5e12d..0c2661b3fd 100644 --- a/resources/quality/gmax15plus/gmax15plus_global_very_thick.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_global_very_thick.inst.cfg @@ -4,7 +4,7 @@ name = gMax 1.5+ Very Thick Layers definition = gmax15plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = extra_course weight = -3 diff --git a/resources/quality/high.inst.cfg b/resources/quality/high.inst.cfg index 2ef1aba9e1..8d306c9de4 100644 --- a/resources/quality/high.inst.cfg +++ b/resources/quality/high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = fdmprinter [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg index e299e675e0..a9138ec70b 100644 --- a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = imade3d_jellybox [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg index 7123c6440a..227072b3a1 100644 --- a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = imade3d_jellybox [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg index 297531f989..a8bcd8d4b0 100644 --- a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg @@ -4,7 +4,7 @@ name = Medium definition = imade3d_jellybox [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg index d15c4a3b2d..7dd26b4f70 100644 --- a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg @@ -4,7 +4,7 @@ name = Medium definition = imade3d_jellybox [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg index 9ff4e6d49e..055e804c9c 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = imade3d_jellybox [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg index 88635bb56d..7909892c18 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = imade3d_jellybox [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg index 89dcca901c..979158fdcf 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = imade3d_jellybox [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg index c7fd702eeb..8cc3108d0e 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = imade3d_jellybox [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg index 7f030b53e2..5620ac43f8 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg @@ -4,7 +4,7 @@ name = Medium definition = imade3d_jellybox [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg index 2759a24a8d..4c6d81e643 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg @@ -4,7 +4,7 @@ name = Medium definition = imade3d_jellybox [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg index b74b9434b7..3eb99a52ea 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg @@ -4,7 +4,7 @@ name = UltraFine definition = imade3d_jellybox [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = ultrahigh weight = 2 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine_2-fans.inst.cfg index 21df5445ab..4a044228c0 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine_2-fans.inst.cfg @@ -4,7 +4,7 @@ name = UltraFine definition = imade3d_jellybox [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = ultrahigh weight = 2 diff --git a/resources/quality/imade3d_jellybox/imade3d_jellybox_coarse.inst.cfg b/resources/quality/imade3d_jellybox/imade3d_jellybox_coarse.inst.cfg index 1c6ef69145..62fe55a619 100644 --- a/resources/quality/imade3d_jellybox/imade3d_jellybox_coarse.inst.cfg +++ b/resources/quality/imade3d_jellybox/imade3d_jellybox_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = imade3d_jellybox [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/imade3d_jellybox/imade3d_jellybox_fine.inst.cfg b/resources/quality/imade3d_jellybox/imade3d_jellybox_fine.inst.cfg index 702c5182c9..f808d5657f 100644 --- a/resources/quality/imade3d_jellybox/imade3d_jellybox_fine.inst.cfg +++ b/resources/quality/imade3d_jellybox/imade3d_jellybox_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = imade3d_jellybox [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/imade3d_jellybox/imade3d_jellybox_normal.inst.cfg b/resources/quality/imade3d_jellybox/imade3d_jellybox_normal.inst.cfg index 87256a9af7..c09bbed35e 100644 --- a/resources/quality/imade3d_jellybox/imade3d_jellybox_normal.inst.cfg +++ b/resources/quality/imade3d_jellybox/imade3d_jellybox_normal.inst.cfg @@ -4,7 +4,7 @@ name = Medium definition = imade3d_jellybox [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/imade3d_jellybox/imade3d_jellybox_ultrafine.inst.cfg b/resources/quality/imade3d_jellybox/imade3d_jellybox_ultrafine.inst.cfg index ffa7ed4550..27bfbbaf58 100644 --- a/resources/quality/imade3d_jellybox/imade3d_jellybox_ultrafine.inst.cfg +++ b/resources/quality/imade3d_jellybox/imade3d_jellybox_ultrafine.inst.cfg @@ -4,7 +4,7 @@ name = UltraFine definition = imade3d_jellybox [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = ultrahigh weight = 2 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_draft.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_draft.inst.cfg index e4b6411ef6..bda943ccb3 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_draft.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = kemiq_q2_beta [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = coarse weight = -3 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_extra_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_extra_fine.inst.cfg index faeaee854d..17a61de974 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_extra_fine.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_extra_fine.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = kemiq_q2_beta [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_fine.inst.cfg index 1ee9821018..310d93a32a 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_fine.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = kemiq_q2_beta [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_low.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_low.inst.cfg index c47239ee4a..4d738769b4 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_low.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_low.inst.cfg @@ -4,7 +4,7 @@ name = Low definition = kemiq_q2_beta [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg index 8eac1515ca..55593d7bc2 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = kemiq_q2_beta [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_draft.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_draft.inst.cfg index e51e3f6cd8..a270353100 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_draft.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = kemiq_q2_beta [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = coarse weight = -3 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_extra_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_extra_fine.inst.cfg index f3d9aa9409..9efb3ccb63 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_extra_fine.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_extra_fine.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = kemiq_q2_beta [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_fine.inst.cfg index 92d1a98e2b..8c41234af8 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_fine.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = kemiq_q2_beta [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_low.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_low.inst.cfg index 3fa48b32a6..957d009be3 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_low.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_low.inst.cfg @@ -4,7 +4,7 @@ name = Low definition = kemiq_q2_beta [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg index 277ddc7ec5..546572b2a6 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = kemiq_q2_beta [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_draft.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_draft.inst.cfg index e73ff9b982..743cc19a20 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_draft.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = kemiq_q2_gama [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = coarse weight = -3 diff --git a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_extra_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_extra_fine.inst.cfg index 0175eb8ffa..ece0fa19c7 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_extra_fine.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_extra_fine.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = kemiq_q2_gama [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_fine.inst.cfg index 415fbef684..71338c8c5f 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_fine.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = kemiq_q2_gama [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_low.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_low.inst.cfg index 94aa963911..60066b5f28 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_low.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_low.inst.cfg @@ -4,7 +4,7 @@ name = Low definition = kemiq_q2_gama [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg index cc69216ecd..42ded06db1 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = kemiq_q2_gama [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_draft.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_draft.inst.cfg index d54f0071cd..6e430754cf 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_draft.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_fast.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_fast.inst.cfg index bdd9a1ccb8..71af7efca1 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_fast.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_high.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_high.inst.cfg index 7a4722d599..adc8128e6f 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_high.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_high.inst.cfg @@ -4,7 +4,7 @@ name = Finer definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_normal.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_normal.inst.cfg index 4cd3f34466..c66aec810e 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_normal.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_superdraft.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_superdraft.inst.cfg index bd349b6d72..9d8d46e5ca 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_superdraft.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_superdraft.inst.cfg @@ -4,7 +4,7 @@ name = Lowest Quality Draft definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -5 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_thickerdraft.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_thickerdraft.inst.cfg index a01282748b..058fb2fa3c 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_thickerdraft.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_thickerdraft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = thickerdraft weight = -3 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg index ac82e263a7..6cbd615d48 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg @@ -4,7 +4,7 @@ name = Ultra Fine definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = ultra weight = 2 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg index 5e3afcb633..5c4dfe8a86 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg @@ -4,7 +4,7 @@ name = Low Detail Draft definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/malyan_m200/malyan_m200_global_Draft_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_Draft_Quality.inst.cfg index aa1f30d0b3..dd99af5356 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_Draft_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_Draft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/malyan_m200/malyan_m200_global_Fast_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_Fast_Quality.inst.cfg index 8cbbdac2e4..20ea357fba 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_Fast_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_Fast_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/malyan_m200/malyan_m200_global_High_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_High_Quality.inst.cfg index a56a5771d8..5d6e1ed7b7 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_High_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Finer definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/malyan_m200/malyan_m200_global_Normal_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_Normal_Quality.inst.cfg index f24faf98f0..c573ba3eb2 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_Normal_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/malyan_m200/malyan_m200_global_SuperDraft_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_SuperDraft_Quality.inst.cfg index ff0d97b1cc..9e9181b195 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_SuperDraft_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_SuperDraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Lowest Quality Draft definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -5 diff --git a/resources/quality/malyan_m200/malyan_m200_global_ThickerDraft_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_ThickerDraft_Quality.inst.cfg index 623b48acff..54cec5c3f0 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_ThickerDraft_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_ThickerDraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = thickerdraft weight = -3 diff --git a/resources/quality/malyan_m200/malyan_m200_global_Ultra_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_Ultra_Quality.inst.cfg index ec04f9055b..d8aded3c63 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_Ultra_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_Ultra_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Ultra Fine definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = ultra weight = 2 diff --git a/resources/quality/malyan_m200/malyan_m200_global_VeryDraft_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_VeryDraft_Quality.inst.cfg index 85b5d0df6b..84a5bd316a 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_VeryDraft_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_VeryDraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Low Detail Draft definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_draft.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_draft.inst.cfg index 6f36402470..6aad899773 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_draft.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_fast.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_fast.inst.cfg index ff14d6a96e..05917d9769 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_fast.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_high.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_high.inst.cfg index 74ab347def..e2fe95f8d8 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_high.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_high.inst.cfg @@ -4,7 +4,7 @@ name = Finer definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_normal.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_normal.inst.cfg index 0862f96460..387a051d64 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_normal.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_superdraft.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_superdraft.inst.cfg index df50ebcc42..f659c78f80 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_superdraft.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_superdraft.inst.cfg @@ -4,7 +4,7 @@ name = Lowest Quality Draft definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -5 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_thickerdraft.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_thickerdraft.inst.cfg index 3697573e0e..9e19c78b35 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_thickerdraft.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_thickerdraft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = thickerdraft weight = -3 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg index c9858b63c7..5ae85d1eef 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg @@ -4,7 +4,7 @@ name = Ultra Fine definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = ultra weight = 2 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg index b88d57ab76..627f70badb 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg @@ -4,7 +4,7 @@ name = Low Detail Draft definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_draft.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_draft.inst.cfg index 7a3af8285a..7f970601b7 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_draft.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_fast.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_fast.inst.cfg index f813e062dd..b4f5ea7388 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_fast.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_high.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_high.inst.cfg index 5fe854ddab..7bc3141980 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_high.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_high.inst.cfg @@ -4,7 +4,7 @@ name = Finer definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_normal.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_normal.inst.cfg index cce3508550..c7eb38439c 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_normal.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_superdraft.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_superdraft.inst.cfg index 477256a933..ce0604c7cc 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_superdraft.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_superdraft.inst.cfg @@ -4,7 +4,7 @@ name = Lowest Quality Draft definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -5 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_thickerdraft.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_thickerdraft.inst.cfg index 1841b91d3d..5ef6b1027d 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_thickerdraft.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_thickerdraft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = thickerdraft weight = -3 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg index 24717cda19..2a24855305 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg @@ -4,7 +4,7 @@ name = Ultra Fine definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = ultra weight = 2 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg index 9e638d67c5..24c6c205fa 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg @@ -4,7 +4,7 @@ name = Low Detail Draft definition = malyan_m200 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_draft.inst.cfg index e8959a1235..7364bdaa36 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_draft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_fast.inst.cfg index 256eea1976..fd1e5b9a6a 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_fast.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_high.inst.cfg index 6d0250121f..836be1bad9 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_high.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_high.inst.cfg @@ -4,7 +4,7 @@ name = Finer definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_normal.inst.cfg index 88c12a38f0..30672cda4a 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_normal.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_superdraft.inst.cfg index 2eacd312f4..1ef32bd44c 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_superdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_superdraft.inst.cfg @@ -4,7 +4,7 @@ name = Lowest Quality Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -5 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_thickerdraft.inst.cfg index 4b311bcfed..9a2c26b034 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_thickerdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_thickerdraft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = thickerdraft weight = -3 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_ultra.inst.cfg index e9857b76b3..d4bf86569b 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_ultra.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_ultra.inst.cfg @@ -4,7 +4,7 @@ name = Ultra Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = thickerdraft weight = 2 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg index aa29220d34..b0f626bdaf 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg @@ -4,7 +4,7 @@ name = Low Detail Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Draft_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Draft_Quality.inst.cfg index add2590cce..6e3de45b42 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Draft_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Draft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Fast_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Fast_Quality.inst.cfg index 2feddbd32a..db7a7f891f 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Fast_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Fast_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_High_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_High_Quality.inst.cfg index 263bd8544c..145c1a2fd2 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_High_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Finer definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Normal_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Normal_Quality.inst.cfg index 52e2ec79f3..3b264639ad 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Normal_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_SuperDraft_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_SuperDraft_Quality.inst.cfg index dfbd2d4d3d..030d82ec0f 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_SuperDraft_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_SuperDraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Lowest Quality Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -5 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_ThickerDraft_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_ThickerDraft_Quality.inst.cfg index f05617c4f0..a075cd54a1 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_ThickerDraft_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_ThickerDraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = thickerdraft weight = -3 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Ultra_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Ultra_Quality.inst.cfg index e6d835d683..6846f451b1 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Ultra_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Ultra_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Ultra Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = ultra weight = 2 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_VeryDraft_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_VeryDraft_Quality.inst.cfg index f44b085be1..adee263981 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_VeryDraft_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_VeryDraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Low Detail Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_draft.inst.cfg index c7701b56d3..fd1cb1969e 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_draft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_fast.inst.cfg index dbe3b03148..350ecb9e6c 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_fast.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_high.inst.cfg index 4612b19638..661690da24 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_high.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_high.inst.cfg @@ -4,7 +4,7 @@ name = Finer definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_normal.inst.cfg index 7b887afb8d..b056628016 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_normal.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_superdraft.inst.cfg index c696c71fd5..5fe909d1b8 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_superdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_superdraft.inst.cfg @@ -4,7 +4,7 @@ name = Lowest Quality Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -5 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_thickerdraft.inst.cfg index c561bcda04..e423d179e0 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_thickerdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_thickerdraft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = thickerdraft weight = -3 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_ultra.inst.cfg index e16e044708..6e3dc051de 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_ultra.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_ultra.inst.cfg @@ -4,7 +4,7 @@ name = Ultra Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = ultra weight = 2 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg index 9bf829c778..ca6bd27c56 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg @@ -4,7 +4,7 @@ name = Low Detail Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_draft.inst.cfg index 6cc27cd3e8..e33d685f11 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_draft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_fast.inst.cfg index 95ef667be9..e348f871b2 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_fast.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_high.inst.cfg index c874fc5c42..311c7b23f8 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_high.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_high.inst.cfg @@ -4,7 +4,7 @@ name = Finer definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_normal.inst.cfg index 62fb4046aa..4c6f55d812 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_normal.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_superdraft.inst.cfg index e1c88805e7..13e57bf86a 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_superdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_superdraft.inst.cfg @@ -4,7 +4,7 @@ name = Lowest Quality Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -5 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_thickerdraft.inst.cfg index 0cec8831bf..c2e07310d1 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_thickerdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_thickerdraft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = thickerdraft weight = -3 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_ultra.inst.cfg index 6aaf8680f5..41bc8a8431 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_ultra.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_ultra.inst.cfg @@ -4,7 +4,7 @@ name = Ultra Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = ultra weight = 2 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg index 7a63b896c3..50b10e3078 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg @@ -4,7 +4,7 @@ name = Low Detail Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_draft.inst.cfg index 4e31a46fbd..107dfc3d24 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_draft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_fast.inst.cfg index e0d7d393c5..6e55583184 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_fast.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_high.inst.cfg index 64451b0788..f809902f60 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_high.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_high.inst.cfg @@ -4,7 +4,7 @@ name = Finer definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_normal.inst.cfg index 1f5b6c956c..770a51e1dd 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_normal.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_superdraft.inst.cfg index 9b269ee95b..e2116bdd85 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_superdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_superdraft.inst.cfg @@ -4,7 +4,7 @@ name = Lowest Quality Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -5 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_thickerdraft.inst.cfg index e180b50a89..ce902318f8 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_thickerdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_thickerdraft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = thickerdraft weight = -3 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_ultra.inst.cfg index fe77254c56..6b5d2604d0 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_ultra.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_ultra.inst.cfg @@ -4,7 +4,7 @@ name = Ultra Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = ultra weight = 2 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg index 9505b2b15b..b777e97444 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg @@ -4,7 +4,7 @@ name = Low Detail Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_draft.inst.cfg index 8333cd10ac..f1080c776c 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_draft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_fast.inst.cfg index ab83dacbe8..7b7525f007 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_fast.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = 0 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg index 13f31a614e..d0bfe599a4 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg @@ -4,7 +4,7 @@ name = Finer definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_normal.inst.cfg index 57fb63fdea..07b08619d1 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_normal.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_superdraft.inst.cfg index 77c3a18b54..74a03b7cbc 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_superdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_superdraft.inst.cfg @@ -4,7 +4,7 @@ name = Lowest Quality Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -5 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_thickerdraft.inst.cfg index 52b871217b..fc3ec719d0 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_thickerdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_thickerdraft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = thickerdraft weight = -3 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_ultra.inst.cfg index 36ef492905..316c4a2d17 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_ultra.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_ultra.inst.cfg @@ -4,7 +4,7 @@ name = Ultra Fine definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = ultra weight = 2 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_verydraft.inst.cfg index e1d636b2b1..fbbefb9937 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_verydraft.inst.cfg @@ -4,7 +4,7 @@ name = Low Detail Draft definition = monoprice_select_mini_v2 [metadata] -setting_version = 6 +setting_version = 7 type = quality material = generic_pla weight = 0 diff --git a/resources/quality/normal.inst.cfg b/resources/quality/normal.inst.cfg index 02b9ebf621..b8828f07e0 100644 --- a/resources/quality/normal.inst.cfg +++ b/resources/quality/normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = fdmprinter [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/peopoly_moai/peopoly_moai_coarse.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_coarse.inst.cfg index 9ca6cec759..dab819cc38 100644 --- a/resources/quality/peopoly_moai/peopoly_moai_coarse.inst.cfg +++ b/resources/quality/peopoly_moai/peopoly_moai_coarse.inst.cfg @@ -4,7 +4,7 @@ name = Coarse definition = peopoly_moai [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = coarse weight = 3 diff --git a/resources/quality/peopoly_moai/peopoly_moai_draft.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_draft.inst.cfg index 72953e5305..feb005e39c 100644 --- a/resources/quality/peopoly_moai/peopoly_moai_draft.inst.cfg +++ b/resources/quality/peopoly_moai/peopoly_moai_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = peopoly_moai [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/peopoly_moai/peopoly_moai_extra_high.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_extra_high.inst.cfg index 30d41aa7f8..46bd8f4a63 100644 --- a/resources/quality/peopoly_moai/peopoly_moai_extra_high.inst.cfg +++ b/resources/quality/peopoly_moai/peopoly_moai_extra_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra High definition = peopoly_moai [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = extra_high weight = 0 diff --git a/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg index 37442ed20c..2b951c6e4e 100644 --- a/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg +++ b/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = peopoly_moai [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg index 33bb5673ae..b965862a16 100644 --- a/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg +++ b/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = peopoly_moai [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/tevo_blackwidow/tevo_blackwidow_draft.inst.cfg b/resources/quality/tevo_blackwidow/tevo_blackwidow_draft.inst.cfg index 13f12ef643..250c3bd1d5 100644 --- a/resources/quality/tevo_blackwidow/tevo_blackwidow_draft.inst.cfg +++ b/resources/quality/tevo_blackwidow/tevo_blackwidow_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = tevo_blackwidow [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/tevo_blackwidow/tevo_blackwidow_high.inst.cfg b/resources/quality/tevo_blackwidow/tevo_blackwidow_high.inst.cfg index 0f0ccf64c6..0dff2b94ca 100644 --- a/resources/quality/tevo_blackwidow/tevo_blackwidow_high.inst.cfg +++ b/resources/quality/tevo_blackwidow/tevo_blackwidow_high.inst.cfg @@ -4,7 +4,7 @@ name = High definition = tevo_blackwidow [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/tevo_blackwidow/tevo_blackwidow_normal.inst.cfg b/resources/quality/tevo_blackwidow/tevo_blackwidow_normal.inst.cfg index ebd5997027..e5b9290cad 100644 --- a/resources/quality/tevo_blackwidow/tevo_blackwidow_normal.inst.cfg +++ b/resources/quality/tevo_blackwidow/tevo_blackwidow_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = tevo_blackwidow [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/tizyx_k25/tizyx_k25_normal.inst.cfg b/resources/quality/tizyx_k25/tizyx_k25_normal.inst.cfg index f259ad1b34..0e12c38f60 100644 --- a/resources/quality/tizyx_k25/tizyx_k25_normal.inst.cfg +++ b/resources/quality/tizyx_k25/tizyx_k25_normal.inst.cfg @@ -1,29 +1,29 @@ -[general] -version = 4 -name = TiZYX K25 Normal -definition = tizyx_k25 - -[metadata] -quality_type = normal -setting_version = 6 -type = quality -global_quality = True - -[values] -adhesion_type = skirt -skirt_line_count = 2 -skirt_gap = 2 -cool_fan_speed_0 = 100 -fill_outline_gaps = True -infill_angles = [0,90 ] -infill_sparse_density = 15 -material_diameter = 1.75 -retraction_amount = 2.5 -retraction_min_travel = 2 -retraction_speed = 30 -skin_angles = [0,90] -speed_print = 60 -speed_topbottom = 50 -speed_wall_0 = 40 -top_layers = 4 -wall_line_count = 2 +[general] +version = 4 +name = TiZYX K25 Normal +definition = tizyx_k25 + +[metadata] +quality_type = normal +setting_version = 7 +type = quality +global_quality = True + +[values] +adhesion_type = skirt +skirt_line_count = 2 +skirt_gap = 2 +cool_fan_speed_0 = 100 +fill_outline_gaps = True +infill_angles = [0,90 ] +infill_sparse_density = 15 +material_diameter = 1.75 +retraction_amount = 2.5 +retraction_min_travel = 2 +retraction_speed = 30 +skin_angles = [0,90] +speed_print = 60 +speed_topbottom = 50 +speed_wall_0 = 40 +top_layers = 4 +wall_line_count = 2 diff --git a/resources/quality/ultimaker2/um2_draft.inst.cfg b/resources/quality/ultimaker2/um2_draft.inst.cfg index 7d38ba6bf4..121f6f0404 100644 --- a/resources/quality/ultimaker2/um2_draft.inst.cfg +++ b/resources/quality/ultimaker2/um2_draft.inst.cfg @@ -4,7 +4,7 @@ name = Draft definition = ultimaker2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker2/um2_fast.inst.cfg b/resources/quality/ultimaker2/um2_fast.inst.cfg index 39cd4da4ef..8dc9b56082 100644 --- a/resources/quality/ultimaker2/um2_fast.inst.cfg +++ b/resources/quality/ultimaker2/um2_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2/um2_high.inst.cfg b/resources/quality/ultimaker2/um2_high.inst.cfg index 142440d53e..5bb17480b6 100644 --- a/resources/quality/ultimaker2/um2_high.inst.cfg +++ b/resources/quality/ultimaker2/um2_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker2/um2_normal.inst.cfg b/resources/quality/ultimaker2/um2_normal.inst.cfg index b5a87f07f3..1235fe27db 100644 --- a/resources/quality/ultimaker2/um2_normal.inst.cfg +++ b/resources/quality/ultimaker2/um2_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg index d27a136765..059a58e699 100644 --- a/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg index 5bc62e5fd0..59a714708f 100644 --- a/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg index 2847ab8c15..daf244cc5d 100644 --- a/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg index 009fcf7877..1bb29fdf5c 100644 --- a/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg index 7c492f2ec0..910933b73e 100644 --- a/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg index 1b6cee0e1d..8be245a49e 100644 --- a/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg index f55567f986..dc9e0bfd87 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg index 63904632dc..31f14b6d5a 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg index f76efeb7b2..2dc95a860b 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg index fd7dfc86a7..a995cc8c57 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg index aba3222412..491f041130 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg index 23618e2e1d..057eb1d657 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg index db184abe54..aa6662ba58 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg index 2dc076b012..01763c1e2c 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg index 300d5242e2..298cbb2068 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg index 17a9f1a579..5be1ac399d 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg index 6807a1a86a..55f167a046 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg index 7a15ed53ec..ba99eaacc2 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.4_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.4_draft.inst.cfg index cc68478dd8..73ef52e511 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpep_0.4_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.4_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.4_normal.inst.cfg index 0d0e0e2043..2fc95502e7 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpep_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.4_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.6_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.6_draft.inst.cfg index e08a7fc357..89ce35628e 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpep_0.6_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.6_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.6_normal.inst.cfg index 7c8589f09e..94c542e793 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpep_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.6_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.8_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.8_draft.inst.cfg index 1c42d28128..98abf00ebf 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpep_0.8_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.8_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.8_normal.inst.cfg index 072081e092..2091a22f80 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpep_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.8_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_global_Coarse_Quality.inst.cfg b/resources/quality/ultimaker2_plus/um2p_global_Coarse_Quality.inst.cfg index 2a4fe17a24..9cfbefa641 100644 --- a/resources/quality/ultimaker2_plus/um2p_global_Coarse_Quality.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_global_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Coarse Quality definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = coarse weight = -4 diff --git a/resources/quality/ultimaker2_plus/um2p_global_Draft_Quality.inst.cfg b/resources/quality/ultimaker2_plus/um2p_global_Draft_Quality.inst.cfg index bdf79827b2..1f4f9af746 100644 --- a/resources/quality/ultimaker2_plus/um2p_global_Draft_Quality.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_global_Draft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Draft Quality definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker2_plus/um2p_global_Extra_Coarse_Quality.inst.cfg b/resources/quality/ultimaker2_plus/um2p_global_Extra_Coarse_Quality.inst.cfg index e5338c0e34..7d4483d9ff 100644 --- a/resources/quality/ultimaker2_plus/um2p_global_Extra_Coarse_Quality.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_global_Extra_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse Quality definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = extra coarse weight = -3 diff --git a/resources/quality/ultimaker2_plus/um2p_global_Fast_Quality.inst.cfg b/resources/quality/ultimaker2_plus/um2p_global_Fast_Quality.inst.cfg index 453def0668..29e649ffe0 100644 --- a/resources/quality/ultimaker2_plus/um2p_global_Fast_Quality.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_global_Fast_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_global_High_Quality.inst.cfg b/resources/quality/ultimaker2_plus/um2p_global_High_Quality.inst.cfg index 20b9e7ba16..12f449fbd1 100644 --- a/resources/quality/ultimaker2_plus/um2p_global_High_Quality.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_global_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker2_plus/um2p_global_Normal_Quality.inst.cfg b/resources/quality/ultimaker2_plus/um2p_global_Normal_Quality.inst.cfg index c901687f22..908d0e42ab 100644 --- a/resources/quality/ultimaker2_plus/um2p_global_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_global_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.25_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.25_high.inst.cfg index 512f9e499b..176e8b1e13 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.25_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.25_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.25_normal.inst.cfg index ce607f7a83..a4a380f615 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.25_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.4_fast.inst.cfg index 7b06d5205c..74251f21a6 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.4_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.4_normal.inst.cfg index b65f694e11..f0ad7bf95a 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.4_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.6_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.6_fast.inst.cfg index 6caa1d2e82..ce9f0f5c53 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.6_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.6_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.6_normal.inst.cfg index 3dad97297f..d197511fc6 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.6_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.8_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.8_draft.inst.cfg index fe5749aeff..33dfe9f029 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.8_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.8_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.8_normal.inst.cfg index 3e16229ad1..42a7225914 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.8_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.25_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.25_high.inst.cfg index 0195a6170f..f3f1cba3c4 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.25_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.25_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.25_normal.inst.cfg index fe15f050c7..4ae2ba1e59 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.25_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg index 1268e4f5a5..23aa742baf 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.4_normal.inst.cfg index 31a55131bd..4ca6511cce 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.4_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg index a4b0e7865e..3f87070307 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.6_normal.inst.cfg index 9fef7be2f8..251541d530 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.6_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.8_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.8_draft.inst.cfg index cfbd0795ab..0cc384c87f 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.8_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.8_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.8_normal.inst.cfg index fd24f29c40..7ac3e3a6be 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.8_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.4_fast.inst.cfg index 8e320bef25..a6073c15de 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.4_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.4_normal.inst.cfg index 94d7a22965..afe476adec 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.4_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.6_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.6_draft.inst.cfg index aee8437e39..9f70dc9605 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.6_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.6_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.6_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.6_fast.inst.cfg index f1e709495b..1dffcbf795 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.6_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.6_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg index 0e84d2c2e4..eac5de0f53 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg index 905c147e41..9ec9c819f4 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker2_plus/um2p_tpu_0.25_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_tpu_0.25_high.inst.cfg index 47bf078c2f..91cba55809 100644 --- a/resources/quality/ultimaker2_plus/um2p_tpu_0.25_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_tpu_0.25_high.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker2_plus/um2p_tpu_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_tpu_0.4_normal.inst.cfg index d8543f1f8a..a9c9765bcd 100644 --- a/resources/quality/ultimaker2_plus/um2p_tpu_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_tpu_0.4_normal.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker2_plus/um2p_tpu_0.6_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_tpu_0.6_fast.inst.cfg index 1983878a79..4fcdc9579c 100644 --- a/resources/quality/ultimaker2_plus/um2p_tpu_0.6_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_tpu_0.6_fast.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.25_ABS_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_ABS_Normal_Quality.inst.cfg index dda9fd3891..fc56bc41e5 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_ABS_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_ABS_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.25_CPE_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_CPE_Normal_Quality.inst.cfg index 922366d716..c2a687a4d6 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_CPE_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_CPE_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.25_Nylon_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_Nylon_Normal_Quality.inst.cfg index 3535bc4cba..8194d1a510 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_Nylon_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_Nylon_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg index f24c53aaee..fb8212a4a0 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine - Experimental definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.25_PLA_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_PLA_Normal_Quality.inst.cfg index a59c404754..39416d4bb1 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_PLA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_PLA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg index 6f9734511b..e6b10560c3 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine - Experimental definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.25_TPLA_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_TPLA_Normal_Quality.inst.cfg index af9bea762a..c83d3a1f49 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_TPLA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_TPLA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.4_ABS_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_ABS_Draft_Print.inst.cfg index a6ba0a666b..150be3bdcd 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_ABS_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_ABS_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.4_ABS_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_ABS_Fast_Print.inst.cfg index 4bd04e36af..f9d1110512 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_ABS_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_ABS_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg index 6ef2fa3cb4..40229c1307 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg index e0862a137c..df13a81211 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.4_BAM_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_BAM_Draft_Print.inst.cfg index 3de7252b86..d102abe5ee 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_BAM_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_BAM_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.4_BAM_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_BAM_Fast_Print.inst.cfg index 28bce4eb15..57ec919e46 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_BAM_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_BAM_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_BAM_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_BAM_Normal_Quality.inst.cfg index 0f15931e59..c5782aa9bc 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_BAM_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_BAM_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Draft_Print.inst.cfg index c27fc027fb..37801626bd 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Fast_Print.inst.cfg index 6a035522f1..4bf87820fb 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPEP_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPEP_High_Quality.inst.cfg index 3387430d26..cbb3085d85 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPEP_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPEP_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Normal_Quality.inst.cfg index 8d0283a20f..ed87e6d4ed 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPE_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPE_Draft_Print.inst.cfg index a8d5c26315..1a15755577 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPE_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPE_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPE_Fast_Print.inst.cfg index e4b4e2e21b..2cba7b1ccf 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPE_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPE_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPE_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPE_High_Quality.inst.cfg index 3964608aec..e927a79c10 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPE_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPE_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPE_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPE_Normal_Quality.inst.cfg index b0e7234c90..d9a7649123 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPE_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPE_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Draft_Print.inst.cfg index 5bfa29fd61..0139970339 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Fast_Print.inst.cfg index eaec1cdbdb..094a7c0ff5 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_Nylon_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_Nylon_High_Quality.inst.cfg index 7a0a04b6c2..8bb0002b84 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_Nylon_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_Nylon_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Normal_Quality.inst.cfg index 8b18ee20df..f7c733c212 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PC_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PC_Draft_Print.inst.cfg index fafb839f17..e6ac6a7cb6 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PC_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PC_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PC_Fast_Print.inst.cfg index 57527f928c..e50cd7fc02 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PC_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PC_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PC_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PC_High_Quality.inst.cfg index 37e31c5863..5f837fce0e 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PC_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PC_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PC_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PC_Normal_Quality.inst.cfg index 0961b3ccd6..ccba414b57 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PC_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PC_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PLA_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PLA_Draft_Print.inst.cfg index c24c2cacdf..e4cbb6ed35 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PLA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PLA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PLA_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PLA_Fast_Print.inst.cfg index d20a06a94a..96d1a3436a 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PLA_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PLA_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PLA_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PLA_High_Quality.inst.cfg index bd365c56ae..a7d5fa0586 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PLA_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PLA_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PLA_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PLA_Normal_Quality.inst.cfg index a291357e58..bb6b6cb06c 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PLA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PLA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PP_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PP_Draft_Print.inst.cfg index 6dbb444454..6ca1e6fe3e 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PP_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PP_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PP_Fast_Print.inst.cfg index 60c304794b..e34a8ba625 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PP_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PP_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PP_Normal_Quality.inst.cfg index 92d53d6295..d363667af7 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PP_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.4_TPLA_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_TPLA_Draft_Print.inst.cfg index 6d8c6690a2..4efb7d9e78 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_TPLA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_TPLA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.4_TPLA_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_TPLA_Fast_Print.inst.cfg index c8fbe827e3..d461a3187e 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_TPLA_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_TPLA_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_TPLA_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_TPLA_Normal_Quality.inst.cfg index d1a1bc994c..b451c22489 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_TPLA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_TPLA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.4_TPU_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_TPU_Draft_Print.inst.cfg index 13bc7c0b7e..0a3bd45c38 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_TPU_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_TPU_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.4_TPU_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_TPU_Fast_Print.inst.cfg index cb3692a84f..42adf63e8c 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_TPU_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_TPU_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_aa0.4_TPU_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_TPU_Normal_Quality.inst.cfg index a5264ce6ec..a5804ad2e1 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_TPU_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_TPU_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_aa0.8_ABS_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_ABS_Draft_Print.inst.cfg index 474b24a462..051b5bba36 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_ABS_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_ABS_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.8_ABS_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_ABS_Superdraft_Print.inst.cfg index e9c4f9e3e9..dcbe8ca1b0 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_ABS_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_ABS_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_aa0.8_ABS_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_ABS_Verydraft_Print.inst.cfg index 213298653a..1a0c746b20 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_ABS_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_ABS_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg index bb2aa2d6ef..add4025786 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast - Experimental definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Superdraft_Print.inst.cfg index 98086b2bf1..654447e5dc 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint - Experimental definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Verydraft_Print.inst.cfg index 0684b9ac1e..86d145cf39 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast - Experimental definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPE_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPE_Draft_Print.inst.cfg index 05294737b6..243bf8f437 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPE_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPE_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPE_Superdraft_Print.inst.cfg index 555d6da1bf..78362aa1d8 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPE_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPE_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPE_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPE_Verydraft_Print.inst.cfg index da71c679ff..44f254b613 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPE_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPE_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Draft_Print.inst.cfg index ab11f0fe86..be1245b58a 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Superdraft_Print.inst.cfg index 46f5a87a1b..9d15b69dbc 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Verydraft_Print.inst.cfg index 12d96e9f7d..d2b22cd418 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg index 8005618066..4e9c8c9376 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast - Experimental definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg index 601a68ef46..69661c91b6 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint - Experimental definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg index 0d5b579846..1fefa5a141 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast - Experimental definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PLA_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PLA_Draft_Print.inst.cfg index c5000b0a43..d8133eee5f 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PLA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PLA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PLA_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PLA_Superdraft_Print.inst.cfg index e03663bc2b..35b675fd10 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PLA_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PLA_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PLA_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PLA_Verydraft_Print.inst.cfg index 06bf4cf224..fed141f8e9 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PLA_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PLA_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PP_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PP_Draft_Print.inst.cfg index b577ba8185..a6fe2c9e8e 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PP_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PP_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PP_Superdraft_Print.inst.cfg index c0917a9e8e..bd2a09c3cc 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PP_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PP_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PP_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PP_Verydraft_Print.inst.cfg index 00eb39a400..68765f839b 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PP_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PP_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_TPLA_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_TPLA_Draft_Print.inst.cfg index 30ce94000f..2224917fc1 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_TPLA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_TPLA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.8_TPLA_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_TPLA_Superdraft_Print.inst.cfg index ea3525c7ee..e4b3355579 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_TPLA_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_TPLA_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_aa0.8_TPLA_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_TPLA_Verydraft_Print.inst.cfg index 1027f52b38..026372156c 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_TPLA_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_TPLA_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_TPU_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_TPU_Draft_Print.inst.cfg index 83fb56a84d..d30a6db38c 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_TPU_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_TPU_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_aa0.8_TPU_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_TPU_Superdraft_Print.inst.cfg index 36e38654db..28fffe945a 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_TPU_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_TPU_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_aa0.8_TPU_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_TPU_Verydraft_Print.inst.cfg index 96b1406adb..35bc994931 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_TPU_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_TPU_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker3/um3_bb0.4_PVA_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_PVA_Draft_Print.inst.cfg index a41b0c0210..a99a0abdf5 100644 --- a/resources/quality/ultimaker3/um3_bb0.4_PVA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.4_PVA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_bb0.4_PVA_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_PVA_Fast_Print.inst.cfg index d7a8885bf9..4fd5c14f5d 100644 --- a/resources/quality/ultimaker3/um3_bb0.4_PVA_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.4_PVA_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_bb0.4_PVA_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_PVA_High_Quality.inst.cfg index be4eedadc8..6d80217cd5 100644 --- a/resources/quality/ultimaker3/um3_bb0.4_PVA_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.4_PVA_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker3/um3_bb0.4_PVA_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_PVA_Normal_Quality.inst.cfg index ae576790a8..8068af6f22 100644 --- a/resources/quality/ultimaker3/um3_bb0.4_PVA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.4_PVA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_bb0.8_PVA_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_PVA_Draft_Print.inst.cfg index 247e7f12c6..090baba2c8 100644 --- a/resources/quality/ultimaker3/um3_bb0.8_PVA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.8_PVA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_bb0.8_PVA_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_PVA_Superdraft_Print.inst.cfg index 8a4c0cc992..47a82e01a3 100644 --- a/resources/quality/ultimaker3/um3_bb0.8_PVA_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.8_PVA_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_bb0.8_PVA_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_PVA_Verydraft_Print.inst.cfg index c931e6ad5d..a8d0e494cb 100644 --- a/resources/quality/ultimaker3/um3_bb0.8_PVA_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.8_PVA_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg index b95ddb1aa9..936406fce6 100644 --- a/resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg index 3510a05343..14b214da5a 100644 --- a/resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg index 55fe2bdfda..b9c2c19d8c 100644 --- a/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg index cffacfd312..ab9127f26d 100644 --- a/resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker3/um3_global_Superdraft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Superdraft_Quality.inst.cfg index 5fd966bb9f..36d9f932f1 100644 --- a/resources/quality/ultimaker3/um3_global_Superdraft_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_global_Superdraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker3/um3_global_Verydraft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Verydraft_Quality.inst.cfg index 7e65a6c4c4..3eaf8191a2 100644 --- a/resources/quality/ultimaker3/um3_global_Verydraft_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_global_Verydraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_original/umo_global_Coarse_Quality.inst.cfg b/resources/quality/ultimaker_original/umo_global_Coarse_Quality.inst.cfg index 6125d0f687..2ebfb1e2c7 100644 --- a/resources/quality/ultimaker_original/umo_global_Coarse_Quality.inst.cfg +++ b/resources/quality/ultimaker_original/umo_global_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Coarse Quality definition = ultimaker_original [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = coarse weight = -3 diff --git a/resources/quality/ultimaker_original/umo_global_Draft_Quality.inst.cfg b/resources/quality/ultimaker_original/umo_global_Draft_Quality.inst.cfg index ebabe4dd46..b246ba12ea 100644 --- a/resources/quality/ultimaker_original/umo_global_Draft_Quality.inst.cfg +++ b/resources/quality/ultimaker_original/umo_global_Draft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Draft Quality definition = ultimaker_original [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_original/umo_global_Extra_Coarse_Quality.inst.cfg b/resources/quality/ultimaker_original/umo_global_Extra_Coarse_Quality.inst.cfg index b625ec45ea..da8c6a9b39 100644 --- a/resources/quality/ultimaker_original/umo_global_Extra_Coarse_Quality.inst.cfg +++ b/resources/quality/ultimaker_original/umo_global_Extra_Coarse_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Coarse Quality definition = ultimaker_original [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = extra coarse weight = -4 diff --git a/resources/quality/ultimaker_original/umo_global_Fast_Quality.inst.cfg b/resources/quality/ultimaker_original/umo_global_Fast_Quality.inst.cfg index e2bceeae7e..db03a7f18c 100644 --- a/resources/quality/ultimaker_original/umo_global_Fast_Quality.inst.cfg +++ b/resources/quality/ultimaker_original/umo_global_Fast_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_original [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_original/umo_global_High_Quality.inst.cfg b/resources/quality/ultimaker_original/umo_global_High_Quality.inst.cfg index 883048f557..ec1b593f7e 100644 --- a/resources/quality/ultimaker_original/umo_global_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_original/umo_global_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_original [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_original/umo_global_Normal_Quality.inst.cfg b/resources/quality/ultimaker_original/umo_global_Normal_Quality.inst.cfg index 2cec4bfbda..9b39c97682 100644 --- a/resources/quality/ultimaker_original/umo_global_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_original/umo_global_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_original [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.25_ABS_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.25_ABS_Normal_Quality.inst.cfg index be8e56d133..1b46116686 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.25_ABS_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.25_ABS_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.25_CPE_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.25_CPE_Normal_Quality.inst.cfg index 3eaeda67d5..0beec0fba4 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.25_CPE_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.25_CPE_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.25_Nylon_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.25_Nylon_Normal_Quality.inst.cfg index 9407fb72b0..7623872d07 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.25_Nylon_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.25_Nylon_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.25_PC_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.25_PC_Normal_Quality.inst.cfg index 7cde76a1e1..e09ea57792 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.25_PC_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.25_PC_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine - Experimental definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.25_PLA_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.25_PLA_Normal_Quality.inst.cfg index ab45d82a3b..e284ac277a 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.25_PLA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.25_PLA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.25_PP_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.25_PP_Normal_Quality.inst.cfg index 1474cad5c1..a8c5f08448 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.25_PP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.25_PP_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine - Experimental definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.25_TPLA_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.25_TPLA_Normal_Quality.inst.cfg index ea4375b854..27c9c1d63e 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.25_TPLA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.25_TPLA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Draft_Print.inst.cfg index 6d26c2bb97..5d2e8767ba 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Fast_Print.inst.cfg index e2e8bd82e5..7e5fcc0ab6 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_High_Quality.inst.cfg index fc39383f04..829939b2a6 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Normal_Quality.inst.cfg index 8ec7e6453b..a6a51aca4c 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_ABS_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Draft_Print.inst.cfg index 93665c36de..b49dbd674d 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Fast_Print.inst.cfg index 478df58f43..6d4f7206f3 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Normal_Quality.inst.cfg index e936d0f131..e590a56028 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_BAM_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Draft_Print.inst.cfg index da639d22c9..aa32861ddb 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Fast_Print.inst.cfg index 2c2eb99fb0..26edd2d8a7 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_High_Quality.inst.cfg index 20fbcd9430..e200c3b078 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Normal_Quality.inst.cfg index e40949fc7d..dc665ae114 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPEP_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Draft_Print.inst.cfg index 7ccfe4f786..311c335a86 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Fast_Print.inst.cfg index f12c90bc05..02122a40fa 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_High_Quality.inst.cfg index 04957025f1..54ab48e88d 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Normal_Quality.inst.cfg index b0a5fb820f..be9b43b1b8 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_CPE_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Draft_Print.inst.cfg index 1a198f3e03..03fe4f4b8a 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Fast_Print.inst.cfg index e6b882d2af..bd078f7e4d 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_High_Quality.inst.cfg index 292ef73a4c..45506f4152 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Normal_Quality.inst.cfg index 2b71a01e0d..c159402e3f 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_Nylon_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Draft_Print.inst.cfg index e27a6894e3..f6713fd4e9 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Fast_Print.inst.cfg index db1ecee3bc..fbc5328d80 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_High_Quality.inst.cfg index ca80494f3d..d6e002c7f1 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Normal_Quality.inst.cfg index d2d5171fed..0f708b16db 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PC_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Draft_Print.inst.cfg index 9bf58d4f39..ca4ef6bd9b 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Fast_Print.inst.cfg index 017bf46bd8..56cb57cb08 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_High_Quality.inst.cfg index 314f7fe0bb..44b643d529 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Normal_Quality.inst.cfg index 2bb0d31d76..aa737dc1ea 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PLA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Draft_Print.inst.cfg index 8b8bdfd999..d008bb37fc 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Fast_Print.inst.cfg index 0fd70e5973..b0c00f2c07 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Normal_Quality.inst.cfg index 0d683a9f87..835c53eaef 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_PP_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Draft_Print.inst.cfg index df45c190e1..8be35d2ae2 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Fast_Print.inst.cfg index 96b77ebca9..460fd73afa 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_High_Quality.inst.cfg index 3a2cf495a3..3488756cb6 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Normal_Quality.inst.cfg index 2d93d1e980..dc2b844d90 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPLA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Draft_Print.inst.cfg index 30a1e0c29f..ec93e5ec23 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Fast_Print.inst.cfg index 3b57900a46..eff47b9c20 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Normal_Quality.inst.cfg index 368bfd9e48..62e543977c 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_TPU_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Draft_Print.inst.cfg index a2b7aa7b87..6222dcdc7b 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Fast_Print.inst.cfg index 8e82e27210..2bf17429fa 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_High_Quality.inst.cfg index 7e4f17cbf1..7d7f4b2aaa 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Normal_Quality.inst.cfg index 959d9241c7..6d78d9d027 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Draft_Print.inst.cfg index c9083cf2ab..c02317792c 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Fast_Print.inst.cfg index 9d7663b6e1..57be60501c 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_High_Quality.inst.cfg index ba796da940..44235b30eb 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Normal_Quality.inst.cfg index 96ec8d9e36..a0b5af8679 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Draft_Print.inst.cfg index bae8b09016..fdd8bd6d39 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Fast_Print.inst.cfg index f585c2a787..e40a6422db 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_High_Quality.inst.cfg index a580a27176..68d0d77fdb 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Normal_Quality.inst.cfg index 3db4053d2a..563aa27b70 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Draft_Print.inst.cfg index e86c3b363b..ddaef82dcc 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Fast_Print.inst.cfg index 0da88626b6..5c85a32af0 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_High_Quality.inst.cfg index d7552ba921..dbeed2dfe9 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Normal_Quality.inst.cfg index 638ce2323e..3694db3f76 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Draft_Print.inst.cfg index c0ca84281d..f50c38f892 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Fast_Print.inst.cfg index 43b77f6492..8f07b2a6a9 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Normal_Quality.inst.cfg index 04abd0d18b..440d8cbfe6 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Draft_Print.inst.cfg index fb786c7759..56a16595e8 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Superdraft_Print.inst.cfg index cfacaebad0..77c0031feb 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Verydraft_Print.inst.cfg index 18ce266cd6..5a4ee5c515 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_ABS_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Fast_Print.inst.cfg index a4a7a5e08c..a1c4479973 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast - Experimental definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Superdraft_Print.inst.cfg index e4f330099b..3bde53d593 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint - Experimental definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Verydraft_Print.inst.cfg index 0685b27b8a..159c909ba5 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPEP_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast - Experimental definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Draft_Print.inst.cfg index a57bde98b1..af016c06da 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Superdraft_Print.inst.cfg index 2f0851d9fb..17036438a9 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Verydraft_Print.inst.cfg index 6ccca75b44..2973abfdd3 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_CPE_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Draft_Print.inst.cfg index 5d04892443..7760ffa89e 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Superdraft_Print.inst.cfg index 5c31e26bd6..2499e6b3d2 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Verydraft_Print.inst.cfg index d04482c94c..2e611aeecc 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_Nylon_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Fast_Print.inst.cfg index 97afe62e07..2ac89416aa 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast - Experimental definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Superdraft_Print.inst.cfg index 3f296c0300..31db0f93dd 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint - Experimental definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Verydraft_Print.inst.cfg index 5eec532f22..2ef532a8b9 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PC_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast - Experimental definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Draft_Print.inst.cfg index 1410290859..ecfab94ef3 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Superdraft_Print.inst.cfg index 2c65968d77..38f3c9c9d9 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Verydraft_Print.inst.cfg index 9b6e7c2ed9..b4b65ee5f7 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PLA_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Draft_Print.inst.cfg index c5b01ab1b1..9a413c42c1 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Superdraft_Print.inst.cfg index 5c83f24395..0286f482cf 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Verydraft_Print.inst.cfg index f182d5c6cb..ed53d87b78 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_PP_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Draft_Print.inst.cfg index 5b39508f3c..790ff4a922 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Superdraft_Print.inst.cfg index b07a78419a..9111bb5804 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Verydraft_Print.inst.cfg index 46a61bb79f..af0fb786d2 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPLA_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Draft_Print.inst.cfg index 088414fa34..479aab6e7c 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Superdraft_Print.inst.cfg index d74309c476..2b2f280730 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Verydraft_Print.inst.cfg index deb2b55dbb..ef38d96aea 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_TPU_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Draft_Print.inst.cfg index 062fcfdd5b..e0dd599317 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Superdraft_Print.inst.cfg index 38c341af28..0ca1b63c0b 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Verydraft_Print.inst.cfg index 8a38bb9aa3..1611c3fedd 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Fast_Print.inst.cfg index d9dd09c7b6..6b0f12f8dc 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast - Experimental definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Superdraft_Print.inst.cfg index bc6a04ae55..78ad1f6eac 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Verydraft_Print.inst.cfg index b384bd7083..7be2cdbcc8 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Draft_Print.inst.cfg index 28409d4181..a0c0890b1b 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Superdraft_Print.inst.cfg index 33c5d73a59..ca001b62ed 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Verydraft_Print.inst.cfg index 8db23c11c2..ea0cd0fa83 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Fast_Print.inst.cfg index c0af70748a..04170b3ba2 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast - Experimental definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Superdraft_Print.inst.cfg index bba2dfa92f..90b7afdb8d 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Verydraft_Print.inst.cfg index 3987c01ecc..f9b93eac37 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Draft_Print.inst.cfg index 5a2c3005c9..764dc75494 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Superdraft_Print.inst.cfg index aaa8cbfcd3..63a594d3e0 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Verydraft_Print.inst.cfg index 782cadce6b..7de41de9c9 100644 --- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Draft_Print.inst.cfg index 34b078278c..804e9fd62b 100644 --- a/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Fast_Print.inst.cfg index 5677c5931c..52a571c4f1 100644 --- a/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Fast_Print.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_High_Quality.inst.cfg index b9e32cb7c5..e8e293c81b 100644 --- a/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Normal_Quality.inst.cfg index 081ee2261e..b512b47514 100644 --- a/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_bb0.4_PVA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Draft_Print.inst.cfg index 0193081db6..04015fe0f8 100644 --- a/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Superdraft_Print.inst.cfg index 121b32f903..8d79e8fafe 100644 --- a/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Superdraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Verydraft_Print.inst.cfg index f0296c9279..31663ab192 100644 --- a/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_bb0.8_PVA_Verydraft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFCPE_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFCPE_Draft_Print.inst.cfg index 35da5b113e..e3ecf51f13 100644 --- a/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFCPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFCPE_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFPA_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFPA_Draft_Print.inst.cfg index 67400daf9f..f73379dd3d 100644 --- a/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFPA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_cc0.6_CFFPA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFCPE_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFCPE_Draft_Print.inst.cfg index 0c4f55bddf..906f22a66f 100644 --- a/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFCPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFCPE_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFPA_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFPA_Draft_Print.inst.cfg index 8a6f9d2ac8..e411fa877b 100644 --- a/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFPA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_cc0.6_GFFPA_Draft_Print.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_global_Draft_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_global_Draft_Quality.inst.cfg index f0121fa4d7..6d5e9cce24 100644 --- a/resources/quality/ultimaker_s5/um_s5_global_Draft_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_global_Draft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = draft weight = -2 diff --git a/resources/quality/ultimaker_s5/um_s5_global_Fast_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_global_Fast_Quality.inst.cfg index b9bb0beff6..64fa64c463 100644 --- a/resources/quality/ultimaker_s5/um_s5_global_Fast_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_global_Fast_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = -1 diff --git a/resources/quality/ultimaker_s5/um_s5_global_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_global_High_Quality.inst.cfg index aa2420e465..0f15089757 100644 --- a/resources/quality/ultimaker_s5/um_s5_global_High_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_global_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/ultimaker_s5/um_s5_global_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_global_Normal_Quality.inst.cfg index 8bb8f7f282..f31a3e5ee3 100644 --- a/resources/quality/ultimaker_s5/um_s5_global_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_global_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/ultimaker_s5/um_s5_global_Superdraft_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_global_Superdraft_Quality.inst.cfg index ec46668b61..d97e906d8e 100644 --- a/resources/quality/ultimaker_s5/um_s5_global_Superdraft_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_global_Superdraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Sprint definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = superdraft weight = -4 diff --git a/resources/quality/ultimaker_s5/um_s5_global_Verydraft_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_global_Verydraft_Quality.inst.cfg index dd6c7bb4b8..4a6a431e5f 100644 --- a/resources/quality/ultimaker_s5/um_s5_global_Verydraft_Quality.inst.cfg +++ b/resources/quality/ultimaker_s5/um_s5_global_Verydraft_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extra Fast definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = verydraft weight = -3 diff --git a/resources/quality/vertex_delta_k8800/k8800_ABS_Extreme_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_ABS_Extreme_Quality.inst.cfg index 370cc149a2..d1547719f3 100644 --- a/resources/quality/vertex_delta_k8800/k8800_ABS_Extreme_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_ABS_Extreme_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extreme definition = vertex_delta_k8800 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = extreme weight = 2 diff --git a/resources/quality/vertex_delta_k8800/k8800_ABS_High_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_ABS_High_Quality.inst.cfg index 6c96b47169..169fda1f47 100644 --- a/resources/quality/vertex_delta_k8800/k8800_ABS_High_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_ABS_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High definition = vertex_delta_k8800 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/vertex_delta_k8800/k8800_ABS_Normal_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_ABS_Normal_Quality.inst.cfg index 19150baab9..a2a298542e 100644 --- a/resources/quality/vertex_delta_k8800/k8800_ABS_Normal_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_ABS_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = vertex_delta_k8800 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/vertex_delta_k8800/k8800_Global_Extreme_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_Global_Extreme_Quality.inst.cfg index 00d626d72c..f82194c911 100644 --- a/resources/quality/vertex_delta_k8800/k8800_Global_Extreme_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_Global_Extreme_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extreme definition = vertex_delta_k8800 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = extreme weight = 2 diff --git a/resources/quality/vertex_delta_k8800/k8800_Global_High_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_Global_High_Quality.inst.cfg index 0bd519affe..9d8f5fa98d 100644 --- a/resources/quality/vertex_delta_k8800/k8800_Global_High_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_Global_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High definition = vertex_delta_k8800 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/vertex_delta_k8800/k8800_Global_Normal_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_Global_Normal_Quality.inst.cfg index 2b18891998..08bc3aa522 100644 --- a/resources/quality/vertex_delta_k8800/k8800_Global_Normal_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_Global_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = vertex_delta_k8800 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/vertex_delta_k8800/k8800_PET_Extreme_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PET_Extreme_Quality.inst.cfg index 8715e573ab..09c3902405 100644 --- a/resources/quality/vertex_delta_k8800/k8800_PET_Extreme_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_PET_Extreme_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extreme definition = vertex_delta_k8800 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = extreme weight = 2 diff --git a/resources/quality/vertex_delta_k8800/k8800_PET_High_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PET_High_Quality.inst.cfg index 0c94cc5ca4..058ed545b7 100644 --- a/resources/quality/vertex_delta_k8800/k8800_PET_High_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_PET_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High definition = vertex_delta_k8800 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/vertex_delta_k8800/k8800_PET_Normal_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PET_Normal_Quality.inst.cfg index 40698f134d..595f2be25f 100644 --- a/resources/quality/vertex_delta_k8800/k8800_PET_Normal_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_PET_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = vertex_delta_k8800 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/vertex_delta_k8800/k8800_PLA_Extreme_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PLA_Extreme_Quality.inst.cfg index f81c82fa9b..9ec084e758 100644 --- a/resources/quality/vertex_delta_k8800/k8800_PLA_Extreme_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_PLA_Extreme_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extreme definition = vertex_delta_k8800 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = extreme weight = 2 diff --git a/resources/quality/vertex_delta_k8800/k8800_PLA_High_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PLA_High_Quality.inst.cfg index e4b4771b0e..9f1bd25564 100644 --- a/resources/quality/vertex_delta_k8800/k8800_PLA_High_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_PLA_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High definition = vertex_delta_k8800 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/vertex_delta_k8800/k8800_PLA_Normal_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PLA_Normal_Quality.inst.cfg index 41950da7a1..b60c8d8496 100644 --- a/resources/quality/vertex_delta_k8800/k8800_PLA_Normal_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_PLA_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = vertex_delta_k8800 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/vertex_delta_k8800/k8800_TPU_Extreme_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_TPU_Extreme_Quality.inst.cfg index 32077f6cc1..567de3a73b 100644 --- a/resources/quality/vertex_delta_k8800/k8800_TPU_Extreme_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_TPU_Extreme_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Extreme definition = vertex_delta_k8800 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = extreme weight = 2 diff --git a/resources/quality/vertex_delta_k8800/k8800_TPU_High_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_TPU_High_Quality.inst.cfg index a7ef7d8cc8..dbcb27b229 100644 --- a/resources/quality/vertex_delta_k8800/k8800_TPU_High_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_TPU_High_Quality.inst.cfg @@ -4,7 +4,7 @@ name = High definition = vertex_delta_k8800 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = high weight = 1 diff --git a/resources/quality/vertex_delta_k8800/k8800_TPU_Normal_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_TPU_Normal_Quality.inst.cfg index 17a09f366f..975556bb86 100644 --- a/resources/quality/vertex_delta_k8800/k8800_TPU_Normal_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_TPU_Normal_Quality.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = vertex_delta_k8800 [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/zyyx/zyyx_agile_global_fast.inst.cfg b/resources/quality/zyyx/zyyx_agile_global_fast.inst.cfg index 19cda650d3..a795485a6d 100644 --- a/resources/quality/zyyx/zyyx_agile_global_fast.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_global_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = zyyx_agile [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = 1 diff --git a/resources/quality/zyyx/zyyx_agile_global_fine.inst.cfg b/resources/quality/zyyx/zyyx_agile_global_fine.inst.cfg index f2f127f483..6133c0aa99 100644 --- a/resources/quality/zyyx/zyyx_agile_global_fine.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_global_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = zyyx_agile [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fine weight = 1 diff --git a/resources/quality/zyyx/zyyx_agile_global_normal.inst.cfg b/resources/quality/zyyx/zyyx_agile_global_normal.inst.cfg index d9cbdc691e..4a5bfc7d47 100644 --- a/resources/quality/zyyx/zyyx_agile_global_normal.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_global_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = zyyx_agile [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/zyyx/zyyx_agile_pro_flex_fast.inst.cfg b/resources/quality/zyyx/zyyx_agile_pro_flex_fast.inst.cfg index d6f715c09f..ec89e83337 100644 --- a/resources/quality/zyyx/zyyx_agile_pro_flex_fast.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_pro_flex_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = zyyx_agile [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = 1 diff --git a/resources/quality/zyyx/zyyx_agile_pro_flex_fine.inst.cfg b/resources/quality/zyyx/zyyx_agile_pro_flex_fine.inst.cfg index a0aa1996ac..e9ce3c7244 100644 --- a/resources/quality/zyyx/zyyx_agile_pro_flex_fine.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_pro_flex_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = zyyx_agile [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fine weight = 1 diff --git a/resources/quality/zyyx/zyyx_agile_pro_flex_normal.inst.cfg b/resources/quality/zyyx/zyyx_agile_pro_flex_normal.inst.cfg index a70b1dd19a..81d7bcd308 100644 --- a/resources/quality/zyyx/zyyx_agile_pro_flex_normal.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_pro_flex_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = zyyx_agile [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/quality/zyyx/zyyx_agile_pro_pla_fast.inst.cfg b/resources/quality/zyyx/zyyx_agile_pro_pla_fast.inst.cfg index 5b32c3f07b..f805c0f3be 100644 --- a/resources/quality/zyyx/zyyx_agile_pro_pla_fast.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_pro_pla_fast.inst.cfg @@ -4,7 +4,7 @@ name = Fast definition = zyyx_agile [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fast weight = 1 diff --git a/resources/quality/zyyx/zyyx_agile_pro_pla_fine.inst.cfg b/resources/quality/zyyx/zyyx_agile_pro_pla_fine.inst.cfg index a3849bf5e2..9647938cf6 100644 --- a/resources/quality/zyyx/zyyx_agile_pro_pla_fine.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_pro_pla_fine.inst.cfg @@ -4,7 +4,7 @@ name = Fine definition = zyyx_agile [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = fine weight = 1 diff --git a/resources/quality/zyyx/zyyx_agile_pro_pla_normal.inst.cfg b/resources/quality/zyyx/zyyx_agile_pro_pla_normal.inst.cfg index d126308660..af2a32384c 100644 --- a/resources/quality/zyyx/zyyx_agile_pro_pla_normal.inst.cfg +++ b/resources/quality/zyyx/zyyx_agile_pro_pla_normal.inst.cfg @@ -4,7 +4,7 @@ name = Normal definition = zyyx_agile [metadata] -setting_version = 6 +setting_version = 7 type = quality quality_type = normal weight = 0 diff --git a/resources/variants/cartesio_0.25.inst.cfg b/resources/variants/cartesio_0.25.inst.cfg index 53048622f2..24203fa0d3 100644 --- a/resources/variants/cartesio_0.25.inst.cfg +++ b/resources/variants/cartesio_0.25.inst.cfg @@ -5,7 +5,7 @@ definition = cartesio [metadata] author = Cartesio -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/cartesio_0.4.inst.cfg b/resources/variants/cartesio_0.4.inst.cfg index 3ad6b3f3d9..6b980110b7 100644 --- a/resources/variants/cartesio_0.4.inst.cfg +++ b/resources/variants/cartesio_0.4.inst.cfg @@ -5,7 +5,7 @@ definition = cartesio [metadata] author = Cartesio -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/cartesio_0.8.inst.cfg b/resources/variants/cartesio_0.8.inst.cfg index f19c4d58d4..62669929dc 100644 --- a/resources/variants/cartesio_0.8.inst.cfg +++ b/resources/variants/cartesio_0.8.inst.cfg @@ -5,7 +5,7 @@ definition = cartesio [metadata] author = Cartesio -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/fabtotum_hyb35.inst.cfg b/resources/variants/fabtotum_hyb35.inst.cfg index 5ed9eca26a..bf00512c8f 100644 --- a/resources/variants/fabtotum_hyb35.inst.cfg +++ b/resources/variants/fabtotum_hyb35.inst.cfg @@ -5,7 +5,7 @@ definition = fabtotum [metadata] author = FABtotum -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/fabtotum_lite04.inst.cfg b/resources/variants/fabtotum_lite04.inst.cfg index 7b52bf5c29..cb4f7e4d34 100644 --- a/resources/variants/fabtotum_lite04.inst.cfg +++ b/resources/variants/fabtotum_lite04.inst.cfg @@ -5,7 +5,7 @@ definition = fabtotum [metadata] author = FABtotum -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/fabtotum_lite06.inst.cfg b/resources/variants/fabtotum_lite06.inst.cfg index f518f60ce9..9f0e3fe145 100644 --- a/resources/variants/fabtotum_lite06.inst.cfg +++ b/resources/variants/fabtotum_lite06.inst.cfg @@ -5,7 +5,7 @@ definition = fabtotum [metadata] author = FABtotum -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/fabtotum_pro02.inst.cfg b/resources/variants/fabtotum_pro02.inst.cfg index 897bd5aea9..b80f80155b 100644 --- a/resources/variants/fabtotum_pro02.inst.cfg +++ b/resources/variants/fabtotum_pro02.inst.cfg @@ -5,7 +5,7 @@ definition = fabtotum [metadata] author = FABtotum -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/fabtotum_pro04.inst.cfg b/resources/variants/fabtotum_pro04.inst.cfg index d27be2f3b8..7a0afdccb2 100644 --- a/resources/variants/fabtotum_pro04.inst.cfg +++ b/resources/variants/fabtotum_pro04.inst.cfg @@ -5,7 +5,7 @@ definition = fabtotum [metadata] author = FABtotum -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/fabtotum_pro06.inst.cfg b/resources/variants/fabtotum_pro06.inst.cfg index 25b9d7c710..6330b2e77c 100644 --- a/resources/variants/fabtotum_pro06.inst.cfg +++ b/resources/variants/fabtotum_pro06.inst.cfg @@ -5,7 +5,7 @@ definition = fabtotum [metadata] author = FABtotum -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/fabtotum_pro08.inst.cfg b/resources/variants/fabtotum_pro08.inst.cfg index 627e26e2a2..412bbf7410 100644 --- a/resources/variants/fabtotum_pro08.inst.cfg +++ b/resources/variants/fabtotum_pro08.inst.cfg @@ -5,7 +5,7 @@ definition = fabtotum [metadata] author = FABtotum -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/felixtec4_0.25.inst.cfg b/resources/variants/felixtec4_0.25.inst.cfg index 3dda15171b..7a158bcc80 100644 --- a/resources/variants/felixtec4_0.25.inst.cfg +++ b/resources/variants/felixtec4_0.25.inst.cfg @@ -6,7 +6,7 @@ definition = felixtec4dual [metadata] author = kerog777 type = variant -setting_version = 6 +setting_version = 7 hardware_type = nozzle [values] diff --git a/resources/variants/felixtec4_0.35.inst.cfg b/resources/variants/felixtec4_0.35.inst.cfg index db79c3bad4..35850afa7a 100644 --- a/resources/variants/felixtec4_0.35.inst.cfg +++ b/resources/variants/felixtec4_0.35.inst.cfg @@ -6,7 +6,7 @@ definition = felixtec4dual [metadata] author = kerog777 type = variant -setting_version = 6 +setting_version = 7 hardware_type = nozzle [values] diff --git a/resources/variants/felixtec4_0.50.inst.cfg b/resources/variants/felixtec4_0.50.inst.cfg index 6d52881ee5..d4ee356132 100644 --- a/resources/variants/felixtec4_0.50.inst.cfg +++ b/resources/variants/felixtec4_0.50.inst.cfg @@ -7,7 +7,7 @@ definition = felixtec4dual author = kerog777 type = variant hardware_type = nozzle -setting_version = 6 +setting_version = 7 [values] machine_nozzle_size = 0.5 diff --git a/resources/variants/felixtec4_0.70.inst.cfg b/resources/variants/felixtec4_0.70.inst.cfg index 4edeebbc84..b5dfc3758c 100644 --- a/resources/variants/felixtec4_0.70.inst.cfg +++ b/resources/variants/felixtec4_0.70.inst.cfg @@ -7,7 +7,7 @@ definition = felixtec4dual author = kerog777 type = variant hardware_type = nozzle -setting_version = 6 +setting_version = 7 [values] machine_nozzle_size = 0.70 diff --git a/resources/variants/gmax15plus_025_e3d.inst.cfg b/resources/variants/gmax15plus_025_e3d.inst.cfg index a085be0526..42d692d5df 100644 --- a/resources/variants/gmax15plus_025_e3d.inst.cfg +++ b/resources/variants/gmax15plus_025_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus [metadata] author = gcreate -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_04_e3d.inst.cfg b/resources/variants/gmax15plus_04_e3d.inst.cfg index 05473dafd2..fca1fd837d 100644 --- a/resources/variants/gmax15plus_04_e3d.inst.cfg +++ b/resources/variants/gmax15plus_04_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus [metadata] author = gcreate -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_05_e3d.inst.cfg b/resources/variants/gmax15plus_05_e3d.inst.cfg index f3324382ba..9c514dea8f 100644 --- a/resources/variants/gmax15plus_05_e3d.inst.cfg +++ b/resources/variants/gmax15plus_05_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus [metadata] author = gcreate -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_05_jhead.inst.cfg b/resources/variants/gmax15plus_05_jhead.inst.cfg index d480b47367..29dded70e2 100644 --- a/resources/variants/gmax15plus_05_jhead.inst.cfg +++ b/resources/variants/gmax15plus_05_jhead.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus [metadata] author = gcreate -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_06_e3d.inst.cfg b/resources/variants/gmax15plus_06_e3d.inst.cfg index 732870f044..18569ff55a 100644 --- a/resources/variants/gmax15plus_06_e3d.inst.cfg +++ b/resources/variants/gmax15plus_06_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus [metadata] author = gcreate -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_08_e3d.inst.cfg b/resources/variants/gmax15plus_08_e3d.inst.cfg index 0c4137a018..5ec1ce6916 100644 --- a/resources/variants/gmax15plus_08_e3d.inst.cfg +++ b/resources/variants/gmax15plus_08_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus [metadata] author = gcreate -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_10_jhead.inst.cfg b/resources/variants/gmax15plus_10_jhead.inst.cfg index 8ae93fc93c..81c8ce2fcc 100644 --- a/resources/variants/gmax15plus_10_jhead.inst.cfg +++ b/resources/variants/gmax15plus_10_jhead.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus [metadata] author = gcreate -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_12_e3d.inst.cfg b/resources/variants/gmax15plus_12_e3d.inst.cfg index 016f48c1a3..3381f53cd0 100644 --- a/resources/variants/gmax15plus_12_e3d.inst.cfg +++ b/resources/variants/gmax15plus_12_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus [metadata] author = gcreate -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_dual_025_e3d.inst.cfg b/resources/variants/gmax15plus_dual_025_e3d.inst.cfg index 185166d3b5..a3d22f8629 100644 --- a/resources/variants/gmax15plus_dual_025_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_025_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus_dual [metadata] author = gcreate -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_dual_04_e3d.inst.cfg b/resources/variants/gmax15plus_dual_04_e3d.inst.cfg index 1c534f13e0..4338432b10 100644 --- a/resources/variants/gmax15plus_dual_04_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_04_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus_dual [metadata] author = gcreate -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_dual_05_e3d.inst.cfg b/resources/variants/gmax15plus_dual_05_e3d.inst.cfg index f1d67509a9..1c1151324c 100644 --- a/resources/variants/gmax15plus_dual_05_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_05_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus_dual [metadata] author = gcreate -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_dual_05_jhead.inst.cfg b/resources/variants/gmax15plus_dual_05_jhead.inst.cfg index bc72c4ae20..ce2e9546be 100644 --- a/resources/variants/gmax15plus_dual_05_jhead.inst.cfg +++ b/resources/variants/gmax15plus_dual_05_jhead.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus_dual [metadata] author = gcreate -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_dual_06_e3d.inst.cfg b/resources/variants/gmax15plus_dual_06_e3d.inst.cfg index 545cfcb238..ec2f378ff5 100644 --- a/resources/variants/gmax15plus_dual_06_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_06_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus_dual [metadata] author = gcreate -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_dual_08_e3d.inst.cfg b/resources/variants/gmax15plus_dual_08_e3d.inst.cfg index 1923aac7f7..06f9969302 100644 --- a/resources/variants/gmax15plus_dual_08_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_08_e3d.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus_dual [metadata] author = gcreate -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_dual_10_jhead.inst.cfg b/resources/variants/gmax15plus_dual_10_jhead.inst.cfg index de0776ad9b..6fefc37862 100644 --- a/resources/variants/gmax15plus_dual_10_jhead.inst.cfg +++ b/resources/variants/gmax15plus_dual_10_jhead.inst.cfg @@ -5,7 +5,7 @@ definition = gmax15plus_dual [metadata] author = gcreate -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/imade3d_jellybox_0.4.inst.cfg b/resources/variants/imade3d_jellybox_0.4.inst.cfg index 1623e6755c..18481a8342 100644 --- a/resources/variants/imade3d_jellybox_0.4.inst.cfg +++ b/resources/variants/imade3d_jellybox_0.4.inst.cfg @@ -5,7 +5,7 @@ definition = imade3d_jellybox [metadata] author = IMADE3D -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg b/resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg index 2f1cb002b4..2f4d35676e 100644 --- a/resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg +++ b/resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg @@ -5,7 +5,7 @@ definition = imade3d_jellybox [metadata] author = IMADE3D -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/tizyx_k25_0.2.inst.cfg b/resources/variants/tizyx_k25_0.2.inst.cfg index c616579911..589d50f93c 100644 --- a/resources/variants/tizyx_k25_0.2.inst.cfg +++ b/resources/variants/tizyx_k25_0.2.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = tizyx_k25 [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/tizyx_k25_0.3.inst.cfg b/resources/variants/tizyx_k25_0.3.inst.cfg index 180d831cca..41612baa4d 100644 --- a/resources/variants/tizyx_k25_0.3.inst.cfg +++ b/resources/variants/tizyx_k25_0.3.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = tizyx_k25 [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/tizyx_k25_0.4.inst.cfg b/resources/variants/tizyx_k25_0.4.inst.cfg index 07ef3ca8ed..b3fca877b3 100644 --- a/resources/variants/tizyx_k25_0.4.inst.cfg +++ b/resources/variants/tizyx_k25_0.4.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = tizyx_k25 [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/tizyx_k25_0.5.inst.cfg b/resources/variants/tizyx_k25_0.5.inst.cfg index a09a207e7a..e0dd4f1054 100644 --- a/resources/variants/tizyx_k25_0.5.inst.cfg +++ b/resources/variants/tizyx_k25_0.5.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = tizyx_k25 [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/tizyx_k25_0.6.inst.cfg b/resources/variants/tizyx_k25_0.6.inst.cfg index 751cf8e794..d2aebe4695 100644 --- a/resources/variants/tizyx_k25_0.6.inst.cfg +++ b/resources/variants/tizyx_k25_0.6.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = tizyx_k25 [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/tizyx_k25_0.8.inst.cfg b/resources/variants/tizyx_k25_0.8.inst.cfg index cca0986ed5..5a425988ee 100644 --- a/resources/variants/tizyx_k25_0.8.inst.cfg +++ b/resources/variants/tizyx_k25_0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = tizyx_k25 [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/tizyx_k25_1.0.inst.cfg b/resources/variants/tizyx_k25_1.0.inst.cfg index d99948c26c..01c8944960 100644 --- a/resources/variants/tizyx_k25_1.0.inst.cfg +++ b/resources/variants/tizyx_k25_1.0.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = tizyx_k25 [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_0.25.inst.cfg b/resources/variants/ultimaker2_0.25.inst.cfg index 004cdaf671..87bb0a237d 100644 --- a/resources/variants/ultimaker2_0.25.inst.cfg +++ b/resources/variants/ultimaker2_0.25.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2 [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_0.4.inst.cfg b/resources/variants/ultimaker2_0.4.inst.cfg index 607d0c4f29..b50cc32eca 100644 --- a/resources/variants/ultimaker2_0.4.inst.cfg +++ b/resources/variants/ultimaker2_0.4.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2 [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_0.6.inst.cfg b/resources/variants/ultimaker2_0.6.inst.cfg index 1ddc07817b..fac65ed284 100644 --- a/resources/variants/ultimaker2_0.6.inst.cfg +++ b/resources/variants/ultimaker2_0.6.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2 [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_0.8.inst.cfg b/resources/variants/ultimaker2_0.8.inst.cfg index 938b472c2c..9177e8e6ee 100644 --- a/resources/variants/ultimaker2_0.8.inst.cfg +++ b/resources/variants/ultimaker2_0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2 [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_extended_0.25.inst.cfg b/resources/variants/ultimaker2_extended_0.25.inst.cfg index 45546c55aa..eceb659e21 100644 --- a/resources/variants/ultimaker2_extended_0.25.inst.cfg +++ b/resources/variants/ultimaker2_extended_0.25.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_extended [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_extended_0.4.inst.cfg b/resources/variants/ultimaker2_extended_0.4.inst.cfg index fb3d8c1116..e3dad7fd56 100644 --- a/resources/variants/ultimaker2_extended_0.4.inst.cfg +++ b/resources/variants/ultimaker2_extended_0.4.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_extended [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_extended_0.6.inst.cfg b/resources/variants/ultimaker2_extended_0.6.inst.cfg index 50f7dc04c6..82a5c08362 100644 --- a/resources/variants/ultimaker2_extended_0.6.inst.cfg +++ b/resources/variants/ultimaker2_extended_0.6.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_extended [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_extended_0.8.inst.cfg b/resources/variants/ultimaker2_extended_0.8.inst.cfg index 178737dbd5..4f9d1d8889 100644 --- a/resources/variants/ultimaker2_extended_0.8.inst.cfg +++ b/resources/variants/ultimaker2_extended_0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_extended [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg index 7e67824d16..034d094e86 100644 --- a/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_extended_plus [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg index 1150c6127c..976e129393 100644 --- a/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_extended_plus [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg index fbdef77918..b7cbe8fa62 100644 --- a/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_extended_plus [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg index 106537e0a7..437e107e89 100644 --- a/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_extended_plus [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_plus_0.25.inst.cfg b/resources/variants/ultimaker2_plus_0.25.inst.cfg index c07b80c246..0880159d03 100644 --- a/resources/variants/ultimaker2_plus_0.25.inst.cfg +++ b/resources/variants/ultimaker2_plus_0.25.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_plus_0.4.inst.cfg b/resources/variants/ultimaker2_plus_0.4.inst.cfg index 623fffbeb9..4543c148bb 100644 --- a/resources/variants/ultimaker2_plus_0.4.inst.cfg +++ b/resources/variants/ultimaker2_plus_0.4.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_plus_0.6.inst.cfg b/resources/variants/ultimaker2_plus_0.6.inst.cfg index b57fa81dfe..57ff6714a7 100644 --- a/resources/variants/ultimaker2_plus_0.6.inst.cfg +++ b/resources/variants/ultimaker2_plus_0.6.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker2_plus_0.8.inst.cfg b/resources/variants/ultimaker2_plus_0.8.inst.cfg index 702ec2ef31..0fd1b50c5f 100644 --- a/resources/variants/ultimaker2_plus_0.8.inst.cfg +++ b/resources/variants/ultimaker2_plus_0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker2_plus [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker3_aa0.25.inst.cfg b/resources/variants/ultimaker3_aa0.25.inst.cfg index fc8cc3b090..1dadf10e91 100644 --- a/resources/variants/ultimaker3_aa0.25.inst.cfg +++ b/resources/variants/ultimaker3_aa0.25.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker3_aa0.8.inst.cfg b/resources/variants/ultimaker3_aa0.8.inst.cfg index 308bed6fcb..c224c49c43 100644 --- a/resources/variants/ultimaker3_aa0.8.inst.cfg +++ b/resources/variants/ultimaker3_aa0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker3_aa04.inst.cfg b/resources/variants/ultimaker3_aa04.inst.cfg index 25230cd30b..b5a250184f 100644 --- a/resources/variants/ultimaker3_aa04.inst.cfg +++ b/resources/variants/ultimaker3_aa04.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker3_bb0.8.inst.cfg b/resources/variants/ultimaker3_bb0.8.inst.cfg index 5ccf2816ff..df5b654e2e 100644 --- a/resources/variants/ultimaker3_bb0.8.inst.cfg +++ b/resources/variants/ultimaker3_bb0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker3_bb04.inst.cfg b/resources/variants/ultimaker3_bb04.inst.cfg index d919e5aab7..70e2a5faa8 100644 --- a/resources/variants/ultimaker3_bb04.inst.cfg +++ b/resources/variants/ultimaker3_bb04.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker3 [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker3_extended_aa0.25.inst.cfg b/resources/variants/ultimaker3_extended_aa0.25.inst.cfg index ce0f20fa7e..5a9292ad1f 100644 --- a/resources/variants/ultimaker3_extended_aa0.25.inst.cfg +++ b/resources/variants/ultimaker3_extended_aa0.25.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker3_extended [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker3_extended_aa0.8.inst.cfg b/resources/variants/ultimaker3_extended_aa0.8.inst.cfg index f209508875..03b5b0753d 100644 --- a/resources/variants/ultimaker3_extended_aa0.8.inst.cfg +++ b/resources/variants/ultimaker3_extended_aa0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker3_extended [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker3_extended_aa04.inst.cfg b/resources/variants/ultimaker3_extended_aa04.inst.cfg index 714d19051f..8303eca4e6 100644 --- a/resources/variants/ultimaker3_extended_aa04.inst.cfg +++ b/resources/variants/ultimaker3_extended_aa04.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker3_extended [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker3_extended_bb0.8.inst.cfg b/resources/variants/ultimaker3_extended_bb0.8.inst.cfg index 528c7f70ec..13bb67d108 100644 --- a/resources/variants/ultimaker3_extended_bb0.8.inst.cfg +++ b/resources/variants/ultimaker3_extended_bb0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker3_extended [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker3_extended_bb04.inst.cfg b/resources/variants/ultimaker3_extended_bb04.inst.cfg index 5ee562ee38..36191bd054 100644 --- a/resources/variants/ultimaker3_extended_bb04.inst.cfg +++ b/resources/variants/ultimaker3_extended_bb04.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker3_extended [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker_s5_aa0.25.inst.cfg b/resources/variants/ultimaker_s5_aa0.25.inst.cfg index ebdb096b6f..e2ed3defe9 100644 --- a/resources/variants/ultimaker_s5_aa0.25.inst.cfg +++ b/resources/variants/ultimaker_s5_aa0.25.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker_s5_aa0.8.inst.cfg b/resources/variants/ultimaker_s5_aa0.8.inst.cfg index d8ff1c020e..84b3802fef 100644 --- a/resources/variants/ultimaker_s5_aa0.8.inst.cfg +++ b/resources/variants/ultimaker_s5_aa0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker_s5_aa04.inst.cfg b/resources/variants/ultimaker_s5_aa04.inst.cfg index ac377e3e78..88dbc25d91 100644 --- a/resources/variants/ultimaker_s5_aa04.inst.cfg +++ b/resources/variants/ultimaker_s5_aa04.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker_s5_aluminum.inst.cfg b/resources/variants/ultimaker_s5_aluminum.inst.cfg index ca457bd7e7..65b0a6da68 100644 --- a/resources/variants/ultimaker_s5_aluminum.inst.cfg +++ b/resources/variants/ultimaker_s5_aluminum.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = buildplate diff --git a/resources/variants/ultimaker_s5_bb0.8.inst.cfg b/resources/variants/ultimaker_s5_bb0.8.inst.cfg index bb7f2d1420..d05ce74f61 100644 --- a/resources/variants/ultimaker_s5_bb0.8.inst.cfg +++ b/resources/variants/ultimaker_s5_bb0.8.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker_s5_bb04.inst.cfg b/resources/variants/ultimaker_s5_bb04.inst.cfg index cda1036507..2d3bc42a50 100644 --- a/resources/variants/ultimaker_s5_bb04.inst.cfg +++ b/resources/variants/ultimaker_s5_bb04.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker_s5_cc06.inst.cfg b/resources/variants/ultimaker_s5_cc06.inst.cfg index afbeb44462..f64e3b9055 100644 --- a/resources/variants/ultimaker_s5_cc06.inst.cfg +++ b/resources/variants/ultimaker_s5_cc06.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = nozzle diff --git a/resources/variants/ultimaker_s5_glass.inst.cfg b/resources/variants/ultimaker_s5_glass.inst.cfg index e7431c933f..87196e5e9b 100644 --- a/resources/variants/ultimaker_s5_glass.inst.cfg +++ b/resources/variants/ultimaker_s5_glass.inst.cfg @@ -4,7 +4,7 @@ version = 4 definition = ultimaker_s5 [metadata] -setting_version = 6 +setting_version = 7 type = variant hardware_type = buildplate From badb0b0ca9786d3ebdcc4c22b74c1cf2fabc129b Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Thu, 17 Jan 2019 12:58:23 +0100 Subject: [PATCH 1283/1292] Use `patch.object` to allow relative imports Issue STAR-322. --- .../tests/Cloud/TestCloudApiClient.py | 6 +++--- .../tests/Cloud/TestCloudOutputDevice.py | 17 +++++++++-------- .../tests/Cloud/TestCloudOutputDeviceManager.py | 11 ++++++----- run_mypy.py | 1 + 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py index 36e03c6213..b79d009c31 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py @@ -6,7 +6,7 @@ from unittest import TestCase from unittest.mock import patch, MagicMock from cura.UltimakerCloudAuthentication import CuraCloudAPIRoot -from ...src.Cloud.CloudApiClient import CloudApiClient +from ...src.Cloud import CloudApiClient from ...src.Cloud.Models.CloudClusterResponse import CloudClusterResponse from ...src.Cloud.Models.CloudClusterStatus import CloudClusterStatus from ...src.Cloud.Models.CloudPrintJobResponse import CloudPrintJobResponse @@ -28,8 +28,8 @@ class TestCloudApiClient(TestCase): self.account.isLoggedIn.return_value = True self.network = NetworkManagerMock() - with patch("CloudApiClient.QNetworkAccessManager", return_value = self.network): - self.api = CloudApiClient(self.account, self._errorHandler) + with patch.object(CloudApiClient, 'QNetworkAccessManager', return_value = self.network): + self.api = CloudApiClient.CloudApiClient(self.account, self._errorHandler) def test_getClusters(self): result = [] diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py index d9f983640e..14b1f4feba 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py @@ -7,7 +7,7 @@ from unittest.mock import patch, MagicMock from UM.Scene.SceneNode import SceneNode from cura.UltimakerCloudAuthentication import CuraCloudAPIRoot from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel -from ...src.Cloud.CloudApiClient import CloudApiClient +from ...src.Cloud import CloudApiClient from ...src.Cloud.CloudOutputDevice import CloudOutputDevice from ...src.Cloud.Models.CloudClusterResponse import CloudClusterResponse from .Fixtures import readFixture, parseFixture @@ -41,19 +41,20 @@ class TestCloudOutputDevice(TestCase): self.network = NetworkManagerMock() self.account = MagicMock(isLoggedIn=True, accessToken="TestAccessToken") self.onError = MagicMock() - with patch("CloudApiClient.QNetworkAccessManager", - return_value = self.network): - self._api = CloudApiClient(self.account, self.onError) + with patch.object(CloudApiClient, "QNetworkAccessManager", return_value = self.network): + self._api = CloudApiClient.CloudApiClient(self.account, self.onError) self.device = CloudOutputDevice(self._api, self.cluster) self.cluster_status = parseFixture("getClusterStatusResponse") self.network.prepareReply("GET", self.STATUS_URL, 200, readFixture("getClusterStatusResponse")) def tearDown(self): - super().tearDown() - self.network.flushReplies() - for patched_method in self.patches: - patched_method.stop() + try: + super().tearDown() + self.network.flushReplies() + finally: + for patched_method in self.patches: + patched_method.stop() def test_status(self): self.device._update() diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py index 66acac8eff..e24ca1694e 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py @@ -5,7 +5,8 @@ from unittest.mock import patch, MagicMock from UM.OutputDevice.OutputDeviceManager import OutputDeviceManager from cura.UltimakerCloudAuthentication import CuraCloudAPIRoot -from ...src.Cloud.CloudOutputDeviceManager import CloudOutputDeviceManager +from ...src.Cloud import CloudApiClient +from ...src.Cloud import CloudOutputDeviceManager from .Fixtures import parseFixture, readFixture from .NetworkManagerMock import NetworkManagerMock, FakeSignal @@ -28,9 +29,9 @@ class TestCloudOutputDeviceManager(TestCase): self.network = NetworkManagerMock() self.timer = MagicMock(timeout = FakeSignal()) - with patch("CloudApiClient.QNetworkAccessManager", return_value = self.network), \ - patch("CloudOutputDeviceManager.QTimer", return_value = self.timer): - self.manager = CloudOutputDeviceManager() + with patch.object(CloudApiClient, "QNetworkAccessManager", return_value = self.network), \ + patch.object(CloudOutputDeviceManager, "QTimer", return_value = self.timer): + self.manager = CloudOutputDeviceManager.CloudOutputDeviceManager() self.clusters_response = parseFixture("getClusters") self.network.prepareReply("GET", self.URL, 200, readFixture("getClusters")) @@ -112,7 +113,7 @@ class TestCloudOutputDeviceManager(TestCase): active_machine_mock.setMetaDataEntry.assert_called_with("um_cloud_cluster_id", cluster2["cluster_id"]) - @patch("CloudOutputDeviceManager.Message") + @patch.object(CloudOutputDeviceManager, "Message") def test_api_error(self, message_mock): self.clusters_response = { "errors": [{"id": "notFound", "title": "Not found!", "http_status": "404", "code": "notFound"}] diff --git a/run_mypy.py b/run_mypy.py index 27f07cd281..2073f0e9a7 100644 --- a/run_mypy.py +++ b/run_mypy.py @@ -29,6 +29,7 @@ def where(exe_name: str, search_path: str = os.getenv("PATH")) -> str: def findModules(path): + return ["UM3NetworkPrinting"] result = [] for entry in os.scandir(path): if entry.is_dir() and os.path.exists(os.path.join(path, entry.name, "__init__.py")): From 2b27c8c1a980c9ef9c69d4d481af5a226ac5e04c Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Thu, 17 Jan 2019 13:00:42 +0100 Subject: [PATCH 1284/1292] Revert incorrect change to run_mypy --- run_mypy.py | 1 - 1 file changed, 1 deletion(-) diff --git a/run_mypy.py b/run_mypy.py index 2073f0e9a7..27f07cd281 100644 --- a/run_mypy.py +++ b/run_mypy.py @@ -29,7 +29,6 @@ def where(exe_name: str, search_path: str = os.getenv("PATH")) -> str: def findModules(path): - return ["UM3NetworkPrinting"] result = [] for entry in os.scandir(path): if entry.is_dir() and os.path.exists(os.path.join(path, entry.name, "__init__.py")): From 665c33156468270e53fb2702f7d60f0deab0618a Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 17 Jan 2019 13:04:04 +0100 Subject: [PATCH 1285/1292] Added skip mark to failing cloud tests --- plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py | 3 +++ .../UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py | 3 +++ .../tests/Cloud/TestCloudOutputDeviceManager.py | 3 +++ 3 files changed, 9 insertions(+) diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py index 36e03c6213..d6f118d99e 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py @@ -15,6 +15,9 @@ from ...src.Cloud.Models.CloudError import CloudError from .Fixtures import readFixture, parseFixture from .NetworkManagerMock import NetworkManagerMock +import pytest +pytestmark = pytest.mark.skip("Tests failing due to incorrect paths in patch") + class TestCloudApiClient(TestCase): maxDiff = None diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py index d9f983640e..cee074ae54 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py @@ -13,6 +13,9 @@ from ...src.Cloud.Models.CloudClusterResponse import CloudClusterResponse from .Fixtures import readFixture, parseFixture from .NetworkManagerMock import NetworkManagerMock +import pytest +pytestmark = pytest.mark.skip("Tests failing due to incorrect paths in patch") + class TestCloudOutputDevice(TestCase): maxDiff = None diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py index 66acac8eff..615409ffaf 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py @@ -9,6 +9,9 @@ from ...src.Cloud.CloudOutputDeviceManager import CloudOutputDeviceManager from .Fixtures import parseFixture, readFixture from .NetworkManagerMock import NetworkManagerMock, FakeSignal +import pytest +pytestmark = pytest.mark.skip("Tests failing due to incorrect paths in patch") + class TestCloudOutputDeviceManager(TestCase): maxDiff = None From 12a120f04407a1b54770c884c14d6e642984df11 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 17 Jan 2019 14:21:11 +0100 Subject: [PATCH 1286/1292] Slightly modify the variant label to match more with the monitor tab CURA-6100 --- .../ConfigurationMenu/ConfigurationMenu.qml | 63 +++++++------------ 1 file changed, 22 insertions(+), 41 deletions(-) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index 89d753463a..1e3b48b1df 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -61,6 +61,26 @@ Cura.ExpandablePopup width: height } + // Label for the brand of the material + Label + { + id: typeAndBrandNameLabel + + text: model.material_brand + " " + model.material + elide: Text.ElideRight + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + renderType: Text.NativeRendering + + anchors + { + top: extruderIcon.top + left: extruderIcon.right + leftMargin: UM.Theme.getSize("default_margin").width + right: parent.right + rightMargin: UM.Theme.getSize("default_margin").width + } + } // Label that shows the name of the variant Label { @@ -70,7 +90,7 @@ Cura.ExpandablePopup text: model.variant elide: Text.ElideRight - font: UM.Theme.getFont("medium") + font: UM.Theme.getFont("default_bold") color: UM.Theme.getColor("text") renderType: Text.NativeRendering @@ -78,46 +98,7 @@ Cura.ExpandablePopup { left: extruderIcon.right leftMargin: UM.Theme.getSize("default_margin").width - verticalCenter: parent.verticalCenter - } - } - - // Label for the brand of the material - Label - { - id: brandNameLabel - - text: model.material_brand - elide: Text.ElideRight - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text_inactive") - renderType: Text.NativeRendering - - anchors - { - left: variantLabel.visible ? variantLabel.right : extruderIcon.right - leftMargin: UM.Theme.getSize("default_margin").width - right: parent.right - rightMargin: UM.Theme.getSize("default_margin").width - } - } - - // Label that shows the name of the material - Label - { - text: model.material - elide: Text.ElideRight - font: UM.Theme.getFont("medium") - color: UM.Theme.getColor("text") - renderType: Text.NativeRendering - - anchors - { - left: variantLabel.visible ? variantLabel.right : extruderIcon.right - leftMargin: UM.Theme.getSize("default_margin").width - right: parent.right - rightMargin: UM.Theme.getSize("default_margin").width - top: brandNameLabel.bottom + top: typeAndBrandNameLabel.bottom } } } From 894dbcf6f6dc45b2863e1e362dfd12a8bb933a8e Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 17 Jan 2019 14:43:43 +0100 Subject: [PATCH 1287/1292] Revert "Added skip mark to failing cloud tests" This reverts commit 665c33156468270e53fb2702f7d60f0deab0618a. --- plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py | 3 --- .../UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py | 3 --- .../tests/Cloud/TestCloudOutputDeviceManager.py | 3 --- 3 files changed, 9 deletions(-) diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py index e6ae0ef90c..b79d009c31 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py @@ -15,9 +15,6 @@ from ...src.Cloud.Models.CloudError import CloudError from .Fixtures import readFixture, parseFixture from .NetworkManagerMock import NetworkManagerMock -import pytest -pytestmark = pytest.mark.skip("Tests failing due to incorrect paths in patch") - class TestCloudApiClient(TestCase): maxDiff = None diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py index e5c5222589..14b1f4feba 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py @@ -13,9 +13,6 @@ from ...src.Cloud.Models.CloudClusterResponse import CloudClusterResponse from .Fixtures import readFixture, parseFixture from .NetworkManagerMock import NetworkManagerMock -import pytest -pytestmark = pytest.mark.skip("Tests failing due to incorrect paths in patch") - class TestCloudOutputDevice(TestCase): maxDiff = None diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py index 7c9e0a5dbe..e24ca1694e 100644 --- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py @@ -10,9 +10,6 @@ from ...src.Cloud import CloudOutputDeviceManager from .Fixtures import parseFixture, readFixture from .NetworkManagerMock import NetworkManagerMock, FakeSignal -import pytest -pytestmark = pytest.mark.skip("Tests failing due to incorrect paths in patch") - class TestCloudOutputDeviceManager(TestCase): maxDiff = None From 662dd80a1d90debe141527db28ac9b57d7780c83 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 17 Jan 2019 16:06:10 +0100 Subject: [PATCH 1288/1292] Add logging if the status code of toolbox request is not 200 --- plugins/Toolbox/src/Toolbox.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index ccd181cdbc..42cb5d52a8 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -649,6 +649,7 @@ class Toolbox(QObject, Extension): Logger.log("w", "Received invalid JSON for %s.", response_type) break else: + Logger.log("w", "Unable to connect with the server, we got a response code %s while trying to connect to %s", reply.attribute(QNetworkRequest.HttpStatusCodeAttribute), reply.url()) self.setViewPage("errored") self.resetDownload() elif reply.operation() == QNetworkAccessManager.PutOperation: From 72a7cc59cee47301ddbe5cbc861fcad6bd26e589 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 17 Jan 2019 16:14:57 +0100 Subject: [PATCH 1289/1292] Use sane default when CuraCloudApiVersion is not set --- cura/UltimakerCloudAuthentication.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cura/UltimakerCloudAuthentication.py b/cura/UltimakerCloudAuthentication.py index 69bb577354..c8346e5c4e 100644 --- a/cura/UltimakerCloudAuthentication.py +++ b/cura/UltimakerCloudAuthentication.py @@ -17,6 +17,8 @@ except ImportError: try: from cura.CuraVersion import CuraCloudAPIVersion # type: ignore + if CuraCloudAPIVersion == "": + CuraCloudAPIVersion = DEFAULT_CLOUD_API_VERSION except ImportError: CuraCloudAPIVersion = DEFAULT_CLOUD_API_VERSION From 13c1a706776a0db9ecf46b4c2af5f84b493d736a Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 17 Jan 2019 16:31:40 +0100 Subject: [PATCH 1290/1292] Fix margin The theme entry didn't exist. Discovered during work on CURA-6086, but for the rest unrelated. --- .../Recommended/RecommendedTroubleshootingGuides.qml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedTroubleshootingGuides.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedTroubleshootingGuides.qml index 846e343028..e6706421bb 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedTroubleshootingGuides.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedTroubleshootingGuides.qml @@ -13,7 +13,7 @@ Item { id: tipsCell anchors.top: adhesionCheckBox.visible ? adhesionCheckBox.bottom : (enableSupportCheckBox.visible ? supportExtruderCombobox.bottom : infillCellRight.bottom) - anchors.topMargin: Math.round(UM.Theme.getSize("sidebar_margin").height * 2) + anchors.topMargin: Math.round(UM.Theme.getSize("default_margin").height * 2) anchors.left: parent.left width: parent.width height: tipsText.contentHeight * tipsText.lineCount @@ -22,9 +22,9 @@ Item { id: tipsText anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width + anchors.leftMargin: UM.Theme.getSize("default_margin").width anchors.right: parent.right - anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width + anchors.rightMargin: UM.Theme.getSize("default_margin").width anchors.top: parent.top wrapMode: Text.WordWrap text: catalog.i18nc("@label", "Need help improving your prints?
    Read the Ultimaker Troubleshooting Guides").arg("https://ultimaker.com/en/troubleshooting") From 0b69d655dbc44c1c5f9a07008b25254fee24f853 Mon Sep 17 00:00:00 2001 From: DragonJe <41123088+DragonJe@users.noreply.github.com> Date: Thu, 17 Jan 2019 10:39:00 -0600 Subject: [PATCH 1291/1292] Adding NWA3D A5 printer (#5118) * Add files via upload * Add files via upload * Create nwa3d_a5_normal.inst.cfg * Add files via upload * Add files via upload * Delete nwa3d_a5.def.json * Create nwa3d_a5.def.json * Delete nwa3d_backplate.png * Update resources/quality/nwa3d_a5/nwa3d_a5_best.inst.cfg Co-Authored-By: DragonJe <41123088+DragonJe@users.noreply.github.com> * Update resources/quality/nwa3d_a5/nwa3d_a5_best.inst.cfg Co-Authored-By: DragonJe <41123088+DragonJe@users.noreply.github.com> * Update resources/definitions/nwa3d_a5.def.json Co-Authored-By: DragonJe <41123088+DragonJe@users.noreply.github.com> * Update resources/quality/nwa3d_a5/nwa3d_a5_fast.inst.cfg Co-Authored-By: DragonJe <41123088+DragonJe@users.noreply.github.com> * Update resources/quality/nwa3d_a5/nwa3d_a5_normal.inst.cfg Co-Authored-By: DragonJe <41123088+DragonJe@users.noreply.github.com> * Update resources/quality/nwa3d_a5/nwa3d_a5_fast.inst.cfg Co-Authored-By: DragonJe <41123088+DragonJe@users.noreply.github.com> * Update resources/quality/nwa3d_a5/nwa3d_a5_normal.inst.cfg Co-Authored-By: DragonJe <41123088+DragonJe@users.noreply.github.com> * Update resources/definitions/nwa3d_a5.def.json Co-Authored-By: DragonJe <41123088+DragonJe@users.noreply.github.com> * Update resources/definitions/nwa3d_a5.def.json Co-Authored-By: DragonJe <41123088+DragonJe@users.noreply.github.com> * Update resources/definitions/nwa3d_a5.def.json Co-Authored-By: DragonJe <41123088+DragonJe@users.noreply.github.com> * Update resources/quality/nwa3d_a5/nwa3d_a5_best.inst.cfg Co-Authored-By: DragonJe <41123088+DragonJe@users.noreply.github.com> * Update resources/quality/nwa3d_a5/nwa3d_a5_fast.inst.cfg Co-Authored-By: DragonJe <41123088+DragonJe@users.noreply.github.com> * Update resources/quality/nwa3d_a5/nwa3d_a5_normal.inst.cfg Co-Authored-By: DragonJe <41123088+DragonJe@users.noreply.github.com> * Update resources/definitions/nwa3d_a5.def.json Co-Authored-By: DragonJe <41123088+DragonJe@users.noreply.github.com> * Update resources/extruders/nwa3d_a5_extruder_0.def.json Co-Authored-By: DragonJe <41123088+DragonJe@users.noreply.github.com> --- resources/definitions/nwa3d_a5.def.json | 64 +++++++++ .../extruders/nwa3d_a5_extruder_0.def.json | 16 +++ .../quality/nwa3d_a5/nwa3d_a5_best.inst.cfg | 131 ++++++++++++++++++ .../quality/nwa3d_a5/nwa3d_a5_fast.inst.cfg | 125 +++++++++++++++++ .../quality/nwa3d_a5/nwa3d_a5_normal.inst.cfg | 125 +++++++++++++++++ 5 files changed, 461 insertions(+) create mode 100644 resources/definitions/nwa3d_a5.def.json create mode 100644 resources/extruders/nwa3d_a5_extruder_0.def.json create mode 100644 resources/quality/nwa3d_a5/nwa3d_a5_best.inst.cfg create mode 100644 resources/quality/nwa3d_a5/nwa3d_a5_fast.inst.cfg create mode 100644 resources/quality/nwa3d_a5/nwa3d_a5_normal.inst.cfg diff --git a/resources/definitions/nwa3d_a5.def.json b/resources/definitions/nwa3d_a5.def.json new file mode 100644 index 0000000000..3deb0027fd --- /dev/null +++ b/resources/definitions/nwa3d_a5.def.json @@ -0,0 +1,64 @@ +{ + "name": "NWA3D A5", + "version": 2, + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "author": "DragonJe", + "manufacturer": "NWA 3D LLC", + "file_formats": "text/x-gcode", + "platform_offset": [0, 0, 0], + "has_materials": true, + "has_variants": false, + "has_machine_materials": true, + "has_variant_materials": false, + "preferred_quality_type": "normal", + "has_machine_quality": true, + "preferred_material": "generic_pla", + "machine_extruder_trains": + { + "0": "nwa3d_a5_extruder_0" + } + }, + + "overrides": { + "machine_name": { + "default_value": "NWA3D A5" + }, + "machine_width": { + "default_value": 125 + }, + "machine_height": { + "default_value": 100 + }, + "machine_depth": { + "default_value": 150 + }, + "machine_head_polygon": { + "default_value": [ + [-30, 34], + [-30, -32], + [30, -32], + [30, 34] + ] + }, + "gantry_height": { + "default_value": 30 + }, + "machine_heated_bed": { + "default_value": false + }, + "material_diameter": { + "default_value": 1.75 + }, + "machine_gcode_flavor": { + "default_value": "RepRap (RepRap)" + }, + "machine_start_gcode": { + "default_value": "G28 ; Home\nG1 Z15.0 F6000 ; Move Z axis up 15mm\n ; Prime the extruder\nG92 E0\nG1 F200 E3\nG92 E0" + }, + "machine_end_gcode": { + "default_value": "M104 S0\nM140 S0\n ; Retract the filament\nG92 E1\nG1 E-1 F300\nG28 X0 Y0\nM84" + } + } +} diff --git a/resources/extruders/nwa3d_a5_extruder_0.def.json b/resources/extruders/nwa3d_a5_extruder_0.def.json new file mode 100644 index 0000000000..5c3cc6a127 --- /dev/null +++ b/resources/extruders/nwa3d_a5_extruder_0.def.json @@ -0,0 +1,16 @@ +{ + "id": "nwa3d_a5_extruder_0", + "version": 2, + "name": "Regular 0.4mm Nozzle", + "inherits": "fdmextruder", + "metadata": { + "machine": "nwa3d_a5", + "position": "0" + }, + + "overrides": { + "extruder_nr": { "default_value": 0 }, + "machine_nozzle_size": { "default_value": 0.4 }, + "material_diameter": { "default_value": 1.75 } + } +} diff --git a/resources/quality/nwa3d_a5/nwa3d_a5_best.inst.cfg b/resources/quality/nwa3d_a5/nwa3d_a5_best.inst.cfg new file mode 100644 index 0000000000..933f731dbd --- /dev/null +++ b/resources/quality/nwa3d_a5/nwa3d_a5_best.inst.cfg @@ -0,0 +1,131 @@ +[general] +version = 4 +name = Best Quality +definition = nwa3d_a5 + +[metadata] +setting_version = 6 +type = quality +quality_type = best +weight = 1 +global_quality = True + +[values] +layer_height = 0.08 +initial_layer_height = 0.25 +line_width = 0.4 +initial_layer_line_width = 100 +wall_thickness = 0.8 +outer_wall_wipe_distance = 0.2 +top_surface_skin_layers = 1 +top_bottom_thickness = 0.6 +top_thickness = 0.8 +top_layers = 5 +bottom_thickness = 0.6 +bottom_layers = 3 +top_bottom_pattern = lines +bottom_pattern_initial_layer = lines +outer_wall_inset = 0 +optimize_wall_printing_order = false +outer_before_inner_walls = false +alternate_extra_wall = false +compensate_wall_overlaps = true +compensate_outer_wall_overlaps = true +compensate_inner_wall_overlaps = true +minimum_wall_flow = 0 +fill_gaps_between_walls = everywhere +filter_out_tiny_gaps = true +print_thin_walls = true +horizontal_expansion = 0 +ignore_small_z_gaps = true +extra_skin_wall_count = 1 +enable_ironing = false +infill_density = 20 +connect_infill_lines = false +infill_line_multiplier = 1 +extra_infill_wall_count = 0 +infill_overlap_percentage = 10 +skin_overlap_percentage = 5 +infill_wipe_distance = 0.1 +gradual_infill_steps = 0 +infill_before_walls = false +infill_support = false +maximum_skin_angle_for_expansion = 90 +material_diameter = 1.75 +default_printing_temperature = 220 +initial_printing_temperature = 220 +final_printing_temperature = 220 +default_build_plate_temperature = 0 +build_plate_temperature = 0 +flow = 100 +enable_retraction = true +retract_at_layer_change = false +retraction_distance = 5 +retraction_speed = 45 +retraction_extra_prime_amount = 0 +retraction_minimum_travel = 0.8 +maximum_retraction_count = 90 +minimum_extrusion_distance_window = 5 +limit_support_retractions = true +nozzle_switch_retraction_distance = 16 +nozzle_switch_retraction_speed = 20 +print_speed = 30 +travel_speed = 150 +initial_layer_speed = 10 +initial_layer_travel_speed = 50 +maximum_z_speed = 0 +number_of_slower_layers = 2 +equalize_filament_flow = false +enable_acceleration_control = false +top_surface_skin_acceleration = 3000 +enable_jerk_control = false +combing_mode = off +retract_before_outer_wall = false +z_hop_when_retracted = false +enable_print_cooling = true +fan_speed = 100 +initial_fan_speed = 0 +regular_fan_speed_at_height = 0.25 +regular_fan_speed_at_layer = 2 +lift_head = false +generate_support = true +support_placement = everywhere +support_overhang_angle = 50 +support_pattern = grid +support_wall_line_count = 0 +connect_support_lines = false +support_density = 20 +support_infill_line_direction = 0 +enable_support_brim = true +support_brim_line_count = 5 +support_z_distance = 0.18 +support_x_y_distance = 0.7 +minimum_support_x_y_distance = 0.2 +support_stair_step_height = 0.3 +support_stair_step_maximum_width = 5.0 +support_join_distance = 2.0 +support_horizontal_expansion = 0.2 +gradual_support_infill_steps = 0 +enable_support_roof = true +enable_support_floor = false +support_roof_thickness = 0.45 +support_roof_density = 45 +support_roof_pattern = lines +fan_speed_override = false +use_towers = true +tower_diameter = 3 +tower_roof_angle = 65 +build_plate_adhesion_type = skirt +skirt_line_count = 2 +skirt_distance = 3 +union_overlapping_volumes = true +remove_all_holes = false +extensive_stiching = false +keep_disconnected_faces = false +merge_meshes_overlap = 0.15 +remove_mesh_intersection = false + + + + + diff --git a/resources/quality/nwa3d_a5/nwa3d_a5_fast.inst.cfg b/resources/quality/nwa3d_a5/nwa3d_a5_fast.inst.cfg new file mode 100644 index 0000000000..167bfb5dad --- /dev/null +++ b/resources/quality/nwa3d_a5/nwa3d_a5_fast.inst.cfg @@ -0,0 +1,125 @@ +[general] +version = 4 +name = Fast Quality +definition = nwa3d_a5 + +[metadata] +setting_version = 6 +type = quality +quality_type = fast +weight = -1 +global_quality = True + +[values] +layer_height = 0.25 +initial_layer_height = 0.25 +line_width = 0.4 +initial_layer_line_width = 100 +wall_thickness = 0.8 +outer_wall_wipe_distance = 0.2 +top_surface_skin_layers = 1 +top_bottom_thickness = 0.6 +top_thickness = 0.8 +top_layers = 5 +bottom_thickness = 0.6 +bottom_layers = 3 +top_bottom_pattern = lines +bottom_pattern_initial_layer = lines +outer_wall_inset = 0 +optimize_wall_printing_order = false +outer_before_inner_walls = false +alternate_extra_wall = false +compensate_wall_overlaps = true +compensate_outer_wall_overlaps = true +compensate_inner_wall_overlaps = true +minimum_wall_flow = 0 +fill_gaps_between_walls = everywhere +filter_out_tiny_gaps = true +print_thin_walls = true +horizontal_expansion = 0 +ignore_small_z_gaps = true +extra_skin_wall_count = 1 +enable_ironing = false +infill_density = 15 +connect_infill_lines = false +infill_line_multiplier = 1 +extra_infill_wall_count = 0 +infill_overlap_percentage = 10 +skin_overlap_percentage = 5 +infill_wipe_distance = 0.1 +gradual_infill_steps = 0 +infill_before_walls = false +infill_support = false +maximum_skin_angle_for_expansion = 90 +material_diameter = 1.75 +default_printing_temperature = 220 +initial_printing_temperature = 220 +final_printing_temperature = 220 +default_build_plate_temperature = 0 +build_plate_temperature = 0 +flow = 100 +enable_retraction = true +retract_at_layer_change = false +retraction_distance = 5 +retraction_speed = 45 +retraction_extra_prime_amount = 0 +retraction_minimum_travel = 0.8 +maximum_retraction_count = 90 +minimum_extrusion_distance_window = 5 +limit_support_retractions = true +nozzle_switch_retraction_distance = 16 +nozzle_switch_retraction_speed = 20 +print_speed = 60 +travel_speed = 150 +initial_layer_speed = 10 +initial_layer_travel_speed = 50 +maximum_z_speed = 0 +number_of_slower_layers = 2 +equalize_filament_flow = false +enable_acceleration_control = false +enable_jerk_control = false +combing_mode = off +retract_before_outer_wall = false +z_hop_when_retracted = false +enable_print_cooling = true +fan_speed = 100 +initial_fan_speed = 0 +regular_fan_speed_at_height = 0.5 +regular_fan_speed_at_layer = 2 +lift_head = false +generate_support = true +support_placement = everywhere +support_overhang_angle = 50 +support_pattern = grid +support_wall_line_count = 0 +connect_support_lines = false +support_density = 15 +support_infill_line_direction = 0 +enable_support_brim = true +support_brim_line_count = 5 +support_z_distance = 0.3 +support_x_y_distance = 0.7 +minimum_support_x_y_distance = 0.2 +support_stair_step_height = 0.3 +support_stair_step_maximum_width = 5.0 +support_join_distance = 2.0 +support_horizontal_expansion = 0.2 +gradual_support_infill_steps = 0 +enable_support_roof = true +enable_support_floor = false +support_roof_thickness = 0.45 +support_roof_density = 45 +support_roof_pattern = lines +fan_speed_override = false +use_towers = true +tower_diameter = 3 +tower_roof_angle = 65 +build_plate_adhesion_type = skirt +skirt_line_count = 2 +skirt_distance = 3 +union_overlapping_volumes = true +remove_all_holes = false +extensive_stiching = false +keep_disconnected_faces = false +merged_meshes_overlap = 0.15 +remove_mesh_intersection = false diff --git a/resources/quality/nwa3d_a5/nwa3d_a5_normal.inst.cfg b/resources/quality/nwa3d_a5/nwa3d_a5_normal.inst.cfg new file mode 100644 index 0000000000..30bcbed244 --- /dev/null +++ b/resources/quality/nwa3d_a5/nwa3d_a5_normal.inst.cfg @@ -0,0 +1,125 @@ +[general] +version = 4 +name = Normal Quality +definition = nwa3d_a5 + +[metadata] +setting_version = 6 +type = quality +quality_type = normal +weight = 0 +global_quality = True + +[values] +layer_height = 0.15 +initial_layer_height = 0.25 +line_width = 0.4 +initial_layer_line_width = 100 +wall_thickness = 0.8 +outer_wall_wipe_distance = 0.2 +top_surface_skin_layers = 1 +top_bottom_thickness = 0.6 +top_thickness = 0.8 +top_layers = 5 +bottom_thickness = 0.6 +bottom_layers = 3 +top_bottom_pattern = lines +bottom_pattern_initial_layer = lines +outer_wall_inset = 0 +optimize_wall_printing_order = false +outer_before_inner_walls = false +alternate_extra_wall = false +compensate_wall_overlaps = true +compensate_outer_wall_overlaps = true +compensate_inner_wall_overlaps = true +minimum_wall_flow = 0 +fill_gaps_between_walls = everywhere +filter_out_tiny_gaps = true +print_thin_walls = true +horizontal_expansion = 0 +ignore_small_z_gaps = true +extra_skin_wall_count = 1 +enable_ironing = false +infill_density = 20 +connect_infill_lines = false +infill_line_multiplier = 1 +extra_infill_wall_count = 0 +infill_overlap_percentage = 10 +skin_overlap_percentage = 5 +infill_wipe_distance = 0.1 +gradual_infill_steps = 0 +infill_before_walls = false +infill_support = false +maximum_skin_angle_for_expansion = 90 +material_diameter = 1.75 +default_printing_temperature = 220 +initial_printing_temperature = 220 +final_printing_temperature = 220 +default_build_plate_temperature = 0 +build_plate_temperature = 0 +flow = 100 +enable_retraction = true +retract_at_layer_change = false +retraction_distance = 5 +retraction_speed = 45 +retraction_extra_prime_amount = 0 +retraction_minimum_travel = 0.8 +maximum_retraction_count = 90 +minimum_extrusion_distance_window = 5 +limit_support_retractions = true +nozzle_switch_retraction_distance = 16 +nozzle_switch_retraction_speed = 20 +print_speed = 50 +travel_speed = 150 +initial_layer_speed = 10 +initial_layer_travel_speed = 50 +maximum_z_speed = 0 +number_of_slower_layers = 2 +equalize_filament_flow = false +enable_acceleration_control = false +enable_jerk_control = false +combing_mode = off +retract_before_outer_wall = false +z_hop_when_retracted = false +enable_print_cooling = true +fan_speed = 100 +initial_fan_speed = 0 +regular_fan_speed_at_height = 0.25 +regular_fan_speed_at_layer = 2 +lift_head = false +generate_support = true +support_placement = everywhere +support_overhang_angle = 50 +support_pattern = grid +support_wall_line_count = 0 +connect_support_lines = false +support_density = 20 +support_infill_line_direction = 0 +enable_support_brim = true +support_brim_line_count = 5 +support_z_distance = 0.2 +support_x_y_distance = 0.7 +minimum_support_x_y_distance = 0.2 +support_stair_step_height = 0.3 +support_stair_step_maximum_width = 5.0 +support_join_distance = 2.0 +support_horizontal_expansion = 0.2 +gradual_support_infill_steps = 0 +enable_support_roof = true +enable_support_floor = false +support_roof_thickness = 0.45 +support_roof_density = 45 +support_roof_pattern = lines +fan_speed_override = false +use_towers = true +tower_diameter = 3 +tower_roof_angle = 65 +build_plate_adhesion_type = skirt +skirt_line_count = 2 +skirt_distance = 3 +union_overlapping_volumes = true +remove_all_holes = false +extensive_stiching = false +keep_disconnected_faces = false +merged_meshes_overlap = 0.15 +remove_mesh_intersection = false From 057c30f86e86635721e8a269d864e1597699c834 Mon Sep 17 00:00:00 2001 From: Nicolas NSSM Date: Fri, 18 Jan 2019 10:40:59 +0100 Subject: [PATCH 1292/1292] Create alfawise_u30.def.json (#5083) * Create alfawise_u30.def.json I basically took the base from https://github.com/Ultimaker/Cura/blob/master/resources/definitions/alfawise_u20.def.json and compiled it with the old Cura ini given by Alfawise on the SD card. I don't know anything about Cura config so double check it real good! * Update alfawise_u30.def.json * Create alfawise_u30_extruder_0.def.json * Update alfawise_u30.def.json * Update alfawise_u30.def.json * Update alfawise_u30.def.json * Update alfawise_u30.def.json Turn off the fan at the end of a print --- resources/definitions/alfawise_u30.def.json | 93 +++++++++++++++++++ .../alfawise_u30_extruder_0.def.json | 16 ++++ 2 files changed, 109 insertions(+) create mode 100644 resources/definitions/alfawise_u30.def.json create mode 100644 resources/extruders/alfawise_u30_extruder_0.def.json diff --git a/resources/definitions/alfawise_u30.def.json b/resources/definitions/alfawise_u30.def.json new file mode 100644 index 0000000000..65f6adcfe0 --- /dev/null +++ b/resources/definitions/alfawise_u30.def.json @@ -0,0 +1,93 @@ +{ + "name": "Alfawise U30", + "version": 2, + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "author": "Nicolas Nussbaum", + "manufacturer": "Alfawise", + "file_formats": "text/x-gcode", + "preferred_quality_type": "fast", + "machine_extruder_trains": + { + "0": "alfawise_u30_extruder_0" + } + }, + "overrides": { + "machine_name": { + "default_value": "Alfawise U30" + }, + "machine_start_gcode": { + "default_value": "; -- START GCODE --\nG21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z1 F1000 ;move up slightly\nG1 Y60.0 Z0 E9.0 F1000.0;intro line\nG1 Y100.0 E21.5 F1000.0 ;continue line\nG92 E0 ;zero the extruded length again\nG1 F80\n;Put printing message on LCD screen\nM117 Printing...\n; -- end of START GCODE --" + }, + "machine_end_gcode": { + "default_value": "; -- END GCODE --\nM104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F80 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning\nM107 ;turn the fan off; -- end of END GCODE --" + }, + "machine_width": { + "default_value": 220 + }, + "machine_height": { + "default_value": 250 + }, + "machine_depth": { + "default_value": 220 + }, + "machine_heated_bed": { + "default_value": true + }, + "machine_center_is_zero": { + "default_value": false + }, + "gantry_height": { + "default_value": 10 + }, + "machine_gcode_flavor": { + "default_value": "RepRap (Marlin/Sprinter)" + }, + "material_diameter": { + "default_value": 1.75 + }, + "material_print_temperature": { + "default_value": 210 + }, + "material_bed_temperature": { + "default_value": 50 + }, + "layer_height_0": { + "default_value": 0.2 + }, + "wall_thickness": { + "default_value": 1.2 + }, + "speed_print": { + "default_value": 40 + }, + "speed_infill": { + "default_value": 40 + }, + "speed_wall": { + "default_value": 35 + }, + "speed_topbottom": { + "default_value": 35 + }, + "speed_travel": { + "default_value": 120 + }, + "speed_layer_0": { + "default_value": 20 + }, + "support_enable": { + "default_value": true + }, + "retraction_enable": { + "default_value": true + }, + "retraction_amount": { + "default_value": 5 + }, + "retraction_speed": { + "default_value": 45 + } + } +} diff --git a/resources/extruders/alfawise_u30_extruder_0.def.json b/resources/extruders/alfawise_u30_extruder_0.def.json new file mode 100644 index 0000000000..37f59eb567 --- /dev/null +++ b/resources/extruders/alfawise_u30_extruder_0.def.json @@ -0,0 +1,16 @@ +{ + "id": "alfawise_u30_extruder_0", + "version": 2, + "name": "Extruder 1", + "inherits": "fdmextruder", + "metadata": { + "machine": "alfawise_u30", + "position": "0" + }, + + "overrides": { + "extruder_nr": { "default_value": 0 }, + "machine_nozzle_size": { "default_value": 0.4 }, + "material_diameter": { "default_value": 1.75 } + } +}

    fcgH6pO(=&uw9i7{^0?z7UA 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

    yIHgERaU=JNy7=q=;-jo7etgJi>{^i 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­1b1ri#7y-f4`n@X-6bylLTqFUm5RTM1i+O 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